# HG changeset patch # User truebrain # Date 2011-12-19 20:59:19 # Node ID ec777ff0426a77e1df074ce06f92ffa8e133bbdf # Parent 4b7ab185eacd3de22975df2ad8298bcc083f062f (svn r23620) -Add: ScriptTown::SetCargoGoal and ScriptTown::SetGrowthRate (GameScript only) diff --git a/src/command.cpp b/src/command.cpp --- a/src/command.cpp +++ b/src/command.cpp @@ -128,6 +128,8 @@ CommandProc CmdBuyCompany; CommandProc CmdFoundTown; CommandProc CmdRenameTown; CommandProc CmdDoTownAction; +CommandProc CmdTownGrowthRate; +CommandProc CmdTownCargoGoal; CommandProc CmdExpandTown; CommandProc CmdDeleteTown; @@ -265,6 +267,8 @@ static const Command _command_proc_table DEF_CMD(CmdFoundTown, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run DEF_CMD(CmdRenameTown, CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION + DEF_CMD(CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_CARGO_GOAL + DEF_CMD(CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_GROWTH_RATE DEF_CMD(CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_EXPAND_TOWN DEF_CMD(CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DELETE_TOWN diff --git a/src/command_type.h b/src/command_type.h --- a/src/command_type.h +++ b/src/command_type.h @@ -248,6 +248,8 @@ enum Commands { CMD_FOUND_TOWN, ///< found a town CMD_RENAME_TOWN, ///< rename a town CMD_DO_TOWN_ACTION, ///< do a action from the town detail window (like advertises or bribe) + CMD_TOWN_CARGO_GOAL, ///< set the goal of a cargo for a town + CMD_TOWN_GROWTH_RATE, ///< set the town growth rate CMD_EXPAND_TOWN, ///< expand a town CMD_DELETE_TOWN, ///< delete a town diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -90,7 +90,7 @@ uint32 TownGetVariable(byte variable, ui case 0xAE: return t->have_ratings; case 0xB2: return t->statues; case 0xB6: return ClampToU16(t->num_houses); - case 0xB9: return t->growth_rate; + case 0xB9: return t->growth_rate & (~TOWN_GROW_RATE_CUSTOM); case 0xBA: return ClampToU16(t->supplied[CT_PASSENGERS].new_max); case 0xBB: return GB(ClampToU16(t->supplied[CT_PASSENGERS].new_max), 8, 8); case 0xBC: return ClampToU16(t->supplied[CT_MAIL].new_max); diff --git a/src/script/api/game/game_town.hpp.sq b/src/script/api/game/game_town.hpp.sq --- a/src/script/api/game/game_town.hpp.sq +++ b/src/script/api/game/game_town.hpp.sq @@ -47,7 +47,9 @@ void SQGSTown_Register(Squirrel *engine) SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetLastMonthSupplied, "GetLastMonthSupplied", 3, ".ii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetLastMonthTransportedPercentage, "GetLastMonthTransportedPercentage", 3, ".ii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetLastMonthReceived, "GetLastMonthReceived", 3, ".ii"); + SQGSTown.DefSQStaticMethod(engine, &ScriptTown::SetCargoGoal, "SetCargoGoal", 4, ".iii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetCargoGoal, "GetCargoGoal", 3, ".ii"); + SQGSTown.DefSQStaticMethod(engine, &ScriptTown::SetGrowthRate, "SetGrowthRate", 3, ".ii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetGrowthRate, "GetGrowthRate", 2, ".i"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, ".ii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetDistanceSquareToTile, "GetDistanceSquareToTile", 3, ".ii"); diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -103,6 +103,14 @@ return t->received[towneffect_id].old_act; } +/* static */ bool ScriptTown::SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, uint32 goal) +{ + EnforcePrecondition(false, IsValidTown(town_id)); + EnforcePrecondition(false, ScriptCargo::IsValidTownEffect(towneffect_id)); + + return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id | (towneffect_id << 16), goal, CMD_TOWN_CARGO_GOAL); +} + /* static */ uint32 ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id) { if (!IsValidTown(town_id)) return -1; @@ -123,6 +131,16 @@ } } +/* static */ bool ScriptTown::SetGrowthRate(TownID town_id, uint16 days_between_town_growth) +{ + days_between_town_growth = days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS; + + EnforcePrecondition(false, IsValidTown(town_id)); + EnforcePrecondition(false, (days_between_town_growth & TOWN_GROW_RATE_CUSTOM) == 0); + + return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, days_between_town_growth, CMD_TOWN_GROWTH_RATE); +} + /* static */ int32 ScriptTown::GetGrowthRate(TownID town_id) { if (!IsValidTown(town_id)) return false; diff --git a/src/script/api/script_town.hpp b/src/script/api/script_town.hpp --- a/src/script/api/script_town.hpp +++ b/src/script/api/script_town.hpp @@ -192,6 +192,18 @@ public: static int32 GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id); /** + * Set the goal of a cargo for this town. + * @param town_id The index of the town. + * @param towneffect_id The index of the cargo. + * @param goal The new goal. + * @pre IsValidTown(town_id). + * @pre ScriptCargo::IsValidTownEffect(cargo_id). + * @return True if the action succeeded. + * @api -ai + */ + static bool SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, uint32 goal); + + /** * Get the amount of cargo that needs to be delivered (per TownEffect) for a * town to grow. All goals need to be reached before a town will grow. * @param town_id The index of the town. @@ -205,6 +217,17 @@ public: static uint32 GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id); /** + * Set the amount of days between town growth. + * @param town_id The index of the town. + * @param days_between_town_growth The amont of days between town growth. + * @pre IsValidTown(town_id). + * @return True if the action succeeded. + * @note If 'Fund Building' and 'economy.town_growth_rate' is active, the game will often set a new GrowthRate. + * @api -ai + */ + static bool SetGrowthRate(TownID town_id, uint16 days_between_town_growth); + + /** * Get the amount of days between town growth. * @param town_id The index of the town. * @pre IsValidTown(town_id). diff --git a/src/town.h b/src/town.h --- a/src/town.h +++ b/src/town.h @@ -37,6 +37,7 @@ static const uint INVALID_TOWN = 0xFFFF; static const uint TOWN_GROWTH_WINTER = 0xFFFFFFFE; ///< The town only needs this cargo in the winter (any amount) static const uint TOWN_GROWTH_DESERT = 0xFFFFFFFF; ///< The town needs the cargo for growth when on desert (any amount) +static const uint16 TOWN_GROW_RATE_CUSTOM = 0x8000; ///< If this mask is applied to Town::grow_counter, the grow_counter will not be calculated by the system (but assumed to be set by scripts) typedef Pool TownPool; extern TownPool _town_pool; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -762,7 +762,7 @@ static void TownTickHandler(Town *t) int i = t->grow_counter - 1; if (i < 0) { if (GrowTown(t)) { - i = t->growth_rate; + i = t->growth_rate & (~TOWN_GROW_RATE_CUSTOM); } else { i = 0; } @@ -2434,6 +2434,70 @@ const CargoSpec *FindFirstCargoWithTownE return NULL; } +static void UpdateTownGrowRate(Town *t); + +/** + * Change the cargo goal of a town. + * @param tile Unused. + * @param flags Type of operation. + * @param p1 various bitstuffed elements + * - p1 = (bit 0 - 15) - Town ID to cargo game of. + * - p1 = (bit 16 - 23) - TownEffect to change the game of. + * @param p2 The new goal value. + * @param text Unused. + * @return Empty cost or an error. + */ +CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + + TownEffect te = (TownEffect)GB(p1, 16, 8); + if (te < TE_BEGIN || te > TE_END) return CMD_ERROR; + + uint16 index = GB(p1, 0, 16); + Town *t = Town::GetIfValid(index); + if (t == NULL) return CMD_ERROR; + + /* Validate if there is a cargo which is the requested TownEffect */ + const CargoSpec *cargo = FindFirstCargoWithTownEffect(te); + if (cargo == NULL) return CMD_ERROR; + + if (flags & DC_EXEC) { + t->goal[te] = p2; + UpdateTownGrowRate(t); + InvalidateWindowData(WC_TOWN_VIEW, index); + } + + return CommandCost(); +} + +/** + * Change the growth rate of the town. + * @param tile Unused. + * @param flags Type of operation. + * @param p1 Town ID to cargo game of. + * @param p2 Amount of days between growth. + * @param text Unused. + * @return Empty cost or an error. + */ +CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + if ((p2 & TOWN_GROW_RATE_CUSTOM) != 0) return CMD_ERROR; + if (GB(p2, 16, 16) != 0) return CMD_ERROR; + + Town *t = Town::GetIfValid(p1); + if (t == NULL) return CMD_ERROR; + + if (flags & DC_EXEC) { + t->growth_rate = (p2 == 0) ? 0 : p2 | TOWN_GROW_RATE_CUSTOM; + UpdateTownGrowRate(t); + InvalidateWindowData(WC_TOWN_VIEW, p1); + } + + return CommandCost(); +} + /** * Expand a town (scenario editor only). * @param tile Unused. @@ -2883,6 +2947,12 @@ static void UpdateTownGrowRate(Town *t) } } + if ((t->growth_rate & TOWN_GROW_RATE_CUSTOM) != 0) { + SetBit(t->flags, TOWN_IS_FUNDED); + SetWindowDirty(WC_TOWN_VIEW, t->index); + return; + } + /** * Towns are processed every TOWN_GROWTH_TICKS ticks, and this is the * number of times towns are processed before a new building is built. @@ -2907,7 +2977,6 @@ static void UpdateTownGrowRate(Town *t) if (t->fund_buildings_months != 0) { m = _grow_count_values[0][min(n, 5)]; - t->fund_buildings_months--; } else { m = _grow_count_values[1][min(n, 5)]; if (n == 0 && !Chance16(1, 12)) return; @@ -2933,6 +3002,7 @@ static void UpdateTownAmounts(Town *t) { for (CargoID i = 0; i < NUM_CARGO; i++) t->supplied[i].NewMonth(); for (int i = TE_BEGIN; i < TE_END; i++) t->received[i].NewMonth(); + if (t->fund_buildings_months != 0) t->fund_buildings_months--; SetWindowDirty(WC_TOWN_VIEW, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -391,7 +391,7 @@ public: } if (HasBit(this->town->flags, TOWN_IS_FUNDED)) { - SetDParam(0, (this->town->growth_rate * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS); + SetDParam(0, ((this->town->growth_rate & (~TOWN_GROW_RATE_CUSTOM)) * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); } else { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_TOWN_GROW_STOPPED);