src/vehicle.cpp
branchcpp_gui
changeset 6308 646711c5feaa
parent 6307 f40e88cff863
--- a/src/vehicle.cpp	Sun Apr 15 17:04:44 2007 +0000
+++ b/src/vehicle.cpp	Sat Apr 21 08:23:57 2007 +0000
@@ -188,9 +188,9 @@
 	}
 	FOR_ALL_VEHICLES(veh) {
 		if (without_crashed && (veh->vehstatus & VS_CRASHED) != 0) continue;
-		if ((veh->type == VEH_TRAIN || veh->type == VEH_ROAD) && (z==0xFF || veh->z_pos == z)) {
-			if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 &&
-					(veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
+		if ((veh->type == VEH_TRAIN || veh->type == VEH_ROAD) && (z == 0xFF || veh->z_pos == z)) {
+			if ((veh->x_pos >> 4) >= x1 && (veh->x_pos >> 4) <= x2 &&
+					(veh->y_pos >> 4) >= y1 && (veh->y_pos >> 4) <= y2) {
 				return veh;
 			}
 		}
@@ -251,6 +251,8 @@
 						Vehicle *rotor = shadow->next;
 						rotor->cur_image = GetRotorImage(v);
 					}
+
+					UpdateAircraftCache(v);
 				}
 				break;
 			default: break;
@@ -419,7 +421,7 @@
 	int old_x = v->left_coord;
 	int old_y = v->top_coord;
 
-	new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x,y)];
+	new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x, y)];
 	old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)];
 
 	if (old_hash == new_hash) return;
@@ -568,6 +570,10 @@
 
 void DestroyVehicle(Vehicle *v)
 {
+	if (IsValidStationID(v->last_station_visited)) {
+		GetStation(v->last_station_visited)->loading_vehicles.remove(v);
+	}
+
 	if (IsEngineCountable(v)) {
 		GetPlayer(v->owner)->num_engines[v->engine_type]--;
 		if (v->owner == _local_player) InvalidateAutoreplaceWindow(v->engine_type);
@@ -767,7 +773,7 @@
 }
 
 /** Find the first cargo type that an engine can be refitted to.
- * @param engine Which engine to find cargo for.
+ * @param engine_type Which engine to find cargo for.
  * @return A climate dependent cargo type. CT_INVALID is returned if not refittable.
  */
 CargoID FindFirstRefittableCargo(EngineID engine_type)
@@ -784,7 +790,7 @@
 }
 
 /** Learn the price of refitting a certain engine
-* @param engine Which engine to refit
+* @param engine_type Which engine to refit
 * @return Price for refitting
 */
 int32 GetRefitCost(EngineID engine_type)
@@ -1837,6 +1843,17 @@
 
 	do {
 
+		if (!(flags & DC_EXEC)) {
+			/* Get the refit cost.
+			 * This is only needed when estimating as when the command is executed, the cost from the refit command is used.
+			 * This needs to be done for every single unit, so it should be done before checking if it's a multiheaded engine. */
+			CargoID new_cargo_type = GetEngineCargoType(v->engine_type);
+
+			if (new_cargo_type != v->cargo_type && new_cargo_type != CT_INVALID) {
+				total_cost += GetRefitCost(v->engine_type);
+			}
+		}
+
 		if (IsMultiheaded(v) && !IsTrainEngine(v)) {
 			/* we build the rear ends of multiheaded trains with the front ones */
 			continue;
@@ -1859,7 +1876,7 @@
 					/* We can't pay for refitting because we can't estimate refitting costs for a vehicle before it's build.
 					 * If we pay for it anyway, the cost and the estimated cost will not be the same and we will have an assert.
 					 * We need to check the whole chain if it is a train because some newgrf articulated engines can refit some units only (and not the front) */
-					DoCommand(0, w->index, v2->cargo_type | (v2->cargo_subtype << 8), flags, GetCmdRefitVeh(v));
+					total_cost += DoCommand(0, w->index, v2->cargo_type | (v2->cargo_subtype << 8), flags, GetCmdRefitVeh(v));
 					break; // We learned that the engine in question needed a refit. No need to check anymore
 				}
 			} while (v->type == VEH_TRAIN && (w2 = w2->next) != NULL && (v2 = v2->next) != NULL);
