Changeset - r6998:9587370cd6e8
[Not reviewed]
master
0 13 1
truelight - 17 years ago 2007-06-21 16:17:47
truelight@openttd.org
(svn r10254) -Feature: loading indicator, which shows in % how full a vehicle is while loading/unloading (TheJosh)
14 files changed with 180 insertions and 36 deletions:
0 comments (0 inline, 0 general)
src/economy.cpp
Show inline comments
 
@@ -1718,6 +1718,16 @@ static void LoadUnloadVehicle(Vehicle *v
 
		}
 
	}
 

	
 
	/* Calculate the loading indicator fill percent and display */
 
	if (_patches.loading_indicators && _game_mode != GM_MENU && v->owner == _local_player) {
 
		int percent = CalcPercentVehicleFilled(v);
 
		if (v->fill_percent_te_id == INVALID_TE_ID) {
 
			v->fill_percent_te_id = ShowFillingPercent(v->x_pos, v->y_pos, v->z_pos + 20, percent);
 
		} else {
 
			UpdateFillingPercent(v->fill_percent_te_id, percent);
 
		}
 
	}
 

	
 
	v->load_unload_time_rem = unloading_time;
 

	
 
	if (completely_empty) {
src/functions.h
Show inline comments
 
@@ -79,16 +79,6 @@ uint32 InteractiveRandom(); // Used for 
 
uint InteractiveRandomRange(uint max);
 

	
 
/* texteff.cpp */
 
void MoveAllTextEffects();
 
void AddTextEffect(StringID msg, int x, int y, uint16 duration);
 
void InitTextEffects();
 
void DrawTextEffects(DrawPixelInfo *dpi);
 

	
 
void InitTextMessage();
 
void DrawTextMessage();
 
void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...);
 
void UndrawTextMessage();
 

	
 
bool AddAnimatedTile(TileIndex tile);
 
void DeleteAnimatedTile(TileIndex tile);
 
void AnimateAnimatedTiles();
src/gfx.cpp
Show inline comments
 
@@ -19,6 +19,7 @@
 
#include "genworld.h"
 
#include "debug.h"
 
#include "zoom.hpp"
 
#include "texteff.hpp"
 
#include "blitter/factory.hpp"
 

	
 
#ifdef _DEBUG
src/lang/english.txt
Show inline comments
 
@@ -1103,6 +1103,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_OFF      
 
STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER                       :{LTBLUE}Map scrollwheel speed: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME                            :{LTBLUE}Automatically pause when starting a new game: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS                       :{LTBLUE}Use the advanced vehicle list: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_LOADING_INDICATORS                           :{LTBLUE}Use loading indicators: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_TIMETABLE_ALLOW                              :{LTBLUE}Enable timetabling for vehicles: {ORANGE}{STRING1}
 
STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS                           :{LTBLUE}Show timetable in ticks rather than days: {ORANGE}{STRING1}
 

	
 
@@ -3289,6 +3290,10 @@ STR_TRANSPARENT_INDUSTRIES_DESC         
 
STR_TRANSPARENT_BUILDINGS_DESC                                  :{BLACK}Toggle transparency for buildables like stations, depots, waypoints and catenary
 
STR_TRANSPARENT_BRIDGES_DESC                                    :{BLACK}Toggle transparency for bridges
 
STR_TRANSPARENT_STRUCTURES_DESC                                 :{BLACK}Toggle transparency for structures like lighthouses and antennas, maybe in future for eyecandy
 
STR_TRANSPARENT_LOADING_DESC                                    :{BLACK}Toggle transparency for loading indicators
 

	
 
STR_PERCENT_FULL_SMALL                                          :{TINYFONT}{WHITE}{NUM}%
 
STR_PERCENT_FULL                                                :{WHITE}{NUM}%
 

	
 
##### Mass Order
 
STR_GROUP_NAME_FORMAT                                           :Group {COMMA}
src/misc_gui.cpp
Show inline comments
 
