Show building preview when funding industries

This commit is contained in:
dP
2023-03-31 18:31:27 +04:00
parent cff80683a1
commit db2a20afac
5 changed files with 118 additions and 11 deletions

View File

@@ -32,6 +32,7 @@
#include "../table/airporttile_ids.h"
#include "../table/track_land.h"
#include "../table/autorail.h"
#include "../table/industry_land.h"
#include "../debug.h"
#include <set>
@@ -176,10 +177,21 @@ ObjectTileHighlight ObjectTileHighlight::make_airport_tile(SpriteID palette, Sta
return oh;
}
ObjectTileHighlight ObjectTileHighlight::make_industry_tile(SpriteID palette, IndustryGfx gfx) {
auto oh = ObjectTileHighlight(Type::INDUSTRY_TILE, palette);
oh.u.industry_tile.gfx = gfx;
return oh;
}
ObjectTileHighlight ObjectTileHighlight::make_point(SpriteID palette) {
return ObjectTileHighlight(Type::POINT, palette);
}
ObjectTileHighlight ObjectTileHighlight::make_rect(SpriteID palette) {
auto oh = ObjectTileHighlight(Type::RECT, palette);
return oh;
}
ObjectTileHighlight ObjectTileHighlight::make_numbered_rect(SpriteID palette, uint32 number) {
auto oh = ObjectTileHighlight(Type::NUMBERED_RECT, palette);
oh.u.numbered_rect.number = number;
@@ -505,16 +517,35 @@ void ObjectHighlight::UpdateTiles() {
add_track(this->tile2, this->end_tile2, this->trackdir2, PALETTE_SEL_TILE_BLUE, INVALID_TILE, INVALID_TILE);
break;
}
case Type::INDUSTRY:
this->AddTile(this->tile, ObjectTileHighlight::make_numbered_rect(CM_PALETTE_TINT_WHITE, this->ind_layout));
case Type::INDUSTRY: {
auto cost = cmd::BuildIndustry{this->tile, this->ind_type, this->ind_layout, true, 0}.call(DC_NONE);
if (cost.Succeeded()) {
const IndustrySpec *indspec = GetIndustrySpec(this->ind_type);
Debug(misc, 0, "Layout requested: {}, layout founded: {}", this->ind_layout, cost.cm.industry_layout);
if (indspec == nullptr) break;
if (cost.cm.industry_layout >= indspec->layouts.size()) break;
const IndustryTileLayout &layout = indspec->layouts[cost.cm.industry_layout];
for (const IndustryTileLayoutTile &it : layout) {
if (it.gfx == GFX_WATERTILE_SPECIALCHECK) continue;
TileIndex cur_tile = this->tile + ToTileIndexDiff(it.ti);
// WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
this->AddTile(
cur_tile,
ObjectTileHighlight::make_industry_tile(CM_PALETTE_TINT_WHITE, it.gfx)
);
}
} else {
this->AddTile(this->tile, ObjectTileHighlight::make_rect(CM_SPR_PALETTE_ZONING_RED));
}
break;
}
default:
NOT_REACHED();
}
}
void ObjectHighlight::MarkDirty() {
this->UpdateTiles();
for (const auto &kv: this->tiles) {
MarkTileDirtyByTile(kv.first);
}
@@ -793,6 +824,57 @@ void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) {
}
}
void DrawIndustryTile(SpriteID palette, const TileInfo *ti, IndustryGfx gfx) {
const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
if (gfx >= NEW_INDUSTRYTILEOFFSET) return; // TODO
// if (gfx >= NEW_INDUSTRYTILEOFFSET) {
// /* Draw the tile using the specialized method of newgrf industrytile.
// * DrawNewIndustry will return false if ever the resolver could not
// * find any sprite to display. So in this case, we will jump on the
// * substitute gfx instead. */
// if (indts->grf_prop.spritegroup[0] != nullptr && DrawNewIndustryTile(ti, ind, gfx, indts)) {
// return;
// } else {
// /* No sprite group (or no valid one) found, meaning no graphics associated.
// * Use the substitute one instead */
// if (indts->grf_prop.subst_id != INVALID_INDUSTRYTILE) {
// gfx = indts->grf_prop.subst_id;
// /* And point the industrytile spec accordingly */
// indts = GetIndustryTileSpec(gfx);
// }
// }
// }
const DrawBuildingsTileStruct *dits = &_industry_draw_tile_data[gfx << 2 | INDUSTRY_COMPLETED];
SpriteID image = dits->ground.sprite;
/* DrawFoundation() modifies ti->z and ti->tileh */
// if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
/* If the ground sprite is the default flat water sprite, draw also canal/river borders.
* Do not do this if the tile's WaterClass is 'land'. */
// if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
// DrawWaterClassGround(ti);
// } else {
DrawGroundSprite(image, GroundSpritePaletteTransform(image, palette, PALETTE_RECOLOUR_START));
// }
/* Add industry on top of the ground? */
image = dits->building.sprite;
if (image != 0) {
AddSortableSpriteToDraw(image, palette,
ti->x + dits->subtile_x,
ti->y + dits->subtile_y,
dits->width,
dits->height,
dits->dz,
ti->z,
false);
}
}
enum SignalOffsets { // from rail_cmd.cpp
SIGNAL_TO_SOUTHWEST,
SIGNAL_TO_NORTHEAST,
@@ -970,9 +1052,15 @@ void ObjectHighlight::Draw(const TileInfo *ti) {
case ObjectTileHighlight::Type::AIRPORT_TILE:
DrawAirportTile(oth.palette, ti, oth.u.airport_tile.gfx);
break;
case ObjectTileHighlight::Type::INDUSTRY_TILE:
DrawIndustryTile(oth.palette, ti, oth.u.industry_tile.gfx);
break;
case ObjectTileHighlight::Type::POINT:
DrawSelectionPoint(oth.palette, ti);
break;
case ObjectTileHighlight::Type::RECT:
DrawTileSelectionRect(ti, oth.palette);
break;
case ObjectTileHighlight::Type::NUMBERED_RECT: {
DrawTileSelectionRect(ti, oth.palette);
ViewportSign sign;
@@ -1374,7 +1462,8 @@ bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
if (_thd.select_proc == DDSP_BUILD_STATION || _thd.select_proc == DDSP_BUILD_BUSSTOP
|| _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT
|| _thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT || _thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) {
|| _thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT || _thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT
|| _thd.select_proc == CM_DDSP_FUND_INDUSTRY) {
// handled by DrawTileZoning
return true;
}
@@ -1503,6 +1592,7 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
if (force_new || _thd.cm != _thd.cm_new) {
_thd.cm.MarkDirty();
_thd.cm = _thd.cm_new;
_thd.cm.UpdateTiles();
_thd.cm.MarkDirty();
}
return new_drawstyle;

View File

@@ -46,7 +46,9 @@ public:
ROAD_DEPOT,
AIRPORT_TILE,
INDUSTRY_TILE,
POINT,
RECT,
NUMBERED_RECT,
END,
};
@@ -92,6 +94,9 @@ public:
struct {
StationGfx gfx;
} airport_tile;
struct {
IndustryGfx gfx;
} industry_tile;
struct {
uint32 number;
} numbered_rect;
@@ -108,7 +113,9 @@ public:
static ObjectTileHighlight make_road_stop(SpriteID palette, RoadType roadtype, DiagDirection ddir, bool is_truck);
static ObjectTileHighlight make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir);
static ObjectTileHighlight make_airport_tile(SpriteID palette, StationGfx gfx);
static ObjectTileHighlight make_industry_tile(SpriteID palette, IndustryGfx gfx);
static ObjectTileHighlight make_point(SpriteID palette);
static ObjectTileHighlight make_rect(SpriteID palette);
static ObjectTileHighlight make_numbered_rect(SpriteID palette, uint32 number);
};
@@ -257,7 +264,6 @@ protected:
std::vector<DetachedHighlight> sprites = {};
void AddTile(TileIndex tile, ObjectTileHighlight &&oh);
// void AddSprite(TileIndex tile, ObjectTileHighlight &&oh);
void UpdateTiles();
void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track);
public:
@@ -278,6 +284,7 @@ public:
void Draw(const TileInfo *ti);
void DrawOverlay(DrawPixelInfo *dpi);
void UpdateTiles();
void MarkDirty();
};