@@ -1904,7 +1921,7 @@
 /** Generates a list of vehicles inside a depot
  * Will enlarge allocated space for the list if they are too small, so it's ok to call with (pointer to NULL array, pointer to uninitised uint16, pointer to 0)
  * If one of the lists is not needed (say wagons when finding ships), all the pointers regarding that list should be set to NULL
- * @param Type type of vehicle
+ * @param type Type of vehicle
  * @param tile The tile the depot is located in
  * @param ***engine_list Pointer to a pointer to an array of vehicles in the depot (old list is freed and a new one is malloced)
  * @param *engine_list_length Allocated size of engine_list. Needs to be set to 0 when engine_list points to a NULL array
@@ -1986,11 +2003,13 @@
 * @param length_of_array informs the length allocated for sort_list. This is not the same as the number of vehicles in the list. Needs to be 0 when sort_list is NULL
 * @param type type of vehicle
 * @param owner PlayerID of owner to generate a list for
-* @param index This parameter got different meanings depending on window_type
-			VLW_STATION_LIST:  index of station to generate a list for
-			VLW_SHARED_ORDERS: index of order to generate a list for
-			VLW_STANDARD: not used
-			VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for
+* @param index This parameter has different meanings depending on window_type
+    <ul>
+      <li>VLW_STATION_LIST:  index of station to generate a list for</li>
+      <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
+      <li>VLW_STANDARD: not used<li>
+      <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
+    </ul>
 * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
 * @return the number of vehicles added to the list
 */
@@ -2088,7 +2107,7 @@
  * @param flags the flags used for DoCommand()
  * @param service should the vehicles only get service in the depots
  * @param owner PlayerID of owner of the vehicles to send
- * @param VLW_flag tells what kind of list requested the goto depot
+ * @param vlw_flag tells what kind of list requested the goto depot
  * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
  */
 int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
@@ -2219,7 +2238,7 @@
 				}
 
 				SetDParam(0, v->unitnumber);
-				AddNewsItem(string, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),	v->index, 0);
+				AddNewsItem(string, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 			}
 		}
 	}
@@ -2448,26 +2467,13 @@
 	return unit;
 }
 
-static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
+
+const Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
 {
-	SpriteID map = PAL_NONE;
 	const Player *p = GetPlayer(player);
 	LiveryScheme scheme = LS_DEFAULT;
 	CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
 
-	/* Check if we should use the colour map callback */
-	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) {
-		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
-		/* A return value of 0xC000 is stated to "use the default two-color
-		 * maps" which happens to be the failure action too... */
-		if (callback != CALLBACK_FAILED && callback != 0xC000) {
-			map = GB(callback, 0, 14);
-			/* If bit 14 is set, then the company colours are applied to the
-			 * map else it's returned as-is. */
-			if (!HASBIT(callback, 14)) return map;
-		}
-	}
-
 	/* The default livery is always available for use, but its in_use flag determines
 	 * whether any _other_ liveries are in use. */
 	if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
@@ -2544,12 +2550,35 @@
 		if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
 	}
 
+	return &p->livery[scheme];
+}
+
+
+static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
+{
+	SpriteID map = PAL_NONE;
+
+	/* Check if we should use the colour map callback */
+	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) {
+		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
+		/* A return value of 0xC000 is stated to "use the default two-color
+		 * maps" which happens to be the failure action too... */
+		if (callback != CALLBACK_FAILED && callback != 0xC000) {
+			map = GB(callback, 0, 14);
+			/* If bit 14 is set, then the company colours are applied to the
+			 * map else it's returned as-is. */
+			if (!HASBIT(callback, 14)) return map;
+		}
+	}
+
 	bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC);
 
 	if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START;
 
-	map += p->livery[scheme].colour1;
-	if (twocc) map += p->livery[scheme].colour2 * 16;
+	const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v);
+
+	map += livery->colour1;
+	if (twocc) map += livery->colour2 * 16;
 
 	return map;
 }
@@ -2899,6 +2928,7 @@
 {
 	assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP);
 	current_order.type = OT_LOADING;
+	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
 }
 
 void Vehicle::LeaveStation()
@@ -2907,4 +2937,5 @@
 	assert(current_order.type == OT_LOADING);
 	current_order.type = OT_LEAVESTATION;
 	current_order.flags = 0;
+	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
 }