@@ -633,7 +633,7 @@ void ShowCostOrIncomeAnimation(int x, in
 
		msg = STR_0803_INCOME;
 
	}
 
	SetDParamMoney(0, cost);
 
	AddTextEffect(msg, pt.x, pt.y, 0x250);
 
	AddTextEffect(msg, pt.x, pt.y, 0x250, TE_RISING);
 
}
 

	
 
void ShowFeederIncomeAnimation(int x, int y, int z, Money cost)
 
@@ -641,7 +641,26 @@ void ShowFeederIncomeAnimation(int x, in
 
	Point pt = RemapCoords(x,y,z);
 

	
 
	SetDParamMoney(0, cost);
 
	AddTextEffect(STR_FEEDER, pt.x, pt.y, 0x250);
 
	AddTextEffect(STR_FEEDER, pt.x, pt.y, 0x250, TE_RISING);
 
}
 

	
 
TextEffectID ShowFillingPercent(int x, int y, int z, uint8 percent)
 
{
 
	Point pt = RemapCoords(x, y, z);
 

	
 
	SetDParam(0, percent);
 
	return AddTextEffect(STR_PERCENT_FULL, pt.x, pt.y, 0xFFFF, TE_STATIC);
 
}
 

	
 
void UpdateFillingPercent(TextEffectID te_id, uint8 percent)
 
{
 
	SetDParam(0, percent);
 
	UpdateTextEffect(te_id, STR_PERCENT_FULL);
 
}
 

	
 
void HideFillingPercent(TextEffectID te_id)
 
{
 
	if (te_id != INVALID_TE_ID) RemoveTextEffect(te_id);
 
}
 

	
 
static const Widget _tooltips_widgets[] = {
src/openttd.h
Show inline comments
 
@@ -192,6 +192,7 @@ enum {
 
	TO_BUILDINGS,
 
	TO_BRIDGES,
 
	TO_STRUCTURES,
 
	TO_LOADING,
 
};
 

	
 
/* Landscape types */
src/settings.cpp
Show inline comments
 
@@ -1350,6 +1350,7 @@ const SettingDesc _patch_settings[] = {
 
	SDT_BOOL(Patches, pause_on_newgame,              S, 0, false,        STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME,     NULL),
 
	SDT_BOOL(Patches, advanced_vehicle_list,         S, 0, true,         STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS,     NULL),
 
	SDT_BOOL(Patches, timetable_in_ticks,            S, 0, false,        STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS,    NULL),
 
	SDT_BOOL(Patches, loading_indicators,            S, 0, true,         STR_CONFIG_PATCHES_LOADING_INDICATORS,    RedrawScreen),
 

	
 
	/***************************************************************************/
 
	/* Construction section of the GUI-configure patches window */
src/settings_gui.cpp
Show inline comments
 
@@ -652,6 +652,7 @@ static const char *_patches_ui[] = {
 
	"scrollwheel_multiplier",
 
	"pause_on_newgame",
 
	"advanced_vehicle_list",
 
	"loading_indicators",
 
	"timetable_in_ticks",
 
};
 

	
src/texteff.cpp
Show inline comments
 
@@ -19,10 +19,11 @@
 
#include "blitter/factory.hpp"
 
#include <stdarg.h> /* va_list */
 
#include "date.h"
 
#include "texteff.hpp"
 

	
 
enum {
 
	MAX_TEXTMESSAGE_LENGTH = 200,
 
	MAX_TEXT_MESSAGES      =  30,
 
	INIT_NUM_TEXT_MESSAGES =  20,
 
	MAX_CHAT_MESSAGES      =  10,
 
	MAX_ANIMATED_TILES     = 256,
 
};
 
@@ -36,6 +37,7 @@ struct TextEffect {
 
	uint16 duration;
 
	uint32 params_1;
 
	uint32 params_2;
 
	TextEffectMode mode;
 
};
 

	
 

	
 
@@ -45,12 +47,13 @@ struct TextMessage {
 
	Date end_date;
 
};
 

	
 
static TextEffect _text_effect_list[MAX_TEXT_MESSAGES];
 
static TextEffect *_text_effect_list = NULL;
 
static TextMessage _textmsg_list[MAX_CHAT_MESSAGES];
 
TileIndex _animated_tile_list[MAX_ANIMATED_TILES];
 

	
 
static bool _textmessage_dirty = false;
 
static bool _textmessage_visible = false;
 
static uint16 _num_text_effects = INIT_NUM_TEXT_MESSAGES;
 

	
 
/* The chatbox grows from the bottom so the coordinates are pixels from
 
 * the left and pixels from the bottom. The height is the maximum height */
 
@@ -261,24 +264,38 @@ static void MarkTextEffectAreaDirty(Text
 
	);
 
}
 

	
 
void AddTextEffect(StringID msg, int x, int y, uint16 duration)
 
TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffectMode mode)
 
