Ejemplo n.º 1
0
/** Refits a ship to the specified cargo type.
 * @param tile unused
 * @param flags type of operation
 * @param p1 vehicle ID of the ship to refit
 * @param p2 various bitstuffed elements
 * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF)
 * - p2 = (bit 8-15) - the new cargo subtype to refit to
 * - p2 = (bit 16) - refit only this vehicle (ignored)
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdRefitShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	CargoID new_cid = GB(p2, 0, 8); // gets the cargo number
	byte new_subtype = GB(p2, 8, 8);

	Ship *v = Ship::GetIfValid(p1);

	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
	if (!v->IsStoppedInDepot()) return_cmd_error(STR_ERROR_SHIP_MUST_BE_STOPPED_IN_DEPOT);
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_REFIT_DESTROYED_VEHICLE);

	/* Check cargo */
	if (new_cid >= NUM_CARGO) return CMD_ERROR;

	CommandCost cost = RefitVehicle(v, true, new_cid, new_subtype, flags);

	if (flags & DC_EXEC) {
		v->colourmap = PAL_NONE; // invalidate vehicle colour map
		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
		SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
		InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
	}
	v->InvalidateNewGRFCacheOfChain(); // always invalidate; querycost might have filled it

	return cost;

}
Ejemplo n.º 2
0
/**
 * Refits a vehicle to the specified cargo type.
 * @param tile unused
 * @param flags type of operation
 * @param p1 vehicle ID to refit
 * @param p2 various bitstuffed elements
 * - p2 = (bit 0-4)   - New cargo type to refit to.
 * - p2 = (bit 6)     - Automatic refitting.
 * - p2 = (bit 7)     - Refit only this vehicle. Used only for cloning vehicles.
 * - p2 = (bit 8-15)  - New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
 * - p2 = (bit 16-23) - Number of vehicles to refit (not counting articulated parts). Zero means all vehicles.
 *                      Only used if "refit only this vehicle" is false.
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	Vehicle *v = Vehicle::GetIfValid(p1);
	if (v == NULL) return CMD_ERROR;

	/* Don't allow disasters and sparks and such to be refitted.
	 * We cannot check for IsPrimaryVehicle as autoreplace also refits in free wagon chains. */
	if (!IsCompanyBuildableVehicleType(v->type)) return CMD_ERROR;

	Vehicle *front = v->First();

	CommandCost ret = CheckOwnership(front->owner);
	if (ret.Failed()) return ret;

	bool auto_refit = HasBit(p2, 6);

	/* Don't allow shadows and such to be refitted. */
	if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
	/* Allow auto-refitting only during loading and normal refitting only in a depot. */
	if ((!auto_refit || !front->current_order.IsType(OT_LOADING)) && !front->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
	if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);

	/* Check cargo */
	CargoID new_cid = GB(p2, 0, 5);
	byte new_subtype = GB(p2, 8, 8);
	if (new_cid >= NUM_CARGO) return CMD_ERROR;

	/* For ships and aircrafts there is always only one. */
	bool only_this = HasBit(p2, 7) || front->type == VEH_SHIP || front->type == VEH_AIRCRAFT;
	uint8 num_vehicles = GB(p2, 16, 8);

	CommandCost cost = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit);

	if (flags & DC_EXEC) {
		/* Update the cached variables */
		switch (v->type) {
			case VEH_TRAIN:
				Train::From(front)->ConsistChanged(auto_refit);
				break;
			case VEH_ROAD:
				RoadVehUpdateCache(RoadVehicle::From(front), auto_refit);
				if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) RoadVehicle::From(front)->CargoChanged();
				break;

			case VEH_SHIP:
				v->InvalidateNewGRFCacheOfChain();
				v->colourmap = PAL_NONE; // invalidate vehicle colour map
				Ship::From(v)->UpdateCache();
				break;

			case VEH_AIRCRAFT:
				v->InvalidateNewGRFCacheOfChain();
				v->colourmap = PAL_NONE; // invalidate vehicle colour map
				UpdateAircraftCache(Aircraft::From(v), true);
				break;

			default: NOT_REACHED();
		}

		InvalidateWindowData(WC_VEHICLE_DETAILS, front->index);
		SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
		InvalidateWindowClassesData(GetWindowClassForVehicleType(v->type), 0);
	} else {
		/* Always invalidate the cache; querycost might have filled it. */
		v->InvalidateNewGRFCacheOfChain();
	}

	return cost;
}