/** * Build a ship. * @param tile tile of the depot where ship is built. * @param flags type of operation. * @param e the engine to build. * @param data unused. * @param ret[out] the vehicle that has been built. * @return the cost of this operation or an error. */ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) { tile = GetShipDepotNorthTile(tile); if (flags & DC_EXEC) { int x; int y; const ShipVehicleInfo *svi = &e->u.ship; Ship *v = new Ship(); *ret = v; v->owner = _current_company; v->tile = tile; x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; v->x_pos = x; v->y_pos = y; v->z_pos = GetSlopeZ(x, y); v->UpdateDeltaXY(v->direction); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = svi->image_index; v->cargo_type = e->GetDefaultCargoType(); v->cargo_cap = svi->capacity; v->last_station_visited = INVALID_STATION; v->engine_type = e->index; v->reliability = e->reliability; v->reliability_spd_dec = e->reliability_spd_dec; v->max_age = e->GetLifeLengthInDays(); _new_vehicle_id = v->index; v->state = TRACK_BIT_DEPOT; v->service_interval = Company::Get(_current_company)->settings.vehicle.servint_ships; v->date_of_last_service = _date; v->build_year = _cur_year; v->cur_image = SPR_IMG_QUERY; v->random_bits = VehicleRandomBits(); v->UpdateCache(); if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->InvalidateNewGRFCacheOfChain(); v->cargo_cap = GetVehicleCapacity(v); v->InvalidateNewGRFCacheOfChain(); VehicleMove(v, false); } return CommandCost(); }
/** * Refits a vehicle (chain). * This is the vehicle-type independent part of the CmdRefitXXX functions. * @param v The vehicle to refit. * @param only_this Whether to only refit this vehicle, or the whole chain. * @param new_cid Cargotype to refit to * @param new_subtype Cargo subtype to refit to * @param flags Command flags * @return refit cost; or CMD_ERROR if no vehicle was actually refitable to the cargo */ CommandCost RefitVehicle(Vehicle *v, bool only_this, CargoID new_cid, byte new_subtype, DoCommandFlag flags) { CommandCost cost(v->GetExpenseType(false)); uint total_capacity = 0; v->InvalidateNewGRFCacheOfChain(); for (; v != NULL; v = (only_this ? NULL : v->Next())) { const Engine *e = Engine::Get(v->engine_type); if (!e->CanCarryCargo() || !HasBit(e->info.refit_mask, new_cid)) continue; /* Back up the vehicle's cargo type */ CargoID temp_cid = v->cargo_type; byte temp_subtype = v->cargo_subtype; v->cargo_type = new_cid; v->cargo_subtype = new_subtype; uint16 mail_capacity; uint amount = GetVehicleCapacity(v, &mail_capacity); total_capacity += amount; /* Restore the original cargo type */ v->cargo_type = temp_cid; v->cargo_subtype = temp_subtype; if (new_cid != v->cargo_type) { cost.AddCost(GetRefitCost(v->engine_type)); } if (flags & DC_EXEC) { v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0); v->cargo_type = new_cid; v->cargo_cap = amount; v->cargo_subtype = new_subtype; if (v->type == VEH_AIRCRAFT) { Vehicle *u = v->Next(); u->cargo_cap = mail_capacity; u->cargo.Truncate(mail_capacity); } } } _returned_refit_capacity = total_capacity; return cost; }
/** Build a ship. * @param tile tile of depot where ship is built * @param flags type of operation * @param p1 ship type being built (engine) * @param p2 unused * @param text unused * @return the cost of this operation or an error */ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { UnitID unit_num; if (!IsEngineBuildable(p1, VEH_SHIP, _current_company)) return_cmd_error(STR_ERROR_SHIP_NOT_AVAILABLE); const Engine *e = Engine::Get(p1); CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost()); /* Engines without valid cargo should not be available */ if (e->GetDefaultCargoType() == CT_INVALID) return CMD_ERROR; if (flags & DC_QUERY_COST) return value; /* The ai_new queries the vehicle cost before building the route, * so we must check against cheaters no sooner than now. --pasky */ if (!IsShipDepotTile(tile)) return CMD_ERROR; if (!IsTileOwner(tile, _current_company)) return CMD_ERROR; unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_SHIP); if (!Vehicle::CanAllocateItem() || unit_num > _settings_game.vehicle.max_ships) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); if (flags & DC_EXEC) { int x; int y; const ShipVehicleInfo *svi = &e->u.ship; Ship *v = new Ship(); v->unitnumber = unit_num; v->owner = _current_company; v->tile = tile; x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; v->x_pos = x; v->y_pos = y; v->z_pos = GetSlopeZ(x, y); v->UpdateDeltaXY(v->direction); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = svi->image_index; v->cargo_type = e->GetDefaultCargoType(); v->cargo_cap = svi->capacity; v->value = value.GetCost(); v->last_station_visited = INVALID_STATION; v->max_speed = svi->max_speed; v->engine_type = p1; v->reliability = e->reliability; v->reliability_spd_dec = e->reliability_spd_dec; v->max_age = e->GetLifeLengthInDays(); _new_vehicle_id = v->index; v->state = TRACK_BIT_DEPOT; v->service_interval = Company::Get(_current_company)->settings.vehicle.servint_ships; v->date_of_last_service = _date; v->build_year = _cur_year; v->cur_image = SPR_IMG_QUERY; v->random_bits = VehicleRandomBits(); if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->InvalidateNewGRFCacheOfChain(); v->cargo_cap = GetVehicleCapacity(v); v->InvalidateNewGRFCacheOfChain(); VehicleMove(v, false); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); InvalidateWindowClassesData(WC_SHIPS_LIST, 0); SetWindowDirty(WC_COMPANY, v->owner); if (IsLocalCompany()) { InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Ship window } Company::Get(_current_company)->num_engines[p1]++; } return value; }