{
 
	TextEffect *te;
 
	int w;
 
	char buffer[100];
 
	TextEffectID i;
 

	
 
	if (_game_mode == GM_MENU) return;
 
	if (_game_mode == GM_MENU) return INVALID_TE_ID;
 

	
 
	for (te = _text_effect_list; te->string_id != INVALID_STRING_ID; ) {
 
		if (++te == endof(_text_effect_list)) return;
 
	/* Look for a free spot in the text effect array */
 
	for (i = 0; i < _num_text_effects; i++) {
 
		if (_text_effect_list[i].string_id == INVALID_STRING_ID) break;
 
	}
 

	
 
	/* If there is none found, we grow the array */
 
	if (i == _num_text_effects) {
 
		_num_text_effects += 25;
 
		_text_effect_list = (TextEffect*) realloc(_text_effect_list, _num_text_effects * sizeof(TextEffect));
 
		for (; i < _num_text_effects; i++) _text_effect_list[i].string_id = INVALID_STRING_ID;
 
		i = _num_text_effects - 1;
 
	}
 

	
 
	te = &_text_effect_list[i];
 

	
 
	/* Start defining this object */
 
	te->string_id = msg;
 
	te->duration = duration;
 
	te->y = y - 5;
 
	te->bottom = y + 5;
 
	te->params_1 = GetDParam(0);
 
	te->params_2 = GetDParam(4);
 
	te->mode = mode;
 

	
 
	GetString(buffer, msg, lastof(buffer));
 
	w = GetStringBoundingBox(buffer).width;
 
@@ -286,10 +303,38 @@ void AddTextEffect(StringID msg, int x, 
 
	te->x = x - (w >> 1);
 
	te->right = x + (w >> 1) - 1;
 
	MarkTextEffectAreaDirty(te);
 

	
 
	return i;
 
}
 

	
 
void UpdateTextEffect(TextEffectID te_id, StringID msg)
 
{
 
	assert(te_id < _num_text_effects);
 
	TextEffect *te;
 

	
 
	/* Update details */
 
	te = &_text_effect_list[te_id];
 
	te->string_id = msg;
 
	te->params_1 = GetDParam(0);
 
	te->params_2 = GetDParam(4);
 

	
 
	MarkTextEffectAreaDirty(te);
 
}
 

	
 
void RemoveTextEffect(TextEffectID te_id)
 
{
 
	assert(te_id < _num_text_effects);
 
	TextEffect *te;
 

	
 
	te = &_text_effect_list[te_id];
 
	MarkTextEffectAreaDirty(te);
 
	te->string_id = INVALID_STRING_ID;
 
}
 

	
 
static void MoveTextEffect(TextEffect *te)
 
{
 
	/* Never expire for duration of 0xFFFF */
 
	if (te->duration == 0xFFFF) return;
 
	if (te->duration < 8) {
 
		te->string_id = INVALID_STRING_ID;
 
	} else {
 
@@ -302,47 +347,48 @@ static void MoveTextEffect(TextEffect *t
 

	
 
void MoveAllTextEffects()
 
{
 
	TextEffect *te;
 

	
 
	for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
 
		if (te->string_id != INVALID_STRING_ID) MoveTextEffect(te);
 
	for (TextEffectID i = 0; i < _num_text_effects; i++) {
 
		TextEffect *te = &_text_effect_list[i];
 
		if (te->string_id != INVALID_STRING_ID && te->mode == TE_RISING) MoveTextEffect(te);
 
	}
 
}
 

	
 
void InitTextEffects()
 
{
 
	TextEffect *te;
 
	if (_text_effect_list == NULL) _text_effect_list = MallocT<TextEffect>(_num_text_effects);
 

	
 
	for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
 
		te->string_id = INVALID_STRING_ID;
 
	}
 
	for (TextEffectID i = 0; i < _num_text_effects; i++) _text_effect_list[i].string_id = INVALID_STRING_ID;
 
}
 

	
 
void DrawTextEffects(DrawPixelInfo *dpi)
 
{
 
	const TextEffect* te;
 

	
 
	switch (dpi->zoom) {
 
		case ZOOM_LVL_NORMAL:
 
			for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
 
			for (TextEffectID i = 0; i < _num_text_effects; i++) {
 
				TextEffect *te = &_text_effect_list[i];
 
				if (te->string_id != INVALID_STRING_ID &&
 
						dpi->left <= te->right &&
 
						dpi->top  <= te->bottom &&
 
						dpi->left + dpi->width  > te->x &&
 
						dpi->top  + dpi->height > te->y) {
 
					AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
 
					if (te->mode == TE_RISING || (_patches.loading_indicators && !HASBIT(_transparent_opt, TO_LOADING))) {
 
						AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
 
					}
 
				}
 
			}
 
			break;
 

	
 
		case ZOOM_LVL_OUT_2X:
 
			for (te = _text_effect_list; te != endof(_text_effect_list); te++) {
 
			for (TextEffectID i = 0; i < _num_text_effects; i++) {
 
				TextEffect *te = &_text_effect_list[i];
 
				if (te->string_id != INVALID_STRING_ID &&
 
						dpi->left <= te->right  * 2 - te->x &&
 
						dpi->top  <= te->bottom * 2 - te->y &&
 
						dpi->left + dpi->width  > te->x &&
 
						dpi->top  + dpi->height > te->y) {
 
					AddStringToDraw(te->x, te->y, (StringID)(te->string_id-1), te->params_1, te->params_2);
 
					if (te->mode == TE_RISING || (_patches.loading_indicators && !HASBIT(_transparent_opt, TO_LOADING))) {
 
						AddStringToDraw(te->x, te->y, (StringID)(te->string_id - 1), te->params_1, te->params_2);
 
					}
 
				}
 
			}
 
			break;
src/texteff.hpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef TEXTEFF_HPP
 
#define TEXTEFF_HPP
 

	
 
/**
 
 * Text effect modes.
 
 */
 
enum TextEffectMode {
 
	TE_RISING, ///< Make the text effect slowly go upwards
 
	TE_STATIC, ///< Keep the text effect static
 

	
 
	INVALID_TE_ID = 0xFFFF,
 
};
 

	
 
typedef uint16 TextEffectID;
 

	
 
void MoveAllTextEffects();
 
TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffectMode mode);
 
void InitTextEffects();
 
void DrawTextEffects(DrawPixelInfo *dpi);
 
void UpdateTextEffect(TextEffectID effect_id, StringID msg);
 
void RemoveTextEffect(TextEffectID effect_id);
 

	
 
void InitTextMessage();
 
void DrawTextMessage();
 
void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...);
 
void UndrawTextMessage();
 

	
 
/* misc_gui.cpp */
 
TextEffectID ShowFillingPercent(int x, int y, int z, uint8 percent);
 
void UpdateFillingPercent(TextEffectID te_id, uint8 percent);
 
void HideFillingPercent(TextEffectID te_id);
 

	
 
#endif /* TEXTEFF_HPP */
src/transparency_gui.cpp
Show inline comments
 
@@ -23,6 +23,7 @@ enum TransparencyToolbarWidgets{
 
	TTW_WIDGET_BUILDINGS,    ///< Make player buildings and structures transparent
 
	TTW_WIDGET_BRIDGES,      ///< Make bridges transparent
 
	TTW_WIDGET_STRUCTURES,   ///< Make unmovable structures transparent
 
	TTW_WIDGET_LOADING,      ///< Make loading indicators transperent
 
	TTW_WIDGET_END,          ///< End of toggle buttons
 
};
 

	
 
@@ -59,11 +60,11 @@ static void TransparencyToolbWndProc(Win
 

	
 
static const Widget _transparency_widgets[] = {
 
{ WWT_CLOSEBOX,   RESIZE_NONE,  7,   0,  10,   0,  13, STR_00C5,                 STR_018B_CLOSE_WINDOW},
 
{  WWT_CAPTION,   RESIZE_NONE,  7,  11, 162,   0,  13, STR_TRANSPARENCY_TOOLB,   STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{WWT_STICKYBOX,   RESIZE_NONE,  7, 163, 174,   0,  13, STR_NULL,                 STR_STICKY_BUTTON},
 
{  WWT_CAPTION,   RESIZE_NONE,  7,  11, 184,   0,  13, STR_TRANSPARENCY_TOOLB,   STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{WWT_STICKYBOX,   RESIZE_NONE,  7, 185, 196,   0,  13, STR_NULL,                 STR_STICKY_BUTTON},
 

	
 
/* transparency widgets:
 
 * transparent signs, trees, houses, industries, player's buildings, bridges and unmovable structures */
 
 * transparent signs, trees, houses, industries, player's buildings, bridges, unmovable structures and loading indicators */
 
{   WWT_IMGBTN,   RESIZE_NONE,  7,   0,  21,  14,  35, SPR_IMG_SIGN,         STR_TRANSPARENT_SIGNS_DESC},
 
{   WWT_IMGBTN,   RESIZE_NONE,  7,  22,  43,  14,  35, SPR_IMG_PLANTTREES,   STR_TRANSPARENT_TREES_DESC},
 
{   WWT_IMGBTN,   RESIZE_NONE,  7,  44,  65,  14,  35, SPR_IMG_TOWN,         STR_TRANSPARENT_HOUSES_DESC},
 
@@ -71,12 +72,13 @@ static const Widget _transparency_widget
 
{   WWT_IMGBTN,   RESIZE_NONE,  7,  88, 109,  14,  35, SPR_IMG_COMPANY_LIST, STR_TRANSPARENT_BUILDINGS_DESC},
 
{   WWT_IMGBTN,   RESIZE_NONE,  7, 110, 152,  14,  35, SPR_IMG_BRIDGE,       STR_TRANSPARENT_BRIDGES_DESC},
 
{   WWT_IMGBTN,   RESIZE_NONE,  7, 153, 174,  14,  35, SPR_IMG_TRANSMITTER,  STR_TRANSPARENT_STRUCTURES_DESC},
 
{   WWT_IMGBTN,   RESIZE_NONE,  7, 175, 196,  14,  35, SPR_IMG_TRAINLIST,    STR_TRANSPARENT_LOADING_DESC},
 

	
 
{   WIDGETS_END},
 
};
 

	
 
static const WindowDesc _transparency_desc = {
 
	WDP_ALIGN_TBR, 58+36, 175, 36,
 
	WDP_ALIGN_TBR, 58+36, 197, 36,
 
	WC_TRANSPARENCY_TOOLBAR, WC_NONE,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
 
	_transparency_widgets,
src/variables.h
Show inline comments
 
@@ -133,6 +133,7 @@ struct Patches {
 
	byte liveries;                      // Options for displaying company liveries, 0=none, 1=self, 2=all
 
	bool prefer_teamchat;               // Choose the chat message target with <ENTER>, true=all players, false=your team
 
	bool advanced_vehicle_list;         // Use the "advanced" vehicle list
 
	bool loading_indicators;            // Show loading indicators
 

	
 
	uint8 toolbar_pos;                  // position of toolbars, 0=left, 1=center, 2=right
 
	uint8 window_snap_radius;           // Windows snap at each other if closer than this
src/vehicle.cpp
Show inline comments
 
@@ -229,6 +229,7 @@ void AfterLoadVehicles()
 
	FOR_ALL_VEHICLES(v) {
 
		v->UpdateDeltaXY(v->direction);
 

	
 
		v->fill_percent_te_id = INVALID_TE_ID;
 
		v->first = NULL;
 
		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
 
		if (v->type == VEH_ROAD)  v->u.road.first_engine = INVALID_ENGINE;
 
@@ -296,6 +297,7 @@ static Vehicle *InitializeVehicle(Vehicl
 
	v->depot_list  = NULL;
 
	v->random_bits = 0;
 
	v->group_id = DEFAULT_GROUP;
 
	v->fill_percent_te_id = INVALID_TE_ID;
 

	
 
	return v;
 
}
 
@@ -2263,6 +2265,29 @@ bool IsVehicleInDepot(const Vehicle *v)
 
	return false;
 
}
 

	
 
/**
 
 * Calculates how full a vehicle is.
 
 * @param v The Vehicle to check. For trains, use the first engine.
 
 * @return A percentage of how full the Vehicle is.
 
 */
 
uint8 CalcPercentVehicleFilled(Vehicle *v)
 
{
 
	int count = 0;
 
	int max = 0;
 

	
 
	/* Count up max and used */
 
	for (; v != NULL; v = v->next) {
 
		count += v->cargo_count;
 
		max += v->cargo_cap;
 
	}
 

	
 
	/* Train without capacity */
 
	if (max == 0) return 100;
 

	
 
	/* Return the percentage */
 
	return (count * 100) / max;
 
}
 

	
 
void VehicleEnterDepot(Vehicle *v)
 
{
 
	switch (v->type) {
 
@@ -3107,6 +3132,9 @@ void Vehicle::LeaveStation()
 
	current_order.flags = 0;
 
	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
 

	
 
	HideFillingPercent(this->fill_percent_te_id);
 
	this->fill_percent_te_id = INVALID_TE_ID;
 

	
 
	UpdateVehicleTimetable(this, false);
 
}
 

	
src/vehicle.h
Show inline comments
 
@@ -9,6 +9,7 @@
 
#include "order.h"
 
#include "rail.h"
 
#include "road.h"
 
#include "texteff.hpp"
 

	
 
/** The returned bits of VehicleEnterTile. */
 
enum VehicleEnterTileStatus {
 
@@ -245,6 +246,8 @@ struct Vehicle {
 
	int8 y_offs;             // y offset for vehicle sprite
 
	EngineID engine_type;
 

	
 
	TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
 

	
 
	/* for randomized variational spritegroups
 
	 * bitmask used to resolve them; parts of it get reseeded when triggers
 
	 * of corresponding spritegroups get matched */
 
@@ -506,6 +509,7 @@ void *VehicleFromPos(TileIndex tile, voi
 
void *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc);
 
void CallVehicleTicks();
 
Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z);
 
uint8 CalcPercentVehicleFilled(Vehicle *v);
 

	
 
void InitializeTrains();
 
byte VehicleRandomBits();
0 comments (0 inline, 0 general)