src/build_vehicle_gui.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6725 23339968083f
equal deleted inserted replaced
6719:4cc327ad39d5 6720:35756db7e577
   138 	const EngineID vb = *(const EngineID*)b;
   138 	const EngineID vb = *(const EngineID*)b;
   139 	int r;
   139 	int r;
   140 
   140 
   141 	if (va != last_engine[0]) {
   141 	if (va != last_engine[0]) {
   142 		last_engine[0] = va;
   142 		last_engine[0] = va;
   143 		GetString(last_name[0], GetCustomEngineName(va), lastof(last_name[0]));
   143 		SetDParam(0, va);
       
   144 		GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0]));
   144 	}
   145 	}
   145 
   146 
   146 	if (vb != last_engine[1]) {
   147 	if (vb != last_engine[1]) {
   147 		last_engine[1] = vb;
   148 		last_engine[1] = vb;
   148 		GetString(last_name[1], GetCustomEngineName(vb), lastof(last_name[1]));
   149 		SetDParam(0, vb);
       
   150 		GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1]));
   149 	}
   151 	}
   150 
   152 
   151 	r = strcmp(last_name[0], last_name[1]); // sort by name
   153 	r = strcmp(last_name[0], last_name[1]); // sort by name
   152 
   154 
   153 	if (r == 0) {
   155 	if (r == 0) {
   204 static int CDECL TrainEngineRunningCostSorter(const void *a, const void *b)
   206 static int CDECL TrainEngineRunningCostSorter(const void *a, const void *b)
   205 {
   207 {
   206 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
   208 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
   207 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
   209 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
   208 
   210 
   209 	int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
   211 	Money va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
   210 	int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
   212 	Money vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
   211 	int r = va - vb;
   213 	int r = ClampToI32(va - vb);
   212 
   214 
   213 	return _internal_sort_order ? -r : r;
   215 	return _internal_sort_order ? -r : r;
   214 }
   216 }
   215 
   217 
   216 static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
   218 static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
   222 		* We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
   224 		* We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
   223 		* we will actually calculate cunning cost/power (to make it more than 1).
   225 		* we will actually calculate cunning cost/power (to make it more than 1).
   224 		* Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
   226 		* Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
   225 		* Another thing is that both power and running costs should be doubled for multiheaded engines.
   227 		* Another thing is that both power and running costs should be doubled for multiheaded engines.
   226 		* Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
   228 		* Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
   227 	int va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power);
   229 	Money va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power);
   228 	int vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power);
   230 	Money vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power);
   229 	int r = vb - va;
   231 	int r = ClampToI32(vb - va);
   230 
   232 
   231 	return _internal_sort_order ? -r : r;
   233 	return _internal_sort_order ? -r : r;
   232 }
   234 }
   233 
   235 
   234 static int CDECL TrainEngineNumberSorter(const void *a, const void *b)
   236 static int CDECL TrainEngineNumberSorter(const void *a, const void *b)
   668 	EngineID eid, sel_id;
   670 	EngineID eid, sel_id;
   669 	int num_engines = 0;
   671 	int num_engines = 0;
   670 	int num_wagons  = 0;
   672 	int num_wagons  = 0;
   671 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   673 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   672 
   674 
   673 	bv->filter.railtype = (w->window_number == 0) ? RAILTYPE_END : GetRailType(w->window_number);
   675 	bv->filter.railtype = (w->window_number <= VEH_END) ? RAILTYPE_END : GetRailType(w->window_number);
   674 
   676 
   675 	EngList_RemoveAll(&bv->eng_list);
   677 	EngList_RemoveAll(&bv->eng_list);
   676 
   678 
   677 	/* Make list of all available train engines and wagons.
   679 	/* Make list of all available train engines and wagons.
   678 	 * Also check to see if the previously selected engine is still available,
   680 	 * Also check to see if the previously selected engine is still available,
   760 	 * and if not, reset selection to INVALID_ENGINE. This could be the case
   762 	 * and if not, reset selection to INVALID_ENGINE. This could be the case
   761 	 * when planes become obsolete and are removed */
   763 	 * when planes become obsolete and are removed */
   762 	sel_id = INVALID_ENGINE;
   764 	sel_id = INVALID_ENGINE;
   763 	for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
   765 	for (eid = AIRCRAFT_ENGINES_INDEX; eid < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; eid++) {
   764 		if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
   766 		if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
   765 		if (w->window_number != 0 && !IsAircraftBuildableAtStation(eid, w->window_number)) continue;
   767 		/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
       
   768 		if (w->window_number > VEH_END && !IsAircraftBuildableAtStation(eid, w->window_number)) continue;
   766 
   769 
   767 		EngList_Add(&bv->eng_list, eid);
   770 		EngList_Add(&bv->eng_list, eid);
   768 		if (eid == bv->sel_engine) sel_id = eid;
   771 		if (eid == bv->sel_engine) sel_id = eid;
   769 	}
   772 	}
   770 
   773 
   851 
   854 
   852 	for (; min < max; min++, y += step_size) {
   855 	for (; min < max; min++, y += step_size) {
   853 		const EngineID engine = eng_list[min];
   856 		const EngineID engine = eng_list[min];
   854 		const uint num_engines = IsDefaultGroupID(selected_group) ? p->num_engines[engine] : GetGroup(selected_group)->num_engines[engine];
   857 		const uint num_engines = IsDefaultGroupID(selected_group) ? p->num_engines[engine] : GetGroup(selected_group)->num_engines[engine];
   855 
   858 
   856 		DrawString(x + x_offset, y, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10);
   859 		SetDParam(0, engine);
       
   860 		DrawString(x + x_offset, y, STR_ENGINE_NAME, engine == selected_id ? 0xC : 0x10);
   857 		DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player));
   861 		DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player));
   858 		if (show_count) {
   862 		if (show_count) {
   859 			SetDParam(0, num_engines);
   863 			SetDParam(0, num_engines);
   860 			DrawStringRightAligned(213, y + (GetVehicleListHeight(type) == 14 ? 3 : 8), STR_TINY_BLACK, 0);
   864 			DrawStringRightAligned(213, y + (GetVehicleListHeight(type) == 14 ? 3 : 8), STR_TINY_BLACK, 0);
   861 		}
   865 		}
   882 static void DrawBuildVehicleWindow(Window *w)
   886 static void DrawBuildVehicleWindow(Window *w)
   883 {
   887 {
   884 	const buildvehicle_d *bv = &WP(w, buildvehicle_d);
   888 	const buildvehicle_d *bv = &WP(w, buildvehicle_d);
   885 	uint max = min(w->vscroll.pos + w->vscroll.cap, EngList_Count(&bv->eng_list));
   889 	uint max = min(w->vscroll.pos + w->vscroll.cap, EngList_Count(&bv->eng_list));
   886 
   890 
   887 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
   891 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number <= VEH_END);
   888 
   892 
   889 	SetVScrollCount(w, EngList_Count(&bv->eng_list));
   893 	SetVScrollCount(w, EngList_Count(&bv->eng_list));
   890 	SetDParam(0, bv->filter.railtype + STR_881C_NEW_RAIL_VEHICLES); // This should only affect rail vehicles
   894 	SetDParam(0, bv->filter.railtype + STR_881C_NEW_RAIL_VEHICLES); // This should only affect rail vehicles
   891 	DrawWindowWidgets(w);
   895 	DrawWindowWidgets(w);
   892 
   896 
   961 					case VEH_TRAIN:    str = STR_886A_RENAME_TRAIN_VEHICLE_TYPE; break;
   965 					case VEH_TRAIN:    str = STR_886A_RENAME_TRAIN_VEHICLE_TYPE; break;
   962 					case VEH_ROAD:     str = STR_9036_RENAME_ROAD_VEHICLE_TYPE;  break;
   966 					case VEH_ROAD:     str = STR_9036_RENAME_ROAD_VEHICLE_TYPE;  break;
   963 					case VEH_SHIP:     str = STR_9838_RENAME_SHIP_TYPE;          break;
   967 					case VEH_SHIP:     str = STR_9838_RENAME_SHIP_TYPE;          break;
   964 					case VEH_AIRCRAFT: str = STR_A039_RENAME_AIRCRAFT_TYPE;      break;
   968 					case VEH_AIRCRAFT: str = STR_A039_RENAME_AIRCRAFT_TYPE;      break;
   965 				}
   969 				}
   966 				ShowQueryString(GetCustomEngineName(sel_eng), str, 31, 160, w, CS_ALPHANUMERAL);
   970 				SetDParam(0, sel_eng);
       
   971 				ShowQueryString(STR_ENGINE_NAME, str, 31, 160, w, CS_ALPHANUMERAL);
   967 			}
   972 			}
   968 			break;
   973 			break;
   969 		}
   974 		}
   970 	}
   975 	}
   971 }
   976 }
   992 			DrawBuildVehicleWindow(w);
   997 			DrawBuildVehicleWindow(w);
   993 			break;
   998 			break;
   994 
   999 
   995 		case WE_CLICK:
  1000 		case WE_CLICK:
   996 			BuildVehicleClickEvent(w, e);
  1001 			BuildVehicleClickEvent(w, e);
       
  1002 			break;
       
  1003 
       
  1004 		case WE_DOUBLE_CLICK:
       
  1005 			if (e->we.click.widget == BUILD_VEHICLE_WIDGET_LIST) {
       
  1006 				/* When double clicking, we want to buy a vehicle */
       
  1007 				e->we.click.widget = BUILD_VEHICLE_WIDGET_BUILD;
       
  1008 				BuildVehicleClickEvent(w, e);
       
  1009 			}
   997 			break;
  1010 			break;
   998 
  1011 
   999 		case WE_ON_EDIT_TEXT: {
  1012 		case WE_ON_EDIT_TEXT: {
  1000 			if (e->we.edittext.str[0] != '\0') {
  1013 			if (e->we.edittext.str[0] != '\0') {
  1001 				StringID str = STR_NULL;
  1014 				StringID str = STR_NULL;
  1041 
  1054 
  1042 void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)
  1055 void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)
  1043 {
  1056 {
  1044 	buildvehicle_d *bv;
  1057 	buildvehicle_d *bv;
  1045 	Window *w;
  1058 	Window *w;
       
  1059 	/* We want to be able to open both Available Train as Available Ships,
       
  1060 	 *  so if tile == 0 (Available XXX Window), use 'type' as unique number.
       
  1061 	 *  As it always is a low value, it won't collide with any real tile
       
  1062 	 *  number. */
       
  1063 	uint num = (tile == 0) ? (int)type : tile;
  1046 
  1064 
  1047 	assert(IsPlayerBuildableVehicleType(type));
  1065 	assert(IsPlayerBuildableVehicleType(type));
  1048 
  1066 
  1049 	DeleteWindowById(WC_BUILD_VEHICLE, tile);
  1067 	DeleteWindowById(WC_BUILD_VEHICLE, num);
  1050 
  1068 
  1051 	w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
  1069 	w = AllocateWindowDescFront(&_build_vehicle_desc, num);
  1052 
  1070 
  1053 	if (w == NULL) return;
  1071 	if (w == NULL) return;
  1054 
  1072 
  1055 	w->caption_color = (tile != 0) ? GetTileOwner(tile) : _local_player;
  1073 	w->caption_color = (tile != 0) ? GetTileOwner(tile) : _local_player;
  1056 	w->resize.step_height = GetVehicleListHeight(type);
  1074 	w->resize.step_height = GetVehicleListHeight(type);