script_town.cpp

Go to the documentation of this file.
00001 /* $Id: script_town.cpp 23636 2011-12-19 21:06:06Z truebrain $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../../stdafx.h"
00013 #include "script_town.hpp"
00014 #include "script_map.hpp"
00015 #include "script_cargo.hpp"
00016 #include "script_error.hpp"
00017 #include "../../town.h"
00018 #include "../../strings_func.h"
00019 #include "../../company_func.h"
00020 #include "../../station_base.h"
00021 #include "../../landscape.h"
00022 #include "table/strings.h"
00023 
00024 /* static */ int32 ScriptTown::GetTownCount()
00025 {
00026   return (int32)::Town::GetNumItems();
00027 }
00028 
00029 /* static */ bool ScriptTown::IsValidTown(TownID town_id)
00030 {
00031   return ::Town::IsValidID(town_id);
00032 }
00033 
00034 /* static */ char *ScriptTown::GetName(TownID town_id)
00035 {
00036   if (!IsValidTown(town_id)) return NULL;
00037   static const int len = 64;
00038   char *town_name = MallocT<char>(len);
00039 
00040 	::SetDParam(0, town_id);
00041   ::GetString(town_name, STR_TOWN_NAME, &town_name[len - 1]);
00042 
00043   return town_name;
00044 }
00045 
00046 /* static */ bool ScriptTown::SetText(TownID town_id, Text *text)
00047 {
00048   CCountedPtr<Text> counter(text);
00049 
00050   EnforcePrecondition(false, text != NULL);
00051   EnforcePrecondition(false, IsValidTown(town_id));
00052 
00053   return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, 0, CMD_TOWN_SET_TEXT, text->GetEncodedText());
00054 }
00055 
00056 /* static */ int32 ScriptTown::GetPopulation(TownID town_id)
00057 {
00058   if (!IsValidTown(town_id)) return -1;
00059   const Town *t = ::Town::Get(town_id);
00060   return t->population;
00061 }
00062 
00063 /* static */ int32 ScriptTown::GetHouseCount(TownID town_id)
00064 {
00065   if (!IsValidTown(town_id)) return -1;
00066   const Town *t = ::Town::Get(town_id);
00067   return t->num_houses;
00068 }
00069 
00070 /* static */ TileIndex ScriptTown::GetLocation(TownID town_id)
00071 {
00072   if (!IsValidTown(town_id)) return INVALID_TILE;
00073   const Town *t = ::Town::Get(town_id);
00074   return t->xy;
00075 }
00076 
00077 /* static */ int32 ScriptTown::GetLastMonthProduction(TownID town_id, CargoID cargo_id)
00078 {
00079   if (!IsValidTown(town_id)) return -1;
00080   if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
00081 
00082   const Town *t = ::Town::Get(town_id);
00083 
00084   return t->supplied[cargo_id].old_max;
00085 }
00086 
00087 /* static */ int32 ScriptTown::GetLastMonthSupplied(TownID town_id, CargoID cargo_id)
00088 {
00089   if (!IsValidTown(town_id)) return -1;
00090   if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
00091 
00092   const Town *t = ::Town::Get(town_id);
00093 
00094   return t->supplied[cargo_id].old_act;
00095 }
00096 
00097 /* static */ int32 ScriptTown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id)
00098 {
00099   if (!IsValidTown(town_id)) return -1;
00100   if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
00101 
00102   const Town *t = ::Town::Get(town_id);
00103   return ::ToPercent8(t->GetPercentTransported(cargo_id));
00104 }
00105 
00106 /* static */ int32 ScriptTown::GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id)
00107 {
00108   if (!IsValidTown(town_id)) return -1;
00109   if (!ScriptCargo::IsValidTownEffect(towneffect_id)) return -1;
00110 
00111   const Town *t = ::Town::Get(town_id);
00112 
00113   return t->received[towneffect_id].old_act;
00114 }
00115 
00116 /* static */ bool ScriptTown::SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, uint32 goal)
00117 {
00118   EnforcePrecondition(false, IsValidTown(town_id));
00119   EnforcePrecondition(false, ScriptCargo::IsValidTownEffect(towneffect_id));
00120 
00121   return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id | (towneffect_id << 16), goal, CMD_TOWN_CARGO_GOAL);
00122 }
00123 
00124 /* static */ uint32 ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id)
00125 {
00126   if (!IsValidTown(town_id)) return -1;
00127   if (!ScriptCargo::IsValidTownEffect(towneffect_id)) return -1;
00128 
00129   const Town *t = ::Town::Get(town_id);
00130 
00131   switch (t->goal[towneffect_id]) {
00132     case TOWN_GROWTH_WINTER:
00133       if (TileHeight(t->xy) >= GetSnowLine() && t->population > 90) return 1;
00134       return 0;
00135 
00136     case TOWN_GROWTH_DESERT:
00137       if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->population > 60) return 1;
00138       return 0;
00139 
00140     default: return t->goal[towneffect_id];
00141   }
00142 }
00143 
00144 /* static */ bool ScriptTown::SetGrowthRate(TownID town_id, uint16 days_between_town_growth)
00145 {
00146   days_between_town_growth = days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS;
00147 
00148   EnforcePrecondition(false, IsValidTown(town_id));
00149   EnforcePrecondition(false, (days_between_town_growth & TOWN_GROW_RATE_CUSTOM) == 0);
00150 
00151   return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, days_between_town_growth, CMD_TOWN_GROWTH_RATE);
00152 }
00153 
00154 /* static */ int32 ScriptTown::GetGrowthRate(TownID town_id)
00155 {
00156   if (!IsValidTown(town_id)) return false;
00157 
00158   const Town *t = ::Town::Get(town_id);
00159 
00160   return (t->growth_rate * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS;
00161 }
00162 
00163 /* static */ int32 ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile)
00164 {
00165   return ScriptMap::DistanceManhattan(tile, GetLocation(town_id));
00166 }
00167 
00168 /* static */ int32 ScriptTown::GetDistanceSquareToTile(TownID town_id, TileIndex tile)
00169 {
00170   return ScriptMap::DistanceSquare(tile, GetLocation(town_id));
00171 }
00172 
00173 /* static */ bool ScriptTown::IsWithinTownInfluence(TownID town_id, TileIndex tile)
00174 {
00175   if (!IsValidTown(town_id)) return false;
00176 
00177   const Town *t = ::Town::Get(town_id);
00178   return ((uint32)GetDistanceSquareToTile(town_id, tile) <= t->squared_town_zone_radius[0]);
00179 }
00180 
00181 /* static */ bool ScriptTown::HasStatue(TownID town_id)
00182 {
00183   if (ScriptObject::GetCompany() == OWNER_DEITY) return false;
00184   if (!IsValidTown(town_id)) return false;
00185 
00186   return ::HasBit(::Town::Get(town_id)->statues, ScriptObject::GetCompany());
00187 }
00188 
00189 /* static */ bool ScriptTown::IsCity(TownID town_id)
00190 {
00191   if (!IsValidTown(town_id)) return false;
00192 
00193   return ::Town::Get(town_id)->larger_town;
00194 }
00195 
00196 /* static */ int ScriptTown::GetRoadReworkDuration(TownID town_id)
00197 {
00198   if (!IsValidTown(town_id)) return -1;
00199 
00200   return ::Town::Get(town_id)->road_build_months;
00201 }
00202 
00203 /* static */ ScriptCompany::CompanyID ScriptTown::GetExclusiveRightsCompany(TownID town_id)
00204 {
00205   if (ScriptObject::GetCompany() == OWNER_DEITY) return ScriptCompany::COMPANY_INVALID;
00206   if (!IsValidTown(town_id)) return ScriptCompany::COMPANY_INVALID;
00207 
00208   return (ScriptCompany::CompanyID)(int8)::Town::Get(town_id)->exclusivity;
00209 }
00210 
00211 /* static */ int32 ScriptTown::GetExclusiveRightsDuration(TownID town_id)
00212 {
00213   if (!IsValidTown(town_id)) return -1;
00214 
00215   return ::Town::Get(town_id)->exclusive_counter;
00216 }
00217 
00218 /* static */ bool ScriptTown::IsActionAvailable(TownID town_id, TownAction town_action)
00219 {
00220   if (ScriptObject::GetCompany() == OWNER_DEITY) return false;
00221   if (!IsValidTown(town_id)) return false;
00222 
00223   return HasBit(::GetMaskOfTownActions(NULL, ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action);
00224 }
00225 
00226 /* static */ bool ScriptTown::PerformTownAction(TownID town_id, TownAction town_action)
00227 {
00228   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00229   EnforcePrecondition(false, IsValidTown(town_id));
00230   EnforcePrecondition(false, IsActionAvailable(town_id, town_action));
00231 
00232   return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, town_action, CMD_DO_TOWN_ACTION);
00233 }
00234 
00235 /* static */ bool ScriptTown::ExpandTown(TownID town_id, int houses)
00236 {
00237   EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY);
00238   EnforcePrecondition(false, IsValidTown(town_id));
00239   EnforcePrecondition(false, houses > 0);
00240 
00241   return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, houses, CMD_EXPAND_TOWN);
00242 }
00243 
00244 /* static */ ScriptTown::TownRating ScriptTown::GetRating(TownID town_id, ScriptCompany::CompanyID company_id)
00245 {
00246   if (!IsValidTown(town_id)) return TOWN_RATING_INVALID;
00247   ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id);
00248   if (company == ScriptCompany::COMPANY_INVALID) return TOWN_RATING_INVALID;
00249 
00250   const Town *t = ::Town::Get(town_id);
00251   if (!HasBit(t->have_ratings, company)) {
00252     return TOWN_RATING_NONE;
00253   } else if (t->ratings[company] <= RATING_APPALLING) {
00254     return TOWN_RATING_APPALLING;
00255   } else if (t->ratings[company] <= RATING_VERYPOOR) {
00256     return TOWN_RATING_VERY_POOR;
00257   } else if (t->ratings[company] <= RATING_POOR) {
00258     return TOWN_RATING_POOR;
00259   } else if (t->ratings[company] <= RATING_MEDIOCRE) {
00260     return TOWN_RATING_MEDIOCRE;
00261   } else if (t->ratings[company] <= RATING_GOOD) {
00262     return TOWN_RATING_GOOD;
00263   } else if (t->ratings[company] <= RATING_VERYGOOD) {
00264     return TOWN_RATING_VERY_GOOD;
00265   } else if (t->ratings[company] <= RATING_EXCELLENT) {
00266     return TOWN_RATING_EXCELLENT;
00267   } else {
00268     return TOWN_RATING_OUTSTANDING;
00269   }
00270 }
00271 
00272 /* static */ int ScriptTown::GetAllowedNoise(TownID town_id)
00273 {
00274   if (!IsValidTown(town_id)) return -1;
00275 
00276   const Town *t = ::Town::Get(town_id);
00277   if (_settings_game.economy.station_noise_level) {
00278     return t->MaxTownNoise() - t->noise_reached;
00279   }
00280 
00281   int num = 0;
00282   const Station *st;
00283   FOR_ALL_STATIONS(st) {
00284     if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++;
00285   }
00286   return max(0, 2 - num);
00287 }
00288 
00289 /* static */ ScriptTown::RoadLayout ScriptTown::GetRoadLayout(TownID town_id)
00290 {
00291   if (!IsValidTown(town_id)) return ROAD_LAYOUT_INVALID;
00292 
00293   return (ScriptTown::RoadLayout)((TownLayout)::Town::Get(town_id)->layout);
00294 }