Index: src/station.cpp =================================================================== --- src/station.cpp (revision 24178) +++ src/station.cpp (working copy) @@ -169,6 +169,43 @@ } /** + * Called when happen ctrl+click on row in StationView. + * Delete this item from current acceptance of production. + * Two parts: when click first time just stop get new production from indestries. + * On second click clear that cargo list on this station. + * @param cargo_type_to_drop CargoID that need to be dropped on this station. + * @param waitind Click happen in WaitingCargo list or not. + */ +void Station::ChangeAcceptance(CargoID cargo_type, bool waiting) +{ + GoodsEntry &ge = this->goods[cargo_type]; + + if (waiting) { + if (HasBit(ge.acceptance_pickup, GoodsEntry::GES_PICKUP)) { + /* Stop getting new cargoes from industry around*/ + ClrBit(ge.acceptance_pickup, GoodsEntry::GES_PICKUP); + ge.days_since_pickup = 255; + ge.last_speed = 0; + ge.last_age = 255; + ge.rating = ge.rating * 0.5; + } + else { + /* Clear this cargo list. Station will be completely empty of this type of cargo. */ + ge.cargo.Truncate(0); + } + } + else { + if (!HasBit(ge.acceptance_pickup, GoodsEntry::GES_PICKUP)) { + /* Start getting new cargoes from industry around */ + SetBit(ge.acceptance_pickup, GoodsEntry::GES_PICKUP); + ge.days_since_pickup = 100; // Some penalties: vehicle on station is still good thing. + ge.last_speed = 1; + ge.last_age = 50; + ge.rating = ge.rating * 0.8; + } + } +} + +/** * Marks the tiles of the station as dirty. * * @ingroup dirty Index: src/command.cpp =================================================================== --- src/command.cpp (revision 24178) +++ src/command.cpp (working copy) @@ -182,6 +182,7 @@ CommandProc CmdSetTimetableStart; CommandProc CmdOpenCloseAirport; +CommandProc CmdChangeStationAcceptance; #define DEF_CMD(proc, flags, type) {proc, #proc, (CommandFlags)flags, type} @@ -326,6 +327,8 @@ DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_TIMETABLE_START DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT + DEF_CMD(CmdChangeStationAcceptance, 0, CMDT_OTHER_MANAGEMENT ), // CMD_CHANGE_STATION_ACCEPTANCE + }; /*! Index: src/station_gui.cpp =================================================================== --- src/station_gui.cpp (revision 24178) +++ src/station_gui.cpp (working copy) @@ -825,6 +825,8 @@ struct StationViewWindow : public Window { uint32 cargo; ///< Bitmask of cargo types to expand uint16 cargo_rows[NUM_CARGO]; ///< Header row for each cargo type + bool stdacceptratings; ///< Standart or extended type of ACCEPTRATINGS list. + CargoArray cargo_around; ///< Array of extra cargo that not visible in standart view. uint expand_shrink_width; ///< The width allocated to the expand/shrink 'button' int rating_lines; ///< Number of lines in the cargo ratings view. int accepts_lines; ///< Number of lines in the accepted cargo view. @@ -840,6 +842,7 @@ { this->rating_lines = ALH_RATING; this->accepts_lines = ALH_ACCEPTS; + this->stdacceptratings = true; this->CreateNestedTree(desc); this->vscroll = this->GetScrollbar(WID_SV_SCROLLBAR); @@ -917,7 +920,7 @@ return; } } else { - int lines = this->DrawCargoRatings(r); + int lines = this->stdacceptratings ? this->DrawCargoRatings(r) : this->DrawExtraCargoRatings(r); if (lines > this->rating_lines) { // Resize the widget, and perform re-initialization of the window. this->rating_lines = lines; this->ReInit(); @@ -988,7 +991,6 @@ break; } } - if (!added) cargolist->push_back(CargoData(i, cp->SourceStation(), cp->Count())); } } @@ -1048,7 +1050,6 @@ SetDParam(2, cd->source); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_EN_ROUTE_FROM, TC_FROMSTRING, SA_RIGHT); } - y += FONT_HEIGHT_NORMAL; } } @@ -1089,7 +1090,39 @@ FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { const GoodsEntry *ge = &st->goods[cs->Index()]; if (!HasBit(ge->acceptance_pickup, GoodsEntry::GES_PICKUP)) continue; + SetDParam(0, cs->name); + SetDParam(2, ToPercent8(ge->rating)); + SetDParam(1, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); + DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT - 6, y, STR_STATION_VIEW_CARGO_RATING); + y += FONT_HEIGHT_NORMAL; + } + return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + } + + /** + * Draw cargo ratings that is not in the standart #WID_SV_ACCEPT_RATING_LIST widget. + * @param r Rectangle of the widget. + * @return Number of lines needed for drawing the cargo ratings. + */ + int DrawExtraCargoRatings(const Rect &r) + { + const Station *st = Station::Get(this->window_number); + Rect sr = st->GetCatchmentRect(); + cargo_around = GetProductionAroundTiles(TileXY(sr.left, sr.top), sr.right - sr.left + 1, sr.bottom - sr.top + 1, 0); + int y = r.top + WD_FRAMERECT_TOP; + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_CARGO_RATINGS_TITLE); + y += FONT_HEIGHT_NORMAL; + + /* Stop drawing if there no any production around */ + if (cargo_around.GetCount() == 0) return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + + CargoID counter = 0; /* Count rows of finded industries */ + const CargoSpec *cs; + FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + const GoodsEntry *ge = &st->goods[cs->Index()]; + if (HasBit(ge->acceptance_pickup, GoodsEntry::GES_PICKUP) || cargo_around[cs->Index()] == 0) continue; + cargo_around[cs->Index()] = ++counter; SetDParam(0, cs->name); SetDParam(2, ToPercent8(ge->rating)); SetDParam(1, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); @@ -1099,14 +1132,32 @@ return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); } + void HandleAcceptRatingClick(int row) + { + if (row == 0 || !_ctrl_pressed) return; + + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (this->cargo_around[c] == (uint16)row) { + DoCommandP(0, this->window_number , c, CMD_CHANGE_STATION_ACCEPTANCE); + break; + } + } + } + void HandleCargoWaitingClick(int row) { if (row == 0) return; - + for (CargoID c = 0; c < NUM_CARGO; c++) { if (this->cargo_rows[c] == row) { - ToggleBit(this->cargo, c); - this->SetWidgetDirty(WID_SV_WAITING); + /* Check for ctrl-click. If not - do thing as when old good times. */ + if (!_ctrl_pressed) { + ToggleBit(this->cargo, c); + } + else { + /* If ctrl-click happen - stop accepting it/delete this cargo from list. */ + DoCommandP(0, this->window_number , c | 0x0100, CMD_CHANGE_STATION_ACCEPTANCE); + } break; } } @@ -1115,9 +1166,29 @@ virtual void OnClick(Point pt, int widget, int click_count) { switch (widget) { - case WID_SV_WAITING: - this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL)); + case WID_SV_WAITING: { + if (click_count == 1) { + this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL)); + } + else { + /* Toggle draw list with std/extra oprions */ + this->stdacceptratings = this->stdacceptratings ? false : true; + } + this->SetWidgetDirty(WID_SV_WAITING); + this->SetWidgetDirty(WID_SV_ACCEPT_RATING_LIST); break; + } + + case WID_SV_ACCEPT_RATING_LIST: { + if (click_count == 1) { + this->HandleAcceptRatingClick(this->GetRowFromWidget(pt.y, WID_SV_ACCEPT_RATING_LIST, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL)); + } + else { + this->stdacceptratings = this->stdacceptratings ? false : true; + } + this->SetWidgetDirty(WID_SV_ACCEPT_RATING_LIST); + break; + } case WID_SV_LOCATION: if (_ctrl_pressed) { Index: src/station_base.h =================================================================== --- src/station_base.h (revision 24178) +++ src/station_base.h (working copy) @@ -231,7 +231,8 @@ ~Station(); void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy); - + void ChangeAcceptance(CargoID cargo_type, bool waiting); + void MarkTilesDirty(bool cargo_change) const; void UpdateVirtCoord(); Index: src/station_cmd.cpp =================================================================== --- src/station_cmd.cpp (revision 24178) +++ src/station_cmd.cpp (working copy) @@ -618,6 +618,35 @@ SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_ACCEPT_RATING_LIST); } +/* + * Remove or add cargo type from cargolist of this station. + * @param tile unused + * @param flags Operation to perform + * @param p1 StationID + * @param p2 CargoID and flag of from what widget command comes. 00FF - cargo mask, FF00 - flag mask + * @param text unused + * @return The cost in case of success, or an error code if it failed. + */ + +CommandCost CmdChangeStationAcceptance(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (!Station::IsValidID(p1)) return CMD_ERROR; + Station *st = Station::Get(p1); + + CommandCost ret = CheckOwnership(st->owner); + if (ret.Failed()) return ret; + + /* Determine in what widget click happen: WID_SV_WAITING have mask 0100, WID_SV_ACCEPT_RATING_LIST in other case */ + bool waiting; + waiting = (p2 & 0x0100) ? true : false; + p2 &= 0x00FF; + + if (flags & DC_EXEC) { + st->ChangeAcceptance(p2, waiting); + } + return CommandCost(); +} + static void UpdateStationSignCoord(BaseStation *st) { const StationRect *r = &st->rect; Index: src/command_type.h =================================================================== --- src/command_type.h (revision 24178) +++ src/command_type.h (working copy) @@ -303,6 +303,7 @@ CMD_SET_TIMETABLE_START, ///< set the date that a timetable should start CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft + CMD_CHANGE_STATION_ACCEPTANCE, ///< stop accepting/remove cargo from nearby industry CMD_END, ///< Must ALWAYS be on the end of this list!! (period) };