View File

@@ -15,6 +15,8 @@
#include "tile_type.h"
#include <vector>
#include "citymania/extensions/cmext_commandcost.hpp"
struct GRFFile;
/**
@@ -32,6 +34,8 @@ class CommandCost {
static uint32 textref_stack[16];
public:
citymania::ext::CommandCost cm;
/**
* Creates a command cost return with no cost and no error
*/

View File

@@ -2102,6 +2102,7 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i
for (size_t j = 0; j < num_layouts; j++) {
layout = (layout + 1) % num_layouts;
ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), calltype, &ind);
ret.cm.industry_layout = layout;
if (ret.Succeeded()) break;
}
if (ret.Succeeded()) break;
@@ -2124,6 +2125,7 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i
for (size_t i = 0; i < num_layouts; i++) {
layout = (layout + 1) % num_layouts;
ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
ret.cm.industry_layout = layout;
if (ret.Succeeded()) break;
}
@@ -2135,7 +2137,9 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i
AdvertiseIndustryOpening(ind);
}
return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
auto cm_ret = CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
cm_ret.cm.industry_layout = ret.cm.industry_layout;
return cm_ret;
}
/**

View File

@@ -688,10 +688,11 @@ public:
if (y < this->count) { // Is it within the boundaries of available data?
this->selected_index = y;
_cm_funding_type = this->selected_type = this->index[y];
_cm_funding_layout = 0;
citymania::SetIndustryForbiddenTilesHighlight(this->selected_type);
const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type);
_cm_funding_layout = (indsp == nullptr ? 0 : InteractiveRandomRange((uint32)indsp->layouts.size()));
citymania::SetIndustryForbiddenTilesHighlight(this->selected_type);
this->SetDirty();
if (_thd.GetCallbackWnd() == this &&
@@ -749,8 +750,8 @@ public:
/* We do not need to protect ourselves against "Random Many Industries" in this mode */
const IndustrySpec *indsp = GetIndustrySpec(this->selected_type);
uint32 seed = InteractiveRandom();
uint32 layout_index = InteractiveRandomRange((uint32)indsp->layouts.size());
if (_cm_funding_layout > 0) layout_index = _cm_funding_layout - 1;
// uint32 layout_index = InteractiveRandomRange((uint32)indsp->layouts.size());
uint32 layout_index = _cm_funding_layout;
if (_game_mode == GM_EDITOR) {
/* Show error if no town exists at all */
@@ -769,6 +770,7 @@ public:
cur_company.Restore();
old_generating_world.Restore();
_ignore_restrictions = false;
_cm_funding_layout = InteractiveRandomRange((uint32)indsp->layouts.size());
} else {
success = Command<CMD_BUILD_INDUSTRY>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, this->selected_type, layout_index, false, seed);
}
@@ -830,7 +832,7 @@ public:
const IndustrySpec *indspec = GetIndustrySpec(this->selected_type);
size_t num_layouts = indspec->layouts.size();
MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
_cm_funding_layout = (_cm_funding_layout + 1) % (num_layouts + 1);
_cm_funding_layout = (_cm_funding_layout + 1) % num_layouts;
return ES_HANDLED;
} else return ES_NOT_HANDLED;
}