# HG changeset patch # User celestar # Date 1181735114 0 # Node ID 0b8b245a2391891b03002951b531d8c3cb8d483c # Parent 0b2aebc8283ed7722172b5c61fa5d6456fe7f64a (svn r10135) [gamebalance] -Sync: r9700:9900 from trunk diff -r 0b2aebc8283e -r 0b8b245a2391 Makefile.src.in --- a/Makefile.src.in Wed Jun 13 11:17:30 2007 +0000 +++ b/Makefile.src.in Wed Jun 13 11:45:14 2007 +0000 @@ -28,6 +28,7 @@ SORT = !!SORT!! REVISION = !!REVISION!! AWK = !!AWK!! +GCC295 = !!GCC295!! CONFIG_CACHE_COMPILER = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_COMPILER!! CONFIG_CACHE_LINKER = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_LINKER!! CONFIG_CACHE_ENDIAN = $(SRC_OBJS_DIR)/!!CONFIG_CACHE_ENDIAN!! @@ -51,6 +52,17 @@ ENDIAN_TARGETS := endian_target.h $(ENDIAN_CHECK) +# This 'sed' basicly just removes 'const' from the line if it is a 2+D array +# For more information, please check: +# http://maillist.openttd.org/pipermail/devs/2007-April/000284.html +# http://maillist.openttd.org/pipermail/devs/2007-February/000248.html +GCC295_FIX=sed -r 's/^(\t*)(.*)( const )([A-Za-z0-9_ ]+(\[.*\]){2,})(( = \{)|(;))(.*)$$/\1\2 \4\6\8\9/g' +# This 'sed' removes the 3rd '4' in the # lines of the -E output of +# gcc 2.95.3 and lower, as it should indicate that it is a C-linkage, but the +# compiler can't handle that information (just don't ask). So we remove it +# and then it compiles happily and without bitching :) +GCC295_FIX_2=sed -e 's|\(^\# [0-9][0-9]* "[^"]*"[ 0-9]*\) 4$$|\1|g' + # Check if we want to show what we are doing ifdef VERBOSE Q = @@ -210,7 +222,11 @@ $(OBJS_CPP): %.o: $(SRC_DIR)/%.cpp $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' +ifeq ($(GCC295), 1) + $(Q)$(CXX_HOST) -E $(CFLAGS) $< | $(GCC295_FIX) | $(GCC295_FIX_2) | $(CXX_HOST) $(CFLAGS) -c -o $@ -x c++ - +else $(Q)$(CXX_HOST) $(CFLAGS) -c -o $@ $< +endif $(OBJS_MM): %.o: $(SRC_DIR)/%.mm $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.mm=%.mm)' diff -r 0b2aebc8283e -r 0b8b245a2391 bin/data/group.grf Binary file bin/data/group.grf has changed diff -r 0b2aebc8283e -r 0b8b245a2391 bin/data/openttd.grf Binary file bin/data/openttd.grf has changed diff -r 0b2aebc8283e -r 0b8b245a2391 config.lib --- a/config.lib Wed Jun 13 11:17:30 2007 +0000 +++ b/config.lib Wed Jun 13 11:45:14 2007 +0000 @@ -673,6 +673,13 @@ CC_CFLAGS="$CC_CFLAGS -Wstrict-prototypes" fi + gcc295="" + if [ "$cc_version" = 29 ]; then + # Make sure we mark GCC 2.95 flag for Makefile.src.in, as we + # need a lovely hack there to make it compile correctly. + gcc295="1" + fi + if [ $cc_version -ge 30 ]; then CFLAGS="$CFLAGS -W -Wno-unused-parameter" fi @@ -1853,6 +1860,7 @@ s#!!CONFIGURE_FILES!!#$CONFIGURE_FILES#g; s#!!REVISION!!#$revision#g; s#!!AWK!!#$awk#g; + s#!!GCC295!!#$gcc295#g; s#!!ENABLE_INSTALL!!#$enable_install#g; " } diff -r 0b2aebc8283e -r 0b8b245a2391 projects/openttd.vcproj --- a/projects/openttd.vcproj Wed Jun 13 11:17:30 2007 +0000 +++ b/projects/openttd.vcproj Wed Jun 13 11:45:14 2007 +0000 @@ -459,6 +459,9 @@ RelativePath=".\..\src\gfxinit.h"> + + + + + + + + + + + + + + + + + + @@ -920,10 +924,18 @@ > + + + + @@ -1115,6 +1127,10 @@ RelativePath=".\..\src\window.h" > + + + + @@ -1276,6 +1296,10 @@ > + + @@ -1476,10 +1500,18 @@ > + + + + diff -r 0b2aebc8283e -r 0b8b245a2391 source.list --- a/source.list Wed Jun 13 11:17:30 2007 +0000 +++ b/source.list Wed Jun 13 11:45:14 2007 +0000 @@ -120,6 +120,7 @@ genworld.h gfx.h gfxinit.h +group.h gui.h hal.h heightmap.h @@ -140,7 +141,9 @@ network/network_udp.h newgrf.h newgrf_callbacks.h +newgrf_canal.h newgrf_cargo.h +newgrf_commons.h newgrf_config.h newgrf_engine.h newgrf_house.h @@ -189,6 +192,7 @@ sound/win32_s.h video/win32_v.h window.h +zoom.hpp # GUI Source Code aircraft_gui.cpp @@ -201,6 +205,7 @@ engine_gui.cpp genworld_gui.cpp graph_gui.cpp +group_gui.cpp industry_gui.cpp intro_gui.cpp main_gui.cpp @@ -231,6 +236,7 @@ clear_cmd.cpp disaster_cmd.cpp dummy_land.cpp +group_cmd.cpp industry_cmd.cpp misc_cmd.cpp order_cmd.cpp @@ -284,7 +290,9 @@ # NewGRF newgrf.cpp +newgrf_canal.cpp newgrf_cargo.cpp +newgrf_commons.cpp newgrf_config.cpp newgrf_engine.cpp newgrf_house.cpp diff -r 0b2aebc8283e -r 0b8b245a2391 src/ai/default/default.cpp --- a/src/ai/default/default.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/ai/default/default.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -543,6 +543,7 @@ static void AiFindRandomIndustryRoute(FoundRoute *fr) { Industry* i; + const IndustrySpec *indsp; uint32 r; CargoID cargo; @@ -556,8 +557,9 @@ if (i == NULL) return; // pick a random produced cargo - cargo = i->produced_cargo[0]; - if (r & 1 && i->produced_cargo[1] != CT_INVALID) cargo = i->produced_cargo[1]; + indsp = GetIndustrySpec(i->type); + cargo = indsp->produced_cargo[0]; + if (r & 1 && indsp->produced_cargo[1] != CT_INVALID) cargo = indsp->produced_cargo[1]; fr->cargo = cargo; @@ -567,12 +569,16 @@ if (cargo != CT_GOODS && cargo != CT_FOOD) { // pick a dest, and see if it can receive Industry* i2 = AiFindRandomIndustry(); - - if (i2 == NULL || i == i2 || ( - i2->accepts_cargo[0] != cargo && - i2->accepts_cargo[1] != cargo && - i2->accepts_cargo[2] != cargo) - ) { + if (i2 == NULL) { + return; + } + + indsp = GetIndustrySpec(i2->type); + + if (i == i2 || + (indsp->accepts_cargo[0] != cargo && + indsp->accepts_cargo[1] != cargo && + indsp->accepts_cargo[2] != cargo)) { return; } @@ -664,9 +670,10 @@ } } else { const Industry* i = (const Industry*)fr->from; - - if (i->pct_transported[fr->cargo != i->produced_cargo[0]] > 0x99 || - i->total_production[fr->cargo != i->produced_cargo[0]] == 0) { + const IndustrySpec *indsp = GetIndustrySpec(i->type); + + if (i->pct_transported[fr->cargo != indsp->produced_cargo[0]] > 0x99 || + i->total_production[fr->cargo != indsp->produced_cargo[0]] == 0) { return false; } } @@ -1792,17 +1799,15 @@ p->ai.state_mode = -p->ai.state_mode; } } else if (CheckPlayerHasMoney(cost)) { - int32 r; // player has money, build it. aib->cur_building_rule = rule; - r = AiDoBuildDefaultRailTrack( + AiDoBuildDefaultRailTrack( aib->use_tile, _default_rail_track_data[rule]->data, p->ai.railtype_to_use, DC_EXEC | DC_NO_TOWN_RATING ); - assert(!CmdFailed(r)); } } while (++aib, --j); } @@ -2574,11 +2579,11 @@ if (p->mode == 2) { if (IsTileType(c, MP_STREET) && GetRoadTileType(c) == ROAD_TILE_NORMAL && - (GetRoadBits(c) & p->attr) != 0) { + (GetRoadBits(c, ROADTYPE_ROAD) & p->attr) != 0) { roadflag |= 2; // all bits are already built? - if ((GetRoadBits(c) & p->attr) == p->attr) continue; + if ((GetRoadBits(c, ROADTYPE_ROAD) & p->attr) == p->attr) continue; } ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD); diff -r 0b2aebc8283e -r 0b8b245a2391 src/ai/trolly/trolly.cpp --- a/src/ai/trolly/trolly.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/ai/trolly/trolly.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -271,6 +271,7 @@ } if (type == AI_INDUSTRY) { const Industry* i = GetIndustry(ic); + const IndustrySpec *indsp = GetIndustrySpec(i->type); const Station* st; int count = 0; int j = 0; @@ -279,7 +280,7 @@ // No limits on delevering stations! // Or for industry that does not give anything yet - if (i->produced_cargo[0] == CT_INVALID || i->total_production[0] == 0) return true; + if (indsp->produced_cargo[0] == CT_INVALID || i->total_production[0] == 0) return true; if (i->total_production[0] - i->total_transported[0] < AI_CHECKCITY_NEEDED_CARGO) return false; @@ -302,13 +303,13 @@ // we want to know if this station gets the same good. If so, // we want to know its rating. If it is too high, we are not going // to build there - if (i->produced_cargo[0] == CT_INVALID) continue; + if (indsp->produced_cargo[0] == CT_INVALID) continue; // It does not take this cargo - if (!st->goods[i->produced_cargo[0]].last_speed) continue; + if (!st->goods[indsp->produced_cargo[0]].last_speed) continue; // Is it around our industry if (DistanceManhattan(st->xy, i->xy) > 5) continue; // It does take this cargo.. what is his rating? - if (st->goods[i->produced_cargo[0]].rating < AI_CHECKCITY_CARGO_RATING) continue; + if (st->goods[indsp->produced_cargo[0]].rating < AI_CHECKCITY_CARGO_RATING) continue; j++; // The rating is high.. a little chance that we still continue // But if there are 2 stations of this size, we never go on... @@ -458,17 +459,19 @@ } } else if (p->ainew.tbt == AI_TRUCK) { const Industry* ind_from = GetIndustry(p->ainew.from_ic); + const IndustrySpec *indsp_from = GetIndustrySpec(ind_from->type); const Industry* ind_temp = GetIndustry(p->ainew.temp); + const IndustrySpec *indsp_temp = GetIndustrySpec(ind_temp->type); bool found = false; int max_cargo = 0; uint i; // TODO: in max_cargo, also check other cargo (beside [0]) // First we check if the from_ic produces cargo that this ic accepts - if (ind_from->produced_cargo[0] != CT_INVALID && ind_from->total_production[0] != 0) { - for (i = 0; i < lengthof(ind_temp->accepts_cargo); i++) { - if (ind_temp->accepts_cargo[i] == CT_INVALID) break; - if (ind_from->produced_cargo[0] == ind_temp->accepts_cargo[i]) { + if (indsp_from->produced_cargo[0] != CT_INVALID && ind_from->total_production[0] != 0) { + for (i = 0; i < lengthof(indsp_temp->accepts_cargo); i++) { + if (indsp_temp->accepts_cargo[i] == CT_INVALID) break; + if (indsp_from->produced_cargo[0] == indsp_temp->accepts_cargo[i]) { // Found a compatible industry max_cargo = ind_from->total_production[0] - ind_from->total_transported[0]; found = true; @@ -478,11 +481,11 @@ } } } - if (!found && ind_temp->produced_cargo[0] != CT_INVALID && ind_temp->total_production[0] != 0) { + if (!found && indsp_temp->produced_cargo[0] != CT_INVALID && ind_temp->total_production[0] != 0) { // If not check if the current ic produces cargo that the from_ic accepts - for (i = 0; i < lengthof(ind_from->accepts_cargo); i++) { - if (ind_from->accepts_cargo[i] == CT_INVALID) break; - if (ind_temp->produced_cargo[0] == ind_from->accepts_cargo[i]) { + for (i = 0; i < lengthof(indsp_from->accepts_cargo); i++) { + if (indsp_from->accepts_cargo[i] == CT_INVALID) break; + if (indsp_from->produced_cargo[0] == indsp_from->accepts_cargo[i]) { // Found a compatbiel industry found = true; max_cargo = ind_temp->total_production[0] - ind_temp->total_transported[0]; @@ -501,9 +504,9 @@ distance <= max_cargo * AI_LOCATEROUTE_TRUCK_CARGO_DISTANCE) { p->ainew.to_ic = p->ainew.temp; if (p->ainew.from_deliver) { - p->ainew.cargo = ind_from->produced_cargo[0]; + p->ainew.cargo = indsp_from->produced_cargo[0]; } else { - p->ainew.cargo = ind_temp->produced_cargo[0]; + p->ainew.cargo = indsp_temp->produced_cargo[0]; } p->ainew.state = AI_STATE_FIND_STATION; diff -r 0b2aebc8283e -r 0b8b245a2391 src/aircraft.h --- a/src/aircraft.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/aircraft.h Wed Jun 13 11:45:14 2007 +0000 @@ -115,4 +115,26 @@ */ void UpdateAircraftCache(Vehicle *v); +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Aircraft(); + * + * As side-effect the vehicle type is set correctly. + */ +struct Aircraft : public Vehicle { + /** Initializes the Vehicle to an aircraft */ + Aircraft() { this->type = VEH_AIRCRAFT; } + + /** We want to 'destruct' the right class. */ + virtual ~Aircraft() {} + + const char *GetTypeString() const { return "aircraft"; } + void MarkDirty(); + void UpdateDeltaXY(Direction direction); + ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_AIRCRAFT_INC : EXPENSES_AIRCRAFT_RUN; } + WindowClass GetVehicleListWindowClass() const { return WC_AIRCRAFT_LIST; } +}; + #endif /* AIRCRAFT_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/aircraft_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -33,6 +33,35 @@ #include "spritecache.h" #include "cargotype.h" +void Aircraft::UpdateDeltaXY(Direction direction) +{ + uint32 x; +#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0) + switch (this->subtype) { + default: NOT_REACHED(); + case AIR_AIRCRAFT: + case AIR_HELICOPTER: + switch (this->u.air.state) { + case ENDTAKEOFF: + case LANDING: + case HELILANDING: + case FLYING: x = MKIT(24, 24, -1, -1); break; + default: x = MKIT( 2, 2, -1, -1); break; + } + this->z_height = 5; + break; + case AIR_SHADOW: this->z_height = 1; x = MKIT(2, 2, 0, 0); break; + case AIR_ROTOR: this->z_height = 1; x = MKIT(2, 2, -1, -1); break; + } +#undef MKIT + + this->x_offs = GB(x, 0, 8); + this->y_offs = GB(x, 8, 8); + this->sprite_width = GB(x, 16, 8); + this->sprite_height = GB(x, 24, 8); +} + + /** this maps the terminal to its corresponding state and block flag * currently set for 10 terms, 4 helipads */ static const byte _airport_terminal_state[] = {2, 3, 4, 5, 6, 7, 19, 20, 0, 0, 8, 9, 21, 22}; @@ -198,9 +227,9 @@ height = spr->height; } -static int32 EstimateAircraftCost(const AircraftVehicleInfo *avi) +static int32 EstimateAircraftCost(EngineID engine, const AircraftVehicleInfo *avi) { - return avi->base_cost * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5; + return GetEngineProperty(engine, 0x0B, avi->base_cost) * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5; } @@ -241,7 +270,7 @@ if (!IsEngineBuildable(p1, VEH_AIRCRAFT, _current_player)) return_cmd_error(STR_AIRCRAFT_NOT_AVAILABLE); const AircraftVehicleInfo *avi = AircraftVehInfo(p1); - int32 value = EstimateAircraftCost(avi); + int32 value = EstimateAircraftCost(p1, avi); /* to just query the cost, it is not neccessary to have a valid tile (automation/AI) */ if (flags & DC_QUERY_COST) return value; @@ -269,7 +298,8 @@ Vehicle *u = vl[1]; // shadow v->unitnumber = unit_num; - v->type = u->type = VEH_AIRCRAFT; + v = new (v) Aircraft(); + u = new (u) Aircraft(); v->direction = DIR_SE; v->owner = u->owner = _current_player; @@ -286,15 +316,8 @@ u->z_pos = GetSlopeZ(x, y); v->z_pos = u->z_pos + 1; - v->x_offs = v->y_offs = -1; // u->delta_x = u->delta_y = 0; - v->sprite_width = v->sprite_height = 2; - v->z_height = 5; - - u->sprite_width = u->sprite_height = 2; - u->z_height = 1; - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; u->vehstatus = VS_HIDDEN | VS_UNCLICKABLE | VS_SHADOW; @@ -322,9 +345,11 @@ v->engine_type = p1; v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER); + v->UpdateDeltaXY(INVALID_DIR); v->value = value; u->subtype = AIR_SHADOW; + u->UpdateDeltaXY(INVALID_DIR); /* Danger, Will Robinson! * If the aircraft is refittable, but cannot be refitted to @@ -404,15 +429,12 @@ u->next = w; - w->type = VEH_AIRCRAFT; + w = new (w) Aircraft(); w->direction = DIR_N; w->owner = _current_player; w->x_pos = v->x_pos; w->y_pos = v->y_pos; w->z_pos = v->z_pos + 5; - w->x_offs = w->y_offs = -1; - w->sprite_width = w->sprite_height = 2; - w->z_height = 1; w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE; w->spritenum = 0xFF; w->subtype = AIR_ROTOR; @@ -420,6 +442,7 @@ w->random_bits = VehicleRandomBits(); /* Use rotor's air.state to store the rotor animation frame */ w->u.air.state = HRS_ROTOR_STOPPED; + w->UpdateDeltaXY(INVALID_DIR); VehiclePositionChanged(w); } @@ -597,6 +620,7 @@ * @param p2 various bitstuffed elements * - p2 = (bit 0-7) - the new cargo type to refit to * - p2 = (bit 8-15) - the new cargo subtype to refit to + * - p2 = (bit 16) - refit only this vehicle (ignored) * @return cost of refit or error */ int32 CmdRefitAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) @@ -695,6 +719,7 @@ if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) { // printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index); // v->u.air.targetairport = st->index; + if (v->current_order.type == OT_LOADING) v->LeaveStation(); v->current_order.type = OT_GOTO_DEPOT; v->current_order.flags = OF_NON_STOP; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); @@ -1068,6 +1093,7 @@ * helicopter will circle until sign disappears, then go to next order * what to do when it is the only order left, right now it just stays in 1 place */ v->u.air.state = FLYING; + UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); return false; } @@ -1182,6 +1208,7 @@ if (st->airport_tile == 0) { /* Airport has been removed, abort the landing procedure */ v->u.air.state = FLYING; + UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); /* get aircraft back on running altitude */ SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v)); @@ -1384,50 +1411,11 @@ InvalidateWindowClasses(WC_AIRCRAFT_LIST); } -/** Mark all views dirty for an aircraft. - * @param v vehicle to be redrawn. - */ -static void MarkAircraftDirty(Vehicle *v) -{ - v->cur_image = GetAircraftImage(v, v->direction); - if (v->subtype == AIR_HELICOPTER) v->next->next->cur_image = GetRotorImage(v); - MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1); -} - -static void HandleAircraftLoading(Vehicle *v, int mode) +void Aircraft::MarkDirty() { - switch (v->current_order.type) { - case OT_LOADING: { - if (mode != 0) return; - if (--v->load_unload_time_rem != 0) return; - - if (CanFillVehicle(v) && ( - v->current_order.flags & OF_FULL_LOAD || - (_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)) - )) { - SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC); - if (LoadUnloadVehicle(v, false)) { - InvalidateWindow(WC_AIRCRAFT_LIST, v->owner); - MarkAircraftDirty(v); - } - return; - } - - Order b = v->current_order; - v->LeaveStation(); - v->current_order.Free(); - MarkAircraftDirty(v); - if (!(b.flags & OF_NON_STOP)) return; - break; - } - - case OT_DUMMY: break; - - default: return; - } - - v->cur_order_index++; - InvalidateVehicleOrder(v); + this->cur_image = GetAircraftImage(this, this->direction); + if (this->subtype == AIR_HELICOPTER) this->next->next->cur_image = GetRotorImage(this); + MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1); } static void CrashAirplane(Vehicle *v) @@ -1509,31 +1497,13 @@ 0); } - Order old_order = v->current_order; v->BeginLoading(); - v->current_order.flags = 0; - - if (old_order.type == OT_GOTO_STATION && - v->current_order.dest == v->last_station_visited) { - v->current_order.flags = - (old_order.flags & (OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER)) | OF_NON_STOP; - } - - SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC); - LoadUnloadVehicle(v, true); - MarkAircraftDirty(v); - InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); - InvalidateWindowClasses(WC_AIRCRAFT_LIST); -} - -static void AircraftLand(Vehicle *v) -{ - v->sprite_width = v->sprite_height = 2; } static void AircraftLandAirplane(Vehicle *v) { - AircraftLand(v); + v->UpdateDeltaXY(INVALID_DIR); + if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) { SndPlayVehicleFx(SND_17_SKID_PLANE, v); } @@ -1692,8 +1662,8 @@ static void AircraftEventHandler_StartTakeOff(Vehicle *v, const AirportFTAClass *apc) { - v->sprite_width = v->sprite_height = 24; // ??? no idea what this is v->u.air.state = ENDTAKEOFF; + v->UpdateDeltaXY(INVALID_DIR); } static void AircraftEventHandler_EndTakeOff(Vehicle *v, const AirportFTAClass *apc) @@ -1706,15 +1676,16 @@ static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *apc) { const Player* p = GetPlayer(v->owner); - v->sprite_width = v->sprite_height = 24; // ??? no idea what this is v->u.air.state = FLYING; + v->UpdateDeltaXY(INVALID_DIR); + /* get the next position to go to, differs per airport */ AircraftNextAirportPos_and_Order(v); /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed * unless it is due for renewal but the engine is no longer available */ if (v->owner == _local_player && ( - EngineHasReplacementForPlayer(p, v->engine_type) || + EngineHasReplacementForPlayer(p, v->engine_type, v->group_id) || ((p->engine_renew && v->age - v->max_age > p->engine_renew_months * 30) && HASBIT(GetEngine(v->engine_type)->player_avail, _local_player)) )) { @@ -1765,13 +1736,14 @@ static void AircraftEventHandler_Landing(Vehicle *v, const AirportFTAClass *apc) { + v->u.air.state = ENDLANDING; AircraftLandAirplane(v); // maybe crash airplane - v->u.air.state = ENDLANDING; + /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->current_order.type != OT_GOTO_DEPOT && v->owner == _local_player) { /* only the vehicle owner needs to calculate the rest (locally) */ const Player* p = GetPlayer(v->owner); - if (EngineHasReplacementForPlayer(p, v->engine_type) || + if (EngineHasReplacementForPlayer(p, v->engine_type, v->group_id) || (p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) { /* send the aircraft to the hangar at next airport */ _current_player = _local_player; @@ -1783,8 +1755,8 @@ static void AircraftEventHandler_HeliLanding(Vehicle *v, const AirportFTAClass *apc) { - AircraftLand(v); // helicopters don't crash v->u.air.state = HELIENDLANDING; + v->UpdateDeltaXY(INVALID_DIR); } static void AircraftEventHandler_EndLanding(Vehicle *v, const AirportFTAClass *apc) @@ -1885,7 +1857,7 @@ byte prev_state = v->u.air.state; _aircraft_state_handlers[v->u.air.state](v, apc); if (v->u.air.state != FLYING) v->u.air.previous_pos = prev_pos; - if (v->u.air.state != prev_state) UpdateAircraftCache(v); + if (v->u.air.state != prev_state || v->u.air.pos != prev_pos) UpdateAircraftCache(v); return true; } @@ -1895,6 +1867,7 @@ if (current->next == NULL) { if (AirportSetBlocks(v, current, apc)) { v->u.air.pos = current->next_position; + UpdateAircraftCache(v); } // move to next position return false; } @@ -1905,6 +1878,7 @@ if (v->u.air.state == current->heading || current->heading == TO_ALL) { if (AirportSetBlocks(v, current, apc)) { v->u.air.pos = current->next_position; + UpdateAircraftCache(v); } // move to next position return false; } @@ -2132,7 +2106,7 @@ HandleAircraftSmoke(v); ProcessAircraftOrder(v); - HandleAircraftLoading(v, loop); + v->HandleLoading(loop != 0); if (v->current_order.type >= OT_LOADING) return; @@ -2209,6 +2183,7 @@ if (v->u.air.state >= FLYING) { // circle around v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, ap); v->u.air.state = FLYING; + UpdateAircraftCache(v); /* landing plane needs to be reset to flying height (only if in pause mode upgrade, * in normal mode, plane is reset in AircraftController. It doesn't hurt for FLYING */ GetNewVehiclePosResult gp = GetNewVehiclePos(v); @@ -2222,6 +2197,7 @@ for (uint cnt = 0; cnt < ap->nofelements; cnt++) { if (ap->layout[cnt].heading == takeofftype) { v->u.air.pos = ap->layout[cnt].position; + UpdateAircraftCache(v); break; } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/aircraft_gui.cpp --- a/src/aircraft_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/aircraft_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -393,6 +393,6 @@ if (w != NULL) { w->caption_color = v->owner; - AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0); + AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), ZOOM_LVL_AIRCRAFT); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/airport_gui.cpp --- a/src/airport_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/airport_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -39,7 +39,7 @@ static void PlaceAir_DemolishArea(TileIndex tile) { - VpStartPlaceSizing(tile, 4); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_None); } @@ -91,7 +91,7 @@ break; case WE_PLACE_DRAG: - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); break; case WE_PLACE_MOUSEUP: diff -r 0b2aebc8283e -r 0b8b245a2391 src/airport_movement.h --- a/src/airport_movement.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/airport_movement.h Wed Jun 13 11:45:14 2007 +0000 @@ -276,7 +276,7 @@ { 136, 96, AMED_HELI_LOWER, {DIR_N} }, // 56 Land in front of hangar2 { 126, 104, 0, {DIR_SE} }, // 57 Outway 2 { 136, 136, 0, {DIR_NE} }, // 58 Airport OUTWAY 2 - { 136, 152, AMED_EXACTPOS, {DIR_SW} }, // 59 Accelerate to end of runway2 + { 136, 152, AMED_EXACTPOS, {DIR_NE} }, // 59 Accelerate to end of runway2 { 16, 152, AMED_NOSPDCLAMP, {DIR_N} }, // 60 Release control of runway2, for smoother movement { 20, 152, AMED_NOSPDCLAMP, {DIR_N} }, // 61 End of runway2 { -56, 152, AMED_NOSPDCLAMP | AMED_TAKEOFF, {DIR_N} }, // 62 Take off2 diff -r 0b2aebc8283e -r 0b8b245a2391 src/autoreplace_cmd.cpp --- a/src/autoreplace_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/autoreplace_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -16,6 +16,7 @@ #include "train.h" #include "aircraft.h" #include "cargotype.h" +#include "group.h" /* @@ -136,7 +137,18 @@ char vehicle_name[32]; CargoID replacement_cargo_type; - new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type); + /* If the vehicle belongs to a group, check if the group is protected from the global autoreplace. + * If not, chek if an global auto replacement is defined */ + new_engine_type = (IsValidGroupID(old_v->group_id) && GetGroup(old_v->group_id)->replace_protection) ? + INVALID_ENGINE : + EngineReplacementForPlayer(p, old_v->engine_type, DEFAULT_GROUP); + + /* If we don't set new_egnine_type previously, we try to check if an autoreplacement was defined + * for the group and the engine_type of the vehicle */ + if (new_engine_type == INVALID_ENGINE && !IsDefaultGroupID(old_v->group_id)) { + new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type, old_v->group_id); + } + if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type; replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type); @@ -194,8 +206,10 @@ new_v->profit_this_year = old_v->profit_this_year; new_v->profit_last_year = old_v->profit_last_year; new_v->service_interval = old_v->service_interval; + DoCommand(0, old_v->group_id, new_v->index, flags, CMD_ADD_VEHICLE_GROUP); new_front = true; new_v->unitnumber = old_v->unitnumber; // use the same unit number + new_v->dest_tile = old_v->dest_tile; new_v->current_order = old_v->current_order; if (old_v->type == VEH_TRAIN && GetNextVehicle(old_v) != NULL){ @@ -210,6 +224,10 @@ if (temp_v != NULL) { DoCommand(0, (new_v->index << 16) | temp_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); } + } else if (!IsDefaultGroupID(old_v->group_id) && IsValidGroupID(old_v->group_id)) { + /* Increase the new num engines of the group for the ships, aircraft, and road vehicles + The old new num engine is decrease in the destroyvehicle function */ + GetGroup(old_v->group_id)->num_engines[new_v->engine_type]++; } } /* We are done setting up the new vehicle. Now we move the cargo from the old one to the new one */ @@ -304,8 +322,17 @@ if (!p->engine_renew || w->age - w->max_age < (p->engine_renew_months * 30) || // replace if engine is too old w->max_age == 0) { // rail cars got a max age of 0 - if (!EngineHasReplacementForPlayer(p, w->engine_type)) // updates to a new model + /* If the vehicle belongs to a group, check if the group is protected from the global autoreplace. + If not, chek if an global auto remplacement is defined */ + if (IsValidGroupID(w->group_id)) { + if (!EngineHasReplacementForPlayer(p, w->engine_type, w->group_id) && ( + GetGroup(w->group_id)->replace_protection || + !EngineHasReplacementForPlayer(p, w->engine_type, DEFAULT_GROUP))) { + continue; + } + } else if (!EngineHasReplacementForPlayer(p, w->engine_type, DEFAULT_GROUP)) { continue; + } } /* Now replace the vehicle */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/autoreplace_gui.cpp --- a/src/autoreplace_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/autoreplace_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -14,6 +14,7 @@ #include "variables.h" #include "vehicle_gui.h" #include "newgrf_engine.h" +#include "group.h" static RailType _railtype_selected_in_replace_gui; @@ -62,7 +63,7 @@ /** When an engine is made buildable or is removed from being buildable, add/remove it from the build/autoreplace lists * @param type The type of engine */ -void AddRemoveEngineFromAutoreplaceAndBuildWindows(byte type) +void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type) { _rebuild_left_list = false; // left list is only for the vehicles the player owns and is not related to being buildable _rebuild_right_list = true; @@ -150,8 +151,11 @@ if (type == VEH_TRAIN && !GenerateReplaceRailList(e, draw_left, WP(w, replaceveh_d).wagon_btnstate)) continue; // special rules for trains if (draw_left) { + const GroupID selected_group = WP(w, replaceveh_d).sel_group; + const uint num_engines = IsDefaultGroupID(selected_group) ? p->num_engines[e] : GetGroup(selected_group)->num_engines[e]; + /* Skip drawing the engines we don't have any of and haven't set for replacement */ - if (p->num_engines[e] == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), e) == INVALID_ENGINE) continue; + if (num_engines == 0 && EngineReplacementForPlayer(GetPlayer(_local_player), e, selected_group) == INVALID_ENGINE) continue; } else { /* This is for engines we can replace to and they should depend on what we selected to replace from */ if (!IsEngineBuildable(e, type, _local_player)) continue; // we need to be able to build the engine @@ -202,7 +206,7 @@ } -void DrawEngineList(byte type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count); +void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); static void ReplaceVehicleWndProc(Window *w, WindowEvent *e) { @@ -231,6 +235,7 @@ Player *p = GetPlayer(_local_player); EngineID selected_id[2]; + const GroupID selected_group = WP(w,replaceveh_d).sel_group; selected_id[0] = WP(w, replaceveh_d).sel_engine[0]; selected_id[1] = WP(w, replaceveh_d).sel_engine[1]; @@ -242,15 +247,15 @@ SetWindowWidgetDisabledState(w, 4, selected_id[0] == INVALID_ENGINE || selected_id[1] == INVALID_ENGINE || - EngineReplacementForPlayer(p, selected_id[1]) != INVALID_ENGINE || - EngineReplacementForPlayer(p, selected_id[0]) == selected_id[1]); + EngineReplacementForPlayer(p, selected_id[1], selected_group) != INVALID_ENGINE || + EngineReplacementForPlayer(p, selected_id[0], selected_group) == selected_id[1]); /* Disable the "Stop Replacing" button if: * The left list (existing vehicle) is empty * or The selected vehicle has no replacement set up */ SetWindowWidgetDisabledState(w, 6, selected_id[0] == INVALID_ENGINE || - !EngineHasReplacementForPlayer(p, selected_id[0])); + !EngineHasReplacementForPlayer(p, selected_id[0], selected_group)); /* now the actual drawing of the window itself takes place */ SetDParam(0, _vehicle_type_names[w->window_number]); @@ -277,10 +282,10 @@ /* sets up the string for the vehicle that is being replaced to */ if (selected_id[0] != INVALID_ENGINE) { - if (!EngineHasReplacementForPlayer(p, selected_id[0])) { + if (!EngineHasReplacementForPlayer(p, selected_id[0], selected_group)) { SetDParam(0, STR_NOT_REPLACING); } else { - SetDParam(0, GetCustomEngineName(EngineReplacementForPlayer(p, selected_id[0]))); + SetDParam(0, GetCustomEngineName(EngineReplacementForPlayer(p, selected_id[0], selected_group))); } } else { SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED); @@ -296,7 +301,7 @@ EngineID end = min((i == 0 ? w->vscroll.cap : w->vscroll2.cap) + start, EngList_Count(&list)); /* Do the actual drawing */ - DrawEngineList(w->window_number, x, 15, list, start, end, WP(w, replaceveh_d).sel_engine[i], i == 0); + DrawEngineList((VehicleType)w->window_number, x, 15, list, start, end, WP(w, replaceveh_d).sel_engine[i], i == 0, selected_group); /* Also draw the details if an engine is selected */ if (WP(w, replaceveh_d).sel_engine[i] != INVALID_ENGINE) { @@ -328,12 +333,12 @@ case 4: { /* Start replacing */ EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; EngineID veh_to = WP(w, replaceveh_d).sel_engine[1]; - DoCommandP(0, 3, veh_from + (veh_to << 16), NULL, CMD_SET_AUTOREPLACE); + DoCommandP(0, 3 + (WP(w, replaceveh_d).sel_group << 16) , veh_from + (veh_to << 16), NULL, CMD_SET_AUTOREPLACE); } break; case 6: { /* Stop replacing */ EngineID veh_from = WP(w, replaceveh_d).sel_engine[0]; - DoCommandP(0, 3, veh_from + (INVALID_ENGINE << 16), NULL, CMD_SET_AUTOREPLACE); + DoCommandP(0, 3 + (WP(w, replaceveh_d).sel_group << 16), veh_from + (INVALID_ENGINE << 16), NULL, CMD_SET_AUTOREPLACE); } break; case 7: @@ -480,7 +485,7 @@ }; -void ShowReplaceVehicleWindow(byte vehicletype) +void ShowReplaceVehicleWindow(VehicleType vehicletype) { Window *w; @@ -509,4 +514,37 @@ w->caption_color = _local_player; w->vscroll2.cap = w->vscroll.cap; // these two are always the same + WP(w, replaceveh_d).sel_group = DEFAULT_GROUP; + } + +void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype) +{ + Window *w; + + DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); + + switch (vehicletype) { + default: NOT_REACHED(); + case VEH_TRAIN: + w = AllocateWindowDescFront(&_replace_rail_vehicle_desc, vehicletype); + w->vscroll.cap = 8; + w->resize.step_height = 14; + WP(w, replaceveh_d).wagon_btnstate = true; + break; + case VEH_ROAD: + w = AllocateWindowDescFront(&_replace_road_vehicle_desc, vehicletype); + w->vscroll.cap = 8; + w->resize.step_height = 14; + break; + case VEH_SHIP: + case VEH_AIRCRAFT: + w = AllocateWindowDescFront(&_replace_ship_aircraft_vehicle_desc, vehicletype); + w->vscroll.cap = 4; + w->resize.step_height = 24; + break; + } + + w->caption_color = _local_player; + WP(w, replaceveh_d).sel_group = id_g; + w->vscroll2.cap = w->vscroll.cap; // these two are always the same } diff -r 0b2aebc8283e -r 0b8b245a2391 src/bridge_map.h --- a/src/bridge_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/bridge_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -211,7 +211,6 @@ SETBIT(_m[t].m6, 6 + a); } - /** * Generic part to make a bridge ramp for both roads and rails. * @param t the tile to make a bridge ramp @@ -219,13 +218,15 @@ * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing * @param tt the transport type of the bridge + * @param rt the road or rail type * @note this function should not be called directly. */ -static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt) +static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt, uint rt) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); _m[t].m2 = bridgetype << 4; + _m[t].m3 = rt; _m[t].m4 = 0; _m[t].m5 = 1 << 7 | tt << 2 | d; } @@ -236,11 +237,11 @@ * @param o the new owner of the bridge ramp * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing + * @param r the road type of the bridge */ -static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d) +static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RoadTypes r) { - MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD); - _m[t].m3 = 0; + MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, r); } /** @@ -253,8 +254,7 @@ */ static inline void MakeRailBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RailType r) { - MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL); - _m[t].m3 = r; + MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/build_vehicle_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -27,6 +27,7 @@ #include "date.h" #include "strings.h" #include "cargotype.h" +#include "group.h" enum BuildVehicleWidgets { @@ -409,21 +410,25 @@ static int DrawRailWagonPurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi) { /* Purchase cost */ - SetDParam(0, (rvi->base_cost * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8); + SetDParam(0, (GetEngineProperty(engine_number, 0x17, rvi->base_cost) * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8); DrawString(x, y, STR_PURCHASE_INFO_COST, 0); y += 10; /* Wagon weight - (including cargo) */ - SetDParam(0, rvi->weight); - SetDParam(1, (GetCargo(rvi->cargo_type)->weight * rvi->capacity >> 4) + rvi->weight); + uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); + SetDParam(0, weight); + SetDParam(1, (GetCargo(rvi->cargo_type)->weight * GetEngineProperty(engine_number, 0x14, rvi->capacity) >> 4) + weight); DrawString(x, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT, 0); y += 10; /* Wagon speed limit, displayed if above zero */ - if (rvi->max_speed > 0 && _patches.wagon_speed_limits) { - SetDParam(0, rvi->max_speed * 10 / 16); - DrawString(x, y, STR_PURCHASE_INFO_SPEED, 0); - y += 10; + if (_patches.wagon_speed_limits) { + uint max_speed = GetEngineProperty(engine_number, 0x09, rvi->max_speed); + if (max_speed > 0) { + SetDParam(0, max_speed * 10 / 16); + DrawString(x, y, STR_PURCHASE_INFO_SPEED, 0); + y += 10; + } } return y; } @@ -432,22 +437,23 @@ static int DrawRailEnginePurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi) { int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); + uint weight = GetEngineProperty(engine_number, 0x16, rvi->weight); /* Purchase Cost - Engine weight */ - SetDParam(0, rvi->base_cost * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5); - SetDParam(1, rvi->weight << multihead); + SetDParam(0, GetEngineProperty(engine_number, 0x17, rvi->base_cost) * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5); + SetDParam(1, weight << multihead); DrawString(x, y, STR_PURCHASE_INFO_COST_WEIGHT, 0); y += 10; /* Max speed - Engine power */ - SetDParam(0, rvi->max_speed * 10 / 16); - SetDParam(1, rvi->power << multihead); + SetDParam(0, GetEngineProperty(engine_number, 0x09, rvi->max_speed) * 10 / 16); + SetDParam(1, GetEngineProperty(engine_number, 0x0B, rvi->power) << multihead); DrawString(x, y, STR_PURCHASE_INFO_SPEED_POWER, 0); y += 10; /* Max tractive effort - not applicable if old acceleration or maglev */ if (_patches.realistic_acceleration && rvi->railtype != RAILTYPE_MAGLEV) { - SetDParam(0, ((rvi->weight << multihead) * 10 * rvi->tractive_effort) / 256); + SetDParam(0, ((weight << multihead) * 10 * GetEngineProperty(engine_number, 0x1F, rvi->tractive_effort)) / 256); DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0); y += 10; } @@ -462,7 +468,7 @@ } /* Running cost */ - SetDParam(0, (rvi->running_cost_base * cost_class >> 8) << multihead); + SetDParam(0, (GetEngineProperty(engine_number, 0x0D, rvi->running_cost_base) * cost_class >> 8) << multihead); DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); y += 10; @@ -483,7 +489,7 @@ bool refittable = (_engine_info[engine_number].refit_mask != 0); /* Purchase cost - Max speed */ - SetDParam(0, rvi->base_cost * (_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) >> 5); + SetDParam(0, GetEngineProperty(engine_number, 0x11, rvi->base_cost) * (_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) >> 5); SetDParam(1, rvi->max_speed * 10 / 32); DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); y += 10; @@ -495,7 +501,7 @@ /* Cargo type + capacity */ SetDParam(0, rvi->cargo_type); - SetDParam(1, rvi->capacity); + SetDParam(1, GetEngineProperty(engine_number, 0x0F, rvi->capacity)); SetDParam(2, refittable ? STR_9842_REFITTABLE : STR_EMPTY); DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); y += 10; @@ -507,20 +513,21 @@ static int DrawShipPurchaseInfo(int x, int y, EngineID engine_number, const ShipVehicleInfo *svi) { /* Purchase cost - Max speed */ - SetDParam(0, svi->base_cost * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5); - SetDParam(1, svi->max_speed * 10 / 32); + SetDParam(0, GetEngineProperty(engine_number, 0x0A, svi->base_cost) + * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5); + SetDParam(1, GetEngineProperty(engine_number, 0x0B, svi->max_speed) * 10 / 32); DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); y += 10; /* Cargo type + capacity */ SetDParam(0, svi->cargo_type); - SetDParam(1, svi->capacity); + SetDParam(1, GetEngineProperty(engine_number, 0x0D, svi->capacity)); SetDParam(2, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY); DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); y += 10; /* Running cost */ - SetDParam(0, svi->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) >> 8); + SetDParam(0, GetEngineProperty(engine_number, 0x0F, svi->running_cost) * _eco->GetPrice(CEconomy::SHIP_RUNNING) >> 8); DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); y += 10; @@ -533,7 +540,7 @@ CargoID cargo; /* Purchase cost - Max speed */ - SetDParam(0, avi->base_cost * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5); + SetDParam(0, GetEngineProperty(engine_number, 0x0B, avi->base_cost) * (_eco->GetPrice(CEconomy::AIRCRAFT_BASE) >> 3) >> 5); SetDParam(1, avi->max_speed * 10 / 16); DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0); y += 10; @@ -555,7 +562,7 @@ y += 10; /* Running cost */ - SetDParam(0, avi->running_cost * _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) >> 8); + SetDParam(0, GetEngineProperty(engine_number, 0x0E, avi->running_cost) * _eco->GetPrice(CEconomy::AIRCRAFT_RUNNING) >> 8); DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0); y += 10; @@ -577,10 +584,12 @@ bool refitable = false; switch (e->type) { + default: NOT_REACHED(); case VEH_TRAIN: { const RailVehicleInfo *rvi = RailVehInfo(engine_number); + uint capacity = GetEngineProperty(engine_number, 0x14, rvi->capacity); - refitable = (EngInfo(engine_number)->refit_mask != 0) && (rvi->capacity > 0); + refitable = (EngInfo(engine_number)->refit_mask != 0) && (capacity > 0); if (rvi->railveh_type == RAILVEH_WAGON) { y = DrawRailWagonPurchaseInfo(x, y, engine_number, rvi); @@ -596,7 +605,7 @@ int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); SetDParam(0, rvi->cargo_type); - SetDParam(1, (rvi->capacity * (CountArticulatedParts(engine_number) + 1)) << multihead); + SetDParam(1, (capacity * (CountArticulatedParts(engine_number) + 1)) << multihead); SetDParam(2, refitable ? STR_9842_REFITTABLE : STR_EMPTY); } DrawString(x, y, STR_PURCHASE_INFO_CAPACITY, 0); @@ -753,6 +762,7 @@ buildvehicle_d *bv = &WP(w, buildvehicle_d); switch (bv->vehicle_type) { + default: NOT_REACHED(); case VEH_TRAIN: GenerateBuildTrainList(w); return; // trains should not reach the last sorting @@ -790,7 +800,7 @@ * @param selected_id what engine to highlight as selected, if any * @param show_count Display the number of vehicles (used by autoreplace) */ -void DrawEngineList(byte type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count) +void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) { byte step_size = GetVehicleListHeight(type); byte x_offset = 0; @@ -826,11 +836,12 @@ for (; min < max; min++, y += step_size) { const EngineID engine = eng_list[min]; + const uint num_engines = IsDefaultGroupID(selected_group) ? p->num_engines[engine] : GetGroup(selected_group)->num_engines[engine]; DrawString(x + x_offset, y, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10); - DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && p->num_engines[engine] == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player)); + DrawVehicleEngine(type, x, y + y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_player)); if (show_count) { - SetDParam(0, p->num_engines[engine]); + SetDParam(0, num_engines); DrawStringRightAligned(213, y + (GetVehicleListHeight(type) == 14 ? 3 : 8), STR_TINY_BLACK, 0); } } @@ -864,7 +875,7 @@ SetDParam(0, bv->filter.railtype + STR_881C_NEW_RAIL_VEHICLES); // This should only affect rail vehicles DrawWindowWidgets(w); - DrawEngineList(bv->vehicle_type, 2, 27, bv->eng_list, w->vscroll.pos, max, bv->sel_engine, false); + DrawEngineList(bv->vehicle_type, 2, 27, bv->eng_list, w->vscroll.pos, max, bv->sel_engine, false, DEFAULT_GROUP); if (bv->sel_engine != INVALID_ENGINE) { const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL]; @@ -905,6 +916,7 @@ EngineID sel_eng = bv->sel_engine; if (sel_eng != INVALID_ENGINE) { switch (bv->vehicle_type) { + default: NOT_REACHED(); case VEH_TRAIN: DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildLoco, CMD_BUILD_RAIL_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE)); @@ -930,6 +942,7 @@ bv->rename_engine = sel_eng; switch (bv->vehicle_type) { + default: NOT_REACHED(); case VEH_TRAIN: str = STR_886A_RENAME_TRAIN_VEHICLE_TYPE; break; case VEH_ROAD: str = STR_9036_RENAME_ROAD_VEHICLE_TYPE; break; case VEH_SHIP: str = STR_9838_RENAME_SHIP_TYPE; break; @@ -973,6 +986,7 @@ StringID str = STR_NULL; _cmd_text = e->we.edittext.str; switch (bv->vehicle_type) { + default: NOT_REACHED(); case VEH_TRAIN: str = STR_886B_CAN_T_RENAME_TRAIN_VEHICLE; break; case VEH_ROAD: str = STR_9037_CAN_T_RENAME_ROAD_VEHICLE; break; case VEH_SHIP: str = STR_9839_CAN_T_RENAME_SHIP_TYPE; break; @@ -1010,7 +1024,7 @@ NewVehicleWndProc }; -void ShowBuildVehicleWindow(TileIndex tile, byte type) +void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) { buildvehicle_d *bv; Window *w; @@ -1039,6 +1053,7 @@ bv->descending_sort_order = _last_sort_order[type]; switch (type) { + default: NOT_REACHED(); case VEH_TRAIN: WP(w, buildvehicle_d).filter.railtype = (tile == 0) ? RAILTYPE_END : GetRailType(tile); ResizeWindow(w, 0, 16); diff -r 0b2aebc8283e -r 0b8b245a2391 src/cargotype.cpp --- a/src/cargotype.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/cargotype.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -33,6 +33,14 @@ for (CargoID i = 0; i < lengthof(_default_climate_cargo[l]); i++) { CargoLabel cl = _default_climate_cargo[l][i]; + /* Bzzt: check if cl is just an index into the cargo table */ + if (cl < lengthof(_default_cargo)) { + /* Copy the indexed cargo */ + _cargo[i] = _default_cargo[cl]; + SETBIT(_cargo_mask, i); + continue; + } + /* Loop through each of the default cargo types to see if * the label matches */ for (uint j = 0; j < lengthof(_default_cargo); j++) { diff -r 0b2aebc8283e -r 0b8b245a2391 src/command.cpp --- a/src/command.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/command.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -168,6 +168,14 @@ DEF_COMMAND(CmdDepotSellAllVehicles); DEF_COMMAND(CmdDepotMassAutoReplace); +DEF_COMMAND(CmdCreateGroup); +DEF_COMMAND(CmdRenameGroup); +DEF_COMMAND(CmdDeleteGroup); +DEF_COMMAND(CmdAddVehicleGroup); +DEF_COMMAND(CmdAddSharedVehicleGroup); +DEF_COMMAND(CmdRemoveAllVehiclesGroup); +DEF_COMMAND(CmdSetGroupReplaceProtection); + /* The master command table */ static const Command _command_proc_table[] = { {CmdBuildRailroadTrack, 0}, /* 0 */ @@ -313,6 +321,13 @@ {CmdMassStartStopVehicle, 0}, /* 117 */ {CmdDepotSellAllVehicles, 0}, /* 118 */ {CmdDepotMassAutoReplace, 0}, /* 119 */ + {CmdCreateGroup, 0}, /* 120 */ + {CmdDeleteGroup, 0}, /* 121 */ + {CmdRenameGroup, 0}, /* 122 */ + {CmdAddVehicleGroup, 0}, /* 123 */ + {CmdAddSharedVehicleGroup, 0}, /* 124 */ + {CmdRemoveAllVehiclesGroup, 0}, /* 125 */ + {CmdSetGroupReplaceProtection, 0}, /* 126 */ }; /* This function range-checks a cmd, and checks if the cmd is not NULL */ @@ -339,7 +354,7 @@ CommandProc *proc; /* Do not even think about executing out-of-bounds tile-commands */ - if (tile >= MapSize()) { + if (tile >= MapSize() || IsTileType(tile, MP_VOID)) { _cmd_text = NULL; return CMD_ERROR; } @@ -417,7 +432,7 @@ int y = TileY(tile) * TILE_SIZE; /* Do not even think about executing out-of-bounds tile-commands */ - if (tile >= MapSize()) { + if (tile >= MapSize() || IsTileType(tile, MP_VOID)) { _cmd_text = NULL; return false; } @@ -456,13 +471,17 @@ * restrictions which may cause the test run to fail (the previous * road fragments still stay there and the town won't let you * disconnect the road system), but the exec will succeed and this - * fact will trigger an assertion failure. --pasky */ + * fact will trigger an assertion failure. --pasky + * CMD_CLONE_VEHICLE: Both building new vehicles and refitting them can be + * influenced by newgrf callbacks, which makes it impossible to accurately + * estimate the cost of cloning a vehicle. */ notest = (cmd & 0xFF) == CMD_CLEAR_AREA || (cmd & 0xFF) == CMD_CONVERT_RAIL || (cmd & 0xFF) == CMD_LEVEL_LAND || (cmd & 0xFF) == CMD_REMOVE_ROAD || - (cmd & 0xFF) == CMD_REMOVE_LONG_ROAD; + (cmd & 0xFF) == CMD_REMOVE_LONG_ROAD || + (cmd & 0xFF) == CMD_CLONE_VEHICLE; _docommand_recursive = 1; diff -r 0b2aebc8283e -r 0b8b245a2391 src/command.h --- a/src/command.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/command.h Wed Jun 13 11:45:14 2007 +0000 @@ -143,6 +143,13 @@ CMD_MASS_START_STOP = 117, CMD_DEPOT_SELL_ALL_VEHICLES = 118, CMD_DEPOT_MASS_AUTOREPLACE = 119, + CMD_CREATE_GROUP = 120, + CMD_DELETE_GROUP = 121, + CMD_RENAME_GROUP = 122, + CMD_ADD_VEHICLE_GROUP = 123, + CMD_ADD_SHARED_VEHICLE_GROUP = 124, + CMD_REMOVE_ALL_VEHICLES_GROUP = 125, + CMD_SET_GROUP_REPLACE_PROTECTION = 126, }; enum { diff -r 0b2aebc8283e -r 0b8b245a2391 src/console_cmds.cpp --- a/src/console_cmds.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/console_cmds.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -142,8 +142,6 @@ FOR_ALL_VEHICLES(v) { /* Code ripped from CmdStartStopTrain. Can't call it, because of * ownership problems, so we'll duplicate some code, for now */ - if (v->type == VEH_TRAIN) - v->u.rail.days_since_order_progr = 0; v->vehstatus |= VS_STOPPED; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); @@ -1234,13 +1232,16 @@ if (!p->is_active) continue; + const NetworkPlayerInfo *npi = &_network_player_info[p->index]; + GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer)); - IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %d Loan: %d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d)", - p->index + 1, buffer, _network_player_info[p->index].company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p), - /* trains */ _network_player_info[p->index].num_vehicle[0], - /* lorry + bus */ _network_player_info[p->index].num_vehicle[1] + _network_player_info[p->index].num_vehicle[2], - /* planes */ _network_player_info[p->index].num_vehicle[3], - /* ships */ _network_player_info[p->index].num_vehicle[4]); + IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %d Loan: %d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d) %sprotected", + p->index + 1, buffer, npi->company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p), + /* trains */ npi->num_vehicle[0], + /* lorry + bus */ npi->num_vehicle[1] + npi->num_vehicle[2], + /* planes */ npi->num_vehicle[3], + /* ships */ npi->num_vehicle[4], + /* protected */ StrEmpty(npi->password) ? "un" : ""); } return true; diff -r 0b2aebc8283e -r 0b8b245a2391 src/depot.cpp --- a/src/depot.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/depot.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -4,6 +4,7 @@ #include "stdafx.h" #include "openttd.h" +#include "vehicle.h" #include "depot.h" #include "functions.h" #include "landscape.h" diff -r 0b2aebc8283e -r 0b8b245a2391 src/depot.h --- a/src/depot.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/depot.h Wed Jun 13 11:45:14 2007 +0000 @@ -42,7 +42,7 @@ depot->xy = 0; } -void ShowDepotWindow(TileIndex tile, byte type); +void ShowDepotWindow(TileIndex tile, VehicleType type); #define FOR_ALL_DEPOTS_FROM(d, start) for (d = GetDepot(start); d != NULL; d = (d->index + 1U < GetDepotPoolSize()) ? GetDepot(d->index + 1U) : NULL) if (IsValidDepot(d)) #define FOR_ALL_DEPOTS(d) FOR_ALL_DEPOTS_FROM(d, 0) diff -r 0b2aebc8283e -r 0b8b245a2391 src/depot_gui.cpp --- a/src/depot_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/depot_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -137,6 +137,7 @@ case VEH_ROAD: CcCloneRoadVeh( true, tile, p1, p2); break; case VEH_SHIP: CcCloneShip( true, tile, p1, p2); break; case VEH_AIRCRAFT: CcCloneAircraft(true, tile, p1, p2); break; + default: NOT_REACHED(); } } @@ -656,7 +657,7 @@ _block_sizes[VEH_ROAD][1] = GetVehicleListHeight(VEH_ROAD); } -static void ResizeDefaultWindowSize(byte type) +static void ResizeDefaultWindowSize(VehicleType type) { EngineID engine; uint max_width = 0; @@ -696,7 +697,7 @@ ResizeDefaultWindowSize(VEH_AIRCRAFT); } -static void CreateDepotListWindow(Window *w, byte type) +static void CreateDepotListWindow(Window *w, VehicleType type) { WP(w, depot_d).type = type; _backup_orders_tile = 0; @@ -974,7 +975,7 @@ * @param tile The tile where the depot/hangar is located * @param type The type of vehicles in the depot */ -void ShowDepotWindow(TileIndex tile, byte type) +void ShowDepotWindow(TileIndex tile, VehicleType type) { Window *w; diff -r 0b2aebc8283e -r 0b8b245a2391 src/disaster_cmd.cpp --- a/src/disaster_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/disaster_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -116,23 +116,18 @@ v->cur_image = img; } - /** Initialize a disaster vehicle. These vehicles are of type VEH_DISASTER, are unclickable * and owned by nobody */ static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype) { - v->type = VEH_DISASTER; + v = new (v) DisasterVehicle(); v->x_pos = x; v->y_pos = y; v->z_pos = z; v->tile = TileVirtXY(x, y); v->direction = direction; v->subtype = subtype; - v->x_offs = -1; - v->y_offs = -1; - v->sprite_width = 2; - v->sprite_height = 2; - v->z_height = 5; + v->UpdateDeltaXY(INVALID_DIR); v->owner = OWNER_NONE; v->vehstatus = VS_UNCLICKABLE; v->u.disaster.image_override = 0; @@ -1065,3 +1060,12 @@ { ResetDisasterDelay(); } + +void DisasterVehicle::UpdateDeltaXY(Direction direction) +{ + this->x_offs = -1; + this->y_offs = -1; + this->sprite_width = 2; + this->sprite_height = 2; + this->z_height = 5; +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/dock_gui.cpp --- a/src/dock_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/dock_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -53,12 +53,12 @@ static void PlaceDocks_DemolishArea(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DemolishArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_DemolishArea); } static void PlaceDocks_BuildCanal(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_OR_Y); + VpStartPlaceSizing(tile, VPM_X_OR_Y, GUI_PlaceProc_None); } static void PlaceDocks_BuildLock(TileIndex tile) @@ -147,16 +147,20 @@ break; case WE_PLACE_DRAG: { - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); return; } case WE_PLACE_MOUSEUP: if (e->we.place.pt.x != -1) { - if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) { // dragged actions - GUIPlaceProcDragXY(e); - } else if (e->we.place.userdata == VPM_X_OR_Y) { - DoCommandP(e->we.place.tile, e->we.place.starttile, 0, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS)); + switch (e->we.place.select_method) { + case VPM_X_AND_Y: + GUIPlaceProcDragXY(e); + break; + case VPM_X_OR_Y: + DoCommandP(e->we.place.tile, e->we.place.starttile, 0, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS)); + break; + default: break; } } break; diff -r 0b2aebc8283e -r 0b8b245a2391 src/economy.cpp --- a/src/economy.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/economy.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -38,6 +38,7 @@ #include "date.h" #include "cargotype.h" #include "player_face.h" +#include "group.h" /* Score info */ const ScoreInfo _score_info[] = { @@ -359,12 +360,14 @@ DeleteVehicle(v); } else { v->owner = new_player; + v->group_id = DEFAULT_GROUP; if (IsEngineCountable(v)) GetPlayer(new_player)->num_engines[v->engine_type]++; switch (v->type) { case VEH_TRAIN: if (IsFrontEngine(v)) v->unitnumber = ++num_train; break; case VEH_ROAD: v->unitnumber = ++num_road; break; case VEH_SHIP: v->unitnumber = ++num_ship; break; case VEH_AIRCRAFT: if (IsNormalAircraft(v)) v->unitnumber = ++num_aircraft; break; + default: NOT_REACHED(); } } } @@ -804,6 +807,7 @@ static void FindSubsidyCargoRoute(FoundRoute *fr) { Industry *i; + const IndustrySpec *ind; int trans, total; CargoID cargo; @@ -811,14 +815,15 @@ fr->from = i = GetRandomIndustry(); if (i == NULL) return; + ind = GetIndustrySpec(i->type); /* Randomize cargo type */ - if (Random()&1 && i->produced_cargo[1] != CT_INVALID) { - cargo = i->produced_cargo[1]; + if (HASBIT(Random(), 0) && ind->produced_cargo[1] != CT_INVALID) { + cargo = ind->produced_cargo[1]; trans = i->pct_transported[1]; total = i->total_production[1]; } else { - cargo = i->produced_cargo[0]; + cargo = ind->produced_cargo[0]; trans = i->pct_transported[0]; total = i->total_production[0]; } @@ -845,13 +850,19 @@ } else { /* The destination is an industry */ Industry *i2 = GetRandomIndustry(); + if (i2 == NULL) { + return; + } + + ind = GetIndustrySpec(i2->type); /* The industry must accept the cargo */ - if (i == i2 || i == NULL || - (cargo != i2->accepts_cargo[0] && - cargo != i2->accepts_cargo[1] && - cargo != i2->accepts_cargo[2])) + if (i == i2 || + (cargo != ind->accepts_cargo[0] && + cargo != ind->accepts_cargo[1] && + cargo != ind->accepts_cargo[2])) { return; + } fr->distance = DistanceManhattan(i->xy, i2->xy); fr->to = i2; } @@ -1025,34 +1036,48 @@ static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pieces) { - Industry* best = NULL; - Industry* ind; - uint u; + Industry *best = NULL; + Industry *ind; + const IndustrySpec *indspec; + uint best_dist; + uint accepted_cargo_index = 0; ///< unlikely value, just for warning removing /* Check if there's an industry close to the station that accepts the cargo * XXX - Think of something better to * 1) Only deliver to industries which are withing the catchment radius * 2) Distribute between industries if more then one is present */ - u = (_patches.station_spread + 8) * 2; + best_dist = (_patches.station_spread + 8) * 2; FOR_ALL_INDUSTRIES(ind) { - uint t; + indspec = GetIndustrySpec(ind->type); + uint i; - if (( cargo_type == ind->accepts_cargo[0] || - cargo_type == ind->accepts_cargo[1] || - cargo_type == ind->accepts_cargo[2] - ) && - ind->produced_cargo[0] != CT_INVALID && - ind->produced_cargo[0] != cargo_type && - (t = DistanceManhattan(ind->xy, xy)) < u) { - u = t; + if (indspec->produced_cargo[0] == CT_INVALID) continue; + + for (i = 0; i < lengthof(indspec->accepts_cargo); i++) { + if (cargo_type == indspec->accepts_cargo[i] && + (indspec->input_cargo_multiplier[i][0] != 0 || indspec->input_cargo_multiplier[i][1] != 0)) { + break; + } + } + + /* Check if matching cargo has been found */ + if (i == lengthof(indspec->accepts_cargo)) continue; + + uint dist = DistanceManhattan(ind->xy, xy); + + if (dist < best_dist) { best = ind; + best_dist = dist; + accepted_cargo_index = i; } } /* Found one? */ if (best != NULL) { + indspec = GetIndustrySpec(best->type); best->was_cargo_delivered = true; - best->cargo_waiting[0] = min(best->cargo_waiting[0] + num_pieces, 0xFFFF); + best->cargo_waiting[0] = min(best->cargo_waiting[0] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][0] / 256), 0xFFFF); + best->cargo_waiting[1] = min(best->cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF); } } @@ -1171,213 +1196,222 @@ return profit; } -/* - * Returns true if Vehicle v should wait loading because other vehicle is - * already loading the same cargo type - * v = vehicle to load, u = GetFirstInChain(v) +/** + * Performs the vehicle payment _and_ marks the vehicle to be unloaded. + * @param front_v the vehicle to be unloaded */ -static bool LoadWait(const Vehicle* v, const Vehicle* u) +void VehiclePayment(Vehicle *front_v) { - const Vehicle *w; - bool has_any_cargo = false; - - if (!(u->current_order.flags & OF_FULL_LOAD)) return false; + int result = 0; - for (w = u; w != NULL; w = w->next) { - if (w->cargo_count != 0) { - if (v->cargo_type == w->cargo_type && - u->last_station_visited == w->cargo_source) { - return false; + int profit = 0; + int total_veh_profit = 0; // accumulates the profit across the vehicle chain (used by trains) + int32 route_profit = 0; // the grand total amount for the route. A-D of transfer chain A-B-C-D + int virtual_profit = 0; // virtual profit of one vehicle element for feeder systems + int virtual_profit_total = 0; // virtual profit for entire vehicle chain + int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step + + int all_vehicles_cargo_feeder_share = front_v->cargo_feeder_share; // used to hold transfer value of complete vehicle chain - used by trains + + StationID last_visited = front_v->last_station_visited; + Station *st = GetStation(last_visited); + + /* The owner of the train wants to be paid */ + PlayerID old_player = _current_player; + _current_player = front_v->owner; + + /* At this moment loading cannot be finished */ + CLRBIT(front_v->vehicle_flags, VF_LOADING_FINISHED); + + /* Start unloading in at the first possible moment */ + front_v->load_unload_time_rem = 1; + + for (Vehicle *v = front_v; v != NULL; v = v->next) { + /* No cargo to unload */ + if (v->cargo_cap == 0 || v->cargo_count == 0) continue; + + SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING); + /* All cargo has already been paid for, no need to pay again */ + if (v->cargo_count == v->cargo_paid_for) continue; + + GoodsEntry *ge = &st->goods[v->cargo_type]; + + if (v->cargo_source != last_visited && + HASBIT(ge->waiting_acceptance, 15) && + (front_v->current_order.flags & OF_TRANSFER) == 0) { + /* Deliver goods to the station */ + st->time_since_unload = 0; + + /* handle end of route payment */ + profit += DeliverGoods(v->cargo_count - v->cargo_paid_for, v->cargo_type, v->cargo_source, last_visited, v->cargo_source_xy, v->cargo_days); + v->cargo_paid_for = v->cargo_count; + route_profit = profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D + total_veh_profit = profit - all_vehicles_cargo_feeder_share; // whole vehicle is not payed for transfers picked up earlier + total_cargo_feeder_share = -all_vehicles_cargo_feeder_share; // total of transfer fees in vehicle chain needs to be zero at end of unload + + v->cargo_feeder_share = 0; // clear transfer cost per vehicle + result |= 1; + } else if (front_v->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { + if ((front_v->current_order.flags & OF_TRANSFER) != 0) { + virtual_profit = GetTransportedGoodsIncome( + v->cargo_count - v->cargo_paid_for, + /* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */ + DistanceManhattan(v->cargo_loaded_at_xy, GetStation(last_visited)->xy), + v->cargo_days, + v->cargo_type); + + front_v->profit_this_year += virtual_profit; + ge->feeder_profit += v->cargo_feeder_share + virtual_profit; // transfer cargo transfer fees to station + total_cargo_feeder_share -= v->cargo_feeder_share; // accumulate deduction of feeder shares + v->cargo_feeder_share = 0; // clear transfer cost + + /* keep total of cargo unloaded (pending) for accurate cargoshare calculation on load */ + SB(ge->unload_pending, 0, 12, GB(ge->unload_pending, 0, 12) + v->cargo_count); + + virtual_profit_total += virtual_profit; // accumulate transfer profits for whole vehicle + v->cargo_paid_for = v->cargo_count; // record how much of the cargo has been paid for to eliminate double counting } - has_any_cargo = true; + result |= 2; } } - const Station *st = GetStation(u->last_station_visited); - std::list::const_iterator iter; - for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) { - const Vehicle *x = *iter; - if (!(x->vehstatus & (VS_STOPPED | VS_CRASHED)) && u != x) { - bool other_has_any_cargo = false; - bool has_space_for_same_type = false; - bool other_has_same_type = false; - - for (w = x; w != NULL; w = w->next) { - if (w->cargo_count < w->cargo_cap && v->cargo_type == w->cargo_type) { - has_space_for_same_type = true; - } + /* Ensure a negative total is only applied to the vehicle if there is value to reduce. */ + front_v->cargo_feeder_share = max(front_v->cargo_feeder_share + total_cargo_feeder_share, 0); - if (w->cargo_count != 0) { - if (v->cargo_type == w->cargo_type && - u->last_station_visited == w->cargo_source) { - other_has_same_type = true; - } - other_has_any_cargo = true; - } - } - - if (has_space_for_same_type) { - if (other_has_same_type) return true; - if (other_has_any_cargo && !has_any_cargo) return true; - } - } + if (virtual_profit_total > 0) { + ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit_total); } - return false; + if (route_profit != 0) { + front_v->profit_this_year += total_veh_profit; + SubtractMoneyFromPlayer(-route_profit); + + if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) { + SndPlayVehicleFx(SND_14_CASHTILL, front_v); + } + + ShowCostOrIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, -total_veh_profit); + } + + _current_player = old_player; } -int LoadUnloadVehicle(Vehicle *v, bool just_arrived) +/** + * Loads/unload the vehicle if possible. + * @param v the vehicle to be (un)loaded + * @param cargo_left the amount of each cargo type that is + * virtually left on the platform to be + * picked up by another vehicle when all + * previous vehicles have loaded. + */ +static void LoadUnloadVehicle(Vehicle *v, int *cargo_left) { - int profit = 0; - int total_veh_profit = 0; // accumulates the profit across the vehicle chain (used by trains) - int32 route_profit = 0; // the grand total amount for the route. A-D of transfer chain A-B-C-D - int virtual_profit = 0; // virtual profit of one vehicle element for feeder systems - int virtual_profit_total = 0; // virtual profit for entire vehicle chain - int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step + assert(v->current_order.type == OT_LOADING); - int unloading_time = 20; + /* We have not waited enough time till the next round of loading/unloading */ + if (--v->load_unload_time_rem != 0) { + if (_patches.improved_load && HASBIT(v->current_order.flags, OFB_FULL_LOAD)) { + /* 'Reserve' this cargo for this vehicle, because we were first. */ + for (; v != NULL; v = v->next) { + if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count; + } + } + return; + } + + int unloading_time = 0; Vehicle *u = v; int result = 0; - int t; - uint count, cap; - PlayerID old_player; - bool completely_empty = true; - byte load_amount; - bool anything_loaded = false; + int cap; - assert(v->current_order.type == OT_LOADING); + bool completely_empty = true; + bool anything_unloaded = false; + bool anything_loaded = false; + uint32 cargo_not_full = 0; + uint32 cargo_full = 0; + int total_cargo_feeder_share = 0; // the feeder cash amount for the goods being loaded/unloaded in this load step v->cur_speed = 0; - /* Loading can only have finished when all the cargo has been unloaded, and - * there is nothing left to load. It's easier to clear this if the - * conditions haven't been met than attempting to check them all before - * enabling though. */ - SETBIT(v->vehicle_flags, VF_LOADING_FINISHED); - - old_player = _current_player; - _current_player = v->owner; - StationID last_visited = v->last_station_visited; Station *st = GetStation(last_visited); - int all_vehicles_cargo_feeder_share = v->cargo_feeder_share; // used to hold transfer value of complete vehicle chain - used by trains + for (; v != NULL; v = v->next) { + if (v->cargo_cap == 0) continue; - for (; v != NULL; v = v->next) { - GoodsEntry* ge; - load_amount = EngInfo(v->engine_type)->load_amount; + byte load_amount = EngInfo(v->engine_type)->load_amount; if (_patches.gradual_loading && HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_LOAD_AMOUNT)) { uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v); if (cb_load_amount != CALLBACK_FAILED) load_amount = cb_load_amount & 0xFF; } - if (v->cargo_cap == 0) continue; - - /* If the vehicle has just arrived, set it to unload. */ - if (just_arrived) SETBIT(v->vehicle_flags, VF_CARGO_UNLOADING); + GoodsEntry *ge = &st->goods[v->cargo_type]; + int count = GB(ge->waiting_acceptance, 0, 12); - ge = &st->goods[v->cargo_type]; - count = GB(ge->waiting_acceptance, 0, 12); - - /* unload? */ - if (v->cargo_count != 0 && HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING)) { + if (HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING)) { uint16 amount_unloaded = _patches.gradual_loading ? min(v->cargo_count, load_amount) : v->cargo_count; - CLRBIT(u->vehicle_flags, VF_LOADING_FINISHED); - if (v->cargo_source != last_visited && ge->waiting_acceptance & 0x8000 && !(u->current_order.flags & OF_TRANSFER)) { - /* deliver goods to the station */ - st->time_since_unload = 0; - - unloading_time += v->cargo_count; // TTDBUG: bug in original TTD - - /* handle end of route payment */ - if (just_arrived && v->cargo_paid_for < v->cargo_count) { - profit += DeliverGoods(v->cargo_count - v->cargo_paid_for, v->cargo_type, v->cargo_source, last_visited, v->cargo_source_xy, v->cargo_days); - v->cargo_paid_for = v->cargo_count; - route_profit = profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D - total_veh_profit = profit - all_vehicles_cargo_feeder_share; // whole vehicle is not payed for transfers picked up earlier - total_cargo_feeder_share = -all_vehicles_cargo_feeder_share; // total of transfer fees in vehicle chain needs to be zero at end of unload - v->cargo_feeder_share = 0; // clear transfer cost per vehicle - } result |= 1; - v->cargo_count -= amount_unloaded; - v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for); - if (_patches.gradual_loading) continue; - } else if (u->current_order.flags & (OF_UNLOAD | OF_TRANSFER)) { - - /* unload goods and let it wait at the station */ - st->time_since_unload = 0; - - /* handle transfer */ - if (just_arrived && (u->current_order.flags & OF_TRANSFER) && v->cargo_paid_for < v->cargo_count) { - virtual_profit = GetTransportedGoodsIncome( - v->cargo_count - v->cargo_paid_for, - /* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */ - DistanceManhattan(v->cargo_loaded_at_xy, GetStation(last_visited)->xy), - v->cargo_days, - v->cargo_type); - - ge->feeder_profit += v->cargo_feeder_share; // transfer cargo transfer fees to station - total_cargo_feeder_share -= v->cargo_feeder_share; // accumulate deduction of feeder shares - v->cargo_feeder_share = 0; // clear transfer cost - - /* keep total of cargo unloaded (pending) for accurate cargoshare calculation on load */ - SB(ge->unload_pending, 0, 12, GB(ge->unload_pending, 0, 12) + v->cargo_count); - - virtual_profit_total += virtual_profit; // accumulate transfer profits for whole vehicle - v->cargo_paid_for = v->cargo_count; // record how much of the cargo has been paid for to eliminate double counting - } - - unloading_time += v->cargo_count; - t = GB(ge->waiting_acceptance, 0, 12); - if (t == 0) { + if (count == 0) { /* No goods waiting at station */ - ge->enroute_time = v->cargo_days; - ge->enroute_from = v->cargo_source; + ge->enroute_time = v->cargo_days; + ge->enroute_from = v->cargo_source; ge->enroute_from_xy = v->cargo_source_xy; } else { /* Goods already waiting at station. Set counters to the worst value. */ if (v->cargo_days >= ge->enroute_time) ge->enroute_time = v->cargo_days; if (last_visited != ge->enroute_from) { - ge->enroute_from = v->cargo_source; + ge->enroute_from = v->cargo_source; ge->enroute_from_xy = v->cargo_source_xy; } } - /* Update amount of waiting cargo */ - SB(ge->waiting_acceptance, 0, 12, min(amount_unloaded + t, 0xFFF)); + /* Update amount of waiting cargo. There is, however, no sense in + * updating the count variable because this vehicle will not be + * able to take the cargo. */ + SB(ge->waiting_acceptance, 0, 12, min(amount_unloaded + count, 0xFFF)); /* if there is not enough to unload from pending, ensure it does not go -ve * else deduct amount actually unloaded from unload_pending */ SB(ge->unload_pending, 0, 12, max(GB(ge->unload_pending, 0, 12) - amount_unloaded, 0U)); - if (u->current_order.flags & OF_TRANSFER) { - ge->feeder_profit += virtual_profit; - u->profit_this_year += virtual_profit; - } result |= 2; - v->cargo_count -= amount_unloaded; - v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for); - if (_patches.gradual_loading) continue; + } else { + /* The order changed while unloading (unset unload/transfer) or the + * station does not accept goods anymore. */ + CLRBIT(v->vehicle_flags, VF_CARGO_UNLOADING); + continue; } - if (v->cargo_count != 0) completely_empty = false; - } + /* Deliver goods to the station */ + st->time_since_unload = 0; - /* The vehicle must have been unloaded because it is either empty, or - * the UNLOADING bit is already clear in v->vehicle_flags. */ - CLRBIT(v->vehicle_flags, VF_CARGO_UNLOADING); + unloading_time += amount_unloaded; + + v->cargo_count -= amount_unloaded; + v->cargo_paid_for -= min(amount_unloaded, v->cargo_paid_for); + + anything_unloaded = true; + if (_patches.gradual_loading && v->cargo_count != 0) { + completely_empty = false; + } else { + /* We have finished unloading (cargo count == 0) */ + CLRBIT(v->vehicle_flags, VF_CARGO_UNLOADING); + } + + continue; + } /* We cannot have paid for more cargo than there is on board. */ assert(v->cargo_paid_for <= v->cargo_count); - /* don't pick up goods that we unloaded */ + /* Do not pick up goods that we unloaded */ if (u->current_order.flags & OF_UNLOAD) continue; /* update stats */ - ge->days_since_pickup = 0; + int t; switch (u->type) { case VEH_TRAIN: t = u->u.rail.cached_max_speed; break; case VEH_ROAD: t = u->max_speed / 2; break; @@ -1385,6 +1419,7 @@ } /* if last speed is 0, we treat that as if no vehicle has ever visited the station. */ + ge->days_since_pickup = 0; ge->last_speed = min(t, 255); ge->last_age = _cur_year - v->build_year; @@ -1393,11 +1428,22 @@ if (count != 0 && (cap = v->cargo_cap - v->cargo_count) != 0) { - if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); - /* Skip loading this vehicle if another train/vehicle is already handling * the same cargo type at this station */ - if (_patches.improved_load && (u->current_order.flags & OF_FULL_LOAD) && LoadWait(v,u)) continue; + if (_patches.improved_load && cargo_left[v->cargo_type] < 0) { + SETBIT(cargo_not_full, v->cargo_type); + continue; + } + + if (cap > count) cap = count; + if (_patches.gradual_loading) cap = min(cap, load_amount); + if (_patches.improved_load) { + /* Don't load stuff that is already 'reserved' for other vehicles */ + cap = min(cargo_left[v->cargo_type], cap); + cargo_left[v->cargo_type] -= cap; + } + + if (v->cargo_count == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); /* TODO: Regarding this, when we do gradual loading, we * should first unload all vehicles and then start @@ -1409,10 +1455,6 @@ completely_empty = false; anything_loaded = true; - if (cap > count) cap = count; - if (_patches.gradual_loading) cap = min(cap, load_amount); - if (cap < count) CLRBIT(u->vehicle_flags, VF_LOADING_FINISHED); - /* cargoshare is proportioned by the amount due to unload * Otherwise, with gradual loading, 100% of credits would be taken immediately, * even if the cargo volume represents a tiny percent of the whole. @@ -1437,31 +1479,54 @@ result |= 2; st->last_vehicle_type = v->type; } + + if (v->cargo_count == v->cargo_cap) { + SETBIT(cargo_full, v->cargo_type); + } else { + SETBIT(cargo_not_full, v->cargo_type); + } + } + + /* We update these variables here, so gradual loading still fills + * all wagons at the same time instead of using the same 'improved' + * loading algorithm for the wagons (only fill wagon when there is + * enough to fill the previous wagons) */ + if (_patches.improved_load && HASBIT(u->current_order.flags, OFB_FULL_LOAD)) { + /* Update left cargo */ + for (v = u; v != NULL; v = v->next) { + if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo_count; + } } v = u; - /* Ensure a negative total is only applied to the vehicle if there is value to reduce. */ - if (!((v->cargo_feeder_share == 0) && (total_cargo_feeder_share < 0))) - v->cargo_feeder_share += total_cargo_feeder_share; + v->cargo_feeder_share += total_cargo_feeder_share; - if (_patches.gradual_loading) { - /* The time it takes to load one 'slice' of cargo or passengers depends - * on the vehicle type - the values here are those found in TTDPatch */ - uint gradual_loading_wait_time[] = { 40, 20, 10, 20 }; + if (anything_loaded || anything_unloaded) { + if (_patches.gradual_loading) { + /* The time it takes to load one 'slice' of cargo or passengers depends + * on the vehicle type - the values here are those found in TTDPatch */ + const uint gradual_loading_wait_time[] = { 40, 20, 10, 20 }; - unloading_time = gradual_loading_wait_time[v->type]; - if (HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)) { - if (anything_loaded) { - unloading_time += 20; - } else { - unloading_time = 20; + unloading_time = gradual_loading_wait_time[v->type]; + } + } else { + bool finished_loading = true; + if (HASBIT(v->current_order.flags, OFB_FULL_LOAD)) { + if (_patches.full_load_any) { + /* if the aircraft carries passengers and is NOT full, then + * continue loading, no matter how much mail is in */ + if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap != v->cargo_count) || + (cargo_not_full && (cargo_full & ~cargo_not_full) == 0)) { // There are stull non-full cargos + finished_loading = false; + } + } else if (cargo_not_full != 0) { + finished_loading = false; } } - } + unloading_time = 20; - if (virtual_profit_total > 0) { - ShowFeederIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, virtual_profit_total); + SB(v->vehicle_flags, VF_LOADING_FINISHED, 1, finished_loading); } if (v->type == VEH_TRAIN) { @@ -1480,25 +1545,32 @@ } if (result != 0) { + InvalidateWindow(v->GetVehicleListWindowClass(), v->owner); InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + st->MarkTilesDirty(); + v->MarkDirty(); if (result & 2) InvalidateWindow(WC_STATION_VIEW, last_visited); - - if (route_profit != 0) { - v->profit_this_year += total_veh_profit; - SubtractMoneyFromPlayer(-route_profit); + } +} - if (IsLocalPlayer() && !PlayVehicleSound(v, VSE_LOAD_UNLOAD)) { - SndPlayVehicleFx(SND_14_CASHTILL, v); - } +/** + * Load/unload the vehicles in this station according to the order + * they entered. + * @param st the station to do the loading/unloading for + */ +void LoadUnloadStation(Station *st) +{ + int cargo_left[NUM_CARGO]; - ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, -total_veh_profit); - } + for (uint i = 0; i < NUM_CARGO; i++) cargo_left[i] = GB(st->goods[i].waiting_acceptance, 0, 12); + + std::list::iterator iter; + for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) { + Vehicle *v = *iter; + if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v, cargo_left); } - - _current_player = old_player; - return result; } void PlayersMonthlyLoop() diff -r 0b2aebc8283e -r 0b8b245a2391 src/economy.h --- a/src/economy.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/economy.h Wed Jun 13 11:45:14 2007 +0000 @@ -68,4 +68,7 @@ int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type); uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount); +void VehiclePayment(Vehicle *front_v); +void LoadUnloadStation(Station *st); + #endif /* ECONOMY_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/engine.cpp --- a/src/engine.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/engine.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -20,6 +20,7 @@ #include "newgrf_cargo.h" #include "date.h" #include "table/engines.h" +#include "group.h" EngineInfo _engine_info[TOTAL_NUM_ENGINES]; RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES]; @@ -70,6 +71,16 @@ { uint age = e->age; + /* Check for early retirement */ + if (e->player_avail != 0 && !_patches.never_expire_vehicles) { + uint retire_early = EngInfo(e - _engines)->retire_early; + if (retire_early > 0 && age >= e->duration_phase_1 + e->duration_phase_2 - retire_early * 12) { + /* Early retirement is enabled and we're past the date... */ + e->player_avail = 0; + AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); + } + } + if (age < e->duration_phase_1) { uint start = e->reliability_start; e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start; @@ -401,6 +412,12 @@ /* check if it's available */ if (!HASBIT(e->player_avail, player)) return false; + if (type == VEH_TRAIN) { + /* Check if the rail type is available to this player */ + const Player *p = GetPlayer(player); + if (!HASBIT(p->avail_railtypes, RailVehInfo(engine)->railtype)) return false; + } + return true; } @@ -465,6 +482,7 @@ er->to = INVALID_ENGINE; er->next = NULL; + er->group_id = DEFAULT_GROUP; return er; } @@ -477,12 +495,12 @@ /** * Retrieves the EngineRenew that specifies the replacement of the given * engine type from the given renewlist */ -static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine) +static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) { EngineRenew *er = (EngineRenew *)erl; while (er) { - if (er->from == engine) return er; + if (er->from == engine && er->group_id == group) return er; er = er->next; } return NULL; @@ -501,18 +519,18 @@ *erl = NULL; // Empty list } -EngineID EngineReplacement(EngineRenewList erl, EngineID engine) +EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) { - const EngineRenew *er = GetEngineReplacement(erl, engine); + const EngineRenew *er = GetEngineReplacement(erl, engine, group); return er == NULL ? INVALID_ENGINE : er->to; } -int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, uint32 flags) +int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags) { EngineRenew *er; /* Check if the old vehicle is already in the list */ - er = GetEngineReplacement(*erl, old_engine); + er = GetEngineReplacement(*erl, old_engine, group); if (er != NULL) { if (flags & DC_EXEC) er->to = new_engine; return 0; @@ -524,6 +542,7 @@ if (flags & DC_EXEC) { er->from = old_engine; er->to = new_engine; + er->group_id = group; /* Insert before the first element */ er->next = (EngineRenew *)(*erl); @@ -533,14 +552,14 @@ return 0; } -int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, uint32 flags) +int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags) { EngineRenew *er = (EngineRenew *)(*erl); EngineRenew *prev = NULL; while (er) { - if (er->from == engine) { + if (er->from == engine && er->group_id == group) { if (flags & DC_EXEC) { if (prev == NULL) { // First element /* The second becomes the new first element */ @@ -561,11 +580,11 @@ } static const SaveLoad _engine_renew_desc[] = { - SLE_VAR(EngineRenew, from, SLE_UINT16), - SLE_VAR(EngineRenew, to, SLE_UINT16), + SLE_VAR(EngineRenew, from, SLE_UINT16), + SLE_VAR(EngineRenew, to, SLE_UINT16), - SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS), - + SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS), + SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION), SLE_END() }; @@ -591,6 +610,9 @@ er = GetEngineRenew(index); SlObject(er, _engine_renew_desc); + + /* Advanced vehicle lists got added */ + if (CheckSavegameVersion(60)) er->group_id = DEFAULT_GROUP; } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/engine.h --- a/src/engine.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/engine.h Wed Jun 13 11:45:14 2007 +0000 @@ -16,6 +16,14 @@ RAILVEH_WAGON, ///< simple wagon, not motorized }; +enum EngineClass { + EC_STEAM, + EC_DIESEL, + EC_ELECTRIC, + EC_MONORAIL, + EC_MAGLEV, +}; + struct RailVehicleInfo { byte image_index; RailVehicleTypes railveh_type; @@ -26,7 +34,7 @@ uint16 weight; byte running_cost_base; byte running_cost_class; - byte engclass; ///< 0: steam, 1: diesel, 2: electric + EngineClass engclass; ///< Class of engine for this vehicle byte capacity; CargoID cargo_type; byte ai_rank; @@ -97,6 +105,7 @@ byte refit_cost; byte misc_flags; byte callbackmask; + byte retire_early; ///< Number of years early to retire vehicle }; struct Engine { @@ -111,7 +120,7 @@ PlayerByte preview_player; byte preview_wait; byte player_avail; - byte type; ///< type, ie VEH_ROAD, VEH_TRAIN, etc. Same as in vehicle.h + VehicleType type; ///< type, ie VEH_ROAD, VEH_TRAIN, etc. Same as in vehicle.h }; /** @@ -263,6 +272,7 @@ EngineID from; EngineID to; EngineRenew *next; + GroupID group_id; }; /** @@ -308,7 +318,7 @@ * @return The engine type to replace with, or INVALID_ENGINE if no * replacement is in the list. */ -EngineID EngineReplacement(EngineRenewList erl, EngineID engine); +EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group); /** * Add an engine replacement to the given renewlist. @@ -318,7 +328,7 @@ * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -int32 AddEngineReplacement(EngineRenewList* erl, EngineID old_engine, EngineID new_engine, uint32 flags); +int32 AddEngineReplacement(EngineRenewList* erl, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags); /** * Remove an engine replacement from a given renewlist. @@ -327,12 +337,12 @@ * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -int32 RemoveEngineReplacement(EngineRenewList* erl, EngineID engine, uint32 flags); +int32 RemoveEngineReplacement(EngineRenewList* erl, EngineID engine, GroupID group, uint32 flags); /** When an engine is made buildable or is removed from being buildable, add/remove it from the build/autoreplace lists * @param type The type of engine */ -void AddRemoveEngineFromAutoreplaceAndBuildWindows(byte type); +void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type); /* Engine list manipulators - current implementation is only C wrapper of CBlobT class (helpers.cpp) */ void EngList_Create(EngineList *el); ///< Creates engine list diff -r 0b2aebc8283e -r 0b8b245a2391 src/functions.h --- a/src/functions.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/functions.h Wed Jun 13 11:45:14 2007 +0000 @@ -30,7 +30,6 @@ /* standard */ void ShowInfo(const char *str); void CDECL ShowInfoF(const char *str, ...); -void NORETURN CDECL error(const char *str, ...); /* openttd.cpp */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/genworld.cpp --- a/src/genworld.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/genworld.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -10,6 +10,7 @@ #include "table/sprites.h" #include "variables.h" #include "thread.h" +#include "command.h" #include "genworld.h" #include "gfx.h" #include "gfxinit.h" @@ -153,6 +154,8 @@ if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game"); + if (_patches.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, NULL, CMD_PAUSE); + return NULL; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/genworld_gui.cpp --- a/src/genworld_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/genworld_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -199,7 +199,7 @@ } } -static void HeightmapScaledTooMuchCallback(Window *w, bool confirmed) +static void LandscapeGenerationCallback(Window *w, bool confirmed) { if (confirmed) StartGeneratingLandscape((glwp_modes)w->window_number); } @@ -213,8 +213,8 @@ static const StringID tree_placer[] = {STR_CONFIG_PATCHES_TREE_PLACER_NONE, STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL, STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED, INVALID_STRING_ID}; static const StringID rotation[] = {STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID}; static const StringID landscape[] = {STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL, STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID}; - static const StringID num_towns[] = {STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID}; - static const StringID num_inds[] = {STR_26816_NONE, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID}; + static const StringID num_towns[] = {STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID}; + static const StringID num_inds[] = {STR_26816_NONE, STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID}; /* Data used for the generate seed edit box */ static querystr_d _genseed_query; @@ -354,14 +354,26 @@ SetWindowDirty(w); break; case GLAND_GENERATE_BUTTON: // Generate - if (mode == GLWP_HEIGHTMAP && ( - _heightmap_x * 2 < (1U << _patches_newgame.map_x) || _heightmap_x / 2 > (1U << _patches_newgame.map_x) || - _heightmap_y * 2 < (1U << _patches_newgame.map_y) || _heightmap_y / 2 > (1U << _patches_newgame.map_y))) { + + UpdatePatches(); + + if (_patches.town_layout == TL_NO_ROADS) { + ShowQuery( + STR_TOWN_LAYOUT_WARNING_CAPTION, + STR_TOWN_LAYOUT_WARNING_MESSAGE, + w, + LandscapeGenerationCallback); + } else if (mode == GLWP_HEIGHTMAP && + (_heightmap_x * 2 < (1U << _patches_newgame.map_x) || + _heightmap_x / 2 > (1U << _patches_newgame.map_x) || + _heightmap_y * 2 < (1U << _patches_newgame.map_y) || + _heightmap_y / 2 > (1U << _patches_newgame.map_y))) { ShowQuery( STR_HEIGHTMAP_SCALE_WARNING_CAPTION, STR_HEIGHTMAP_SCALE_WARNING_MESSAGE, w, - HeightmapScaledTooMuchCallback); + LandscapeGenerationCallback); + } else { StartGeneratingLandscape(mode); } @@ -545,6 +557,10 @@ void StartScenarioEditor() { + if (_patches_newgame.town_layout == TL_NO_ROADS) { + _patches_newgame.town_layout = TL_ORIGINAL; + } + StartGeneratingLandscape(GLWP_SCENARIO); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/gfx.cpp --- a/src/gfx.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/gfx.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -18,6 +18,7 @@ #include "fontcache.h" #include "genworld.h" #include "debug.h" +#include "zoom.hpp" #ifdef _DEBUG bool _dbg_screen_rect; @@ -64,12 +65,12 @@ void memcpy_pitch(void *dst, void *src, int w, int h, int srcpitch, int dstpitch) { - byte *dstp = (byte*)dst; - byte *srcp = (byte*)src; + Pixel *dstp = (Pixel *)dst; + Pixel *srcp = (Pixel *)src; assert(h >= 0); for (; h != 0; --h) { - memcpy(dstp, srcp, w); + memcpy(dstp, srcp, w * sizeof(Pixel)); dstp += dstpitch; srcp += srcpitch; } @@ -110,7 +111,7 @@ } for (ht = height; ht > 0; --ht) { - memcpy(dst, src, width); + memcpy(dst, src, width * sizeof(Pixel)); src -= p; dst -= p; } @@ -136,7 +137,7 @@ /* the y-displacement may be 0 therefore we have to use memmove, * because source and destination may overlap */ for (ht = height; ht > 0; --ht) { - memmove(dst, src, width); + memmove(dst, src, width * sizeof(Pixel)); src += p; dst += p; } @@ -153,7 +154,7 @@ const int otop = top; const int oleft = left; - if (dpi->zoom != 0) return; + if (dpi->zoom != ZOOM_LVL_NORMAL) return; if (left > right || top > bottom) return; if (right < dpi->left || left >= dpi->left + dpi->width) return; if (bottom < dpi->top || top >= dpi->top + dpi->height) return; @@ -175,7 +176,7 @@ if (!HASBIT(color, PALETTE_MODIFIER_GREYOUT)) { if (!HASBIT(color, USE_COLORTABLE)) { do { - memset(dst, color, right); + memset(dst, color, right * sizeof(Pixel)); dst += dpi->pitch; } while (--bottom); } else { @@ -737,142 +738,7 @@ int pitch; }; -static void GfxBlitTileZoomIn(BlitterParams *bp) -{ - const byte *src_o = bp->sprite; - const byte *src; - int num, skip; - byte done; - Pixel *dst; - const byte *ctab; - - src_o += ReadLE16Aligned(src_o + bp->start_y * 2); - switch (bp->mode) { - case BM_COLOUR_REMAP: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - - if ( (skip -= bp->start_x) > 0) { - dst += skip; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - ctab = _color_remap_ptr; - - for (; num >= 4; num -=4) { - dst[3] = ctab[src[3]]; - dst[2] = ctab[src[2]]; - dst[1] = ctab[src[1]]; - dst[0] = ctab[src[0]]; - dst += 4; - src += 4; - } - for (; num != 0; num--) *dst++ = ctab[*src++]; - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - } while (--bp->height != 0); - break; - - case BM_TRANSPARENT: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src_o += num + 2; - - dst = bp->dst; - - if ( (skip -= bp->start_x) > 0) { - dst += skip; - } else { - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - ctab = _color_remap_ptr; - for (; num != 0; num--) { - *dst = ctab[*dst]; - dst++; - } - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - } while (--bp->height != 0); - break; - - default: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - - if ( (skip -= bp->start_x) > 0) { - dst += skip; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } -#if defined(_WIN32) - if (num & 1) *dst++ = *src++; - if (num & 2) { *(uint16*)dst = *(uint16*)src; dst += 2; src += 2; } - if (num >>= 2) { - do { - *(uint32*)dst = *(uint32*)src; - dst += 4; - src += 4; - } while (--num != 0); - } -#else - memcpy(dst, src, num); -#endif - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - } while (--bp->height != 0); - break; - } -} - -static void GfxBlitZoomInUncomp(BlitterParams *bp) +static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom) { const byte *src = bp->sprite; Pixel *dst = bp->dst; @@ -883,62 +749,48 @@ assert(height > 0); assert(width > 0); + height = UnScaleByZoom(height, zoom); + switch (bp->mode) { case BM_COLOUR_REMAP: { const byte *ctab = _color_remap_ptr; - do { - for (i = 0; i != width; i++) { - byte b = ctab[src[i]]; + for (; height != 0; height--) { + for (i = 0; i != UnScaleByZoom(width, zoom); i++) { + byte b = ctab[src[ScaleByZoom(i, zoom)]]; if (b != 0) dst[i] = b; } - src += bp->width_org; + src += ScaleByZoom(bp->width_org, zoom); dst += bp->pitch; - } while (--height != 0); + } break; } case BM_TRANSPARENT: { const byte *ctab = _color_remap_ptr; - do { - for (i = 0; i != width; i++) - if (src[i] != 0) dst[i] = ctab[dst[i]]; - src += bp->width_org; + for (; height != 0; height--) { + for (i = 0; i != UnScaleByZoom(width, zoom); i++) + if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = ctab[dst[i]]; + src += ScaleByZoom(bp->width_org, zoom); dst += bp->pitch; - } while (--height != 0); + } break; } default: - do { - int n = width; - - for (; n >= 4; n -= 4) { - if (src[0] != 0) dst[0] = src[0]; - if (src[1] != 0) dst[1] = src[1]; - if (src[2] != 0) dst[2] = src[2]; - if (src[3] != 0) dst[3] = src[3]; - - dst += 4; - src += 4; - } - - for (; n != 0; n--) { - if (src[0] != 0) dst[0] = src[0]; - src++; - dst++; - } - - src += bp->width_org - width; - dst += bp->pitch - width; - } while (--height != 0); + for (; height != 0; height--) { + for (i = 0; i != UnScaleByZoom(width, zoom); i++) + if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = src[ScaleByZoom(i, zoom)]; + src += ScaleByZoom(bp->width_org, zoom); + dst += bp->pitch; + } break; } } -static void GfxBlitTileZoomMedium(BlitterParams *bp) +static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom) { const byte *src_o = bp->sprite; const byte *src; @@ -948,484 +800,111 @@ const byte *ctab; src_o += ReadLE16Aligned(src_o + bp->start_y * 2); - switch (bp->mode) { - case BM_COLOUR_REMAP: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - if (skip & 1) { - skip++; - src++; - if (--num == 0) continue; - } + for (;;) { + do { + done = src_o[0]; + num = done & 0x7F; + skip = src_o[1]; + src = src_o + 2; + src_o += num + 2; - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 1; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } + dst = bp->dst; - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } + if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) { + skip += 1; + src += 1; + num -= 1; + if (num <= 0) continue; + } + if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) { + skip += 2; + src += 2; + num -= 2; + if (num <= 0) continue; + } + + if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) { + skip += 4; + src += 4; + num -= 4; + if (num <= 0) continue; + } + + if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) { + skip += 8; + src += 8; + num -= 8; + if (num <= 0) continue; + } + + if ( (skip -= bp->start_x) > 0) { + dst += UnScaleByZoom(skip, zoom); + } else { + src -= skip; + num += skip; + if (num <= 0) continue; + skip = 0; + } + + skip = skip + num - bp->width; + if (skip > 0) { + num -= skip; + if (num <= 0) continue; + } + + num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom); + + switch (bp->mode) { + case BM_COLOUR_REMAP: ctab = _color_remap_ptr; - num = (num + 1) >> 1; for (; num != 0; num--) { *dst = ctab[*src]; dst++; - src += 2; + src += ScaleByZoom(1, zoom); } - } while (!(done & 0x80)); - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - } while (--bp->height != 0); - break; - - case BM_TRANSPARENT: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src_o += num + 2; + break; - dst = bp->dst; - - if (skip & 1) { - skip++; - if (--num == 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 1; - } else { - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - + case BM_TRANSPARENT: ctab = _color_remap_ptr; - num = (num + 1) >> 1; for (; num != 0; num--) { *dst = ctab[*dst]; dst++; } - } while (!(done & 0x80)); - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - } while (--bp->height != 0); - break; - - default: - do { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; + break; - if (skip & 1) { - skip++; - src++; - if (--num == 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 1; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - num = (num + 1) >> 1; - + default: for (; num != 0; num--) { *dst = *src; dst++; - src += 2; + src += ScaleByZoom(1, zoom); } - - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - } while (--bp->height != 0); - break; - } -} - -static void GfxBlitZoomMediumUncomp(BlitterParams *bp) -{ - const byte *src = bp->sprite; - Pixel *dst = bp->dst; - int height = bp->height; - int width = bp->width; - int i; - - assert(height > 0); - assert(width > 0); - - switch (bp->mode) { - case BM_COLOUR_REMAP: { - const byte *ctab = _color_remap_ptr; + break; + } - for (height >>= 1; height != 0; height--) { - for (i = 0; i != width >> 1; i++) { - byte b = ctab[src[i * 2]]; - - if (b != 0) dst[i] = b; - } - src += bp->width_org * 2; - dst += bp->pitch; - } - break; - } - - case BM_TRANSPARENT: { - const byte *ctab = _color_remap_ptr; - for (height >>= 1; height != 0; height--) { - for (i = 0; i != width >> 1; i++) - if (src[i * 2] != 0) dst[i] = ctab[dst[i]]; - src += bp->width_org * 2; - dst += bp->pitch; - } - break; + } while (!(done & 0x80)); + + bp->dst += bp->pitch; + if (--bp->height == 0) return; + + for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) { + do { + done = src_o[0]; + src_o += (done & 0x7F) + 2; + } while (!(done & 0x80)); + if (--bp->height == 0) return; } - - default: - for (height >>= 1; height != 0; height--) { - for (i = 0; i != width >> 1; i++) - if (src[i * 2] != 0) dst[i] = src[i * 2]; - src += bp->width_org * 2; - dst += bp->pitch; - } - break; } } -static void GfxBlitTileZoomOut(BlitterParams *bp) -{ - const byte *src_o = bp->sprite; - const byte *src; - int num, skip; - byte done; - Pixel *dst; - const byte *ctab; - - src_o += ReadLE16Aligned(src_o + bp->start_y * 2); - switch (bp->mode) { - case BM_COLOUR_REMAP: - for (;;) { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - - if (skip & 1) { - skip++; - src++; - if (--num == 0) continue; - } - - if (skip & 2) { - skip += 2; - src += 2; - num -= 2; - if (num <= 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 2; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - ctab = _color_remap_ptr; - num = (num + 3) >> 2; - for (; num != 0; num--) { - *dst = ctab[*src]; - dst++; - src += 4; - } - } while (!(done & 0x80)); - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - } - break; - - case BM_TRANSPARENT: - for (;;) { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src_o += num + 2; - - dst = bp->dst; - - if (skip & 1) { - skip++; - if (--num == 0) continue; - } - - if (skip & 2) { - skip += 2; - num -= 2; - if (num <= 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 2; - } else { - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - ctab = _color_remap_ptr; - num = (num + 3) >> 2; - for (; num != 0; num--) { - *dst = ctab[*dst]; - dst++; - } - - } while (!(done & 0x80)); - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - } - break; - - default: - for (;;) { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - - if (skip & 1) { - skip++; - src++; - if (--num == 0) continue; - } - - if (skip & 2) { - skip += 2; - src += 2; - num -= 2; - if (num <= 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += skip >> 2; - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - num = (num + 3) >> 2; - - for (; num != 0; num--) { - *dst = *src; - dst++; - src += 4; - } - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - } - break; - } -} - -static void GfxBlitZoomOutUncomp(BlitterParams *bp) -{ - const byte *src = bp->sprite; - Pixel *dst = bp->dst; - int height = bp->height; - int width = bp->width; - int i; - - assert(height > 0); - assert(width > 0); - - switch (bp->mode) { - case BM_COLOUR_REMAP: { - const byte *ctab = _color_remap_ptr; - - for (height >>= 2; height != 0; height--) { - for (i = 0; i != width >> 2; i++) { - byte b = ctab[src[i * 4]]; - - if (b != 0) dst[i] = b; - } - src += bp->width_org * 4; - dst += bp->pitch; - } - break; - } - - case BM_TRANSPARENT: { - const byte *ctab = _color_remap_ptr; - - for (height >>= 2; height != 0; height--) { - for (i = 0; i != width >> 2; i++) - if (src[i * 4] != 0) dst[i] = ctab[dst[i]]; - src += bp->width_org * 4; - dst += bp->pitch; - } - break; - } - - default: - for (height >>= 2; height != 0; height--) { - for (i = 0; i != width >> 2; i++) - if (src[i * 4] != 0) dst[i] = src[i * 4]; - src += bp->width_org * 4; - dst += bp->pitch; - } - break; - } -} - - static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode) { const DrawPixelInfo *dpi = _cur_dpi; int start_x, start_y; BlitterParams bp; - int zoom_mask = ~((1 << dpi->zoom) - 1); + int zoom_mask = ~(ScaleByZoom(1, dpi->zoom) - 1); /* decode sprite header */ x += sprite->x_offs; @@ -1444,7 +923,7 @@ /* tile blit */ start_y = 0; - if (dpi->zoom > 0) { + if (dpi->zoom > ZOOM_LVL_NORMAL) { start_y += bp.height & ~zoom_mask; bp.height &= zoom_mask; if (bp.height == 0) return; @@ -1457,7 +936,7 @@ start_y -= y; y = 0; } else { - bp.dst += bp.pitch * (y >> dpi->zoom); + bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); } bp.start_y = start_y; @@ -1475,19 +954,14 @@ x = 0; } bp.start_x = start_x; - bp.dst += x >> dpi->zoom; + bp.dst += UnScaleByZoom(x, dpi->zoom); if ( (x = x + bp.width - dpi->width) > 0) { bp.width -= x; if (bp.width <= 0) return; } - switch (dpi->zoom) { - default: NOT_REACHED(); - case 0: GfxBlitTileZoomIn(&bp); break; - case 1: GfxBlitTileZoomMedium(&bp); break; - case 2: GfxBlitTileZoomOut(&bp); break; - } + GfxBlitTileZoom(&bp, dpi->zoom); } else { bp.sprite += bp.width * (bp.height & ~zoom_mask); bp.height &= zoom_mask; @@ -1501,7 +975,7 @@ bp.sprite -= bp.width * y; y = 0; } else { - bp.dst += bp.pitch * (y >> dpi->zoom); + bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); } if (bp.height > dpi->height - y) { @@ -1517,19 +991,14 @@ bp.sprite -= x; x = 0; } - bp.dst += x >> dpi->zoom; + bp.dst += UnScaleByZoom(x, dpi->zoom); if (bp.width > dpi->width - x) { bp.width = dpi->width - x; if (bp.width <= 0) return; } - switch (dpi->zoom) { - default: NOT_REACHED(); - case 0: GfxBlitZoomInUncomp(&bp); break; - case 1: GfxBlitZoomMediumUncomp(&bp); break; - case 2: GfxBlitZoomOutUncomp(&bp); break; - } + GfxBlitZoomUncomp(&bp, dpi->zoom); } } @@ -1946,7 +1415,7 @@ { const DrawPixelInfo *o = _cur_dpi; - n->zoom = 0; + n->zoom = ZOOM_LVL_NORMAL; assert(width > 0); assert(height > 0); diff -r 0b2aebc8283e -r 0b8b245a2391 src/gfx.h --- a/src/gfx.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/gfx.h Wed Jun 13 11:45:14 2007 +0000 @@ -6,6 +6,7 @@ #define GFX_H #include "openttd.h" +#include "zoom.hpp" enum WindowKeyCodes { WKC_SHIFT = 0x8000, @@ -136,7 +137,7 @@ Pixel *dst_ptr; int left, top, width, height; int pitch; - uint16 zoom; + ZoomLevel zoom; }; struct Colour { diff -r 0b2aebc8283e -r 0b8b245a2391 src/gfxinit.cpp --- a/src/gfxinit.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/gfxinit.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -393,6 +393,9 @@ assert(load_index == SPR_ROADSTOP_BASE); load_index += LoadGrfFile("roadstops.grf", load_index, i++); + assert(load_index == SPR_GROUP_BASE); + load_index += LoadGrfFile("group.grf", load_index, i++); + /* Initialize the unicode to sprite mapping table */ InitializeUnicodeGlyphMap(); diff -r 0b2aebc8283e -r 0b8b245a2391 src/group.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/group.h Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,97 @@ +/* $Id$ */ + +/** @file group.h */ + +#ifndef GROUP_H +#define GROUP_H + +#include "oldpool.h" + +enum { + DEFAULT_GROUP = 0xFFFE, + INVALID_GROUP = 0xFFFF, +}; + +struct Group { + StringID string_id; ///< Group Name + + uint16 num_vehicle; ///< Number of vehicles wich belong to the group + PlayerID owner; ///< Group Owner + GroupID index; ///< Array index + VehicleTypeByte vehicle_type; ///< Vehicle type of the group + + bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group + uint16 num_engines[TOTAL_NUM_ENGINES]; ///< Caches the number of engines of each type the player owns (no need to save this) +}; + +DECLARE_OLD_POOL(Group, Group, 5, 2047) + + +static inline bool IsValidGroup(const Group *g) +{ + return g->string_id != STR_NULL; +} + +static inline void DestroyGroup(Group *g) +{ + DeleteName(g->string_id); +} + +static inline void DeleteGroup(Group *g) +{ + DestroyGroup(g); + g->string_id = STR_NULL; +} + +static inline bool IsValidGroupID(GroupID index) +{ + return index < GetGroupPoolSize() && IsValidGroup(GetGroup(index)); +} + +static inline bool IsDefaultGroupID(GroupID index) +{ + return (index == DEFAULT_GROUP); +} + +static inline StringID GetGroupName(GroupID index) +{ + if (!IsValidGroupID(index)) return STR_NULL; + + return GetGroup(index)->string_id; +} + + +#define FOR_ALL_GROUPS_FROM(g, start) for (g = GetGroup(start); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) if (IsValidGroup(g)) +#define FOR_ALL_GROUPS(g) FOR_ALL_GROUPS_FROM(g, 0) + +/** + * Get the current size of the GroupPool + */ +static inline uint GetGroupArraySize(void) +{ + const Group *g; + uint num = 0; + + FOR_ALL_GROUPS(g) num++; + + return num; +} + +static inline void IncreaseGroupNumVehicle(GroupID id_g) +{ + if (IsValidGroupID(id_g)) GetGroup(id_g)->num_vehicle++; +} + +static inline void DecreaseGroupNumVehicle(GroupID id_g) +{ + if (IsValidGroupID(id_g)) GetGroup(id_g)->num_vehicle--; +} + + +void InitializeGroup(); +void SetTrainGroupID(Vehicle *v, GroupID grp); +void UpdateTrainGroupID(Vehicle *v); +void RemoveVehicleFromGroup(const Vehicle *v); +void RemoveAllGroupsForPlayer(const Player *p); + +#endif /* GROUP_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/group_cmd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/group_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,448 @@ +/* $Id$ */ + +/** @file group_cmd.cpp Handling of the engine groups */ + +#include "stdafx.h" +#include "openttd.h" +#include "functions.h" +#include "player.h" +#include "table/strings.h" +#include "command.h" +#include "vehicle.h" +#include "saveload.h" +#include "debug.h" +#include "group.h" +#include "train.h" +#include "aircraft.h" +#include "string.h" +#include "window.h" +#include "vehicle_gui.h" + +/** + * Update the num engines of a groupID. Decrease the old one and increase the new one + * @note called in SetTrainGroupID and UpdateTrainGroupID + * @param i EngineID we have to update + * @param old_g index of the old group + * @param new_g index of the new group + */ +static inline void UpdateNumEngineGroup(EngineID i, GroupID old_g, GroupID new_g) +{ + if (old_g != new_g) { + /* Decrease the num engines of EngineID i of the old group if it's not the default one */ + if (!IsDefaultGroupID(old_g) && IsValidGroupID(old_g)) GetGroup(old_g)->num_engines[i]--; + + /* Increase the num engines of EngineID i of the new group if it's not the new one */ + if (!IsDefaultGroupID(new_g) && IsValidGroupID(new_g)) GetGroup(new_g)->num_engines[i]++; + } +} + + +/** + * Called if a new block is added to the group-pool + */ +static void GroupPoolNewBlock(uint start_item) +{ + /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. + * TODO - This is just a temporary stage, this will be removed. */ + for (Group *g = GetGroup(start_item); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) g->index = start_item++; +} + +DEFINE_OLD_POOL(Group, Group, GroupPoolNewBlock, NULL) + +static Group *AllocateGroup(void) +{ + /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. + * TODO - This is just a temporary stage, this will be removed. */ + for (Group *g = GetGroup(0); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) { + if (!IsValidGroup(g)) { + const GroupID index = g->index; + + memset(g, 0, sizeof(*g)); + g->index = index; + + return g; + } + } + + /* Check if we can add a block to the pool */ + return (AddBlockToPool(&_Group_pool)) ? AllocateGroup() : NULL; +} + +void InitializeGroup(void) +{ + CleanPool(&_Group_pool); + AddBlockToPool(&_Group_pool); +} + + +static WindowClass GetWCForVT(VehicleType vt) +{ + switch (vt) { + default: + case VEH_TRAIN: return WC_TRAINS_LIST; + case VEH_ROAD: return WC_ROADVEH_LIST; + case VEH_SHIP: return WC_SHIPS_LIST; + case VEH_AIRCRAFT: return WC_AIRCRAFT_LIST; + } +} + + +/** + * Add a vehicle to a group + * @param tile unused + * @param p1 vehicle type + * @param p2 unused + */ +int32 CmdCreateGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + VehicleType vt = (VehicleType)p1; + if (!IsPlayerBuildableVehicleType(vt)) return CMD_ERROR; + + Group *g = AllocateGroup(); + if (g == NULL) return CMD_ERROR; + + if (flags & DC_EXEC) { + g->owner = _current_player; + g->string_id = STR_SV_GROUP_NAME; + g->replace_protection = false; + g->vehicle_type = vt; + + InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + + +/** + * Add a vehicle to a group + * @param tile unused + * @param p1 index of array group + * - p1 bit 0-15 : GroupID + * @param p2 unused + */ +int32 CmdDeleteGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + if (!IsValidGroupID(p1)) return CMD_ERROR; + + Group *g = GetGroup(p1); + if (g->owner != _current_player) return CMD_ERROR; + + if (flags & DC_EXEC) { + Vehicle *v; + + /* Add all vehicles belong to the group to the default group */ + FOR_ALL_VEHICLES(v) { + if (v->group_id == g->index && v->type == g->vehicle_type) v->group_id = DEFAULT_GROUP; + } + + /* If we set an autoreplace for the group we delete, remove it. */ + if (_current_player < MAX_PLAYERS) { + Player *p; + EngineRenew *er; + + p = GetPlayer(_current_player); + FOR_ALL_ENGINE_RENEWS(er) { + if (er->group_id == g->index) RemoveEngineReplacementForPlayer(p, er->from, g->index, flags); + } + } + + VehicleType vt = g->vehicle_type; + + /* Delete the Replace Vehicle Windows */ + DeleteWindowById(WC_REPLACE_VEHICLE, g->vehicle_type); + DeleteGroup(g); + + InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + + +/** + * Rename a group + * @param tile unused + * @param p1 index of array group + * - p1 bit 0-15 : GroupID + * @param p2 unused + */ +int32 CmdRenameGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + if (!IsValidGroupID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR; + + Group *g = GetGroup(p1); + if (g->owner != _current_player) return CMD_ERROR; + + /* Create the name */ + StringID str = AllocateName(_cmd_text, 0); + if (str == STR_NULL) return CMD_ERROR; + + if (flags & DC_EXEC) { + /* Delete the old name */ + DeleteName(g->string_id); + /* Assign the new one */ + g->string_id = str; + + InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + + +/** + * Add a vehicle to a group + * @param tile unused + * @param p1 index of array group + * - p1 bit 0-15 : GroupID + * @param p2 vehicle to add to a group + * - p2 bit 0-15 : VehicleID + */ +int32 CmdAddVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + GroupID new_g = p1; + + if (!IsValidVehicleID(p2) || (!IsValidGroupID(new_g) && !IsDefaultGroupID(new_g))) return CMD_ERROR; + + Group *g = GetGroup(new_g); + if (g->owner != _current_player) return CMD_ERROR; + + Vehicle *v = GetVehicle(p2); + if (v->owner != _current_player || (v->type == VEH_TRAIN && !IsFrontEngine(v))) return CMD_ERROR; + + if (flags & DC_EXEC) { + DecreaseGroupNumVehicle(v->group_id); + IncreaseGroupNumVehicle(new_g); + + switch (v->type) { + default: NOT_REACHED(); + case VEH_TRAIN: + SetTrainGroupID(v, new_g); + break; + case VEH_ROAD: + case VEH_SHIP: + case VEH_AIRCRAFT: + if (IsEngineCountable(v)) UpdateNumEngineGroup(v->engine_type, v->group_id, new_g); + v->group_id = new_g; + break; + } + + /* Update the Replace Vehicle Windows */ + InvalidateWindow(WC_REPLACE_VEHICLE, v->type); + InvalidateWindowData(GetWCForVT(v->type), (v->type << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + +/** + * Add all shared vehicles of all vehicles from a group + * @param tile unused + * @param p1 index of group array + * - p1 bit 0-15 : GroupID + * @param p2 type of vehicles + */ +int32 CmdAddSharedVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + VehicleType type = (VehicleType)p2; + if (!IsValidGroupID(p1) || !IsPlayerBuildableVehicleType(type)) return CMD_ERROR; + + if (flags & DC_EXEC) { + Vehicle *v; + VehicleType type = (VehicleType)p2; + GroupID id_g = p1; + uint subtype = (type == VEH_AIRCRAFT) ? AIR_AIRCRAFT : 0; + + /* Find the first front engine which belong to the group id_g + * then add all shared vehicles of this front engine to the group id_g */ + FOR_ALL_VEHICLES(v) { + if ((v->type == type) && ( + (type == VEH_TRAIN && IsFrontEngine(v)) || + (type != VEH_TRAIN && v->subtype <= subtype))) { + if (v->group_id != id_g) continue; + + /* For each shared vehicles add it to the group */ + for (Vehicle *v2 = GetFirstVehicleFromSharedList(v); v2 != NULL; v2 = v2->next_shared) { + if (v2->group_id != id_g) CmdAddVehicleGroup(tile, flags, id_g, v2->index); + } + } + } + + InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + + +/** + * Remove all vehicles from a group + * @param tile unused + * @param p1 index of group array + * - p1 bit 0-15 : GroupID + * @param p2 type of vehicles + */ +int32 CmdRemoveAllVehiclesGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + VehicleType type = (VehicleType)p2; + if (!IsValidGroupID(p1) || !IsPlayerBuildableVehicleType(type)) return CMD_ERROR; + + Group *g = GetGroup(p1); + if (g->owner != _current_player) return CMD_ERROR; + + if (flags & DC_EXEC) { + GroupID old_g = p1; + uint subtype = (type == VEH_AIRCRAFT) ? AIR_AIRCRAFT : 0; + Vehicle *v; + + /* Find each Vehicle that belongs to the group old_g and add it to the default group */ + FOR_ALL_VEHICLES(v) { + if ((v->type == type) && ( + (type == VEH_TRAIN && IsFrontEngine(v)) || + (type != VEH_TRAIN && v->subtype <= subtype))) { + if (v->group_id != old_g) continue; + + /* Add The Vehicle to the default group */ + CmdAddVehicleGroup(tile, flags, DEFAULT_GROUP, v->index); + } + } + + InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + + +/** + * (Un)set global replace protection from a group + * @param tile unused + * @param p1 index of group array + * - p1 bit 0-15 : GroupID + * @param p2 + * - p2 bit 0 : 1 to set or 0 to clear protection. + */ +int32 CmdSetGroupReplaceProtection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + if (!IsValidGroupID(p1)) return CMD_ERROR; + + Group *g = GetGroup(p1); + if (g->owner != _current_player) return CMD_ERROR; + + if (flags & DC_EXEC) { + g->replace_protection = HASBIT(p2, 0); + + InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player); + } + + return 0; +} + +/** + * Decrease the num_vehicle variable before delete an front engine from a group + * @note Called in CmdSellRailWagon and DeleteLasWagon, + * @param v FrontEngine of the train we want to remove. + */ +void RemoveVehicleFromGroup(const Vehicle *v) +{ + if (!IsValidVehicle(v) || v->type != VEH_TRAIN || !IsFrontEngine(v)) return; + + if (!IsDefaultGroupID(v->group_id)) DecreaseGroupNumVehicle(v->group_id); +} + + +/** + * Affect the groupID of a train to new_g. + * @note called in CmdAddVehicleGroup and CmdMoveRailVehicle + * @param v First vehicle of the chain. + * @param new_g index of array group + */ +void SetTrainGroupID(Vehicle *v, GroupID new_g) +{ + if (!IsValidGroupID(new_g) && !IsDefaultGroupID(new_g)) return; + + assert(IsValidVehicle(v) && v->type == VEH_TRAIN && IsFrontEngine(v)); + + for (Vehicle *u = v; u != NULL; u = u->next) { + if (IsEngineCountable(u)) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g); + + u->group_id = new_g; + } + + /* Update the Replace Vehicle Windows */ + InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN); +} + + +/** + * Recalculates the groupID of a train. Should be called each time a vehicle is added + * to/removed from the chain,. + * @note this needs to be called too for 'wagon chains' (in the depot, without an engine) + * @note Called in CmdBuildRailVehicle, CmdBuildRailWagon, CmdMoveRailVehicle, CmdSellRailWagon + * @param v First vehicle of the chain. + */ +void UpdateTrainGroupID(Vehicle *v) +{ + assert(IsValidVehicle(v) && v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))); + + GroupID new_g = IsFrontEngine(v) ? v->group_id : (GroupID)DEFAULT_GROUP; + for (Vehicle *u = v; u != NULL; u = u->next) { + if (IsEngineCountable(u)) UpdateNumEngineGroup(u->engine_type, u->group_id, new_g); + + u->group_id = new_g; + } + + /* Update the Replace Vehicle Windows */ + InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN); +} + + +void RemoveAllGroupsForPlayer(const Player *p) +{ + Group *g; + + FOR_ALL_GROUPS(g) { + if (p->index == g->owner) DeleteGroup(g); + } +} + + +static const SaveLoad _group_desc[] = { + SLE_VAR(Group, string_id, SLE_UINT16), + SLE_VAR(Group, num_vehicle, SLE_UINT16), + SLE_VAR(Group, owner, SLE_UINT8), + SLE_VAR(Group, vehicle_type, SLE_UINT8), + SLE_VAR(Group, replace_protection, SLE_BOOL), + SLE_END() +}; + + +static void Save_GROUP(void) +{ + Group *g; + + FOR_ALL_GROUPS(g) { + SlSetArrayIndex(g->index); + SlObject(g, _group_desc); + } +} + + +static void Load_GROUP(void) +{ + int index; + + while ((index = SlIterateArray()) != -1) { + if (!AddBlockIfNeeded(&_Group_pool, index)) { + error("Groups: failed loading savegame: too many groups"); + } + + Group *g = GetGroup(index); + SlObject(g, _group_desc); + } +} + +extern const ChunkHandler _group_chunk_handlers[] = { + { 'GRPS', Save_GROUP, Load_GROUP, CH_ARRAY | CH_LAST}, +}; diff -r 0b2aebc8283e -r 0b8b245a2391 src/group_gui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/group_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,801 @@ +/* $Id$ */ + +/** @file group_gui.cpp */ + +#include "stdafx.h" +#include "openttd.h" +#include "functions.h" +#include "table/strings.h" +#include "table/sprites.h" +#include "window.h" +#include "gui.h" +#include "gfx.h" +#include "vehicle.h" +#include "command.h" +#include "engine.h" +#include "vehicle_gui.h" +#include "depot.h" +#include "train.h" +#include "date.h" +#include "group.h" +#include "helpers.hpp" +#include "viewport.h" +#include "strings.h" +#include "debug.h" + + +struct Sorting { + Listing aircraft; + Listing roadveh; + Listing ship; + Listing train; +}; + +static Sorting _sorting; + + +static void BuildGroupList(grouplist_d* gl, PlayerID owner, VehicleType vehicle_type) +{ + const Group** list; + const Group *g; + uint n = 0; + + if (!(gl->l.flags & VL_REBUILD)) return; + + list = MallocT(GetGroupArraySize()); + if (list == NULL) { + error("Could not allocate memory for the group-sorting-list"); + } + + FOR_ALL_GROUPS(g) { + if (g->owner == owner && g->vehicle_type == vehicle_type) list[n++] = g; + } + + free((void*)gl->sort_list); + gl->sort_list = MallocT(n); + if (n != 0 && gl->sort_list == NULL) { + error("Could not allocate memory for the group-sorting-list"); + } + gl->l.list_length = n; + + for (uint i = 0; i < n; ++i) gl->sort_list[i] = list[i]; + free((void*)list); + + gl->l.flags &= ~VL_REBUILD; + gl->l.flags |= VL_RESORT; +} + + +static int CDECL GroupNameSorter(const void *a, const void *b) +{ + static const Group *last_group[2] = { NULL, NULL }; + static char last_name[2][64] = { "", "" }; + + const Group *ga = *(const Group**)a; + const Group *gb = *(const Group**)b; + int r; + + if (ga != last_group[0]) { + last_group[0] = ga; + SetDParam(0, ga->index); + GetString(last_name[0], ga->string_id, lastof(last_name[0])); + } + + if (gb != last_group[1]) { + last_group[1] = gb; + SetDParam(0, gb->index); + GetString(last_name[1], gb->string_id, lastof(last_name[1])); + } + + r = strcmp(last_name[0], last_name[1]); // sort by name + + if (r == 0) return ga->index - gb->index; + + return r; +} + + +static void SortGroupList(grouplist_d *gl) +{ + if (!(gl->l.flags & VL_RESORT)) return; + + qsort((void*)gl->sort_list, gl->l.list_length, sizeof(gl->sort_list[0]), GroupNameSorter); + + gl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; + gl->l.flags &= ~VL_RESORT; +} + + +enum GroupListWidgets { + GRP_WIDGET_CLOSEBOX = 0, + GRP_WIDGET_CAPTION, + GRP_WIDGET_STICKY, + GRP_WIDGET_EMPTY_TOP_LEFT, + GRP_WIDGET_ALL_VEHICLES, + GRP_WIDGET_LIST_GROUP, + GRP_WIDGET_LIST_GROUP_SCROLLBAR, + GRP_WIDGET_SORT_BY_ORDER, + GRP_WIDGET_SORT_BY_TEXT, + GRP_WIDGET_SORT_BY_DROPDOWN, + GRP_WIDGET_EMPTY_TOP_RIGHT, + GRP_WIDGET_LIST_VEHICLE, + GRP_WIDGET_LIST_VEHICLE_SCROLLBAR, + GRP_WIDGET_CREATE_GROUP, + GRP_WIDGET_DELETE_GROUP, + GRP_WIDGET_RENAME_GROUP, + GRP_WIDGET_EMPTY1, + GRP_WIDGET_REPLACE_PROTECTION, + GRP_WIDGET_EMPTY2, + GRP_WIDGET_AVAILABLE_VEHICLES, + GRP_WIDGET_MANAGE_VEHICLES, + GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN, + GRP_WIDGET_STOP_ALL, + GRP_WIDGET_START_ALL, + GRP_WIDGET_EMPTY_BOTTOM_RIGHT, + GRP_WIDGET_RESIZE, +}; + + +static const Widget _group_widgets[] = { +{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, +{ WWT_CAPTION, RESIZE_RIGHT, 14, 11, 513, 0, 13, 0x0, STR_018C_WINDOW_TITLE_DRAG_THIS}, +{ WWT_STICKYBOX, RESIZE_LR, 14, 514, 525, 0, 13, 0x0, STR_STICKY_BUTTON}, +{ WWT_PANEL, RESIZE_NONE, 14, 0, 200, 14, 25, 0x0, STR_NULL}, +{ WWT_PANEL, RESIZE_NONE, 14, 0, 200, 26, 39, 0x0, STR_NULL}, +{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 188, 39, 220, 0x701, STR_GROUPS_CLICK_ON_GROUP_FOR_TIP}, +{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 189, 200, 26, 220, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, +{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 201, 281, 14, 25, STR_SORT_BY, STR_SORT_ORDER_TIP}, +{ WWT_PANEL, RESIZE_NONE, 14, 282, 435, 14, 25, 0x0, STR_SORT_CRITERIA_TIP}, +{ WWT_TEXTBTN, RESIZE_NONE, 14, 436, 447, 14, 25, STR_0225, STR_SORT_CRITERIA_TIP}, +{ WWT_PANEL, RESIZE_RIGHT, 14, 448, 525, 14, 25, 0x0, STR_NULL}, +{ WWT_MATRIX, RESIZE_RB, 14, 201, 513, 26, 233, 0x701, STR_NULL}, +{ WWT_SCROLL2BAR, RESIZE_LRB, 14, 514, 525, 26, 233, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 0, 23, 221, 245, 0x0, STR_GROUP_CREATE_TIP}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 24, 47, 221, 245, 0x0, STR_GROUP_DELETE_TIP}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 48, 71, 221, 245, 0x0, STR_GROUP_RENAME_TIP}, +{ WWT_PANEL, RESIZE_TB, 14, 72, 164, 221, 245, 0x0, STR_NULL}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 165, 188, 221, 245, 0x0, STR_GROUP_REPLACE_PROTECTION_TIP}, +{ WWT_PANEL, RESIZE_TB, 14, 189, 200, 221, 245, 0x0, STR_NULL}, +{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 201, 306, 234, 245, 0x0, STR_AVAILABLE_ENGINES_TIP}, +{ WWT_TEXTBTN, RESIZE_TB, 14, 307, 411, 234, 245, STR_MANAGE_LIST, STR_MANAGE_LIST_TIP}, +{ WWT_TEXTBTN, RESIZE_TB, 14, 412, 423, 234, 245, STR_0225, STR_MANAGE_LIST_TIP}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 424, 435, 234, 245, SPR_FLAG_VEH_STOPPED, STR_MASS_STOP_LIST_TIP}, +{ WWT_PUSHIMGBTN, RESIZE_TB, 14, 436, 447, 234, 245, SPR_FLAG_VEH_RUNNING, STR_MASS_START_LIST_TIP}, +{ WWT_PANEL, RESIZE_RTB, 14, 448, 513, 234, 245, 0x0, STR_NULL}, +{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 514, 525, 234, 245, 0x0, STR_RESIZE_BUTTON}, +{ WIDGETS_END}, +}; + + +static void CreateVehicleGroupWindow(Window *w) +{ + const PlayerID owner = (PlayerID)GB(w->window_number, 0, 8); + groupveh_d *gv = &WP(w, groupveh_d); + grouplist_d *gl = &WP(w, groupveh_d).gl; + + w->caption_color = owner; + w->hscroll.cap = 10 * 29; + w->resize.step_width = 1; + + switch (gv->vehicle_type) { + default: NOT_REACHED(); + case VEH_TRAIN: + case VEH_ROAD: + w->vscroll.cap = 14; + w->vscroll2.cap = 8; + w->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_SMALL; + break; + case VEH_SHIP: + case VEH_AIRCRAFT: + w->vscroll.cap = 10; + w->vscroll2.cap = 4; + w->resize.step_height = PLY_WND_PRC__SIZE_OF_ROW_BIG2; + break; + } + + w->widget[GRP_WIDGET_LIST_GROUP].data = (w->vscroll.cap << 8) + 1; + w->widget[GRP_WIDGET_LIST_VEHICLE].data = (w->vscroll2.cap << 8) + 1; + + switch (gv->vehicle_type) { + default: NOT_REACHED(); break; + case VEH_TRAIN: gv->_sorting = &_sorting.train; break; + case VEH_ROAD: gv->_sorting = &_sorting.roadveh; break; + case VEH_SHIP: gv->_sorting = &_sorting.ship; break; + case VEH_AIRCRAFT: gv->_sorting = &_sorting.aircraft; break; + } + + gv->sort_list = NULL; + gv->vehicle_type = (VehicleType)GB(w->window_number, 11, 5); + gv->l.sort_type = gv->_sorting->criteria; + gv->l.flags = VL_REBUILD | (gv->_sorting->order ? VL_DESC : VL_NONE); + gv->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer + + gl->sort_list = NULL; + gl->l.flags = VL_REBUILD | VL_NONE; + gl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer + + gv->group_sel = DEFAULT_GROUP; + + switch (gv->vehicle_type) { + case VEH_TRAIN: + w->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_883D_TRAINS_CLICK_ON_TRAIN_FOR; + w->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_TRAINS; + + w->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_TRAIN; + w->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_TRAIN; + w->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_TRAIN; + break; + + case VEH_ROAD: + w->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_901A_ROAD_VEHICLES_CLICK_ON; + w->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_ROAD_VEHICLES; + + w->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_ROADVEH; + w->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_ROADVEH; + w->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_ROADVEH; + break; + + case VEH_SHIP: + w->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_9823_SHIPS_CLICK_ON_SHIP_FOR; + w->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_SHIPS; + + w->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_SHIP; + w->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_SHIP; + w->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_SHIP; + break; + + case VEH_AIRCRAFT: + w->widget[GRP_WIDGET_LIST_VEHICLE].tooltips = STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT; + w->widget[GRP_WIDGET_AVAILABLE_VEHICLES].data = STR_AVAILABLE_AIRCRAFT; + + w->widget[GRP_WIDGET_CREATE_GROUP].data = SPR_GROUP_CREATE_AIRCRAFT; + w->widget[GRP_WIDGET_RENAME_GROUP].data = SPR_GROUP_RENAME_AIRCRAFT; + w->widget[GRP_WIDGET_DELETE_GROUP].data = SPR_GROUP_DELETE_AIRCRAFT; + break; + + default: NOT_REACHED(); + } +} + +/** + * Update/redraw the group action dropdown + * @param w the window the dropdown belongs to + * @param gid the currently selected group in the window + */ +static void UpdateGroupActionDropdown(Window *w, GroupID gid, bool refresh = true) +{ + if (refresh && !IsWindowWidgetLowered(w, GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) return; + + static StringID action_str[] = { + STR_REPLACE_VEHICLES, + STR_SEND_FOR_SERVICING, + STR_SEND_TRAIN_TO_DEPOT, + STR_NULL, + STR_NULL, + INVALID_STRING_ID + }; + + action_str[3] = IsDefaultGroupID(gid) ? INVALID_STRING_ID : STR_GROUP_ADD_SHARED_VEHICLE; + action_str[4] = IsDefaultGroupID(gid) ? INVALID_STRING_ID : STR_GROUP_REMOVE_ALL_VEHICLES; + + ShowDropDownMenu(w, action_str, 0, GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN, 0, 0); +} + +/** + * bitmask for w->window_number + * 0-7 PlayerID (owner) + * 11-15 vehicle type + **/ +static void GroupWndProc(Window *w, WindowEvent *e) +{ + const PlayerID owner = (PlayerID)GB(w->window_number, 0, 8); + const Player *p = GetPlayer(owner); + groupveh_d *gv = &WP(w, groupveh_d); + grouplist_d *gl = &WP(w, groupveh_d).gl; + + gv->vehicle_type = (VehicleType)GB(w->window_number, 11, 5); + + switch(e->event) { + case WE_INVALIDATE_DATA: + gv->l.flags |= VL_REBUILD; + gl->l.flags |= VL_REBUILD; + UpdateGroupActionDropdown(w, gv->group_sel); + SetWindowDirty(w); + break; + + case WE_CREATE: + CreateVehicleGroupWindow(w); + break; + + case WE_PAINT: { + int x = 203; + int y2 = PLY_WND_PRC__OFFSET_TOP_WIDGET; + int y1 = PLY_WND_PRC__OFFSET_TOP_WIDGET + 2; + int max; + int i; + + /* If we select the default group, gv->list will contain all vehicles of the player + * else gv->list will contain all vehicles which belong to the selected group */ + BuildVehicleList(gv, owner, gv->group_sel, IsDefaultGroupID(gv->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST); + SortVehicleList(gv); + + + BuildGroupList(gl, owner, gv->vehicle_type); + SortGroupList(gl); + + SetVScrollCount(w, gl->l.list_length); + SetVScroll2Count(w, gv->l.list_length); + + /* Disable all lists management button when the list is empty */ + SetWindowWidgetsDisabledState(w, gv->l.list_length == 0, + GRP_WIDGET_STOP_ALL, + GRP_WIDGET_START_ALL, + GRP_WIDGET_MANAGE_VEHICLES, + GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN, + WIDGET_LIST_END); + + /* Disable the group specific function when we select the default group */ + SetWindowWidgetsDisabledState(w, IsDefaultGroupID(gv->group_sel), + GRP_WIDGET_DELETE_GROUP, + GRP_WIDGET_RENAME_GROUP, + GRP_WIDGET_REPLACE_PROTECTION, + WIDGET_LIST_END); + + /* If selected_group == DEFAULT_GROUP, draw the standard caption + We list all vehicles */ + if (IsDefaultGroupID(gv->group_sel)) { + SetDParam(0, p->name_1); + SetDParam(1, p->name_2); + SetDParam(2, gv->l.list_length); + + switch (gv->vehicle_type) { + case VEH_TRAIN: + w->widget[GRP_WIDGET_CAPTION].data = STR_881B_TRAINS; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_TRAIN; + break; + case VEH_ROAD: + w->widget[GRP_WIDGET_CAPTION].data = STR_9001_ROAD_VEHICLES; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_ROADVEH; + break; + case VEH_SHIP: + w->widget[GRP_WIDGET_CAPTION].data = STR_9805_SHIPS; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_SHIP; + break; + case VEH_AIRCRAFT: + w->widget[GRP_WIDGET_CAPTION].data = STR_A009_AIRCRAFT; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = SPR_GROUP_REPLACE_OFF_AIRCRAFT; + break; + default: NOT_REACHED(); break; + } + } else { + const Group *g = GetGroup(gv->group_sel); + + SetDParam(0, g->index); + SetDParam(1, g->num_vehicle); + + switch (gv->vehicle_type) { + case VEH_TRAIN: + w->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_TRAINS_CAPTION; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_TRAIN : SPR_GROUP_REPLACE_OFF_TRAIN; + break; + case VEH_ROAD: + w->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_ROADVEH_CAPTION; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_ROADVEH : SPR_GROUP_REPLACE_OFF_ROADVEH; + break; + case VEH_SHIP: + w->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_SHIPS_CAPTION; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_SHIP : SPR_GROUP_REPLACE_OFF_SHIP; + break; + case VEH_AIRCRAFT: + w->widget[GRP_WIDGET_CAPTION].data = STR_GROUP_AIRCRAFTS_CAPTION; + w->widget[GRP_WIDGET_REPLACE_PROTECTION].data = (g->replace_protection) ? SPR_GROUP_REPLACE_ON_AIRCRAFT : SPR_GROUP_REPLACE_OFF_AIRCRAFT; + break; + default: NOT_REACHED(); break; + } + } + + + DrawWindowWidgets(w); + + /* Draw Matrix Group + * The selected group is drawn in white */ + StringID str; + + switch (gv->vehicle_type) { + case VEH_TRAIN: str = STR_GROUP_ALL_TRAINS; break; + case VEH_ROAD: str = STR_GROUP_ALL_ROADS; break; + case VEH_SHIP: str = STR_GROUP_ALL_SHIPS; break; + case VEH_AIRCRAFT: str = STR_GROUP_ALL_AIRCRAFTS; break; + default: NOT_REACHED(); break; + } + DrawString(10, y1, str, IsDefaultGroupID(gv->group_sel) ? 12 : 16); + + max = min(w->vscroll.pos + w->vscroll.cap, gl->l.list_length); + for (i = w->vscroll.pos ; i < max ; ++i) { + const Group *g = gl->sort_list[i]; + + assert(g->owner == owner); + + y1 += PLY_WND_PRC__SIZE_OF_ROW_TINY; + + /* draw the selected group in white, else we draw it in black */ + SetDParam(0, g->index); + DrawString(10, y1, STR_SV_GROUP_NAME, (gv->group_sel == g->index) ? 12 : 16); + + /* draw the number of vehicles of the group */ + SetDParam(0, g->num_vehicle); + DrawStringRightAligned(187, y1 + 1, STR_GROUP_TINY_NUM, (gv->group_sel == g->index) ? 12 : 16); + } + + /* Draw Matrix Vehicle according to the vehicle list built before */ + DrawString(285, 15, _vehicle_sort_listing[gv->l.sort_type], 0x10); + DoDrawString(gv->l.flags & VL_DESC ? DOWNARROW : UPARROW, 269, 15, 0x10); + + max = min(w->vscroll2.pos + w->vscroll2.cap, gv->l.list_length); + for (i = w->vscroll2.pos ; i < max ; ++i) { + const Vehicle* v = gv->sort_list[i]; + StringID str; + + assert(v->type == gv->vehicle_type && v->owner == owner); + + DrawVehicleImage(v, x + 19, y2 + 6, w->hscroll.cap, 0, gv->vehicle_sel); + DrawVehicleProfitButton(v, x, y2 + 13); + + if (IsVehicleInDepot(v)) { + str = STR_021F; + } else { + str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2; + } + SetDParam(0, v->unitnumber); + DrawString(x, y2 + 2, str, 0); + + if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG2) DrawSmallOrderList(v, x + 138, y2); + + if (v->profit_this_year < 0) { + str = v->profit_last_year < 0 ? + STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR : + STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR; + } else { + str = v->profit_last_year < 0 ? + STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR : + STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR; + } + + SetDParam(0, v->profit_this_year); + SetDParam(1, v->profit_last_year); + DrawString(x + 19, y2 + w->resize.step_height - 8, str, 0); + + if (IsValidGroupID(v->group_id)) { + SetDParam(0, v->group_id); + DrawString(x + 19, y2, STR_GROUP_TINY_NAME, 16); + } + + y2 += w->resize.step_height; + } + + break; + } + + case WE_CLICK: + switch(e->we.click.widget) { + case GRP_WIDGET_SORT_BY_ORDER: // Flip sorting method ascending/descending + gv->l.flags ^= VL_DESC; + gv->l.flags |= VL_RESORT; + + gv->_sorting->order = !!(gv->l.flags & VL_DESC); + SetWindowDirty(w); + break; + + case GRP_WIDGET_SORT_BY_TEXT: + case GRP_WIDGET_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu + ShowDropDownMenu(w, _vehicle_sort_listing, gv->l.sort_type, GRP_WIDGET_SORT_BY_DROPDOWN, 0, 0); + return; + + case GRP_WIDGET_ALL_VEHICLES: // All vehicles button + if (!IsDefaultGroupID(gv->group_sel)) { + gv->group_sel = DEFAULT_GROUP; + gv->l.flags |= VL_REBUILD; + UpdateGroupActionDropdown(w, gv->group_sel); + SetWindowDirty(w); + } + break; + + case GRP_WIDGET_LIST_GROUP: { // Matrix Group + uint16 id_g = (e->we.click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET - 13) / PLY_WND_PRC__SIZE_OF_ROW_TINY; + + if (id_g >= w->vscroll.cap) return; + + id_g += w->vscroll.pos; + + if (id_g >= gl->l.list_length) return; + + gv->group_sel = gl->sort_list[id_g]->index;; + + gv->l.flags |= VL_REBUILD; + UpdateGroupActionDropdown(w, gv->group_sel); + SetWindowDirty(w); + break; + } + + case GRP_WIDGET_LIST_VEHICLE: { // Matrix Vehicle + uint32 id_v = (e->we.click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)w->resize.step_height; + const Vehicle *v; + + if (id_v >= w->vscroll2.cap) return; // click out of bounds + + id_v += w->vscroll2.pos; + + if (id_v >= gv->l.list_length) return; // click out of list bound + + v = gv->sort_list[id_v]; + + gv->vehicle_sel = v->index; + + if (IsValidVehicle(v)) { + CursorID image; + + switch (gv->vehicle_type) { + case VEH_TRAIN: image = GetTrainImage(v, DIR_W); break; + case VEH_ROAD: image = GetRoadVehImage(v, DIR_W); break; + case VEH_SHIP: image = GetShipImage(v, DIR_W); break; + case VEH_AIRCRAFT: image = GetAircraftImage(v, DIR_W); break; + default: NOT_REACHED(); break; + } + + SetObjectToPlaceWnd(image, GetVehiclePalette(v), 4, w); + } + + SetWindowDirty(w); + break; + } + + case GRP_WIDGET_CREATE_GROUP: // Create a new group + DoCommandP(0, gv->vehicle_type, 0, NULL, CMD_CREATE_GROUP | CMD_MSG(STR_GROUP_CAN_T_CREATE)); + break; + + case GRP_WIDGET_DELETE_GROUP: { // Delete the selected group + GroupID group = gv->group_sel; + gv->group_sel = DEFAULT_GROUP; + + DoCommandP(0, group, 0, NULL, CMD_DELETE_GROUP | CMD_MSG(STR_GROUP_CAN_T_DELETE)); + break; + } + + case GRP_WIDGET_RENAME_GROUP: { // Rename the selected roup + assert(!IsDefaultGroupID(gv->group_sel)); + + const Group *g = GetGroup(gv->group_sel); + + SetDParam(0, g->index); + ShowQueryString(g->string_id, STR_GROUP_RENAME_CAPTION, 31, 150, w, CS_ALPHANUMERAL); + } break; + + + case GRP_WIDGET_AVAILABLE_VEHICLES: + ShowBuildVehicleWindow(0, gv->vehicle_type); + break; + + case GRP_WIDGET_MANAGE_VEHICLES: + case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN: { + UpdateGroupActionDropdown(w, gv->group_sel, false); + break; + } + + + case GRP_WIDGET_START_ALL: + case GRP_WIDGET_STOP_ALL: { // Start/stop all vehicles of the list + DoCommandP(0, gv->group_sel, ((IsDefaultGroupID(gv->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK) + | (1 << 6) + | (e->we.click.widget == GRP_WIDGET_START_ALL ? (1 << 5) : 0) + | gv->vehicle_type, NULL, CMD_MASS_START_STOP); + + break; + } + + case GRP_WIDGET_REPLACE_PROTECTION: + if (!IsDefaultGroupID(gv->group_sel)) { + const Group *g = GetGroup(gv->group_sel); + + DoCommandP(0, gv->group_sel, !g->replace_protection, NULL, CMD_SET_GROUP_REPLACE_PROTECTION); + } + break; + } + + break; + + case WE_DRAGDROP: { + switch (e->we.click.widget) { + case GRP_WIDGET_ALL_VEHICLES: // All trains + DoCommandP(0, DEFAULT_GROUP, gv->vehicle_sel, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE)); + + gv->vehicle_sel = INVALID_VEHICLE; + + SetWindowDirty(w); + + break; + + case GRP_WIDGET_LIST_GROUP: { // Maxtrix group + uint16 id_g = (e->we.click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET - 13) / PLY_WND_PRC__SIZE_OF_ROW_TINY; + const VehicleID vindex = gv->vehicle_sel; + + gv->vehicle_sel = INVALID_VEHICLE; + + SetWindowDirty(w); + + if (id_g >= w->vscroll.cap) return; + + id_g += w->vscroll.pos; + + if (id_g >= gl->l.list_length) return; + + DoCommandP(0, gl->sort_list[id_g]->index, vindex, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE)); + + break; + } + + case GRP_WIDGET_LIST_VEHICLE: { // Maxtrix vehicle + uint32 id_v = (e->we.click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / (int)w->resize.step_height; + const Vehicle *v; + const VehicleID vindex = gv->vehicle_sel; + + gv->vehicle_sel = INVALID_VEHICLE; + + SetWindowDirty(w); + + if (id_v >= w->vscroll2.cap) return; // click out of bounds + + id_v += w->vscroll2.pos; + + if (id_v >= gv->l.list_length) return; // click out of list bound + + v = gv->sort_list[id_v]; + + if (vindex == v->index) { + switch (gv->vehicle_type) { + default: NOT_REACHED(); break; + case VEH_TRAIN: ShowTrainViewWindow(v); break; + case VEH_ROAD: ShowRoadVehViewWindow(v); break; + case VEH_SHIP: ShowShipViewWindow(v); break; + case VEH_AIRCRAFT: ShowAircraftViewWindow(v); break; + } + } + + break; + } + } + break; + } + + case WE_ON_EDIT_TEXT: + if (!StrEmpty(e->we.edittext.str)) { + _cmd_text = e->we.edittext.str; + + DoCommandP(0, gv->group_sel, 0, NULL, CMD_RENAME_GROUP | CMD_MSG(STR_GROUP_CAN_T_RENAME)); + } + break; + + case WE_RESIZE: + w->hscroll.cap += e->we.sizing.diff.x; + w->vscroll.cap += e->we.sizing.diff.y / PLY_WND_PRC__SIZE_OF_ROW_TINY; + w->vscroll2.cap += e->we.sizing.diff.y / (int)w->resize.step_height; + + w->widget[GRP_WIDGET_LIST_GROUP].data = (w->vscroll.cap << 8) + 1; + w->widget[GRP_WIDGET_LIST_VEHICLE].data = (w->vscroll2.cap << 8) + 1; + break; + + + case WE_DROPDOWN_SELECT: // we have selected a dropdown item in the list + switch (e->we.dropdown.button) { + case GRP_WIDGET_SORT_BY_DROPDOWN: + if (gv->l.sort_type != e->we.dropdown.index) { + gv->l.flags |= VL_RESORT; + gv->l.sort_type = e->we.dropdown.index; + gv->_sorting->criteria = gv->l.sort_type; + } + break; + + case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN: + assert(gv->l.list_length != 0); + + switch (e->we.dropdown.index) { + case 0: // Replace window + ShowReplaceGroupVehicleWindow(gv->group_sel, gv->vehicle_type); + break; + case 1: // Send for servicing + DoCommandP(0, gv->group_sel, ((IsDefaultGroupID(gv->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK) + | DEPOT_MASS_SEND + | DEPOT_SERVICE, NULL, GetCmdSendToDepot(gv->vehicle_type)); + break; + case 2: // Send to Depots + DoCommandP(0, gv->group_sel, ((IsDefaultGroupID(gv->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST) & VLW_MASK) + | DEPOT_MASS_SEND, NULL, GetCmdSendToDepot(gv->vehicle_type)); + break; + case 3: // Add shared Vehicles + assert(!IsDefaultGroupID(gv->group_sel)); + + DoCommandP(0, gv->group_sel, gv->vehicle_type, NULL, CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_SHARED_VEHICLE)); + break; + case 4: // Remove all Vehicles from the selected group + assert(!IsDefaultGroupID(gv->group_sel)); + + DoCommandP(0, gv->group_sel, gv->vehicle_type, NULL, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES)); + break; + default: NOT_REACHED(); + } + break; + + default: NOT_REACHED(); + } + + SetWindowDirty(w); + break; + + + case WE_DESTROY: + free((void*)gv->sort_list); + free((void*)gl->sort_list); + break; + + + case WE_TICK: // resort the lists every 20 seconds orso (10 days) + if (--gv->l.resort_timer == 0) { + gv->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; + gv->l.flags |= VL_RESORT; + SetWindowDirty(w); + } + if (--gl->l.resort_timer == 0) { + gl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; + gl->l.flags |= VL_RESORT; + SetWindowDirty(w); + } + break; + } +} + + +static const WindowDesc _group_desc = { + WDP_AUTO, WDP_AUTO, 526, 246, + WC_TRAINS_LIST, WC_NONE, + WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, + _group_widgets, + GroupWndProc +}; + +void ShowPlayerGroup(PlayerID player, VehicleType vehicle_type) +{ + WindowClass wc; + + switch (vehicle_type) { + default: NOT_REACHED(); + case VEH_TRAIN: wc = WC_TRAINS_LIST; break; + case VEH_ROAD: wc = WC_ROADVEH_LIST; break; + case VEH_SHIP: wc = WC_SHIPS_LIST; break; + case VEH_AIRCRAFT: wc = WC_AIRCRAFT_LIST; break; + } + + WindowNumber num = (vehicle_type << 11) | VLW_GROUP_LIST | player; + DeleteWindowById(wc, num); + Window *w = AllocateWindowDescFront(&_group_desc, num); + if (w == NULL) return; + + w->window_class = wc; + + switch (vehicle_type) { + default: NOT_REACHED(); + case VEH_ROAD: + ResizeWindow(w, -66, 0); + /* FALL THROUGH */ + case VEH_TRAIN: + w->resize.height = w->height - (PLY_WND_PRC__SIZE_OF_ROW_SMALL * 4); // Minimum of 4 vehicles + break; + + case VEH_SHIP: + case VEH_AIRCRAFT: + ResizeWindow(w, -66, -52); + w->resize.height = w->height; // Minimum of 4 vehicles + break; + } + + /* Set the minimum window size to the current window size */ + w->resize.width = w->width; +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/gui.h --- a/src/gui.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/gui.h Wed Jun 13 11:45:14 2007 +0000 @@ -46,7 +46,7 @@ void ShowOrdersWindow(const Vehicle *v); /* road_gui.cpp */ -void ShowBuildRoadToolbar(); +void ShowBuildRoadToolbar(RoadType roadtype); void ShowBuildRoadScenToolbar(); void ShowRoadVehViewWindow(const Vehicle *v); @@ -68,13 +68,15 @@ void PlaceProc_LevelLand(TileIndex tile); bool GUIPlaceProcDragXY(const WindowEvent *e); -enum { // max 32 - 4 = 28 types - GUI_PlaceProc_DemolishArea = 0 << 4, - GUI_PlaceProc_LevelArea = 1 << 4, - GUI_PlaceProc_DesertArea = 2 << 4, - GUI_PlaceProc_WaterArea = 3 << 4, - GUI_PlaceProc_ConvertRailArea = 4 << 4, - GUI_PlaceProc_RockyArea = 5 << 4, +enum { + GUI_PlaceProc_None, + GUI_PlaceProc_DemolishArea, + GUI_PlaceProc_LevelArea, + GUI_PlaceProc_DesertArea, + GUI_PlaceProc_WaterArea, + GUI_PlaceProc_ConvertRailArea, + GUI_PlaceProc_RockyArea, + GUI_PlaceProc_RemoveFromStation, }; /* misc_gui.cpp */ @@ -138,4 +140,6 @@ /* vehicle_gui.cpp */ void InitializeGUI(); +void ShowPlayerGroup(PlayerID player, VehicleType veh); + #endif /* GUI_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/heightmap.cpp --- a/src/heightmap.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/heightmap.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -275,6 +275,13 @@ return true; } +/** + * Converts a given grayscale map to something that fits in OTTD map system + * and create a map of that data. + * @param img_width the with of the image in pixels/tiles + * @param img_height the height of the image in pixels/tiles + * @param map the input map + */ static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map) { /* Defines the detail of the aspect ratio (to avoid doubles) */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/industry.h --- a/src/industry.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/industry.h Wed Jun 13 11:45:14 2007 +0000 @@ -67,10 +67,8 @@ byte width; byte height; const Town* town; ///< Nearest town - CargoID produced_cargo[2]; ///< 2 production cargo slots uint16 cargo_waiting[2]; ///< amount of cargo produced per cargo byte production_rate[2]; ///< production rate for each cargo - CargoID accepts_cargo[3]; ///< 3 input cargo slots byte prod_level; ///< general production level uint16 last_mo_production[2]; ///< stats of last month production per cargo uint16 last_mo_transported[2]; ///< stats of last month transport per cargo @@ -79,7 +77,7 @@ uint16 total_transported[2]; ///< total units transported per cargo uint16 counter; ///< used for animation and/or production (if available cargo) - byte type; ///< type of industry. see IT_COAL_MINE and others + IndustryType type; ///< type of industry. see IT_COAL_MINE and others OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE byte random_color; ///< randomized colour of the industry, for display purpose Year last_prod_year; ///< last year of production @@ -107,6 +105,7 @@ byte minimal_cargo; ///< minimum amount of cargo transported to the stations ///< If the waiting cargo is less than this number, no cargo is moved to it CargoID accepts_cargo[3]; ///< 3 accepted cargos + uint16 input_cargo_multiplier[3][2]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced cargos) IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs byte climate_availability; ///< Bitmask, giving landscape enums as bit position IndustyBehaviour behaviour; ///< How this industry will behave, and how others entities can use it @@ -118,6 +117,8 @@ StringID production_down_text; ///< Message appearing when the industry's production is decreasing byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation + uint8 number_of_sounds; ///< Number of sounds available in the sounds array + const uint8 *random_sounds; ///< array of random sounds. /* Newgrf stuff coming in */ uint16 callback_flags; ///< Flags telling which grf callback is set byte subst_id; @@ -134,11 +135,17 @@ byte anim_production; ///< Animation frame to start when goods are produced byte anim_next; ///< Next frame in an animation bool anim_state; ///< When true, the tile has to be drawn using the animation - ///< state instead of the construction state + ///< state instead of the construction state }; +/* industry_cmd.cpp*/ const IndustrySpec *GetIndustrySpec(IndustryType thistype); ///< Array of industries default data const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx); ///< Array of industry tiles default data +void ResetIndustries(); +void PlantRandomFarmField(const Industry *i); + +/* smallmap_gui.cpp */ +void BuildIndustriesLegend(); DECLARE_OLD_POOL(Industry, Industry, 3, 8000) @@ -217,10 +224,6 @@ VARDEF const Industry** _industry_sort; VARDEF bool _industry_sort_dirty; - -void DeleteIndustry(Industry *is); -void PlantRandomFarmField(const Industry *i); - enum { IT_COAL_MINE = 0, IT_POWER_STATION = 1, diff -r 0b2aebc8283e -r 0b8b245a2391 src/industry_cmd.cpp --- a/src/industry_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/industry_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -55,26 +55,16 @@ * Retrieve the type for this industry. Although it is accessed by a tile, * it will return the general type of industry, and not the sprite index * as would do GetIndustryGfx. - * The same information can be accessed by looking at Industry->type * @param tile that is queried * @pre IsTileType(tile, MP_INDUSTRY) * @return general type for this industry, as defined in industry.h **/ IndustryType GetIndustryType(TileIndex tile) { - IndustryGfx this_type = GetIndustryGfx(tile); - IndustryType iloop; - assert(IsTileType(tile, MP_INDUSTRY)); - for (iloop = IT_COAL_MINE; iloop < NUM_INDUSTRYTYPES; iloop += 1) { - if (IS_BYTE_INSIDE(this_type, industry_gfx_Solver[iloop].MinGfx, - industry_gfx_Solver[iloop].MaxGfx + 1)) { - return iloop; - } - } - - return IT_INVALID; //we have not found equivalent, whatever the reason + const Industry *ind = GetIndustryByTile(tile); + return IsValidIndustry(ind) ? ind->type : (IndustryType)IT_INVALID; } /** @@ -137,8 +127,7 @@ static void IndustryDrawSugarMine(const TileInfo *ti) { - const DrawIndustrySpec1Struct *d; - uint32 image; + const DrawIndustryAnimationStruct *d; if (!IsIndustryCompleted(ti->tile)) return; @@ -146,23 +135,23 @@ AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0); - image = d->image_2; - if (image != 0) AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + image - 1, PAL_NONE, 8, 41); + if (d->image_2 != 0) { + AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + d->image_2 - 1, PAL_NONE, 8, 41); + } - image = d->image_3; - if (image != 0) { - AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + image - 1, PAL_NONE, - _drawtile_proc1_x[image - 1], _drawtile_proc1_y[image - 1]); + if (d->image_3 != 0) { + AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + d->image_3 - 1, PAL_NONE, + _drawtile_proc1[d->image_3 - 1].x, _drawtile_proc1[d->image_3 - 1].y); } } static void IndustryDrawToffeeQuarry(const TileInfo *ti) { - int x = 0; + uint8 x = 0; if (IsIndustryCompleted(ti->tile)) { - x = _industry_anim_offs[GetIndustryAnimationState(ti->tile)]; - if ( (byte)x == 0xFF) + x = _industry_anim_offs_toffee[GetIndustryAnimationState(ti->tile)]; + if (x == 0xFF) x = 0; } @@ -173,7 +162,7 @@ static void IndustryDrawBubbleGenerator( const TileInfo *ti) { if (IsIndustryCompleted(ti->tile)) { - AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_2[GetIndustryAnimationState(ti->tile)]); + AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_bubbles[GetIndustryAnimationState(ti->tile)]); } else { AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67); } @@ -181,12 +170,12 @@ static void IndustryDrawToyFactory(const TileInfo *ti) { - const DrawIndustrySpec4Struct *d; + const DrawIndustryAnimationStruct *d; - d = &_industry_anim_offs_3[GetIndustryAnimationState(ti->tile)]; + d = &_industry_anim_offs_toys[GetIndustryAnimationState(ti->tile)]; if (d->image_1 != 0xFF) { - AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, 50 - d->image_1 * 2, 96 + d->image_1); + AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, d->x, 96 + d->image_1); } if (d->image_2 != 0xFF) { @@ -200,13 +189,13 @@ static void IndustryDrawCoalPlantSparks(const TileInfo *ti) { if (IsIndustryCompleted(ti->tile)) { - uint image = GetIndustryAnimationState(ti->tile); + uint8 image = GetIndustryAnimationState(ti->tile); if (image != 0 && image < 7) { AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS, PAL_NONE, - _coal_plant_sparks_x[image - 1], - _coal_plant_sparks_y[image - 1] + _coal_plant_sparks[image - 1].x, + _coal_plant_sparks[image - 1].y ); } } @@ -356,7 +345,7 @@ i->last_mo_production[0] += cw; - am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw); + am = MoveGoodsToStation(i->xy, i->width, i->height, indspec->produced_cargo[0], cw); i->last_mo_transported[0] += am; if (am != 0) { uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production; @@ -378,7 +367,7 @@ i->last_mo_production[1] += cw; - am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[1], cw); + am = MoveGoodsToStation(i->xy, i->width, i->height, indspec->produced_cargo[1], cw); i->last_mo_transported[1] += am; } } @@ -412,7 +401,7 @@ if ((_tick_counter & 3) == 0) { m = GetIndustryAnimationState(tile); - if (_industry_anim_offs[m] == 0xFF) { + if (_industry_anim_offs_toffee[m] == 0xFF) { SndPlayTileFx(SND_30_CARTOON_SOUND, tile); } @@ -753,7 +742,7 @@ static void GetProducedCargo_Industry(TileIndex tile, CargoID *b) { - const Industry *i = GetIndustryByTile(tile); + const IndustrySpec *i = GetIndustrySpec(GetIndustryByTile(tile)->type); b[0] = i->produced_cargo[0]; b[1] = i->produced_cargo[1]; @@ -916,57 +905,17 @@ i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + 45); ///< Found a tree, add according value to waiting cargo } -static const byte _industry_sounds[37][2] = { - {0}, - {0}, - {1, SND_28_SAWMILL}, - {0}, - {0}, - {0}, - {1, SND_03_FACTORY_WHISTLE}, - {1, SND_03_FACTORY_WHISTLE}, - {0}, - {3, SND_24_SHEEP}, - {0}, - {0}, - {0}, - {0}, - {1, SND_28_SAWMILL}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {1, SND_03_FACTORY_WHISTLE}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {1, SND_33_PLASTIC_MINE}, - {0}, - {0}, - {0}, - {0}, -}; - - static void ProduceIndustryGoods(Industry *i) { uint32 r; uint num; + const IndustrySpec *indsp = GetIndustrySpec(i->type); /* play a sound? */ if ((i->counter & 0x3F) == 0) { - if (CHANCE16R(1, 14, r) && (num = _industry_sounds[i->type][0]) != 0) { + if (CHANCE16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) { SndPlayTileFx( - (SoundFx)(_industry_sounds[i->type][1] + (((r >> 16) * num) >> 16)), + (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]), i->xy); } } @@ -975,7 +924,7 @@ /* produce some cargo */ if ((i->counter & 0xFF) == 0) { - IndustyBehaviour indbehav = GetIndustrySpec(i->type)->behaviour; + IndustyBehaviour indbehav = indsp->behaviour; i->cargo_waiting[0] = min(0xffff, i->cargo_waiting[0] + i->production_rate[0]); i->cargo_waiting[1] = min(0xffff, i->cargo_waiting[1] + i->production_rate[1]); @@ -1334,7 +1283,7 @@ /* check if an industry that accepts the same goods is nearby */ if (DistanceMax(tile, i->xy) <= 14 && indspec->accepts_cargo[0] != CT_INVALID && - indspec->accepts_cargo[0] == i->accepts_cargo[0] && ( + indspec->accepts_cargo[0] == indspec->accepts_cargo[0] && ( _game_mode != GM_EDITOR || !_patches.same_industry_close || !_patches.multiple_industry_per_town @@ -1385,11 +1334,6 @@ i->width = i->height = 0; i->type = type; - i->produced_cargo[0] = indspec->produced_cargo[0]; - i->produced_cargo[1] = indspec->produced_cargo[1]; - i->accepts_cargo[0] = indspec->accepts_cargo[0]; - i->accepts_cargo[1] = indspec->accepts_cargo[1]; - i->accepts_cargo[2] = indspec->accepts_cargo[2]; i->production_rate[0] = indspec->production_rate[0]; i->production_rate[1] = indspec->production_rate[1]; @@ -1542,9 +1486,10 @@ return CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, it); } -static const byte _numof_industry_table[4][12] = { +static const byte _numof_industry_table[5][12] = { /* difficulty settings for number of industries */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //none + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, //very low {0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5}, //low {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, //normal {0, 2, 3, 4, 6, 7, 8, 9, 10, 10, 10}, //high @@ -1638,7 +1583,7 @@ break; default: /* INDUSTRY_PRODUCTION */ - for (j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){ + for (j = 0; j < 2 && indspec->produced_cargo[j] != CT_INVALID; j++){ uint32 r = Random(); int old_prod, new_prod, percent; int mag; @@ -1664,7 +1609,7 @@ mag = abs(percent); if (mag >= 10) { SetDParam(2, mag); - SetDParam(0, GetCargo(i->produced_cargo[j])->name); + SetDParam(0, GetCargo(indspec->produced_cargo[j])->name); SetDParam(1, i->index); AddNewsItem( percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN, @@ -1693,40 +1638,26 @@ { byte pct; bool refresh = false; + const IndustrySpec *indsp = GetIndustrySpec(i->type); - if (i->produced_cargo[0] != CT_INVALID) { - pct = 0; - if (i->last_mo_production[0] != 0) { - i->last_prod_year = _cur_year; - pct = min(i->last_mo_transported[0] * 256 / i->last_mo_production[0], 255); + for (byte j = 0; j < lengthof(indsp->produced_cargo); j++) { + if (indsp->produced_cargo[j] != CT_INVALID) { + pct = 0; + if (i->last_mo_production[j] != 0) { + i->last_prod_year = _cur_year; + pct = min(i->last_mo_transported[j] * 256 / i->last_mo_production[j], 255); + } + i->pct_transported[j] = pct; + + i->total_production[j] = i->last_mo_production[j]; + i->last_mo_production[j] = 0; + + i->total_transported[j] = i->last_mo_transported[j]; + i->last_mo_transported[j] = 0; + refresh = true; } - i->pct_transported[0] = pct; - - i->total_production[0] = i->last_mo_production[0]; - i->last_mo_production[0] = 0; - - i->total_transported[0] = i->last_mo_transported[0]; - i->last_mo_transported[0] = 0; - refresh = true; } - if (i->produced_cargo[1] != CT_INVALID) { - pct = 0; - if (i->last_mo_production[1] != 0) { - i->last_prod_year = _cur_year; - pct = min(i->last_mo_transported[1] * 256 / i->last_mo_production[1], 255); - } - i->pct_transported[1] = pct; - - i->total_production[1] = i->last_mo_production[1]; - i->last_mo_production[1] = 0; - - i->total_transported[1] = i->last_mo_transported[1]; - i->last_mo_transported[1] = 0; - refresh = true; - } - - if (refresh) InvalidateWindow(WC_INDUSTRY_VIEW, i->index); @@ -1920,10 +1851,10 @@ SLE_VAR(Industry, width, SLE_UINT8), SLE_VAR(Industry, height, SLE_UINT8), SLE_REF(Industry, town, REF_TOWN), - SLE_ARR(Industry, produced_cargo, SLE_UINT8, 2), + SLE_CONDNULL( 2, 2, 60), ///< used to be industry's produced_cargo SLE_ARR(Industry, cargo_waiting, SLE_UINT16, 2), SLE_ARR(Industry, production_rate, SLE_UINT8, 2), - SLE_ARR(Industry, accepts_cargo, SLE_UINT8, 3), + SLE_CONDNULL( 3, 2, 60), ///< used to be industry's accepts_cargo SLE_VAR(Industry, prod_level, SLE_UINT8), SLE_ARR(Industry, last_mo_production, SLE_UINT16, 2), SLE_ARR(Industry, last_mo_transported, SLE_UINT16, 2), diff -r 0b2aebc8283e -r 0b8b245a2391 src/industry_gui.cpp --- a/src/industry_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/industry_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -287,8 +287,9 @@ static inline bool IsProductionAlterable(const Industry *i) { + const IndustrySpec *ind = GetIndustrySpec(i->type); return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) && - (i->accepts_cargo[0] == CT_INVALID || i->accepts_cargo[0] == CT_VALUABLES)); + (ind->accepts_cargo[0] == CT_INVALID || ind->accepts_cargo[0] == CT_VALUABLES)); } static void IndustryViewWndProc(Window *w, WindowEvent *e) @@ -300,30 +301,31 @@ switch (e->event) { case WE_PAINT: { const Industry *i = GetIndustry(w->window_number); + const IndustrySpec *ind = GetIndustrySpec(i->type); SetDParam(0, w->window_number); DrawWindowWidgets(w); - if (i->accepts_cargo[0] != CT_INVALID) { + if (ind->accepts_cargo[0] != CT_INVALID) { StringID str; - SetDParam(0, GetCargo(i->accepts_cargo[0])->name); + SetDParam(0, GetCargo(ind->accepts_cargo[0])->name); str = STR_4827_REQUIRES; - if (i->accepts_cargo[1] != CT_INVALID) { - SetDParam(1, GetCargo(i->accepts_cargo[1])->name); + if (ind->accepts_cargo[1] != CT_INVALID) { + SetDParam(1, GetCargo(ind->accepts_cargo[1])->name); str = STR_4828_REQUIRES; - if (i->accepts_cargo[2] != CT_INVALID) { - SetDParam(2, GetCargo(i->accepts_cargo[2])->name); + if (ind->accepts_cargo[2] != CT_INVALID) { + SetDParam(2, GetCargo(ind->accepts_cargo[2])->name); str = STR_4829_REQUIRES; } } DrawString(2, 107, str, 0); } - if (i->produced_cargo[0] != CT_INVALID) { + if (ind->produced_cargo[0] != CT_INVALID) { DrawString(2, 117, STR_482A_PRODUCTION_LAST_MONTH, 0); - SetDParam(0, i->produced_cargo[0]); + SetDParam(0, ind->produced_cargo[0]); SetDParam(1, i->total_production[0]); SetDParam(2, i->pct_transported[0] * 100 >> 8); @@ -334,8 +336,8 @@ !isProductionMinimum(i, 0), !isProductionMaximum(i, 0)); } - if (i->produced_cargo[1] != CT_INVALID) { - SetDParam(0, i->produced_cargo[1]); + if (ind->produced_cargo[1] != CT_INVALID) { + SetDParam(0, ind->produced_cargo[1]); SetDParam(1, i->total_production[1]); SetDParam(2, i->pct_transported[1] * 100 >> 8); DrawString(4 + (IsProductionAlterable(i) ? 30 : 0), 137, STR_482B_TRANSPORTED, 0); @@ -365,7 +367,8 @@ x = e->we.click.pt.x; line = (e->we.click.pt.y - 127) / 10; - if (e->we.click.pt.y >= 127 && IS_INT_INSIDE(line, 0, 2) && i->produced_cargo[line] != CT_INVALID) { + if (e->we.click.pt.y >= 127 && IS_INT_INSIDE(line, 0, 2) && + GetIndustrySpec(i->type)->produced_cargo[line] != CT_INVALID) { if (IS_INT_INSIDE(x, 5, 25) ) { /* Clicked buttons, decrease or increase production */ if (x < 15) { @@ -416,11 +419,13 @@ static void UpdateIndustryProduction(Industry *i) { - if (i->produced_cargo[0] != CT_INVALID) - i->total_production[0] = 8 * i->production_rate[0]; + const IndustrySpec *ind = GetIndustrySpec(i->type); - if (i->produced_cargo[1] != CT_INVALID) - i->total_production[1] = 8 * i->production_rate[1]; + for (byte j = 0; j < lengthof(ind->produced_cargo); j++) { + if (ind->produced_cargo[j] != CT_INVALID) { + i->total_production[j] = 8 * i->production_rate[j]; + } + } } static const Widget _industry_view_widgets[] = { @@ -452,7 +457,7 @@ WP(w, vp2_d).data_1 = 0; WP(w, vp2_d).data_2 = 0; WP(w, vp2_d).data_3 = 0; - AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetIndustry(w->window_number)->xy + TileDiffXY(1, 1), 1); + AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetIndustry(w->window_number)->xy + TileDiffXY(1, 1), ZOOM_LVL_INDUSTRY); } } @@ -482,6 +487,8 @@ { const Industry* i = *(const Industry**)a; const Industry* j = *(const Industry**)b; + const IndustrySpec *ind_i = GetIndustrySpec(i->type); + const IndustrySpec *ind_j = GetIndustrySpec(j->type); int r; switch (_industry_sort_order >> 1) { @@ -495,10 +502,10 @@ break; case 2: /* Sort by Production */ - if (i->produced_cargo[0] == CT_INVALID) { - r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1); + if (ind_i->produced_cargo[0] == CT_INVALID) { + r = (ind_j->produced_cargo[0] == CT_INVALID ? 0 : -1); } else { - if (j->produced_cargo[0] == CT_INVALID) { + if (ind_j->produced_cargo[0] == CT_INVALID) { r = 1; } else { r = @@ -509,23 +516,23 @@ break; case 3: /* Sort by transported fraction */ - if (i->produced_cargo[0] == CT_INVALID) { - r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1); + if (ind_i->produced_cargo[0] == CT_INVALID) { + r = (ind_j->produced_cargo[0] == CT_INVALID ? 0 : -1); } else { - if (j->produced_cargo[0] == CT_INVALID) { + if (ind_j->produced_cargo[0] == CT_INVALID) { r = 1; } else { int pi; int pj; pi = i->pct_transported[0] * 100 >> 8; - if (i->produced_cargo[1] != CT_INVALID) { + if (ind_i->produced_cargo[1] != CT_INVALID) { int p = i->pct_transported[1] * 100 >> 8; if (p < pi) pi = p; } pj = j->pct_transported[0] * 100 >> 8; - if (j->produced_cargo[1] != CT_INVALID) { + if (ind_j->produced_cargo[1] != CT_INVALID) { int p = j->pct_transported[1] * 100 >> 8; if (p < pj) pj = p; } @@ -606,14 +613,15 @@ while (p < _num_industry_sort) { const Industry* i = _industry_sort[p]; + const IndustrySpec *ind = GetIndustrySpec(i->type); SetDParam(0, i->index); - if (i->produced_cargo[0] != CT_INVALID) { - SetDParam(1, i->produced_cargo[0]); + if (ind->produced_cargo[0] != CT_INVALID) { + SetDParam(1, ind->produced_cargo[0]); SetDParam(2, i->total_production[0]); - if (i->produced_cargo[1] != CT_INVALID) { - SetDParam(3, i->produced_cargo[1]); + if (ind->produced_cargo[1] != CT_INVALID) { + SetDParam(3, ind->produced_cargo[1]); SetDParam(4, i->total_production[1]); SetDParam(5, i->pct_transported[0] * 100 >> 8); SetDParam(6, i->pct_transported[1] * 100 >> 8); diff -r 0b2aebc8283e -r 0b8b245a2391 src/industry_map.h --- a/src/industry_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/industry_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -207,46 +207,6 @@ IndustryGfx MaxGfx; ///< The last gfx index for the industry type }; -/** Mapping of industry gfx to industry type */ -static const IndustryTypeSolver industry_gfx_Solver[IT_END] = { - { 0, 6}, ///< IT_COAL_MINE - { 7, 10}, ///< IT_POWER_STATION, - { 11, 15}, ///< IT_SAWMILL, - { 16, 17}, ///< IT_FOREST, - { 18, 23}, ///< IT_OIL_REFINERY, - { 24, 28}, ///< IT_OIL_RIG, - { 29, 31}, ///< IT_OIL_WELL, - { 32, 38}, ///< IT_FARM, - { 39, 42}, ///< IT_FACTORY, - { 43, 46}, ///< IT_PRINTING_WORKS, - { 47, 51}, ///< IT_COPPER_MINE, - { 52, 57}, ///< IT_STEEL_MILL, - { 58, 59}, ///< IT_BANK_TEMP, - { 60, 63}, ///< IT_FOOD_PROCESS, - { 64, 71}, ///< IT_PAPER_MILL, - { 72, 88}, ///< IT_GOLD_MINE, - { 89, 90}, ///< IT_BANK_TROPIC_ARCTIC, - { 91, 99}, ///< IT_DIAMOND_MINE, - {100, 115}, ///< IT_IRON_MINE, - {116, 116}, ///< IT_FRUIT_PLANTATION, - {117, 117}, ///< IT_RUBBER_PLANTATION, - {118, 119}, ///< IT_WATER_SUPPLY, - {120, 120}, ///< IT_WATER_TOWER, - {121, 124}, ///< IT_FACTORY_2, - {125, 128}, ///< IT_LUMBER_MILL, - {129, 130}, ///< IT_COTTON_CANDY, - {131, 134}, ///< IT_CANDY_FACTORY or sweet factory - {135, 136}, ///< IT_BATTERY_FARM, - {137, 137}, ///< IT_COLA_WELLS, - {138, 141}, ///< IT_TOY_SHOP, - {142, 147}, ///< IT_TOY_FACTORY, - {148, 155}, ///< IT_PLASTIC_FOUNTAINS, - {156, 159}, ///< IT_FIZZY_DRINK_FACTORY, - {160, 163}, ///< IT_BUBBLE_GENERATOR, - {164, 166}, ///< IT_TOFFEE_QUARRY, - {167, 174} ///< IT_SUGAR_MINE, -}; - /** * Get the animation loop number * @param tile the tile to get the animation loop number of diff -r 0b2aebc8283e -r 0b8b245a2391 src/intro_gui.cpp --- a/src/intro_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/intro_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -64,6 +64,10 @@ break; case WE_CLICK: + /* Do not create a network server when you (just) have closed one of the game + * creation/load windows for the network server. */ + if (2 <= e->we.click.widget && e->we.click.widget <= 6) _is_network_server = false; + switch (e->we.click.widget) { case 2: ShowGenerateLandscape(); break; case 3: ShowSaveLoadDialog(SLD_LOAD_GAME); break; diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/american.txt --- a/src/lang/american.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/american.txt Wed Jun 13 11:45:14 2007 +0000 @@ -751,6 +751,7 @@ STR_02A1_SMALL :{BLACK}Small STR_02A2_MEDIUM :{BLACK}Medium STR_02A3_LARGE :{BLACK}Large +STR_SCENARIO_EDITOR_CITY :{BLACK}City STR_02A4_SELECT_TOWN_SIZE :{BLACK}Select town size STR_02A5_TOWN_SIZE :{YELLOW}Town size: @@ -1096,6 +1097,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll map STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Off STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Map scrollwheel speed: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatically pause when starting a new game: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Use the advanced vehicle list: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trains per player: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max road vehicles per player: {ORANGE}{STRING} @@ -1129,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Allow buying shares from other companies STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}When dragging place signals every: {ORANGE}{STRING} tile(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatically build semaphores before: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}The town layout "no more roads" isn't valid in the scenario editor +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Select town-road layout: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :no more roads +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :default +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :better roads +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 grid +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 grid + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre @@ -1143,6 +1155,7 @@ STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Very fast STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Proportion of towns that will grow twice as fast: {ORANGE}1 in {STRING} STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}Proportion of towns that will grow twice as fast: {ORANGE}None +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Initial city size multiplier: {ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Interface STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construction @@ -1999,6 +2012,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Heliport STR_SV_STNAME_FOREST :{STRING} Forest +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2034,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :None +STR_NUM_VERY_LOW :Very low STR_6816_LOW :Low STR_6817_NORMAL :Normal STR_6818_HIGH :High @@ -3099,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Change starting year STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Scale warning STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Resizing source map too much is not recommended. Continue with the generation? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Town layout warning +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}The town layout "no more roads" is not recommended. Continue with the generation? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Heightmap name: STR_HEIGHTMAP_SIZE :{BLACK}Size: {ORANGE}{NUM} x {NUM} @@ -3171,3 +3189,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Toggle transparency for buildables like stations, depots, waypoints and catenary STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Toggle transparency for bridges STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Toggle transparency for structures like lighthouses and antennas, maybe in future for eyecandy + +##### Mass Order +STR_GROUP_NAME_FORMAT :Group {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :All trains +STR_GROUP_ALL_ROADS :All road vehicles +STR_GROUP_ALL_SHIPS :All ships +STR_GROUP_ALL_AIRCRAFTS :All aircraft +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Add shared vehicles +STR_GROUP_REMOVE_ALL_VEHICLES :Remove all vehicles + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Train{P "" s} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Road Vehicle{P "" s} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Ship{P "" s} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Aircraft +STR_GROUP_RENAME_CAPTION :{BLACK}Rename a group +STR_GROUP_REPLACE_CAPTION :{WHITE}Replace Vehicles of "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... +STR_GROUP_CAN_T_DELETE :{WHITE}Can't delete this group... +STR_GROUP_CAN_T_RENAME :{WHITE}Can't rename group... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Can't remove all vehicles from this group... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this group... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Can't add shared vehicles to group... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Groups - Click on a group to list all of its vehicles +STR_GROUP_CREATE_TIP :{BLACK}Click to create a group +STR_GROUP_DELETE_TIP :{BLACK}Delete the selected group +STR_GROUP_RENAME_TIP :{BLACK}Rename the selected group +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Click to protect this group from global autoreplace + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {GREEN}{CURRENCY} {BLACK}(last year: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {RED}{CURRENCY} {BLACK}(last year: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {GREEN}{CURRENCY} {BLACK}(last year: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {RED}{CURRENCY} {BLACK}(last year: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/brazilian_portuguese.txt --- a/src/lang/brazilian_portuguese.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/brazilian_portuguese.txt Wed Jun 13 11:45:14 2007 +0000 @@ -753,6 +753,7 @@ STR_02A1_SMALL :{BLACK}Pequena STR_02A2_MEDIUM :{BLACK}Média STR_02A3_LARGE :{BLACK}Grande +STR_SCENARIO_EDITOR_CITY :{BLACK}Cidade STR_02A4_SELECT_TOWN_SIZE :{BLACK}Selecionar tamanho da cidade STR_02A5_TOWN_SIZE :{YELLOW}Tamanho da cidade: @@ -1098,6 +1099,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll map STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Desligado STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Velocidade do scrollwheel do mapa: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Pausar automaticamente ao inicar um novo jogo: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Usar a lista avançada de veículos: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máximo de trens por jogador: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máximo de automóveis por jogador: {ORANGE}{STRING} @@ -1131,6 +1134,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite comprar ações de outras companhias STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ao arrastar colocar sinais a cada: {ORANGE}{STRING} quadrado(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automaticamente constroi semáforos anteriores: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}O layout de cidade "sem mais estradas" não é válido no editor +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Selecione o layout das estradas {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :sem mais estradas +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :padrão +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :melhores estradas +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :grade 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :grade 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posição da barra de ferramentas principal: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerda STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro @@ -1145,6 +1157,7 @@ STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Muito rápido STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Proporção de cidades que irão crescer duas vezes mais rápido: {ORANGE}1 em {STRING} STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}Proporção de cidades que irão crescer duas vezes mais rápido: {ORANGE}Nenhum +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Multiplicador do tamanho inicial da cidade: {ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Interface STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construção @@ -2003,6 +2016,7 @@ STR_SV_STNAME_HELIPORT :Heliporto de {STRING} STR_SV_STNAME_FOREST :Floresta de {STRING} + ############ end of savegame specific region! ##id 0x6800 @@ -2038,6 +2052,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Nenhum +STR_NUM_VERY_LOW :Muito baixo STR_6816_LOW :Baixo STR_6817_NORMAL :Normal STR_6818_HIGH :Alto @@ -3103,6 +3118,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Mudar data de início STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Aviso de Escala STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Alterar muito o tamanho do mapa original não é recomendado. Continuar com a geração? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Aviso do layout da cidade +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}O Layout "sem mais estradas" não é recomendado. Continuar com a geração? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nome do mapa em relevo: STR_HEIGHTMAP_SIZE :{BLACK}Tamanho: {ORANGE}{NUM} x {NUM} @@ -3175,3 +3192,35 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Alternar transparência para construções como estações, depósitos, pontos de controle e eletrificação da ferrovia STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Alternar transparência para pontes STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Alternar transparência para estruturas como faróis e antenas, talvez no futuro para efeitos visuais + +##### Mass Order +STR_GROUP_NAME_FORMAT :Agrupar {COMMA} +STR_GROUP_ALL_TRAINS :Todos os trens +STR_GROUP_ALL_ROADS :Todos os automóveis +STR_GROUP_ALL_SHIPS :Todos os navios +STR_GROUP_ALL_AIRCRAFTS :Todas as aeronaves +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Adicionar veículos compartilhados +STR_GROUP_REMOVE_ALL_VEHICLES :Remover todos os veículos + +STR_GROUP_RENAME_CAPTION :{BLACK}Renomear um grupo + +STR_GROUP_CAN_T_CREATE :{WHITE}Impossível criar grupo... +STR_GROUP_CAN_T_DELETE :{WHITE}Impossível remover grupo... +STR_GROUP_CAN_T_RENAME :{WHITE}Impossível renomear grupo... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Impossível remover todos os veículos desse grupo... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Impossível adicionar veículo a esse grupo +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossível adicionar veículos compartilhados a esse grupo... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Grupos - Clique em um grupo para listar seus veículos +STR_GROUP_CREATE_TIP :{BLACK}Clique para criar um grupo +STR_GROUP_DELETE_TIP :{BLACK}Remove o grupo selecionado +STR_GROUP_RENAME_TIP :{BLACK}Renomeia o grupo selecionado +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Clique para excluir esse grupo da substituição automática + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Lucros do ano: {GREEN}{CURRENCY} {BLACK}(ano passado: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Lucros do ano: {RED}{CURRENCY} {BLACK}(ano passado: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Lucros do ano {GREEN}{CURRENCY} {BLACK}(ano passado: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Lucros do ano: {RED}{CURRENCY} {BLACK}(ano passado {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/bulgarian.txt --- a/src/lang/bulgarian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/bulgarian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1099,6 +1099,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Разгледай картата STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Изклучен STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Scrollwheel скорост на картата: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Автоматична пауза стартирайки нова игра: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Макс. влакове на играч: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Макс. брой коли на играч: {ORANGE}{STRING} @@ -1132,6 +1133,14 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Позволяване покупката на акции от други компании STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При влачене, поставяне на семафори всеки: {ORANGE}{STRING} плочка(и) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Автоматично построй семафори преди: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Грацкиа план "няма повече пътища" е невалиден в сценарий редакторат +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Избери грацки пътформат: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :няма повече пътища +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :по-добри пътища +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2х2 мрежа +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3х3 мрежа + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Позиция на лента за инструменти: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Ляво STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Център @@ -2003,6 +2012,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Хелипорт STR_SV_STNAME_FOREST :{STRING} Дървета +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2038,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Николко +STR_NUM_VERY_LOW :Много ниско STR_6816_LOW :малко STR_6817_NORMAL :нормално STR_6818_HIGH :много @@ -3103,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Промяна началната година STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Мащаб предупреждение STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Прекаленото оразмеряване не е препорачително. Продължаване с генерацията? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Грацки план предупреждение +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Грацкиа план "няма повече пътища" не е препоръчан. Продължи със създаването? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Име на височинна карта: STR_HEIGHTMAP_SIZE :{BLACK}Размер: {ORANGE}{NUM} x {NUM} @@ -3175,3 +3189,13 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Използвай прозрачност за сгради като гари, депа, пътни точки и висящи жици STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Използвай прозрачност за мостове STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Използвай прозрачност за сгради като фарове и антени, може би в бъдеще за украси + +##### Mass Order +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} + + + + + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/catalan.txt --- a/src/lang/catalan.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/catalan.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Moure mapa STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Off STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Velocitat del mapa amb la rodeta del ratolí: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Posa en pausa automàticament en començar un joc nou: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trens per jugador: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max automòbils per jugador: {ORANGE}{STRING} @@ -1130,6 +1131,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permet comprar participacions d'altres empreses STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Arrossegant, sitúa senyals cada: {ORANGE}{STRING} quadre(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Construir semàfors automàticament abans de: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}El format de poble "no més carreteres" no és vàlid a l'editor d'escenaris +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Selecciona el format poble-carretera: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :sense més carreteres +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :predeterminat +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :millors carreteres +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :graella 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :graella 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posició de la barra d'eines principal: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerra STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre @@ -2036,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Cap +STR_NUM_VERY_LOW :Molt baix STR_6816_LOW :Baix STR_6817_NORMAL :Normal STR_6818_HIGH :Alt @@ -3101,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Canviar l'any inicial STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Alerta d'escala STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}No es recomana redimensionar massa el mapa d'origen. Vols continuar amb la generació? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Alerta de format de poble +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}El format de poble "no més carreteres" no està recomanat. Continuar amb la generació? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nom del mapa d'alçades: STR_HEIGHTMAP_SIZE :{BLACK}Mida: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/czech.txt --- a/src/lang/czech.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/czech.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1155,6 +1155,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :pohyb po mapě STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :nic STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Rychlost skrolovacího kolečka: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Zastavit automaticky hru při začínání nové hry: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximum vlaků na hráče: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximum silničních vozidel na hráče: {ORANGE}{STRING} @@ -1188,6 +1189,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Povolit kupování podílu z ostatních společností STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Při tažení umisťovat signály každých(é): {ORANGE}{STRING} dilků(y) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Semafory automaticky stavět do roku: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Vzor "žádné silnice" se neuplatňuje v editoru scénářů +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Vyber vzor městských silnic: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :žádné silnice +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :původní +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :lepší silnice +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :mřížka 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :mřížka 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Umístění hlavní lišty: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :vlevo STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :uprostřed @@ -2094,6 +2104,7 @@ ############ range for difficulty settings ends STR_26816_NONE :žádný +STR_NUM_VERY_LOW :velmi nízké STR_6816_LOW :nízké STR_6817_NORMAL :střední STR_6818_HIGH :vysoké @@ -3165,6 +3176,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Změnit počáteční rok STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Varování kvůli velikosti STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Tak velká zmena velikosti zdrojové mapy není doporučena. Pokračovat s generováním? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Varování kvůli vzoru silnic +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Vzor "žádné silnice" není doporučen (nepostaví se ani domy). Pokračovat ve vytváření mapy? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Jméno výškové mapy: STR_HEIGHTMAP_SIZE :{BLACK}Velikost: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/danish.txt --- a/src/lang/danish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/danish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -385,7 +385,7 @@ STR_SORT_BY_VALUE :Værdi STR_SORT_BY_FACILITY :Stationstype STR_SORT_BY_WAITING :Værdi af ventende fragt -STR_SORT_BY_RATING_MAX :Fragtrangering +STR_SORT_BY_RATING_MAX :Fragtbedømmelse STR_ENGINE_SORT_ENGINE_ID :Lokomotiv ID (klassisk) STR_ENGINE_SORT_COST :Omkostning STR_ENGINE_SORT_POWER :Drivmiddel @@ -408,7 +408,7 @@ STR_SEND_ROAD_VEHICLE_TO_DEPOT :Send til værksted STR_SEND_SHIP_TO_DEPOT :Send til skibsdok STR_SEND_AIRCRAFT_TO_HANGAR :Send til hangar -STR_SEND_FOR_SERVICING :Send til service +STR_SEND_FOR_SERVICING :Send til eftersyn ############ range for months starts STR_0162_JAN :jan @@ -458,7 +458,7 @@ STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Vinduestitel - træk her for at flytte vinduet STR_STICKY_BUTTON :{BLACK}Marker dette vindue som ulukkeligt af 'Luk ALLE vinduer' tasten STR_RESIZE_BUTTON :{BLACK}Klik og træk for at ændre vinduets størrelse -STR_SAVELOAD_HOME_BUTTON :{BLACK}Klik her for at gå til det nuværende default gemme/hente bibliotek +STR_SAVELOAD_HOME_BUTTON :{BLACK}Klik her for at gå til det nuværende standard gemme/hente bibliotek STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Nedriv bygninger osv. på et stykke land STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Sænk et hjørne af landet STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Hæv et hjørne af landet @@ -989,15 +989,15 @@ # DON'T ADD OR REMOVE LINES HERE STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Tog {COMMA} har for få ordrer i sin odreliste STR_TRAIN_HAS_VOID_ORDER :{WHITE}Tog {COMMA} har en ugyldig ordre -STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Tog {COMMA} har dobbelt ordrer +STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}Tog {COMMA} har dobbelte ordrer STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}Tog {COMMA} har en ugyldig station i sin ordreliste -STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Køretøj {COMMA} har for få ordrer i sin ruteplan +STR_ROADVEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}Køretøj {COMMA} har for få ordrer i sin ordreliste STR_ROADVEHICLE_HAS_VOID_ORDER :{WHITE}Køretøj {COMMA} har en ugyldig ordre -STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Køretøj {COMMA} har dobbelt ordrer +STR_ROADVEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}Køretøj {COMMA} har dobbelte ordrer STR_ROADVEHICLE_HAS_INVALID_ENTRY :{WHITE}Køretøj {COMMA} har en ugyldig station i sin ordreliste STR_SHIP_HAS_TOO_FEW_ORDERS :{WHITE}Skib {COMMA} har for få ordrer i sin ordreliste STR_SHIP_HAS_VOID_ORDER :{WHITE}Skib {COMMA} har en ugyldig ordre -STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Skib {COMMA} har dobbelt ordrer +STR_SHIP_HAS_DUPLICATE_ENTRY :{WHITE}Skib {COMMA} har dobbelte ordrer STR_SHIP_HAS_INVALID_ENTRY :{WHITE}Skib {COMMA} har en ugyldig havn i sin ordreliste STR_AIRCRAFT_HAS_TOO_FEW_ORDERS :{WHITE}Fly {COMMA} har for få ordrer i sin ordreliste STR_AIRCRAFT_HAS_VOID_ORDER :{WHITE}Fly {COMMA} har en ugyldig ordre @@ -1097,6 +1097,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Rul kort STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Slået fra STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Rulleknap-hastighed på kort: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Sæt automatisk på pause når nyt spil startes: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Brug avanceret køretøjsliste: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. antal tog per spiller: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks. antal køretøjer per spiller: {ORANGE}{STRING} @@ -1130,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillad at købe aktier i andre selskaber STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ved trækning placer signal hvert: {ORANGE}{STRING} felt STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Byg automatisk semaforer før: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Vejlayoutet "ikke flere veje" er ikke gyldigt i scenarieeditoren +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Vælg layout for veje i byer: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :ikke flere veje +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :standard +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :bedre veje +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 gitter +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 gitter + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Placering af værktøjslinje: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Venstre STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Center @@ -1244,7 +1255,7 @@ STR_DRAG_DROP :{BLACK}Træk & slip STR_STATION_DRAG_DROP :{BLACK}Byg en station vha. træk & slip STR_SELECT_STATION_CLASS_TIP :{BLACK}Vælg hvilken stationstype, der skal vises -STR_SELECT_STATION_TYPE_TIP :{BLACK}Vælg hvilen stationstype du vil bygge +STR_SELECT_STATION_TYPE_TIP :{BLACK}Vælg hvilken stationstype du vil bygge STR_FAST_FORWARD :{BLACK}Kør spillet hurtigere STR_MESSAGE_HISTORY :{WHITE}Tidligere beskeder @@ -1279,10 +1290,10 @@ STR_INDUSTRY_TOO_CLOSE :{WHITE}...for tæt på en anden industribygning -STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Ombyg toget til at køre med en anden slags last +STR_RAIL_REFIT_VEHICLE_TO_CARRY :{BLACK}Ombyg toget til at køre med en anden lasttype STR_RAIL_REFIT_VEHICLE :{BLACK}Ombyg toget -STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg den slags last toget skal køre med -STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg toget til at køre med den markerede slags last +STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg den lasttype toget skal køre med +STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg toget til at køre med den markerede lasttype STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Kan ikke ombygge toget... STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Service intervaller er i procent: {ORANGE}{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Skift produktion @@ -1580,7 +1591,7 @@ ##id 0x1800 STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Det er nødvendigt at fjerne vejen først -STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vejarbejde er i gang +STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vejarbejde i gang STR_1802_ROAD_CONSTRUCTION :{WHITE}Vejkonstruktion STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Vælg vejbro STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Kan ikke bygge vej her... @@ -1693,7 +1704,7 @@ STR_2051_BUILD_A_STATUE_IN_HONOR :{WHITE}{STRING}{}{YELLOW} Byg en statue til ære for dit selskab.{} Pris: {CURRENCY} STR_2052_FUND_THE_CONSTRUCTION_OF :{WHITE}{STRING}{}{YELLOW} Betal for opførelse af forretningsbygninger i byen.{} Pris: {CURRENCY} STR_2053_BUY_1_YEAR_S_EXCLUSIVE :{WHITE}{STRING}{}{YELLOW} Køb et års eksklusive rettigheder til transport i byen. De lokale myndigheder vil kun tillade passagerer og last at bruge dine stationer.{} Prist: {CURRENCY} -STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bestik de lokale myndigheder til at hæve din bedømmelse, med sandsynlighed for en stor straf hvis det bliver opdaget.{} Pris: {CURRENCY} +STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bestik de lokale myndigheder til at hæve din bedømmelse, med risiko for en stor straf hvis det bliver opdaget.{} Pris: {CURRENCY} STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Trafikkaos i byen {TOWN}!{}{}Vejfornyelse betalt af {COMPANY} forårsager 6 måneders kaos i trafikken! STR_2056 :{TINYFONT}{WHITE}{TOWN} STR_2058_UNDER_CONSTRUCTION :{STRING} (under konstruktion) @@ -2001,6 +2012,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Helikopterplads STR_SV_STNAME_FOREST :{STRING} Skov +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2036,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ingen +STR_NUM_VERY_LOW :Meget lav STR_6816_LOW :Lav STR_6817_NORMAL :Normal STR_6818_HIGH :Høj @@ -2136,7 +2150,7 @@ STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Direktør) STR_7038_INAUGURATED :{GOLD}Indviet: {WHITE}{NUM} STR_7039_VEHICLES :{GOLD}Køretøjer: -STR_TRAINS :{WHITE}{COMMA} tog +STR_TRAINS :{WHITE}{COMMA} tog{P "" e} STR_ROAD_VEHICLES :{WHITE}{COMMA} køretøj{P "" er} STR_AIRCRAFT :{WHITE}{COMMA} fly STR_SHIPS :{WHITE}{COMMA} skib{P "" e} @@ -2714,7 +2728,7 @@ STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Ombyg vejkøretøj til at laste en anden type last STR_REFIT_ROAD_VEHICLE :{BLACK}Ombyg lastbil -STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg vejkøretøjet til at laste den markede type last +STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Ombyg vejkøretøjet til at laste den markerede type last STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Kan ikke ombygge vejkøretøj STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Vælg lasttype som lastbilen skal transportere @@ -2975,7 +2989,7 @@ STR_SCHEDULED_AIRCRAFT :{WHITE}{STATION} - {COMMA} Fly STR_SCHEDULED_SHIPS :{WHITE}{STATION} - {COMMA} Skib{P "" e} -STR_SCHEDULED_TRAINS_TIP :{BLACK}Vis alle tog, som har denne station i deres ruteplan +STR_SCHEDULED_TRAINS_TIP :{BLACK}Vis alle toge, som har denne station i deres ruteplan STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Vis alle køretøjer, som har denne station i deres ruteplan STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Vis alle fly, som har denne lufthavn i deres ruteplan STR_SCHEDULED_SHIPS_TIP :{BLACK}Vis alle skibe, som har denne station i deres ruteplan @@ -3012,7 +3026,7 @@ STR_NOT_REPLACING :{BLACK}Udskifter ikke STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Intet køretøj valgt STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Vælg en køretøjstype, som du ønsker udskiftet -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vælg en køretøjstype, som du ønker at få i stedet for den type, du har valgt i venste side +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Vælg en køretøjstype, som du ønker benyttet i stedet for den type, du har valgt i venste side STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Tryk for at stoppe udskiftningen at den køretøjstype, som du har valgt til venstre STR_REPLACE_HELP_START_BUTTON :{BLACK}Tryk for at begynde at udskifte køretøjstypen til venstre med køretøjstypen til højre STR_REPLACE_HELP_RAILTYPE :{BLACK}Vælg den skinnetype, hvor du vil udskifte lokomotiver @@ -3021,10 +3035,10 @@ STR_REPLACE_REMOVE_WAGON :{BLACK}Fjern vogn: {ORANGE}{SKIP}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Få autoudskift til at bevare længden af tog ved at fjerne vogne (startende fra fronten), hvis autoudskiftningen gør toget længere. STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Udskifter: {ORANGE}{SKIP}{SKIP}{STRING} -STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERIMENTEL EGENSKAB {}Skift imellem lokomotiv- og vogn-udskiftningsvindue.{}Vognudskiftning vil kun finde sted hvis den nye vogn kan ændres til at transportere samme godstype some den gamle vogn. Dette bliver checket for hver vogn, når udskiftningen finder sted. -STR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Tog er ikke tilgængelig -STR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Vejkøretøj er ikke tilgængelig -STR_SHIP_NOT_AVAILABLE :{WHITE}Skib er ikke tilgængelig +STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK} EKSPERIMENTEL EGENSKAB {}Skift imellem lokomotiv- og vogn-udskiftningsvindue.{}Vognudskiftning vil kun finde sted hvis den nye vogn kan ændres til at transportere samme godstype som den gamle vogn. Dette bliver checket for hver vogn, når udskiftningen finder sted. +STR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Tog er ikke tilgængeligt +STR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Vejkøretøj er ikke tilgængeligt +STR_SHIP_NOT_AVAILABLE :{WHITE}Skib er ikke tilgængeligt STR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Fly er ikke tilgængelig STR_ENGINES :Lokomotiver @@ -3101,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Ændre startår STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalerings advarsel STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}At ændre størrelsen på kildebilledet anbefales ikke. Fortsæt genereringen? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Vejlayout-advarsel +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Vejlayoutet "ikke flere veje" anbefales ikke. Fortsæt med at generere? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Højdekortets navn: STR_HEIGHTMAP_SIZE :{BLACK}Størrelse: {ORANGE}{NUM} x {NUM} @@ -3173,3 +3189,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Skift gennemsigtighed for konstruktioner som stationer, værksteder, kontrolsteder og køreledninger STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Skift gennemsigtighed for broer STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Skift gennemsigtighed for strukturer som fyrtårne og antenner, og måske i fremtiden for øjeguf + +##### Mass Order +STR_GROUP_NAME_FORMAT :Gruppe {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Alle toge +STR_GROUP_ALL_ROADS :Alle vejkøretøjer +STR_GROUP_ALL_SHIPS :Alle skibe +STR_GROUP_ALL_AIRCRAFTS :Alle fly +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Tilføj delte køretøjer +STR_GROUP_REMOVE_ALL_VEHICLES :Fjern alle køretøjer + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Tog{P "" e} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Vejkøretøj{P "" er} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Skib{P "" e} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Fly +STR_GROUP_RENAME_CAPTION :{BLACK}Omdøb en gruppe +STR_GROUP_REPLACE_CAPTION :{WHITE}Udskift køretøjer i "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Kan ikke oprette gruppe... +STR_GROUP_CAN_T_DELETE :{WHITE}Kan ikke slette denne gruppe... +STR_GROUP_CAN_T_RENAME :{WHITE}Kan ikke omdøbe gruppe... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan ikke fjerne alle køretøjer fra denne gruppe... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan ikke tilføje køretøjet til denne gruppe... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan ikke tilføje delte køretøjer til gruppe... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Grupper - klik på en gruppe for at vise alle køretøjer i gruppen +STR_GROUP_CREATE_TIP :{BLACK}Klik for at oprette en gruppe +STR_GROUP_DELETE_TIP :{BLACK}Slet den valgte gruppe +STR_GROUP_RENAME_TIP :{BLACK}Omdøb den valgte gruppe +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Klik for at beskytte denne gruppe mod global auto-udskiftning + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Afkast i indeværende år: {GREEN}{CURRENCY} {BLACK}(sidste år: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Afkast i indeværende år: {RED}{CURRENCY} {BLACK}(sidste år: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Afkast i indeværende år: {GREEN}{CURRENCY} {BLACK}(sidste år: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Afkast i indeværende år: {RED}{CURRENCY} {BLACK}(sidste år: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/dutch.txt --- a/src/lang/dutch.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/dutch.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll kaart STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Uit STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Kaart muiswiel snelheid: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatisch pauzeren wanneer je een nieuw spel start: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Gebruik de geavanceerde voertuigenlijst: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximaal aantal treinen per speler: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximaal aantal wegvoertuigen per speler: {ORANGE}{STRING} @@ -1130,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Sta het kopen van aandelen toe STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Bij slepen, plaats seinen elke: {ORANGE}{STRING} tegel(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Plaats automatisch semaphore seinen voor: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}De stadindeling "geen wegen" is niet geldig in de scenario editor +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Selecteer stedelijke wegindeling: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :geen wegen +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :standaard +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :betere wegen +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 raster +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 raster + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Positie van algemene toolbar: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Midden @@ -2001,6 +2012,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Helihaven STR_SV_STNAME_FOREST :{STRING} Bossen +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2036,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Geen +STR_NUM_VERY_LOW :Erg laag STR_6816_LOW :Laag STR_6817_NORMAL :Normaal STR_6818_HIGH :Hoog @@ -3078,7 +3092,7 @@ ########### String for New Landscape Generator -STR_GENERATE :{WHITE}Creeër +STR_GENERATE :{WHITE}Maak aan STR_RANDOM :{BLACK}Willekeurig maken STR_RANDOM_HELP :{BLACK}Wijzig het willekeurige getal voor terrein creatie STR_WORLD_GENERATION_CAPTION :{WHITE}Wereld maken @@ -3101,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Verander begin jaar STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Schaal waarschuwing STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Het aanpassen van de grootte van een bronkaar is niet aan te bevelen. Toch doorgaan? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Stadsindelingswaarschuwing +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}De stadsindeling "geen wegen" is niet aanbevolen. Doorgaan met aanmaken? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Hoogtekaart naam: STR_HEIGHTMAP_SIZE :{BLACK}Grootte: {ORANGE}{NUM} x {NUM} @@ -3121,7 +3137,7 @@ STR_SE_FLAT_WORLD :{WHITE}Vlak land STR_SE_FLAT_WORLD_TIP :{BLACK}Genereer een platte kaart STR_SE_RANDOM_LAND :{WHITE}Willekeurig land -STR_SE_NEW_WORLD :{BLACK}Creeër nieuw scenario +STR_SE_NEW_WORLD :{BLACK}Maak nieuw scenario aan STR_SE_CAPTION :{WHITE}Scenario type STR_FLAT_WORLD_HEIGHT_DOWN :{BLACK}Maak de hoogte van plat land een lager STR_FLAT_WORLD_HEIGHT_UP :{BLACK}Maak de hoogte van plat land een hoger @@ -3173,3 +3189,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Wissel doorzichtigheid voor gebouwen zoals stations, depots, waypoints en bovenleiding STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Wissel doorzichtigheid voor bruggen STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Wissel doorzichtigheid voor structuren zoals vuurtoren en antennes, in de toekomst misschien voor eyecandy + +##### Mass Order +STR_GROUP_NAME_FORMAT :Groep {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Alle treinen +STR_GROUP_ALL_ROADS :Alle voertuigen +STR_GROUP_ALL_SHIPS :Alle schepen +STR_GROUP_ALL_AIRCRAFTS :Alle vliegtuigen +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Toevoegen gedeelde voertuigen +STR_GROUP_REMOVE_ALL_VEHICLES :Verwijder alle voertuigen + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Trein{P "" en} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Weg Voertuig{P "" en} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Schip{P "" s} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Vliegtuig +STR_GROUP_RENAME_CAPTION :{BLACK}Hernoem een groep +STR_GROUP_REPLACE_CAPTION :{WHITE}Vervang voertuigen van "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Kan groep niet maken... +STR_GROUP_CAN_T_DELETE :{WHITE}Kan deze groep niet verwijderen... +STR_GROUP_CAN_T_RENAME :{WHITE}Kan deze groep niet hernoemen... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan niet alle voertuigen van deze groep verwijderen... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan niet alle voertuigen aan deze groep toevoegen... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan niet alle gedeelde voertuigen aan deze groep toevoegen... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Groepen - Klik op een groep voor een lijst van alle voertuigen in deze groep +STR_GROUP_CREATE_TIP :{BLACK}Klik om een groep te maken +STR_GROUP_DELETE_TIP :{BLACK}Verwijder de geselecteerde groep +STR_GROUP_RENAME_TIP :{BLACK}Hernoem de geselecteerde groep +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Klik om deze groep te beschermen tegen globaal automatisch vervangen + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Winst dit jaar: {GREEN}{CURRENCY} {BLACK}(vorig jaar: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Winst dit jaar: {RED}{CURRENCY} {BLACK}(vorig jaar: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Winst dit jaar: {GREEN}{CURRENCY} {BLACK}(vorig jaar: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Winst dit jaar: {RED}{CURRENCY} {BLACK}(vorig jaar: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/english.txt --- a/src/lang/english.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/english.txt Wed Jun 13 11:45:14 2007 +0000 @@ -3,6 +3,8 @@ ##isocode en_GB ##plural 0 +# + ##id 0x0000 STR_NULL : STR_0001_OFF_EDGE_OF_MAP :{WHITE}Off edge of map @@ -1099,6 +1101,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll map STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Off STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Map scrollwheel speed: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatically pause when starting a new game: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Use the advanced vehicle list: {ORANGE}{STRING1} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max trains per player: {ORANGE}{STRING1} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max road vehicles per player: {ORANGE}{STRING1} @@ -1132,6 +1136,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Allow buying shares from other companies STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}When dragging, place signals every: {ORANGE}{STRING1} tile(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatically build semaphores before: {ORANGE}{STRING1} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}The town layout "no more roads" isn't valid in the scenario editor +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Select town-road layout: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :no more roads +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :default +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :better roads +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 grid +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 grid + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position of main toolbar: {ORANGE}{STRING1} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Left STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre @@ -2011,6 +2024,8 @@ STR_SV_STNAME_HELIPORT :{STRING1} Heliport STR_SV_STNAME_FOREST :{STRING1} Forest +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2048,6 +2063,7 @@ ############ range for difficulty settings ends STR_26816_NONE :None +STR_NUM_VERY_LOW :Very low STR_6816_LOW :Low STR_6817_NORMAL :Normal STR_6818_HIGH :High @@ -3117,6 +3133,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Change starting year STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Scale warning STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Resizing source map too much is not recommended. Continue with the generation? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Town layout warning +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}The town layout "no more roads" is not recommended. Continue with the generation? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Heightmap name: STR_HEIGHTMAP_SIZE :{BLACK}Size: {ORANGE}{NUM} x {NUM} @@ -3189,3 +3207,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Toggle transparency for buildables like stations, depots, waypoints and catenary STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Toggle transparency for bridges STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Toggle transparency for structures like lighthouses and antennas, maybe in future for eyecandy + +##### Mass Order +STR_GROUP_NAME_FORMAT :Group {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :All trains +STR_GROUP_ALL_ROADS :All road vehicles +STR_GROUP_ALL_SHIPS :All ships +STR_GROUP_ALL_AIRCRAFTS :All aircraft +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Add shared vehicles +STR_GROUP_REMOVE_ALL_VEHICLES :Remove all vehicles + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Train{P "" s} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Road Vehicle{P "" s} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Ship{P "" s} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Aircraft +STR_GROUP_RENAME_CAPTION :{BLACK}Rename a group +STR_GROUP_REPLACE_CAPTION :{WHITE}Replace Vehicles of "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... +STR_GROUP_CAN_T_DELETE :{WHITE}Can't delete this group... +STR_GROUP_CAN_T_RENAME :{WHITE}Can't rename group... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Can't remove all vehicles from this group... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this group... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Can't add shared vehicles to group... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Groups - Click on a group to list all vehicles of this group +STR_GROUP_CREATE_TIP :{BLACK}Click to create a group +STR_GROUP_DELETE_TIP :{BLACK}Delete the selected group +STR_GROUP_RENAME_TIP :{BLACK}Rename the selected group +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Click to protect this group from global autoreplace + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {GREEN}{CURRENCY} {BLACK}(last year: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {RED}{CURRENCY} {BLACK}(last year: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {GREEN}{CURRENCY} {BLACK}(last year: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {RED}{CURRENCY} {BLACK}(last year: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/esperanto.txt --- a/src/lang/esperanto.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/esperanto.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1098,6 +1098,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Skroli mapon STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Malaktiva STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Mapskrolrada rapido: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Aŭtomate paŭzu startante novan ludon: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Trajna maksimumo por ĉiu ludanto: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Vojveturila maksimumo por ĉiu ludanto: {ORANGE}{STRING} @@ -1131,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permesu aĉetadon de dividaĵoj en aliaj kompanioj STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Tirante metu signalojn je ĉiuj: {ORANGE}{STRING} kvadrado(j) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Aŭtomate konstruu semaforojn antaŭ: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}La urbaspekto "sen pliaj vojoj" ne validas en la scenarkreilo +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Elektu urbvojan aspekton: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :sen pliaj vojoj +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :defaŭlte +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :pli bonaj vojoj +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :kvadrataro de 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :kvadrataro de 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Loko de ĉefa ilbreto: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Maldekstre STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centre @@ -2037,6 +2047,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Neniu +STR_NUM_VERY_LOW :Tre malalte STR_6816_LOW :Malalte STR_6817_NORMAL :Normale STR_6818_HIGH :Alte @@ -3102,6 +3113,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Ŝanĝu komencjaron STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skala averto STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Ne rekomendindas tro ŝanĝi la grandecon de la mapo. Ĉu daŭrigi la generadon? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Urbaspekta averto +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}La urbaspekto "sen pliaj vojoj" ne estas rekomendata. Ĉu plugeneri? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Mapa nomo: STR_HEIGHTMAP_SIZE :{BLACK}Grandeco: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/estonian.txt --- a/src/lang/estonian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/estonian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1197,6 +1197,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Keri kaarti STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Väljas STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Kaarti kerimisratta kiirus: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automaatne mängu peatamine uue mängu alustamisel: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. rongide arv mängija kohta: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Suurim maanteesõidukite arv mängija kohta: {ORANGE}{STRING} @@ -1230,6 +1231,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Luba teiste ettevõtete aktsiate ostmine STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Venitades paigutatud signaaltulede tihedus: {ORANGE}{STRING} ühik(ut) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Ehita semaforid automaatselt enne: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Stsenaariumiredaktor ei tunnista "ilma teedeta" linnaplaneeringut +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Vali linnale teeplaan: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :ilma teedeta +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :tavalised +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :paremad teed +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 ruudustik +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 ruudustik + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Tööriistariba asukoht: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Vasakul STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Keskel @@ -2136,6 +2146,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Pole +STR_NUM_VERY_LOW :Väga madal STR_6816_LOW :Madal STR_6817_NORMAL :Harilik STR_6818_HIGH :Kõrge @@ -2507,7 +2518,7 @@ STR_80A5_UHL_WATER_TANKER :Uhl veeveok STR_80A6_BALOGH_WATER_TANKER :Balogh veeveok STR_80A7_MPS_WATER_TANKER :MPS veeveok -STR_80A8_BALOGH_FRUIT_TRUCK :Balogh veeveok +STR_80A8_BALOGH_FRUIT_TRUCK :Balogh puuviljaveok STR_80A9_UHL_FRUIT_TRUCK :Uhl puuviljaveok STR_80AA_KELLING_FRUIT_TRUCK :Kelling puuviljaveok STR_80AB_BALOGH_RUBBER_TRUCK :Balogh kummiveok @@ -3201,6 +3212,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Muuda algusaastat STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skaala hoiatus STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Kaardi suuruse muutmine pole soovitatav. Jätka? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Linnaplaneerimise hoiatus +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Linnaplaneeringut "ilma teedeta" ei ole soovitatav kasutada. Jätkata selle tekitamisega? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Kõrgusekaardi nimi: STR_HEIGHTMAP_SIZE :{BLACK}Suurus: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/finnish.txt --- a/src/lang/finnish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/finnish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Vieritä karttaa STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Pois STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Rullan nopeus: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Uusi peli alkaa pysäytettynä: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Junia/pelaaja: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Ajoneuvoja/pelaaja: {ORANGE}{STRING} @@ -1130,6 +1131,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Salli osakkeiden ostaminen muista yhtiöistä STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Vedettäessä aseta opastimien väleiksi: {ORANGE}{STRING} ruutu(a) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Rakenna opasteet automaattisesti ennen: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Tiekaavaa "ei uusia teitä" ei voi käyttää editorissa +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Valitse tiekaava: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :ei uusia teitä +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :oletus +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :parempia teitä +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 ruudukko +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 ruudukko + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Päätyökalupalkin sijainti: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :vasen STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :keskellä @@ -2036,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ei mitään +STR_NUM_VERY_LOW :Erittäin alhainen STR_6816_LOW :Matala STR_6817_NORMAL :Normaali STR_6818_HIGH :Korkea @@ -3101,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Vaihda aloitusvuosi STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Mittakaava-varoitus STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Lähdekartan koon liiallinen muuttaminen ei ole suositeltavaa. Haluatko jatkaa? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Varoitus tiekaavasta +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Tiekaavaa "ei uusia teitä" ei suositella. Jatketaanko? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Korkeuskartan nimi: STR_HEIGHTMAP_SIZE :{BLACK}Koko: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/french.txt --- a/src/lang/french.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/french.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1098,6 +1098,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Défilement de la carte STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Désactivé STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Vitesse de défilement avec molette: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Pause automatique en début de nouvelle partie: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Utiliser la liste de véhicules avancée: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Nombre de trains max. par joueur: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Nombre de véhicules routiers max. par joueur: {ORANGE}{STRING} @@ -1131,6 +1133,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permettre d'acheter des actions d'autres compagnies STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Espacements des signaux en mode drag & drop : {ORANGE}{STRING} case(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Construire automatiquement des sémaphores avant: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Le schéma de ville "pas de routes" n'est pas autorisé dans l'éditeur de scénario +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Choisir un schéma de ville: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :pas de routes +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :défaut +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :meilleures routes +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :grille 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :grille 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position de la barre d'outils principale: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :À gauche STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centrée @@ -2002,6 +2013,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Héliport STR_SV_STNAME_FOREST :{STRING} Forêt +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2037,6 +2050,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Aucune +STR_NUM_VERY_LOW :Très bas STR_6816_LOW :Bas STR_6817_NORMAL :Normal STR_6818_HIGH :Élevé @@ -3102,6 +3116,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Modifier l'année de départ STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avertissement de redimensionnement STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Trop redimensionner la carte source n'est pas recommandé. Continuer la génération ? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Avertissement schéma de ville +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Le schéma de ville "pas de routes" n'est pas recommandé. Voulez-vous poursuivre la génération? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nom de la carte d'altitude : STR_HEIGHTMAP_SIZE :{BLACK}Taille: {ORANGE}{NUM} x {NUM} @@ -3174,3 +3190,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Transparence des éléments constructibles tels que stations, dépôts, points de contrôle et caténaire STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Transparence des ponts STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Transparence des structures telles que phares et antennes + +##### Mass Order +STR_GROUP_NAME_FORMAT :Groupe {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Tous les trains +STR_GROUP_ALL_ROADS :Tous les véhicules routiers +STR_GROUP_ALL_SHIPS :Tous les navires +STR_GROUP_ALL_AIRCRAFTS :Tous les aéronefs +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Ajouter des véhicules partagés +STR_GROUP_REMOVE_ALL_VEHICLES :Retirer tous les véhicules + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Train{P "" s} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Véhicule{P "" s} routier{P "" s} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Navire{P "" s} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Aéronef{P "" s} +STR_GROUP_RENAME_CAPTION :{BLACK}Renommer un groupe +STR_GROUP_REPLACE_CAPTION :{WHITE}Remplacer les véhicules de "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Impossible de créer le groupe... +STR_GROUP_CAN_T_DELETE :{WHITE}Impossible de supprimer ce groupe... +STR_GROUP_CAN_T_RENAME :{WHITE}Impossible de renommer le groupe... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Impossible de retirer tous les véhicules de ce groupe... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Impossible d'ajouter le véhicule à ce groupe... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossible d'ajouter les véhicules partagés à ce groupe... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Groupes - Cliquer sur un groupe pour lister tous les véhicules de ce groupe +STR_GROUP_CREATE_TIP :{BLACK}Cliquer pour créer un groupe +STR_GROUP_DELETE_TIP :{BLACK}Supprimer le groupe sélectionné +STR_GROUP_RENAME_TIP :{BLACK}Renommer le groupe sélectionné +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Cliquer pour protéger ce groupe contre l'auto-remplacement global + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit cette année: {GREEN}{CURRENCY} {BLACK}(an dernier: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profit cette année: {RED}{CURRENCY} {BLACK}(an dernier: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit cette année: {GREEN}{CURRENCY} {BLACK}(an dernier: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profit cette année: {RED}{CURRENCY} {BLACK}(an dernier: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/german.txt --- a/src/lang/german.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/german.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_ZOOM :Karte vergrößern STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Kartenansicht verschieben STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Aus +STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Scrollradgeschwindigkeit auf der Karte: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatische Pause bei Spielstart: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximale Anzahl der Züge pro Spieler: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximale Anzahl der Straßenfahrzeuge pro Spieler: {ORANGE}{STRING} @@ -1130,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Erlaube Anteile an anderen Firmen zu kaufen STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Errichte Signale alle {ORANGE}{STRING} Felder beim Ziehen mit der Maus STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatischer Bau von Formsignalen bis: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Der Stadtaufbau "keine weiteren Straßen" ist im Szenarioeditor nicht möglich +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Wähle den Stadtstraßenaufbau: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :keine weiteren Straßen +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :Vorgabe +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :bessere Straßen +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 Gitter +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 Gitter + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position der Werkzeugleiste: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Links STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Mitte @@ -2001,6 +2012,7 @@ STR_SV_STNAME_HELIPORT :{STRING} Heliport STR_SV_STNAME_FOREST :{STRING} Wald + ############ end of savegame specific region! ##id 0x6800 @@ -2036,6 +2048,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Keine +STR_NUM_VERY_LOW :Sehr niedrig STR_6816_LOW :Niedrig STR_6817_NORMAL :Normal STR_6818_HIGH :Hoch @@ -3101,6 +3114,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Ändere Startjahr STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalierungswarnung STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Zu starke Skalierung der Karte ist nicht empfohlen. Trotzdem Generierung fortsetzen? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Städtebauwarnung +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Der Stadtaufbau "keine weiteren Straßen" ist nicht empfohlen. Mit der Generierung fortfahren? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Reliefkartenname: STR_HEIGHTMAP_SIZE :{BLACK}Größe: {ORANGE}{NUM} x {NUM} @@ -3173,3 +3188,28 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Verändere die Transparenz für Gebäude wie Bahnhöfe, Depots, Wegpunkte und Oberleitung STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Verändere die Transparenz für Brücken STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Verändere die Transparenz für Bauten wie Leuchttürme und Antennen, evtl. in der Zukunft auch für Sehenswürdigkeiten + +##### Mass Order +STR_GROUP_NAME_FORMAT :Gruppe {COMMA} +STR_GROUP_ALL_TRAINS :Alle Züge +STR_GROUP_ALL_ROADS :Alle Straßenfahrzeuge +STR_GROUP_ALL_SHIPS :Alle Schiffe +STR_GROUP_ALL_AIRCRAFTS :Alle Flugzeuge +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_REMOVE_ALL_VEHICLES :Entferne alle Fahrzeuge + +STR_GROUP_RENAME_CAPTION :{BLACK}Gruppe umbenennen + +STR_GROUP_CAN_T_CREATE :{WHITE}Kann Gruppe nicht erstellen... +STR_GROUP_CAN_T_DELETE :{WHITE}Kann diese Gruppe nicht löschen... +STR_GROUP_CAN_T_RENAME :{WHITE}Kann Gruppe nicht umbenennen... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kann nicht alle Fahrzeuge dieser Gruppe entfernen... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kann das Fahrzeug nicht zu dieser Gruppe hinzufügen... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Gruppen - Klicke auf eine Gruppe für eine Liste aller Fahrzeuge der Gruppe +STR_GROUP_CREATE_TIP :{BLACK}Klicken um eine Gruppe zu erstellen +STR_GROUP_DELETE_TIP :{BLACK}Die ausgewählte Gruppe löschen +STR_GROUP_RENAME_TIP :{BLACK}Die ausgewählte Gruppe umbenennen + + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/hungarian.txt --- a/src/lang/hungarian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/hungarian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1163,6 +1163,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Térkép mozgatás STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Ki STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Scrollgomb sebessége a térképen: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatikus pause-mode új játék esetén: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Továbbfejlesztett járműlista használata: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximum vonat játékosonként: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximum közúti jármű játékosonként: {ORANGE}{STRING} @@ -1196,6 +1198,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Másik cégekből részvényt lehet vásárolni STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Amikor megragadom helyezzen lámpákat minden {ORANGE}{STRING}. mezőre STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatikusan szemafor épüljön eddig: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}A "nincs több út" városkinézeti séma a pályaszerkesztőben nem elérhető +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Válassz városi úthálózat-sémát: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :nincs több út +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :alapértelmezett +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :jobb utak +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2-es háló +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3-as háló + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}A fő eszközsor helye: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Balra STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Középen @@ -2104,6 +2115,8 @@ STR_SV_STNAME_HELIPORT :{STRING}i helikopter-leszálló STR_SV_STNAME_FOREST :{STRING}i erdőség +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2139,6 +2152,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Egyiksem +STR_NUM_VERY_LOW :Nagyon kevés STR_6816_LOW :Kevés STR_6817_NORMAL :Normál STR_6818_HIGH :Sok @@ -3204,6 +3218,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Kezdő év megváltoztatása STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Átméretezési figyelmeztetés STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}A forrás térkép túlságosan nagy mértékű átméretezése nem javasolt. Folytatod mégis? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Városkinézeti figyelmeztetés +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}A "nincs több út" városkinézeti séma ellenjavallott. Biztosan folytatod a generálást? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Magasságtérkép neve: STR_HEIGHTMAP_SIZE :{BLACK}Méret: {ORANGE}{NUM} x {NUM} @@ -3276,3 +3292,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Átkapcsolni az építhető elemekre (állomások, depók, útipontok és felsővezeték) STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Átkapcsolni a hidakra STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Átkapcsolni egyéb épületekre, mint világítótorony és antennák (esetleg egyéb jövőbeni díszek) + +##### Mass Order +STR_GROUP_NAME_FORMAT :{COMMA} csoport +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Összes vonat +STR_GROUP_ALL_ROADS :Összes közúti jármű +STR_GROUP_ALL_SHIPS :Összes hajó +STR_GROUP_ALL_AIRCRAFTS :Összes repülő +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Megosztott jármű hozzáadása +STR_GROUP_REMOVE_ALL_VEHICLES :Összes jármű eltávolítása + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} vonat +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} közúti jármű +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} hajó +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} repülő +STR_GROUP_RENAME_CAPTION :{BLACK}Csoport átnevezése +STR_GROUP_REPLACE_CAPTION :{WHITE}A(z) "{GROUP}" csoport járműveinek lecserélése + +STR_GROUP_CAN_T_CREATE :{WHITE}Csoport létrehozás sikertelen... +STR_GROUP_CAN_T_DELETE :{WHITE}Csoport törlése sikertelen... +STR_GROUP_CAN_T_RENAME :{WHITE}Csoport átnevezése sikertelen... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Csoport járműveinek törlése sikertelen... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Jármű hozzáadása a csoporthoz sikertelen... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Megosztott jármű csoporthoz való hozzáadása sikertelen... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Csoportok - Kattints a csoport nevére a járművek listázásához +STR_GROUP_CREATE_TIP :{BLACK}Csoport létrehozásához kattints ide +STR_GROUP_DELETE_TIP :{BLACK}Kijelölt csoport törlése +STR_GROUP_RENAME_TIP :{BLACK}Kijelölt csoport átnevezése +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Csoport automata csere alóli mentességének beállításához kattints ide + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Idei profit: {GREEN}{CURRENCY} {BLACK}(tavalyi: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Idei profit: {RED}{CURRENCY} {BLACK}(tavalyi: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Idei profit: {GREEN}{CURRENCY} {BLACK}(tavalyi: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Idei profit: {RED}{CURRENCY} {BLACK}(tavalyi: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/italian.txt --- a/src/lang/italian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/italian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1099,6 +1099,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scorri la mappa STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Off STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Velocità rotellina mappa: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Metti in pausa all'inizio di una nuova partita: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Utilizza la lista veicoli avanzata: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max treni per giocatore: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max automezzi per giocatore: {ORANGE}{STRING} @@ -1132,6 +1134,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permetti l'acquisto di azioni di altre compagnie STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Trascinando il cursore, piazza i segnali ogni: {ORANGE}{STRING} quadrato/i STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Costruisci automaticamente i semafori prima del: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}L'opzione "Nessuna nuova strada" non è valida nell'editor di scenari +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Disposizione delle strade cittadine: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :Nessuna nuova strada +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :Predefinita +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :Pianta migliorata +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :Griglia 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :Griglia 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posizione barra degli strumenti principale: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Sinistra STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro @@ -1386,7 +1397,7 @@ STR_NETWORK_LANG_FRENCH :Francese ############ End of leave-in-this-order -STR_NETWORK_GAME_LOBBY :{WHITE}Stanza principale partite multigiocatore +STR_NETWORK_GAME_LOBBY :{WHITE}Stanza principale partita multigiocatore STR_NETWORK_PREPARE_TO_JOIN :{BLACK}Preparazione all'ingresso in: {ORANGE}{STRING} STR_NETWORK_COMPANY_LIST_TIP :{BLACK}Elenco di tutte le compagnie attualmente nella partita. È possibile unirsi ad una di esse o fondarne una nuova se è disponibile un posto @@ -2003,6 +2014,8 @@ STR_SV_STNAME_HELIPORT :Eliporto di {STRING} STR_SV_STNAME_FOREST :{STRING} Foresta +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2038,6 +2051,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Nessuno +STR_NUM_VERY_LOW :Molto basso STR_6816_LOW :Basso STR_6817_NORMAL :Normale STR_6818_HIGH :Alto @@ -2049,25 +2063,9 @@ STR_681E_FAST :Veloce STR_681F_VERY_FAST :Molto veloce STR_VERY_LOW :Molto basso -STR_VERY_LOW.ms :Molto basso -STR_VERY_LOW.mp :Molto bassi -STR_VERY_LOW.fp :Molto basse -STR_VERY_LOW.fs :Molto bassa STR_6820_LOW :Basso -STR_6820_LOW.ms :Basso -STR_6820_LOW.mp :Bassi -STR_6820_LOW.fs :Bassa -STR_6820_LOW.fp :Basse STR_6821_MEDIUM :Medio -STR_6821_MEDIUM.ms :Medio -STR_6821_MEDIUM.mp :Medi -STR_6821_MEDIUM.fs :Media -STR_6821_MEDIUM.fp :Medie STR_6822_HIGH :Alto -STR_6822_HIGH.ms :Alto -STR_6822_HIGH.mp :Alti -STR_6822_HIGH.fs :Alta -STR_6822_HIGH.fp :Alte STR_6823_NONE :Nessuno STR_6824_REDUCED :Ridotti STR_6825_NORMAL :Normali @@ -2179,7 +2177,7 @@ STR_7054 :{WHITE}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}' STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}' STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Compagnia di trasporti in difficolta! -STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}La {COMPANY} verrà venduta o dichiarerà bancarotta a meno che le prestazioni non miglioreranno presto! +STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT}La {COMPANY} verrà venduta o dichiarerà bancarotta a meno che le prestazioni non migliorino presto! STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Presidente) STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Fusione tra compagnie di trasporti! STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}La {COMPANY} è stata venduta alla {COMPANY} per {CURRENCY}! @@ -3119,6 +3117,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Cambia l'anno di inizio STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avviso scala STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Ridimensionare di molto l'heightmap sorgente non è consigliabile. Continuare con la generazione? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Avviso sulla disposizione delle strade +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}L'opzione "Nessuna nuova strada" non è raccomandata. Proseguire con la generazione? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nome heightmap: STR_HEIGHTMAP_SIZE :{BLACK}Dim.: {ORANGE}{NUM} x {NUM} @@ -3191,3 +3191,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Attiva/disattiva la trasparenza delle strutture edificabili come stazioni, depositi, waypoint e catenarie STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Attiva/disattiva la trasparenza dei ponti STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Attiva/disattiva la trasparenza di strutture come fari, antenne e altri futuri oggetti decorativi + +##### Mass Order +STR_GROUP_NAME_FORMAT :Gruppo {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Tutti i treni +STR_GROUP_ALL_ROADS :Tutti gli automezzi +STR_GROUP_ALL_SHIPS :Tutte le navi +STR_GROUP_ALL_AIRCRAFTS :Tutti gli aeromobili +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Aggiungi veicoli condivisi +STR_GROUP_REMOVE_ALL_VEHICLES :Rimuovi tutti i veicoli + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} tren{P o i} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} automezz{P o i} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} nav{P e i} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} aeromobil{P e i} +STR_GROUP_RENAME_CAPTION :{BLACK}Rinomina un gruppo +STR_GROUP_REPLACE_CAPTION :{WHITE}Rimpiazza i veicoli del {GROUP} + +STR_GROUP_CAN_T_CREATE :{WHITE}Impossibile creare il gruppo... +STR_GROUP_CAN_T_DELETE :{WHITE}Impossibile eliminare il gruppo... +STR_GROUP_CAN_T_RENAME :{WHITE}Impossibile rinominare il gruppo... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Impossibile rimuovere tutti i veicoli del gruppo... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Impossibile aggiungere il veicolo al gruppo... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossibile aggiungere veicoli condivisi al gruppo... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Gruppi - Fare clic su un gruppo per elencare tutti i suoi veicoli +STR_GROUP_CREATE_TIP :{BLACK}Fare clic per creare un gruppo +STR_GROUP_DELETE_TIP :{BLACK}Elimina il gruppo selezionato +STR_GROUP_RENAME_TIP :{BLACK}Rinomina il gruppo selezionato +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Fare clic per proteggere questo gruppo dal rimpiazzo automatico + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profitto quest'anno: {GREEN}{CURRENCY} {BLACK}(anno scorso: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Profitto quest'anno: {RED}{CURRENCY} {BLACK}(anno scorso: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profitto quest'anno: {GREEN}{CURRENCY} {BLACK}(anno scorso: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Profitto quest'anno: {RED}{CURRENCY} {BLACK}(anno scorso: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/japanese.txt --- a/src/lang/japanese.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/japanese.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :地図をスクロール STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :切 STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}地図のスクロール速度:{ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}新規ゲームを開始したときに自動的にポーズ:{ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}一人のプレヤーの列車数上限:{ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}一人のプレヤーの道路車両数上限:{ORANGE}{STRING} @@ -1130,6 +1131,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}他の会社が所有している株式の購入を入にする STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}ドラッグするときの信号設備頻度:{ORANGE}{STRING} STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}次の年まで腕木式信号を建設:{ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}シナリオエディタを使用時に、「道路網を拡大せず」という道路網が選択できません +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}道路網の選択:{ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :道路網を拡大せず +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :デフォルト +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :改善の道路網 +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :格子状(2x2) +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :格子状(3x3) + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}主のツールバーの位置:{ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :左 STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :中位 @@ -2036,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :なし +STR_NUM_VERY_LOW :特に低い STR_6816_LOW :低い STR_6817_NORMAL :通常 STR_6818_HIGH :高い @@ -3101,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}始める年を変えます STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}リサイズ警告 STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}ソース地図をリサイズしすぎることはお勧めしません。地形作成を続けてもよろしいですか? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}道路網の警告 +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}「道路網を拡大せず」という道路網をおすすめしません。続けてもよろしいですか? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}ハイトマップ名: STR_HEIGHTMAP_SIZE :{BLACK}サイズ:{ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/korean.txt --- a/src/lang/korean.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/korean.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1098,6 +1098,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :맵 스크롤 STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :끄기 STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}맵 스크롤 속도: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}새로운 게임 시작할 때 자동으로 일시정지: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}진보된 차량 목록 사용: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}최대 열차 수: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}최대 자동차 수: {ORANGE}{STRING} @@ -1131,6 +1133,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}다른 회사가 주식을 사는 것을 허용 STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}드래그 할때 신호등을 매 {ORANGE}{STRING}타일마다 설치 STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}자동으로 신호기 설치 : {ORANGE}{STRING} 이전에 + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}도시설계 "도로건설 안함"은 시나리오 에디터에서 유효하지 않습니다 +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}도시도로 설계: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :도로건설 안함 +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :기본값 +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :개선된 도로 +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 칸 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 칸 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}주메뉴의 위치 : {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :왼쪽 STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :가운데 @@ -2002,6 +2013,8 @@ STR_SV_STNAME_HELIPORT :{STRING} 헬리포트 STR_SV_STNAME_FOREST :{STRING} 삼림 +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2037,6 +2050,7 @@ ############ range for difficulty settings ends STR_26816_NONE :없음 +STR_NUM_VERY_LOW :매우 적음 STR_6816_LOW :낮음 STR_6817_NORMAL :보통 STR_6818_HIGH :높음 @@ -3102,6 +3116,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}시작 년도를 변경합니다. STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}맵 크기에 대한 경고 STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}맵 자원의 크기를 너무 키우는 것은 좋지 않습니다. 생성을 계속하시겠습니까? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}도시 설계 경고 +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}도시 설계 "도로건설 안함"은 추천하지 않습니다. 생성을 계속 하시겠습니까? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}DEM지형 이름: STR_HEIGHTMAP_SIZE :{BLACK}크기: {ORANGE}{NUM} x {NUM} @@ -3174,3 +3190,38 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}정거장, 차량기지, 웨이포인트, 연결고리와 같은 건설 가능한 것들에 대한 투명 전환 STR_TRANSPARENT_BRIDGES_DESC :{BLACK}다리 투명 전환 STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}등대와 안테나와 같은 구조물 투명 전환 + +##### Mass Order +STR_GROUP_NAME_FORMAT :그룹 {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :모든 기차 +STR_GROUP_ALL_ROADS :모든 차량 +STR_GROUP_ALL_SHIPS :모든 선박 +STR_GROUP_ALL_AIRCRAFTS :모든 항공기 +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :모든 공유된 차량 +STR_GROUP_REMOVE_ALL_VEHICLES :모든 차량 제거 + +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} 항공기 +STR_GROUP_RENAME_CAPTION :{BLACK}그룹 이름 바꾸기 +STR_GROUP_REPLACE_CAPTION :{WHITE}"{GROUP}"의 차량 교체 + +STR_GROUP_CAN_T_CREATE :{WHITE}그룹을 만들 수 없습니다... +STR_GROUP_CAN_T_DELETE :{WHITE}이 그룹을 지울 수 없습니다. +STR_GROUP_CAN_T_RENAME :{WHITE}그룹의 이름을 바꿀 수 없습니다. +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}이 구릅의 모든 차량을 제거할 수 없습니다. +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}이 그룹에 차량을 추가할 수 없습니다. +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}이 구릅에 공유된 차량을 추가할 수 없습니다. + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}그룹 - 땅을 클릭하면 이 그룹의 모든 차량을 나열 +STR_GROUP_CREATE_TIP :{BLACK}그룹 만들기 +STR_GROUP_DELETE_TIP :{BLACK}선택한 그룹 삭제 +STR_GROUP_RENAME_TIP :{BLACK}선택한 그룹 이름 바꾸기 +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}전체 자동 교체로부터 이 그룹 보호 + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}올해의 수입: {GREEN}{CURRENCY} {BLACK}(작년: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}올해의 수입: {RED}{CURRENCY} {BLACK}(작년: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}올해 수입: {GREEN}{CURRENCY} {BLACK}(작년: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}올해 수입: {RED}{CURRENCY} {BLACK}(작년: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/norwegian_nynorsk.txt --- a/src/lang/norwegian_nynorsk.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/norwegian_nynorsk.txt Wed Jun 13 11:45:14 2007 +0000 @@ -752,6 +752,7 @@ STR_02A1_SMALL :{BLACK}Liten STR_02A2_MEDIUM :{BLACK}Middels STR_02A3_LARGE :{BLACK}Stor +STR_SCENARIO_EDITOR_CITY :{BLACK}By STR_02A4_SELECT_TOWN_SIZE :{BLACK}Vel storleik på by STR_02A5_TOWN_SIZE :{YELLOW}Bystorleik: @@ -1095,8 +1096,9 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING :{LTBLUE}Funksjonen til scrollhjulet: {ORANGE}{STRING} STR_CONFIG_PATCHES_SCROLLWHEEL_ZOOM :Zoom kart STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll kart -STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Av +STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :av STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Fart på rullehjul: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatisk pause når ein startar nytt spel: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks antal tog per speler: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks antal køyretøy per spelar: {ORANGE}{STRING} @@ -1130,12 +1132,30 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillat kjøping av aksjar i andre selskap STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ved opptrekking, plasser signal hver: {ORANGE}{STRING} rute{P "" r} STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Bygg semaforer automatisk før: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Byoppsettet " ingen fleire vegar" kan ikkje brukast i scenarioredigeringsprogrammet +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Velg oppsett for byvegar: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :Ingen fleire vegar +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :standard +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :betre vegar +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 rutenett +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 rutenett + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Plassering av hovudverktøylinje: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Venstre STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Midtstilt STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Høgre STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Knipseradius for vindauge: {ORANGE}{STRING} px STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Knipseradius for vindauge: {ORANGE}deaktivert +STR_CONFIG_PATCHES_TOWN_GROWTH :{LTBLUE}Byen sin vekseProporsjonfart: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_GROWTH_NONE :Ingen +STR_CONFIG_PATCHES_TOWN_GROWTH_SLOW :Sakte +STR_CONFIG_PATCHES_TOWN_GROWTH_NORMAL :Normal +STR_CONFIG_PATCHES_TOWN_GROWTH_FAST :Rask +STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Særs rask +STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Proporsjon på byar som vil vekse dobbelt så fort: {ORANGE}1 av {STRING} +STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}Proporsjon på byar som vil vekse dobbelt så fort: {ORANGE}Ingen +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Faktor for multiplikasjon av bystorleik: {ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Grensesnitt STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Konstruksjon @@ -1454,7 +1474,7 @@ STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :mottok merkeleg pakke STR_NETWORK_ERR_CLIENT_WRONG_REVISION :feil versjon STR_NETWORK_ERR_CLIENT_NAME_IN_USE :namnet er brukt av nokon andre -STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :feil passord til spelet +STR_NETWORK_ERR_CLIENT_WRONG_PASSWORD :feil passord for til spelet STR_NETWORK_ERR_CLIENT_PLAYER_MISMATCH :feil spelar-id i DoCommand STR_NETWORK_ERR_CLIENT_KICKED :sparka ut av tenaren STR_NETWORK_ERR_CLIENT_CHEATER :freista å jukse @@ -2027,6 +2047,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ingen +STR_NUM_VERY_LOW :Særs låg STR_6816_LOW :Lite STR_6817_NORMAL :Normal STR_6818_HIGH :Høgt @@ -2778,7 +2799,7 @@ STR_9841_CAN_T_REFIT_SHIP :{WHITE}Kan ikkje bygge om skip... STR_9842_REFITTABLE :(ombyggbart) STR_GO_TO_SHIP_DEPOT :Seil til {TOWN} skipsdepot -SERVICE_AT_SHIP_DEPOT :Vedlikehald ved {TOWN} skipsdepot +SERVICE_AT_SHIP_DEPOT :Vedlikehald ved {TOWN} Skipsdepot ##id 0xA000 STR_A000_AIRPORTS :{WHITE}Flyplassar @@ -3092,6 +3113,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Endre startår STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skalaåtvaring STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Å endre storleiken på kjeldekartet for mykje er ikkje anbefalt. Vil du halde fram med genereringa? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Åtvaring for byoppsett +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Byoppsettet "ingen fleire vegar" er ikkje anbefalt. Hald fram med bygginga? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Høgdekartnamn: STR_HEIGHTMAP_SIZE :{BLACK}Storleik: {ORANGE}{NUM} x {NUM} @@ -3154,4 +3177,13 @@ STR_FEEDER_CARGO_VALUE :{BLACK}Overfør kreditt: {LTBLUE}{CURRENCY} STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD :{WHITE}...denne vegen eigast av ein by +STR_DRIVE_THROUGH_ERROR_DIRECTION :{WHITE}...vegen peiker feil veg +STR_TRANSPARENCY_TOOLB :{WHITE}Gjennomsynsval +STR_TRANSPARENT_SIGNS_DESC :{BLACK}Byt gjennomsyn for stasjonssktilt +STR_TRANSPARENT_TREES_DESC :{BLACK}Byt gjennomsyn for tre +STR_TRANSPARENT_HOUSES_DESC :{BLACK}Byt gjennomsyn for hus +STR_TRANSPARENT_INDUSTRIES_DESC :{BLACK}Byt gjennomsyn for industriar +STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Byt gjennomsyn for bygningar som kan byggast, til dømes depot og vegmerker +STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Byt gjennomsyn for bruer +STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Byt gjennomsyn for bygningar som fyrtårn og antenner, kanskje i framtida for fine effekter diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/polish.txt --- a/src/lang/polish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/polish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1184,6 +1184,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Przesuń widok STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Rolka wyłączona STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Prędkość przesuwania widoku: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automatycznie włącz pauzę tworząc nową grę: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maks. liczba pociągów na gracza: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maks. liczba samochodów na gracza: {ORANGE}{STRING} @@ -1217,6 +1218,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Pozwól kupować odziały w innych firmach STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}W trakcie przeciągania ustaw sygnały co: {ORANGE}{STRING} kratk{P e i ek} STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatycznie buduj semafory przed: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Plan sieci dróg "bez nowych dróg" nie jest poprawny dla edytora scenariuszy +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Wybierz plan sieci dróg miejskich: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :bez nowych dróg +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :standardowy +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :lepsze drogi +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :siatka 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :siatka 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozycja głównego paska narzędzi: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Z lewej strony STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Wyśrodkowane diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/portuguese.txt --- a/src/lang/portuguese.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/portuguese.txt Wed Jun 13 11:45:14 2007 +0000 @@ -386,7 +386,7 @@ STR_SORT_BY_FACILITY :Tipo de Estação STR_SORT_BY_WAITING :Valor da carga em espera STR_SORT_BY_RATING_MAX :Avaliação de carga -STR_ENGINE_SORT_ENGINE_ID :Ordenação clássica +STR_ENGINE_SORT_ENGINE_ID :EngineID (ordernação clássica) STR_ENGINE_SORT_COST :Custo STR_ENGINE_SORT_POWER :Potência STR_ENGINE_SORT_INTRO_DATE :Data de Introdução @@ -751,6 +751,7 @@ STR_02A1_SMALL :{BLACK}Pequena STR_02A2_MEDIUM :{BLACK}Média STR_02A3_LARGE :{BLACK}Grande +STR_SCENARIO_EDITOR_CITY :{BLACK}Cidade STR_02A4_SELECT_TOWN_SIZE :{BLACK}Seleccione o tamanho da cidade STR_02A5_TOWN_SIZE :{YELLOW}Tamanho da cidade: @@ -1048,7 +1049,7 @@ STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Permitir sempre aeroportos pequenos: {ORANGE}{STRING} -STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Avisar quando comboios andam perdidos: {ORANGE}{STRING} +STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Alertar em caso de perda do combóio: {ORANGE}{STRING} STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Analisar ordens dos veículos: {ORANGE}{STRING} STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :Não STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :Sim, mas excluir veículos parados @@ -1085,7 +1086,7 @@ STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Manutenção automática de helicópteros em heliportos: {ORANGE}{STRING} STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Ligar ferramentas de paisagem com as de construção: {ORANGE}{STRING} STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Ao deslizar com o rato, mover a vista na direcção oposta: {ORANGE}{STRING} -STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostrar medidas ao usar ferramentas de construção: {ORANGE}{STRING} +STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Mostrar uma dica de medição ao utilizar várias ferramentas de construção: {ORANGE}{STRING} STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Mostrar estampagens da companhia: {ORANGE}{STRING} STR_CONFIG_PATCHES_LIVERIES_NONE :Nenhum STR_CONFIG_PATCHES_LIVERIES_OWN :Própria companhia @@ -1096,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Percorrer mapa STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Desligado STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Velocidade do scrollwheel no mapa: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Pausa automática ao iniciar um novo jogo: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máximo de comboios por jogador: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máximo de veículos de estrada por jogador: {ORANGE}{STRING} @@ -1129,12 +1131,30 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite comprar acções de outras companhias STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Ao arrastar colocar sinais a cada: {ORANGE}{STRING} quadrado(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Construir automaticamente semáforos antes de: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}A disposição de cidade "sem mais estradas" não é válida no editor de cenários +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Seleccionar disposição das estradas na cidade: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :sem mais estradas +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :por defeito +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :estradas melhores +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :grelha 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :grelha 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posição da barra de ferramentas principal: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Esquerda STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Direita STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Raio de atracção de janelas: {ORANGE}{STRING} px STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Raio de atracção de janelas: {ORANGE}desactivado +STR_CONFIG_PATCHES_TOWN_GROWTH :{LTBLUE}Ritmo de crescimento de cidades: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_GROWTH_NONE :Nenhum +STR_CONFIG_PATCHES_TOWN_GROWTH_SLOW :Lento +STR_CONFIG_PATCHES_TOWN_GROWTH_NORMAL :Normal +STR_CONFIG_PATCHES_TOWN_GROWTH_FAST :Rápido +STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Muito Rápido +STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Proporção de cidades que se tornarão metrópoles: {ORANGE}1 em {STRING} +STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}Proporção de cidades que se tornarão metrópoles: {ORANGE}Nenhuma +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Multiplicador inicial para dimensão da cidade: {ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Interface STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Construção @@ -2026,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Nenhum +STR_NUM_VERY_LOW :Muito baixo STR_6816_LOW :Baixo STR_6817_NORMAL :Normal STR_6818_HIGH :Alto @@ -2556,9 +2577,9 @@ STR_8826_GO_TO :{BLACK}Ir Para STR_8827_FULL_LOAD :{BLACK}Carga STR_8828_UNLOAD :{BLACK}Descarga -STR_REFIT :{BLACK}Reconverter -STR_REFIT_TIP :{BLACK}Escolha o tipo de carga para reconverter nesta ordem. Control click para remover a instrução de reconversão -STR_REFIT_ORDER :(Reconverter para {STRING}) +STR_REFIT :{BLACK}Converter +STR_REFIT_TIP :{BLACK}Seleccionar o tipo de carga a converter nesta ordem. Pressionar Ctrl e botão-esquerdo do rato para remover instrução de conversão +STR_REFIT_ORDER :(Converter para {STRING}) STR_8829_ORDERS :{WHITE}{VEHICLE} (Ordens) STR_882A_END_OF_ORDERS :{SETX 10}- - Fim de Ordens - - STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING} @@ -3091,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Mudar ano de início STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Aviso de redimensionamento STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Redimensionar muito o mapa não é recomendado. Continuar com a criação? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Aviso de disposição da cidade +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}A disposição de cidade "sem mais estradas" não é recomendado. Continuar a geração? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nome mapa de alt.: STR_HEIGHTMAP_SIZE :{BLACK}Tamanho: {ORANGE}{NUM} x {NUM} @@ -3152,5 +3175,14 @@ ######## STR_FEEDER_CARGO_VALUE :{BLACK}Créditos de Transferência: {LTBLUE}{CURRENCY} +STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD :{WHITE}...esta estrada é detida pela cidade +STR_DRIVE_THROUGH_ERROR_DIRECTION :{WHITE}...estrada orientada na direcção incorrecta STR_TRANSPARENCY_TOOLB :{WHITE}Opções de Transparência +STR_TRANSPARENT_SIGNS_DESC :{BLACK}Comutar transparência para sinais das estações +STR_TRANSPARENT_TREES_DESC :{BLACK}Comutar transparência das árvores +STR_TRANSPARENT_HOUSES_DESC :{BLACK}Comutar transparência das casas +STR_TRANSPARENT_INDUSTRIES_DESC :{BLACK}Comutar transparência das indústrias +STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Comutar transparência para edificações como estações, depósitos, pontos-de-passagem e catenárias +STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Comutar transparência para pontes +STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Comutar transparência para estruturas como faróis-terrestres e antenas (talvez, no futuro, para embelezamentos) diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/romanian.txt --- a/src/lang/romanian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/romanian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Ruleaza harta STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :inactiva STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Viteza harta la rotita mouse: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}La pornirea unui joc nou, pune-l pe pauza: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Nr. max. de trenuri per jucãtor: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Nr. max. de autovehicule pentru un jucãtor: {ORANGE}{STRING} @@ -1130,6 +1131,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permite cumpararea de actiuni de la alte companii STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Plasare automatã a semnalelor la fiecare: {ORANGE}{STRING} pãtrãtele STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Construieste automat semafaore înainte de: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Apectul de oras "fara alte drumuri" nu este valid in editorul de scenarii +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Alege aspect drum-de-oras: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :fara alte drumuri +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :implicit +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :drumuri mai bune +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :grila 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :grila 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozitia listei cu instrumente: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :stânga STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :centru @@ -2036,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :zero +STR_NUM_VERY_LOW :Foarte putine STR_6816_LOW :scãzut STR_6817_NORMAL :normal STR_6818_HIGH :ridicat @@ -3101,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Modifica inceputul anului STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Avertisment de scala STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Redimensionarea excesiva a hartii nu este recomandata. Continui cu generarea? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Avertisment aspect oras +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Aspectul de oras "fara alte drumuri" nu este recomanat. Continui generarea? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nume harta inaltimi: STR_HEIGHTMAP_SIZE :{BLACK}Dimensiune: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/russian.txt --- a/src/lang/russian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/russian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -158,7 +158,7 @@ STR_00B3_MESSAGE_FROM :{YELLOW}Сообщение из {STRING} STR_POPUP_CAUTION_CAPTION :{WHITE}Осторожно! STR_00B4_CAN_T_DO_THIS :{WHITE}Это невозможно -STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить +STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить... STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Оригинальные авторские права {COPYRIGHT} 1995 Chris Sawyer, Все права защищены STR_00B7_VERSION :{BLACK}OpenTTD v{REV} STR_00BA_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2007 Команда разработчиков OpenTTD @@ -195,7 +195,7 @@ STR_00E1_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Слишком много транспорта в игре STR_00E2 :{BLACK}{COMMA} STR_00E3 :{RED}{COMMA} -STR_00E4_LOCATION :{BLACK}Позиция +STR_00E4_LOCATION :{BLACK}Обзор STR_00E5_CONTOURS :Контуры STR_00E6_VEHICLES :Транспорт STR_00E7_INDUSTRIES :Промышленность @@ -221,7 +221,7 @@ STR_00FB_POWER_STATION :{BLACK}{TINYFONT}Электростанция STR_00FC_FOREST :{BLACK}{TINYFONT}Лес STR_00FD_SAWMILL :{BLACK}{TINYFONT}Лесопилка -STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Нефтеперегонный завод +STR_00FE_OIL_REFINERY :{BLACK}{TINYFONT}Нефтезавод STR_00FF_FARM :{BLACK}{TINYFONT}Ферма STR_0100_FACTORY :{BLACK}{TINYFONT}Завод STR_0101_PRINTING_WORKS :{BLACK}{TINYFONT}Типография @@ -229,7 +229,7 @@ STR_0103_IRON_ORE_MINE :{BLACK}{TINYFONT}Шахта железной руды STR_0104_STEEL_MILL :{BLACK}{TINYFONT}Сталелитейный завод STR_0105_BANK :{BLACK}{TINYFONT}Банк -STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Целлюлозно-бумажный комбинат +STR_0106_PAPER_MILL :{BLACK}{TINYFONT}Бумажная фабрика STR_0107_GOLD_MINE :{BLACK}{TINYFONT}Золотой прииск STR_0108_FOOD_PROCESSING_PLANT :{BLACK}{TINYFONT}Пищевой завод STR_0109_DIAMOND_MINE :{BLACK}{TINYFONT}Алмазная шахта @@ -270,7 +270,7 @@ STR_012C_MESSAGE :{WHITE}Сообщение STR_012D :{WHITE}{STRING} STR_012E_CANCEL :{BLACK}Отмена -STR_012F_OK :{BLACK}Хорошо +STR_012F_OK :{BLACK}Принять STR_0130_RENAME :{BLACK}Переимен. STR_0131_TOO_MANY_NAMES_DEFINED :{WHITE}Слишком много имен определено STR_0132_CHOSEN_NAME_IN_USE_ALREADY :{WHITE}Выбранное имя уже используется @@ -284,7 +284,7 @@ STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS -STR_013B_OWNED_BY :{WHITE}...принадлежащий {STRING} +STR_013B_OWNED_BY :{WHITE}...принадлежит {STRING} STR_013C_CARGO :{BLACK}Груз STR_013D_INFORMATION :{BLACK}Информация STR_013E_CAPACITIES :{BLACK}Вместимость @@ -348,14 +348,14 @@ STR_UNITS_FORCE_SI :{COMMA} kN ############ range for menu starts -STR_0154_OPERATING_PROFIT_GRAPH :Текущий график доходов +STR_0154_OPERATING_PROFIT_GRAPH :График прибыли STR_0155_INCOME_GRAPH :График дохода -STR_0156_DELIVERED_CARGO_GRAPH :Доставленные грузы -STR_0157_PERFORMANCE_HISTORY_GRAPH :Рейтинг -STR_0158_COMPANY_VALUE_GRAPH :Стоимость компании -STR_0159_CARGO_PAYMENT_RATES :Оплата перевозок -STR_015A_COMPANY_LEAGUE_TABLE :Порядковая таблица компаний -STR_PERFORMANCE_DETAIL_MENU :Подробные данные +STR_0156_DELIVERED_CARGO_GRAPH :График доставленного груза +STR_0157_PERFORMANCE_HISTORY_GRAPH :График рейтинга компаний +STR_0158_COMPANY_VALUE_GRAPH :График стоимости компаний +STR_0159_CARGO_PAYMENT_RATES :График оплаты перевозок +STR_015A_COMPANY_LEAGUE_TABLE :Табель о рангах +STR_PERFORMANCE_DETAIL_MENU :Рейтинг в деталях ############ range for menu ends STR_015B_OPENTTD :{WHITE}Об OpenTTD @@ -365,35 +365,35 @@ STR_015F_QUIT :Выход STR_ABANDON_GAME_QUERY :{YELLOW}Вы действительно хотите выйти из игры? STR_0161_QUIT_GAME :{WHITE}В главное меню -STR_SORT_ORDER_TIP :{BLACK}Выбор направления сортировки (убывание/возрастание) -STR_SORT_CRITERIA_TIP :{BLACK}Выбор критерия сортировки -STR_SORT_BY :{BLACK}Сортировать по +STR_SORT_ORDER_TIP :{BLACK}Смена направления сортировки (убывание/возрастание) +STR_SORT_CRITERIA_TIP :{BLACK}Смена критерия сортировки +STR_SORT_BY :{BLACK}Сортировка -STR_SORT_BY_POPULATION :{BLACK}населению -STR_SORT_BY_PRODUCTION :{BLACK}кол-ву продукции -STR_SORT_BY_TYPE :{BLACK}типу -STR_SORT_BY_TRANSPORTED :{BLACK}перевезенной прод. -STR_SORT_BY_NAME :{BLACK}имени -STR_SORT_BY_DROPDOWN_NAME :названию -STR_SORT_BY_DATE :{BLACK}дате -STR_SORT_BY_NUMBER :номеру -STR_SORT_BY_PROFIT_LAST_YEAR :прибыли в прошлом году -STR_SORT_BY_PROFIT_THIS_YEAR :прибыли в этом году -STR_SORT_BY_AGE :возрасту -STR_SORT_BY_RELIABILITY :надежности -STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :вместимости грузов -STR_SORT_BY_MAX_SPEED :макс. скорости -STR_SORT_BY_MODEL :модели -STR_SORT_BY_VALUE :значению -STR_SORT_BY_FACILITY :типу станции -STR_SORT_BY_WAITING :кол-ву товара на станции -STR_SORT_BY_RATING_MAX :рейтингу грузов +STR_SORT_BY_POPULATION :{BLACK}Население +STR_SORT_BY_PRODUCTION :{BLACK}Продукция +STR_SORT_BY_TYPE :{BLACK}Тип +STR_SORT_BY_TRANSPORTED :{BLACK}Вывоз +STR_SORT_BY_NAME :{BLACK}Имя +STR_SORT_BY_DROPDOWN_NAME :Название +STR_SORT_BY_DATE :{BLACK}Дата +STR_SORT_BY_NUMBER :Номер +STR_SORT_BY_PROFIT_LAST_YEAR :Прибыль в прошлом году +STR_SORT_BY_PROFIT_THIS_YEAR :Прибыль в этом году +STR_SORT_BY_AGE :Возраст +STR_SORT_BY_RELIABILITY :Надежность +STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Вместимость груза +STR_SORT_BY_MAX_SPEED :Максимальная скорость +STR_SORT_BY_MODEL :Модель +STR_SORT_BY_VALUE :Стоимость +STR_SORT_BY_FACILITY :Тип станции +STR_SORT_BY_WAITING :Кол-во товара на станции +STR_SORT_BY_RATING_MAX :Рейтинг грузов STR_ENGINE_SORT_ENGINE_ID :Название STR_ENGINE_SORT_COST :Цена STR_ENGINE_SORT_POWER :Мощность STR_ENGINE_SORT_INTRO_DATE :Дата постройки -STR_ENGINE_SORT_RUNNING_COST :Стоимость обслуж. -STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Мощн./Стоим. обслуж. +STR_ENGINE_SORT_RUNNING_COST :Цена обслуживания +STR_ENGINE_SORT_POWER_VS_RUNNING_COST :Мощность/Цена обслуживания STR_ENGINE_SORT_CARGO_CAPACITY :Вместимость STR_NO_WAITING_CARGO :{BLACK}На станции нет грузов, ожидающих погрузки STR_SELECT_ALL_FACILITIES :{BLACK}Выбрать все устройства @@ -403,14 +403,14 @@ STR_AVAILABLE_SHIPS :{BLACK}Доступные суда STR_AVAILABLE_AIRCRAFT :{BLACK}Доступные самолеты STR_AVAILABLE_ENGINES_TIP :{BLACK}Список доступного транспорта. -STR_MANAGE_LIST :{BLACK}Редакт. список -STR_MANAGE_LIST_TIP :{BLACK}Послать инструкции всему транспорту в списке -STR_REPLACE_VEHICLES :Замена Транспорта -STR_SEND_TRAIN_TO_DEPOT :Послать в Депо +STR_MANAGE_LIST :{BLACK}Организация +STR_MANAGE_LIST_TIP :{BLACK}Управление транспортом, находящимся в этом списке +STR_REPLACE_VEHICLES :Замена транспорта +STR_SEND_TRAIN_TO_DEPOT :Послать в депо STR_SEND_ROAD_VEHICLE_TO_DEPOT :Послать в гараж -STR_SEND_SHIP_TO_DEPOT :Послать в Док -STR_SEND_AIRCRAFT_TO_HANGAR :Послать в Ангар -STR_SEND_FOR_SERVICING :Послать на обслуживание +STR_SEND_SHIP_TO_DEPOT :Послать в док +STR_SEND_AIRCRAFT_TO_HANGAR :Послать в ангар +STR_SEND_FOR_SERVICING :Послать обслужить ############ range for months starts STR_0162_JAN :Янв @@ -458,10 +458,10 @@ STR_018A_CAN_T_CHANGE_SERVICING :{WHITE}Невозможно изменить сервисный интервал... STR_018B_CLOSE_WINDOW :{BLACK}Закрыть Окно STR_018C_WINDOW_TITLE_DRAG_THIS :{BLACK}Заголовок окна - для перемещения окна тащить за него -STR_STICKY_BUTTON :{BLACK}Пометить это окно как незакрываемое для клавиши 'Закрыть все Окна' +STR_STICKY_BUTTON :{BLACK}Иммунитет от нажатия клавиши 'Закрыть все окна' STR_RESIZE_BUTTON :{BLACK}Нажмите и тащите для изменения размера окна STR_SAVELOAD_HOME_BUTTON :{BLACK}Кликните, чтобы перейти к текущей папке загрузки/сохранения по умолчанию -STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Уничтожить постройки и т.п. в квадрате земли +STR_018D_DEMOLISH_BUILDINGS_ETC :{BLACK}Уничтожить здания, постройки, траву, деревья в ячейке местности STR_018E_LOWER_A_CORNER_OF_LAND :{BLACK}Опустить угол земли STR_018F_RAISE_A_CORNER_OF_LAND :{BLACK}Поднять угол земли STR_0190_SCROLL_BAR_SCROLLS_LIST :{BLACK}Прокрутка вверх/вниз @@ -482,8 +482,8 @@ STR_019C_ROAD_VEHICLE :Автотранспорт STR_019D_AIRCRAFT :Воздушный транспорт -STR_019E_SHIP :Корабли -STR_019F_TRAIN :Поезда +STR_019E_SHIP :Корабль +STR_019F_TRAIN :Поезд STR_01A0_IS_GETTING_OLD :{WHITE}{STRING} {COMMA} устарел STR_01A1_IS_GETTING_VERY_OLD :{WHITE}{STRING} {COMMA} сильно устарел STR_01A2_IS_GETTING_VERY_OLD_AND :{WHITE}{STRING} {COMMA} сильно устарел и требует замены @@ -577,7 +577,7 @@ STR_01F8_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Очистка пользовательской программы STR_01F9_SAVE_MUSIC_SETTINGS :{BLACK}Сохранить настройки музыки STR_01FA_CLICK_ON_MUSIC_TRACK_TO :{BLACK}Кликните по названию трека для добавления в пользовательскую программу -STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Выберите трек для удаления его из данной программы (только пользовательские) +STR_CLICK_ON_TRACK_TO_REMOVE :{BLACK}Выберите дорожку для удаления из списка (только пользовательского) STR_01FB_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Вкл./Выкл. случайный выбор программы STR_01FC_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Показать окно выбора музыкальных треков STR_01FD_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Нажмите на маршрут для отображения предприятия/города @@ -653,8 +653,8 @@ STR_0241_POWER_STATION :{BLACK}Электростанция STR_0242_SAWMILL :{BLACK}Лесопилка STR_0243_FOREST :{BLACK}Лес -STR_0244_OIL_REFINERY :{BLACK}Нефтеобраб. завод -STR_0245_OIL_RIG :{BLACK}Буровая вышка +STR_0244_OIL_REFINERY :{BLACK}Нефтезавод +STR_0245_OIL_RIG :{BLACK}Нефтяная вышка STR_0246_FACTORY :{BLACK}Фабрика STR_0247_STEEL_MILL :{BLACK}Сталеплавильный завод STR_0248_FARM :{BLACK}Ферма @@ -687,24 +687,24 @@ STR_0263_CONSTRUCT_POWER_STATION :{BLACK}Построить электростанцию STR_0264_CONSTRUCT_SAWMILL :{BLACK}Построить лесопилку STR_0265_PLANT_FOREST :{BLACK}Посадить лес -STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Построить нефтеперераб. завод -STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Построить буровую платформу (возможно только у края карты) +STR_0266_CONSTRUCT_OIL_REFINERY :{BLACK}Построить нефтезавод +STR_0267_CONSTRUCT_OIL_RIG_CAN_ONLY :{BLACK}Построить нефтяную вышку (только возможно у края карты) STR_0268_CONSTRUCT_FACTORY :{BLACK}Построить фабрику -STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Построить Сталелитейный завод +STR_0269_CONSTRUCT_STEEL_MILL :{BLACK}Построить сталелитейный завод STR_026A_CONSTRUCT_FARM :{BLACK}Построить ферму STR_026B_CONSTRUCT_IRON_ORE_MINE :{BLACK}Построить шахту железной руды STR_026C_CONSTRUCT_OIL_WELLS :{BLACK}Построить нефтяные скважины -STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Построить банк (Возможно только в городе с населением более 1200) -STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Построить ЦБК +STR_026D_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Построить банк (только возможно в городе с населением более 1200) +STR_026E_CONSTRUCT_PAPER_MILL :{BLACK}Построить бумажную фабрику STR_026F_CONSTRUCT_FOOD_PROCESSING :{BLACK}Построить пищевой завод STR_0270_CONSTRUCT_PRINTING_WORKS :{BLACK}Построить типографию STR_0271_CONSTRUCT_GOLD_MINE :{BLACK}Построить золотой прииск -STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Построить банк (Возможно только в городе) +STR_0272_CONSTRUCT_BANK_CAN_ONLY :{BLACK}Построить банк (только возможно в городе) STR_0273_CONSTRUCT_LUMBER_MILL_TO :{BLACK}Построить лесопилку (уничтожает джунгли и производит дерево) STR_0274_PLANT_FRUIT_PLANTATION :{BLACK}Создать фруктовую плантацию STR_0275_PLANT_RUBBER_PLANTATION :{BLACK}Создать плантацию каучука STR_0276_CONSTRUCT_WATER_SUPPLY :{BLACK}Построить водокачку -STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Построить водонапорную башню (только в городе) +STR_0277_CONSTRUCT_WATER_TOWER_CAN :{BLACK}Построить водонапорную башню (только возможно в городе) STR_0278_CONSTRUCT_DIAMOND_MINE :{BLACK}Построить алмазную шахту STR_0279_CONSTRUCT_COPPER_ORE_MINE :{BLACK}Построить шахту медной руды STR_027A_PLANT_COTTON_CANDY_FOREST :{BLACK}Посадить лес сахарной ваты @@ -718,18 +718,18 @@ STR_0282_CONSTRUCT_BUBBLE_GENERATOR :{BLACK}Построить генератор пузырьков STR_0283_CONSTRUCT_TOFFEE_QUARRY :{BLACK}Построить карьер ирисок STR_0284_CONSTRUCT_SUGAR_MINE :{BLACK}Построить сахарную шахту -STR_0285_CAN_T_BUILD_HERE :{WHITE}Здесь нельзя создать {STRING} ... +STR_0285_CAN_T_BUILD_HERE :{WHITE}Здесь нельзя создать {STRING}... STR_0286_MUST_BUILD_TOWN_FIRST :{WHITE}...сначала постройте город STR_0287_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}...такой объект уже есть в городе STR_0288_PLANT_TREES :{BLACK}Сажать деревья STR_0289_PLACE_SIGN :{BLACK}Поместить знак -STR_028A_RANDOM_TREES :{BLACK}Случайные деревья -STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Разместить случайные деревья на карте +STR_028A_RANDOM_TREES :{BLACK}Расставить по карте +STR_028B_PLANT_TREES_RANDOMLY_OVER :{BLACK}Разместить по карте деревья случайным образом STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Разместить скалы на карте STR_028D_PLACE_LIGHTHOUSE :{BLACK}Поставить маяк STR_028E_PLACE_TRANSMITTER :{BLACK}Поставить передатчик STR_028F_DEFINE_DESERT_AREA :{BLACK}Задать площадь пустыни.{}Нажмите и держите CTRL для удаления -STR_CREATE_LAKE :{BLACK}Указать водную область.{}Создать канал, или наводнить всю окружающую область при зажатом CTRL на уровне моря. +STR_CREATE_LAKE :{BLACK}Создать воду:{}При отжатом CTRL создаётся канал.{}При зажатом CTRL клетка на уровне моря наполняется водой. STR_0290_DELETE :{BLACK}Уничтожить STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Полностью уничтожить этот город STR_0292_SAVE_SCENARIO :Сохранить сценарий @@ -746,7 +746,7 @@ STR_PLAY_HEIGHTMAP_HINT :{BLACK}Начать новую игру, используя карту высот в качестве шаблона карты STR_QUIT_SCENARIO_QUERY :{YELLOW}Вы уверены, что хотите выйти из этого сценария? STR_029C_QUIT_EDITOR :{WHITE}Выход из редактора -STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...может быть построен только в городах с населением не менее 1200 +STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}...можно построить в городах с населением более 1200 жителей STR_029E_MOVE_THE_STARTING_DATE :{BLACK}Уменьшить год начала игры на 1 STR_029F_MOVE_THE_STARTING_DATE :{BLACK}Увеличить год начала игры на 1 STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...оба конца моста должны опираться на землю @@ -768,9 +768,9 @@ STR_02BD :{BLACK}{STRING} STR_02BE_DEFAULT :По умолчанию STR_02BF_CUSTOM :Свои -STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Сохранить названия транспорта -STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Выберите названия транспортных средств -STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Сохранить свои названия транспортных средств +STR_02C0_SAVE_CUSTOM_NAMES :{BLACK}Сохранить пользовательские названия +STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION :{BLACK}Загрузка пользовательских названий транспортных средств +STR_02C2_SAVE_CUSTOMIZED_VEHICLE :{BLACK}Сохранить пользовательские названия транспортных средств STR_CHECKMARK :{CHECKMARK} ############ range for menu starts @@ -805,33 +805,33 @@ STR_02DE_MAP_OF_WORLD :Карта мира STR_EXTRA_VIEW_PORT :Доп. окно просмотра STR_SIGN_LIST :Список меток -STR_TRANSPARENCY_OPTIONS :Настройки прозрачности. +STR_TRANSPARENCY_OPTIONS :Настройки прозрачности STR_02DF_TOWN_DIRECTORY :Список городов STR_TOWN_POPULATION :{BLACK}Население: {COMMA} STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Окно просмотра {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Скопировать позицию в окно просмотра +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Скопировать в окно STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Скопировать эту позицию в окно просмотра -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Вставить позицию из окна просмотра +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Вставить из окна STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Вставить эту позицию из окна просмотра STR_02E0_CURRENCY_UNITS :{BLACK}Валюта STR_02E1 :{BLACK}{SKIP}{STRING} -STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Выберите валюту +STR_02E2_CURRENCY_UNITS_SELECTION :{BLACK}Смена используемой в игре валюты STR_MEASURING_UNITS :{BLACK}Единицы измерения STR_02E4 :{BLACK}{SKIP}{SKIP}{STRING} -STR_MEASURING_UNITS_SELECTION :{BLACK}Выберите систему единиц измерения +STR_MEASURING_UNITS_SELECTION :{BLACK}Используемая система единиц измерения STR_02E6_ROAD_VEHICLES :{BLACK}Направление движения STR_02E7 :{BLACK}{SKIP}{SKIP}{SKIP}{STRING} -STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}Выберите направление движения +STR_02E8_SELECT_SIDE_OF_ROAD_FOR :{BLACK}С какой стороны дороги ездит автотранспорт STR_02E9_DRIVE_ON_LEFT :Левостороннее STR_02EA_DRIVE_ON_RIGHT :Правостороннее STR_02EB_TOWN_NAMES :{BLACK}Названия городов STR_02EC :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}Выберите язык названий городов +STR_02ED_SELECT_STYLE_OF_TOWN_NAMES :{BLACK}На каком языке будут названы населённые пункты STR_02F4_AUTOSAVE :{BLACK}Автосохранение STR_02F5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Выберите интервал автосохранения игры +STR_02F6_SELECT_INTERVAL_BETWEEN :{BLACK}Интервал автосохранения игры STR_02F7_OFF :Отключено STR_02F8_EVERY_3_MONTHS :Каждые 3 месяца STR_02F9_EVERY_6_MONTHS :Каждые 6 месяцев @@ -871,7 +871,7 @@ STR_0329_PURCHASE_LAND_FOR_FUTURE :{BLACK}Купить землю STR_032F_AUTOSAVE :{RED}Автосохранение -STR_SAVING_GAME :{RED}* * СОХРАНЯЮ ИГРУ * * +STR_SAVING_GAME :{RED}* * СОХРАНЕНИЕ ИГРЫ * * STR_SAVE_STILL_IN_PROGRESS :{WHITE}Сохранение все еще идет,{}пожалуйста, дождитесь завершения! STR_0330_SELECT_EZY_STREET_STYLE :{BLACK}Выбрать музыкальную программу @@ -879,10 +879,10 @@ STR_0336_7 :{BLACK}7 ############ start of townname region -STR_TOWNNAME_ORIGINAL_ENGLISH :Английские (оригинальные) +STR_TOWNNAME_ORIGINAL_ENGLISH :Английские STR_TOWNNAME_FRENCH :Французские STR_TOWNNAME_GERMAN :Немецкие -STR_TOWNNAME_ADDITIONAL_ENGLISH :Английские (дополнительные) +STR_TOWNNAME_ADDITIONAL_ENGLISH :Английские (дополн.) STR_TOWNNAME_LATIN_AMERICAN :Латино-американские STR_TOWNNAME_SILLY :Английские (шуточные) STR_TOWNNAME_SWEDISH :Шведские @@ -934,18 +934,18 @@ STR_OPTIONS_LANG :{BLACK}Язык STR_OPTIONS_LANG_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_OPTIONS_LANG_TIP :{BLACK}Выберите язык интерфейса +STR_OPTIONS_LANG_TIP :{BLACK}Язык пользовательского интерфейса STR_OPTIONS_FULLSCREEN :{BLACK}Полноэкранный режим STR_OPTIONS_FULLSCREEN_TIP :{BLACK}Включить/выключить полноэкранный режим STR_OPTIONS_RES :{BLACK}Разрешение экрана STR_OPTIONS_RES_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_OPTIONS_RES_TIP :{BLACK}Выберите разрешение экрана +STR_OPTIONS_RES_TIP :{BLACK}Выбор разрешения экрана STR_OPTIONS_SCREENSHOT_FORMAT :{BLACK}Формат скриншотов STR_OPTIONS_SCREENSHOT_FORMAT_CBO :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Выберите формат скриншотов +STR_OPTIONS_SCREENSHOT_FORMAT_TIP :{BLACK}Формат, в котором будут сохраняться снимки экрана STR_AUTOSAVE_1_MONTH :Каждый месяц STR_AUTOSAVE_FAILED :{WHITE}Ошибка автосохранения @@ -981,15 +981,15 @@ STR_CANT_SHARE_ORDER_LIST :{WHITE}Невозможно использовать общий список заданий STR_CANT_COPY_ORDER_LIST :{WHITE}Невозможно скопировать список заданий -STR_END_OF_SHARED_ORDERS :{SETX 10}- - Конец списка заданий - - +STR_END_OF_SHARED_ORDERS :{SETX 10}- - Конец общих заданий - - -STR_TRAIN_IS_LOST :{WHITE}Поезд {COMMA} не находит путь ... -STR_TRAIN_IS_UNPROFITABLE :{WHITE}Доход поезда {COMMA} за прошлый год составил {CURRENCY} +STR_TRAIN_IS_LOST :{WHITE}Поезд {COMMA} не может найти пути +STR_TRAIN_IS_UNPROFITABLE :{WHITE}Поезд {COMMA} за прошлый год принёс {CURRENCY} убытка STR_EURO_INTRODUCE :{BLACK}{BIGFONT}Создана зона евро!{}{}Теперь в вашей стране в качестве единой валюты используется евро! # Start of order review system. # DON'T ADD OR REMOVE LINES HERE -STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Только одно задание в списке заданий для поезда {COMMA} +STR_TRAIN_HAS_TOO_FEW_ORDERS :{WHITE}Только одно задание у поезда {COMMA} STR_TRAIN_HAS_VOID_ORDER :{WHITE}У поезда {COMMA} нет заданий STR_TRAIN_HAS_DUPLICATE_ENTRY :{WHITE}У поезда {COMMA} дублируются задания STR_TRAIN_HAS_INVALID_ENTRY :{WHITE}У поезда {COMMA} неправильное место назначения @@ -1022,53 +1022,53 @@ STR_CONFIG_PATCHES_VEHICLESPEED :{LTBLUE}Показывать скорость в панели статуса транспорта: {ORANGE}{STRING} STR_CONFIG_PATCHES_BUILDONSLOPES :{LTBLUE}Разрешить строительство на склонах и на берегу: {ORANGE}{STRING} STR_CONFIG_PATCHES_CATCHMENT :{LTBLUE}Зона покрытия зависит от типа станции: {ORANGE}{STRING} -STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Разрешить удаление всех городских объектов: {ORANGE}{STRING} -STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Разрешить строительство очень длинных поездов: {ORANGE}{STRING} +STR_CONFIG_PATCHES_EXTRADYNAMITE :{LTBLUE}Разрешить снос (почти) всех городских объектов: {ORANGE}{STRING} +STR_CONFIG_PATCHES_MAMMOTHTRAINS :{LTBLUE}Разрешить очень длинные поезда: {ORANGE}{STRING} STR_CONFIG_PATCHES_REALISTICACCEL :{LTBLUE}Включить реалистичное ускорение для поездов: {ORANGE}{STRING} -STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Запретить резкие повороты поездам и кораблям: {ORANGE}{STRING} {LTBLUE}(NPF) -STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Объединять построенные рядом ж/д станции: {ORANGE}{STRING} +STR_CONFIG_PATCHES_FORBID_90_DEG :{LTBLUE}Запретить 90-градусные повороты на ж/д и море: {ORANGE}{STRING} {LTBLUE} (NPF) +STR_CONFIG_PATCHES_JOINSTATIONS :{LTBLUE}Объединять рядом построенные ж/д станции: {ORANGE}{STRING} STR_CONFIG_PATCHES_FULLLOADANY :{LTBLUE}Покидать станцию, когда любой груз полностью загружен: {ORANGE}{STRING} STR_CONFIG_PATCHES_IMPROVEDLOAD :{LTBLUE}Использовать улучшенный алгоритм загрузки: {ORANGE}{STRING} STR_CONFIG_PATCHES_GRADUAL_LOADING :{LTBLUE}Постепенная загрузка транспорта: {ORANGE}{STRING} STR_CONFIG_PATCHES_INFLATION :{LTBLUE}Включить инфляцию: {ORANGE}{STRING} STR_CONFIG_PATCHES_SELECTGOODS :{LTBLUE}Поставлять груз на станцию, только если на него был спрос: {ORANGE}{STRING} STR_CONFIG_PATCHES_LONGBRIDGES :{LTBLUE}Разрешить строительство очень длинных мостов: {ORANGE}{STRING} -STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Разрешить добавлять депо в маршрут: {ORANGE}{STRING} +STR_CONFIG_PATCHES_GOTODEPOT :{LTBLUE}Депо можно добавить в маршрут: {ORANGE}{STRING} STR_CONFIG_PATCHES_BUILDXTRAIND :{LTBLUE}Разрешить строительство сырьевых предприятий: {ORANGE}{STRING} STR_CONFIG_PATCHES_MULTIPINDTOWN :{LTBLUE}Разрешить несколько предприятий одного типа на город: {ORANGE}{STRING} STR_CONFIG_PATCHES_SAMEINDCLOSE :{LTBLUE}Одинаковые предприятия могут быть рядом друг с другом: {ORANGE}{STRING} -STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Всегда показывать длинную дату в панели состояния: {ORANGE}{STRING} +STR_CONFIG_PATCHES_LONGDATE :{LTBLUE}Всегда полная дата в панели состояния: {ORANGE}{STRING} STR_CONFIG_PATCHES_SIGNALSIDE :{LTBLUE}Показывать светофоры на стороне движения: {ORANGE}{STRING} -STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Показывать финансовую статистику в конце года: {ORANGE}{STRING} +STR_CONFIG_PATCHES_SHOWFINANCES :{LTBLUE}Показывать финансовую статистику каждый год: {ORANGE}{STRING} STR_CONFIG_PATCHES_NEW_NONSTOP :{LTBLUE}Использовать поведение TTDP для приказа "без остановок": {ORANGE}{STRING} -STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Разрешить автомобилям ожидать въезда на станцию: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ROADVEH_QUEUE :{LTBLUE}Автотранспорт строится в очередь у станции: {ORANGE}{STRING} STR_CONFIG_PATCHES_AUTOSCROLL :{LTBLUE}Смещать обзор, когда курсор находится у края экрана: {ORANGE}{STRING} STR_CONFIG_PATCHES_BRIBE :{LTBLUE}Разрешить подкупать муниципальную власть: {ORANGE}{STRING} STR_CONFIG_PATCHES_NONUNIFORM_STATIONS :{LTBLUE}Станции могут быть произвольной формы: {ORANGE}{STRING} -STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Включить новый алгоритм навигации (NPF, заменяет NTP): {ORANGE}{STRING} +STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}Алгоритм навигации NPF (замена оригинального): {ORANGE}{STRING} STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Множитель увеличения веса груза для товарных поездов: {ORANGE}{STRING} STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD :{LTBLUE}Позволять строить остановки на городских дорогах: {ORANGE}{STRING} -STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Всегда разрешать строительство малых аэропортов: {ORANGE}{STRING} +STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Малые аэропорты всегда доступны: {ORANGE}{STRING} STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Предупреждать, если поезд заблудился: {ORANGE}{STRING} STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Проверять маршруты на правильность: {ORANGE}{STRING} -STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :нет -STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :кроме остановленного -STR_CONFIG_PATCHES_ORDER_REVIEW_ON :всего транспорта -STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Предупреждать, если поезд приносит убыток: {ORANGE}{STRING} -STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Транспорт никогда не устаревает: {ORANGE}{STRING} -STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Автоматически обновлять изношенный транспорт -STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Обновлять через {ORANGE}{STRING}{LTBLUE} месяцев после истечения срока службы -STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Сумма, необходимая для автообновления: {ORANGE}{STRING} -STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Длительность сообщений об ошибке: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :не проверять +STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :у всех запущенных +STR_CONFIG_PATCHES_ORDER_REVIEW_ON :у всех +STR_CONFIG_PATCHES_WARN_INCOME_LESS :{LTBLUE}Предупреждать, если поезд убыточный: {ORANGE}{STRING} +STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES :{LTBLUE}Транспорт не будет выходить из эксплутации: {ORANGE}{STRING} +STR_CONFIG_PATCHES_AUTORENEW_VEHICLE :{LTBLUE}Автоозамена изношенного транспорта +STR_CONFIG_PATCHES_AUTORENEW_MONTHS :{LTBLUE}Замена через {ORANGE}{STRING}{LTBLUE} месяц{P "" а ев} после истечения срока службы +STR_CONFIG_PATCHES_AUTORENEW_MONEY :{LTBLUE}Сумма, необходимая для автозамены: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ERRMSG_DURATION :{LTBLUE}Макс. длительность сообщений об ошибке (сек.): {ORANGE}{STRING} STR_CONFIG_PATCHES_POPULATION_IN_LABEL :{LTBLUE}Показывать количество жителей города после названия: {ORANGE}{STRING} STR_CONFIG_PATCHES_INVISIBLE_TREES :{LTBLUE}Убирать деревья при включении прозрачности зданий: {ORANGE}{STRING} STR_CONFIG_PATCHES_LAND_GENERATOR :{LTBLUE}Генератор земли: {ORANGE}{STRING} -STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :оригинальный +STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL :Оригинальный STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis -STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Макс. расстояние от края карты до нефтепер. заводов: {ORANGE}{STRING} +STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE :{LTBLUE}Нефтезаводы не дальше от края карты (клеток): {ORANGE}{STRING} STR_CONFIG_PATCHES_SNOWLINE_HEIGHT :{LTBLUE}Высота "снежной" линии: {ORANGE}{STRING} STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN :{LTBLUE}Неровность земли (только для TerraGenesis) : {ORANGE}{STRING} STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Очень гладкий @@ -1086,8 +1086,8 @@ STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Макс. протяженность: {ORANGE}{STRING} {RED}(большие значения замедляют игру) STR_CONFIG_PATCHES_SERVICEATHELIPAD :{LTBLUE}Включить обслуживание на вертолетных площадках: {ORANGE}{STRING} -STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Открывать ландшафтную панель вместе с транспортными: {ORANGE}{STRING} -STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Обратить направление перетаскивания обзора: {ORANGE}{STRING} +STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR :{LTBLUE}Связать ландшафтную панель с транспортной: {ORANGE}{STRING} +STR_CONFIG_PATCHES_REVERSE_SCROLLING :{LTBLUE}Обратить направление перемещения обзора мышью: {ORANGE}{STRING} STR_CONFIG_PATCHES_MEASURE_TOOLTIP :{LTBLUE}Показывать замеры при строительстве: {ORANGE}{STRING} STR_CONFIG_PATCHES_LIVERIES :{LTBLUE}Показывать окраску транспорта: {ORANGE}{STRING} STR_CONFIG_PATCHES_LIVERIES_NONE :нет @@ -1099,45 +1099,46 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :для смещения обзора STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :не использовать STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Скорость смещения обзора прокруткой колеса мыши: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Автопауза в начале игры: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Максимальное количество поездов на игрока: {ORANGE}{STRING} -STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Максимальное количество автомобилей на игрока: {ORANGE}{STRING} +STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Максимальное количество автотранспорта на игрока: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_AIRCRAFT :{LTBLUE}Максимальное количество авиатранспорта на игрока: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_SHIPS :{LTBLUE}Максимальное количество кораблей на игрока: {ORANGE}{STRING} -STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Не допускать постройки поездов конкурентами: {ORANGE}{STRING} -STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Не допускать постройки автомобилей конкурентами: {ORANGE}{STRING} -STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Не допускать постройки авиатранспорта конкурентами: {ORANGE}{STRING} -STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Не допускать постройки кораблей конкурентами: {ORANGE}{STRING} +STR_CONFIG_PATCHES_AI_BUILDS_TRAINS :{LTBLUE}Не допускать постройки поездов компьютером: {ORANGE}{STRING} +STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH :{LTBLUE}Не допускать постройки автомобилей компьютером: {ORANGE}{STRING} +STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Не допускать постройки авиатранспорта компьютером: {ORANGE}{STRING} +STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Не допускать постройки кораблей компьютером: {ORANGE}{STRING} STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Включить новый AI (альфа-версия): {ORANGE}{STRING} STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Разрешить появление AI-конкурентов в сетевой игре: {ORANGE}{STRING} -STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Интервал обслуживания поездов: {ORANGE}{STRING} дней/% -STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Интервал обслуживания поездов: {ORANGE}не обслуживаются -STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Интервал обслуживания автомобилей: {ORANGE}{STRING} дней/% -STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Интервал обслуживания автомобилей: {ORANGE}не обслуживаются -STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Интервал обслуживания авиатранспорта: {ORANGE}{STRING} дней/% -STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Интервал обслуживания авиатранспорта: {ORANGE}не обслуживается -STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Интервал обслуживания кораблей: {ORANGE}{STRING} дней/% -STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Интервал обслуживания кораблей: {ORANGE}не обслуживаются -STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Отключить обслуживание, если поломки выключены: {ORANGE}{STRING} -STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Включить ограничение скорости вагонов: {ORANGE}{STRING} -STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Отключить электрофицированную железную дорогу: {ORANGE}{STRING} +STR_CONFIG_PATCHES_SERVINT_TRAINS :{LTBLUE}Обслуживание поездов по умолчанию: {ORANGE}кажд{P 1 ый ые ые} {STRING} д{P 1 ень ня ней}/% +STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED :{LTBLUE}Обслуживание поездов по умолчанию: {ORANGE}не обслуживаются +STR_CONFIG_PATCHES_SERVINT_ROADVEH :{LTBLUE}Обслуживание автотранспорта: {ORANGE}кажд{P 1 ый ые ые} {STRING} д{P 1 ень ня ней}/% +STR_CONFIG_PATCHES_SERVINT_ROADVEH_DISABLED :{LTBLUE}Обслуживание автотранспорта: {ORANGE}не обслуживаются +STR_CONFIG_PATCHES_SERVINT_AIRCRAFT :{LTBLUE}Обслуживание авиатранспорта: {ORANGE}кажд{P 1 ый ые ые} {STRING} д{P 1 ень ня ней}/% +STR_CONFIG_PATCHES_SERVINT_AIRCRAFT_DISABLED :{LTBLUE}Обслуживание авиатранспорта: {ORANGE}не обслуживается +STR_CONFIG_PATCHES_SERVINT_SHIPS :{LTBLUE}Обслуживание кораблей: {ORANGE}кажд{P 1 ый ые ые} {STRING} д{P 1 ень ня ней}/% +STR_CONFIG_PATCHES_SERVINT_SHIPS_DISABLED :{LTBLUE}Обслуживание кораблей: {ORANGE}не обслуживаются +STR_CONFIG_PATCHES_NOSERVICE :{LTBLUE}Не обслуживать транспорт, если отключены поломки: {ORANGE}{STRING} +STR_CONFIG_PATCHES_WAGONSPEEDLIMITS :{LTBLUE}Использовать органичение скорости у вагонов (если есть): {ORANGE}{STRING} +STR_CONFIG_PATCHES_DISABLE_ELRAILS :{LTBLUE}Выключить электрофицированную железную дорогу: {ORANGE}{STRING} STR_CONFIG_PATCHES_COLORED_NEWS_YEAR :{LTBLUE}Цветные газеты появляются: {ORANGE}в {STRING} году STR_CONFIG_PATCHES_STARTING_YEAR :{LTBLUE}Год начала игры: {ORANGE}{STRING} STR_CONFIG_PATCHES_ENDING_YEAR :{LTBLUE}Заканчивать игру: {ORANGE}в {STRING} году STR_CONFIG_PATCHES_SMOOTH_ECONOMY :{LTBLUE}Включить плавную экономику (частые, небольшие изменения) -STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Разрешить покупать акции других компаний -STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При перетаскивании ставить светофоры каждые: {ORANGE}{STRING} клетки -STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Автоматически строить семафоры: {ORANGE}до {STRING} года +STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Разрешить торговлю акциями других компаний +STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При установке светофоров линией, ставить кажд{P 1 ую ые ые}: {ORANGE}{STRING} клет{P 1 ку ки ок} +STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Строить семафоры старого стиля: {ORANGE}до {STRING} года STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Положение главной панели инструментов: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :слева STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :в центре STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :справа -STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Радиус прилипания окон: {ORANGE}{STRING} -STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Радиус прилипания окон: {ORANGE}отключено +STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Радиус прилипания окон (пикселей): {ORANGE}{STRING} +STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Радиус прилипания окон (пикселей): {ORANGE}отключено STR_CONFIG_PATCHES_TOWN_GROWTH :{LTBLUE}Скорость роста городов: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOWN_GROWTH_NONE :нет STR_CONFIG_PATCHES_TOWN_GROWTH_SLOW :медленная @@ -1160,10 +1161,10 @@ STR_CONFIG_PATCHES_CURRENCY :{CURRENCY} STR_CONFIG_PATCHES_QUERY_CAPT :{WHITE}Изменить значение -STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Некоторые интервалы не совместимы с выбранной установкой. Допускаются значения 5-90% или 30-800 дней. -STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Использовать YAPF для кораблей: {ORANGE}{STRING} -STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Использовать YAPF для автомобилей: {ORANGE}{STRING} -STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Использовать YAPF для поездов: {ORANGE}{STRING} +STR_CONFIG_PATCHES_SERVICE_INTERVAL_INCOMPATIBLE :{WHITE}Некоторые интервалы не совместимы с выбранной установкой. Допускаются значения 5-90% или 30-800 дней +STR_CONFIG_PATCHES_YAPF_SHIPS :{LTBLUE}Алгоритм навигации YAPF для кораблей: {ORANGE}{STRING} +STR_CONFIG_PATCHES_YAPF_ROAD :{LTBLUE}Алгоритм навигации YAPF для автотранспорта: {ORANGE}{STRING} +STR_CONFIG_PATCHES_YAPF_RAIL :{LTBLUE}Алгоритм навигации YAPF для поездов: {ORANGE}{STRING} STR_TEMPERATE_LANDSCAPE :Умеренный ландшафт STR_SUB_ARCTIC_LANDSCAPE :Субарктический ландшафт @@ -1174,11 +1175,11 @@ STR_CHEATS_TIP :{BLACK}Галочка показывает, использовали ли Вы этот ЧИТ раньше STR_CHEATS_WARNING :{BLACK}Внимание, вы собираетесь предать своих соперников! Этого вам никогда не простят! STR_CHEAT_MONEY :{LTBLUE}Увеличить деньги на {CURRENCY64} -STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Управлять игроком: {ORANGE}{COMMA} -STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Волшебный бульдозер (удаляет промышленность и т.п.): {ORANGE}{STRING} +STR_CHEAT_CHANGE_PLAYER :{LTBLUE}Играть за компанию: {ORANGE}{COMMA} +STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Волшебный динамит (снос _ВСЕГО_): {ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Туннели могут пересекаться: {ORANGE}{STRING} STR_CHEAT_BUILD_IN_PAUSE :{LTBLUE}Строить в режиме паузы: {ORANGE}{STRING} -STR_CHEAT_NO_JETCRASH :{LTBLUE}Большие самолеты не будут часто разбиваться в маленьких аэропортах: {ORANGE} {STRING} +STR_CHEAT_NO_JETCRASH :{LTBLUE}Большие самолеты реже разбиваются в малых аэропортах: {ORANGE}{STRING} STR_CHEAT_SWITCH_CLIMATE :{LTBLUE}Сменить климат на: {ORANGE} {STRING} STR_CHEAT_CHANGE_DATE :{LTBLUE}Изменение даты: {ORANGE} {DATE_SHORT} STR_CHEAT_SETUP_PROD :{LTBLUE}Разрешить изменение производительности: {ORANGE}{STRING} @@ -1186,8 +1187,8 @@ STR_HEADING_FOR_WAYPOINT :{LTBLUE}Следует к {WAYPOINT} STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Следует к {WAYPOINT}, {VELOCITY} -STR_GO_TO_WAYPOINT :Идти через {WAYPOINT} -STR_GO_NON_STOP_TO_WAYPOINT :Идти б/остан. через {WAYPOINT} +STR_GO_TO_WAYPOINT :Ехать через {WAYPOINT} +STR_GO_NON_STOP_TO_WAYPOINT :Ехать через {WAYPOINT} без остановки STR_WAYPOINTNAME_CITY :Точка пути {TOWN} STR_WAYPOINTNAME_CITY_SERIAL :Точка пути {TOWN} #{COMMA} @@ -1226,7 +1227,7 @@ STR_TREES_RANDOM_TYPE_TIP :{BLACK}Разместить деревья случайного типа STR_CANT_BUILD_CANALS :{WHITE}Невозможно построить канал здесь... -STR_BUILD_CANALS_TIP :{BLACK}Строить каналы. +STR_BUILD_CANALS_TIP :{BLACK}Строить каналы STR_LANDINFO_CANAL :Канал STR_CANT_BUILD_LOCKS :{WHITE}Невозможно построить шлюз здесь... @@ -1243,8 +1244,8 @@ STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP :{BLACK}Перетащите сюда локомотив для продажи всего поезда -STR_DRAG_DROP :{BLACK}Перетаскивание -STR_STATION_DRAG_DROP :{BLACK}Строить станцию, используя перетаскивание +STR_DRAG_DROP :{BLACK}Участок +STR_STATION_DRAG_DROP :{BLACK}Постройка станции на указанном игроком участке STR_SELECT_STATION_CLASS_TIP :{BLACK}Выберите класс станций для отображения STR_SELECT_STATION_TYPE_TIP :{BLACK}Выберите тип станции для постройки @@ -1285,36 +1286,36 @@ STR_RAIL_REFIT_VEHICLE :{BLACK}Переоборудовать поезда STR_RAIL_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выбор типа груза для перевозки STR_RAIL_REFIT_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборудование поезда для выделенного типа груза -STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Не могу переоборуд. поезд... -STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Интервалы обслуживания в процентах от срока службы: {ORANGE}{STRING} +STR_RAIL_CAN_T_REFIT_VEHICLE :{WHITE}Не могу переоборудовать поезд... +STR_CONFIG_PATCHES_SERVINT_ISPERCENT :{LTBLUE}Интервал обслуживания в процентах: {ORANGE}{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Изменить производительность TEMP_AI_IN_PROGRESS :{WHITE}Добро пожаловать в новый ИИ, он совершенствуется. Вы должны быть готовы к проблемам. Когда это случится, сделайте снимок и отправьте на форум. Наслаждайтесь! TEMP_AI_ACTIVATED :{WHITE}Внимание: новый AI всё еще находится в состоянии альфа-версии! В настоящее время работает только с автотранспортом! -TEMP_AI_MULTIPLAYER :{WHITE}Внимание: экспериментальная эксплуатация нового AI. Пожалуйста, сообщайте обо всех проблемах на truelight@openttd.org. +TEMP_AI_MULTIPLAYER :{WHITE}Внимание: экспериментальная эксплуатация нового AI. Пожалуйста, сообщайте обо всех проблемах на truelight@openttd.org ############ network gui strings STR_NETWORK_MULTIPLAYER :{WHITE}Сетевая игра STR_NETWORK_PLAYER_NAME :{BLACK}Имя игрока: -STR_NETWORK_ENTER_NAME_TIP :{BLACK}Это имя, по которому другие игроки определяют вас +STR_NETWORK_ENTER_NAME_TIP :{BLACK}Это имя, под которым вы представитесь другим игрокам STR_NETWORK_CONNECTION :{BLACK}Соединение: -STR_NETWORK_CONNECTION_TIP :{BLACK}Выбор между Интернет игрой или игрой в Локальной Сети (СЕТЬ) +STR_NETWORK_CONNECTION_TIP :{BLACK}Искать сервера в локальной сети, или в Интернете STR_NETWORK_START_SERVER :{BLACK}Запуск сервера -STR_NETWORK_START_SERVER_TIP :{BLACK}Запуск своего сервера +STR_NETWORK_START_SERVER_TIP :{BLACK}Запуск сервера на вашем компьютере. К этой игре смогут подсоединяться другие игроки. STR_NETWORK_GAME_NAME :{BLACK}Название STR_NETWORK_GAME_NAME_TIP :{BLACK}Название игры STR_NETWORK_INFO_ICONS_TIP :{BLACK}Язык, версия сервера и т.п. STR_NETWORK_CLICK_GAME_TO_SELECT :{BLACK}Выберите игру из списка -STR_NETWORK_FIND_SERVER :{BLACK}Найти сервер -STR_NETWORK_FIND_SERVER_TIP :{BLACK}Найти сервер в сети +STR_NETWORK_FIND_SERVER :{BLACK}Обновить +STR_NETWORK_FIND_SERVER_TIP :{BLACK}Обновить список серверов, которые сейчас есть в сети STR_NETWORK_ADD_SERVER :{BLACK}Добавить сервер -STR_NETWORK_ADD_SERVER_TIP :{BLACK}Добавить сервер в список, который будет всегда проверяться при запуске игр. -STR_NETWORK_ENTER_IP :{BLACK}Ввести адрес сервера +STR_NETWORK_ADD_SERVER_TIP :{BLACK}Добавить сервер, который будет автоматически обновляться при открытии этого окна +STR_NETWORK_ENTER_IP :{BLACK}Введите адрес сервера STR_NETWORK_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA} STR_NETWORK_CLIENTS_CAPTION :{BLACK}Клиенты @@ -1335,7 +1336,7 @@ STR_NETWORK_VERSION_MISMATCH :{SILVER}ВЕРСИЯ НЕ ПОДХОДИТ STR_NETWORK_GRF_MISMATCH :{SILVER}НЕ СОВПАДАЕТ НАБОР NEWGRF -STR_NETWORK_JOIN_GAME :{BLACK}Присоединиться к игре +STR_NETWORK_JOIN_GAME :{BLACK}Присоединиться STR_NETWORK_START_GAME_WINDOW :{WHITE}Запуск новой сетевой игры @@ -1351,8 +1352,8 @@ STR_NETWORK_COMBO1 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} STR_NETWORK_LAN :Локальная сеть STR_NETWORK_INTERNET :Интернет -STR_NETWORK_LAN_INTERNET :Локальная сеть/Интернет -STR_NETWORK_INTERNET_ADVERTISE :Интернет (объявленный) +STR_NETWORK_LAN_INTERNET :Лок. сеть/Интернет +STR_NETWORK_INTERNET_ADVERTISE :Интернет (объявл.) STR_NETWORK_COMBO2 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} STR_NETWORK_0_PLAYERS :0 игроков STR_NETWORK_1_PLAYERS :1 игрок @@ -1374,9 +1375,9 @@ STR_NETWORK_LANGUAGE_SPOKEN :{BLACK}Язык общения: STR_NETWORK_LANGUAGE_TIP :{BLACK}Другие игроки будут знать, на каком языке говорят на сервере STR_NETWORK_COMBO5 :{BLACK}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{SKIP}{STRING} -STR_NETWORK_START_GAME :{BLACK}Запуск Игры +STR_NETWORK_START_GAME :{BLACK}Запуск игры STR_NETWORK_START_GAME_TIP :{BLACK}Запуск новой сетевой игры с произвольной карты или сценария -STR_NETWORK_LOAD_GAME :{BLACK}Загрузка Игры +STR_NETWORK_LOAD_GAME :{BLACK}Загрузка игры STR_NETWORK_LOAD_GAME_TIP :{BLACK}Продолжить ранее сохраненную сетевую игру (проверьте, что подсоединились прежним игроком) ############ Leave those lines in this order!! @@ -1394,8 +1395,8 @@ STR_NETWORK_NEW_COMPANY_TIP :{BLACK}Основать новую компанию STR_NETWORK_SPECTATE_GAME :{BLACK}Наблюдать за игрой STR_NETWORK_SPECTATE_GAME_TIP :{BLACK}Следить за игрой в качестве зрителя -STR_NETWORK_JOIN_COMPANY :{BLACK}Присоединиться к компании -STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Помочь в управлении компанией +STR_NETWORK_JOIN_COMPANY :{BLACK}Присоединиться +STR_NETWORK_JOIN_COMPANY_TIP :{BLACK}Присоединиться к компании и помочь в управлении ею STR_NETWORK_REFRESH :{BLACK}Обновить сервер STR_NETWORK_REFRESH_TIP :{BLACK}Обновить информацию о сервере @@ -1518,8 +1519,8 @@ STR_BMPMAP_ERR_IMAGE_TYPE :{WHITE}...невозможно преобразовать тип изображения. ##id 0x0800 -STR_0800_COST :{TINYFONT}{RED}Цена: {CURRENCY} -STR_0801_COST :{RED}Цена: {CURRENCY} +STR_0800_COST :{TINYFONT}{RED}Расход: {CURRENCY} +STR_0801_COST :{RED}Расход: {CURRENCY} STR_0802_INCOME :{TINYFONT}{GREEN}Доход: {CURRENCY} STR_0803_INCOME :{GREEN}Доход: {CURRENCY} STR_FEEDER_TINY :{TINYFONT}{YELLOW}Трансфер: {CURRENCY} @@ -1582,7 +1583,7 @@ ##id 0x1800 STR_1801_MUST_REMOVE_ROAD_FIRST :{WHITE}Сначала удалите дорогу -STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Идут дорожные работы ... +STR_ROAD_WORKS_IN_PROGRESS :{WHITE}Идут дорожные работы... STR_1802_ROAD_CONSTRUCTION :{WHITE}Строительство дорог STR_1803_SELECT_ROAD_BRIDGE :{WHITE}Выберите тип моста STR_1804_CAN_T_BUILD_ROAD_HERE :{WHITE}Не могу проложить дорогу здесь... @@ -1620,7 +1621,7 @@ STR_2006_POPULATION :{BLACK}Население: {ORANGE}{COMMA}{BLACK} Зданий: {ORANGE}{COMMA} STR_2007_RENAME_TOWN :Переименовать город STR_2008_CAN_T_RENAME_TOWN :{WHITE}Не могу переименовать город... -STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} местная администрация не дает +STR_2009_LOCAL_AUTHORITY_REFUSES :{WHITE}Местная администрация города {TOWN} не допустит. STR_200A_TOWN_NAMES_CLICK_ON_NAME :{BLACK}Названия городов - кликните на названии для отображения города STR_200B_CENTER_THE_MAIN_VIEW_ON :{BLACK}Отцентрировать основное окно по городу STR_200C_CHANGE_TOWN_NAME :{BLACK}Переименовать город @@ -1650,7 +1651,7 @@ STR_2024 :{YELLOW}{COMPANY}{PLAYERNAME}: {ORANGE}{STRING} STR_2025_SUBSIDIES :{WHITE}Субсидии STR_2026_SUBSIDIES_ON_OFFER_FOR :{BLACK}Свободные субсидии -STR_2027_FROM_TO :{ORANGE}{STRING} по маршруту из {STRING} в {STRING} +STR_2027_FROM_TO :{ORANGE}{STRING.p} по маршруту из {STRING} в {STRING} STR_2028_BY :{YELLOW} (по {DATE_SHORT}) STR_202A_NONE :{ORANGE}нет STR_202B_SERVICES_ALREADY_SUBSIDISED :{BLACK}Субсидируемые маршруты: @@ -1659,10 +1660,10 @@ STR_202E_OFFER_OF_SUBSIDY_EXPIRED :{BLACK}{BIGFONT}Предложение субсидии истекло:{}{}{STRING} по маршруту {STRING} - {STRING} субсидироваться не будет. STR_202F_SUBSIDY_WITHDRAWN_SERVICE :{BLACK}{BIGFONT}Срок субсидии истек:{}{}{STRING} по маршруту {STATION} - {STATION} больше не субсидируется. STR_2030_SERVICE_SUBSIDY_OFFERED :{BLACK}{BIGFONT}Предложена субсидия:{}{}Первая компания, которая повезет {STRING} по маршруту {STRING} - {STRING} получит годовую субсидию от местных властей! -STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается на 50% больше в следующем году! -STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY}получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается вдвойне в следующем году! -STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания{COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается втройне в следующем году! -STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} в {STATION} оплачивается вчетверо в следующем году! +STR_2031_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается наполовину больше в следующем году! +STR_2032_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается вдвойне в следующем году! +STR_2033_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается втройне в следующем году! +STR_2034_SERVICE_SUBSIDY_AWARDED :{BLACK}{BIGFONT}Компания {COMPANY} получает субсидию!{}{}{STRING} по маршруту {STATION} - {STATION} оплачивается вчетверо в следующем году! STR_2035_LOCAL_AUTHORITY_REFUSES :{WHITE}{TOWN} местная власть запрещает постройку другого аэропорта в городе STR_2036_COTTAGES :Коттеджи STR_2037_HOUSES :Дома @@ -1676,7 +1677,7 @@ STR_203F_HOUSES :Дома STR_2040_CINEMA :Кинотеатр STR_2041_SHOPPING_MALL :Торговый центр -STR_2042_DO_IT :{BLACK}ДАВАЙ! +STR_2042_DO_IT :{BLACK}Применить STR_2043_LIST_OF_THINGS_TO_DO_AT :{BLACK}То, что можно сделать в этом городе - кликните для получения доп. сведений STR_2044_CARRY_OUT_THE_HIGHLIGHTED :{BLACK}Выполнить выделенное действие в списке выше STR_2045_ACTIONS_AVAILABLE :{BLACK}Доступные действия: @@ -1684,10 +1685,10 @@ STR_2047_MEDIUM_ADVERTISING_CAMPAIGN :Средняя рекламная компания STR_2048_LARGE_ADVERTISING_CAMPAIGN :Большая рекламная компания STR_2049_FUND_LOCAL_ROAD_RECONSTRUCTION :Профинансировать ремонт городских дорог -STR_204A_BUILD_STATUE_OF_COMPANY :Построить статую владельца компании +STR_204A_BUILD_STATUE_OF_COMPANY :Установить статую владельца компании STR_204B_FUND_NEW_BUILDINGS :Профинансировать строительство новых зданий STR_204C_BUY_EXCLUSIVE_TRANSPORT :Купить эксклюзивные транспортные права -STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Дать взятку местной администрации +STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY :Взятка местной администрации STR_204D_INITIATE_A_SMALL_LOCAL :{WHITE}{STRING}{}{YELLOW} Провести малую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{} Цена: {CURRENCY} STR_204E_INITIATE_A_MEDIUM_LOCAL :{WHITE}{STRING}{}{YELLOW} Провести среднюю рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{} Цена: {CURRENCY} STR_204F_INITIATE_A_LARGE_LOCAL :{WHITE}{STRING}{}{YELLOW} Провести большую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{} Цена: {CURRENCY} @@ -1772,7 +1773,7 @@ STR_3043_TRUCK_STATION_ORIENT :{WHITE}Ориентация станции STR_3046_MUST_DEMOLISH_BUS_STATION :{WHITE}Сначала удалите автобусную остановку STR_3047_MUST_DEMOLISH_TRUCK_STATION :{WHITE}Сначала удалите грузовой терминал -STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Станции +STR_3048_STATIONS :{WHITE}{COMPANY} - {COMMA} Станц{P 2 ия ии ий} STR_3049_0 :{YELLOW}{STATION} {STATIONFEATURES} STR_304A_NONE :{YELLOW}- Нет - STR_304B_SITE_UNSUITABLE :{WHITE}...неподходящее место @@ -1848,14 +1849,14 @@ STR_4803_POWER_STATION :Электростанция STR_4804_SAWMILL :Лесопилка STR_4805_FOREST :Лес -STR_4806_OIL_REFINERY :Нефтеперерабат. завод -STR_4807_OIL_RIG :Буровая вышка +STR_4806_OIL_REFINERY :Нефтезавод +STR_4807_OIL_RIG :Нефтяная вышка STR_4808_FACTORY :Завод STR_4809_PRINTING_WORKS :Типография STR_480A_STEEL_MILL :Сталелитейный завод STR_480B_FARM :Ферма STR_480C_COPPER_ORE_MINE :Шахта медной руды -STR_480D_OIL_WELLS :Нефтяная платформа +STR_480D_OIL_WELLS :Нефтяная скважина STR_480E_BANK :Банк STR_480F_FOOD_PROCESSING_PLANT :Пищевая фабрика STR_4810_PAPER_MILL :Бумажная фабрика @@ -1891,8 +1892,8 @@ STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Произведено за прошлый месяц: STR_482B_TRANSPORTED :{YELLOW}{CARGO}{BLACK} ({COMMA}% перевезено) STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Показать предприятие в основном окне -STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Новое предприятие - {STRING} строится возле г. {TOWN}! -STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Новое предприятие - {STRING} заложен возле г. {TOWN}! +STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}Новое предприятие! {STRING} строится возле г. {TOWN}! +STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}Новое предприятие! {STRING} заложен возле г. {TOWN}! STR_482F_COST :{BLACK}Цена: {YELLOW}{CURRENCY} STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Невозможно построить это предприятие здесь... STR_4831_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}...лес можно сажать только выше линии снега @@ -1970,21 +1971,21 @@ STR_SV_AIRCRAFT_NAME :Самолет {COMMA} STR_SV_STNAME :{STRING} -STR_SV_STNAME_NORTH :{STRING} Северная -STR_SV_STNAME_SOUTH :{STRING} Южная -STR_SV_STNAME_EAST :{STRING} Восточная -STR_SV_STNAME_WEST :{STRING} Западная -STR_SV_STNAME_CENTRAL :{STRING} Центральная -STR_SV_STNAME_TRANSFER :Платформа {STRING} -STR_SV_STNAME_HALT :Полустанок {STRING} -STR_SV_STNAME_VALLEY :{STRING} Долина -STR_SV_STNAME_HEIGHTS :{STRING} Высотная -STR_SV_STNAME_WOODS :{STRING} Лесная -STR_SV_STNAME_LAKESIDE :{STRING} Озерная -STR_SV_STNAME_EXCHANGE :{STRING} Сортировочная -STR_SV_STNAME_AIRPORT :{STRING} Аэропорт -STR_SV_STNAME_OILFIELD :Нефтяное поле {STRING} -STR_SV_STNAME_MINES :{STRING} Шахты +STR_SV_STNAME_NORTH :Северный {STRING} +STR_SV_STNAME_SOUTH :Южный {STRING} +STR_SV_STNAME_EAST :Восточный {STRING} +STR_SV_STNAME_WEST :Западный {STRING} +STR_SV_STNAME_CENTRAL :Центральный {STRING} +STR_SV_STNAME_TRANSFER :Перегонный {STRING} +STR_SV_STNAME_HALT :{STRING}-привал +STR_SV_STNAME_VALLEY :Долина {STRING} +STR_SV_STNAME_HEIGHTS :{STRING}-высотная +STR_SV_STNAME_WOODS :Лесная {STRING} +STR_SV_STNAME_LAKESIDE :Озёрная {STRING} +STR_SV_STNAME_EXCHANGE :{STRING}-сортировочная +STR_SV_STNAME_AIRPORT :Аэропорт {STRING} +STR_SV_STNAME_OILFIELD :Нефтяная вышка {STRING} +STR_SV_STNAME_MINES :Шахты {STRING} STR_SV_STNAME_DOCKS :Пристань {STRING} STR_SV_STNAME_BUOY_1 :{STRING} Буй 1 STR_SV_STNAME_BUOY_2 :{STRING} Буй 2 @@ -1995,13 +1996,13 @@ STR_SV_STNAME_BUOY_7 :{STRING} Буй 7 STR_SV_STNAME_BUOY_8 :{STRING} Буй 8 STR_SV_STNAME_BUOY_9 :{STRING} Буй 9 -STR_SV_STNAME_ANNEXE :{STRING} Дополнительная -STR_SV_STNAME_SIDINGS :{STRING} Запасная -STR_SV_STNAME_BRANCH :{STRING} Береговая -STR_SV_STNAME_UPPER :{STRING} Верхняя -STR_SV_STNAME_LOWER :{STRING} Нижняя +STR_SV_STNAME_ANNEXE :{STRING}-дополнительная +STR_SV_STNAME_SIDINGS :{STRING}-запасный +STR_SV_STNAME_BRANCH :{STRING}-ветка +STR_SV_STNAME_UPPER :Верхний {STRING} +STR_SV_STNAME_LOWER :Нижний {STRING} STR_SV_STNAME_HELIPORT :Площадка {STRING} -STR_SV_STNAME_FOREST :{STRING} Лес +STR_SV_STNAME_FOREST :Лес {STRING} ############ end of savegame specific region! @@ -2016,8 +2017,8 @@ STR_6802_MEDIUM.f :{BLACK}средняя STR_6803_HARD :{BLACK}Тяжёлый STR_6803_HARD.f :{BLACK}тяжёлая -STR_6804_CUSTOM :{BLACK}Свой -STR_6804_CUSTOM.f :{BLACK}своя +STR_6804_CUSTOM :{BLACK}Пользов. +STR_6804_CUSTOM.f :{BLACK}пользов. ############ range for difficulty levels ends ############ range for difficulty settings starts @@ -2025,7 +2026,7 @@ STR_6806_COMPETITOR_START_TIME :{LTBLUE}Конкуренты начинают игру: {ORANGE}{STRING} STR_6807_NO_OF_TOWNS :{LTBLUE}Количество городов: {ORANGE}{STRING} STR_6808_NO_OF_INDUSTRIES :{LTBLUE}Количество предприятий: {ORANGE}{STRING} -STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Максимальная начальная ссуда: {ORANGE}{CURRENCY} +STR_6809_MAXIMUM_INITIAL_LOAN_000 :{LTBLUE}Максимальная стартовая ссуда: {ORANGE}{CURRENCY} STR_680A_INITIAL_INTEREST_RATE :{LTBLUE}Начальная процентная ставка: {ORANGE}{COMMA}% STR_680B_VEHICLE_RUNNING_COSTS :{LTBLUE}Затраты на содержание транспорта: {ORANGE}{STRING.p} STR_680C_CONSTRUCTION_SPEED_OF_COMPETITOR :{LTBLUE}Скорость строительства конкурентов: {ORANGE}{STRING} @@ -2041,70 +2042,70 @@ STR_16816_CITY_APPROVAL :{LTBLUE}Отношение властей к изменению территорий: {ORANGE}{STRING} ############ range for difficulty settings ends -STR_26816_NONE :нет -STR_6816_LOW :низкое -STR_6817_NORMAL :среднее -STR_6818_HIGH :большое +STR_26816_NONE :Нет +STR_6816_LOW :Низкое +STR_6817_NORMAL :Среднее +STR_6818_HIGH :Большое STR_6819 :{BLACK}{SMALLLEFTARROW} STR_681A :{BLACK}{SMALLRIGHTARROW} -STR_681B_VERY_SLOW :очень медленная -STR_681C_SLOW :медленная -STR_681D_MEDIUM :средняя -STR_681E_FAST :быстрая -STR_681F_VERY_FAST :очень быстрая -STR_VERY_LOW :очень низкий -STR_VERY_LOW.n :очень низкое -STR_6820_LOW :низкий +STR_681B_VERY_SLOW :Очень медленная +STR_681C_SLOW :Медленная +STR_681D_MEDIUM :Средняя +STR_681E_FAST :Быстрая +STR_681F_VERY_FAST :Очень быстрая +STR_VERY_LOW :Очень низкий +STR_VERY_LOW.n :Очень низкое +STR_6820_LOW :Низкий STR_6820_LOW.n :низкое -STR_6820_LOW.p :низкие -STR_6821_MEDIUM :средний +STR_6820_LOW.p :Низкие +STR_6821_MEDIUM :Средний STR_6821_MEDIUM.n :среднее -STR_6821_MEDIUM.p :средние -STR_6822_HIGH :высокий +STR_6821_MEDIUM.p :Средние +STR_6822_HIGH :Высокий STR_6822_HIGH.n :высокое -STR_6822_HIGH.p :высокие -STR_6823_NONE :нет -STR_6824_REDUCED :уменьшенная -STR_6825_NORMAL :нормальная +STR_6822_HIGH.p :Высокие +STR_6823_NONE :Выключено +STR_6824_REDUCED :Умеренная +STR_6825_NORMAL :Обычная STR_6826_X1_5 :x1.5 STR_6827_X2 :x2 STR_6828_X3 :x3 STR_6829_X4 :x4 -STR_682A_VERY_FLAT :очень плоский -STR_682B_FLAT :плоский -STR_682C_HILLY :холмистый -STR_682D_MOUNTAINOUS :гористый -STR_682E_STEADY :стабильная -STR_682F_FLUCTUATING :неустойчивая -STR_6830_IMMEDIATE :немедленно -STR_6831_3_MONTHS_AFTER_PLAYER :через 3 месяца после игрока -STR_6832_6_MONTHS_AFTER_PLAYER :через 6 месяцев после игрока -STR_6833_9_MONTHS_AFTER_PLAYER :через 9 месяцев после игрока -STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :в конце линий и на станциях -STR_6835_AT_END_OF_LINE_ONLY :только в конце линий -STR_6836_OFF :выключены -STR_6837_ON :включены +STR_682A_VERY_FLAT :Очень плоский +STR_682B_FLAT :Плоский +STR_682C_HILLY :Холмистый +STR_682D_MOUNTAINOUS :Гористый +STR_682E_STEADY :Стабильная +STR_682F_FLUCTUATING :Неустойчивая +STR_6830_IMMEDIATE :Немедленно +STR_6831_3_MONTHS_AFTER_PLAYER :Через 3 месяца после игрока +STR_6832_6_MONTHS_AFTER_PLAYER :Через 6 месяцев после игрока +STR_6833_9_MONTHS_AFTER_PLAYER :Через 9 месяцев после игрока +STR_6834_AT_END_OF_LINE_AND_AT_STATIONS :В конце линий и на станциях +STR_6835_AT_END_OF_LINE_ONLY :Только в конце линий +STR_6836_OFF :Выключены +STR_6837_ON :Включены STR_6838_SHOW_HI_SCORE_CHART :{BLACK}Показать таблицу рекордов -STR_6839_PERMISSIVE :снисходительное -STR_683A_TOLERANT :терпимое -STR_683B_HOSTILE :отрицательное +STR_6839_PERMISSIVE :Дозволяющее +STR_683A_TOLERANT :Терпимое +STR_683B_HOSTILE :Враждебное ##id 0x7000 STR_7000 : STR_7001 :{WHITE}{COMPANY} {BLACK}{PLAYERNAME} STR_7002_PLAYER :(Игрок {COMMA}) -STR_7004_NEW_FACE :{BLACK}Новое лицо +STR_7004_NEW_FACE :{BLACK}Лицо STR_7005_COLOR_SCHEME :{BLACK}Цвет STR_7006_COLOR_SCHEME :{GOLD}Цвет: STR_7007_NEW_COLOR_SCHEME :{WHITE}Новый цвет -STR_7008_COMPANY_NAME :{BLACK}Название фирмы -STR_7009_PRESIDENT_NAME :{BLACK}Имя директора +STR_7008_COMPANY_NAME :{BLACK}Название +STR_7009_PRESIDENT_NAME :{BLACK}Директор STR_700A_COMPANY_NAME :Компания STR_700B_PRESIDENT_S_NAME :Имя директора STR_700C_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Невозможно изменить название компании... STR_700D_CAN_T_CHANGE_PRESIDENT :{WHITE}Невозможно изменить имя директора... STR_700E_FINANCES :{WHITE}{COMPANY} Денежные средства {BLACK}{PLAYERNAME} -STR_700F_EXPENDITURE_INCOME :{WHITE}Статьи расхода/дохода +STR_700F_EXPENDITURE_INCOME :{WHITE}Расход/доход STR_7010 :{WHITE}{NUM} STR_7011_CONSTRUCTION :{GOLD}Строительство STR_7012_NEW_VEHICLES :{GOLD}Новая техника @@ -2133,22 +2134,22 @@ STR_7028 :{BLACK}{CURRENCY64} STR_7029_BORROW :{BLACK}Занять {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY} STR_702A_REPAY :{BLACK}Отдать {SKIP}{SKIP}{SKIP}{SKIP}{CURRENCY} -STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...максимально допустимый размер ссуды {CURRENCY} +STR_702B_MAXIMUM_PERMITTED_LOAN :{WHITE}...максимально допустимый размер ссуды - {CURRENCY}. STR_702C_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}Невозможно занять больше денег... STR_702D_LOAN_ALREADY_REPAYED :{WHITE}...нет ссуды для выплачивания STR_702E_REQUIRED :{WHITE}...{CURRENCY} надо STR_702F_CAN_T_REPAY_LOAN :{WHITE}Невозможно погасить ссуду... STR_INSUFFICIENT_FUNDS :{WHITE}Невозможно отдать ссуженные банком деньги... -STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Выбрать новое лицо управляющего +STR_7030_SELECT_NEW_FACE_FOR_PRESIDENT :{BLACK}Выбрать новое лицо директора STR_7031_CHANGE_THE_COMPANY_VEHICLE :{BLACK}Изменить цвет транспортных средств компании -STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Изменение имени управляющего +STR_7032_CHANGE_THE_PRESIDENT_S :{BLACK}Изменение имени директора STR_7033_CHANGE_THE_COMPANY_NAME :{BLACK}Изменение названия компании STR_7034_CLICK_ON_SELECTED_NEW_COLOR :{BLACK}Выберите цветовую схему STR_7035_INCREASE_SIZE_OF_LOAN :{BLACK}Взять/увеличить кредит STR_7036_REPAY_PART_OF_LOAN :{BLACK}Вернуть часть ссуды -STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Управляющий) +STR_7037_PRESIDENT :{WHITE}{PLAYERNAME}{}{GOLD}(Директор) STR_7038_INAUGURATED :{GOLD}В должности с: {WHITE}{NUM} -STR_7039_VEHICLES :{GOLD}Транспорта: +STR_7039_VEHICLES :{GOLD}Транспорт: STR_TRAINS :{WHITE}{COMMA} поезд{P "" а ов} STR_ROAD_VEHICLES :{WHITE}{COMMA} автомашин{P а ы ""} STR_AIRCRAFT :{WHITE}{COMMA} авиатранспорт @@ -2175,7 +2176,7 @@ STR_7055 :{YELLOW}{STRING}{SETX 45}{ORANGE}{COMPANY} {BLACK}{PLAYERNAME} '{STRING}' STR_7056_TRANSPORT_COMPANY_IN_TROUBLE :{BLACK}{BIGFONT}Транспортная компания в опасном положении! STR_7057_WILL_BE_SOLD_OFF_OR_DECLARED :{BLACK}{BIGFONT} {COMPANY} будет продана или объявлена банкротом, если ситуация не изменится! -STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Управляющий) +STR_7058_PRESIDENT :{BLACK}{PLAYERNAME}{}(Директор) STR_7059_TRANSPORT_COMPANY_MERGER :{BLACK}{BIGFONT}Объединение компаний! STR_705A_HAS_BEEN_SOLD_TO_FOR :{BLACK}{BIGFONT}{COMPANY} продана {COMPANY} за {CURRENCY}! STR_705B_WE_ARE_LOOKING_FOR_A_TRANSPORT :{WHITE}Мы ищем транспортную компанию для присоединения к ней.{}{}Вы хотите купить {COMPANY} за {CURRENCY}? @@ -2198,12 +2199,12 @@ STR_706C_CHAIRMAN :Председатель STR_706D_PRESIDENT :Президент STR_706E_TYCOON :Магнат -STR_706F_BUILD_HQ :{BLACK}Построить штаб-квартиру -STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Построить/просмотреть штаб-квартиру компании -STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Перестроить штаб компании в другом месте за 1% оценочной стоимости капитала компании +STR_706F_BUILD_HQ :{BLACK}Построить штаб +STR_7070_BUILD_COMPANY_HEADQUARTERS :{BLACK}Построить штаб-квартиру компании / Осмотреть штаб-квартиру компании +STR_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Переместить штаб компании в другом месте за 1% оценочной стоимости капитала компании STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Невозможно построить штаб-квартиру компании... -STR_7072_VIEW_HQ :{BLACK}Посмотреть штаб -STR_RELOCATE_HQ :{BLACK}Переместить штаб +STR_7072_VIEW_HQ :{BLACK}Осмотреть штаб +STR_RELOCATE_HQ :{BLACK}Переместить STR_COMPANY_PASSWORD :{BLACK}Пароль STR_COMPANY_PASSWORD_TOOLTIP :{BLACK}Защитить вашу компанию паролем, чтобы неавторизованные пользователи не могли присоединиться STR_SET_COMPANY_PASSWORD :Установить пароль компании @@ -2230,9 +2231,9 @@ STR_LIVERY_MAGLEV :Маглев STR_LIVERY_DMU :DMU STR_LIVERY_EMU :EMU -STR_LIVERY_PASSENGER_WAGON_STEAM :Пассажирский вагон (паровоз) -STR_LIVERY_PASSENGER_WAGON_DIESEL :Пассажирский вагон (дизель) -STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Пассажирский вагон (электро) +STR_LIVERY_PASSENGER_WAGON_STEAM :Пассаж. вагон (паровоз) +STR_LIVERY_PASSENGER_WAGON_DIESEL :Пассаж. вагон (дизель) +STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Пассаж. вагон (электро) STR_LIVERY_FREIGHT_WAGON :Грузовой вагон STR_LIVERY_BUS :Автобус STR_LIVERY_TRUCK :Грузовое авто @@ -2242,13 +2243,13 @@ STR_LIVERY_SMALL_PLANE :Малый самолет STR_LIVERY_LARGE_PLANE :Большой самолет -STR_LIVERY_GENERAL_TIP :{BLACK}Показ. основную цветовую схему -STR_LIVERY_TRAIN_TIP :{BLACK}Показ. цветовую схему поездов -STR_LIVERY_ROADVEH_TIP :{BLACK}Показ. цветовую схему авто -STR_LIVERY_SHIP_TIP :{BLACK}Показ. цветовую схему судов -STR_LIVERY_AIRCRAFT_TIP :{BLACK}Показ. цветовую схему авиатранспорта -STR_LIVERY_PRIMARY_TIP :{BLACK}Выберите основной цвет для данной схемы -STR_LIVERY_SECONDARY_TIP :{BLACK}Выберите вторичный цвет для данной схемы +STR_LIVERY_GENERAL_TIP :{BLACK}Настройка основной цветовой схемы +STR_LIVERY_TRAIN_TIP :{BLACK}Настройка цветовой схемы поездов +STR_LIVERY_ROADVEH_TIP :{BLACK}Настройка цветовой схемы автотранспорта +STR_LIVERY_SHIP_TIP :{BLACK}Настройка цветовой схемы судов +STR_LIVERY_AIRCRAFT_TIP :{BLACK}Настройка цветовой схемы авиатранспорта +STR_LIVERY_PRIMARY_TIP :{BLACK}Настройка основного цвета +STR_LIVERY_SECONDARY_TIP :{BLACK}Настройка вторичного цвета STR_LIVERY_PANEL_TIP :{BLACK}Выберите цветовую схему для изменения, либо несколько схем с CTRL. Кликните на чекбокс для использования выбранной схемы. ##id 0x8000 @@ -2511,35 +2512,35 @@ STR_8100_MESSAGE_FROM_VEHICLE_MANUFACTURE :{WHITE}Сообщение от производителя транспорта STR_8101_WE_HAVE_JUST_DESIGNED_A :{GOLD}Мы создали новую модель: {STRING}. Заинтересованы ли вы в его годовом эксклюзивном использовании для проверки перед запуском в серийное производство? STR_8102_RAILROAD_LOCOMOTIVE :ж/д локомотив -STR_8103_ROAD_VEHICLE :автомобиль -STR_8104_AIRCRAFT :воздушное судно +STR_8103_ROAD_VEHICLE :автотранспорт +STR_8104_AIRCRAFT :авиатранспорт STR_8105_SHIP :корабль -STR_8106_MONORAIL_LOCOMOTIVE :монорельс -STR_8107_MAGLEV_LOCOMOTIVE :магниторельс +STR_8106_MONORAIL_LOCOMOTIVE :монорельсовый локомотив +STR_8107_MAGLEV_LOCOMOTIVE :магниторельсовый локомотив ##id 0x8800 STR_8800_TRAIN_DEPOT :{WHITE}Депо {TOWN} -STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый поезд прибыл на станцию {STATION}! +STR_8801_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют!{}Первый поезд прибыл на станцию {STATION}! STR_8802_DETAILS :{WHITE}{STRING} (Детали) -STR_8803_TRAIN_IN_THE_WAY :{WHITE}Впереди поезд +STR_8803_TRAIN_IN_THE_WAY :{WHITE}Поезд мешает STR_8804 :{SETX 10}{COMMA}: {STRING} {STRING} STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING} {STRING} STR_8806_GO_TO :Ехать к ст. {STATION} -STR_8807_GO_TO_TRANSFER :Ехать к ст. {STATION} (Отдать и забрать груз) -STR_8808_GO_TO_UNLOAD :Ехать к ст. {STATION} (Разгрузка) -STR_8809_GO_TO_TRANSFER_UNLOAD :Ехать к ст. {STATION} (Разгрузиться и уехать пустым) -STR_880A_GO_TO_LOAD :Ехать к ст. {STATION} (Загрузиться) -STR_880B_GO_TO_TRANSFER_LOAD :Ехать к ст. {STATION} (Отдать и ждать полной загрузки) -STR_880C_GO_NON_STOP_TO :Ехать без ост. на {STATION} -STR_880D_GO_TO_NON_STOP_TRANSFER :Ехать без ост. на {STATION} (Отдать и забрать груз) -STR_880E_GO_NON_STOP_TO_UNLOAD :Ехать без ост. на {STATION} (Разгрузка) -STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ехать без ост. на {STATION} (Разгрузиться и уехать пустым) -STR_8810_GO_NON_STOP_TO_LOAD :Ехать без ост. на {STATION} (Загрузиться) -STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ехать без ост. на {STATION} (Отдать и ждать полной загрузки) +STR_8807_GO_TO_TRANSFER :Ехать к ст. {STATION} (Трансфер) +STR_8808_GO_TO_UNLOAD :Ехать к ст. {STATION} (Не грузиться) +STR_8809_GO_TO_TRANSFER_UNLOAD :Ехать к ст. {STATION} (Трансфер и не грузиться) +STR_880A_GO_TO_LOAD :Ехать к ст. {STATION} (Полная загрузка) +STR_880B_GO_TO_TRANSFER_LOAD :Ехать к ст. {STATION} (Трансфер и полная загрузка) +STR_880C_GO_NON_STOP_TO :Ехать к ст. {STATION} без остановки +STR_880D_GO_TO_NON_STOP_TRANSFER :Ехать к ст. {STATION} без остановки (Трансфер) +STR_880E_GO_NON_STOP_TO_UNLOAD :Ехать к ст. {STATION} без остановки (Не грузиться) +STR_880F_GO_TO_NON_STOP_TRANSFER_UNLOAD :Ехать к ст. {STATION} без остановки (Трансфер и не грузиться) +STR_8810_GO_NON_STOP_TO_LOAD :Ехать к ст. {STATION} без остановки (Полная загрузка) +STR_8811_GO_TO_NON_STOP_TRANSFER_LOAD :Ехать к ст. {STATION} без остановки (Трансфер и полная загрузка) STR_GO_TO_TRAIN_DEPOT :Ехать в депо {TOWN} -STR_SERVICE_AT_TRAIN_DEPOT :Обслуж. в депо {TOWN} -STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ехать без ост. в Депо {TOWN} -STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Обслуж. без ост. в депо {TOWN} +STR_SERVICE_AT_TRAIN_DEPOT :Обслужиться в депо {TOWN} +STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT :Ехать в депо {TOWN} без остановки +STR_SERVICE_NON_STOP_AT_TRAIN_DEPOT :Обслужиться в депо {TOWN} без остановки STR_HEADING_FOR_TRAIN_DEPOT :{ORANGE}Следует в депо {TOWN} STR_HEADING_FOR_TRAIN_DEPOT_VEL :{ORANGE}Следует в Депо {TOWN}, {VELOCITY} @@ -2557,7 +2558,7 @@ STR_8816 :{BLACK}- STR_8819_TRAIN_TOO_LONG :{WHITE}Поезд слишком длинный STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Структуру поезда можно менять только в депо -STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Поезда +STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Поезд{P 2 "" а ов} STR_881C_NEW_RAIL_VEHICLES :{WHITE}Новый поезд STR_NEW_ELRAIL_VEHICLES :{WHITE}Новый электропоезд @@ -2566,7 +2567,7 @@ STR_ALL_AVAIL_RAIL_VEHICLES :{WHITE}Поезда STR_881F_BUILD_VEHICLE :{BLACK}Построить -STR_CLONE_ROAD_VEHICLE :{BLACK}Копировать транспорт +STR_CLONE_ROAD_VEHICLE :{BLACK}Копировать STR_CLONE_ROAD_VEHICLE_INFO :{BLACK}Создает копию автомобиля. Control-щелчок копирует задания STR_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Создает копию автомобиля. Щелкнуть на кнопке и затем на машине внутри или снаружи гаража. Control-щелчок копирует и задания STR_CLONE_TRAIN :{BLACK}Копировать состав @@ -2575,17 +2576,17 @@ STR_8820_RENAME :{BLACK}Переимен. STR_8823_SKIP :{BLACK}Пропуск STR_8824_DELETE :{BLACK}Удалить -STR_8825_NON_STOP :{BLACK}Б/останов. +STR_8825_NON_STOP :{BLACK}Без ост. STR_8826_GO_TO :{BLACK}Ехать -STR_8827_FULL_LOAD :{BLACK}Загрузка -STR_8828_UNLOAD :{BLACK}Разгрузка -STR_REFIT :{BLACK}Переоборуд. +STR_8827_FULL_LOAD :{BLACK}Полный +STR_8828_UNLOAD :{BLACK}Без груза +STR_REFIT :{BLACK}Переоб. STR_REFIT_TIP :{BLACK}Выберите тип грузов для переоборудования. CTRL+клик - для удаления. STR_REFIT_ORDER :(Переоборуд. для {STRING}) STR_8829_ORDERS :{WHITE}{VEHICLE} (Задания) -STR_882A_END_OF_ORDERS :{SETX 10}- - Конец списка заданий - - +STR_882A_END_OF_ORDERS :{SETX 10}- - Конец заданий - - STR_FULLLOAD_OR_SERVICE :{SKIP}{SKIP}{STRING} -STR_SERVICE :{BLACK}Обслуживание +STR_SERVICE :{BLACK}Обслуж. STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE :{WHITE}Невозможно построить ж/д транспорт... STR_882C_BUILT_VALUE :{LTBLUE}{STRING}{BLACK} Построен: {LTBLUE}{NUM}{BLACK} Стоимость: {LTBLUE}{CURRENCY} STR_882D_VALUE :{LTBLUE}{STRING}{BLACK} Стоимость: {LTBLUE}{CURRENCY} @@ -2600,7 +2601,7 @@ STR_8835_CAN_T_MODIFY_THIS_ORDER :{WHITE}Невозможно изменить это задание... STR_8837_CAN_T_MOVE_VEHICLE :{WHITE}Невозможно переместить трансп. средство... STR_REAR_ENGINE_FOLLOW_FRONT_ERROR :{WHITE}Тыловой локомотив всегда следует за его передней частью -STR_8838_N_A :недоступно{SKIP} +STR_8838_N_A :отсутствует{SKIP} STR_8839_CAN_T_SELL_RAILROAD_VEHICLE :{WHITE}Невозможно продать рельсовый транспорт... STR_883A_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Невозможно найти дорогу к депо STR_883B_CAN_T_STOP_START_TRAIN :{WHITE}Невозможно остановить/запустить поезд... @@ -2628,19 +2629,19 @@ STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES :{BLACK}Показать сведения о вагонах STR_8851_SHOW_CAPACITIES_OF_EACH :{BLACK}Показать вместимость вагонов STR_8852_SHOW_TOTAL_CARGO :{BLACK}Показать общую вместимость поезда по типам грузов -STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Показать список заданий - кликните для выделения. CTRL+клик - переход к станции. +STR_8852_ORDERS_LIST_CLICK_ON_ORDER :{BLACK}Показ списка заданий - щелкните для выделения. Если зажать CTRL - обзор станции. STR_8853_SKIP_THE_CURRENT_ORDER :{BLACK}Пропустить текущее задание и перейти к следующему STR_8854_DELETE_THE_HIGHLIGHTED :{BLACK}Удалить выделенное задание STR_8855_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Ехать по выбранному заданию без остановок -STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Вставить новое задание перед выделенным или в конец списка +STR_8856_INSERT_A_NEW_ORDER_BEFORE :{BLACK}Вставить новое задание перед выделенным, или в конец списка STR_8857_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Задать ожидание полной загрузки STR_8858_MAKE_THE_HIGHLIGHTED_ORDER :{BLACK}Задать ожидание полной разгрузки STR_SERVICE_HINT :{BLACK}Пропустить это задание, если обслуживание не требуется STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Цена: {CURRENCY} Вес: {WEIGHT_S}{}Скорость: {VELOCITY} Мощность: {POWER}{}Цена обслуж.: {CURRENCY}/год{}Емкость: {CARGO} STR_885C_BROKEN_DOWN :{RED}Поломка STR_885D_AGE_RUNNING_COST_YR :{BLACK}Возраст: {LTBLUE}{STRING}{BLACK} Стоимость обслуживания: {LTBLUE}{CURRENCY}/год -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Вес: {LTBLUE}{WEIGHT_S} {BLACK}Мощность: {LTBLUE}{POWER}{BLACK} Макс. скорость: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Вес: {LTBLUE}{WEIGHT_S} {BLACK}Мощность: {LTBLUE}{POWER}{BLACK} Макс. скорость: {LTBLUE}{VELOCITY} {BLACK}Макс. Тяговое Усилие: {LTBLUE}{FORCE} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Вес: {LTBLUE}{WEIGHT_S} {BLACK}Мощность: {LTBLUE}{POWER}{BLACK} Макс. скорость: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Вес: {LTBLUE}{WEIGHT_S} {BLACK}Мощн.: {LTBLUE}{POWER}{BLACK} Макс. ск.: {LTBLUE}{VELOCITY} {BLACK}Макс. ТУ: {LTBLUE}{FORCE} STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в этом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY}) STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Надежность: {LTBLUE}{COMMA}% {BLACK}Поломок с последнего ремонта: {LTBLUE}{COMMA} STR_8861_STOPPED :{RED}Остановлен @@ -2650,7 +2651,7 @@ STR_8865_NAME_TRAIN :{WHITE}Назвать поезд STR_8866_CAN_T_NAME_TRAIN :{WHITE}Невозможно назвать поезд... STR_8867_NAME_TRAIN :{BLACK}Назвать поезд -STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Крушение поезда!{}{COMMA} чел. погибло в огне! +STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Крушение поезда!{}{COMMA} человек{P "" а ""} погиб{P "" ло ли} в огне! STR_8869_CAN_T_REVERSE_DIRECTION :{WHITE}Невозможно развернуть поезд... STR_886A_RENAME_TRAIN_VEHICLE_TYPE :{WHITE}Переименовать тип вагона STR_886B_CAN_T_RENAME_TRAIN_VEHICLE :{WHITE}Невозможно переименовать тип вагона ... @@ -2659,7 +2660,7 @@ STR_TRAIN_STOPPING :{RED}Остановлен STR_TRAIN_STOPPING_VEL :{RED}Останавливаю, {VELOCITY} -STR_INCOMPATIBLE_RAIL_TYPES :IНесовместимый тип рельсов +STR_INCOMPATIBLE_RAIL_TYPES :IНесовместимый тип рельс STR_TRAIN_NO_POWER :{RED}Нет тока. STR_TRAIN_START_NO_CATENARY :Кто-то украл все провода, поезд не может ехать... @@ -2669,9 +2670,9 @@ ##id 0x9000 STR_9000_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Машина на пути -STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Автомашин{P а ы ""} +STR_9001_ROAD_VEHICLES :{WHITE}{COMPANY} - {COMMA} Автомашин{P 2 а ы ""} STR_9002 :{WHITE}{VEHICLE} -STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}{TOWN} Гараж +STR_9003_ROAD_VEHICLE_DEPOT :{WHITE}Гараж {TOWN} STR_9004_NEW_VEHICLES :{BLACK}Новая машина STR_9006_NEW_ROAD_VEHICLES :{WHITE}Новая машина STR_9007_BUILD_VEHICLE :{BLACK}Построить @@ -2705,42 +2706,42 @@ STR_9023_BUILD_NEW_ROAD_VEHICLE :{BLACK}Построить новый автомобиль STR_9024_DRAG_ROAD_VEHICLE_TO_HERE :{BLACK}Перетащите автомобиль сюда, чтобы продать его STR_9025_CENTER_MAIN_VIEW_ON_ROAD :{BLACK}Показать гараж в главном окне -STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Список автомобилей - кликните для получения информации +STR_9026_ROAD_VEHICLE_SELECTION :{BLACK}Список автотранспорта - кликните для получения информации STR_9027_BUILD_THE_HIGHLIGHTED_ROAD :{BLACK}Построить выделенный автомобиль -STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Цена: {CURRENCY}{}Скорость: {VELOCITY}{}Стоимость обслуж.: {CURRENCY}/год{}Емкость: {CARGO} +STR_902A_COST_SPEED_RUNNING_COST :{BLACK}Цена: {CURRENCY}{}Скорость: {VELOCITY}{}Стоимость обслуживания: {CURRENCY}/год{}Емкость: {CARGO} -STR_902C_NAME_ROAD_VEHICLE :{WHITE}Назвать автомобиль -STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Невозможно переименовать автомобиль ... -STR_902E_NAME_ROAD_VEHICLE :{BLACK}Назвать автомобиль -STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый автобус прибыл на остановку {STATION}! -STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый грузовик прибыл на станцию {STATION}! +STR_902C_NAME_ROAD_VEHICLE :{WHITE}Назвать автотранспорт +STR_902D_CAN_T_NAME_ROAD_VEHICLE :{WHITE}Невозможно переименовать автотранспорт ... +STR_902E_NAME_ROAD_VEHICLE :{BLACK}Назвать автотранспорт +STR_902F_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют!{}Первый автобус прибыл на остановку {STATION}! +STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют!{}Первый грузовик прибыл на станцию {STATION}! STR_9031_ROAD_VEHICLE_CRASH_DRIVER :{BLACK}{BIGFONT}АВАРИЯ!{}Водитель погиб при столкновении с поездом -STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}АВАРИЯ!{}{COMMA} человек погибло в столкновении с поездом -STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Невозможно развернуть автомобиль ... +STR_9032_ROAD_VEHICLE_CRASH_DIE :{BLACK}{BIGFONT}АВАРИЯ!{}{COMMA} человек{P "" а ""} погиб{P "" ло ли} в столкновении с поездом! +STR_9033_CAN_T_MAKE_VEHICLE_TURN :{WHITE}Невозможно развернуть автомобиль... STR_ONLY_TURN_SINGLE_UNIT :{WHITE}Невозможно развернуть многосоставной транспорт STR_9034_RENAME :{BLACK}Переимен. STR_9035_RENAME_ROAD_VEHICLE_TYPE :{BLACK}Переименовать автомобиль STR_9036_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Переименовать автомобиль -STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Невозможно переименовать автомобиль ... +STR_9037_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Невозможно переименовать автомобиль... STR_9038_GO_TO_ROADVEH_DEPOT :Ехать в гараж {TOWN} STR_SERVICE_AT_ROADVEH_DEPOT :Обслуж. в гараже {TOWN} STR_REFIT_ROAD_VEHICLE_TO_CARRY :{BLACK}Переоборуд. авто для доставки разных видов грузов. STR_REFIT_ROAD_VEHICLE :{BLACK}Переоборуд. авто STR_REFIT_ROAD_VEHICLE_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборуд авто для перевозки доступных видов грузов -STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Невозможно переоборуд. авто... +STR_REFIT_ROAD_VEHICLE_CAN_T :{WHITE}Невозможно переоборудовать авто... STR_ROAD_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выберите тип грузов для перевозки ##id 0x9800 -STR_9800_DOCK_CONSTRUCTION :Строительство РЕКА-МОРЕ -STR_9801_DOCK_CONSTRUCTION :{WHITE}Строительство РЕКА-МОРЕ +STR_9800_DOCK_CONSTRUCTION :Морские коммуникации +STR_9801_DOCK_CONSTRUCTION :{WHITE}Морские коммуникации STR_9802_CAN_T_BUILD_DOCK_HERE :{WHITE}Невозможно построить пристань здесь... -STR_9803_SHIP_DEPOT :{WHITE}{TOWN} ДОК -STR_9804_NEW_SHIPS :{BLACK}Новые корабли -STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Корабли -STR_9808_NEW_SHIPS :{WHITE}Новые корабли -STR_9809_BUILD_SHIP :{BLACK}Купить Корабль -STR_CLONE_SHIP :{BLACK}Копировать Судно +STR_9803_SHIP_DEPOT :{WHITE}Док {TOWN} +STR_9804_NEW_SHIPS :{BLACK}Новое судно +STR_9805_SHIPS :{WHITE}{COMPANY} - {COMMA} Корабл{P 2 ь я ей} +STR_9808_NEW_SHIPS :{WHITE}Покупка кораблей +STR_9809_BUILD_SHIP :{BLACK}Купить +STR_CLONE_SHIP :{BLACK}Копировать судно STR_CLONE_SHIP_INFO :{BLACK}Создает копию корабля. Control-клик копирует задания STR_CLONE_SHIP_DEPOT_INFO :{BLACK}Создает копию корабля. Щелкнуть на кнопке и затем на корабле внутри или снаружи дока. Control-клик копирует задания STR_980B_SHIP_MUST_BE_STOPPED_IN :{WHITE}Корабль должен быть остановлен в доке @@ -2749,7 +2750,7 @@ STR_980E_SHIP_IN_THE_WAY :{WHITE}Корабль на пути STR_980F :{WHITE}{VEHICLE} STR_9811_DETAILS :{WHITE}{VEHICLE} (Детали) -STR_9812_AGE_RUNNING_COST_YR :{BLACK}Возраст: {LTBLUE}{STRING}{BLACK} Стоимость обслуж.: {LTBLUE}{CURRENCY}/год +STR_9812_AGE_RUNNING_COST_YR :{BLACK}Возраст: {LTBLUE}{STRING}{BLACK} Стоимость обслуживания: {LTBLUE}{CURRENCY}/год STR_9813_MAX_SPEED :{BLACK}Макс. скорость: {LTBLUE}{VELOCITY} STR_9814_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в этом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY}) STR_9815_RELIABILITY_BREAKDOWNS :{BLACK}Надежность: {LTBLUE}{COMMA}% {BLACK}Поломок с последнего обслуж.: {LTBLUE}{COMMA} @@ -2778,13 +2779,13 @@ STR_9829_CENTER_MAIN_VIEW_ON_SHIP :{BLACK}Показать корабль в главном окне STR_982A_SEND_SHIP_TO_DEPOT :{BLACK}Отправить корабль в док. CTRL+клик - только для обслуживания STR_982B_SHOW_SHIP_DETAILS :{BLACK}Показать информацию о корабле -STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} Макс. Скорость: {VELOCITY}{}Емкость: {CARGO}{}Стоимость обслуж.: {CURRENCY}/год +STR_982E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} Макс. Скорость: {VELOCITY}{}Емкость: {CARGO}{}Стоимость обслуживания: {CURRENCY}/год STR_982F_NAME_SHIP :{BLACK}Название корабля STR_9831_NAME_SHIP :{WHITE}Название корабля STR_9832_CAN_T_NAME_SHIP :{WHITE}Не могу назвать корабль... -STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют . . .{}Первый корабль причалил к {STATION}! -STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Постройте буй, чтобы использовать его как точку маршрута +STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют!{}Первый корабль причалил к {STATION}! +STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Буй помогает в навигации, если дистанция большая, исользуйте его как точку маршрута STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Не могу построить буй здесь... STR_9836_RENAME :{BLACK}Переимен. STR_9837_RENAME_SHIP_TYPE :{BLACK}Переименовать @@ -2796,28 +2797,28 @@ STR_983D_SELECT_TYPE_OF_CARGO_FOR :{BLACK}Выберите тип груза для перевозки STR_983E_REFIT_SHIP_TO_CARRY_HIGHLIGHTED :{BLACK}Переоборудовать корабль для перевозки выбранного груза STR_983F_SELECT_CARGO_TYPE_TO_CARRY :{GOLD}Выберите тип груза для перевозки: -STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Новая емкость: {GOLD}{CARGO}{}{BLACK}Стоимость переоборуд.: {GOLD}{CURRENCY} -STR_9841_CAN_T_REFIT_SHIP :{WHITE}Не могу переоборуд. корабль...... -STR_9842_REFITTABLE :(переоборудование) +STR_9840_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Новая емкость: {GOLD}{CARGO}{}{BLACK}Стоимость переоборудования: {GOLD}{CURRENCY} +STR_9841_CAN_T_REFIT_SHIP :{WHITE}Не могу переоборудовать корабль...... +STR_9842_REFITTABLE :(переоб.) STR_GO_TO_SHIP_DEPOT :Плыть в Док {TOWN} SERVICE_AT_SHIP_DEPOT :Обслуживание в доке {TOWN} ##id 0xA000 STR_A000_AIRPORTS :{WHITE}Аэропорты STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Невозможно построить аэропорт здесь... -STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} Ангар -STR_A003_NEW_AIRCRAFT :{BLACK}Новый -STR_CLONE_AIRCRAFT :{BLACK}Копировать транспорт +STR_A002_AIRCRAFT_HANGAR :{WHITE}Ангар {STATION} +STR_A003_NEW_AIRCRAFT :{BLACK}Новое судно +STR_CLONE_AIRCRAFT :{BLACK}Копировать STR_CLONE_AIRCRAFT_INFO :{BLACK}Создает копию самолета. Control-клик - копирует задания STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Построить копию возд. судна. Нажмите на кнопку, а потом на возд. судно в/вне ангара. CTRL+click - также скопирует и задание. STR_A005_NEW_AIRCRAFT :{WHITE}Новый STR_A006_BUILD_AIRCRAFT :{BLACK}Построить STR_A008_CAN_T_BUILD_AIRCRAFT :{WHITE}Невозможно построить возд. транспорт... -STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Авиатранспорт +STR_A009_AIRCRAFT :{WHITE}{COMPANY} - {COMMA} Единиц{P 2 а ы ""} авиатранспорта STR_A00A :{WHITE}{VEHICLE} STR_A00B_ORDERS :{WHITE}{VEHICLE} (Задания) STR_A00C_DETAILS :{WHITE}{VEHICLE} (Детали) -STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Возраст: {LTBLUE}{STRING}{BLACK} Стоимость обслуж.: {LTBLUE}{CURRENCY}/год +STR_A00D_AGE_RUNNING_COST_YR :{BLACK}Возраст: {LTBLUE}{STRING}{BLACK} Стоимость обслуживания: {LTBLUE}{CURRENCY}/год STR_A00E_MAX_SPEED :{BLACK}Макс. скорость: {LTBLUE}{VELOCITY} STR_A00F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в этом году: {LTBLUE}{CURRENCY} (прошлый год: {CURRENCY}) STR_A010_RELIABILITY_BREAKDOWNS :{BLACK}Надежность: {LTBLUE}{COMMA}% {BLACK}Поломок с последнего ремонта: {LTBLUE}{COMMA} @@ -2850,14 +2851,14 @@ STR_A029_CENTER_MAIN_VIEW_ON_AIRCRAFT :{BLACK}Показать транспорт в главном окне STR_A02A_SEND_AIRCRAFT_TO_HANGAR :{BLACK}Послать авиатранспорт в ангар. CTRL+клик - только для обслуживания. STR_A02B_SHOW_AIRCRAFT_DETAILS :{BLACK}Показать сведения об авиатранспорте. -STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} Макс. Скорость: {VELOCITY}{}Емкость: {COMMA} пассажиров, {COMMA} почты{}Цена обслуж.: {CURRENCY}/год +STR_A02E_COST_MAX_SPEED_CAPACITY :{BLACK}Цена: {CURRENCY} Макс. Скорость: {VELOCITY}{}Емкость: {COMMA} пассажиров, {COMMA} почты{}Цена обслуживания: {CURRENCY}/год STR_A030_NAME_AIRCRAFT :{WHITE}Название самолета STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}Не могу назвать самолет... STR_A032_NAME_AIRCRAFT :{BLACK}Название самолета -STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют...{}Первый самолет прибыл в {STATION}! -STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Авиакатастрофа!{}{COMMA} человек погибло в огне в {STATION} -STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Авиакатастрофа{}В самолете закончилось топливо, {COMMA} человек погибли при столкновении с землей! +STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Жители празднуют!{}Первый самолет прибыл в {STATION}! +STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}Авиакатастрофа!{}{COMMA} человек{P "" а ""} погиб{P "" ло ли} в огне в {STATION}! +STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}Авиакатастрофа!{}В самолете закончилось топливо, {COMMA} человек{P "" а ""} погиб{P "" ло ли} при столкновении с землей! STR_A036 :{TINYFONT}{BLACK}{STATION} STR_A037_RENAME :{BLACK}Переимен. STR_A038_RENAME_AIRCRAFT_TYPE :{BLACK}Переименовать @@ -2881,13 +2882,13 @@ STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS :{BLACK}{BIGFONT}Взрыв завода при подозрительных обстоятельствах вблизи {TOWN}! STR_B004_UFO_LANDS_NEAR :{BLACK}{BIGFONT}НЛО приземлилось возле {TOWN}! STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Обвал на угольной шахте вызывает оползень около {TOWN}! -STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}НАВОДНЕНИЕ!{}По крайней мере {COMMA} скорее всего погибли при наводнении! +STR_B006_FLOOD_VEHICLE_DESTROYED :{BLACK}{BIGFONT}ПОТОП!{}{COMMA} человек{P "" а ""} погиб{P "" ло ли} при наводнении транспорта! STR_BRIBE_FAILED :{WHITE}Ваша попытка дать взятку была STR_BRIBE_FAILED_2 :{WHITE}обнаружена региональным следователем STR_BUILD_DATE :{BLACK}Построено: {LTBLUE}{DATE_LONG} -STR_PERFORMANCE_DETAIL :{WHITE}Подробные данные +STR_PERFORMANCE_DETAIL :{WHITE}Рейтинг в деталях STR_PERFORMANCE_DETAIL_KEY :{BLACK}Детали STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRCOMPACT}/{CURRCOMPACT}) STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA}) @@ -2925,7 +2926,7 @@ STR_NEWGRF_FILENAME :{BLACK}Имя файла: {SILVER}{STRING} STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING} STR_NEWGRF_MD5SUM :{BLACK}Сумма MD5: {SILVER}{STRING} -STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Вы хотите сделать изменения в уже запущенной игре - это может привести к сбоям и игровым несоответствиям.{}Вы абсолютно уверены в том, что хотите сделать? +STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Вы вносите изменения в загруженной карте - это может привести к нестабильности игры.{}{}Вы действительно хотите этого? STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} STR_NEWGRF_ERROR_MSG_WARNING :{RED}Внимание: {SILVER}{STRING} @@ -3019,20 +3020,20 @@ STR_VEHICLE_LIST_SHIP_DEPOT :{BLACK}{STRING} - {COMMA} корабл{P ь я ей} STR_VEHICLE_LIST_AIRCRAFT_DEPOT :{BLACK}{STRING} - {COMMA} авиатранспорт{P "" а ов} -STR_REPLACE_VEHICLES_WHITE :{WHITE}Заменить транспорт {STRING} -STR_REPLACE_VEHICLES_START :{BLACK}Начать замену транспорта -STR_REPLACE_VEHICLES_STOP :{BLACK}Остановить замену транспорта +STR_REPLACE_VEHICLES_WHITE :{WHITE}Замена {STRING.p} +STR_REPLACE_VEHICLES_START :{BLACK}Начать замену +STR_REPLACE_VEHICLES_STOP :{BLACK}Прекратить замену STR_NOT_REPLACING :{BLACK}Нет замены STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Транспорт не выбран STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Выбор типа транспорта для замены -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Выбор нового типа машин, который хотелось бы использовать вместо выбранного слева типа транспорта -STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Нажмите, чтобы прекратить замену локомотивов выбранного -STR_REPLACE_HELP_START_BUTTON :{BLACK}Нажмите для начала замены выбранного слева типа на выбранный справа тип -STR_REPLACE_HELP_RAILTYPE :{BLACK}Выберите тип пути, для которого вы хотите заменить локомотивы -STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показывает, на какой локомотив заменяется локомотив, выбранный слева. +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Выбор типа транспорта, на который следует заменить +STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Прекратить замену транспорта +STR_REPLACE_HELP_START_BUTTON :{BLACK}Начать замену выбранных типов транспорта +STR_REPLACE_HELP_RAILTYPE :{BLACK}Тип пути, на котором производить замену +STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}На какой танспорт происходит замена STR_REPLACE_HELP :{BLACK}Это позволяет заменять один тип локомотива другим, когда локомотивы выбранного типа заезжают в депо. -STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагона: {ORANGE}{SKIP}{STRING} -STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Разрешить при автозамене сохранять длину поездов удалением вагонов (начиная с головы поезда), если при автозамене локомотив увеличит длину поезда. +STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагонов: {ORANGE}{SKIP}{STRING} +STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Разрешить при автозамене сохранять длину поездов способом удаления вагонов (начиная с головы поезда), если при автозамене локомотива увеличится длина поезда. STR_REPLACE_ENGINE_WAGON_SELECT :{BLACK}Заменяем: {ORANGE}{SKIP}{SKIP}{STRING} STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}ЭКСПЕРИМЕНТАЛЬНО {}Переключение между окнами замены локомотивов и вагонов.{}Автозамена вагонов производится только в том случае, если совпадает тип перевозимых грузов. Эта проверка производится для каждого вагона во время автозамены. STR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Локомотив недоступен @@ -3057,16 +3058,16 @@ STR_MASS_START_LIST_TIP :{BLACK}Нажмите для запуска всего транспорта в списке STR_SHORT_DATE :{WHITE}{DATE_TINY} -STR_SIGN_LIST_CAPTION :{WHITE}Список меток - {COMMA} Метки +STR_SIGN_LIST_CAPTION :{WHITE}Список меток - {COMMA} Мет{P ка ки ок} STR_ORDER_REFIT_FAILED :{WHITE}Ошибка задания переоборудования {STRING} {COMMA} ############ Lists rail types -STR_RAIL_VEHICLES :ЖД Транспорт +STR_RAIL_VEHICLES :Поезда STR_ELRAIL_VEHICLES :Электропоезда -STR_MONORAIL_VEHICLES :Монорельсовый Транспорт -STR_MAGLEV_VEHICLES :Магнитный Транспорт +STR_MONORAIL_VEHICLES :Монорельсовые +STR_MAGLEV_VEHICLES :Магнитные ############ End of list of rail types @@ -3075,9 +3076,9 @@ STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Цена: {GOLD}{CURRENCY}{BLACK} Вес: {GOLD}{WEIGHT_S} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Скорость: {GOLD}{VELOCITY}{BLACK} Мощность: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Скорость: {GOLD}{VELOCITY} -STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Стоимость обслуж.: {GOLD}{CURRENCY}/год +STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Стоимость обслуживания: {GOLD}{CURRENCY}/год STR_PURCHASE_INFO_CAPACITY :{BLACK}Емкость: {GOLD}{CARGO} {STRING} -STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Разработано в: {GOLD}{NUM}{BLACK} Срок работы: {GOLD}{COMMA} лет +STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Разработано в: {GOLD}{NUM}{BLACK} Срок службы: {GOLD}{COMMA} лет STR_PURCHASE_INFO_RELIABILITY :{BLACK}Макс. надежность: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Цена: {GOLD}{CURRENCY} STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Вес: {GOLD}{WEIGHT_S} ({WEIGHT_S}) @@ -3087,16 +3088,16 @@ STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Переоборуд. для: {GOLD} STR_PURCHASE_INFO_ALL_TYPES :Всех типов грузов STR_PURCHASE_INFO_ALL_BUT :Все, кроме {GOLD} -STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. Тяговое Усилие: {GOLD}{FORCE} +STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. тяговое усилие: {GOLD}{FORCE} ########### String for New Landscape Generator STR_GENERATE :{WHITE}Создать -STR_RANDOM :{BLACK}Случайно -STR_RANDOM_HELP :{BLACK}Изменить случайный номер, используемый Генератором ландшафта. +STR_RANDOM :{BLACK}Изменить +STR_RANDOM_HELP :{BLACK}Изменить случайный номер, используемый генератором ландшафта STR_WORLD_GENERATION_CAPTION :{WHITE}Создание мира -STR_RANDOM_SEED :{BLACK}Случ. номер: -STR_RANDOM_SEED_HELP :{BLACK}Нажмите для ввода случайного номера +STR_RANDOM_SEED :{BLACK}Начальное число: +STR_RANDOM_SEED_HELP :{BLACK}Ландшафт генерируется псевдослучайно, число - опорная точка в последовательности случайных чисел. STR_LAND_GENERATOR :{BLACK}Генератор ландш.: STR_TREE_PLACER :{BLACK}Генератор лесов: STR_HEIGHTMAP_ROTATION :{BLACK}Поворот РЕЛЬЕФА: @@ -3126,11 +3127,11 @@ STR_WORLD_GENERATION :{BLACK}Создание мира STR_TREE_GENERATION :{BLACK}Высадка лесов STR_UNMOVABLE_GENERATION :{BLACK}Генерация недвижимости -STR_CLEARING_TILES :{BLACK}Время разбрасывать камни ... +STR_CLEARING_TILES :{BLACK}Расстановка декораций и камней STR_SETTINGUP_GAME :{BLACK}Настройка STR_PREPARING_TILELOOP :{BLACK}Выполняем цикл STR_PREPARING_GAME :{BLACK}Подготовка игры -STR_DIFFICULTY_TO_CUSTOM :{WHITE}Здесь можно изменить уровень сложности +STR_DIFFICULTY_TO_CUSTOM :{WHITE}Ваши действия сменили уровень сложности на пользовательский STR_SE_FLAT_WORLD :{WHITE}Ровная земля STR_SE_FLAT_WORLD_TIP :{BLACK}Создать ровную землю STR_SE_RANDOM_LAND :{WHITE}Случайная земля @@ -3145,20 +3146,20 @@ STR_SMALLMAP_CENTER :{BLACK}Центрировать миникарту по этой позиции ########### String for new airports -STR_SMALL_AIRPORT :{BLACK}Малый аэропорт -STR_CITY_AIRPORT :{BLACK}Городской аэропорт -STR_METRO_AIRPORT :{BLACK}Федеральный аэропорт -STR_INTERNATIONAL_AIRPORT :{BLACK}Международный аэропорт -STR_COMMUTER_AIRPORT :{BLACK}Пригородный аэропорт -STR_INTERCONTINENTAL_AIRPORT :{BLACK}Межконтинентальный аэропорт -STR_HELIPORT :{BLACK}Вертопорт -STR_HELIDEPOT :{BLACK}ВертоДепо -STR_HELISTATION :{BLACK}Вертостанция +STR_SMALL_AIRPORT :{BLACK}Малый +STR_CITY_AIRPORT :{BLACK}Городской +STR_METRO_AIRPORT :{BLACK}Федеральный +STR_INTERNATIONAL_AIRPORT :{BLACK}Международный +STR_COMMUTER_AIRPORT :{BLACK}Пригородный +STR_INTERCONTINENTAL_AIRPORT :{BLACK}Межконтинентальный +STR_HELIPORT :{BLACK}Вертолётная площадка +STR_HELIDEPOT :{BLACK}Вертолётное депо +STR_HELISTATION :{BLACK}Вертолётная станция STR_SMALL_AIRPORTS :{BLACK}Малые аэропорты STR_LARGE_AIRPORTS :{BLACK}Большие аэропорты STR_HUB_AIRPORTS :{BLACK}Базовые аэропорты -STR_HELIPORTS :{BLACK}Вертопорты +STR_HELIPORTS :{BLACK}Вертолётные площадки ############ Tooltip measurment @@ -3178,7 +3179,7 @@ STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD :{WHITE}...эта дорога принадлежит городу STR_DRIVE_THROUGH_ERROR_DIRECTION :{WHITE}...дорога неправильного направления -STR_TRANSPARENCY_TOOLB :{WHITE}Настройки прозрачности. +STR_TRANSPARENCY_TOOLB :{WHITE}Настройки прозрачности STR_TRANSPARENT_SIGNS_DESC :{BLACK}Переключить прозрачность значков станций. STR_TRANSPARENT_TREES_DESC :{BLACK}Переключить прозрачность деревьев. STR_TRANSPARENT_HOUSES_DESC :{BLACK}Переключить прозрачность зданий. diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/simplified_chinese.txt --- a/src/lang/simplified_chinese.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/simplified_chinese.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1144,6 +1144,7 @@ STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :非常快 STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}城镇发展为城市的比例:{ORANGE}1 / {STRING} STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}城镇发展为城市的比例:{ORANGE}无 +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}初始城市规模因子:{ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}界面 STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}建设 @@ -3166,3 +3167,9 @@ STR_TRANSPARENCY_TOOLB :{WHITE}透明选项 STR_TRANSPARENT_SIGNS_DESC :{BLACK}调整站牌的透明度 +STR_TRANSPARENT_TREES_DESC :{BLACK}调节树木透明度 +STR_TRANSPARENT_HOUSES_DESC :{BLACK}调节建筑透明度 +STR_TRANSPARENT_INDUSTRIES_DESC :{BLACK}调节工业设施透明度 +STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}调节车站、码头及路点等的透明度 +STR_TRANSPARENT_BRIDGES_DESC :{BLACK}调节桥梁的透明度 +STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}调节灯塔及信号发射塔的透明度 diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/slovak.txt --- a/src/lang/slovak.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/slovak.txt Wed Jun 13 11:45:14 2007 +0000 @@ -602,36 +602,36 @@ STR_01D3_SOUND_MUSIC :Zvuk/Hudba STR_01D4_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Zobraz okno zvuku a hudby STR_01D5_ALL :{TINYFONT}Všetko -STR_01D6_OLD_STYLE :{TINYFONT}Stary styl -STR_01D7_NEW_STYLE :{TINYFONT}Novy styl +STR_01D6_OLD_STYLE :{TINYFONT}Starý štýl +STR_01D7_NEW_STYLE :{TINYFONT}Nový štýl STR_01D8_EZY_STREET :{TINYFONT}Ezy Street -STR_01D9_CUSTOM_1 :{TINYFONT}Vlastne 1 -STR_01DA_CUSTOM_2 :{TINYFONT}Vlastne 2 +STR_01D9_CUSTOM_1 :{TINYFONT}Vlastné 1 +STR_01DA_CUSTOM_2 :{TINYFONT}Vlastné 2 STR_01DB_MUSIC_VOLUME :{BLACK}{TINYFONT}Hlasitost hudby STR_01DC_EFFECTS_VOLUME :{BLACK}{TINYFONT}Hlasitost zvuk. efektov STR_01DD_MIN_MAX :{BLACK}{TINYFONT}MIN ' ' ' ' ' ' MAX -STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Predchadzajuca stopa -STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Nasledujuca stopa -STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zastavit prehravanie hudby -STR_01E1_START_PLAYING_MUSIC :{BLACK}Spustit prehravanie hudby -STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Tahat posuvace pre zmenu hlasitosti +STR_01DE_SKIP_TO_PREVIOUS_TRACK :{BLACK}Predchádzajúca stopa +STR_01DF_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Nasledujúca stopa +STR_01E0_STOP_PLAYING_MUSIC :{BLACK}Zastavit prehrávanie hudby +STR_01E1_START_PLAYING_MUSIC :{BLACK}Spustit prehrávanie hudby +STR_01E2_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Tahat posúvace pre zmenu hlasitosti STR_01E3 :{DKGREEN}{TINYFONT}-- STR_01E4_0 :{DKGREEN}{TINYFONT}0{COMMA} STR_01E5 :{DKGREEN}{TINYFONT}{COMMA} STR_01E6 :{DKGREEN}{TINYFONT}------ STR_01E7 :{DKGREEN}{TINYFONT}"{STRING}" STR_01E8_TRACK_XTITLE :{BLACK}{TINYFONT}Stopa{SETX 88}Title -STR_01E9_SHUFFLE :{TINYFONT}Nahodne +STR_01E9_SHUFFLE :{TINYFONT}Náhodne STR_01EA_PROGRAM :{TINYFONT}{BLACK}Program -STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Vyber hudobneho programu +STR_01EB_MUSIC_PROGRAM_SELECTION :{WHITE}Výber hudobného programu STR_01EC_0 :{TINYFONT}{LTBLUE}0{COMMA} "{STRING}" STR_01ED :{TINYFONT}{LTBLUE}{COMMA} "{STRING}" -STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Cislo stopy +STR_01EE_TRACK_INDEX :{TINYFONT}{BLACK}Císlo stopy STR_01EF_PROGRAM :{TINYFONT}{BLACK}Program - '{STRING}' STR_01F0_CLEAR :{TINYFONT}{BLACK}Zmazat -STR_01F1_SAVE :{TINYFONT}{BLACK}Ulozit -STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Aktualny program -STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Vybrat 'Vsetko' +STR_01F1_SAVE :{TINYFONT}{BLACK}Uložit +STR_01F2_CURRENT_PROGRAM_OF_MUSIC :{BLACK}Aktuálny program +STR_01F3_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Vybrat 'Všetko' STR_01F4_SELECT_OLD_STYLE_MUSIC :{BLACK}Vybrat 'Stary styl' STR_01F5_SELECT_NEW_STYLE_MUSIC :{BLACK}Vybrat 'Novy styl' STR_01F6_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Vybrat 'Vlastny 1' (uzivatelom definovany) program @@ -1161,6 +1161,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Posúvat mapu STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Vypnuté STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Rychlost posúvania mapy: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automaticka pauza pri štarte novej hry: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Použit vylepšený zoznam vozidiel: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Maximalny pocet vlakov hraca: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Maximalny pocet automobilov hraca: {ORANGE}{STRING} @@ -1194,6 +1196,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Povolit nakup akcii ostatnych spolocnosti STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Pri stavbe tahanim umiestnit semafory na kazde: {ORANGE}{STRING}. pole STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatická stavba semafórov pred: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Struktúra mesta "žiadne cesty naviac" nie je platná v editore scenárov +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Štruktúra mestských ciestt: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :žiadne cesty naviac +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :štandardná +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :lepšie cesty +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :mriežka 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :mriežka 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozicia hlavneho menu: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Nalavo STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :V strede @@ -2065,6 +2076,7 @@ STR_SV_STNAME_HELIPORT :{STRING} Heliport STR_SV_STNAME_FOREST :{STRING} Les + ############ end of savegame specific region! ##id 0x6800 @@ -2100,6 +2112,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ziadny +STR_NUM_VERY_LOW :Velmi malý STR_6816_LOW :Nizke STR_6817_NORMAL :Normalne STR_6818_HIGH :Vysoke @@ -3165,6 +3178,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Zmenit rok zaciatku hry STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Upozornenie na stupnicu STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Prilis velka zmena velkosti zdrojovej mapy sa neodporuca. Pokracovat s generovanim? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Upozornenie na štruktúra mesta +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Štruktúra mesta "žiadne cesty naviac" sa neodporúca. Pokracovat s generovaním? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nazov vyskovej mapy: STR_HEIGHTMAP_SIZE :{BLACK}Velkost: {ORANGE}{NUM} x {NUM} @@ -3237,3 +3252,35 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Prepnút priehladnost staníc, garáží, tratí, ... STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Prepnút priehladnost mostov STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Prepnút priehladnost objektov ako sú majáky a antény + +##### Mass Order +STR_GROUP_NAME_FORMAT :Skupina {COMMA} +STR_GROUP_ALL_TRAINS :Všetky vlaky +STR_GROUP_ALL_ROADS :Všetky cestné vozidlá +STR_GROUP_ALL_SHIPS :Všetky lode +STR_GROUP_ALL_AIRCRAFTS :Všetky lietadlá +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Pridat zdielané vozidlá +STR_GROUP_REMOVE_ALL_VEHICLES :Odstránit všetky vozidlá + +STR_GROUP_RENAME_CAPTION :{BLACK}Premenovat skupinu + +STR_GROUP_CAN_T_CREATE :{WHITE}Nie je možné vytvorit skupinu ... +STR_GROUP_CAN_T_DELETE :{WHITE}Nie je možné zrušit túto skupinu ... +STR_GROUP_CAN_T_RENAME :{WHITE}Nie je možné premenovat skupinu ... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nie je možné odstránit všetky vozdilá z tejto skupiny ... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nie je možné pridat vozidlo do tejto skupiny +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nie je možné pridat zdielané vozidlo do skupiny + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Skupiny - kliknite na skupinu pre zobrazenie všetkých vozidiel skupiny +STR_GROUP_CREATE_TIP :{BLACK}Kliknite pre vytvorenie skupiny +STR_GROUP_DELETE_TIP :{BLACK}Zrušit vybranú skupinu +STR_GROUP_RENAME_TIP :{BLACK}Premenovat vybranú skupinu +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Kliknite pre znemoznenie automatického nahradzovania v skupine + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {GREEN}{CURRENCY} {BLACK}(minulý rok: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {RED}{CURRENCY} {BLACK}(lminulý rok: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {GREEN}{CURRENCY} {BLACK}(minulý rok: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Zisk tento rok: {RED}{CURRENCY} {BLACK}(minulý rok: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/slovenian.txt --- a/src/lang/slovenian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/slovenian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1139,6 +1139,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Premikaj zemljevid STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Izklopljeno STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Hitrost premika s kolescem miške: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Avtomatsko pavziraj ob zagonu nove igre: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Največ vlakov na igralca: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Največ cestnih vozil na igralca: {ORANGE}{STRING} @@ -1172,6 +1173,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Dovoli kupovanje delnic od drugih podjetij STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Med vlečenjem postavi signale vsakih: {ORANGE}{STRING} ploščic STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Samodejno postavi semaforje pred: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Mestna razporeditev "nič več cest" ni veljavna v urejevalniku terena +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Izberi razporeditev mestnih cest: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :nič več cest +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :privzeto +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :boljše ceste +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 mreža +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 mreža + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Pozicija glavne orodne vrstice: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Levo STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Sredina @@ -2081,6 +2091,7 @@ STR_SV_STNAME_HELIPORT :{STRING} Pristajališče STR_SV_STNAME_FOREST :{STRING} Gozd + ############ end of savegame specific region! ##id 0x6800 @@ -2116,6 +2127,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Brez +STR_NUM_VERY_LOW :Zelo malo STR_6816_LOW :Malo STR_6817_NORMAL :Normalno STR_6818_HIGH :Veliko @@ -3181,6 +3193,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Spremeni začetno leto STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Opozorilo za merilo STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Prevelika sprememba velikosti ozemlja ni priporočena. Nadaljujem? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Opozorilo mestne razporeditve +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Mestna razporeditev "nič več cest" ni priporočena. Nadaljuješ z ustvarjanjem? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Ime višinskega zemljevida: STR_HEIGHTMAP_SIZE :{BLACK}Velikost: {ORANGE}{NUM} x {NUM} @@ -3253,3 +3267,11 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Prozoren ali navaden pogled ostalih objektov kot so postaje, garaže... STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Prozoren ali navaden pogled mostov STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Prozoren ali navaden pogled struktur kot so antene, svetilniki... + +##### Mass Order + + + + + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/spanish.txt --- a/src/lang/spanish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/spanish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1098,6 +1098,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scroll sobre el mapa STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Nada STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Velocidad del scroll sobre el mapa: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Automaticamente hace pausa cuando empieza un juego nuevo: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Usar la lista avanza de vehículos: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Máx trenes por jugador: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Máx vehículos de carretera por jugador: {ORANGE}{STRING} @@ -1131,6 +1133,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Permitir comprar acciones de otras empresas STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Cuando arrastre colocar señales cada: {ORANGE}{STRING} casilla(s) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Coloca automáticamente semáforos antes de: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}El trazado de ciudad "no más carreteras" no es válido en el editor de escenarios +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Selecciona trazado de carretera en ciudad: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :no más carreteras +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :por defecto +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :mejores carreteras +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :rejilla 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :rejilla 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Posición de la barra de herramientas principal: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Izquierda STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centro @@ -2002,6 +2013,7 @@ STR_SV_STNAME_HELIPORT :Helipuerto de {STRING} STR_SV_STNAME_FOREST :Bosque de {STRING} + ############ end of savegame specific region! ##id 0x6800 @@ -2037,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ninguno +STR_NUM_VERY_LOW :Muy bajo STR_6816_LOW :Baja STR_6817_NORMAL :Normal STR_6818_HIGH :Alta @@ -3102,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Cambiar año de inicio STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Alerta de escala STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Cambiar demasiado el tamaño del mapa de origen no está recomendado. ¿Desea continuar con la generación? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Aviso de trazado de ciudad +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}El trazado de ciudad "no más carreteras" no es recomendable. ¿Continuar con la generación? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Nombre del mapa de alturas: STR_HEIGHTMAP_SIZE :{BLACK}Tamaño: {ORANGE}{NUM} x {NUM} @@ -3174,3 +3189,35 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Activar transparencias para construcciones como estaciones, depósitos, puntos de paso, etc. STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Activar transparencias para puentes STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Activar transparencias para estructuras como faros, antenas, etc. + +##### Mass Order +STR_GROUP_NAME_FORMAT :Grupo {COMMA} +STR_GROUP_ALL_TRAINS :Todos los trenes +STR_GROUP_ALL_ROADS :Todos los vehículos de carretera +STR_GROUP_ALL_SHIPS :Todos los barcos +STR_GROUP_ALL_AIRCRAFTS :Todas las aeronaves +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Todos los vehículos compartidos +STR_GROUP_REMOVE_ALL_VEHICLES :Quitar todos los vehículos + +STR_GROUP_RENAME_CAPTION :{BLACK}Renombrar un grupo + +STR_GROUP_CAN_T_CREATE :{WHITE}No se puede crear grupo... +STR_GROUP_CAN_T_DELETE :{WHITE}No se puede borrar este grupo... +STR_GROUP_CAN_T_RENAME :{WHITE}No se puede renombrar grupo... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}No se pueden quitar todos los vehículos de este grupo... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}No se puede añadir el vehículo a este grupo... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}No se pueden añadir vehículos compartidos al grupo... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Grupos - Pulsa en el grupo para ver la lista de vehículos que tiene el grupo +STR_GROUP_CREATE_TIP :{BLACK}Pulsa para crear un grupo +STR_GROUP_DELETE_TIP :{BLACK}Borrar el grupo seleccionado +STR_GROUP_RENAME_TIP :{BLACK}Renombrar el grupo seleccionado +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Pulsa para proteger este grupo del auto reemplazado global + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Beneficio este año: {GREEN}{CURRENCY} {BLACK}(año pasado: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Beneficio este año: {RED}{CURRENCY} {BLACK}(año pasado: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Beneficio este año: {GREEN}{CURRENCY} {BLACK}(año pasado: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Beneficio este año: {RED}{CURRENCY} {BLACK}(año pasado: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/swedish.txt --- a/src/lang/swedish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/swedish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1097,6 +1097,8 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Scrolla kartan STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Avstängd STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Mushjulshastighet: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Pausa automatiskt vid start av nytt spel: {ORANGE}{STRING} +STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS :{LTBLUE}Använd den avancerade fordonslistan: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Max antal tåg per spelare: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Max antal vägfordon per spelare: {ORANGE}{STRING} @@ -1130,6 +1132,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Tillåt inköp av aktier från andra företag STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Vid utdragning av signaler, placera en signal var: {ORANGE}{STRING} ruta STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Bygg automatiskt semaforer innan: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Det går ej att använda "inga fler vägar" i scenario editorn +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Välj stadens väg-inställningar: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :inga fler vägar +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :standard +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :bättre vägar +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 rutnät +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 rutnät + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Position av verktygsraden: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Vänster STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Centrerad @@ -2001,6 +2012,8 @@ STR_SV_STNAME_HELIPORT :{STRING} Helikopterplats STR_SV_STNAME_FOREST :{STRING} Skog +STR_SV_GROUP_NAME :{GROUP} + ############ end of savegame specific region! ##id 0x6800 @@ -2036,6 +2049,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Ingen +STR_NUM_VERY_LOW :Väldigt låg STR_6816_LOW :Låg STR_6817_NORMAL :Normal STR_6818_HIGH :Hög @@ -3101,6 +3115,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Ändra Startår STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Skala-varning STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}För stora storleksändringar av källkarta är inte rekomenderat. Fortsätt med generering? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Varning genererat från stadens väg-inställningar +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Det är ej rekommenderat att använda inställningen "inga fler vägar". Vill du fortsätta ändå? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Namn på höjdkarta: STR_HEIGHTMAP_SIZE :{BLACK}Storlek: {ORANGE}{NUM} x {NUM} @@ -3173,3 +3189,41 @@ STR_TRANSPARENT_BUILDINGS_DESC :{BLACK}Växla genomskinlighet för byggnader såsom stationer, depåer, riktmärken eller kedjelinje STR_TRANSPARENT_BRIDGES_DESC :{BLACK}Växla genomskinlighet för industrier STR_TRANSPARENT_STRUCTURES_DESC :{BLACK}Växla genomskinlighet för byggnader såsom fyrar och antenner, kanske i framtiden även ögongodis + +##### Mass Order +STR_GROUP_NAME_FORMAT :Grupp {COMMA} +STR_GROUP_TINY_NAME :{TINYFONT}{GROUP} +STR_GROUP_ALL_TRAINS :Alla tåg +STR_GROUP_ALL_ROADS :Alla vägfordon +STR_GROUP_ALL_SHIPS :Alla skepp +STR_GROUP_ALL_AIRCRAFTS :Alla flygplan +STR_GROUP_TINY_NUM :{TINYFONT}{COMMA} +STR_GROUP_ADD_SHARED_VEHICLE :Lägg till delade fordon +STR_GROUP_REMOVE_ALL_VEHICLES :Ta bort alla fordon + +STR_GROUP_TRAINS_CAPTION :{WHITE}{GROUP} - {COMMA} Tåg{P "" s} +STR_GROUP_ROADVEH_CAPTION :{WHITE}{GROUP} - {COMMA} Vägfordon{P "" s} +STR_GROUP_SHIPS_CAPTION :{WHITE}{GROUP} - {COMMA} Skepp{P "" s} +STR_GROUP_AIRCRAFTS_CAPTION :{WHITE}{GROUP} - {COMMA} Flygplan +STR_GROUP_RENAME_CAPTION :{BLACK}Döp om en grupp +STR_GROUP_REPLACE_CAPTION :{WHITE}Byt ut fordonen i "{GROUP}" + +STR_GROUP_CAN_T_CREATE :{WHITE}Kan inte skapa grupp... +STR_GROUP_CAN_T_DELETE :{WHITE}Kan inte ta bort denna grupp... +STR_GROUP_CAN_T_RENAME :{WHITE}Kan inte döpa om grupp... +STR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan inte ta bort alla fordon från denna grupp... +STR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan inte lägga till fordonet till denna grupp... +STR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan inte lägga till delade fordon till grupp... + +STR_GROUPS_CLICK_ON_GROUP_FOR_TIP :{BLACK}Grupper - Klicka på en grupp för att lista alla fordon i denna grupp +STR_GROUP_CREATE_TIP :{BLACK}Klicka för att skapa en grupp +STR_GROUP_DELETE_TIP :{BLACK}Ta bort den valda gruppen +STR_GROUP_RENAME_TIP :{BLACK}Döp om den valda gruppen +STR_GROUP_REPLACE_PROTECTION_TIP :{BLACK}Klicka för att skydda denna grupp från globalt autoutbyte + +STR_PROFIT_GOOD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Vinst detta år: {GREEN}{CURRENCY} {BLACK}(förra året: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_GOOD_LAST_YEAR :{TINYFONT}{BLACK}Vinst detta år: {RED}{CURRENCY} {BLACK}(förra året: {GREEN}{CURRENCY}{BLACK}) +STR_PROFIT_GOOD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Vinst detta år: {GREEN}{CURRENCY} {BLACK}(förra året: {RED}{CURRENCY}{BLACK}) +STR_PROFIT_BAD_THIS_YEAR_BAD_LAST_YEAR :{TINYFONT}{BLACK}Vinst detta år: {RED}{CURRENCY} {BLACK}(förra året: {RED}{CURRENCY}{BLACK}) + +######## diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/traditional_chinese.txt --- a/src/lang/traditional_chinese.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/traditional_chinese.txt Wed Jun 13 11:45:14 2007 +0000 @@ -25,7 +25,7 @@ STR_0012_OIL :石油 STR_0013_LIVESTOCK :牲畜 STR_0014_GOODS :商品 -STR_0015_GRAIN :穀粒 +STR_0015_GRAIN :穀物 STR_0016_WOOD :木材 STR_0017_IRON_ORE :鐵礦石 STR_0018_STEEL :鋼鐵 @@ -57,7 +57,7 @@ STR_0032_OIL :石油 STR_0033_LIVESTOCK :牲畜 STR_0034_GOODS :商品 -STR_0035_GRAIN :穀粒 +STR_0035_GRAIN :穀物 STR_0036_WOOD :木材 STR_0037_IRON_ORE :鐵礦石 STR_0038_STEEL :鋼鐵 @@ -89,7 +89,7 @@ STR_QUANTITY_OIL :{VOLUME}石油 STR_QUANTITY_LIVESTOCK :{COMMA}頭牲畜 STR_QUANTITY_GOODS :{COMMA}箱商品 -STR_QUANTITY_GRAIN :{WEIGHT}小麥 +STR_QUANTITY_GRAIN :{WEIGHT}穀物 STR_QUANTITY_WOOD :{WEIGHT}木材 STR_QUANTITY_IRON_ORE :{WEIGHT}鐵礦 STR_QUANTITY_STEEL :{WEIGHT}鋼鐵 @@ -101,7 +101,7 @@ STR_QUANTITY_FOOD :{WEIGHT}食物 STR_QUANTITY_PAPER :{WEIGHT}紙張 STR_QUANTITY_GOLD :{COMMA}包黃金 -STR_QUANTITY_WATER :{VOLUME}食水 +STR_QUANTITY_WATER :{VOLUME}淡水 STR_QUANTITY_WHEAT :{WEIGHT}小麥 STR_QUANTITY_RUBBER :{VOLUME}橡膠 STR_QUANTITY_SUGAR :{WEIGHT}砂糖 @@ -421,8 +421,8 @@ STR_0169_AUG :8 STR_016A_SEP :9 STR_016B_OCT :10 -STR_016C_NOV :十一月 -STR_016D_DEC :十二月 +STR_016C_NOV :11 +STR_016D_DEC :12 ############ range for months ends STR_016E :{TINYFONT}{STRING}{} {STRING} @@ -1097,6 +1097,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :捲動地圖 STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :關閉 STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}滾輪地圖捲動速度: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}自動在開始新遊戲時暫停:{ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}每位玩家可擁有列車數目:{ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}每位玩家可擁有車輛數目:{ORANGE}{STRING} @@ -1130,6 +1131,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}可以從對手購入股份 STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}拖放時訊號燈之間距離:{ORANGE}{STRING} 格 STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}於日期前自動建立舊式號誌臂:{ORANGE}{STRING}年 + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}在場景編輯器中,"市鎮道路不再規劃" 是不可行的 +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}選擇市鎮道路規劃:{ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :道路不再規劃 +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :預設 +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :較好的規劃 +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2乘2網格 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3乘3網格 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}主工具列位置:{ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :左 STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :中 @@ -1728,7 +1738,7 @@ ##id 0x3000 STR_3000_RAIL_STATION_SELECTION :{WHITE}選擇鐵道車站 -STR_3001_AIRPORT_SELECTION :{WHITE}選擇飛機場 +STR_3001_AIRPORT_SELECTION :{WHITE}選擇機場 STR_3002_ORIENTATION :{BLACK}方向 STR_3003_NUMBER_OF_TRACKS :{BLACK}軌數 STR_3004_PLATFORM_LENGTH :{BLACK}月台長度 @@ -1742,7 +1752,7 @@ STR_300A_0 :{WHITE}{STATION} {STATIONFEATURES} STR_300B_MUST_DEMOLISH_RAILROAD :{WHITE}必須先摧毀鐵道車站 STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}太靠近另一個飛機場 -STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}必須先摧毀飛機場 +STR_300E_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}必須先剷除機場 STR_3030_RENAME_STATION_LOADING :修改車站/載貨區名稱 STR_3031_CAN_T_RENAME_STATION :{WHITE}不能修改車站名稱... @@ -1791,7 +1801,7 @@ STR_STATION_SIGN_TINY :{TINYFONT}{STATION} STR_305E_RAILROAD_STATION :鐵道車站 STR_305F_AIRCRAFT_HANGAR :飛機棚 -STR_3060_AIRPORT :飛機場 +STR_3060_AIRPORT :機場 STR_3061_TRUCK_LOADING_AREA :貨運場 STR_3062_BUS_STATION :公車站 STR_3063_SHIP_DOCK :船塢 @@ -2036,6 +2046,7 @@ ############ range for difficulty settings ends STR_26816_NONE :無 +STR_NUM_VERY_LOW :非常少 STR_6816_LOW :低 STR_6817_NORMAL :普通 STR_6818_HIGH :高 @@ -2540,7 +2551,7 @@ STR_8813_FROM :{LTBLUE}{CARGO} 來自 {STATION} STR_FROM_MULT :{LTBLUE}{CARGO} 來自 {STATION} (x{NUM}) STR_8814_TRAIN_IS_WAITING_IN_DEPOT :{WHITE}列車 {COMMA} 已在機廠待命 -STR_8815_NEW_VEHICLES :{BLACK}新造車輛 +STR_8815_NEW_VEHICLES :{BLACK}購買新車輛 STR_8816 :{BLACK}- STR_8819_TRAIN_TOO_LONG :{WHITE}列車太長 STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}列車只有在停放於機廠內的時候才能變動 @@ -2791,7 +2802,7 @@ ##id 0xA000 STR_A000_AIRPORTS :{WHITE}機場 -STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}無法在此建造機場... +STR_A001_CAN_T_BUILD_AIRPORT_HERE :{WHITE}無法在此興建機場... STR_A002_AIRCRAFT_HANGAR :{WHITE}{STATION} 停機棚 STR_A003_NEW_AIRCRAFT :{BLACK}購買飛機 STR_CLONE_AIRCRAFT :{BLACK}複製飛機 @@ -2822,12 +2833,12 @@ STR_A01A_CAPACITY :{BLACK}容量:{LTBLUE}{CARGO} STR_A01B_AIRCRAFT_MUST_BE_STOPPED :{WHITE}飛機必須停在機棚内 STR_A01C_CAN_T_SELL_AIRCRAFT :{WHITE}無法出售飛機... -STR_A01D_AIRPORT_CONSTRUCTION :建造機場 -STR_A01E_BUILD_AIRPORT :{BLACK}建造機場 +STR_A01D_AIRPORT_CONSTRUCTION :興建機場 +STR_A01E_BUILD_AIRPORT :{BLACK}興建機場 STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}飛機 - 點選飛機顯示詳細資料 STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES :{BLACK}購買新飛機 (需要有機棚的機場) STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT :{BLACK}飛機 - 點選飛機顯示詳細資料 -STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}建造新機場 +STR_A022_BUILD_NEW_AIRCRAFT :{BLACK}購買新飛機 STR_A023_DRAG_AIRCRAFT_TO_HERE_TO :{BLACK}將飛機拉至此即可出售 STR_A024_CENTER_MAIN_VIEW_ON_HANGAR :{BLACK}將主視野帶到機棚位置 STR_A025_AIRCRAFT_SELECTION_LIST :{BLACK}飛機清單 - 點選飛機檢視詳細資料 @@ -2843,7 +2854,7 @@ STR_A031_CAN_T_NAME_AIRCRAFT :{WHITE}無法命名飛機 STR_A032_NAME_AIRCRAFT :{BLACK}命名飛機 STR_A033_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}市民慶賀 . . .{}首架飛機抵達 {STATION}! -STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}飛機墜毀!{}{COMMA} 名死於 {STATION} 機場的火球下 +STR_A034_PLANE_CRASH_DIE_IN_FIREBALL :{BLACK}{BIGFONT}墜機!{}{COMMA} 名乘客與機組員死於 {STATION} 的火球下 STR_PLANE_CRASH_OUT_OF_FUEL :{BLACK}{BIGFONT}飛機墜毀!{}飛機用光燃油, {COMMA} 死在火球裡! STR_A036 :{TINYFONT}{BLACK}{STATION} STR_A037_RENAME :{BLACK}更名 @@ -3073,7 +3084,7 @@ STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}動力車廂:{GOLD}+{POWER}{BLACK} 重量:{GOLD}+{WEIGHT_S} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}可改裝成:{GOLD} STR_PURCHASE_INFO_ALL_TYPES :所有酬載類型 -STR_PURCHASE_INFO_ALL_BUT :{GOLD} 以外皆可 +STR_PURCHASE_INFO_ALL_BUT :{GOLD}除了 STR_PURCHASE_INFO_MAX_TE :{BLACK}最大牽引力:{GOLD}{FORCE} ########### String for New Landscape Generator @@ -3101,6 +3112,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}變更開始年份 STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}縮放警告 STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}不建議過度縮放地圖。繼續產生? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}市鎮規劃警告 +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW} "市鎮道路不再規劃" 是不建議的。要繼續產生嗎? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}高度圖名稱: STR_HEIGHTMAP_SIZE :{BLACK}大小:{ORANGE}{NUM} x {NUM} @@ -3142,8 +3155,8 @@ STR_HELIDEPOT :{BLACK}直升機棚 STR_HELISTATION :{BLACK}直升機站 -STR_SMALL_AIRPORTS :{BLACK}小機場 -STR_LARGE_AIRPORTS :{BLACK}大機場 +STR_SMALL_AIRPORTS :{BLACK}小型機場 +STR_LARGE_AIRPORTS :{BLACK}大型機場 STR_HUB_AIRPORTS :{BLACK}轉運機場 STR_HELIPORTS :{BLACK}直升機場 diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/turkish.txt --- a/src/lang/turkish.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/turkish.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1130,17 +1130,27 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Diğer şirketlerin hisseleri alınabilsin STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}Sürüklerken her: {ORANGE}{STRING} karede bir sinyal koy STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Bu tarihten önce ışık yerine semafor kullan: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Senaryo düzenleyicisinde "yolsuz" şehir seçeneği kullanılamaz +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :yolsuz +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :varsayılan +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :daha iyi yollar +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Ana araç çubuğu pozisyonu: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Sol STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :Orta STR_CONFIG_PATCHES_TOOLBAR_POS_RIGHT :Sağ STR_CONFIG_PATCHES_SNAP_RADIUS :{LTBLUE}Pencere yapışma yarıçapı: {ORANGE}{STRING} piksel STR_CONFIG_PATCHES_SNAP_RADIUS_DISABLED :{LTBLUE}Pencere yapışma yarıçapı: {ORANGE}kapalı +STR_CONFIG_PATCHES_TOWN_GROWTH :{LTBLUE}Şehirlerin genişleme hızı: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOWN_GROWTH_NONE :Hiçbiri STR_CONFIG_PATCHES_TOWN_GROWTH_SLOW :Yavaş STR_CONFIG_PATCHES_TOWN_GROWTH_NORMAL :Normal STR_CONFIG_PATCHES_TOWN_GROWTH_FAST :Hızlı STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Çok Hızlı +STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Kasabaların şehir olması için gerekli nüfus: {ORANGE}1 in {STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Arayüz STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}İnşaat diff -r 0b2aebc8283e -r 0b8b245a2391 src/lang/ukrainian.txt --- a/src/lang/ukrainian.txt Wed Jun 13 11:17:30 2007 +0000 +++ b/src/lang/ukrainian.txt Wed Jun 13 11:45:14 2007 +0000 @@ -1223,6 +1223,7 @@ STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLL :Прокрутка карти STR_CONFIG_PATCHES_SCROLLWHEEL_OFF :Відкл. STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER :{LTBLUE}Швидкість прокрутки колесом миші: {ORANGE}{STRING} +STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME :{LTBLUE}Автоматично ставити паузу при старті нової гри: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_TRAINS :{LTBLUE}Макс. поїздів у гравця: {ORANGE}{STRING} STR_CONFIG_PATCHES_MAX_ROADVEH :{LTBLUE}Макс. авто у гравця: {ORANGE}{STRING} @@ -1256,6 +1257,15 @@ STR_CONFIG_PATCHES_ALLOW_SHARES :{LTBLUE}Можна купувати інші компанії STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY :{LTBLUE}При протаскуванні сигнали ставляться через:{ORANGE}{STRING} клітки(ок) STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Автоматично будувати семафори до: {ORANGE}{STRING} + +STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID :{WHITE}Схема міста "не треба більше доріг" недійсна у редакторі сценаріїв +STR_CONFIG_PATCHES_TOWN_LAYOUT :{LTBLUE}Виберіть схему доріг у місті: {ORANGE}{STRING} +STR_CONFIG_PATCHES_TOWN_LAYOUT_NO_ROADS :не треба більше доріг +STR_CONFIG_PATCHES_TOWN_LAYOUT_DEFAULT :стандартна +STR_CONFIG_PATCHES_TOWN_LAYOUT_BETTER_ROADS :кращі дороги +STR_CONFIG_PATCHES_TOWN_LAYOUT_2X2_GRID :сітка 2x2 +STR_CONFIG_PATCHES_TOWN_LAYOUT_3X3_GRID :сітка 3x3 + STR_CONFIG_PATCHES_TOOLBAR_POS :{LTBLUE}Положення головного меню: {ORANGE}{STRING} STR_CONFIG_PATCHES_TOOLBAR_POS_LEFT :Ліворуч STR_CONFIG_PATCHES_TOOLBAR_POS_CENTER :По центру @@ -1270,7 +1280,7 @@ STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST :Дуже швидка STR_CONFIG_PATCHES_LARGER_TOWNS :{LTBLUE}Кількість міст, які будуть рости вдвічі швидше: {ORANGE}1 з {STRING} STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED :{LTBLUE}Кількість міст, які будуть рости вдвічі швидше: {ORANGE}нема -STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Початковий коєффіцієнт розміру міст: {ORANGE}{STRING} +STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER :{LTBLUE}Початковий коефіцієнт розміру міст: {ORANGE}{STRING} STR_CONFIG_PATCHES_GUI :{BLACK}Вигляд STR_CONFIG_PATCHES_CONSTRUCTION :{BLACK}Споруди @@ -2199,6 +2209,7 @@ ############ range for difficulty settings ends STR_26816_NONE :Нема +STR_NUM_VERY_LOW :дуже мало STR_6816_LOW :МалО STR_6817_NORMAL :Нормально STR_6818_HIGH :Багато @@ -3264,6 +3275,8 @@ STR_START_DATE_QUERY_CAPT :{WHITE}Змінити рік початку гри STR_HEIGHTMAP_SCALE_WARNING_CAPTION :{WHITE}Завелике значення STR_HEIGHTMAP_SCALE_WARNING_MESSAGE :{YELLOW}Розміри дуже великі. Продовжити генерацію? +STR_TOWN_LAYOUT_WARNING_CAPTION :{WHITE}Попередження про схему міста +STR_TOWN_LAYOUT_WARNING_MESSAGE :{YELLOW}Схема міста "не треба більше доріг" небажана. Продовжити генерацію? STR_SNOW_LINE_HEIGHT_NUM :{NUM} STR_HEIGHTMAP_NAME :{BLACK}Ім'я рельєфа: STR_HEIGHTMAP_SIZE :{BLACK}Розмір: {ORANGE}{NUM} x {NUM} diff -r 0b2aebc8283e -r 0b8b245a2391 src/main_gui.cpp --- a/src/main_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/main_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -51,6 +51,7 @@ static byte _terraform_size = 1; RailType _last_built_railtype; +RoadType _last_built_roadtype; static int _scengen_town_size = 1; // depress medium-sized towns per default extern void GenerateIndustries(); @@ -171,12 +172,12 @@ case 2: ShowPatchesSelection(); return; case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return; - case 5: _display_opt ^= DO_SHOW_TOWN_NAMES; break; - case 6: _display_opt ^= DO_SHOW_STATION_NAMES; break; - case 7: _display_opt ^= DO_SHOW_SIGNS; break; - case 8: _display_opt ^= DO_WAYPOINTS; break; - case 9: _display_opt ^= DO_FULL_ANIMATION; break; - case 10: _display_opt ^= DO_FULL_DETAIL; break; + case 5: TOGGLEBIT(_display_opt, DO_SHOW_TOWN_NAMES); break; + case 6: TOGGLEBIT(_display_opt, DO_SHOW_STATION_NAMES); break; + case 7: TOGGLEBIT(_display_opt, DO_SHOW_SIGNS); break; + case 8: TOGGLEBIT(_display_opt, DO_WAYPOINTS); break; + case 9: TOGGLEBIT(_display_opt, DO_FULL_ANIMATION); break; + case 10: TOGGLEBIT(_display_opt, DO_FULL_DETAIL); break; case 11: ToggleTransparency(); break; case 12: TOGGLEBIT(_transparent_opt, TO_SIGNS); break; } @@ -310,7 +311,8 @@ static void MenuClickBuildRoad(int index) { - ShowBuildRoadToolbar(); + _last_built_roadtype = (RoadType)index; + ShowBuildRoadToolbar(_last_built_roadtype); } static void MenuClickBuildWater(int index) @@ -880,8 +882,8 @@ switch (how) { case ZOOM_IN: - if (vp->zoom == 0) return false; - vp->zoom--; + if (vp->zoom == ZOOM_LVL_MIN) return false; + vp->zoom = (ZoomLevel)((byte)vp->zoom - 1); vp->virtual_width >>= 1; vp->virtual_height >>= 1; @@ -889,8 +891,8 @@ WP(w,vp_d).scrollpos_y += vp->virtual_height >> 1; break; case ZOOM_OUT: - if (vp->zoom == 2) return false; - vp->zoom++; + if (vp->zoom == ZOOM_LVL_MAX) return false; + vp->zoom = (ZoomLevel)((byte)vp->zoom + 1); WP(w,vp_d).scrollpos_x -= vp->virtual_width >> 1; WP(w,vp_d).scrollpos_y -= vp->virtual_height >> 1; @@ -930,12 +932,13 @@ const Player *p = GetPlayer(_local_player); Window *w2; w2 = PopupMainToolbMenu(w, 19, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes); - WP(w2,menu_d).sel_index = _last_built_railtype; + WP(w2, menu_d).sel_index = _last_built_railtype; } static void ToolbarBuildRoadClick(Window *w) { - PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 1, 0); + Window *w2 = PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 1, 0); + WP(w2, menu_d).sel_index = _last_built_roadtype; } static void ToolbarBuildWaterClick(Window *w) @@ -974,12 +977,12 @@ w = PopupMainToolbMenu(w, 2, STR_02C3_GAME_OPTIONS, 13, 0); - if (_display_opt & DO_SHOW_TOWN_NAMES) SETBIT(x, 5); - if (_display_opt & DO_SHOW_STATION_NAMES) SETBIT(x, 6); - if (_display_opt & DO_SHOW_SIGNS) SETBIT(x, 7); - if (_display_opt & DO_WAYPOINTS) SETBIT(x, 8); - if (_display_opt & DO_FULL_ANIMATION) SETBIT(x, 9); - if (_display_opt & DO_FULL_DETAIL) SETBIT(x, 10); + if (HASBIT(_display_opt, DO_SHOW_TOWN_NAMES)) SETBIT(x, 5); + if (HASBIT(_display_opt, DO_SHOW_STATION_NAMES)) SETBIT(x, 6); + if (HASBIT(_display_opt, DO_SHOW_SIGNS)) SETBIT(x, 7); + if (HASBIT(_display_opt, DO_WAYPOINTS)) SETBIT(x, 8); + if (HASBIT(_display_opt, DO_FULL_ANIMATION)) SETBIT(x, 9); + if (HASBIT(_display_opt, DO_FULL_DETAIL)) SETBIT(x, 10); if (GB(_transparent_opt, 1, 7) != 0) SETBIT(x, 11); if (HASBIT(_transparent_opt, TO_SIGNS)) SETBIT(x, 12); WP(w,menu_d).checked_items = x; @@ -1049,7 +1052,7 @@ vp = w->viewport; if (_game_mode != GM_MENU) { - if ((in && vp->zoom == 0) || (!in && vp->zoom == 2)) + if ((in && vp->zoom == ZOOM_LVL_MIN) || (!in && vp->zoom == ZOOM_LVL_MAX)) return; pt = GetTileZoomCenterWindow(in,w); @@ -1128,7 +1131,7 @@ static void PlaceProc_RockyArea(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_RockyArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_RockyArea); } static void PlaceProc_LightHouse(TileIndex tile) @@ -1155,12 +1158,12 @@ static void PlaceProc_DesertArea(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DesertArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_DesertArea); } static void PlaceProc_WaterArea(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_WaterArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_WaterArea); } static const Widget _scen_edit_land_gen_widgets[] = { @@ -1374,12 +1377,12 @@ _place_proc(e->we.place.tile); break; case WE_PLACE_DRAG: - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); break; case WE_PLACE_MOUSEUP: if (e->we.place.pt.x != -1) { - if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) // dragged actions + if (e->we.place.select_method == VPM_X_AND_Y) // dragged actions GUIPlaceProcDragXY(e); } break; @@ -1873,7 +1876,7 @@ case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(w); break; case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(w); break; case WKC_SHIFT | WKC_F7: ShowBuildRailToolbar(_last_built_railtype, -1); break; - case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(); break; + case WKC_SHIFT | WKC_F8: ShowBuildRoadToolbar(_last_built_roadtype); break; case WKC_SHIFT | WKC_F9: ShowBuildDocksToolbar(); break; case WKC_SHIFT | WKC_F10:ShowBuildAirToolbar(); break; case WKC_SHIFT | WKC_F11: ShowBuildTreesToolbar(); break; @@ -2425,8 +2428,8 @@ _scrolling_viewport = false; } - WP(w, vp_d).scrollpos_x += e->we.scroll.delta.x << vp->zoom; - WP(w, vp_d).scrollpos_y += e->we.scroll.delta.y << vp->zoom; + WP(w, vp_d).scrollpos_x += ScaleByZoom(e->we.scroll.delta.x, vp->zoom); + WP(w, vp_d).scrollpos_y += ScaleByZoom(e->we.scroll.delta.y, vp->zoom); } break; case WE_MOUSEWHEEL: @@ -2460,7 +2463,7 @@ height = _screen.height; w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL); - AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0); + AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), ZOOM_LVL_VIEWPORT); /* XXX: these are not done */ switch (_game_mode) { @@ -2514,6 +2517,7 @@ { /* Clean old GUI values */ _last_built_railtype = RAILTYPE_RAIL; + _last_built_roadtype = ROADTYPE_ROAD; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/map.cpp --- a/src/map.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/map.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -16,24 +16,29 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); #endif -uint _map_log_x; -uint _map_size_x; -uint _map_size_y; -uint _map_tile_mask; -uint _map_size; +uint _map_log_x; ///< 2^_map_log_x == _map_size_x +uint _map_size_x; ///< Size of the map along the X +uint _map_size_y; ///< Size of the map along the Y +uint _map_size; ///< The number of tiles on the map +uint _map_tile_mask; ///< _map_size - 1 (to mask the mapsize) -Tile *_m = NULL; -TileExtended *_me = NULL; +Tile *_m = NULL; ///< Tiles of the map +TileExtended *_me = NULL; ///< Extended Tiles of the map +/** + * (Re)allocates a map with the given dimension + * @param size_x the width of the map along the NE/SW edge + * @param size_y the 'height' of the map along the SE/NW edge + */ void AllocateMap(uint size_x, uint size_y) { /* Make sure that the map size is within the limits and that * the x axis size is a power of 2. */ if (size_x < 64 || size_x > 2048 || size_y < 64 || size_y > 2048 || - (size_x&(size_x-1)) != 0 || - (size_y&(size_y-1)) != 0) + (size_x & (size_x - 1)) != 0 || + (size_y & (size_y - 1)) != 0) error("Invalid map size"); DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); @@ -92,7 +97,12 @@ } #endif - +/** + * Scales the given value by the map size, where the given value is + * for a 256 by 256 map + * @param n the value to scale + * @return the scaled size + */ uint ScaleByMapSize(uint n) { /* First shift by 12 to prevent integer overflow for large values of n. @@ -102,7 +112,12 @@ } -/* Scale relative to the circumference of the map */ +/** + * Scales the given value by the maps circumference, where the given + * value is for a 256 by 256 map + * @param n the value to scale + * @return the scaled size + */ uint ScaleByMapSize1D(uint n) { /* Normal circumference for the X+Y is 256+256 = 1<<9 @@ -113,12 +128,18 @@ } -/* This function checks if we add addx/addy to tile, if we +/** + * This function checks if we add addx/addy to tile, if we * do wrap around the edges. For example, tile = (10,2) and * addx = +3 and addy = -4. This function will now return * INVALID_TILE, because the y is wrapped. This is needed in * for example, farmland. When the tile is not wrapped, - * the result will be tile + TileDiffXY(addx, addy) */ + * the result will be tile + TileDiffXY(addx, addy) + * @param tile the 'starting' point of the adding + * @param addx the amount of tiles in the X direction to add + * @param addy the amount of tiles in the Y direction to add + * @return translated tile, or INVALID_TILE when it would've wrapped. + */ uint TileAddWrap(TileIndex tile, int addx, int addy) { uint x = TileX(tile) + addx; @@ -131,6 +152,7 @@ return INVALID_TILE; } +/** 'Lookup table' for tile offsets given a DiagDirection */ extern const TileIndexDiffC _tileoffs_by_diagdir[] = { {-1, 0}, ///< DIAGDIR_NE { 0, 1}, ///< DIAGDIR_SE @@ -138,6 +160,7 @@ { 0, -1} ///< DIAGDIR_NW }; +/** 'Lookup table' for tile offsets given a Direction */ extern const TileIndexDiffC _tileoffs_by_dir[] = { {-1, -1}, ///< DIR_N {-1, 0}, ///< DIR_NE @@ -149,6 +172,15 @@ { 0, -1} ///< DIR_NW }; +/** + * Gets the Manhattan distance between the two given tiles. + * The Manhattan distance is the sum of the delta of both the + * X and Y component. + * Also known as L1-Norm + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceManhattan(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -157,6 +189,15 @@ } +/** + * Gets the 'Square' distance between the two given tiles. + * The 'Square' distance is the square of the shortest (straight line) + * distance between the two tiles. + * Also known as euclidian- or L2-Norm squared. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceSquare(TileIndex t0, TileIndex t1) { const int dx = TileX(t0) - TileX(t1); @@ -165,6 +206,13 @@ } +/** + * Gets the biggest distance component (x or y) between the two given tiles. + * Also known as L-Infinity-Norm. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceMax(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -173,6 +221,14 @@ } +/** + * Gets the biggest distance component (x or y) between the two given tiles + * plus the Manhattan distance, i.e. two times the biggest distance component + * and once the smallest component. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -180,6 +236,11 @@ return dx > dy ? 2 * dx + dy : 2 * dy + dx; } +/** + * Param the minimum distance to an edge + * @param tile the tile to get the distance from + * @return the distance from the edge in tiles + */ uint DistanceFromEdge(TileIndex tile) { const uint xl = TileX(tile); diff -r 0b2aebc8283e -r 0b8b245a2391 src/map.h --- a/src/map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/map.h Wed Jun 13 11:45:14 2007 +0000 @@ -7,29 +7,41 @@ #include "stdafx.h" -/* Putting externs inside inline functions seems to confuse the aliasing - * checking on MSVC6. Never use those variables directly. */ -extern uint _map_log_x; -extern uint _map_size_x; -extern uint _map_size_y; extern uint _map_tile_mask; -extern uint _map_size; + +/** + * 'Wraps' the given tile to it is within the map. It does + * this by masking the 'high' bits of. + * @param x the tile to 'wrap' + */ #define TILE_MASK(x) ((x) & _map_tile_mask) +/** + * Asserts when the tile is outside of the map. + * @param x the tile to check + */ #define TILE_ASSERT(x) assert(TILE_MASK(x) == (x)); +/** + * Data that is stored per tile. Also used TileExtended for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ struct Tile { - byte type_height; - byte m1; - uint16 m2; - byte m3; - byte m4; - byte m5; - byte m6; + byte type_height; ///< The type (bits 4..7) and height of the northern corner + byte m1; ///< Primarily used for ownership information + uint16 m2; ///< Primarily used for indices to towns, industries and stations + byte m3; ///< General purpose + byte m4; ///< General purpose + byte m5; ///< General purpose + byte m6; ///< Primarily used for bridges and rainforest/desert }; +/** + * Data that is stored per tile. Also used Tile for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ struct TileExtended { - byte m7; + byte m7; ///< Primarily used for newgrf support }; extern Tile *_m; @@ -37,16 +49,64 @@ void AllocateMap(uint size_x, uint size_y); -/* binary logarithm of the map size, try to avoid using this one */ -static inline uint MapLogX() { return _map_log_x; } -/* The size of the map */ -static inline uint MapSizeX() { return _map_size_x; } -static inline uint MapSizeY() { return _map_size_y; } -/* The maximum coordinates */ -static inline uint MapMaxX() { return _map_size_x - 1; } -static inline uint MapMaxY() { return _map_size_y - 1; } -/* The number of tiles in the map */ -static inline uint MapSize() { return _map_size; } +/** + * Logarithm of the map size along the X side. + * @note try to avoid using this one + * @return 2^"return value" == MapSizeX() + */ +static inline uint MapLogX() +{ + extern uint _map_log_x; + return _map_log_x; +} + +/** + * Get the size of the map along the X + * @return the number of tiles along the X of the map + */ +static inline uint MapSizeX() +{ + extern uint _map_size_x; + return _map_size_x; +} + +/** + * Get the size of the map along the Y + * @return the number of tiles along the Y of the map + */ +static inline uint MapSizeY() +{ + extern uint _map_size_y; + return _map_size_y; +} + +/** + * Get the size of the map + * @return the number of tiles of the map + */ +static inline uint MapSize() +{ + extern uint _map_size; + return _map_size; +} + +/** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ +static inline uint MapMaxX() +{ + return MapSizeX() - 1; +} + +/** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ +static inline uint MapMaxY() +{ + return MapSizeY() - 1; +} /* Scale a number relative to the map size */ uint ScaleByMapSize(uint); // Scale relative to the number of tiles @@ -76,7 +136,7 @@ enum { - INVALID_TILE = (TileIndex)-1 + INVALID_TILE = (TileIndex)-1 ///< The very nice invalid tile marker }; enum { @@ -86,11 +146,21 @@ }; +/** + * Get the X component of a tile + * @param tile the tile to get the X component of + * @return the X component + */ static inline uint TileX(TileIndex tile) { return tile & MapMaxX(); } +/** + * Get the Y component of a tile + * @param tile the tile to get the Y component of + * @return the Y component + */ static inline uint TileY(TileIndex tile) { return tile >> MapLogX(); @@ -139,6 +209,23 @@ return TileXY(x, y); } +/** + * Returns the diff between two tiles + * + * @param tile_a from tile + * @param tile_b to tile + * @return the difference between tila_a and tile_b + */ +static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b) +{ + TileIndexDiffC difference; + + difference.x = TileX(tile_a) - TileX(tile_b); + difference.y = TileY(tile_a) - TileY(tile_b); + + return difference; +} + /* Functions to calculate distances */ uint DistanceManhattan(TileIndex, TileIndex); ///< also known as L1-Norm. Is the shortest distance one could go over diagonal tracks (or roads) uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared diff -r 0b2aebc8283e -r 0b8b245a2391 src/misc.cpp --- a/src/misc.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/misc.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -23,6 +23,7 @@ #include "newgrf_house.h" #include "date.h" #include "cargotype.h" +#include "group.h" char _name_array[512][32]; @@ -121,6 +122,7 @@ InitializeWaypoints(); InitializeDepots(); InitializeOrders(); + InitializeGroup(); InitNewsItemStructs(); InitializeLandscape(); diff -r 0b2aebc8283e -r 0b8b245a2391 src/misc_gui.cpp --- a/src/misc_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/misc_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -382,12 +382,12 @@ } break; case WE_PLACE_OBJ: - VpStartPlaceSizing(e->we.place.tile, VPM_X_AND_Y_LIMITED); + VpStartPlaceSizing(e->we.place.tile, VPM_X_AND_Y_LIMITED, GUI_PlaceProc_None); VpSetPlaceSizingLimit(20); break; case WE_PLACE_DRAG: - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); return; case WE_PLACE_MOUSEUP: @@ -579,11 +579,11 @@ vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; /* move x pos to opposite corner */ - pt.x = ((pt.x - vp->virtual_left) >> vp->zoom) + vp->left; + pt.x = UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left; pt.x = (pt.x < (_screen.width >> 1)) ? _screen.width - 260 : 20; /* move y pos to opposite corner */ - pt.y = ((pt.y - vp->virtual_top) >> vp->zoom) + vp->top; + pt.y = UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top; pt.y = (pt.y < (_screen.height >> 1)) ? _screen.height - 80 : 100; } else { @@ -595,8 +595,8 @@ if ( (x|y) != 0) { pt = RemapCoords2(x, y); vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; - pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); - pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); + pt.x = clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); + pt.y = clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); } else { pt.x = (_screen.width - 334) >> 1; pt.y = (_screen.height - 137) >> 1; diff -r 0b2aebc8283e -r 0b8b245a2391 src/network/network.cpp --- a/src/network/network.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/network/network.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -1395,11 +1395,13 @@ byte cl_max = _network_game_info.clients_max; byte cp_max = _network_game_info.companies_max; byte sp_max = _network_game_info.spectators_max; + byte s_lang = _network_game_info.server_lang; memset(&_network_game_info, 0, sizeof(_network_game_info)); _network_game_info.clients_max = cl_max; _network_game_info.companies_max = cp_max; _network_game_info.spectators_max = sp_max; + _network_game_info.server_lang = s_lang; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/network/network_client.cpp --- a/src/network/network_client.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/network/network_client.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -184,7 +184,7 @@ // Data: // uint8: ActionID (see network_data.h, NetworkAction) // uint8: Destination Type (see network_data.h, DestType); - // uint8: Destination Player (1..MAX_PLAYERS) + // uint16: Destination Player // String: Message (max MAX_TEXT_MSG_LEN) // @@ -192,7 +192,7 @@ p->Send_uint8 (action); p->Send_uint8 (type); - p->Send_uint8 (dest); + p->Send_uint16(dest); p->Send_string(msg); MY_CLIENT->Send_Packet(p); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/network/network_gui.cpp --- a/src/network/network_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/network/network_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -1469,7 +1469,7 @@ if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0); } -static void SendChat(const char *buf, DestType type, byte dest) +static void SendChat(const char *buf, DestType type, int dest) { if (buf[0] == '\0') return; if (!_network_server) { @@ -1533,7 +1533,7 @@ static void ChatTabCompletion(Window *w) { static char _chat_tab_completion_buf[lengthof(_edit_str_buf)]; - Textbuf *tb = &WP(w, querystr_d).text; + Textbuf *tb = &WP(w, chatquerystr_d).text; uint len, tb_len; uint item; char *tb_buf, *pre_buf; @@ -1591,7 +1591,7 @@ } /* Update the textbuffer */ - UpdateTextBufferSize(&WP(w, querystr_d).text); + UpdateTextBufferSize(&WP(w, chatquerystr_d).text); SetWindowDirty(w); free(pre_buf); @@ -1605,17 +1605,17 @@ _chat_tab_completion_active = false; /* Update the textbuffer */ - UpdateTextBufferSize(&WP(w, querystr_d).text); + UpdateTextBufferSize(&WP(w, chatquerystr_d).text); SetWindowDirty(w); } free(pre_buf); } -/* uses querystr_d WP macro - * uses querystr_d->caption to store - * - type of chat message (Private/Team/All) in bytes 0-7 - * - destination of chat message in the case of Team/Private in bytes 8-15 */ +/* + * uses chatquerystr_d WP macro + * uses chatquerystr_d->caption to store type of chat message (Private/Team/All) + */ static void ChatWindowWndProc(Window *w, WindowEvent *e) { switch (e->event) { @@ -1634,25 +1634,25 @@ DrawWindowWidgets(w); - assert(GB(WP(w, querystr_d).caption, 0, 8) < lengthof(chat_captions)); - msg = chat_captions[GB(WP(w, querystr_d).caption, 0, 8)]; + assert(WP(w, chatquerystr_d).caption < lengthof(chat_captions)); + msg = chat_captions[WP(w, chatquerystr_d).caption]; DrawStringRightAligned(w->widget[2].left - 2, w->widget[2].top + 1, msg, 16); - DrawEditBox(w, &WP(w, querystr_d), 2); + DrawEditBox(w, &WP(w, chatquerystr_d), 2); } break; case WE_CLICK: switch (e->we.click.widget) { case 3: { /* Send */ - DestType type = (DestType)GB(WP(w, querystr_d).caption, 0, 8); - byte dest = GB(WP(w, querystr_d).caption, 8, 8); - SendChat(WP(w, querystr_d).text.buf, type, dest); + DestType type = (DestType)WP(w, chatquerystr_d).caption; + int dest = WP(w, chatquerystr_d).dest; + SendChat(WP(w, chatquerystr_d).text.buf, type, dest); } /* FALLTHROUGH */ case 0: /* Cancel */ DeleteWindow(w); break; } break; case WE_MOUSELOOP: - HandleEditBox(w, &WP(w, querystr_d), 2); + HandleEditBox(w, &WP(w, chatquerystr_d), 2); break; case WE_KEYPRESS: @@ -1660,11 +1660,11 @@ ChatTabCompletion(w); } else { _chat_tab_completion_active = false; - switch (HandleEditBoxKey(w, &WP(w, querystr_d), 2, e)) { + switch (HandleEditBoxKey(w, &WP(w, chatquerystr_d), 2, e)) { case 1: { /* Return */ - DestType type = (DestType)GB(WP(w, querystr_d).caption, 0, 8); - byte dest = GB(WP(w, querystr_d).caption, 8, 8); - SendChat(WP(w, querystr_d).text.buf, type, dest); + DestType type = (DestType)WP(w, chatquerystr_d).caption; + int dest = WP(w, chatquerystr_d).dest; + SendChat(WP(w, chatquerystr_d).text.buf, type, dest); } /* FALLTHROUGH */ case 2: /* Escape */ DeleteWindow(w); break; } @@ -1694,7 +1694,7 @@ ChatWindowWndProc }; -void ShowNetworkChatQueryWindow(DestType type, byte dest) +void ShowNetworkChatQueryWindow(DestType type, int dest) { Window *w; @@ -1706,9 +1706,10 @@ w = AllocateWindowDesc(&_chat_window_desc); LowerWindowWidget(w, 2); - WP(w, querystr_d).caption = GB(type, 0, 8) | (dest << 8); // Misuse of caption - WP(w, querystr_d).afilter = CS_ALPHANUMERAL; - InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0); + WP(w, chatquerystr_d).caption = type; // Misuse of caption + WP(w, chatquerystr_d).dest = dest; + WP(w, chatquerystr_d).afilter = CS_ALPHANUMERAL; + InitializeTextBuffer(&WP(w, chatquerystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0); } #endif /* ENABLE_NETWORK */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/network/network_gui.h --- a/src/network/network_gui.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/network/network_gui.h Wed Jun 13 11:45:14 2007 +0000 @@ -9,7 +9,7 @@ void ShowNetworkNeedPassword(NetworkPasswordType npt); void ShowNetworkGiveMoneyWindow(PlayerID player); // PlayerID -void ShowNetworkChatQueryWindow(DestType type, byte dest); +void ShowNetworkChatQueryWindow(DestType type, int dest); void ShowJoinStatusWindow(); void ShowNetworkGameWindow(); void ShowClientList(); @@ -17,7 +17,7 @@ #else /* ENABLE_NETWORK */ /* Network function stubs when networking is disabled */ -static inline void ShowNetworkChatQueryWindow(byte desttype, byte dest) {} +static inline void ShowNetworkChatQueryWindow(byte desttype, int dest) {} static inline void ShowClientList() {} static inline void ShowNetworkGameWindow() {} diff -r 0b2aebc8283e -r 0b8b245a2391 src/network/network_server.cpp --- a/src/network/network_server.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/network/network_server.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -101,7 +101,7 @@ p->Send_uint16(_network_player_info[player->index].performance); /* Send 1 if there is a passord for the company else send 0 */ - p->Send_bool(StrEmpty(_network_player_info[player->index].password)); + p->Send_bool(!StrEmpty(_network_player_info[player->index].password)); for (i = 0; i < NETWORK_VEHICLE_TYPES; i++) { p->Send_uint16(_network_player_info[player->index].num_vehicle[i]); @@ -1115,7 +1115,7 @@ { NetworkAction action = (NetworkAction)p->Recv_uint8(); DestType desttype = (DestType)p->Recv_uint8(); - int dest = p->Recv_uint8(); + int dest = p->Recv_uint16(); char msg[MAX_TEXT_MSG_LEN]; p->Recv_string(msg, MAX_TEXT_MSG_LEN); @@ -1301,9 +1301,7 @@ _network_player_info[v->owner].num_vehicle[4]++; break; - case VEH_SPECIAL: - case VEH_DISASTER: - break; + default: break; } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf.cpp --- a/src/newgrf.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -38,6 +38,9 @@ #include "helpers.hpp" #include "table/town_land.h" #include "cargotype.h" +#include "industry.h" +#include "newgrf_canal.h" +#include "newgrf_commons.h" /* TTDPatch extended GRF format codec * (c) Petr Baudis 2004 (GPL'd) @@ -310,7 +313,7 @@ uint8 tracktype = grf_load_byte(&buf); switch (tracktype) { - case 0: rvi[i].railtype = rvi[i].engclass == 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break; + case 0: rvi[i].railtype = rvi[i].engclass >= 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break; case 1: rvi[i].railtype = RAILTYPE_MONO; break; case 2: rvi[i].railtype = RAILTYPE_MAGLEV; break; default: @@ -446,21 +449,23 @@ */ FOR_EACH_OBJECT { uint8 traction = grf_load_byte(&buf); - int engclass; + EngineClass engclass; if (traction <= 0x07) { - engclass = 0; + engclass = EC_STEAM; } else if (traction <= 0x27) { - engclass = 1; + engclass = EC_DIESEL; } else if (traction <= 0x31) { - engclass = 2; + engclass = EC_ELECTRIC; + } else if (traction <= 0x37) { + engclass = EC_MONORAIL; } else if (traction <= 0x41) { - engclass = 2; + engclass = EC_MAGLEV; } else { break; } - if (rvi[i].railtype == RAILTYPE_RAIL && engclass == 2) rvi[i].railtype = RAILTYPE_ELECTRIC; - if (rvi[i].railtype == RAILTYPE_ELECTRIC && engclass != 2) rvi[i].railtype = RAILTYPE_RAIL; + if (rvi[i].railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi[i].railtype = RAILTYPE_ELECTRIC; + if (rvi[i].railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi[i].railtype = RAILTYPE_RAIL; rvi[i].engclass = engclass; } @@ -527,6 +532,10 @@ FOR_EACH_OBJECT rvi[i].user_def_data = grf_load_byte(&buf); break; + case 0x26: // Retire vehicle early + FOR_EACH_OBJECT ei[i].retire_early = grf_load_byte(&buf); + break; + case 0x27: // Miscellaneous flags FOR_EACH_OBJECT { ei[i].misc_flags = grf_load_byte(&buf); @@ -549,7 +558,6 @@ /* @todo air drag and retire vehicle early * Fall-through for unimplemented one byte long properties. */ case 0x20: // Air drag - case 0x26: // Retire vehicle early FOR_EACH_OBJECT grf_load_byte(&buf); ret = true; break; @@ -646,6 +654,10 @@ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf); break; + case 0x1B: // Retire vehicle early + FOR_EACH_OBJECT ei[i].retire_early = grf_load_byte(&buf); + break; + case 0x1C: // Miscellaneous flags FOR_EACH_OBJECT { ei[i].misc_flags = grf_load_byte(&buf); @@ -667,7 +679,6 @@ case 0x18: // Tractive effort case 0x19: // Air drag - case 0x1B: // Retire vehicle early /* @todo */ FOR_EACH_OBJECT grf_load_byte(&buf); ret = true; @@ -754,6 +765,10 @@ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf); break; + case 0x16: // Retire vehicle early + FOR_EACH_OBJECT ei[i].retire_early = grf_load_byte(&buf); + break; + case 0x17: // Miscellaneous flags FOR_EACH_OBJECT { ei[i].misc_flags = grf_load_byte(&buf); @@ -775,7 +790,6 @@ case 0x14: // Ocean speed fraction case 0x15: // Canal speed fraction - case 0x16: // Retire vehicle early /* @todo */ FOR_EACH_OBJECT grf_load_byte(&buf); ret = true; @@ -867,6 +881,10 @@ FOR_EACH_OBJECT ei[i].refit_cost = grf_load_byte(&buf); break; + case 0x16: // Retire vehicle early + FOR_EACH_OBJECT ei[i].retire_early = grf_load_byte(&buf); + break; + case 0x17: // Miscellaneous flags FOR_EACH_OBJECT { ei[i].misc_flags = grf_load_byte(&buf); @@ -886,12 +904,6 @@ FOR_EACH_OBJECT ei[i].base_intro = grf_load_dword(&buf); break; - case 0x16: // Retire vehicle early - /* @todo */ - FOR_EACH_OBJECT grf_load_byte(&buf); - ret = true; - break; - default: ret = true; break; @@ -1235,7 +1247,7 @@ _cur_grffile->housespec = CallocT(HOUSE_MAX); /* Reset any overrides that have been set. */ - ResetHouseOverrides(); + _house_mngr.ResetOverride(); } housespec = &_cur_grffile->housespec[hid]; @@ -1361,7 +1373,7 @@ return false; } - AddHouseOverride(hid, override); + _house_mngr.Add(hid, override); } break; @@ -1425,6 +1437,10 @@ } break; + case 0x1F: // Minimum life span + FOR_EACH_OBJECT housespec[i]->minimum_life = grf_load_byte(&buf); + break; + default: ret = true; break; @@ -1790,11 +1806,6 @@ EngineInfo *ei = NULL; - if (len == 1) { - grfmsg(8, "Silently ignoring one-byte special sprite 0x00"); - return; - } - if (!check_length(len, 6, "FeatureChangeInfo")) return; buf++; uint8 feature = grf_load_byte(&buf); @@ -1878,11 +1889,6 @@ /* Action 0x00 (GLS_SAFETYSCAN) */ static void SafeChangeInfo(byte *buf, int len) { - if (len == 1) { - grfmsg(8, "Silently ignoring one-byte special sprite 0x00"); - return; - } - if (!check_length(len, 6, "SafeChangeInfo")) return; buf++; uint8 feature = grf_load_byte(&buf); @@ -1908,11 +1914,6 @@ { byte *bufend = buf + len; - if (len == 1) { - grfmsg(8, "Silently ignoring one-byte special sprite 0x00"); - return; - } - if (!check_length(len, 6, "InitChangeInfo")) return; buf++; uint8 feature = grf_load_byte(&buf); @@ -1953,11 +1954,6 @@ { byte *bufend = buf + len; - if (len == 1) { - grfmsg(8, "Silently ignoring one-byte special sprite 0x00"); - return; - } - if (!check_length(len, 6, "InitChangeInfo")) return; buf++; uint8 feature = grf_load_byte(&buf); @@ -2054,6 +2050,20 @@ } } +/* Action 0x01 (SKIP) */ +static void SkipAct1(byte *buf, int len) +{ + if (!check_length(len, 4, "SkipAct1")) return; + buf++; + grf_load_byte(&buf); + uint8 num_sets = grf_load_byte(&buf); + uint16 num_ents = grf_load_extended(&buf); + + _skip_sprites = num_sets * num_ents; + + grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites); +} + /* Helper function to either create a callback or link to a previously * defined spritegroup. */ static const SpriteGroup* GetGroupFromGroupID(byte setid, byte type, uint16 groupid) @@ -2198,7 +2208,7 @@ } while (HASBIT(varadjust, 5)); group->g.determ.num_ranges = grf_load_byte(&buf); - group->g.determ.ranges = CallocT(group->g.determ.num_ranges); + if (group->g.determ.num_ranges > 0) group->g.determ.ranges = CallocT(group->g.determ.num_ranges); if (!check_length(bufend - buf, 2 + (2 + 2 * varsize) * group->g.determ.num_ranges, "NewSpriteGroup (Deterministic)")) return; @@ -2249,6 +2259,7 @@ case GSF_SHIP: case GSF_AIRCRAFT: case GSF_STATION: + case GSF_CANAL: case GSF_CARGOS: { byte sprites = _cur_grffile->spriteset_numents; @@ -2518,6 +2529,30 @@ } +static void CanalMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount) +{ + byte *bp = &buf[4 + idcount + cidcount * 3]; + uint16 groupid = grf_load_word(&bp); + + if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) { + grfmsg(1, "CanalMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.", + groupid, _cur_grffile->spritegroups_count); + return; + } + + for (uint i = 0; i < idcount; i++) { + CanalFeature cf = (CanalFeature)buf[3 + i]; + + if (cf >= CF_END) { + grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf); + continue; + } + + _canal_sg[cf] = _cur_grffile->spritegroups[groupid]; + } +} + + static void StationMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount) { for (uint i = 0; i < idcount; i++) { @@ -2666,6 +2701,10 @@ VehicleMapSpriteGroup(buf, feature, idcount, cidcount, wagover); return; + case GSF_CANAL: + CanalMapSpriteGroup(buf, idcount, cidcount); + return; + case GSF_STATION: StationMapSpriteGroup(buf, idcount, cidcount); return; @@ -2731,66 +2770,59 @@ len -= (int)name_length; - if (name_length == 1) { - grfmsg(7, "FeatureNewName: Can't add empty name"); - } else if (name_length > 127) { - grfmsg(7, "FeatureNewName: Too long a name (%d)", name_length); - } else { - grfmsg(8, "FeatureNewName: %d <- %s", id, name); - - switch (feature) { - case GSF_TRAIN: - case GSF_ROAD: - case GSF_SHIP: - case GSF_AIRCRAFT: { - if (id < TOTAL_NUM_ENGINES) { - StringID string = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_8000_KIRBY_PAUL_TANK_STEAM + id); - SetCustomEngineName(id, string); - } else { - AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, id); - } - break; + grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name); + + switch (feature) { + case GSF_TRAIN: + case GSF_ROAD: + case GSF_SHIP: + case GSF_AIRCRAFT: + if (id < TOTAL_NUM_ENGINES) { + StringID string = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_8000_KIRBY_PAUL_TANK_STEAM + id); + SetCustomEngineName(id, string); + } else { + AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, id); } - - case GSF_TOWNHOUSE: - default: - switch (GB(id, 8, 8)) { - case 0xC4: // Station class name - if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) { - grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); - } else { - StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass; - SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED)); - } - break; - - case 0xC5: // Station name - if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) { - grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); - } else { - _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); - } - break; - - case 0xC9: { // House name - if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) { - grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8)); - } else { - _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); - } - break; + break; + + case GSF_TOWNHOUSE: + default: + switch (GB(id, 8, 8)) { + case 0xC4: // Station class name + if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) { + grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); + } else { + StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass; + SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED)); } - - case 0xD0: - case 0xDC: - AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); - break; - - default: - grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id); - break; - } - break; + break; + + case 0xC5: // Station name + if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) { + grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); + } else { + _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); + } + break; + + case 0xC9: // House name + if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) { + grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8)); + } else { + _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); + } + break; + + case 0xD0: + case 0xDC: + AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED); + break; + + default: + grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id); + break; + } + break; #if 0 case GSF_CANAL : @@ -2811,7 +2843,6 @@ grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature); break; #endif - } } } } @@ -2916,6 +2947,21 @@ } } +/* Action 0x05 (SKIP) */ +static void SkipAct5(byte *buf, int len) +{ + if (!check_length(len, 2, "SkipAct5")) return; + buf++; + + /* Ignore type byte */ + grf_load_byte(&buf); + + /* Skip the sprites of this action */ + _skip_sprites = grf_load_extended(&buf); + + grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites); +} + static uint32 GetParamVal(byte param, uint32 *cond_val) { switch (param) { @@ -2948,7 +2994,7 @@ uint major = 2; uint minor = 6; uint revision = 0; // special case: 2.0.1 is 2.0.10 - uint build = 1168; + uint build = 1210; return (major << 24) | (minor << 20) | (revision << 16) | build; } @@ -3048,11 +3094,18 @@ grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset); + bool carry = false; for (i = 0; i < param_size; i++) { uint32 value = GetParamVal(param_num + i / 4, NULL); + /* Reset carry flag for each iteration of the variable (only really + * matters if param_size is greater than 4) */ + if (i == 0) carry = false; if (add_value) { - _preload_sprite[offset + i] += GB(value, (i % 4) * 8, 8); + uint new_value = _preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0); + _preload_sprite[offset + i] = GB(new_value, 0, 8); + /* Check if the addition overflowed */ + carry = new_value >= 256; } else { _preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8); } @@ -3153,6 +3206,10 @@ break; case 5: result = (param_val & mask) > cond_val; break; + case 11: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID; + break; + case 12: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID; + break; default: grfmsg(1, "SkipIf: Unsupported test %d. Ignoring", condtype); return; } @@ -3283,6 +3340,22 @@ } } +/* Action 0x0A (SKIP) */ +static void SkipActA(byte *buf, int len) +{ + buf++; + uint8 num_sets = grf_load_byte(&buf); + + for (uint i = 0; i < num_sets; i++) { + /* Skip the sprites this replaces */ + _skip_sprites += grf_load_byte(&buf); + /* But ignore where they go */ + grf_load_word(&buf); + } + + grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites); +} + /* Action 0x0B */ static void GRFLoadError(byte *buf, int len) { @@ -3434,6 +3507,28 @@ _skip_sprites = -1; } + +static uint32 GetPatchVariable(uint8 param) +{ + switch (param) { + /* start year - 1920 */ + case 0x0B: return max(_patches.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR; + /* freight trains weight factor */ + case 0x0E: return _patches.freight_trains; + /* empty wagon speed increase */ + case 0x0F: return 0; + /* plane speed factor */ + case 0x10: return 4; + /* 2CC colormap base sprite */ + case 0x11: return SPR_2CCMAP_BASE; + + default: + grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param); + return 0; + } +} + + /* Action 0x0D */ static void ParamSet(byte *buf, int len) { @@ -3488,8 +3583,7 @@ if (GB(data, 0, 8) == 0xFF) { if (data == 0x0000FFFF) { /* Patch variables */ - grfmsg(2, "ParamSet: Reading Patch variables unsupported"); - return; + src1 = GetPatchVariable(src1); } else { /* GRF Resource Management */ if (_cur_stage != GLS_ACTIVATION) { @@ -3711,7 +3805,7 @@ case 0x9E: // Miscellaneous GRF features _misc_grf_features = res; /* Set train list engine width */ - _traininfo_vehicle_width = HASBIT(res, 3) ? 32 : 29; + _traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? 32 : 29; break; default: @@ -4131,7 +4225,7 @@ | (1 << 0x05) // resolutionwidth | (1 << 0x06) // resolutionheight | (0 << 0x07) // newindustries - | (0 << 0x08) // fifoloading + | ((_patches.improved_load ? 1 : 0) << 0x08) // fifoloading | (0 << 0x09) // townroadbranchprob | (0 << 0x0A) // tempsnowline | (1 << 0x0B) // newcargo @@ -4270,6 +4364,9 @@ ResetStationClasses(); ResetCustomStations(); + /* Reset canal sprite groups */ + memset(_canal_sg, 0, sizeof(_canal_sg)); + /* Reset the snowline table. */ ClearSnowLine(); @@ -4464,6 +4561,8 @@ /* Check if this engine's cargo type is valid. If not, set to the first refittable * cargo type. Apparently cargo_type isn't a common property... */ switch (GetEngine(engine)->type) { + default: NOT_REACHED(); + case VEH_AIRCRAFT: break; case VEH_TRAIN: { RailVehicleInfo *rvi = &_rail_vehicle_info[engine]; if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine); @@ -4506,7 +4605,7 @@ for (int i = 0; i < HOUSE_MAX; i++) { HouseSpec *hs = file->housespec[i]; if (hs != NULL) { - SetHouseSpec(hs); + _house_mngr.SetEntitySpec(hs); if (hs->min_date < 1930) reset_dates = false; } } @@ -4563,16 +4662,16 @@ * In other stages we skip action 0x10 since it's already dealt with. */ static const SpecialSpriteHandler handlers[][GLS_END] = { /* 0x00 */ { NULL, SafeChangeInfo, NULL, InitChangeInfo, ReserveChangeInfo, FeatureChangeInfo, }, - /* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NULL, NewSpriteSet, }, - /* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NULL, NewSpriteGroup, }, + /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, }, + /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, }, /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, }, /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, }, - /* 0x05 */ { NULL, NULL, NULL, NULL, NULL, GraphicsNew, }, + /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, }, /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, }, /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, }, /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, NULL, GRFInfo, }, /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, }, - /* 0x0A */ { NULL, NULL, NULL, NULL, NULL, SpriteReplace, }, + /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, }, /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, }, /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, }, /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, }, @@ -4717,6 +4816,9 @@ /* Add all new houses to the house array. */ FinaliseHouseArray(); + /* Create dynamic list of industry legends for smallmap_gui.cpp */ + BuildIndustriesLegend(); + /* Map cargo strings. This is a separate step because cargos are * loaded before strings... */ MapNewCargoStrings(); @@ -4755,3 +4857,8 @@ /* Call any functions that should be run after GRFs have been loaded. */ AfterLoadGRFs(); } + +bool HasGrfMiscBit(GrfMiscBit bit) +{ + return HASBIT(_misc_grf_features, bit); +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf.h --- a/src/newgrf.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf.h Wed Jun 13 11:45:14 2007 +0000 @@ -23,6 +23,14 @@ DECLARE_POSTFIX_INCREMENT(GrfLoadingStage); +enum GrfMiscBit { + GMB_DESERT_TREES_FIELDS = 0, // Unsupported. + GMB_DESERT_PAVED_ROADS = 1, + GMB_FIELD_BOUNDING_BOX = 2, // Unsupported. + GMB_TRAIN_WIDTH_32_PIXELS = 3, + GMB_AMBIENT_SOUND_CALLBACK = 4, // Unsupported. + GMB_CATENARY_ON_3RD_TRACK = 5, // Unsupported. +}; struct GRFLabel { byte label; @@ -85,4 +93,6 @@ void CDECL grfmsg(int severity, const char *str, ...); +bool HasGrfMiscBit(GrfMiscBit bit); + #endif /* NEWGRF_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_canal.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/newgrf_canal.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,96 @@ +/* $Id$ */ + +#include "stdafx.h" +#include "openttd.h" +#include "variables.h" +#include "landscape.h" +#include "debug.h" +#include "newgrf.h" +#include "newgrf_callbacks.h" +#include "newgrf_spritegroup.h" +#include "newgrf_canal.h" + + +/** Table of canal 'feature' sprite groups */ +const SpriteGroup *_canal_sg[CF_END]; + + +/* Random bits and triggers are not supported for canals, so the following + * three functions are stubs. */ +static uint32 CanalGetRandomBits(const ResolverObject *object) +{ + return 0; +} + + +static uint32 CanalGetTriggers(const ResolverObject *object) +{ + return 0; +} + + +static void CanalSetTriggers(const ResolverObject *object, int triggers) +{ + return; +} + + +static uint32 CanalGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) +{ + TileIndex tile = object->u.canal.tile; + + switch (variable) { + case 0x80: + return TileHeight(tile); + + case 0x81: + return ((_opt.landscape == LT_ARCTIC && GetTileZ(tile) > GetSnowLine()) ? 4 : 0) | + (_opt.landscape == LT_TROPIC ? GetTropicZone(tile) : 0); + } + + DEBUG(grf, 1, "Unhandled canal property 0x%02X", variable); + + *available = false; + return 0; +} + + +static const SpriteGroup *CanalResolveReal(const ResolverObject *object, const SpriteGroup *group) +{ + if (group->g.real.num_loaded == 0) return NULL; + + return group->g.real.loaded[0]; +} + + +static void NewCanalResolver(ResolverObject *res, TileIndex tile) +{ + res->GetRandomBits = &CanalGetRandomBits; + res->GetTriggers = &CanalGetTriggers; + res->SetTriggers = &CanalSetTriggers; + res->GetVariable = &CanalGetVariable; + res->ResolveReal = &CanalResolveReal; + + res->u.canal.tile = tile; + + res->callback = 0; + res->callback_param1 = 0; + res->callback_param2 = 0; + res->last_value = 0; + res->trigger = 0; + res->reseed = 0; +} + + +SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile) +{ + ResolverObject object; + const SpriteGroup *group; + + NewCanalResolver(&object, tile); + + group = Resolve(_canal_sg[feature], &object); + if (group == NULL || group->type != SGT_RESULT) return 0; + + return group->g.result.sprite; +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_canal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/newgrf_canal.h Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,29 @@ +/* $Id$ */ + +#ifndef NEWGRF_CANAL_H +#define NEWGRF_CANAL_H + +/** List of different canal 'features'. + * Each feature gets an entry in the canal spritegroup table */ +enum CanalFeature { + CF_WATERSLOPE, + CF_LOCKS, + CF_DIKES, + CF_ICON, + CF_DOCKS, + CF_END, +}; + + +/** Table of canal 'feature' sprite groups */ +extern const SpriteGroup *_canal_sg[CF_END]; + + +/** Lookup the base sprite to use for a canal. + * @param feature Which canal feature we want. + * @param tile Tile index of canal, if appropriate. + * @return Base sprite returned by GRF, or 0 if none. + */ +SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile); + +#endif /* NEWGRF_CANAL_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_cargo.cpp --- a/src/newgrf_cargo.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_cargo.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -39,10 +39,12 @@ static const SpriteGroup *CargoResolveReal(const ResolverObject *object, const SpriteGroup *group) { - /* Cargo action 2s should always have only 1 "loaded" state */ - if (group->g.real.num_loaded == 0) return NULL; + /* Cargo action 2s should always have only 1 "loaded" state, but some + * times things don't follow the spec... */ + if (group->g.real.num_loaded > 0) return group->g.real.loaded[0]; + if (group->g.real.num_loading > 0) return group->g.real.loading[0]; - return group->g.real.loaded[0]; + return NULL; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_commons.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/newgrf_commons.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,150 @@ +/* $Id$ */ + +/** @file newgrf_commons.cpp Implementation of the class OverrideManagerBase + * and its descendance, present and futur + */ + +#include "stdafx.h" +#include "openttd.h" +#include "town.h" +#include "industry.h" +#include "newgrf.h" +#include "newgrf_commons.h" + +/** Constructor of generic class + * @param offset end of original data for this entity. i.e: houses = 110 + * @param maximum of entities this manager can deal with. i.e: houses = 512 + * @param invalid is the ID used to identify an invalid entity id + */ +OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid) +{ + max_offset = offset; + max_new_entities = maximum; + invalid_ID = invalid; + + mapping_ID = CallocT(max_new_entities); + entity_overrides = MallocT(max_offset); + memset(entity_overrides, invalid, sizeof(entity_overrides)); +} + +/** Destructor of the generic class. + * Frees allocated memory of constructor + */ +OverrideManagerBase::~OverrideManagerBase() +{ + free(mapping_ID); + free(entity_overrides); +} + +/** Since the entity IDs defined by the GRF file does not necessarily correlate + * to those used by the game, the IDs used for overriding old entities must be + * translated when the entity spec is set. + * @param local_id id in grf file + * @param entity_type original entity type + */ +void OverrideManagerBase::Add(uint8 local_id, uint entity_type) +{ + assert(entity_type < max_offset); + entity_overrides[entity_type] = local_id; +} + +/** Resets the mapping, which is used while initializing game */ +void OverrideManagerBase::ResetMapping() +{ + memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping)); +} + +/** Resets the override, which is used while initializing game */ +void OverrideManagerBase::ResetOverride() +{ + for (uint16 i = 0; i < max_offset; i++) { + entity_overrides[i] = invalid_ID; + } +} + +/** Return the ID (if ever available) of a previously inserted entity. + * @param grf_local_id ID of this enity withing the grfID + * @param grfid ID of the grf file + * @return the ID of the candidate, of the Invalid flag item ID + */ +uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) +{ + const EntityIDMapping *map; + + for (uint16 id = max_offset; id < max_new_entities; id++) { + map = &mapping_ID[id]; + if (map->entity_id == grf_local_id && map->grfid == grfid) { + return id; + } + } + return invalid_ID; +} + +/** Reserves a place in the mapping array for an entity to be installed + * @param grf_local_id is an arbitrary id given by the grf's author. Also known as setid + * @param grfid is the id of the grf file itself + * @param substitute_id is the original entity from which data is copied for the new one + * @return the proper usable slot id, or invalid marker if none is found + */ +uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id) +{ + uint16 id = this->GetID(grf_local_id, grfid); + EntityIDMapping *map; + + /* Look to see if this entity has already been added. This is done + * separately from the loop below in case a GRF has been deleted, and there + * are any gaps in the array. + */ + if (id != invalid_ID) { + return id; + } + + /* This entity hasn't been defined before, so give it an ID now. */ + for (id = max_offset; id < max_new_entities; id++) { + map = &mapping_ID[id]; + + if (map->entity_id == 0 && map->grfid == 0) { + map->entity_id = grf_local_id; + map->grfid = grfid; + map->substitute_id = substitute_id; + return id; + } + } + + return invalid_ID; +} + +/** Gives the substitute of the entity, as specified by the grf file + * @param entity_id of the entity being queried + * @return mapped id + */ +uint16 OverrideManagerBase::GetSubstituteID(byte entity_id) +{ + return mapping_ID[entity_id].substitute_id; +} + +/** Install the specs into the HouseSpecs array + * It will find itself the proper slot onwhich it will go + * @param hs HouseSpec read from the grf file, ready for inclusion + */ +void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs) +{ + HouseID house_id = this->AddEntityID(hs->local_id, hs->grffile->grfid, hs->substitute_id); + + if (house_id == invalid_ID) { + grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring."); + return; + } + + memcpy(&_house_specs[house_id], hs, sizeof(*hs)); + + /* Now add the overrides. */ + for (int i = 0; i != max_offset; i++) { + HouseSpec *overridden_hs = GetHouseSpecs(i); + + if (entity_overrides[i] != hs->local_id) continue; + + overridden_hs->override = house_id; + entity_overrides[i] = invalid_ID; + } +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_commons.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/newgrf_commons.h Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,69 @@ +/* $Id$ */ + +/** @file newgrf_commons.h This file simplyfies and embeds a common mechanism of + * loading/saving and mapping of grf entities. + */ + +#ifndef NEWGRF_COMMONS_H +#define NEWGRF_COMMONS_H + +/** + * Maps an entity id stored on the map to a GRF file. + * Entities are objects used ingame (houses, industries, industry tiles) for + * which we need to correlate the ids from the grf files with the ones in the + * the savegames themselves. + * An array of EntityIDMapping structs is saved with the savegame so + * that those GRFs can be loaded in a different order, or removed safely. The + * index in the array is the entity's ID stored on the map. + * + * The substitute ID is the ID of an original entity that should be used instead + * if the GRF containing the new entity is not available. + */ +struct EntityIDMapping { + uint32 grfid; ///< The GRF ID of the file the entity belongs to + uint8 entity_id; ///< The entity ID within the GRF file + uint8 substitute_id; ///< The (original) entity ID to use if this GRF is not available +}; + +class OverrideManagerBase +{ +protected: + uint16 *entity_overrides; + + uint16 max_offset; ///< what is the length of the original entity's array of specs + uint16 max_new_entities; ///< what is the amount of entities, old and new summed + + uint16 invalid_ID; ///< ID used to dected invalid entities; + + virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id); +public: + EntityIDMapping *mapping_ID; ///< mapping of ids from grf files. Public out of convenience + + OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid); + virtual ~OverrideManagerBase(); + + void ResetOverride(); + void ResetMapping(); + + void Add(uint8 local_id, uint entity_type); + + uint16 GetSubstituteID(byte entity_id); + uint16 GetID(uint8 grf_local_id, uint32 grfid); + + inline uint16 GetMaxMapping() { return max_new_entities; }; + inline uint16 GetMaxOffset() { return max_offset; }; +}; + + +struct HouseSpec; +class HouseOverrideManager : public OverrideManagerBase +{ +public: + HouseOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : OverrideManagerBase(offset, maximum, invalid) {}; + void SetEntitySpec(const HouseSpec *hs); +}; + + +extern HouseOverrideManager _house_mngr; + +#endif /* NEWGRF_COMMONS_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_engine.cpp --- a/src/newgrf_engine.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_engine.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -63,22 +63,22 @@ memcpy(wo->train_id, train_id, trains); } -static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine) +const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine) { const WagonOverrides *wos = &_engine_wagon_overrides[engine]; - int i; /* XXX: This could turn out to be a timesink on profiles. We could * always just dedicate 65535 bytes for an [engine][train] trampoline * for O(1). Or O(logMlogN) and searching binary tree or smt. like * that. --pasky */ - for (i = 0; i < wos->overrides_count; i++) { + for (int i = 0; i < wos->overrides_count; i++) { const WagonOverride *wo = &wos->overrides[i]; - int j; - for (j = 0; j < wo->trains; j++) { - if (wo->train_id[j] == overriding_engine && (wo->cargo == cargo || wo->cargo == CT_DEFAULT)) return wo->group; + if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue; + + for (int j = 0; j < wo->trains; j++) { + if (wo->train_id[j] == overriding_engine) return wo->group; } } return NULL; @@ -246,7 +246,7 @@ { const Station *st = GetStation(v->u.air.targetairport); const AirportFTAClass *afc = st->Airport(); - byte amdflag = afc->MovingData(v->u.air.pos)->flag; + uint16 amdflag = afc->MovingData(v->u.air.pos)->flag; switch (v->u.air.state) { case HANGAR: @@ -313,7 +313,7 @@ } case FLYING: - return AMS_TTDP_FLIGHT_TO_TOWER; + return amdflag & AMED_HOLD ? AMS_TTDP_FLIGHT_APPROACH : AMS_TTDP_FLIGHT_TO_TOWER; case LANDING: // Descent return AMS_TTDP_FLIGHT_DESCENT; @@ -468,6 +468,22 @@ } +static uint8 LiveryHelper(EngineID engine, const Vehicle *v) +{ + const Livery *l; + + if (v == NULL) { + l = GetEngineLivery(engine, _current_player, INVALID_ENGINE, NULL); + } else if (v->type == VEH_TRAIN) { + l = GetEngineLivery((v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ? v->u.rail.first_engine : v->engine_type, v->owner, v->u.rail.first_engine, v); + } else { + l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v); + } + + return l->colour1 + l->colour2 * 16; +} + + static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { const Vehicle *v = GRV(object); @@ -475,7 +491,7 @@ if (v == NULL) { /* Vehicle does not exist, so we're in a purchase list */ switch (variable) { - case 0x43: return _current_player; // Owner information + case 0x43: return _current_player | (LiveryHelper(object->u.vehicle.self_type, NULL) << 24); // Owner information case 0x46: return 0; // Motion counter case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; // Vehicle Type Info case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year @@ -544,7 +560,7 @@ } case 0x43: // Player information - return v->owner; + return v->owner | (GetPlayer(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24); case 0x44: // Aircraft information if (v->type != VEH_AIRCRAFT) return UINT_MAX; @@ -573,6 +589,25 @@ return (altitude << 8) | airporttype; } + case 0x45: { // Curvature info + /* Format: xxxTxBxF + * F - previous wagon to current wagon, 0 if vehicle is first + * B - current wagon to next wagon, 0 if wagon is last + * T - previous wagon to next wagon, 0 in an S-bend + */ + if (v->type != VEH_TRAIN) return 0; + + const Vehicle *u_p = GetPrevVehicleInChain(v); + const Vehicle *u_n = v->next; + DirDiff f = (u_p == NULL) ? DIRDIFF_SAME : DirDifference(u_p->direction, v->direction); + DirDiff b = (u_n == NULL) ? DIRDIFF_SAME : DirDifference(v->direction, u_n->direction); + DirDiff t = ChangeDirDiff(f, b); + + return ((t > DIRDIFF_REVERSE ? t | 8 : t) << 16) | + ((b > DIRDIFF_REVERSE ? b | 8 : b) << 8) | + ( f > DIRDIFF_REVERSE ? f | 8 : f); + } + case 0x46: // Motion counter return v->motion_counter; @@ -735,6 +770,8 @@ case 0x66: return MapAircraftMovementAction(v); // Current movement action } break; + + default: break; } DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, v->type); @@ -815,8 +852,7 @@ cargo = v->cargo_type; if (v->type == VEH_TRAIN) { - group = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine); - + group = v->u.rail.cached_override; if (group != NULL) return group; } } @@ -877,7 +913,7 @@ bool UsesWagonOverride(const Vehicle* v) { assert(v->type == VEH_TRAIN); - return GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->u.rail.first_engine) != NULL; + return v->u.rail.cached_override != NULL; } /** @@ -936,7 +972,7 @@ } -/* Callback 36 handler */ +/* Callback 36 handlers */ uint GetVehicleProperty(const Vehicle *v, uint8 property, uint orig_value) { uint16 callback = GetVehicleCallback(CBID_VEHICLE_MODIFY_PROPERTY, property, 0, v->engine_type, v); @@ -946,6 +982,15 @@ } +uint GetEngineProperty(EngineID engine, uint8 property, uint orig_value) +{ + uint16 callback = GetVehicleCallback(CBID_VEHICLE_MODIFY_PROPERTY, property, 0, engine, NULL); + if (callback != CALLBACK_FAILED) return callback; + + return orig_value; +} + + static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) { const SpriteGroup *group; diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_engine.h --- a/src/newgrf_engine.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_engine.h Wed Jun 13 11:45:14 2007 +0000 @@ -14,6 +14,7 @@ void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, byte *train_id, int trains); +const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine); void SetCustomEngineSprites(EngineID engine, byte cargo, const struct SpriteGroup *group); void SetRotorOverrideSprites(EngineID engine, const struct SpriteGroup *group); SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle* v, Direction direction); @@ -38,6 +39,7 @@ /* Handler to Evaluate callback 36. If the callback fails (i.e. most of the * time) orig_value is returned */ uint GetVehicleProperty(const Vehicle *v, uint8 property, uint orig_value); +uint GetEngineProperty(EngineID engine, uint8 property, uint orig_value); enum VehicleTrigger { VEHICLE_TRIGGER_NEW_CARGO = 1, diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_house.cpp --- a/src/newgrf_house.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_house.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -24,92 +24,12 @@ #include "newgrf_callbacks.h" #include "newgrf_town.h" #include "newgrf_sound.h" +#include "newgrf_commons.h" static BuildingCounts _building_counts; static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; -HouseIDMapping _house_id_mapping[HOUSE_MAX]; - -/* Since the house IDs defined by the GRF file don't necessarily correlate - * to those used by the game, the IDs used for overriding old houses must be - * translated when the house spec is set. */ -static uint16 _house_overrides[NEW_HOUSE_OFFSET]; - -void AddHouseOverride(uint8 local_id, uint house_type) -{ - assert(house_type < NEW_HOUSE_OFFSET); - _house_overrides[house_type] = local_id; -} - -void ResetHouseOverrides() -{ - for (int i = 0; i != lengthof(_house_overrides); i++) { - _house_overrides[i] = INVALID_HOUSE_ID; - } -} - -static HouseID GetHouseID(byte grf_local_id, uint32 grfid) -{ - const HouseIDMapping *map; - - for (HouseID house_id = NEW_HOUSE_OFFSET; house_id != lengthof(_house_id_mapping); house_id++) { - map = &_house_id_mapping[house_id]; - if (map->house_id == grf_local_id && map->grfid == grfid) return house_id; - } - return INVALID_HOUSE_ID; -} - -static HouseID AddHouseID(byte grf_local_id, uint32 grfid, byte substitute_id) -{ - HouseID house_id; - HouseIDMapping *map; - /* Look to see if this house has already been added. This is done - * separately from the loop below in case a GRF has been deleted, and there - * are any gaps in the array. */ - house_id = GetHouseID(grf_local_id, grfid); - if (house_id != INVALID_HOUSE_ID) return house_id; - - /* This house hasn't been defined before, so give it an ID now. */ - for (house_id = NEW_HOUSE_OFFSET; house_id != lengthof(_house_id_mapping); house_id++) { - map = &_house_id_mapping[house_id]; - - if (map->house_id == 0 && map->grfid == 0) { - map->house_id = grf_local_id; - map->grfid = grfid; - map->substitute_id = substitute_id; - return house_id; - } - } - - return INVALID_HOUSE_ID; -} - -void SetHouseSpec(const HouseSpec *hs) -{ - HouseID house_id = AddHouseID(hs->local_id, hs->grffile->grfid, hs->substitute_id); - - if (house_id == INVALID_HOUSE_ID) { - grfmsg(1, "SetHouseSpec: Too many houses allocated. Ignoring."); - return; - } - - memcpy(&_house_specs[house_id], hs, sizeof(*hs)); - - /* Now add the overrides. */ - for (int i = 0; i != lengthof(_house_overrides); i++) { - HouseSpec *overridden_hs = GetHouseSpecs(i); - - if (_house_overrides[i] != hs->local_id) continue; - - overridden_hs->override = house_id; - _house_overrides[i] = INVALID_HOUSE_ID; - } -} - -void ResetHouseIDMapping() -{ - memset(&_house_id_mapping, 0, sizeof(_house_id_mapping)); -} +HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID); void CheckHouseIDs() { @@ -122,7 +42,7 @@ if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { /* The specs for this type of house are not available any more, so * replace it with the substitute original house type. */ - SetHouseType(t, _house_id_mapping[house_id].substitute_id); + SetHouseType(t, _house_mngr.GetSubstituteID(house_id)); } } @@ -313,7 +233,7 @@ const HouseSpec *hs = GetHouseSpecs(house_id); if (hs->grffile == NULL) return 0; - HouseID new_house = GetHouseID(parameter, hs->grffile->grfid); + HouseID new_house = _house_mngr.GetID(parameter, hs->grffile->grfid); return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, town); } @@ -374,7 +294,7 @@ res->reseed = 0; } -uint16 GetHouseCallback(uint16 callback, uint32 param1, HouseID house_id, Town *town, TileIndex tile) +uint16 GetHouseCallback(uint16 callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile) { ResolverObject object; const SpriteGroup *group; @@ -382,7 +302,7 @@ NewHouseResolver(&object, house_id, tile, town); object.callback = callback; object.callback_param1 = param1; - object.callback_param2 = 0; + object.callback_param2 = param2; group = Resolve(GetHouseSpecs(house_id)->spritegroup, &object); if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; @@ -413,7 +333,7 @@ if (pal == 0) { const HouseSpec *hs = GetHouseSpecs(house_id); if (HASBIT(hs->callback_mask, CBM_BUILDING_COLOUR)) { - uint16 callback = GetHouseCallback(CBID_BUILDING_COLOUR, 0, house_id, GetTownByTile(ti->tile), ti->tile); + uint16 callback = GetHouseCallback(CBID_BUILDING_COLOUR, 0, 0, house_id, GetTownByTile(ti->tile), ti->tile); if (callback != CALLBACK_FAILED) { /* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */ pal = HASBIT(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback; @@ -468,7 +388,7 @@ bool frame_set_by_callback = false; if (HASBIT(hs->callback_mask, CBM_ANIMATION_SPEED)) { - uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_SPEED, 0, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_SPEED, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED) animation_speed = clamp(callback_res & 0xFF, 2, 16); } @@ -483,7 +403,7 @@ if (HASBIT(hs->callback_mask, CBM_ANIMATION_NEXT_FRAME)) { uint32 param = (hs->extra_flags & CALLBACK_1A_RANDOM_BITS) ? Random() : 0; - uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_NEXT_FRAME, param, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_NEXT_FRAME, param, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED) { frame_set_by_callback = true; @@ -549,7 +469,7 @@ || _current_player == OWNER_WATER || _current_player == OWNER_NONE) return true; if (HASBIT(hs->callback_mask, CBM_HOUSE_DENY_DESTRUCTION)) { - uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); return (callback_res == CALLBACK_FAILED || callback_res == 0); } else { return !(hs->extra_flags & BUILDING_IS_PROTECTED); @@ -562,7 +482,7 @@ if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) { uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random(); - uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_START_STOP, param, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_START_STOP, param, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res); } @@ -577,7 +497,11 @@ return true; } - /* @todo: Magic with triggers goes here. Got to implement that, one day. .. */ + /* @todo: Magic with triggers goes here. Got to implement that, one day. .. + * Process randomizing of tiles following specs. + * Once done, redraw the house + * MarkTileDirtyByTile(tile); + */ if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) { /* If this house is marked as having a synchronised callback, all the @@ -598,7 +522,7 @@ /* Check callback 21, which determines if a house should be destroyed. */ if (HASBIT(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) { - uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED && callback_res > 0) { ClearTownHouse(GetTownByTile(tile), tile); return false; diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_house.h --- a/src/newgrf_house.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_house.h Wed Jun 13 11:45:14 2007 +0000 @@ -41,15 +41,7 @@ uint8 class_id; ////< The class id within the grf file }; -extern HouseIDMapping _house_id_mapping[HOUSE_MAX]; ///< Declared in newgrf_house.cpp - -void AddHouseOverride(uint8 local_id, uint house_type); -void ResetHouseOverrides(); - -void SetHouseSpec(const HouseSpec *hs); - void CheckHouseIDs(); -void ResetHouseIDMapping(); HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid); @@ -62,7 +54,7 @@ void AnimateNewHouseTile(TileIndex tile); void ChangeHouseAnimationFrame(TileIndex tile, uint16 callback_result); -uint16 GetHouseCallback(uint16 callback, uint32 param1, HouseID house_id, Town *town, TileIndex tile); +uint16 GetHouseCallback(uint16 callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile); bool CanDeleteHouse(TileIndex tile); diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_spritegroup.cpp --- a/src/newgrf_spritegroup.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_spritegroup.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -76,6 +76,8 @@ _spritegroup_count = 0; } +static uint32 _temp_store[0x110]; + static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { @@ -96,6 +98,8 @@ case 0x1C: return object->last_value; case 0x20: return _opt.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF; + case 0x7D: return _temp_store[parameter]; + /* Not a common variable, so evalute the feature specific variables */ default: return object->GetVariable(object, variable, parameter, available); } @@ -125,14 +129,18 @@ case DSGA_OP_SMAX: return max((S)last_value, (S)value); case DSGA_OP_UMIN: return min((U)last_value, (U)value); case DSGA_OP_UMAX: return max((U)last_value, (U)value); - case DSGA_OP_SDIV: return (S)last_value / (S)value; - case DSGA_OP_SMOD: return (S)last_value % (S)value; - case DSGA_OP_UDIV: return (U)last_value / (U)value; - case DSGA_OP_UMOD: return (U)last_value % (U)value; + case DSGA_OP_SDIV: return value == 0 ? (S)last_value : (S)last_value / (S)value; + case DSGA_OP_SMOD: return value == 0 ? (S)last_value : (S)last_value % (S)value; + case DSGA_OP_UDIV: return value == 0 ? (U)last_value : (U)last_value / (U)value; + case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value; case DSGA_OP_MUL: return last_value * value; case DSGA_OP_AND: return last_value & value; case DSGA_OP_OR: return last_value | value; case DSGA_OP_XOR: return last_value ^ value; + case DSGA_OP_STO: + if (value < lengthof(_temp_store)) _temp_store[value] = last_value; + return last_value; + case DSGA_OP_RST: return value; default: return value; } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_spritegroup.h --- a/src/newgrf_spritegroup.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_spritegroup.h Wed Jun 13 11:45:14 2007 +0000 @@ -60,6 +60,8 @@ DSGA_OP_AND, ///< a & b DSGA_OP_OR, ///< a | b DSGA_OP_XOR, ///< a ^ b + DSGA_OP_STO, ///< store a into temporary storage, indexed by b. return a + DSGA_OP_RST, ///< return b }; @@ -182,6 +184,9 @@ } vehicle; struct { TileIndex tile; + } canal; + struct { + TileIndex tile; const struct Station *st; const struct StationSpec *statspec; CargoID cargo_type; diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_text.cpp --- a/src/newgrf_text.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_text.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -45,9 +45,11 @@ GRFLX_GERMAN = 0x02, GRFLX_FRENCH = 0x03, GRFLX_SPANISH = 0x04, + GRFLX_ESPERANTO = 0x05, GRFLX_RUSSIAN = 0x07, GRFLX_CZECH = 0x15, GRFLX_SLOVAK = 0x16, + GRFLX_BULGARIAN = 0x18, GRFLX_AFRIKAANS = 0x1B, GRFLX_GREEK = 0x1E, GRFLX_DUTCH = 0x1F, @@ -71,6 +73,8 @@ GRFLX_PORTUGUESE = 0x36, GRFLX_BRAZILIAN = 0x37, GRFLX_CROATIAN = 0x38, + GRFLX_JAPANESE = 0x39, + GRFLX_KOREAN = 0x3A, GRFLX_TURKISH = 0x3E, GRFLX_UNSPECIFIED = 0x7F, }; @@ -122,6 +126,10 @@ {"sv_SE", GRFLX_SWEDISH}, {"tr_TR", GRFLX_TURKISH}, {"uk_UA", GRFLX_UKRAINIAN}, + {"eo_EO", GRFLX_ESPERANTO}, + {"bg_BG", GRFLX_BULGARIAN}, + {"ja_JP", GRFLX_JAPANESE}, + {"ko_KR", GRFLX_KOREAN}, {"gen", GRFLB_GENERIC} ///< this is not iso code, but there has to be something... }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/newgrf_town.cpp --- a/src/newgrf_town.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/newgrf_town.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -4,6 +4,7 @@ #include "stdafx.h" #include "openttd.h" +#include "variables.h" #include "debug.h" #include "functions.h" #include "town.h" @@ -18,7 +19,10 @@ { switch (variable) { /* Larger towns */ - case 0x40: return 1; + case 0x40: + if (_patches.larger_towns == 0) return 2; + if (t->larger_town) return 1; + return 0; /* Town index */ case 0x41: return t->index; diff -r 0b2aebc8283e -r 0b8b245a2391 src/news_gui.cpp --- a/src/news_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/news_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -427,7 +427,7 @@ w = AllocateWindowDesc(&_news_type13_desc); if (ni->flags & NF_VIEWPORT) AssignWindowViewport(w, 2, 58, 0x1AA, 0x6E, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0); + ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); break; } @@ -436,7 +436,7 @@ w = AllocateWindowDesc(&_news_type2_desc); if (ni->flags & NF_VIEWPORT) AssignWindowViewport(w, 2, 58, 0x1AA, 0x46, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0); + ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); break; } @@ -445,7 +445,7 @@ w = AllocateWindowDesc(&_news_type0_desc); if (ni->flags & NF_VIEWPORT) AssignWindowViewport(w, 3, 17, 0x112, 0x2F, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), 0); + ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); break; } } @@ -620,15 +620,21 @@ * from it such as big fonts, etc. */ ptr = buffer; dest = buffer2; + WChar c_last = '\0'; for (;;) { WChar c = Utf8Consume(&ptr); if (c == 0) break; - if (c == '\r') { + /* Make a space from a newline, but ignore multiple newlines */ + if (c == '\n' && c_last != '\n') { + dest[0] = ' '; + dest++; + } else if (c == '\r') { dest[0] = dest[1] = dest[2] = dest[3] = ' '; dest += 4; } else if (IsPrintable(c)) { dest += Utf8Encode(dest, c); } + c_last = c; } *dest = '\0'; diff -r 0b2aebc8283e -r 0b8b245a2391 src/oldloader.cpp --- a/src/oldloader.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/oldloader.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -15,6 +15,10 @@ #include "player.h" #include "engine.h" #include "vehicle.h" +#include "aircraft.h" +#include "roadveh.h" +#include "ship.h" +#include "train.h" #include "signs.h" #include "debug.h" #include "depot.h" @@ -326,6 +330,9 @@ FOR_ALL_VEHICLES(v) { Vehicle *u; + /* We haven't used this bit for stations for ages */ + if (v->type == VEH_ROAD) CLRBIT(v->u.road.state, RVS_IS_STOPPING); + FOR_ALL_VEHICLES_FROM(u, v->index + 1) { /* If a vehicle has the same orders, add the link to eachother * in both vehicles */ @@ -619,12 +626,7 @@ }; static bool LoadOldStation(LoadgameState *ls, int num) { - Station *st; - - if (!AddBlockIfNeeded(&_Station_pool, num)) - error("Stations: failed loading savegame: too many stations"); - - st = GetStation(num); + Station *st = new (num) Station(); _current_station_id = num; if (!LoadChunk(ls, st, station_chunk)) @@ -651,8 +653,7 @@ OCL_VAR ( OC_UINT32, 1, &_old_town_index ), OCL_SVAR( OC_UINT8, Industry, width ), OCL_SVAR( OC_UINT8, Industry, height ), - OCL_SVAR( OC_UINT8, Industry, produced_cargo[0] ), - OCL_SVAR( OC_UINT8, Industry, produced_cargo[1] ), + OCL_NULL( 2 ), ///< used to be industry's produced_cargo OCL_SVAR( OC_UINT16, Industry, cargo_waiting[0] ), OCL_SVAR( OC_UINT16, Industry, cargo_waiting[1] ), @@ -660,9 +661,7 @@ OCL_SVAR( OC_UINT8, Industry, production_rate[0] ), OCL_SVAR( OC_UINT8, Industry, production_rate[1] ), - OCL_SVAR( OC_UINT8, Industry, accepts_cargo[0] ), - OCL_SVAR( OC_UINT8, Industry, accepts_cargo[1] ), - OCL_SVAR( OC_UINT8, Industry, accepts_cargo[2] ), + OCL_NULL( 3 ), ///< used to be industry's accepts_cargo OCL_SVAR( OC_UINT8, Industry, prod_level ), @@ -1072,13 +1071,13 @@ * Basically v->type -= 0x10; would suffice, but play safely */ switch (v->type) { default: NOT_REACHED(); - case 0x00 /*VEH_INVALID */: v->type = VEH_INVALID; res = LoadChunk(ls, NULL, vehicle_empty_chunk); break; - case 0x10 /*VEH_TRAIN */: v->type = VEH_TRAIN; res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; - case 0x11 /*VEH_ROAD */: v->type = VEH_ROAD; res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; - case 0x12 /*VEH_SHIP */: v->type = VEH_SHIP; res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break; - case 0x13 /*VEH_AIRCRAFT*/: v->type = VEH_AIRCRAFT; res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break; - case 0x14 /*VEH_SPECIAL */: v->type = VEH_SPECIAL; res = LoadChunk(ls, &v->u.special, vehicle_special_chunk); break; - case 0x15 /*VEH_DISASTER*/: v->type = VEH_DISASTER; res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break; + case 0x00 /*VEH_INVALID */: v = new (v) InvalidVehicle(); res = LoadChunk(ls, NULL, vehicle_empty_chunk); break; + case 0x10 /*VEH_TRAIN */: v = new (v) Train(); res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; + case 0x11 /*VEH_ROAD */: v = new (v) RoadVehicle(); res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; + case 0x12 /*VEH_SHIP */: v = new (v) Ship(); res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break; + case 0x13 /*VEH_AIRCRAFT*/: v = new (v) Aircraft(); res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break; + case 0x14 /*VEH_SPECIAL */: v = new (v) SpecialVehicle(); res = LoadChunk(ls, &v->u.special, vehicle_special_chunk); break; + case 0x15 /*VEH_DISASTER*/: v = new (v) DisasterVehicle(); res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break; } /* This chunk size should always be 10 bytes */ @@ -1114,11 +1113,9 @@ OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ), OCL_SVAR( OC_UINT8, Vehicle, z_pos ), OCL_SVAR( OC_UINT8, Vehicle, direction ), - OCL_SVAR( OC_INT8, Vehicle, x_offs ), - OCL_SVAR( OC_INT8, Vehicle, y_offs ), - OCL_SVAR( OC_UINT8, Vehicle, sprite_width ), - OCL_SVAR( OC_UINT8, Vehicle, sprite_height ), - OCL_SVAR( OC_UINT8, Vehicle, z_height ), + OCL_NULL( 2 ), ///< x_offs and y_offs, calculated automatically + OCL_NULL( 2 ), ///< sprite_width and sprite_height, calculated automatically + OCL_NULL( 1 ), ///< z_height, calculated automatically OCL_SVAR( OC_UINT8, Vehicle, owner ), OCL_SVAR( OC_TILE, Vehicle, tile ), @@ -1554,6 +1551,19 @@ for (i = 0; i < OLD_MAP_SIZE; i ++) { switch (GetTileType(i)) { + case MP_STATION: + _m[i].m4 = 0; // We do not understand this TTDP station mapping (yet) + switch (_m[i].m5) { + /* We have drive through stops at a totally different place */ + case 0x53: case 0x54: _m[i].m5 += GFX_BUS_BASE_EXT - 0x53; break; + case 0x57: case 0x58: _m[i].m5 += GFX_TRUCK_BASE_EXT - 0x57; break; + case 0x55: case 0x56: // Bus tram stop + case 0x59: case 0x5A: // Truck tram stop + DEBUG(oldloader, 0, "Loading failed - we don't support trams (yet)"); + return false; + } + break; + case MP_RAILWAY: /* We save presignals different from TTDPatch, convert them */ if (GetRailTileType(i) == RAIL_TILE_SIGNALS) { diff -r 0b2aebc8283e -r 0b8b245a2391 src/openttd.cpp --- a/src/openttd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/openttd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -61,7 +61,9 @@ #include "newgrf.h" #include "newgrf_config.h" #include "newgrf_house.h" +#include "newgrf_commons.h" #include "player_face.h" +#include "group.h" #include "bridge_map.h" #include "clear_map.h" @@ -293,6 +295,7 @@ CleanPool(&_Vehicle_pool); CleanPool(&_Sign_pool); CleanPool(&_Order_pool); + CleanPool(&_Group_pool); free((void*)_town_sort); free((void*)_industry_sort); @@ -502,6 +505,8 @@ LoadDriver(MUSIC_DRIVER, _ini_musicdriver); LoadDriver(VIDEO_DRIVER, _ini_videodriver); // load video last, to prevent an empty window while sound and music loads _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING; + /* Initialize the zoom level of the screen to normal */ + _screen.zoom = ZOOM_LVL_NORMAL; /* restore saved music volume */ _music_driver->set_volume(msf.music_vol); @@ -685,7 +690,7 @@ _game_mode = GM_NORMAL; ResetGRFConfig(true); - ResetHouseIDMapping(); + _house_mngr.ResetMapping(); GenerateWorldSetCallback(&MakeNewGameDone); GenerateWorld(from_heightmap ? GW_HEIGHTMAP : GW_NEWGAME, 1 << _patches.map_x, 1 << _patches.map_y); @@ -986,8 +991,8 @@ Window *w = FindWindowById(WC_MAIN_WINDOW, 0); assert(w); - WP(w,vp_d).scrollpos_x += x << w->viewport->zoom; - WP(w,vp_d).scrollpos_y += y << w->viewport->zoom; + WP(w,vp_d).scrollpos_x += ScaleByZoom(x, w->viewport->zoom); + WP(w,vp_d).scrollpos_y += ScaleByZoom(y, w->viewport->zoom); } } @@ -1076,7 +1081,7 @@ StateGameLoop(); #endif /* ENABLE_NETWORK */ - if (!_pause_game && _display_opt & DO_FULL_ANIMATION) DoPaletteAnimations(); + if (!_pause_game && HASBIT(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations(); if (!_pause_game || _cheats.build_in_pause.value) MoveAllTextEffects(); @@ -1103,8 +1108,8 @@ for (tile = 0; tile != MapSize(); tile++) { switch (GetTileType(tile)) { case MP_STREET: - if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) & 0x80) { - SetCrossingRoadOwner(tile, OWNER_TOWN); + if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HASBIT(_m[tile].m4, 7)) { + _m[tile].m4 = OWNER_TOWN; } /* FALLTHROUGH */ @@ -1282,8 +1287,8 @@ vp = w->viewport; vp->zoom = _saved_scrollpos_zoom; - vp->virtual_width = vp->width << vp->zoom; - vp->virtual_height = vp->height << vp->zoom; + vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); + vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); /* in version 4.1 of the savegame, is_active was introduced to determine * if a player does exist, rather then checking name_1 */ @@ -1295,8 +1300,8 @@ /* If Load Scenario / New (Scenario) Game is used, * a player does not exist yet. So create one here. * 1 exeption: network-games. Those can have 0 players - * But this exeption is not true for network_servers! */ - if (!_players[0].is_active && (!_networking || (_networking && _network_server))) + * But this exeption is not true for non dedicated network_servers! */ + if (!_players[0].is_active && (!_networking || (_networking && _network_server && !_network_dedicated))) DoStartupNewPlayer(false); DoZoomInOutWindow(ZOOM_NONE, w); // update button status @@ -1409,6 +1414,70 @@ } } + if (CheckSavegameVersion(48)) { + for (TileIndex t = 0; t < map_size; t++) { + switch (GetTileType(t)) { + case MP_RAILWAY: + if (IsPlainRailTile(t)) { + /* Swap ground type and signal type for plain rail tiles, so the + * ground type uses the same bits as for depots and waypoints. */ + uint tmp = GB(_m[t].m4, 0, 4); + SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4)); + SB(_m[t].m2, 0, 4, tmp); + } else if (HASBIT(_m[t].m5, 2)) { + /* Split waypoint and depot rail type and remove the subtype. */ + CLRBIT(_m[t].m5, 2); + CLRBIT(_m[t].m5, 6); + } + break; + + case MP_STREET: + /* Swap m3 and m4, so the track type for rail crossings is the + * same as for normal rail. */ + Swap(_m[t].m3, _m[t].m4); + break; + + default: break; + } + } + } + + if (CheckSavegameVersion(61)) { + /* Added the RoadType */ + for (TileIndex t = 0; t < map_size; t++) { + switch(GetTileType(t)) { + case MP_STREET: + SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2)); + switch (GetRoadTileType(t)) { + default: NOT_REACHED(); + case ROAD_TILE_NORMAL: + SB(_m[t].m4, 0, 4, GB(_m[t].m5, 0, 4)); + SB(_m[t].m4, 4, 4, 0); + SB(_m[t].m6, 2, 4, 0); + break; + case ROAD_TILE_CROSSING: + SB(_m[t].m4, 5, 2, GB(_m[t].m5, 2, 2)); + break; + case ROAD_TILE_DEPOT: break; + } + SetRoadTypes(t, ROADTYPES_ROAD); + break; + + case MP_STATION: + if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD); + break; + + case MP_TUNNELBRIDGE: + if ((IsTunnel(t) ? GetTunnelTransportType(t) : GetBridgeTransportType(t)) == TRANSPORT_ROAD) { + SetRoadTypes(t, ROADTYPES_ROAD); + } + break; + + default: break; + } + } + } + if (CheckSavegameVersion(42)) { Vehicle* v; @@ -1431,9 +1500,10 @@ MakeRoadNormal( t, - GetTileOwner(t), axis == AXIS_X ? ROAD_Y : ROAD_X, - town + ROADTYPES_ROAD, + town, + GetTileOwner(t), OWNER_NONE, OWNER_NONE ); } } else { @@ -1481,34 +1551,6 @@ } } - if (CheckSavegameVersion(48)) { - for (TileIndex t = 0; t < map_size; t++) { - switch (GetTileType(t)) { - case MP_RAILWAY: - if (IsPlainRailTile(t)) { - /* Swap ground type and signal type for plain rail tiles, so the - * ground type uses the same bits as for depots and waypoints. */ - uint tmp = GB(_m[t].m4, 0, 4); - SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4)); - SB(_m[t].m2, 0, 4, tmp); - } else if (HASBIT(_m[t].m5, 2)) { - /* Split waypoint and depot rail type and remove the subtype. */ - CLRBIT(_m[t].m5, 2); - CLRBIT(_m[t].m5, 6); - } - break; - - case MP_STREET: - /* Swap m3 and m4, so the track type for rail crossings is the - * same as for normal rail. */ - Swap(_m[t].m3, _m[t].m4); - break; - - default: break; - } - } - } - /* Elrails got added in rev 24 */ if (CheckSavegameVersion(24)) { Vehicle *v; @@ -1767,8 +1809,6 @@ * space for newhouses grf features. A new byte, m7, was also added. */ if (CheckSavegameVersion(53)) { for (TileIndex t = 0; t < map_size; t++) { - _me[t].m7 = 0; - if (IsTileType(t, MP_HOUSE)) { if (GB(_m[t].m3, 6, 2) != TOWN_HOUSE_COMPLETED) { /* Move the construction stage from m3[7..6] to m5[5..4]. @@ -1934,11 +1974,39 @@ !(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed v->current_order.type == OT_LOADING) { // loading GetStation(v->last_station_visited)->loading_vehicles.push_back(v); + + /* The loading finished flag is *only* set when actually completely + * finished. Because the vehicle is loading, it is not finished. */ + CLRBIT(v->vehicle_flags, VF_LOADING_FINISHED); } } } if (CheckSavegameVersion(58)) { + /* patch difficulty number_industries other then zero get bumped to +1 + * since a new option (very low at position1) has been added */ + if (_opt.diff.number_industries > 0) { + _opt.diff.number_industries++; + } + + /* Same goes for number of towns, although no test is needed, just an increment */ + _opt.diff.number_towns++; + } + + /* Recalculate */ + Group *g; + FOR_ALL_GROUPS(g) { + const Vehicle *v; + FOR_ALL_VEHICLES(v) { + if (!IsEngineCountable(v)) continue; + + if (v->group_id != g->index || v->type != g->vehicle_type || v->owner != g->owner) continue; + + g->num_engines[v->engine_type]++; + } + } + + if (CheckSavegameVersion(62)) { Town *t; FOR_ALL_TOWNS(t) t->SetActivity(1); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/openttd.h --- a/src/openttd.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/openttd.h Wed Jun 13 11:45:14 2007 +0000 @@ -40,6 +40,7 @@ struct NewsItem; struct Industry; struct DrawPixelInfo; +struct Group; typedef byte VehicleOrderID; ///< The index of an order within its current vehicle (not pool related) typedef byte CargoID; typedef byte LandscapeID; @@ -63,6 +64,7 @@ typedef uint16 WaypointID; typedef uint16 OrderID; typedef uint16 SignID; +typedef uint16 GroupID; typedef uint16 EngineRenewID; typedef uint16 DestinationID; @@ -171,12 +173,12 @@ /* Display Options */ enum { - DO_SHOW_TOWN_NAMES = 1 << 0, - DO_SHOW_STATION_NAMES = 1 << 1, - DO_SHOW_SIGNS = 1 << 2, - DO_FULL_ANIMATION = 1 << 3, - DO_FULL_DETAIL = 1 << 5, - DO_WAYPOINTS = 1 << 6, + DO_SHOW_TOWN_NAMES = 0, + DO_SHOW_STATION_NAMES = 1, + DO_SHOW_SIGNS = 2, + DO_FULL_ANIMATION = 3, + DO_FULL_DETAIL = 5, + DO_WAYPOINTS = 6, }; enum { @@ -200,6 +202,23 @@ }; #define GAME_DIFFICULTY_NUM 20 +/** + * Town Layouts + */ +enum TownLayout { + TL_NO_ROADS = 0, ///< Build no more roads, but still build houses + TL_ORIGINAL, ///< Original algorithm (min. 1 distance between roads) + TL_BETTER_ROADS, ///< Extended original algorithm (min. 2 distance between roads) + TL_2X2_GRID, ///< Geometric 2x2 grid algorithm + TL_3X3_GRID, ///< Geometric 3x3 grid algorithm + + NUM_TLS, ///< Number of town layouts +}; + +/* It needs to be 8bits, because we save and load it as such */ +/** Define basic enum properties */ +template <> struct EnumPropsT : MakeEnumPropsT {}; +typedef TinyEnumT TownLayoutByte; //typedefing-enumification of TownLayout struct GameDifficulty { int max_no_competitors; @@ -421,7 +440,7 @@ }; -enum { +enum ExpensesType { EXPENSES_CONSTRUCTION = 0, EXPENSES_NEW_VEHICLES = 1, EXPENSES_TRAIN_RUN = 2, diff -r 0b2aebc8283e -r 0b8b245a2391 src/order_cmd.cpp --- a/src/order_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/order_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -6,10 +6,10 @@ #include "openttd.h" #include "order.h" #include "airport.h" +#include "vehicle.h" #include "depot.h" #include "functions.h" #include "table/strings.h" -#include "vehicle.h" #include "waypoint.h" #include "command.h" #include "station.h" @@ -581,14 +581,14 @@ v->cur_order_index = b; - if (v->type == VEH_TRAIN) v->u.rail.days_since_order_progr = 0; - if (v->type == VEH_ROAD) ClearSlot(v); - /* NON-stop flag is misused to see if a train is in a station that is - * on his order list or not */ - if (v->current_order.type == OT_LOADING && HASBIT(v->current_order.flags, OFB_NON_STOP)) - v->current_order.flags = 0; + if (v->current_order.type == OT_LOADING) { + v->LeaveStation(); + /* NON-stop flag is misused to see if a train is in a station that is + * on his order list or not */ + if (HASBIT(v->current_order.flags, OFB_NON_STOP)) v->current_order.flags = 0; + } InvalidateVehicleOrder(v); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/player.h --- a/src/player.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/player.h Wed Jun 13 11:45:14 2007 +0000 @@ -311,7 +311,7 @@ * @return The engine type to replace with, or INVALID_ENGINE if no * replacement is in the list. */ -static inline EngineID EngineReplacementForPlayer(const Player *p, EngineID engine) { return EngineReplacement(p->engine_renew_list, engine); } +static inline EngineID EngineReplacementForPlayer(const Player *p, EngineID engine, GroupID group) { return EngineReplacement(p->engine_renew_list, engine, group); } /** * Check if a player has a replacement set up for the given engine. @@ -319,7 +319,7 @@ * @param engine Engine type to be replaced. * @return true if a replacement was set up, false otherwise. */ -static inline bool EngineHasReplacementForPlayer(const Player *p, EngineID engine) { return EngineReplacementForPlayer(p, engine) != INVALID_ENGINE; } +static inline bool EngineHasReplacementForPlayer(const Player *p, EngineID engine, GroupID group) { return EngineReplacementForPlayer(p, engine, group) != INVALID_ENGINE; } /** * Add an engine replacement for the player. @@ -329,7 +329,7 @@ * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -static inline int32 AddEngineReplacementForPlayer(Player *p, EngineID old_engine, EngineID new_engine, uint32 flags) { return AddEngineReplacement(&p->engine_renew_list, old_engine, new_engine, flags); } +static inline int32 AddEngineReplacementForPlayer(Player *p, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags) { return AddEngineReplacement(&p->engine_renew_list, old_engine, new_engine, group, flags); } /** * Remove an engine replacement for the player. @@ -338,7 +338,7 @@ * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -static inline int32 RemoveEngineReplacementForPlayer(Player *p, EngineID engine, uint32 flags) {return RemoveEngineReplacement(&p->engine_renew_list, engine, flags); } +static inline int32 RemoveEngineReplacementForPlayer(Player *p, EngineID engine, GroupID group, uint32 flags) {return RemoveEngineReplacement(&p->engine_renew_list, engine, group, flags); } /** * Reset the livery schemes to the player's primary colour. diff -r 0b2aebc8283e -r 0b8b245a2391 src/players.cpp --- a/src/players.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/players.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -27,6 +27,7 @@ #include "date.h" #include "window.h" #include "player_face.h" +#include "group.h" /** * Sets the local player and updates the patch settings that are set on a @@ -638,6 +639,7 @@ * if p1 = 2, then * - p2 = minimum amount of money available * if p1 = 3, then: + * - p1 bits 8-15 = engine group * - p2 bits 0-15 = old engine type * - p2 bits 16-31 = new engine type * if p1 = 4, then: @@ -693,8 +695,10 @@ case 3: { EngineID old_engine_type = GB(p2, 0, 16); EngineID new_engine_type = GB(p2, 16, 16); + GroupID id_g = GB(p1, 16, 16); int32 cost; + if (!IsValidGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; if (new_engine_type != INVALID_ENGINE) { /* First we make sure that it's a valid type the user requested * check that it's an engine that is in the engine array */ @@ -714,9 +718,9 @@ if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player)) return CMD_ERROR; - cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, flags); + cost = AddEngineReplacementForPlayer(p, old_engine_type, new_engine_type, id_g, flags); } else { - cost = RemoveEngineReplacementForPlayer(p, old_engine_type, flags); + cost = RemoveEngineReplacementForPlayer(p, old_engine_type,id_g, flags); } if (IsLocalPlayer()) InvalidateAutoreplaceWindow(old_engine_type); @@ -901,6 +905,7 @@ p->is_active = false; } RemoveAllEngineReplacementForPlayer(p); + RemoveAllGroupsForPlayer(p); } break; @@ -1109,7 +1114,7 @@ SLE_VAR(Player, player_color, SLE_UINT8), SLE_VAR(Player, player_money_fraction, SLE_UINT8), - SLE_VAR(Player, avail_railtypes, SLE_UINT8), + SLE_CONDVAR(Player, avail_railtypes, SLE_UINT8, 0, 57), SLE_VAR(Player, block_preview, SLE_UINT8), SLE_VAR(Player, cargo_types, SLE_UINT16), diff -r 0b2aebc8283e -r 0b8b245a2391 src/rail_cmd.cpp --- a/src/rail_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/rail_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -296,10 +296,25 @@ if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); - if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) || - (track == TRACK_Y && GetRoadBits(tile) == ROAD_X)) { + RoadTypes roadtypes = GetRoadTypes(tile); + RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD); + RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM); + switch (roadtypes) { + default: break; + case ROADTYPES_ROADTRAM: if (road == tram) break; + /* FALL THROUGH */ + case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case + case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case + case ROADTYPES_ALL: // Also incompatible + return CMD_ERROR; + } + + road |= tram | GetRoadBits(tile, ROADTYPE_HWAY); + + if ((track == TRACK_X && road == ROAD_Y) || + (track == TRACK_Y && road == ROAD_X)) { if (flags & DC_EXEC) { - MakeRoadCrossing(tile, GetTileOwner(tile), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, GetTownIndex(tile)); + MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile)); } break; } @@ -362,7 +377,7 @@ cost += _eco->GetPrice(CEconomy::PRICE_RAIL_REMOVE, tile, true); if (flags & DC_EXEC) { - MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile)); + MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); } break; } @@ -1328,7 +1343,7 @@ DrawTrackBits(ti, rails); - if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti); + if (HASBIT(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti); if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails); } else { diff -r 0b2aebc8283e -r 0b8b245a2391 src/rail_gui.cpp --- a/src/rail_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/rail_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -72,7 +72,7 @@ static void PlaceRail_NE(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_FIX_Y); + VpStartPlaceSizing(tile, VPM_FIX_Y, GUI_PlaceProc_None); } static void PlaceRail_E(TileIndex tile) @@ -83,12 +83,12 @@ static void PlaceRail_NW(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_FIX_X); + VpStartPlaceSizing(tile, VPM_FIX_X, GUI_PlaceProc_None); } static void PlaceRail_AutoRail(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_RAILDIRS); + VpStartPlaceSizing(tile, VPM_RAILDIRS, GUI_PlaceProc_None); } static void PlaceExtraDepotRail(TileIndex tile, uint16 extra) @@ -151,9 +151,9 @@ static void PlaceRail_Station(TileIndex tile) { if (_remove_button_clicked) { - DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION)); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_RemoveFromStation); } else if (_railstation.dragdrop) { - VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED); + VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, GUI_PlaceProc_None); VpSetPlaceSizingLimit(_patches.station_spread); } else { DoCommandP(tile, @@ -197,7 +197,7 @@ static void PlaceRail_Bridge(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_OR_Y); + VpStartPlaceSizing(tile, VPM_X_OR_Y, GUI_PlaceProc_None); } void CcBuildRailTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2) @@ -223,12 +223,12 @@ static void PlaceRail_ConvertRail(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_ConvertRailArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_ConvertRailArea); } static void PlaceRail_AutoSignals(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_SIGNALDIRS); + VpStartPlaceSizing(tile, VPM_SIGNALDIRS, GUI_PlaceProc_None); } @@ -492,7 +492,7 @@ return; case WE_PLACE_DRAG: { - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); return; } @@ -501,25 +501,45 @@ TileIndex start_tile = e->we.place.starttile; TileIndex end_tile = e->we.place.tile; - if (e->we.place.userdata == VPM_X_OR_Y) { - ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, _cur_railtype); - } else if (e->we.place.userdata == VPM_RAILDIRS) { - bool old = _remove_button_clicked; - if (_ctrl_pressed) _remove_button_clicked = true; - HandleAutodirPlacement(); - _remove_button_clicked = old; - } else if (e->we.place.userdata == VPM_SIGNALDIRS) { - HandleAutoSignalPlacement(); - } else if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) { - if (GUIPlaceProcDragXY(e)) break; + switch (e->we.place.select_method) { + case VPM_X_OR_Y: + ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, _cur_railtype); + break; - if ((e->we.place.userdata >> 4) == GUI_PlaceProc_ConvertRailArea >> 4) - DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL)); - } else if (e->we.place.userdata == VPM_X_AND_Y_LIMITED) { - HandleStationPlacement(start_tile, end_tile); - } else { - DoRailroadTrack(e->we.place.userdata & 1); + case VPM_RAILDIRS: { + bool old = _remove_button_clicked; + if (_ctrl_pressed) _remove_button_clicked = true; + HandleAutodirPlacement(); + _remove_button_clicked = old; + break; + } + + case VPM_SIGNALDIRS: + HandleAutoSignalPlacement(); + break; + + case VPM_X_AND_Y: + if (GUIPlaceProcDragXY(e)) break; + + switch (e->we.place.select_proc) { + case GUI_PlaceProc_RemoveFromStation: + DoCommandP(end_tile, start_tile, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION)); + break; + + case GUI_PlaceProc_ConvertRailArea: + DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL)); + break; + } + break; + + case VPM_X_AND_Y_LIMITED: + HandleStationPlacement(start_tile, end_tile); + break; + + default: + DoRailroadTrack(e->we.place.select_method == VPM_FIX_Y ? TRACK_X : TRACK_Y); + break; } } break; diff -r 0b2aebc8283e -r 0b8b245a2391 src/rail_map.h --- a/src/rail_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/rail_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -10,13 +10,21 @@ #include "tile.h" +/** Different types of Rail-related tiles */ enum RailTileType { - RAIL_TILE_NORMAL = 0, - RAIL_TILE_SIGNALS = 1, - RAIL_TILE_WAYPOINT = 2, - RAIL_TILE_DEPOT = 3, + RAIL_TILE_NORMAL = 0, ///< Normal rail tile without signals + RAIL_TILE_SIGNALS = 1, ///< Normal rail tile with signals + RAIL_TILE_WAYPOINT = 2, ///< Waypoint (X or Y direction) + RAIL_TILE_DEPOT = 3, ///< Depot (one entrance) }; +/** + * Returns the RailTileType (normal with or without signals, + * waypoint or depot). + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return the RailTileType + */ static inline RailTileType GetRailTileType(TileIndex t) { assert(IsTileType(t, MP_RAILWAY)); @@ -26,23 +34,32 @@ /** * Returns whether this is plain rails, with or without signals. Iow, if this * tiles RailTileType is RAIL_TILE_NORMAL or RAIL_TILE_SIGNALS. + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is normal rail (with or without signals) */ -static inline bool IsPlainRailTile(TileIndex tile) +static inline bool IsPlainRailTile(TileIndex t) { - RailTileType rtt = GetRailTileType(tile); + RailTileType rtt = GetRailTileType(t); return rtt == RAIL_TILE_NORMAL || rtt == RAIL_TILE_SIGNALS; } /** * Checks if a rail tile has signals. + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile has signals */ -static inline bool HasSignals(TileIndex tile) +static inline bool HasSignals(TileIndex t) { - return GetRailTileType(tile) == RAIL_TILE_SIGNALS; + return GetRailTileType(t) == RAIL_TILE_SIGNALS; } /** * Add/remove the 'has signal' bit from the RailTileType + * @param tile the tile to add/remove the signals to/from + * @param signals whether the rail tile should have signals or not + * @pre IsPlainRailTile(tile) */ static inline void SetHasSignals(TileIndex tile, bool signals) { @@ -50,81 +67,144 @@ SB(_m[tile].m5, 6, 1, signals); } - +/** + * Is this tile a rail depot? + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is a rail depot + */ static inline bool IsRailDepot(TileIndex t) { return GetRailTileType(t) == RAIL_TILE_DEPOT; } - +/** + * Is this tile a rail waypoint? + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is a rail waypoint + */ static inline bool IsRailWaypoint(TileIndex t) { return GetRailTileType(t) == RAIL_TILE_WAYPOINT; } +/** + * Gets the rail type of the given tile + * @param t the tile to get the rail type from + * @return the rail type of the tile + */ static inline RailType GetRailType(TileIndex t) { return (RailType)GB(_m[t].m3, 0, 4); } +/** + * Sets the track bits of the given tile + * @param t the tile to set the track bits of + * @param r the new track bits for the tile + */ static inline void SetRailType(TileIndex t, RailType r) { SB(_m[t].m3, 0, 4, r); } +/** + * Gets the rail type of the given tile + * @param t the tile to get the rail type from + * @return the rail type of the tile + */ static inline TrackBits GetTrackBits(TileIndex tile) { return (TrackBits)GB(_m[tile].m5, 0, 6); } +/** + * Sets the track bits of the given tile + * @param t the tile to set the track bits of + * @param b the new track bits for the tile + */ static inline void SetTrackBits(TileIndex t, TrackBits b) { SB(_m[t].m5, 0, 6, b); } /** - * Returns whether the given track is present on the given tile. Tile must be - * a plain rail tile (IsPlainRailTile()). + * Returns whether the given track is present on the given tile. + * @param tile the tile to check the track presence of + * @param track the track to search for on the tile + * @pre IsPlainRailTile(tile) + * @return true if and only if the given track exists on the tile */ static inline bool HasTrack(TileIndex tile, Track track) { return HASBIT(GetTrackBits(tile), track); } - +/** + * Returns the direction the depot is facing to + * @param t the tile to get the depot facing from + * @pre IsRailDepotTile(t) + * @return the direction the depot is facing + */ static inline DiagDirection GetRailDepotDirection(TileIndex t) { return (DiagDirection)GB(_m[t].m5, 0, 2); } +/** + * Returns the axis of the waypoint + * @param t the tile to get the waypoint axis from + * @pre IsRailWaypointTile(t) + * @return the axis of the waypoint + */ static inline Axis GetWaypointAxis(TileIndex t) { return (Axis)GB(_m[t].m5, 0, 1); } +/** + * Returns the track of the waypoint + * @param t the tile to get the waypoint track from + * @pre IsRailWaypointTile(t) + * @return the track of the waypoint + */ static inline Track GetRailWaypointTrack(TileIndex t) { return AxisToTrack(GetWaypointAxis(t)); } +/** + * Returns the track bits of the waypoint + * @param t the tile to get the waypoint track bits from + * @pre IsRailWaypointTile(t) + * @return the track bits of the waypoint + */ static inline TrackBits GetRailWaypointBits(TileIndex t) { return TrackToTrackBits(GetRailWaypointTrack(t)); } +/** + * Returns waypoint index (for the waypoint pool) + * @param t the tile to get the waypoint index from + * @pre IsRailWaypointTile(t) + * @return the waypoint index + */ static inline WaypointID GetWaypointIndex(TileIndex t) { return (WaypointID)_m[t].m2; } +/** Type of signal, i.e. how does the signal behave? */ enum SignalType { - SIGTYPE_NORMAL = 0, // normal signal - SIGTYPE_ENTRY = 1, // presignal block entry - SIGTYPE_EXIT = 2, // presignal block exit - SIGTYPE_COMBO = 3 // presignal inter-block + SIGTYPE_NORMAL = 0, ///< normal signal + SIGTYPE_ENTRY = 1, ///< presignal block entry + SIGTYPE_EXIT = 2, ///< presignal block exit + SIGTYPE_COMBO = 3 ///< presignal inter-block }; static inline SignalType GetSignalType(TileIndex t) @@ -160,10 +240,10 @@ SB(_m[t].m3, pos, 2, sig); } - +/** Variant of the signal, i.e. how does the signal look? */ enum SignalVariant { - SIG_ELECTRIC = 0, - SIG_SEMAPHORE = 1 + SIG_ELECTRIC = 0, ///< Light signal + SIG_SEMAPHORE = 1 ///< Old-fashioned semaphore signal }; static inline SignalVariant GetSignalVariant(TileIndex t) @@ -186,8 +266,8 @@ * normal boolean evaluation, since that will make future additions easier. */ enum SignalState { - SIGNAL_STATE_RED = 0, - SIGNAL_STATE_GREEN = 1, + SIGNAL_STATE_RED = 0, ///< The signal is red + SIGNAL_STATE_GREEN = 1, ///< The signal is green }; static inline SignalState GetSingleSignalState(TileIndex t, byte signalbit) @@ -243,21 +323,21 @@ */ RailType GetTileRailType(TileIndex tile); - +/** The ground 'under' the rail */ enum RailGroundType { - RAIL_GROUND_BARREN = 0, - RAIL_GROUND_GRASS = 1, - RAIL_GROUND_FENCE_NW = 2, - RAIL_GROUND_FENCE_SE = 3, - RAIL_GROUND_FENCE_SENW = 4, - RAIL_GROUND_FENCE_NE = 5, - RAIL_GROUND_FENCE_SW = 6, - RAIL_GROUND_FENCE_NESW = 7, - RAIL_GROUND_FENCE_VERT1 = 8, - RAIL_GROUND_FENCE_VERT2 = 9, - RAIL_GROUND_FENCE_HORIZ1 = 10, - RAIL_GROUND_FENCE_HORIZ2 = 11, - RAIL_GROUND_ICE_DESERT = 12, + RAIL_GROUND_BARREN = 0, ///< Nothing (dirt) + RAIL_GROUND_GRASS = 1, ///< Grassy + RAIL_GROUND_FENCE_NW = 2, ///< Grass with a fence at the NW edge + RAIL_GROUND_FENCE_SE = 3, ///< Grass with a fence at the SE edge + RAIL_GROUND_FENCE_SENW = 4, ///< Grass with a fence at the NW and SE edges + RAIL_GROUND_FENCE_NE = 5, ///< Grass with a fence at the NE edge + RAIL_GROUND_FENCE_SW = 6, ///< Grass with a fence at the SW edge + RAIL_GROUND_FENCE_NESW = 7, ///< Grass with a fence at the NE and SW edges + RAIL_GROUND_FENCE_VERT1 = 8, ///< Grass with a fence at the western side + RAIL_GROUND_FENCE_VERT2 = 9, ///< Grass with a fence at the eastern side + RAIL_GROUND_FENCE_HORIZ1 = 10, ///< Grass with a fence at the southern side + RAIL_GROUND_FENCE_HORIZ2 = 11, ///< Grass with a fence at the northern side + RAIL_GROUND_ICE_DESERT = 12, ///< Icy or sandy }; static inline void SetRailGroundType(TileIndex t, RailGroundType rgt) diff -r 0b2aebc8283e -r 0b8b245a2391 src/road.h --- a/src/road.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road.h Wed Jun 13 11:45:14 2007 +0000 @@ -7,6 +7,68 @@ #include "helpers.hpp" +/** + * The different roadtypes we support + * @note currently only ROADTYPE_ROAD is supported. + */ +enum RoadType { + ROADTYPE_ROAD = 0, + ROADTYPE_TRAM = 1, + ROADTYPE_HWAY = 2, ///< Only a placeholder. Not sure what we are going to do with this road type. + ROADTYPE_END, + INVALID_ROADTYPE = 0xFF +}; +DECLARE_POSTFIX_INCREMENT(RoadType); + +/** + * The different roadtypes we support, but then a bitmask of them + * @note currently only ROADTYPES_ROAD is supported. + */ +enum RoadTypes { + ROADTYPES_NONE = 0, + ROADTYPES_ROAD = 1 << ROADTYPE_ROAD, + ROADTYPES_TRAM = 1 << ROADTYPE_TRAM, + ROADTYPES_HWAY = 1 << ROADTYPE_HWAY, + ROADTYPES_ROADTRAM = ROADTYPES_ROAD | ROADTYPES_TRAM, + ROADTYPES_ROADHWAY = ROADTYPES_ROAD | ROADTYPES_HWAY, + ROADTYPES_TRAMHWAY = ROADTYPES_TRAM | ROADTYPES_HWAY, + ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM | ROADTYPES_HWAY, +}; +DECLARE_ENUM_AS_BIT_SET(RoadTypes); + +/** + * Whether the given roadtype is valid. + * @param rt the roadtype to check for validness + * @return true if and only if valid + */ +static inline bool IsValidRoadType(RoadType rt) +{ + return rt == ROADTYPE_ROAD; +} + +/** + * Are the given bits pointing to valid roadtypes? + * @param rts the roadtypes to check for validness + * @return true if and only if valid + */ +static inline bool AreValidRoadTypes(RoadTypes rts) +{ + return rts == ROADTYPES_ROAD; +} + +/** + * Maps a RoadType to the corresponding RoadTypes value + */ +static inline RoadTypes RoadTypeToRoadTypes(RoadType rt) +{ + return (RoadTypes)(1 << rt); +} + +static inline RoadTypes ComplementRoadTypes(RoadTypes r) +{ + return (RoadTypes)(ROADTYPES_ALL ^ r); +} + enum RoadBits { ROAD_NONE = 0U, ROAD_NW = 1U, @@ -48,8 +110,9 @@ * @param remove the roadbits that are going to be removed * @param owner the actual owner of the roadbits of the tile * @param edge_road are the removed bits from a town? + * @param rt the road type to remove the bits from * @return true when it is allowed to remove the road bits */ -bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road); +bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt); #endif /* ROAD_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/road_cmd.cpp --- a/src/road_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -26,6 +26,7 @@ #include "sound.h" #include "yapf/yapf.h" #include "depot.h" +#include "newgrf.h" static uint CountRoadBits(RoadBits r) @@ -40,13 +41,13 @@ } -bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road) +bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt) { RoadBits present; RoadBits n; *edge_road = true; - if (_game_mode == GM_EDITOR) return true; + if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return true; /* Only do the special processing for actual players. */ if (!IsValidPlayer(_current_player)) return true; @@ -59,11 +60,11 @@ /* Get a bitmask of which neighbouring roads has a tile */ n = ROAD_NONE; - present = GetAnyRoadBits(tile); - if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0)) & ROAD_SW) n |= ROAD_NE; - if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE; - if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW; - if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1)) & ROAD_SE) n |= ROAD_NW; + present = GetAnyRoadBits(tile, rt); + if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0), rt) & ROAD_SW) n |= ROAD_NE; + if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1), rt) & ROAD_NW) n |= ROAD_SE; + if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rt) & ROAD_NE) n |= ROAD_SW; + if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rt) & ROAD_SE) n |= ROAD_NW; /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, * then allow it */ @@ -83,15 +84,16 @@ return true; } -static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road) +static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road, RoadType rt) { - return CheckAllowRemoveRoad(tile, remove, IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile), edge_road); + return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt); } /** Delete a piece of road. * @param tile tile where to remove road from * @param flags operation to perform * @param p1 bit 0..3 road pieces to remove (RoadBits) + * bit 4..5 road type * @param p2 unused */ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) @@ -99,7 +101,6 @@ /* cost for removing inner/edge -roads */ static const uint16 road_remove_cost[2] = {50, 18}; - Owner owner; Town *t; /* true if the roadpiece was always removeable, * false if it was a center piece. Affects town ratings drop */ @@ -107,9 +108,10 @@ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); - if (!IsTileType(tile, MP_STREET)) return CMD_ERROR; + RoadType rt = (RoadType)GB(p1, 4, 2); + if (!IsTileType(tile, MP_STREET) || !IsValidRoadType(rt)) return CMD_ERROR; - owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile); + Owner owner = GetRoadOwner(tile, rt); if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) { t = GetTownByTile(tile); @@ -118,8 +120,11 @@ } RoadBits pieces = Extract(p1); + RoadTypes rts = GetRoadTypes(tile); + /* The tile doesn't have the given road type */ + if (!HASBIT(rts, rt)) return CMD_ERROR; - if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR; + if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR; if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; @@ -129,7 +134,7 @@ switch (GetRoadTileType(tile)) { case ROAD_TILE_NORMAL: { - RoadBits present = GetRoadBits(tile); + RoadBits present = GetRoadBits(tile, rt); RoadBits c = pieces; if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); @@ -142,16 +147,22 @@ /* limit the bits to delete to the existing bits. */ c &= present; - if (c == 0) return CMD_ERROR; + if (c == ROAD_NONE) return CMD_ERROR; present ^= c; if (flags & DC_EXEC) { ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); - if (present == 0) { - DoClearSquare(tile); + if (present == ROAD_NONE) { + RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); + if (rts == ROADTYPES_NONE) { + DoClearSquare(tile); + } else { + SetRoadBits(tile, ROAD_NONE, rt); + SetRoadTypes(tile, rts); + } } else { - SetRoadBits(tile, present); + SetRoadBits(tile, present, rt); MarkTileDirtyByTile(tile); } } @@ -164,9 +175,16 @@ } if (flags & DC_EXEC) { - ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); + if (rt == ROADTYPE_ROAD) { + ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); + } - MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile)); + RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); + if (rts == ROADTYPES_NONE) { + MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile)); + } else { + SetRoadTypes(tile, rts); + } MarkTileDirtyByTile(tile); YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); } @@ -254,6 +272,7 @@ * @param tile tile where to build road * @param flags operation to perform * @param p1 bit 0..3 road pieces to build (RoadBits) + * bit 4..5 road type * @param p2 the town that is building the road (0 if not applicable) */ int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) @@ -271,6 +290,9 @@ RoadBits pieces = Extract(p1); + RoadType rt = (RoadType)GB(p1, 4, 2); + if (!IsValidRoadType(rt)) return CMD_ERROR; + tileh = GetTileSlope(tile, NULL); switch (GetTileType(tile)) { @@ -278,8 +300,9 @@ switch (GetRoadTileType(tile)) { case ROAD_TILE_NORMAL: if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); + if (!HASBIT(GetRoadTypes(tile), rt)) break; - existing = GetRoadBits(tile); + existing = GetRoadBits(tile, rt); if ((existing & pieces) == pieces) { return_cmd_error(STR_1007_ALREADY_BUILT); } @@ -287,10 +310,9 @@ break; case ROAD_TILE_CROSSING: - if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct? - return_cmd_error(STR_1007_ALREADY_BUILT); - } - goto do_clear; + if (HASBIT(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT); + if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) goto do_clear; + break; default: case ROAD_TILE_DEPOT: @@ -331,7 +353,7 @@ if (flags & DC_EXEC) { YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); - MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2); + MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt), p2); MarkTileDirtyByTile(tile); } /** @todo should be more expensive */ @@ -365,9 +387,13 @@ if (flags & DC_EXEC) { if (IsTileType(tile, MP_STREET)) { - SetRoadBits(tile, existing | pieces); + if (existing == ROAD_NONE) { + SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); + SetRoadOwner(tile, rt, _current_player); + } + SetRoadBits(tile, existing | pieces, rt); } else { - MakeRoadNormal(tile, _current_player, pieces, p2); + MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player); } MarkTileDirtyByTile(tile); @@ -414,6 +440,7 @@ * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) + * - p2 = (bit 3 + 4) - road type */ int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) { @@ -425,6 +452,8 @@ if (p1 >= MapSize()) return CMD_ERROR; start_tile = p1; + RoadType rt = (RoadType)GB(p2, 3, 2); + if (!IsValidRoadType(rt)) return CMD_ERROR; /* Only drag in X or Y direction dictated by the direction variable */ if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis @@ -447,7 +476,7 @@ if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; - ret = DoCommand(tile, bits, 0, flags, CMD_BUILD_ROAD); + ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); if (CmdFailed(ret)) { if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR; _error_message = INVALID_STRING_ID; @@ -471,6 +500,7 @@ * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) + * - p2 = (bit 3 + 4) - road type */ int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) { @@ -482,6 +512,8 @@ if (p1 >= MapSize()) return CMD_ERROR; start_tile = p1; + RoadType rt = (RoadType)GB(p2, 3, 2); + if (!IsValidRoadType(rt)) return CMD_ERROR; /* Only drag in X or Y direction dictated by the direction variable */ if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis @@ -506,7 +538,7 @@ /* try to remove the halves. */ if (bits != 0) { - ret = DoCommand(tile, bits, 0, flags, CMD_REMOVE_ROAD); + ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD); if (!CmdFailed(ret)) cost += ret; } @@ -522,6 +554,7 @@ * @param tile tile where to build the depot * @param flags operation to perform * @param p1 bit 0..1 entrance direction (DiagDirection) + * bit 2..3 road type * @param p2 unused * * @todo When checking for the tile slope, @@ -536,6 +569,9 @@ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); DiagDirection dir = Extract(p1); + RoadType rt = (RoadType)GB(p1, 2, 2); + + if (!IsValidRoadType(rt)) return CMD_ERROR; tileh = GetTileSlope(tile, NULL); if (tileh != SLOPE_FLAT && ( @@ -560,7 +596,7 @@ dep->xy = tile; dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index; - MakeRoadDepot(tile, _current_player, dir); + MakeRoadDepot(tile, _current_player, dir, rt); MarkTileDirtyByTile(tile); } return cost; @@ -582,7 +618,7 @@ { switch (GetRoadTileType(tile)) { case ROAD_TILE_NORMAL: { - RoadBits b = GetRoadBits(tile); + RoadBits b = GetAllRoadBits(tile); #define M(x) (1 << (x)) /* Clear the road if only one piece is on the tile OR the AI tries @@ -668,12 +704,29 @@ }; /** + * Whether to draw unpaved roads regardless of the town zone. + * By default, OpenTTD always draws roads as unpaved if they are on a desert + * tile or above the snowline. Newgrf files, however, can set a bit that allows + * paved roads to be built on desert tiles as they would be on grassy tiles. + * + * @param tile The tile the road is on + * @param roadside What sort of road this is + * @return True if the road should be drawn unpaved regardless of the roadside. + */ +static bool AlwaysDrawUnpavedRoads(TileIndex tile, Roadside roadside) +{ + return (IsOnSnow(tile) && + !(_opt.landscape == LT_TROPIC && HasGrfMiscBit(GMB_DESERT_PAVED_ROADS) && + roadside != ROADSIDE_BARREN && roadside != ROADSIDE_GRASS && roadside != ROADSIDE_GRASS_ROAD_WORKS)); +} + +/** * Draw ground sprite and road pieces * @param ti TileInfo */ static void DrawRoadBits(TileInfo* ti) { - RoadBits road = GetRoadBits(ti->tile); + RoadBits road = GetRoadBits(ti->tile, ROADTYPE_ROAD); const DrawRoadTileStruct *drts; SpriteID image = 0; SpriteID pal = PAL_NONE; @@ -693,7 +746,7 @@ roadside = GetRoadside(ti->tile); - if (IsOnSnow(ti->tile)) { + if (AlwaysDrawUnpavedRoads(ti->tile, roadside)) { image += 19; } else { switch (roadside) { @@ -713,7 +766,7 @@ } /* Return if full detail is disabled, or we are zoomed fully out. */ - if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return; + if (!HASBIT(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return; /* Draw extra details. */ for (drts = _road_display_table[roadside][road]; drts->image != 0; drts++) { @@ -735,6 +788,7 @@ case ROAD_TILE_CROSSING: { SpriteID image; SpriteID pal = PAL_NONE; + Roadside roadside = GetRoadside(ti->tile); if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh); @@ -743,10 +797,10 @@ if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++; if (IsCrossingBarred(ti->tile)) image += 2; - if (IsOnSnow(ti->tile)) { + if (AlwaysDrawUnpavedRoads(ti->tile, roadside)) { image += 8; } else { - switch (GetRoadside(ti->tile)) { + switch (roadside) { case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break; case ROADSIDE_GRASS: break; default: image += 4; break; // Paved @@ -797,7 +851,7 @@ DrawBridgeMiddle(ti); } -void DrawRoadDepotSprite(int x, int y, DiagDirection dir) +void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt) { SpriteID palette = PLAYER_SPRITE_COLOR(_local_player); const DrawTileSprites* dts = &_road_depot[dir]; @@ -823,7 +877,7 @@ if (tileh == SLOPE_FLAT) return z; if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { - uint f = GetRoadFoundation(tileh, GetRoadBits(tile)); + uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile)); if (f != 0) { if (IsSteepSlope(tileh)) { @@ -843,7 +897,7 @@ { if (tileh == SLOPE_FLAT) return SLOPE_FLAT; if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { - uint f = GetRoadFoundation(tileh, GetRoadBits(tile)); + uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile)); if (f == 0) return tileh; if (f < 15) return SLOPE_FLAT; // leveled foundation @@ -911,7 +965,7 @@ /* Show an animation to indicate road work */ if (t->road_build_months != 0 && (DistanceManhattan(t->xy, tile) < 8 || grp != 0) && - GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) { + GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) { if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) { StartRoadWorks(tile); @@ -965,15 +1019,18 @@ static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode) { + RoadType rt = ROADTYPE_ROAD; + switch (mode) { case TRANSPORT_RAIL: if (!IsLevelCrossing(tile)) return 0; return GetCrossingRailBits(tile) * 0x101; case TRANSPORT_ROAD: + if (!HASBIT(GetRoadTypes(tile), rt)) return 0; switch (GetRoadTileType(tile)) { case ROAD_TILE_NORMAL: - return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101; + return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * 0x101; case ROAD_TILE_CROSSING: { uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101; @@ -1047,29 +1104,25 @@ static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player) { - if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) == old_player) { - SetCrossingRoadOwner(tile, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player); + if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) { + DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); + return; } - if (!IsTileOwner(tile, old_player)) return; + for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + if (!HASBIT(GetRoadTypes(tile), rt)) continue; - if (new_player != PLAYER_SPECTATOR) { - SetTileOwner(tile, new_player); - } else { - switch (GetRoadTileType(tile)) { - case ROAD_TILE_NORMAL: - SetTileOwner(tile, OWNER_NONE); - break; + if (GetRoadOwner(tile, rt) == old_player) { + SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player); - case ROAD_TILE_CROSSING: - MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile)); - break; + if (rt == ROADTYPE_TRAM) { + DoCommand(tile, ROADTYPE_TRAM << 4 | GetRoadBits(tile, ROADTYPE_ROAD), 0, DC_EXEC, CMD_REMOVE_ROAD); + } + } + } - default: - case ROAD_TILE_DEPOT: - DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - break; - } + if (IsLevelCrossing(tile)) { + MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/road_cmd.h --- a/src/road_cmd.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road_cmd.h Wed Jun 13 11:45:14 2007 +0000 @@ -7,6 +7,6 @@ #include "direction.h" -void DrawRoadDepotSprite(int x, int y, DiagDirection dir); +void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt); #endif /* ROAD_CMD_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/road_gui.cpp --- a/src/road_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -4,8 +4,6 @@ #include "stdafx.h" #include "openttd.h" -#include "road_cmd.h" -#include "road_map.h" #include "table/sprites.h" #include "table/strings.h" #include "functions.h" @@ -18,6 +16,9 @@ #include "sound.h" #include "command.h" #include "variables.h" +#include "road.h" +#include "road_cmd.h" +#include "road_map.h" #include "station_map.h" //needed for catchments #include "station.h" @@ -31,6 +32,8 @@ static byte _place_road_flag; +static RoadType _cur_roadtype; + static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; @@ -42,18 +45,18 @@ static void PlaceRoad_NE(TileIndex tile) { _place_road_flag = (_tile_fract_coords.y >= 8) + 4; - VpStartPlaceSizing(tile, VPM_FIX_X); + VpStartPlaceSizing(tile, VPM_FIX_X, GUI_PlaceProc_None); } static void PlaceRoad_NW(TileIndex tile) { _place_road_flag = (_tile_fract_coords.x >= 8) + 0; - VpStartPlaceSizing(tile, VPM_FIX_Y); + VpStartPlaceSizing(tile, VPM_FIX_Y, GUI_PlaceProc_None); } static void PlaceRoad_Bridge(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_OR_Y); + VpStartPlaceSizing(tile, VPM_X_OR_Y, GUI_PlaceProc_None); } @@ -69,7 +72,7 @@ static void PlaceRoad_Tunnel(TileIndex tile) { - DoCommandP(tile, 0x200, 0, CcBuildRoadTunnel, CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE)); + DoCommandP(tile, 0x200 | RoadTypeToRoadTypes(_cur_roadtype), 0, CcBuildRoadTunnel, CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE)); } static void BuildRoadOutsideStation(TileIndex tile, DiagDirection direction) @@ -77,24 +80,27 @@ tile += TileOffsByDiagDir(direction); // if there is a roadpiece just outside of the station entrance, build a connecting route if (IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL) { - DoCommandP(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), 0, NULL, CMD_BUILD_ROAD); + if (GetRoadBits(tile, _cur_roadtype) != ROAD_NONE) { + DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, NULL, CMD_BUILD_ROAD); + } } } void CcRoadDepot(bool success, TileIndex tile, uint32 p1, uint32 p2) { if (success) { + DiagDirection dir = (DiagDirection)GB(p1, 0, 2); SndPlayTileFx(SND_1F_SPLAT, tile); ResetObjectToPlace(); - BuildRoadOutsideStation(tile, (DiagDirection)p1); + BuildRoadOutsideStation(tile, dir); /* For a drive-through road stop build connecting road for other entrance */ - if (HASBIT(p2, 1)) BuildRoadOutsideStation(tile, ReverseDiagDir((DiagDirection)p1)); + if (HASBIT(p2, 1)) BuildRoadOutsideStation(tile, ReverseDiagDir(dir)); } } static void PlaceRoad_Depot(TileIndex tile) { - DoCommandP(tile, _road_depot_orientation, 0, CcRoadDepot, CMD_BUILD_ROAD_DEPOT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1807_CAN_T_BUILD_ROAD_VEHICLE)); + DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0, CcRoadDepot, CMD_BUILD_ROAD_DEPOT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1807_CAN_T_BUILD_ROAD_VEHICLE)); } static void PlaceRoadStop(TileIndex tile, uint32 p2, uint32 cmd) @@ -113,7 +119,7 @@ if (_remove_button_clicked) { DoCommandP(tile, 0, RoadStop::BUS, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_BUS_STATION)); } else { - PlaceRoadStop(tile, RoadStop::BUS, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION)); + PlaceRoadStop(tile, ROADTYPES_ROAD << 2 | RoadStop::BUS, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION)); } } @@ -122,13 +128,13 @@ if (_remove_button_clicked) { DoCommandP(tile, 0, RoadStop::TRUCK, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_TRUCK_STATION)); } else { - PlaceRoadStop(tile, RoadStop::TRUCK, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION)); + PlaceRoadStop(tile, ROADTYPES_ROAD << 2 | RoadStop::TRUCK, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION)); } } static void PlaceRoad_DemolishArea(TileIndex tile) { - VpStartPlaceSizing(tile, 4); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_None); } @@ -264,47 +270,41 @@ if (w != NULL) WP(w, def_d).close = true; break; - case WE_PLACE_DRAG: { - int sel_method; - switch (e->we.place.userdata) { - case 1: - sel_method = VPM_FIX_X; + case WE_PLACE_DRAG: + switch (e->we.place.select_method) { + case VPM_FIX_X: _place_road_flag = (_place_road_flag & ~2) | ((e->we.place.pt.y & 8) >> 2); break; - case 2: - sel_method = VPM_FIX_Y; + case VPM_FIX_Y: _place_road_flag = (_place_road_flag & ~2) | ((e->we.place.pt.x & 8) >> 2); break; - - case 4: - sel_method = VPM_X_AND_Y; - break; - - default: - sel_method = VPM_X_OR_Y; - break; } - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, sel_method); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); return; - } case WE_PLACE_MOUSEUP: if (e->we.place.pt.x != -1) { TileIndex start_tile = e->we.place.starttile; TileIndex end_tile = e->we.place.tile; - if (e->we.place.userdata == 0) { - ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, 0x80); - } else if (e->we.place.userdata != 4) { - DoCommandP(end_tile, start_tile, _place_road_flag, CcPlaySound1D, - _remove_button_clicked ? - CMD_REMOVE_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1805_CAN_T_REMOVE_ROAD_FROM) : - CMD_BUILD_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1804_CAN_T_BUILD_ROAD_HERE)); - } else { - DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA)); + switch (e->we.place.select_method) { + case VPM_X_OR_Y: + ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, 0x80 | RoadTypeToRoadTypes(_cur_roadtype)); + break; + + case VPM_X_AND_Y: + DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA)); + break; + + default: + DoCommandP(end_tile, start_tile, _place_road_flag | (_cur_roadtype << 3), CcPlaySound1D, + _remove_button_clicked ? + CMD_REMOVE_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1805_CAN_T_REMOVE_ROAD_FROM) : + CMD_BUILD_LONG_ROAD | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1804_CAN_T_BUILD_ROAD_HERE)); + break; } } break; @@ -312,7 +312,7 @@ case WE_PLACE_PRESIZE: { TileIndex tile = e->we.place.tile; - DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL); + DoCommand(tile, 0x200 | _cur_roadtype, 0, DC_AUTO, CMD_BUILD_TUNNEL); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); break; } @@ -348,9 +348,10 @@ BuildRoadToolbWndProc }; -void ShowBuildRoadToolbar() +void ShowBuildRoadToolbar(RoadType roadtype) { if (!IsValidPlayer(_current_player)) return; + _cur_roadtype = roadtype; DeleteWindowById(WC_BUILD_TOOLBAR, 0); Window *w = AllocateWindowDesc(&_build_road_desc); @@ -395,10 +396,10 @@ case WE_PAINT: DrawWindowWidgets(w); - DrawRoadDepotSprite(70, 17, DIAGDIR_NE); - DrawRoadDepotSprite(70, 69, DIAGDIR_SE); - DrawRoadDepotSprite( 2, 69, DIAGDIR_SW); - DrawRoadDepotSprite( 2, 17, DIAGDIR_NW); + DrawRoadDepotSprite(70, 17, DIAGDIR_NE, _cur_roadtype); + DrawRoadDepotSprite(70, 69, DIAGDIR_SE, _cur_roadtype); + DrawRoadDepotSprite( 2, 69, DIAGDIR_SW, _cur_roadtype); + DrawRoadDepotSprite( 2, 17, DIAGDIR_NW, _cur_roadtype); break; case WE_CLICK: { diff -r 0b2aebc8283e -r 0b8b245a2391 src/road_map.cpp --- a/src/road_map.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road_map.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -14,13 +14,15 @@ #include "depot.h" -RoadBits GetAnyRoadBits(TileIndex tile) +RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt) { + if (!HASBIT(GetRoadTypes(tile), rt)) return ROAD_NONE; + switch (GetTileType(tile)) { case MP_STREET: switch (GetRoadTileType(tile)) { default: - case ROAD_TILE_NORMAL: return GetRoadBits(tile); + case ROAD_TILE_NORMAL: return GetRoadBits(tile, rt); case ROAD_TILE_CROSSING: return GetCrossingRoadBits(tile); case ROAD_TILE_DEPOT: return DiagDirToRoadBits(GetRoadDepotDirection(tile)); } @@ -44,15 +46,16 @@ } -TrackBits GetAnyRoadTrackBits(TileIndex tile) +TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt) { uint32 r; /* Don't allow local authorities to build roads through road depots or road stops. */ - if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile))) { + if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile)) || !HASBIT(GetRoadTypes(tile), rt)) { return TRACK_BIT_NONE; } r = GetTileTrackStatus(tile, TRANSPORT_ROAD); + return (TrackBits)(byte)(r | (r >> 8)); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/road_map.h --- a/src/road_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/road_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -18,9 +18,9 @@ }; static inline RoadTileType GetRoadTileType(TileIndex t) -{ + { assert(IsTileType(t, MP_STREET)); - return (RoadTileType)GB(_m[t].m5, 4, 4); + return (RoadTileType)GB(_m[t].m5, 6, 2); } static inline bool IsLevelCrossing(TileIndex t) @@ -33,23 +33,106 @@ return IsTileType(t, MP_STREET) && IsLevelCrossing(t); } -static inline RoadBits GetRoadBits(TileIndex t) +static inline RoadBits GetRoadBits(TileIndex t, RoadType rt) { assert(GetRoadTileType(t) == ROAD_TILE_NORMAL); - return (RoadBits)GB(_m[t].m5, 0, 4); + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m4, 0, 4); + case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m4, 4, 4); + case ROADTYPE_HWAY: return (RoadBits)GB(_m[t].m6, 2, 4); + } } -static inline void SetRoadBits(TileIndex t, RoadBits r) +static inline RoadBits GetAllRoadBits(TileIndex tile) +{ + return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM) | GetRoadBits(tile, ROADTYPE_HWAY); +} + +static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt) { assert(GetRoadTileType(t) == ROAD_TILE_NORMAL); // XXX incomplete - SB(_m[t].m5, 0, 4, r); + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: SB(_m[t].m4, 0, 4, r); break; + case ROADTYPE_TRAM: SB(_m[t].m4, 4, 4, r); break; + case ROADTYPE_HWAY: SB(_m[t].m6, 2, 4, r); break; + } } +static inline RoadTypes GetRoadTypes(TileIndex t) +{ + if (IsTileType(t, MP_STREET)) { + return (RoadTypes)GB(_me[t].m7, 5, 3); + } else { + return (RoadTypes)GB(_m[t].m3, 0, 3); + } +} + +static inline void SetRoadTypes(TileIndex t, RoadTypes rt) +{ + if (IsTileType(t, MP_STREET)) { + SB(_me[t].m7, 5, 3, rt); + } else { + assert(IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); + SB(_m[t].m3, 0, 2, rt); + } +} + +static inline Owner GetRoadOwner(TileIndex t, RoadType rt) +{ + if (!IsTileType(t, MP_STREET)) return GetTileOwner(t); + + switch (GetRoadTileType(t)) { + default: NOT_REACHED(); + case ROAD_TILE_NORMAL: + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: return (Owner)GB( _m[t].m1, 0, 5); + case ROADTYPE_TRAM: return (Owner)GB( _m[t].m5, 0, 5); + case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5); + } + case ROAD_TILE_CROSSING: + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: return (Owner)GB( _m[t].m4, 0, 5); + case ROADTYPE_TRAM: return (Owner)GB( _m[t].m5, 0, 5); + case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5); + } + case ROAD_TILE_DEPOT: return GetTileOwner(t); + } +} + +static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o) +{ + if (!IsTileType(t, MP_STREET)) return SetTileOwner(t, o); + + switch (GetRoadTileType(t)) { + default: NOT_REACHED(); + case ROAD_TILE_NORMAL: + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: SB( _m[t].m1, 0, 5, o); break; + case ROADTYPE_TRAM: SB( _m[t].m5, 0, 5, o); break; + case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break; + } + break; + case ROAD_TILE_CROSSING: + switch (rt) { + default: NOT_REACHED(); + case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break; + case ROADTYPE_TRAM: SB( _m[t].m5, 0, 5, o); break; + case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break; + } + break; + case ROAD_TILE_DEPOT: return SetTileOwner(t, o); + } +} static inline Axis GetCrossingRoadAxis(TileIndex t) { assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - return (Axis)GB(_m[t].m5, 3, 1); + return (Axis)GB(_m[t].m4, 6, 1); } static inline RoadBits GetCrossingRoadBits(TileIndex tile) @@ -63,35 +146,22 @@ } -// TODO swap owner of road and rail -static inline Owner GetCrossingRoadOwner(TileIndex t) -{ - assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - return (Owner)_m[t].m4; -} - -static inline void SetCrossingRoadOwner(TileIndex t, Owner o) -{ - assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - _m[t].m4 = o; -} - static inline void UnbarCrossing(TileIndex t) { assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - CLRBIT(_m[t].m5, 2); + CLRBIT(_m[t].m4, 5); } static inline void BarCrossing(TileIndex t) { assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - SETBIT(_m[t].m5, 2); + SETBIT(_m[t].m4, 5); } static inline bool IsCrossingBarred(TileIndex t) { assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); - return HASBIT(_m[t].m5, 2); + return HASBIT(_m[t].m4, 5); } #define IsOnDesert IsOnSnow @@ -174,9 +244,10 @@ * - bridge ramps: start of the ramp is treated as road piece * - bridge middle parts: bridge itself is ignored * @param tile the tile to get the road bits for + * @param rt the road type to get the road bits form * @return the road bits of the given tile */ -RoadBits GetAnyRoadBits(TileIndex tile); +RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt); /** * Get the accessible track bits for the given tile. @@ -186,39 +257,45 @@ * @param tile the tile to get the track bits for * @return the track bits for the given tile */ -TrackBits GetAnyRoadTrackBits(TileIndex tile); +TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt); -static inline void MakeRoadNormal(TileIndex t, Owner owner, RoadBits bits, TownID town) +static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway) { SetTileType(t, MP_STREET); - SetTileOwner(t, owner); + SetTileOwner(t, road); _m[t].m2 = town; - _m[t].m3 = 0 << 7 | 0 << 4 | 0; - _m[t].m4 = 0; - _m[t].m5 = ROAD_TILE_NORMAL << 4 | bits; + _m[t].m3 = 0; + _m[t].m4 = (HASBIT(rot, ROADTYPE_TRAM) ? bits : 0) << 4 | (HASBIT(rot, ROADTYPE_ROAD) ? bits : 0); + _m[t].m5 = ROAD_TILE_NORMAL << 6 | tram; + SB(_m[t].m6, 2, 4, HASBIT(rot, ROADTYPE_HWAY) ? bits : 0); + _me[t].m7 = rot << 5 | hway; } -static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner rail, Axis roaddir, RailType rt, uint town) +static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner hway, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town) { SetTileType(t, MP_STREET); SetTileOwner(t, rail); _m[t].m2 = town; - _m[t].m3 = 0 << 7 | 0 << 4 | rt; - _m[t].m4 = road; - _m[t].m5 = ROAD_TILE_CROSSING << 4 | roaddir << 3 | 0 << 2; + _m[t].m3 = rat; + _m[t].m4 = roaddir << 6 | road; + _m[t].m5 = ROAD_TILE_CROSSING << 6 | tram; + SB(_m[t].m6, 2, 4, 0); + _me[t].m7 = rot << 5 | hway; } -static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir) +static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir, RoadType rt) { SetTileType(t, MP_STREET); SetTileOwner(t, owner); _m[t].m2 = 0; _m[t].m3 = 0; _m[t].m4 = 0; - _m[t].m5 = ROAD_TILE_DEPOT << 4 | dir; + _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir; + SB(_m[t].m6, 2, 4, 0); + _me[t].m7 = RoadTypeToRoadTypes(rt) << 5; } #endif /* ROAD_MAP_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/roadveh.h --- a/src/roadveh.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/roadveh.h Wed Jun 13 11:45:14 2007 +0000 @@ -22,4 +22,27 @@ void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2); void CcCloneRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2); + +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) RoadVehicle(); + * + * As side-effect the vehicle type is set correctly. + */ +struct RoadVehicle : public Vehicle { + /** Initializes the Vehicle to a road vehicle */ + RoadVehicle() { this->type = VEH_ROAD; } + + /** We want to 'destruct' the right class. */ + virtual ~RoadVehicle() {} + + const char *GetTypeString() const { return "road vehicle"; } + void MarkDirty(); + void UpdateDeltaXY(Direction direction); + ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; } + WindowClass GetVehicleListWindowClass() const { return WC_ROADVEH_LIST; } +}; + #endif /* ROADVEH_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/roadveh_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -117,7 +117,7 @@ static int32 EstimateRoadVehCost(EngineID engine_type) { - return ((_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5; + return ((_eco->GetPrice(CEconomy::ROADVEH_BASE) >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5; } /** Build a road vehicle. @@ -169,7 +169,6 @@ v->x_pos = x; v->y_pos = y; v->z_pos = GetSlopeZ(x, y); - v->z_height = 6; v->u.road.state = RVSB_IN_DEPOT; v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; @@ -205,13 +204,15 @@ v->date_of_last_service = _date; v->build_year = _cur_year; - v->type = VEH_ROAD; + v = new (v) RoadVehicle(); v->cur_image = 0xC15; v->random_bits = VehicleRandomBits(); v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); + v->cargo_cap = GetVehicleProperty(v, 0x0F, rvi->capacity); + VehiclePositionChanged(v); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); @@ -486,15 +487,15 @@ } -static void MarkRoadVehDirty(Vehicle *v) +void RoadVehicle::MarkDirty() { - v->cur_image = GetRoadVehImage(v, v->direction); - MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1); + this->cur_image = GetRoadVehImage(this, this->direction); + MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1); } -static void UpdateRoadVehDeltaXY(Vehicle *v) +void RoadVehicle::UpdateDeltaXY(Direction direction) { -#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0) +#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0) static const uint32 _delta_xy_table[8] = { MKIT(3, 3, -1, -1), MKIT(3, 7, -1, -3), @@ -506,11 +507,13 @@ MKIT(7, 3, -3, -1), }; #undef MKIT - uint32 x = _delta_xy_table[v->direction]; - v->x_offs = GB(x, 0, 8); - v->y_offs = GB(x, 8, 8); - v->sprite_width = GB(x, 16, 8); - v->sprite_height = GB(x, 24, 8); + + uint32 x = _delta_xy_table[direction]; + this->x_offs = GB(x, 0, 8); + this->y_offs = GB(x, 8, 8); + this->sprite_width = GB(x, 16, 8); + this->sprite_height = GB(x, 24, 8); + this->z_height = 6; } static void ClearCrashedStation(Vehicle *v) @@ -566,7 +569,7 @@ v->direction = ChangeDir(v->direction, delta[r & 3]); BeginVehicleMove(v); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); v->cur_image = GetRoadVehImage(v, v->direction); SetRoadVehPosition(v, v->x_pos, v->y_pos); } @@ -752,39 +755,6 @@ InvalidateVehicleOrder(v); } -static void HandleRoadVehLoading(Vehicle *v) -{ - switch (v->current_order.type) { - case OT_LOADING: { - Order b; - - if (--v->load_unload_time_rem != 0) return; - - if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD || - (_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)))) { - SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC); - if (LoadUnloadVehicle(v, false)) { - InvalidateWindow(WC_ROADVEH_LIST, v->owner); - MarkRoadVehDirty(v); - } - return; - } - - b = v->current_order; - v->LeaveStation(); - if (!(b.flags & OF_NON_STOP)) return; - break; - } - - case OT_DUMMY: break; - - default: return; - } - - v->cur_order_index++; - InvalidateVehicleOrder(v); -} - static void StartRoadVehSound(const Vehicle* v) { if (!PlayVehicleSound(v, VSE_START)) { @@ -1311,7 +1281,7 @@ if (v->vehstatus & VS_STOPPED) return; ProcessRoadVehOrder(v); - HandleRoadVehLoading(v); + v->HandleLoading(); if (v->current_order.type == OT_LOADING) return; @@ -1345,7 +1315,7 @@ v->u.road.frame = RVC_DEPOT_START_FRAME; v->cur_image = GetRoadVehImage(v, v->direction); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); SetRoadVehPosition(v,x,y); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); @@ -1381,7 +1351,7 @@ if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { /* Vehicle has just entered a bridge or tunnel */ v->cur_image = GetRoadVehImage(v, v->direction); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); SetRoadVehPosition(v,gp.x,gp.y); return; } @@ -1469,7 +1439,7 @@ } v->cur_image = GetRoadVehImage(v, newdir); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); return; } @@ -1509,7 +1479,7 @@ } v->cur_image = GetRoadVehImage(v, newdir); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); return; } @@ -1539,7 +1509,7 @@ if (old_dir != v->u.road.state) { /* The vehicle is in a road stop */ v->cur_image = GetRoadVehImage(v, new_dir); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); SetRoadVehPosition(v, v->x_pos, v->y_pos); /* Note, return here means that the frame counter is not incremented * for vehicles changing direction in a road stop. This causes frames to @@ -1569,14 +1539,11 @@ if (v->current_order.type != OT_LEAVESTATION && v->current_order.type != OT_GOTO_DEPOT) { /* Vehicle has arrived at a bay in a road stop */ - Order old_order; if (IsDriveThroughStopTile(v->tile)) { TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); RoadStop::Type type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; - assert(HASBIT(v->u.road.state, RVS_IS_STOPPING)); - /* Check if next inline bay is free */ if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { RoadStop *rs_n = GetRoadStopByTile(next_tile, type); @@ -1601,23 +1568,8 @@ v->last_station_visited = GetStationIndex(v->tile); RoadVehArrivesAt(v, st); - - old_order = v->current_order; v->BeginLoading(); - v->current_order.flags = 0; - if (old_order.type == OT_GOTO_STATION && - v->current_order.dest == v->last_station_visited) { - v->current_order.flags = - (old_order.flags & (OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER)) | OF_NON_STOP; - } - - SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC); - if (LoadUnloadVehicle(v, true)) { - InvalidateWindow(WC_ROADVEH_LIST, v->owner); - MarkRoadVehDirty(v); - } - InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); return; } @@ -1677,7 +1629,7 @@ if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++; v->cur_image = GetRoadVehImage(v, v->direction); - UpdateRoadVehDeltaXY(v); + v->UpdateDeltaXY(v->direction); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); } @@ -1734,6 +1686,9 @@ return; } + if (v->current_order.type == OT_LOADING) v->LeaveStation(); + ClearSlot(v); + v->current_order.type = OT_GOTO_DEPOT; v->current_order.flags = OF_NON_STOP; v->current_order.dest = depot->index; @@ -1853,6 +1808,8 @@ * @param p2 Bitstuffed elements * - p2 = (bit 0-7) - the new cargo type to refit to * - p2 = (bit 8-15) - the new cargo subtype to refit to + * - p2 = (bit 16) - refit only this vehicle (ignored) + * @return cost of refit or error */ int32 CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { @@ -1897,7 +1854,7 @@ * carry twice as much mail/goods as normal cargo, and four times as * many passengers */ - capacity = rvi->capacity; + capacity = GetVehicleProperty(v, 0x0F, rvi->capacity); switch (old_cid) { case CT_PASSENGERS: break; case CT_MAIL: diff -r 0b2aebc8283e -r 0b8b245a2391 src/roadveh_gui.cpp --- a/src/roadveh_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/roadveh_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -346,7 +346,7 @@ if (w != NULL) { w->caption_color = v->owner; - AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0); + AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), ZOOM_LVL_ROADVEH); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/saveload.cpp --- a/src/saveload.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/saveload.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -29,7 +29,7 @@ #include #include -extern const uint16 SAVEGAME_VERSION = 58; +extern const uint16 SAVEGAME_VERSION = 62; uint16 _sl_version; ///< the major savegame version identifier byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! @@ -1257,6 +1257,7 @@ extern const ChunkHandler _economy_chunk_handlers[]; extern const ChunkHandler _animated_tile_chunk_handlers[]; extern const ChunkHandler _newgrf_chunk_handlers[]; +extern const ChunkHandler _group_chunk_handlers[]; static const ChunkHandler * const _chunk_handlers[] = { _misc_chunk_handlers, @@ -1274,6 +1275,7 @@ _player_chunk_handlers, _animated_tile_chunk_handlers, _newgrf_chunk_handlers, + _group_chunk_handlers, NULL, }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/screenshot.cpp --- a/src/screenshot.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/screenshot.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -449,7 +449,7 @@ static void CurrentScreenCallback(void *userdata, Pixel *buf, uint y, uint pitch, uint n) { for (; n > 0; --n) { - memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width); + memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width * sizeof(Pixel)); ++y; buf += pitch; } @@ -469,7 +469,7 @@ dpi.height = n; dpi.width = vp->width; dpi.pitch = pitch; - dpi.zoom = 0; + dpi.zoom = ZOOM_LVL_WORLD_SCREENSHOT; dpi.left = 0; dpi.top = y; @@ -479,10 +479,10 @@ left += wx; ViewportDoDraw(vp, - ((left - wx - vp->left) << vp->zoom) + vp->virtual_left, - ((y - vp->top) << vp->zoom) + vp->virtual_top, - ((left - vp->left) << vp->zoom) + vp->virtual_left, - (((y + n) - vp->top) << vp->zoom) + vp->virtual_top + ScaleByZoom(left - wx - vp->left, vp->zoom) + vp->virtual_left, + ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top, + ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left, + ScaleByZoom((y + n) - vp->top, vp->zoom) + vp->virtual_top ); } @@ -540,7 +540,7 @@ ViewPort vp; const ScreenshotFormat *sf; - vp.zoom = 0; + vp.zoom = ZOOM_LVL_WORLD_SCREENSHOT; vp.left = 0; vp.top = 0; vp.virtual_left = -(int)MapMaxX() * TILE_PIXELS; diff -r 0b2aebc8283e -r 0b8b245a2391 src/settings.cpp --- a/src/settings.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/settings.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -1004,7 +1004,7 @@ #define SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max, full, str, proc, from, to)\ SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, proc, from, to) #define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, proc)\ - SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max full, str, proc, 0, SL_MAX_VERSION) + SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max, full, str, proc, 0, SL_MAX_VERSION) #define SDTG_CONDMMANY(name, type, flags, guiflags, var, def, full, str, proc, from, to)\ SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, proc, from, to) @@ -1174,6 +1174,24 @@ DoCommandP(0, 2, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE); return 0; } + +/** + * Check for right TownLayout usage in editor mode. + * The No Road mode is not desirable since towns have to be + * able to grow. If a user desires to have a town with no road, + * he can easily remove them himself. This would create less confusion + * @param p1 unused + * @return always 0 + */ +static int32 CheckTownLayout(int32 p1) +{ + if (_patches.town_layout == TL_NO_ROADS && _game_mode == GM_EDITOR) { + ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID, 0, 0); + _patches.town_layout = TL_ORIGINAL; + } + return 0; +} + /** Conversion callback for _gameopt_settings.landscape * It converts (or try) between old values and the new ones, * without loosing initial setting of the user @@ -1244,29 +1262,30 @@ #ifdef ENABLE_NETWORK static const SettingDescGlobVarList _network_settings[] = { - SDTG_VAR("sync_freq", SLE_UINT16,C|S,0, _network_sync_freq, 100, 0, 100, 0, STR_NULL, NULL), - SDTG_VAR("frame_freq", SLE_UINT8,C|S,0, _network_frame_freq, 0, 0, 100, 0, STR_NULL, NULL), - SDTG_VAR("max_join_time", SLE_UINT16, S, 0, _network_max_join_time, 500, 0, 32000, 0, STR_NULL, NULL), - SDTG_BOOL("pause_on_join", S, 0, _network_pause_on_join, true, STR_NULL, NULL), - SDTG_STR("server_bind_ip", SLE_STRB, S, 0, _network_server_bind_ip_host, "0.0.0.0", STR_NULL, NULL), - SDTG_VAR("server_port", SLE_UINT16, S, 0, _network_server_port, NETWORK_DEFAULT_PORT, 0, 65535, 0, STR_NULL, NULL), - SDTG_BOOL("server_advertise", S, 0, _network_advertise, false, STR_NULL, NULL), - SDTG_VAR("lan_internet", SLE_UINT8, S, 0, _network_lan_internet, 0, 0, 1, 0, STR_NULL, NULL), - SDTG_STR("player_name", SLE_STRB, S, 0, _network_player_name, NULL, STR_NULL, NULL), - SDTG_STR("server_password", SLE_STRB, S, 0, _network_server_password, NULL, STR_NULL, NULL), - SDTG_STR("rcon_password", SLE_STRB, S, 0, _network_rcon_password, NULL, STR_NULL, NULL), - SDTG_STR("server_name", SLE_STRB, S, 0, _network_server_name, NULL, STR_NULL, NULL), - SDTG_STR("connect_to_ip", SLE_STRB, S, 0, _network_default_ip, NULL, STR_NULL, NULL), - SDTG_STR("network_id", SLE_STRB, S, 0, _network_unique_id, NULL, STR_NULL, NULL), - SDTG_BOOL("autoclean_companies", S, 0, _network_autoclean_companies, false, STR_NULL, NULL), - SDTG_VAR("autoclean_unprotected",SLE_UINT8, S, 0, _network_autoclean_unprotected,12, 0, 60, 0, STR_NULL, NULL), - SDTG_VAR("autoclean_protected", SLE_UINT8, S, 0, _network_autoclean_protected, 36, 0, 180, 0, STR_NULL, NULL), - SDTG_VAR("max_companies", SLE_UINT8, S, 0, _network_game_info.companies_max, 8, 0, 8, 0, STR_NULL, NULL), - SDTG_VAR("max_clients", SLE_UINT8, S, 0, _network_game_info.clients_max, 10, 0, 10, 0, STR_NULL, NULL), - SDTG_VAR("max_spectators", SLE_UINT8, S, 0, _network_game_info.spectators_max, 10, 0, 10, 0, STR_NULL, NULL), - SDTG_VAR("restart_game_year", SLE_INT32, S,D0, _network_restart_game_year, 0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL), - SDTG_VAR("min_players", SLE_UINT8, S, 0, _network_min_players, 0, 0, 10, 0, STR_NULL, NULL), - SDTG_END() + SDTG_VAR("sync_freq", SLE_UINT16,C|S,0, _network_sync_freq, 100, 0, 100, 0, STR_NULL, NULL), + SDTG_VAR("frame_freq", SLE_UINT8,C|S,0, _network_frame_freq, 0, 0, 100, 0, STR_NULL, NULL), + SDTG_VAR("max_join_time", SLE_UINT16, S, 0, _network_max_join_time, 500, 0, 32000, 0, STR_NULL, NULL), + SDTG_BOOL("pause_on_join", S, 0, _network_pause_on_join, true, STR_NULL, NULL), + SDTG_STR("server_bind_ip", SLE_STRB, S, 0, _network_server_bind_ip_host, "0.0.0.0", STR_NULL, NULL), + SDTG_VAR("server_port", SLE_UINT16, S, 0, _network_server_port, NETWORK_DEFAULT_PORT, 0, 65535, 0, STR_NULL, NULL), + SDTG_BOOL("server_advertise", S, 0, _network_advertise, false, STR_NULL, NULL), + SDTG_VAR("lan_internet", SLE_UINT8, S, 0, _network_lan_internet, 0, 0, 1, 0, STR_NULL, NULL), + SDTG_STR("player_name", SLE_STRB, S, 0, _network_player_name, NULL, STR_NULL, NULL), + SDTG_STR("server_password", SLE_STRB, S, 0, _network_server_password, NULL, STR_NULL, NULL), + SDTG_STR("rcon_password", SLE_STRB, S, 0, _network_rcon_password, NULL, STR_NULL, NULL), + SDTG_STR("server_name", SLE_STRB, S, 0, _network_server_name, NULL, STR_NULL, NULL), + SDTG_STR("connect_to_ip", SLE_STRB, S, 0, _network_default_ip, NULL, STR_NULL, NULL), + SDTG_STR("network_id", SLE_STRB, S, 0, _network_unique_id, NULL, STR_NULL, NULL), + SDTG_BOOL("autoclean_companies", S, 0, _network_autoclean_companies, false, STR_NULL, NULL), + SDTG_VAR("autoclean_unprotected",SLE_UINT8, S, 0, _network_autoclean_unprotected,12, 0, 60, 0, STR_NULL, NULL), + SDTG_VAR("autoclean_protected", SLE_UINT8, S, 0, _network_autoclean_protected, 36, 0, 180, 0, STR_NULL, NULL), + SDTG_VAR("max_companies", SLE_UINT8, S, 0, _network_game_info.companies_max, 8, 0, 8, 0, STR_NULL, NULL), + SDTG_VAR("max_clients", SLE_UINT8, S, 0, _network_game_info.clients_max, 10, 0, 10, 0, STR_NULL, NULL), + SDTG_VAR("max_spectators", SLE_UINT8, S, 0, _network_game_info.spectators_max, 10, 0, 10, 0, STR_NULL, NULL), + SDTG_VAR("restart_game_year", SLE_INT32, S,D0, _network_restart_game_year, 0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL), + SDTG_VAR("min_players", SLE_UINT8, S, 0, _network_min_players, 0, 0, 10, 0, STR_NULL, NULL), + SDTG_OMANY("server_lang", SLE_UINT8, S, 0, _network_game_info.server_lang, 0, 3, "ANY|ENGLISH|GERMAN|FRENCH", STR_NULL, NULL), + SDTG_END() }; #endif /* ENABLE_NETWORK */ @@ -1323,6 +1342,8 @@ SDT_BOOL(Patches, prefer_teamchat, S, 0, false, STR_CONFIG_PATCHES_PREFER_TEAMCHAT, NULL), SDT_VAR(Patches, scrollwheel_scrolling,SLE_UINT8,S,MS, 0, 0, 2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING, NULL), SDT_VAR(Patches,scrollwheel_multiplier,SLE_UINT8,S, 0, 5, 1, 15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,NULL), + SDT_BOOL(Patches, pause_on_newgame, S, 0, false, STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME, NULL), + SDT_BOOL(Patches, advanced_vehicle_list, S, 0, true, STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS, NULL), /***************************************************************************/ /* Construction section of the GUI-configure patches window */ @@ -1333,6 +1354,7 @@ SDT_BOOL(Patches, always_small_airport, 0, 0, false, STR_CONFIG_PATCHES_SMALL_AIRPORTS, NULL), SDT_VAR(Patches, drag_signals_density,SLE_UINT8,S, 0, 4, 1, 20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,NULL), SDT_VAR(Patches, semaphore_build_before,SLE_INT32, S, NC, 1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE, NULL), + SDT_CONDVAR(Patches, town_layout, SLE_UINT8, 59, SL_MAX_VERSION, 0, MS, TL_ORIGINAL, TL_NO_ROADS, NUM_TLS - 1, 1, STR_CONFIG_PATCHES_TOWN_LAYOUT, CheckTownLayout), /***************************************************************************/ /* Vehicle section of the GUI-configure patches window */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/settings_gui.cpp --- a/src/settings_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/settings_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -203,6 +203,7 @@ break; case 24: /* Change interface language */ ReadLanguagePack(e->we.dropdown.index); + UpdateAllStationVirtCoord(); MarkWholeScreenDirty(); break; case 27: /* Change resolution */ @@ -308,8 +309,8 @@ static const GameSettingData _game_setting_info[] = { { 0, 7, 1, STR_NULL}, { 0, 3, 1, STR_6830_IMMEDIATE}, - { 0, 2, 1, STR_6816_LOW}, - { 0, 3, 1, STR_26816_NONE}, + { 0, 3, 1, STR_NUM_VERY_LOW}, + { 0, 4, 1, STR_26816_NONE}, {100, 500, 50, STR_NULL}, { 2, 4, 1, STR_NULL}, { 0, 2, 1, STR_6820_LOW}, @@ -331,8 +332,8 @@ /* * A: competitors * B: start time in months / 3 - * C: town count (2 = high, 0 = low) - * D: industry count (3 = high, 0 = none) + * C: town count (2 = high, 0 = very low) + * D: industry count (4 = high, 0 = none) * E: inital loan / 1000 (in GBP) * F: interest rate * G: running costs (0 = low, 2 = high) @@ -352,8 +353,8 @@ */ static const int16 _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /* A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T*/ - {2, 2, 1, 3, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 2, 1}, //easy - {4, 1, 1, 2, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2}, //medium + {2, 2, 1, 4, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 2, 1}, //easy + {4, 1, 1, 3, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2}, //medium {7, 0, 2, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2, 0, 3}, //hard }; @@ -600,6 +601,8 @@ * Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */ "scrollwheel_scrolling", "scrollwheel_multiplier", + "pause_on_newgame", + "advanced_vehicle_list", }; static const char *_patches_construction[] = { @@ -611,6 +614,7 @@ "drag_signals_density", "oil_refinery_limit", "semaphore_build_before", + "town_layout", }; static const char *_patches_stations[] = { diff -r 0b2aebc8283e -r 0b8b245a2391 src/ship.h --- a/src/ship.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/ship.h Wed Jun 13 11:45:14 2007 +0000 @@ -23,4 +23,28 @@ return IsShipInDepot(v) && v->vehstatus & VS_STOPPED; } + +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Ship(); + * + * As side-effect the vehicle type is set correctly. + */ +struct Ship: public Vehicle { + /** Initializes the Vehicle to a ship */ + Ship() { this->type = VEH_SHIP; } + + /** We want to 'destruct' the right class. */ + virtual ~Ship() {} + + const char *GetTypeString() const { return "ship"; } + void MarkDirty(); + void UpdateDeltaXY(Direction direction); + ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_INC : EXPENSES_SHIP_RUN; } + WindowClass GetVehicleListWindowClass() const { return WC_SHIPS_LIST; } + void PlayLeaveStationSound() const; +}; + #endif /* SHIP_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/ship_cmd.cpp --- a/src/ship_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/ship_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -165,6 +165,7 @@ return; } + if (v->current_order.type == OT_LOADING) v->LeaveStation(); v->current_order.type = OT_GOTO_DEPOT; v->current_order.flags = OF_NON_STOP; v->current_order.dest = depot->index; @@ -187,7 +188,7 @@ if (v->vehstatus & VS_STOPPED) return; - cost = ShipVehInfo(v->engine_type)->running_cost * _eco->GetPrice(CEconomy::SHIP_RUNNING) / 364; + cost = GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _eco->GetPrice(CEconomy::SHIP_RUNNING) / 364; v->profit_this_year -= cost >> 8; SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); @@ -229,19 +230,24 @@ } } -static void MarkShipDirty(Vehicle *v) +void Ship::MarkDirty() { - v->cur_image = GetShipImage(v, v->direction); - MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1); + this->cur_image = GetShipImage(this, this->direction); + MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1); } -static void PlayShipSound(Vehicle *v) +static void PlayShipSound(const Vehicle *v) { if (!PlayVehicleSound(v, VSE_START)) { SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v); } } +void Ship::PlayLeaveStationSound() const +{ + PlayShipSound(this); +} + static void ProcessShipOrder(Vehicle *v) { const Order *order; @@ -300,66 +306,34 @@ InvalidateWindowClasses(WC_SHIPS_LIST); } -static void HandleShipLoading(Vehicle *v) +void Ship::UpdateDeltaXY(Direction direction) { - switch (v->current_order.type) { - case OT_LOADING: { - if (--v->load_unload_time_rem) return; - - if (CanFillVehicle(v) && ( - v->current_order.flags & OF_FULL_LOAD || - (_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)) - )) { - SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); - if (LoadUnloadVehicle(v, false)) { - InvalidateWindow(WC_SHIPS_LIST, v->owner); - MarkShipDirty(v); - } - return; - } - PlayShipSound(v); - - Order b = v->current_order; - v->LeaveStation(); - if (!(b.flags & OF_NON_STOP)) return; - break; - } - - case OT_DUMMY: break; - - default: return; - } - - v->cur_order_index++; - InvalidateVehicleOrder(v); -} - -static void UpdateShipDeltaXY(Vehicle *v, int dir) -{ -#define MKIT(d,c,b,a) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0) +#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0) static const uint32 _delta_xy_table[8] = { - MKIT( -3, -3, 6, 6), - MKIT(-16, -3, 32, 6), - MKIT( -3, -3, 6, 6), - MKIT( -3, -16, 6, 32), - MKIT( -3, -3, 6, 6), - MKIT(-16, -3, 32, 6), - MKIT( -3, -3, 6, 6), - MKIT( -3, -16, 6, 32), + MKIT( 6, 6, -3, -3), + MKIT( 6, 32, -3, -16), + MKIT( 6, 6, -3, -3), + MKIT(32, 6, -16, -3), + MKIT( 6, 6, -3, -3), + MKIT( 6, 32, -3, -16), + MKIT( 6, 6, -3, -3), + MKIT(32, 6, -16, -3), }; #undef MKIT - uint32 x = _delta_xy_table[dir]; - v->x_offs = GB(x, 0, 8); - v->y_offs = GB(x, 8, 8); - v->sprite_width = GB(x, 16, 8); - v->sprite_height = GB(x, 24, 8); + + uint32 x = _delta_xy_table[direction]; + this->x_offs = GB(x, 0, 8); + this->y_offs = GB(x, 8, 8); + this->sprite_width = GB(x, 16, 8); + this->sprite_height = GB(x, 24, 8); + this->z_height = 6; } void RecalcShipStuff(Vehicle *v) { - UpdateShipDeltaXY(v, v->direction); + v->UpdateDeltaXY(v->direction); v->cur_image = GetShipImage(v, v->direction); - MarkShipDirty(v); + v->MarkDirty(); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); } @@ -428,7 +402,7 @@ static int32 EstimateShipCost(EngineID engine_type) { - return ShipVehInfo(engine_type)->base_cost * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5; + return GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_eco->GetPrice(CEconomy::SHIP_BASE) >> 3) >> 5; } static void ShipArrivesAt(const Vehicle* v, Station* st) @@ -683,7 +657,7 @@ if (v->vehstatus & VS_STOPPED) return; ProcessShipOrder(v); - HandleShipLoading(v); + v->HandleLoading(); if (v->current_order.type == OT_LOADING) return; @@ -735,17 +709,8 @@ /* Process station in the orderlist. */ st = GetStation(v->current_order.dest); if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations - v->BeginLoading(); - v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER; - v->current_order.flags |= OF_NON_STOP; ShipArrivesAt(v, st); - - SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); - if (LoadUnloadVehicle(v, true)) { - InvalidateWindow(WC_SHIPS_LIST, v->owner); - MarkShipDirty(v); - } - InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); + v->BeginLoading(); } else { // leave stations without docks right aways v->current_order.type = OT_LEAVESTATION; v->cur_order_index++; @@ -797,7 +762,7 @@ v->z_pos = GetSlopeZ(gp.x, gp.y); getout: - UpdateShipDeltaXY(v, dir); + v->UpdateDeltaXY(dir); v->cur_image = GetShipImage(v, dir); VehiclePositionChanged(v); EndVehicleMove(v); @@ -882,11 +847,7 @@ v->y_pos = y; v->z_pos = GetSlopeZ(x, y); - v->z_height = 6; - v->sprite_width = 6; - v->sprite_height = 6; - v->x_offs = -3; - v->y_offs = -3; + v->UpdateDeltaXY(v->direction); v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = svi->image_index; @@ -912,12 +873,14 @@ v->date_of_last_service = _date; v->build_year = _cur_year; v->cur_image = 0x0E5E; - v->type = VEH_SHIP; + v = new (v) Ship(); v->random_bits = VehicleRandomBits(); v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); + v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity); + VehiclePositionChanged(v); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); @@ -1087,6 +1050,8 @@ * @param p2 various bitstuffed elements * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF) * - p2 = (bit 8-15) - the new cargo subtype to refit to + * - p2 = (bit 16) - refit only this vehicle (ignored) + * @return cost of refit or error */ int32 CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { @@ -1128,7 +1093,7 @@ } if (capacity == CALLBACK_FAILED) { - capacity = ShipVehInfo(v->engine_type)->capacity; + capacity = GetVehicleProperty(v, 0x0D, ShipVehInfo(v->engine_type)->capacity); } _returned_refit_capacity = capacity; diff -r 0b2aebc8283e -r 0b8b245a2391 src/ship_gui.cpp --- a/src/ship_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/ship_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -347,6 +347,6 @@ if (w != NULL) { w->caption_color = v->owner; - AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), 0); + AssignWindowViewport(w, 3, 17, 0xE2, 0x54, w->window_number | (1 << 31), ZOOM_LVL_SHIP); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/signs.cpp --- a/src/signs.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/signs.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -67,8 +67,8 @@ MarkAllViewportsDirty( si->sign.left - 6, si->sign.top - 3, - si->sign.left + si->sign.width_1 * 4 + 12, - si->sign.top + 45); + si->sign.left + ScaleByZoom(si->sign.width_1 + 12, _cur_dpi->zoom), + si->sign.top + ScaleByZoom(12, _cur_dpi->zoom)); } /** diff -r 0b2aebc8283e -r 0b8b245a2391 src/smallmap_gui.cpp --- a/src/smallmap_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/smallmap_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -91,72 +91,6 @@ MKEND() }; -static const LegendAndColour _legend_industries_normal[] = { - MK(0xD7, STR_00FA_COAL_MINE), - MK(0xB8, STR_00FB_POWER_STATION), - MK(0x56, STR_00FC_FOREST), - MK(0xC2, STR_00FD_SAWMILL), - MK(0xBF, STR_00FE_OIL_REFINERY), - MK(0x0F, STR_0105_BANK), - - MS(0x30, STR_00FF_FARM), - MK(0xAE, STR_0100_FACTORY), - MK(0x98, STR_0102_OIL_WELLS), - MK(0x37, STR_0103_IRON_ORE_MINE), - MK(0x0A, STR_0104_STEEL_MILL), - MKEND() -}; - -static const LegendAndColour _legend_industries_hilly[] = { - MK(0xD7, STR_00FA_COAL_MINE), - MK(0xB8, STR_00FB_POWER_STATION), - MK(0x56, STR_00FC_FOREST), - MK(0x0A, STR_0106_PAPER_MILL), - MK(0xBF, STR_00FE_OIL_REFINERY), - MK(0x37, STR_0108_FOOD_PROCESSING_PLANT), - MS(0x30, STR_00FF_FARM), - - MK(0xAE, STR_0101_PRINTING_WORKS), - MK(0x98, STR_0102_OIL_WELLS), - MK(0xC2, STR_0107_GOLD_MINE), - MK(0x0F, STR_0105_BANK), - MKEND() -}; - -static const LegendAndColour _legend_industries_desert[] = { - MK(0xBF, STR_00FE_OIL_REFINERY), - MK(0x98, STR_0102_OIL_WELLS), - MK(0x0F, STR_0105_BANK), - MK(0xB8, STR_0109_DIAMOND_MINE), - MK(0x37, STR_0108_FOOD_PROCESSING_PLANT), - MK(0x0A, STR_010A_COPPER_ORE_MINE), - MK(0x30, STR_00FF_FARM), - MS(0x56, STR_010B_FRUIT_PLANTATION), - - MK(0x27, STR_010C_RUBBER_PLANTATION), - MK(0x25, STR_010D_WATER_SUPPLY), - MK(0xD0, STR_010E_WATER_TOWER), - MK(0xAE, STR_0100_FACTORY), - MK(0xC2, STR_010F_LUMBER_MILL), - MKEND() -}; - -static const LegendAndColour _legend_industries_candy[] = { - MK(0x30, STR_0110_COTTON_CANDY_FOREST), - MK(0xAE, STR_0111_CANDY_FACTORY), - MK(0x27, STR_0112_BATTERY_FARM), - MK(0x37, STR_0113_COLA_WELLS), - MK(0xD0, STR_0114_TOY_SHOP), - MK(0x0A, STR_0115_TOY_FACTORY), - MS(0x25, STR_0116_PLASTIC_FOUNTAINS), - - MK(0xB8, STR_0117_FIZZY_DRINK_FACTORY), - MK(0x98, STR_0118_BUBBLE_GENERATOR), - MK(0xC2, STR_0119_TOFFEE_QUARRY), - MK(0x0F, STR_011A_SUGAR_MINE), - MKEND() -}; - static const LegendAndColour _legend_routes[] = { MK(0xD7, STR_00EB_ROADS), MK(0x0A, STR_00EC_RAILROADS), @@ -197,21 +131,40 @@ #undef MS #undef MKEND +/** Allow room for all industries, plus a terminator entry + * This is required in order to have the indutry slots all filled up */ +static LegendAndColour _legend_from_industries[NUM_INDUSTRYTYPES+1]; -enum { IND_OFFS = 6 }; ///< allow to "jump" to the industries corresponding to the landscape +/** + * Fills an array for the industries legends. + */ +void BuildIndustriesLegend() +{ + const IndustrySpec *indsp; + uint j = 0; + + /* Add each name */ + for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) { + indsp = GetIndustrySpec(i); + if (HASBIT(indsp->climate_availability, _opt.landscape)) { + _legend_from_industries[j].legend = indsp->name; + _legend_from_industries[j].colour = indsp->map_colour; + _legend_from_industries[j].col_break = (j % 6) == 0; // break is performed on the 7th item + _legend_from_industries[j].end = false; + j++; + } + } + /* Terminate the list */ + _legend_from_industries[j].end = true; +} static const LegendAndColour * const _legend_table[] = { _legend_land_contours, _legend_vehicles, - NULL, + _legend_from_industries, _legend_routes, _legend_vegetation, _legend_land_owners, - - _legend_industries_normal, - _legend_industries_hilly, - _legend_industries_desert, - _legend_industries_candy, }; #if defined(OTTD_ALIGNMENT) @@ -800,15 +753,23 @@ SetDParam(0, STR_00E5_CONTOURS + _smallmap_type); DrawWindowWidgets(w); - /* draw the legend */ - tbl = _legend_table[(_smallmap_type != 2) ? _smallmap_type : (_opt.landscape + IND_OFFS)]; + tbl = _legend_table[_smallmap_type]; + x = 4; y_org = w->height - 44 - 11; y = y_org; for (;;) { GfxFillRect(x, y + 1, x + 8, y + 5, 0); GfxFillRect(x + 1, y + 2, x + 7, y + 4, tbl->colour); - DrawString(x + 11, y, tbl->legend, 0); + + if (_smallmap_type == 2) { + /* Industry name must be formated, since it's not in tiny font in the specs. + * So, draw with a parameter and use the STR_7065 string, which is tiny, black */ + SetDParam(0, tbl->legend); + DrawString(x + 11, y, STR_7065, 0); + } else { + DrawString(x + 11, y, tbl->legend, 0); + } tbl += 1; y += 6; @@ -1055,8 +1016,8 @@ _scrolling_viewport = false; } - WP(w, vp_d).scrollpos_x += e->we.scroll.delta.x << vp->zoom; - WP(w, vp_d).scrollpos_y += e->we.scroll.delta.y << vp->zoom; + WP(w, vp_d).scrollpos_x += ScaleByZoom(e->we.scroll.delta.x, vp->zoom); + WP(w, vp_d).scrollpos_y += ScaleByZoom(e->we.scroll.delta.y, vp->zoom); } break; case WE_MOUSEWHEEL: @@ -1094,7 +1055,7 @@ /* the main window with the main view */ v = FindWindowById(WC_MAIN_WINDOW, 0); /* New viewport start ats (zero,zero) */ - AssignWindowViewport(w, 3, 17, 294, 214, 0 , 0); + AssignWindowViewport(w, 3, 17, 294, 214, 0 , ZOOM_LVL_VIEWPORT); /* center on same place as main window (zoom is maximum, no adjustment needed) */ x = WP(v, vp_d).scrollpos_x; diff -r 0b2aebc8283e -r 0b8b245a2391 src/sound.cpp --- a/src/sound.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/sound.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -152,7 +152,8 @@ } -static const byte _vol_factor_by_zoom[] = {255, 190, 134}; +static const byte _vol_factor_by_zoom[] = {255, 190, 134, 87, 49}; +assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_END); static const byte _sound_base_vol[] = { 128, 90, 128, 128, 128, 128, 128, 128, diff -r 0b2aebc8283e -r 0b8b245a2391 src/station.cpp --- a/src/station.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/station.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -125,8 +125,8 @@ MarkAllViewportsDirty( sign.left - 6, sign.top, - sign.left + (sign.width_1 << 2) + 12, - sign.top + 48); + sign.left + ScaleByZoom(sign.width_1 + 12, _cur_dpi->zoom), + sign.top + ScaleByZoom(12, _cur_dpi->zoom)); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/station_cmd.cpp --- a/src/station_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/station_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -935,7 +935,7 @@ int w = plat_len; do { byte layout = *layout_ptr++; - MakeRailStation(tile, st->owner, st->index, axis, layout, (RailType)GB(p2, 0, 4)); + MakeRailStation(tile, st->owner, st->index, axis, layout & ~1, (RailType)GB(p2, 0, 4)); SetCustomStationSpecIndex(tile, specindex); SetStationTileRandomBits(tile, GB(Random(), 0, 4)); @@ -943,7 +943,7 @@ /* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */ uint32 platinfo = GetPlatformInfo(AXIS_X, 0, plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false); uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, st, tile); - if (callback != CALLBACK_FAILED && callback < 8) SetStationGfx(tile, callback + axis); + if (callback != CALLBACK_FAILED && callback < 8) SetStationGfx(tile, (callback & ~1) + axis); } tile += tile_delta; @@ -1025,43 +1025,77 @@ * This allows for custom-built station with holes and weird layouts * @param tile tile of station piece to remove * @param flags operation to perform - * @param p1 unused + * @param p1 start_tile * @param p2 unused */ int32 CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { + TileIndex start = p1 == 0 ? tile : p1; + + /* Count of the number of tiles removed */ + int quantity = 0; + + if (tile >= MapSize() || start >= MapSize()) return CMD_ERROR; + + /* make sure sx,sy are smaller than ex,ey */ + int ex = TileX(tile); + int ey = TileY(tile); + int sx = TileX(start); + int sy = TileY(start); + if (ex < sx) Swap(ex, sx); + if (ey < sy) Swap(ey, sy); + tile = TileXY(sx, sy); + + int size_x = ex - sx + 1; + int size_y = ey - sy + 1; + SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); - // make sure the specified tile belongs to the current player, and that it is a railroad station. - if (!IsTileType(tile, MP_STATION) || !IsRailwayStation(tile) || !_patches.nonuniform_stations) return CMD_ERROR; - Station *st = GetStationByTile(tile); - if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile))) return CMD_ERROR; - - // if we reached here, it means we can actually delete it. do that. - if (flags & DC_EXEC) { - uint specindex = GetCustomStationSpecIndex(tile); - Track track = GetRailStationTrack(tile); - DoClearSquare(tile); - st->rect.AfterRemoveTile(st, tile); - SetSignalsOnBothDir(tile, track); - YapfNotifyTrackLayoutChange(tile, track); - - DeallocateSpecFromStation(st, specindex); - - // now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges. - // we also need to adjust train_tile. - MakeRailwayStationAreaSmaller(st); - st->MarkTilesDirty(); - UpdateStationSignCoord(st); - - // if we deleted the whole station, delete the train facility. - if (st->train_tile == 0) { - st->facilities &= ~FACIL_TRAIN; - UpdateStationVirtCoordDirty(st); - DeleteStationIfEmpty(st); + /* Do the action for every tile into the area */ + BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) { + /* Make sure the specified tile belongs to the current player, and that it is a railroad station. */ + if (!IsTileType(tile2, MP_STATION) || !IsRailwayStation(tile2) || !_patches.nonuniform_stations) { + continue; } - } - return _eco->GetPrice(CEconomy::REMOVE_RAIL_STATION); + + /* Check ownership of station */ + Station *st = GetStationByTile(tile2); + if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile2))) { + continue; + } + + /* If we reached here, the tile is valid so increase the quantity of tiles we will remove */ + quantity++; + + if (flags & DC_EXEC) { + uint specindex = GetCustomStationSpecIndex(tile2); + Track track = GetRailStationTrack(tile2); + DoClearSquare(tile2); + st->rect.AfterRemoveTile(st, tile2); + SetSignalsOnBothDir(tile2, track); + YapfNotifyTrackLayoutChange(tile2, track); + + DeallocateSpecFromStation(st, specindex); + + // now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges. + // we also need to adjust train_tile. + MakeRailwayStationAreaSmaller(st); + st->MarkTilesDirty(); + UpdateStationSignCoord(st); + + // if we deleted the whole station, delete the train facility. + if (st->train_tile == 0) { + st->facilities &= ~FACIL_TRAIN; + UpdateStationVirtCoordDirty(st); + DeleteStationIfEmpty(st); + } + } + } END_TILE_LOOP(tile2, size_x, size_y, tile) + + /* If we've not removed any tiles, give an error */ + if (quantity == 0) return CMD_ERROR; + + return _eco->GetPrice(CEconomy::REMOVE_RAIL_STATION) * quantity; } @@ -1180,6 +1214,7 @@ * @param p1 entrance direction (DiagDirection) * @param p2 bit 0: 0 for Bus stops, 1 for truck stops * bit 1: 0 for normal, 1 for drive-through + * bit 2..4: the roadtypes */ int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { @@ -1188,17 +1223,23 @@ bool build_over_road = is_drive_through && IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL; bool town_owned_road = build_over_road && IsTileOwner(tile, OWNER_TOWN); Owner cur_owner = _current_player; + RoadTypes rts = (RoadTypes)GB(p2, 2, 3); + + if (rts == ROADTYPES_NONE || HASBIT(rts, ROADTYPE_HWAY)) return CMD_ERROR; /* Saveguard the parameters */ if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR; /* If it is a drive-through stop check for valid axis */ if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR; /* Road bits in the wrong direction */ - if (build_over_road && (GetRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION); + if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION); /* Not allowed to build over this road */ if (build_over_road) { if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD); - if (!IsTileOwner(tile, OWNER_TOWN) && !CheckOwnership(GetTileOwner(tile))) return CMD_ERROR; + if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) return CMD_ERROR; + if (!IsTileOwner(tile, OWNER_TOWN) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_ROAD)) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_TRAM))) return CMD_ERROR; + /* Do not remove roadtypes! */ + if (rts != GetRoadTypes(tile) && rts != ROADTYPES_ROADTRAM) return CMD_ERROR; } SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); @@ -1277,9 +1318,9 @@ RoadStop::Type rs_type = type ? RoadStop::TRUCK : RoadStop::BUS; if (is_drive_through) { - MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, (Axis)p1, town_owned_road); + MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road); } else { - MakeRoadStop(tile, st->owner, st->index, rs_type, (DiagDirection)p1); + MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1); } UpdateStationVirtCoordDirty(st); @@ -1355,7 +1396,10 @@ Station *st = GetStationByTile(tile); /* Save the stop info before it is removed */ bool is_drive_through = IsDriveThroughStopTile(tile); - RoadBits road_bits = GetAnyRoadBits(tile); + RoadTypes rts = GetRoadTypes(tile); + RoadBits road_bits = IsDriveThroughStopTile(tile) ? + ((GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y) : + DiagDirToRoadBits(GetRoadStopDir(tile)); bool is_towns_road = is_drive_through && GetStopBuiltOnTownRoad(tile); int32 ret = RemoveRoadStop(st, flags, tile); @@ -1369,7 +1413,12 @@ index = ClosestTownFromTile(tile, (uint)-1)->index; _current_player = OWNER_TOWN; } - DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD); + if (HASBIT(rts, ROADTYPE_ROAD)) { + DoCommand(tile, ROADTYPE_ROAD << 4 | road_bits, index, DC_EXEC, CMD_BUILD_ROAD); + } + if (HASBIT(rts, ROADTYPE_TRAM)) { + DoCommand(tile, ROADTYPE_TRAM << 4 | road_bits, index, DC_EXEC, CMD_BUILD_ROAD); + } _current_player = cur_owner; } @@ -2642,7 +2691,8 @@ if (!GetStopBuiltOnTownRoad(tile)) return true; bool edge_road; - return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile), OWNER_TOWN, &edge_road); + return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, &edge_road, ROADTYPE_ROAD) && + CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_TRAM), OWNER_TOWN, &edge_road, ROADTYPE_TRAM); } static int32 ClearTile_Station(TileIndex tile, byte flags) diff -r 0b2aebc8283e -r 0b8b245a2391 src/station_gui.cpp --- a/src/station_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/station_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -686,7 +686,7 @@ sprite = cs->sprite; } - if (sprite == 0) return; + if (sprite == 0) sprite = SPR_CARGO_GOODS; do { DrawSprite(sprite, PAL_NONE, x, y); diff -r 0b2aebc8283e -r 0b8b245a2391 src/station_map.h --- a/src/station_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/station_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -6,6 +6,7 @@ #define STATION_MAP_H #include "rail_map.h" +#include "road_map.h" #include "station.h" typedef byte StationGfx; @@ -309,15 +310,17 @@ SetRailType(t, rt); } -static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, DiagDirection d) +static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, RoadTypes rt, DiagDirection d) { MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE : GFX_TRUCK_BASE) + d); + SetRoadTypes(t, rt); } -static inline void MakeDriveThroughRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, Axis a, bool on_town_road) +static inline void MakeDriveThroughRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, RoadTypes rt, Axis a, bool on_town_road) { MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE_EXT : GFX_TRUCK_BASE_EXT) + a); SB(_m[t].m6, 3, 1, on_town_road); + SetRoadTypes(t, rt); } static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section) diff -r 0b2aebc8283e -r 0b8b245a2391 src/stdafx.h --- a/src/stdafx.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/stdafx.h Wed Jun 13 11:45:14 2007 +0000 @@ -78,6 +78,9 @@ # ifdef amiga # undef amiga # endif +/* Act like we already included this file, as it somehow gives linkage problems + * (mismatch linkage of C++ and C between this include and unistd.h). */ +#define CLIB_USERGROUP_PROTOS_H #endif /* __MORPHOS__ */ #ifdef __APPLE__ @@ -109,7 +112,6 @@ # define FORCEINLINE inline # define CDECL # define __int64 long long -# define NOT_REACHED() assert(0) # define GCC_PACK __attribute__((packed)) # if (__GNUC__ == 2) @@ -122,7 +124,6 @@ # define NORETURN # define FORCEINLINE inline # define CDECL -# define NOT_REACHED() assert(0) # define GCC_PACK # include #endif /* __WATCOMC__ */ @@ -160,11 +161,6 @@ # define FORCEINLINE __forceinline # define inline _inline # define CDECL _cdecl -# if defined(_DEBUG) -# define NOT_REACHED() assert(0) -# else -# define NOT_REACHED() _assume(0) -# endif /* _DEBUG */ int CDECL snprintf(char *str, size_t size, const char *format, ...); # if _MSC_VER < 1400 int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap); @@ -331,4 +327,12 @@ # define Point OTTD_AMIGA_POINT #endif +void +#ifndef STRGEN +/* In strgen error is not fatal and returns */ +NORETURN +#endif /* STRGEN */ +CDECL error(const char *str, ...); +#define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__) + #endif /* STDAFX_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/strgen/strgen.cpp --- a/src/strgen/strgen.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/strgen/strgen.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -506,6 +506,7 @@ {"WAYPOINT", EmitSingleChar, SCC_WAYPOINT_NAME, 1, 0}, // waypoint name {"STATION", EmitSingleChar, SCC_STATION_NAME, 1, 0}, {"TOWN", EmitSingleChar, SCC_TOWN_NAME, 1, 0}, + {"GROUP", EmitSingleChar, SCC_GROUP_NAME, 1, 0}, // 0x9D is used for the pseudo command SETCASE // 0x9E is used for case switching diff -r 0b2aebc8283e -r 0b8b245a2391 src/strings.cpp --- a/src/strings.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/strings.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -25,6 +25,8 @@ #include "industry.h" #include "helpers.hpp" #include "cargotype.h" +#include "group.h" +#include "debug.h" /* for opendir/readdir/closedir */ # include "fios.h" @@ -840,6 +842,18 @@ break; } + case SCC_GROUP_NAME: { // {GROUP} + const Group *g = GetGroup(GetInt32(&argv)); + int32 args[1]; + + assert(IsValidGroup(g)); + + args[0] = g->index; + buff = GetStringWithArgs(buff, (g->string_id == STR_SV_GROUP_NAME) ? (StringID)STR_GROUP_NAME_FORMAT : g->string_id, args, last); + + break; + } + case SCC_CURRENCY_64: { // {CURRENCY64} buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), false, last); break; diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/build_industry.h --- a/src/table/build_industry.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/build_industry.h Wed Jun 13 11:45:14 2007 +0000 @@ -5,8 +5,19 @@ #ifndef BUILD_INDUSTRY_H #define BUILD_INDUSTRY_H +/** + * Definition of an industry tiles layout. + * @param x offset x of this tile + * @param y offset y of this tile + * @param m index of the tile. + * @see _industry_specs + * @see IndustryTileTable + */ #define MK(x, y, m) {{x, y}, m} +/** + * Terminator of industry tiles layout definition + */ #define MKEND {{-0x80, 0}, 0} static const IndustryTileTable _tile_table_coal_mine_0[] = { @@ -1068,9 +1079,23 @@ #undef MK #undef MKEND +/** Array with saw sound, for sawmill */ +static const uint8 _sawmill_sounds[] = { SND_28_SAWMILL }; + +/** Array with whistle sound, for factory */ +static const uint8 _factory_sounds[] = { SND_03_FACTORY_WHISTLE }; + +/** Array with 3 animal sounds, for farms */ +static const uint8 _farm_sounds[] = { SND_24_SHEEP, SND_25_COW, SND_26_HORSE }; + +/** Array with... hem... a sound of toyland */ +static const uint8 _plastic_mine_sounds[] = { SND_33_PLASTIC_MINE }; + /** * Writes the properties of an industry into the IndustrySpec struct. * @param tbl tile table + * @param sndc number of sounds + * @param snd sounds table * @param d cost multiplier * @param ai1 appear chance ingame - temperate * @param ai2 appear chance ingame - arctic @@ -1091,8 +1116,11 @@ * @param r2 rate of production 1 * @param m minimum cargo moved to station * @param a1 accepted cargo 1 + * @param im1 input multiplier for cargo 1 * @param a2 accepted cargo 2 + * @param im2 input multiplier for cargo 2 * @param a3 accepted cargo 3 + * @param im3 input multiplier for cargo 3 * @param pr industry life (actually, the same as extractive, organic, processing in ttdpatch's specs) * @param clim climate availaility * @param bev industry behaviour @@ -1103,349 +1131,386 @@ * @param s3 text for production down */ -#define MI(tbl, d, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ - c1, c2, c3, proc, p1, r1, p2, r2, m, a1, a2, a3, pr, clim, bev, in, intx, s1, s2, s3) \ +#define MI(tbl, sndc, snd, d, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ + c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \ {tbl, lengthof(tbl), d, {c1, c2, c3}, proc, {p1, p2}, {r1, r2}, m, \ - {a1, a2, a3}, pr, clim, bev, col, in, intx, s1, s2, s3, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, 0, 0, 0, 0} + {a1, a2, a3}, {{im1, 0}, {im2, 0}, {im3, 0}}, pr, clim, bev, col, in, intx, s1, s2, s3, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, sndc, snd, 0, 0, 0, 0} static const IndustrySpec _industry_specs[] = { /* Format: - tile table cost multiplier appear chances(4ingame, 4random) map colour + tile table count and sounds table + cost multiplier appear chances(4ingame, 4random) map colour cannot be close to these industries (3 times) check proc (produced cargo + rate) (twice) minimum cargo moved to station - 3 accepted cargo + 3 accepted cargo and their corresponding input multiplier industry life climate availability industry behaviours industry name building text messages : Closure production up production down */ - MI(_tile_table_coal_mine, 210, 2, 3, 0, 0, 8, 8, 0, 0, 215, + MI(_tile_table_coal_mine, 0, NULL, + 210, 2, 3, 0, 0, 8, 8, 0, 0, 215, IT_POWER_STATION, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COAL, 15, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE | 1 << LT_ARCTIC, INDUSTRYBEH_CAN_SUBSIDENCE, STR_4802_COAL_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4836_NEW_COAL_SEAM_FOUND_AT, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_power_station, 30, 2, 2, 0, 0, 5, 5, 0, 0, 184, + MI(_tile_table_power_station, 0, NULL, + 30, 2, 2, 0, 0, 5, 5, 0, 0, 184, IT_COAL_MINE, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, - CT_COAL, CT_INVALID, CT_INVALID, + CT_COAL, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_TEMPERATE | 1 << LT_ARCTIC, INDUSTRYBEH_NONE, STR_4803_POWER_STATION, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_sawmill, 28, 2, 0, 0, 0, 5, 0, 0, 0, 194, + MI(_tile_table_sawmill, 1, _sawmill_sounds, + 28, 2, 0, 0, 0, 5, 0, 0, 0, 194, IT_FOREST, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_GOODS, 0, CT_INVALID, 0, 5, - CT_WOOD, CT_INVALID, CT_INVALID, + CT_WOOD, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TEMPERATE, INDUSTRYBEH_NONE, STR_4804_SAWMILL, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_forest, 200, 3, 4, 0, 0, 5, 5, 0, 0, 86, + MI(_tile_table_forest, 0, NULL, + 200, 3, 4, 0, 0, 5, 5, 0, 0, 86, IT_SAWMILL, IT_PAPER_MILL, IT_INVALID, CHECK_FOREST, CT_WOOD, 13, CT_INVALID, 0, 30, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE | 1 << LT_ARCTIC, INDUSTRYBEH_NONE, STR_4805_FOREST, STR_482E_NEW_BEING_PLANTED_NEAR, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_oil_refinery, 31, 2, 2, 2, 0, 4, 4, 4, 0, 191, + MI(_tile_table_oil_refinery, 0, NULL, + 31, 2, 2, 2, 0, 4, 4, 4, 0, 191, IT_OIL_RIG, IT_INVALID, IT_INVALID, CHECK_REFINERY, CT_GOODS, 0, CT_INVALID, 0, 5, - CT_OIL, CT_INVALID, CT_INVALID, + CT_OIL, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TEMPERATE | 1 << LT_ARCTIC | 1 << LT_TROPIC, INDUSTRYBEH_AIRPLANE_ATTACKS, STR_4806_OIL_REFINERY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_oil_rig, 240, 6, 0, 0, 0, 0, 0, 0, 0, 152, + MI(_tile_table_oil_rig, 0, NULL, + 240, 6, 0, 0, 0, 0, 0, 0, 0, 152, IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_OIL_RIG, CT_OIL, 15, CT_PASSENGERS, 2, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE, INDUSTRYBEH_BUILT_ONWATER | INDUSTRYBEH_AFTER_1960 | INDUSTRYBEH_AI_AIRSHIP_ROUTES, STR_4807_OIL_RIG, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4837_NEW_OIL_RESERVES_FOUND, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_factory, 26, 2, 0, 0, 0, 5, 0, 0, 0, 174, + MI(_tile_table_factory, 1, _factory_sounds, + 26, 2, 0, 0, 0, 5, 0, 0, 0, 174, IT_FARM, IT_STEEL_MILL, IT_INVALID, CHECK_NOTHING, CT_GOODS, 0, CT_INVALID, 0, 5, - CT_LIVESTOCK, CT_GRAIN, CT_STEEL, + CT_LIVESTOCK, 256, CT_GRAIN , 256, CT_STEEL, 256, INDUSTRYLIFE_CLOSABLE, 1 << LT_TEMPERATE, INDUSTRYBEH_CHOPPER_ATTACKS, STR_4808_FACTORY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_printing_works, 26, 0, 2, 0, 0, 0, 5, 0, 0, 174, + MI(_tile_table_printing_works, 1, _factory_sounds, + 26, 0, 2, 0, 0, 0, 5, 0, 0, 174, IT_PAPER_MILL, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_GOODS, 0, CT_INVALID, 0, 5, - CT_PAPER, CT_INVALID, CT_INVALID, + CT_PAPER, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_ARCTIC, INDUSTRYBEH_NONE, STR_4809_PRINTING_WORKS, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_steel_mill, 27, 2, 0, 0, 0, 5, 0, 0, 0, 10, + MI(_tile_table_steel_mill, 0, NULL, + 27, 2, 0, 0, 0, 5, 0, 0, 0, 10, IT_IRON_MINE, IT_FACTORY, IT_INVALID, CHECK_NOTHING, CT_STEEL, 0, CT_INVALID, 0, 5, - CT_IRON_ORE, CT_INVALID, CT_INVALID, + CT_IRON_ORE, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TEMPERATE, INDUSTRYBEH_NONE, STR_480A_STEEL_MILL, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_farm, 250, 2, 4, 0, 0, 9, 9, 0, 0, 48, + MI(_tile_table_farm, 3, _farm_sounds, + 250, 2, 4, 0, 0, 9, 9, 0, 0, 48, IT_FACTORY, IT_FOOD_PROCESS, IT_INVALID, CHECK_FARM, CT_GRAIN, 10, CT_LIVESTOCK, 10, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE | 1 << LT_ARCTIC, INDUSTRYBEH_PLANT_FIELDS | INDUSTRYBEH_PLANT_ON_BUILT, STR_480B_FARM, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_copper_mine, 205, 0, 0, 3, 0, 0, 0, 4, 0, 10, + MI(_tile_table_copper_mine, 0, NULL, + 205, 0, 0, 3, 0, 0, 0, 4, 0, 10, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COPPER_ORE, 10, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_480C_COPPER_ORE_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_oil_well, 220, 0, 5, 3, 0, 4, 5, 5, 0, 152, + MI(_tile_table_oil_well, 0, NULL, 220, 0, 5, 3, 0, 4, 5, 5, 0, 152, IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_OIL, 12, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE | 1 << LT_ARCTIC | 1 << LT_TROPIC, INDUSTRYBEH_DONT_INCR_PROD | INDUSTRYBEH_BEFORE_1950, STR_480D_OIL_WELLS, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4837_NEW_OIL_RESERVES_FOUND, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_bank, 193, 7, 0, 0, 0, 0, 0, 0, 0, 15, + MI(_tile_table_bank, 0, NULL, + 193, 7, 0, 0, 0, 0, 0, 0, 0, 15, IT_BANK_TEMP, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_VALUABLES, 6, CT_INVALID, 0, 5, - CT_VALUABLES, CT_INVALID, CT_INVALID, + CT_VALUABLES, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_TEMPERATE, INDUSTRYBEH_TOWN1200_MORE | INDUSTRYBEH_ONLY_INTOWN, STR_480E_BANK, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_food_process, 26, 0, 2, 2, 0, 0, 3, 4, 0, 55, + MI(_tile_table_food_process, 0, NULL, + 26, 0, 2, 2, 0, 0, 3, 4, 0, 55, IT_FRUIT_PLANTATION, IT_FARM, IT_FARM_2, CHECK_NOTHING, CT_FOOD, 0, CT_INVALID, 0, 5, - CT_FRUIT, CT_MAIZE, CT_INVALID, + CT_FRUIT, 256, CT_MAIZE, 256, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_ARCTIC | 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_480F_FOOD_PROCESSING_PLANT, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_paper_mill, 28, 0, 2, 0, 0, 0, 5, 0, 0, 10, + MI(_tile_table_paper_mill, 1, _sawmill_sounds, + 28, 0, 2, 0, 0, 0, 5, 0, 0, 10, IT_FOREST, IT_PRINTING_WORKS, IT_INVALID, CHECK_NOTHING, CT_PAPER, 0, CT_INVALID, 0, 5, - CT_WOOD, CT_INVALID, CT_INVALID, + CT_WOOD, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_ARCTIC, INDUSTRYBEH_NONE, STR_4810_PAPER_MILL, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_gold_mine, 208, 0, 3, 0, 0, 0, 4, 0, 0, 194, + MI(_tile_table_gold_mine, 0, NULL, + 208, 0, 3, 0, 0, 0, 4, 0, 0, 194, IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_GOLD, 7, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_ARCTIC, INDUSTRYBEH_NONE, STR_4811_GOLD_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_bank2, 19, 0, 3, 3, 0, 0, 6, 5, 0, 15, + MI(_tile_table_bank2, 0, NULL, + 19, 0, 3, 3, 0, 0, 6, 5, 0, 15, IT_GOLD_MINE, IT_DIAMOND_MINE, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, - CT_GOLD, CT_INVALID, CT_INVALID, + CT_GOLD, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_ARCTIC | 1 << LT_TROPIC, INDUSTRYBEH_ONLY_INTOWN, STR_4812_BANK, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_diamond_mine, 213, 0, 0, 3, 0, 0, 0, 4, 0, 184, + MI(_tile_table_diamond_mine, 0, NULL, + 213, 0, 0, 3, 0, 0, 0, 4, 0, 184, IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_DIAMONDS, 7, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_4813_DIAMOND_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_iron_mine, 220, 2, 0, 0, 0, 5, 0, 0, 0, 55, + MI(_tile_table_iron_mine, 0, NULL, + 220, 2, 0, 0, 0, 5, 0, 0, 0, 55, IT_STEEL_MILL, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_IRON_ORE, 10, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TEMPERATE, INDUSTRYBEH_NONE, STR_4814_IRON_ORE_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_fruit_plantation, 225, 0, 0, 2, 0, 0, 0, 4, 0, 86, + MI(_tile_table_fruit_plantation, 0, NULL, + 225, 0, 0, 2, 0, 0, 0, 4, 0, 86, IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_FRUIT, 10, CT_INVALID, 0, 15, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_4815_FRUIT_PLANTATION, STR_482E_NEW_BEING_PLANTED_NEAR, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_rubber_plantation, 218, 0, 0, 3, 0, 0, 0, 4, 0, 39, + MI(_tile_table_rubber_plantation, 0, NULL, + 218, 0, 0, 3, 0, 0, 0, 4, 0, 39, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_RUBBER, 10, CT_INVALID, 0, 15, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_4816_RUBBER_PLANTATION, STR_482E_NEW_BEING_PLANTED_NEAR, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_water_supply, 199, 0, 0, 3, 0, 0, 0, 4, 0, 37, + MI(_tile_table_water_supply, 0, NULL, + 199, 0, 0, 3, 0, 0, 0, 4, 0, 37, IT_WATER_TOWER, IT_INVALID, IT_INVALID, CHECK_WATER, CT_WATER, 12, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_4817_WATER_SUPPLY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_water_tower, 14, 0, 0, 4, 0, 0, 0, 8, 0, 208, + MI(_tile_table_water_tower, 0, NULL, + 14, 0, 0, 4, 0, 0, 0, 8, 0, 208, IT_WATER_SUPPLY, IT_INVALID, IT_INVALID, CHECK_WATER, CT_INVALID, 0, CT_INVALID, 0, 5, - CT_WATER, CT_INVALID, CT_INVALID, + CT_WATER, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_TROPIC, INDUSTRYBEH_ONLY_INTOWN, STR_4818_WATER_TOWER, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_factory2, 26, 0, 0, 2, 0, 0, 0, 4, 0, 174, + MI(_tile_table_factory2, 1, _factory_sounds, + 26, 0, 0, 2, 0, 0, 0, 4, 0, 174, IT_RUBBER_PLANTATION, IT_COPPER_MINE, IT_LUMBER_MILL, CHECK_PLANTATION, CT_GOODS, 0, CT_INVALID, 0, 5, - CT_RUBBER, CT_COPPER_ORE, CT_WOOD, + CT_RUBBER, 256, CT_COPPER_ORE, 256, CT_WOOD, 256, INDUSTRYLIFE_CLOSABLE, 1 << LT_TROPIC, INDUSTRYBEH_NONE, STR_4819_FACTORY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_farm2, 250, 0, 0, 1, 0, 0, 0, 2, 0, 48, + MI(_tile_table_farm2, 0, NULL, + 250, 0, 0, 1, 0, 0, 0, 2, 0, 48, IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_MAIZE, 11, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TROPIC, INDUSTRYBEH_PLANT_FIELDS | INDUSTRYBEH_PLANT_ON_BUILT, STR_481A_FARM, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_lumber_mill, 17, 0, 0, 0, 0, 0, 0, 0, 0, 194, + MI(_tile_table_lumber_mill, 0, NULL, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 194, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_LUMBERMILL, CT_WOOD, 0, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TROPIC, INDUSTRYBEH_CUT_TREES, STR_481B_LUMBER_MILL, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4834_LACK_OF_NEARBY_TREES_CAUSES, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_cotton_candy, 195, 0, 0, 0, 3, 0, 0, 0, 5, 48, + MI(_tile_table_cotton_candy, 0, NULL, + 195, 0, 0, 0, 3, 0, 0, 0, 5, 48, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COTTON_CANDY, 13, CT_INVALID, 0, 30, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_481C_COTTON_CANDY_FOREST, STR_482E_NEW_BEING_PLANTED_NEAR, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_candy_factory, 26, 0, 0, 0, 3, 0, 0, 0, 5, 174, + MI(_tile_table_candy_factory, 0, NULL, + 26, 0, 0, 0, 3, 0, 0, 0, 5, 174, IT_COTTON_CANDY, IT_TOFFEE_QUARRY, IT_SUGAR_MINE, CHECK_NOTHING, CT_CANDY, 0, CT_INVALID, 0, 5, - CT_SUGAR, CT_TOFFEE, CT_COTTON_CANDY, + CT_SUGAR, 256, CT_TOFFEE, 256, CT_COTTON_CANDY, 256, INDUSTRYLIFE_CLOSABLE, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_481D_CANDY_FACTORY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_battery_farm, 187, 0, 0, 0, 3, 0, 0, 0, 4, 39, + MI(_tile_table_battery_farm, 0, NULL, + 187, 0, 0, 0, 3, 0, 0, 0, 4, 39, IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_BATTERIES, 11, CT_INVALID, 0, 30, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_481E_BATTERY_FARM, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4838_IMPROVED_FARMING_METHODS, STR_483A_INSECT_INFESTATION_CAUSES), - MI(_tile_table_cola_wells, 193, 0, 0, 0, 3, 0, 0, 0, 5, 55, + MI(_tile_table_cola_wells, 0, NULL, + 193, 0, 0, 0, 3, 0, 0, 0, 5, 55, IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COLA, 12, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_481F_COLA_WELLS, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_toy_shop, 17, 0, 0, 0, 3, 0, 0, 0, 4, 208, + MI(_tile_table_toy_shop, 0, NULL, + 17, 0, 0, 0, 3, 0, 0, 0, 4, 208, IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, - CT_TOYS, CT_INVALID, CT_INVALID, + CT_TOYS, 256, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_NOT_CLOSABLE, 1 << LT_TOYLAND, INDUSTRYBEH_ONLY_NEARTOWN, STR_4820_TOY_SHOP, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_toy_factory, 20, 0, 0, 0, 3, 0, 0, 0, 5, 10, + MI(_tile_table_toy_factory, 0, NULL, + 20, 0, 0, 0, 3, 0, 0, 0, 5, 10, IT_PLASTIC_FOUNTAINS, IT_BATTERY_FARM, IT_TOY_SHOP, CHECK_NOTHING, CT_TOYS, 0, CT_INVALID, 0, 5, - CT_PLASTIC, CT_BATTERIES, CT_INVALID, + CT_PLASTIC, 256, CT_BATTERIES, 256, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4821_TOY_FACTORY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_plastic_fountain, 192, 0, 0, 0, 3, 0, 0, 0, 5, 37, + MI(_tile_table_plastic_fountain, 1, _plastic_mine_sounds, + 192, 0, 0, 0, 3, 0, 0, 0, 5, 37, IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_PLASTIC, 14, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4822_PLASTIC_FOUNTAINS, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_fizzy_drink, 22, 0, 0, 0, 3, 0, 0, 0, 4, 184, + MI(_tile_table_fizzy_drink, 0, NULL, + 22, 0, 0, 0, 3, 0, 0, 0, 4, 184, IT_COLA_WELLS, IT_BUBBLE_GENERATOR, IT_INVALID, CHECK_NOTHING, CT_FIZZY_DRINKS, 0, CT_INVALID, 0, 5, - CT_COLA, CT_BUBBLES, CT_INVALID, + CT_COLA, 256, CT_BUBBLES, 256, CT_INVALID, 0, INDUSTRYLIFE_CLOSABLE, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4823_FIZZY_DRINK_FACTORY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4833_SUPPLY_PROBLEMS_CAUSE_TO, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_bubble_generator, 203, 0, 0, 0, 3, 0, 0, 0, 5, 152, + MI(_tile_table_bubble_generator, 0, NULL, + 203, 0, 0, 0, 3, 0, 0, 0, 5, 152, IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_BUBBLEGEN, CT_BUBBLES, 13, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4824_BUBBLE_GENERATOR, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_toffee_quarry, 213, 0, 0, 0, 3, 0, 0, 0, 5, 194, + MI(_tile_table_toffee_quarry, 0, NULL, + 213, 0, 0, 0, 3, 0, 0, 0, 5, 194, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_TOFFEE, 10, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4825_TOFFEE_QUARRY, STR_482D_NEW_UNDER_CONSTRUCTION, STR_4832_ANNOUNCES_IMMINENT_CLOSURE, STR_4835_INCREASES_PRODUCTION, STR_4839_PRODUCTION_DOWN_BY_50), - MI(_tile_table_sugar_mine, 210, 0, 0, 0, 2, 0, 0, 0, 4, 15, + MI(_tile_table_sugar_mine, 0, NULL, + 210, 0, 0, 0, 2, 0, 0, 0, 4, 15, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_SUGAR, 11, CT_INVALID, 0, 5, - CT_INVALID, CT_INVALID, CT_INVALID, + CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, 0, INDUSTRYLIFE_PRODUCTION, 1 << LT_TOYLAND, INDUSTRYBEH_NONE, STR_4826_SUGAR_MINE, STR_482D_NEW_UNDER_CONSTRUCTION, diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/cargo_const.h --- a/src/table/cargo_const.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/cargo_const.h Wed Jun 13 11:45:14 2007 +0000 @@ -17,10 +17,16 @@ STR_0011_MAIL, STR_0031_MAIL, STR_BAGS, STR_QUANTITY_MAIL, STR_ABBREV_MAIL, SPR_CARGO_MAIL, CC_MAIL ), + /* Oil in temperate and arctic */ MK( 3, 'OIL_', 174, 16, 4437, 25, 255, true, TE_NONE, STR_0012_OIL, STR_0032_OIL, STR_LITERS, STR_QUANTITY_OIL, STR_ABBREV_OIL, SPR_CARGO_OIL, CC_LIQUID ), + /* Oil in subtropic */ + MK( 3, 'OIL_', 174, 16, 4892, 25, 255, true, TE_NONE, + STR_0012_OIL, STR_0032_OIL, STR_LITERS, STR_QUANTITY_OIL, STR_ABBREV_OIL, + SPR_CARGO_OIL, CC_LIQUID ), + MK( 4, 'LVST', 208, 3, 4322, 4, 18, true, TE_NONE, STR_0013_LIVESTOCK, STR_0033_LIVESTOCK, STR_ITEMS, STR_QUANTITY_LIVESTOCK, STR_ABBREV_LIVESTOCK, SPR_CARGO_LIVESTOCK, CC_PIECE_GOODS ), @@ -37,14 +43,20 @@ STR_0022_WHEAT, STR_0042_WHEAT, STR_TONS, STR_QUANTITY_WHEAT, STR_ABBREV_WHEAT, SPR_CARGO_GRAIN, CC_BULK ), - MK( 6, 'MAIZ', 191, 6, 4778, 4, 40, true, TE_NONE, + MK( 6, 'MAIZ', 191, 6, 4322, 4, 40, true, TE_NONE, STR_001B_MAIZE, STR_003B_MAIZE, STR_TONS, STR_QUANTITY_MAIZE, STR_ABBREV_MAIZE, SPR_CARGO_GRAIN, CC_BULK ), + /* Wood in temperate and arctic */ MK( 7, 'WOOD', 84, 16, 5005, 15, 255, true, TE_NONE, STR_0016_WOOD, STR_0036_WOOD, STR_TONS, STR_QUANTITY_WOOD, STR_ABBREV_WOOD, SPR_CARGO_WOOD, CC_PIECE_GOODS ), + /* Wood in subtropic */ + MK( 7, 'WOOD', 84, 16, 7964, 15, 255, true, TE_NONE, + STR_0016_WOOD, STR_0036_WOOD, STR_TONS, STR_QUANTITY_WOOD, STR_ABBREV_WOOD, + SPR_CARGO_WOOD, CC_PIECE_GOODS ), + MK( 8, 'IORE', 184, 16, 5120, 9, 255, true, TE_NONE, STR_0017_IRON_ORE, STR_0037_IRON_ORE, STR_TONS, STR_QUANTITY_IRON_ORE, STR_ABBREV_IRON_ORE, SPR_CARGO_IRON_ORE, CC_BULK ), @@ -57,15 +69,15 @@ STR_0019_VALUABLES, STR_0039_VALUABLES, STR_BAGS, STR_QUANTITY_VALUABLES, STR_ABBREV_VALUABLES, SPR_CARGO_VALUES_GOLD, CC_ARMOURED ), - MK( 10, 'GOLD', 202, 8, 7509, 10, 40, true, TE_NONE, + MK( 10, 'GOLD', 202, 8, 5802, 10, 40, true, TE_NONE, STR_0020_GOLD, STR_0040_GOLD, STR_BAGS, STR_QUANTITY_GOLD, STR_ABBREV_GOLD, SPR_CARGO_VALUES_GOLD, CC_ARMOURED ), - MK( 10, 'DIAM', 202, 2, 7509, 10, 255, true, TE_NONE, + MK( 10, 'DIAM', 202, 2, 5802, 10, 255, true, TE_NONE, STR_001D_DIAMONDS, STR_003D_DIAMOND, STR_BAGS, STR_QUANTITY_DIAMONDS, STR_ABBREV_DIAMONDS, SPR_CARGO_DIAMONDS, CC_ARMOURED ), - MK( 11, 'PAPR', 10, 16, 5688, 7, 60, true, TE_NONE, + MK( 11, 'PAPR', 10, 16, 5461, 7, 60, true, TE_NONE, STR_001F_PAPER, STR_003F_PAPER, STR_TONS, STR_QUANTITY_PAPER, STR_ABBREV_PAPER, SPR_CARGO_PAPER, CC_PIECE_GOODS ), @@ -73,27 +85,27 @@ STR_001E_FOOD, STR_003E_FOOD, STR_TONS, STR_QUANTITY_FOOD, STR_ABBREV_FOOD, SPR_CARGO_FOOD, CC_EXPRESS | CC_REFRIGERATED), - MK( 13, 'FRUT', 208, 6, 4322, 0, 15, true, TE_NONE, + MK( 13, 'FRUT', 208, 6, 4209, 0, 15, true, TE_NONE, STR_001C_FRUIT, STR_003C_FRUIT, STR_TONS, STR_QUANTITY_FRUIT, STR_ABBREV_FRUIT, SPR_CARGO_FRUIT, CC_BULK | CC_REFRIGERATED), - MK( 14, 'CORE', 184, 6, 5120, 12, 255, true, TE_NONE, + MK( 14, 'CORE', 184, 6, 4892, 12, 255, true, TE_NONE, STR_001A_COPPER_ORE, STR_003A_COPPER_ORE, STR_TONS, STR_QUANTITY_COPPER_ORE, STR_ABBREV_COPPER_ORE, SPR_CARGO_COPPER_ORE, CC_BULK ), - MK( 15, 'WATR', 10, 6, 5688, 20, 80, true, TE_WATER, + MK( 15, 'WATR', 10, 6, 4664, 20, 80, true, TE_WATER, STR_0021_WATER, STR_0041_WATER, STR_LITERS, STR_QUANTITY_WATER, STR_ABBREV_WATER, SPR_CARGO_WATERCOLA, CC_LIQUID ), - MK( 16, 'RUBR', 32, 6, 5916, 2, 20, true, TE_NONE, + MK( 16, 'RUBR', 32, 6, 4437, 2, 20, true, TE_NONE, STR_0023_RUBBER, STR_0043_RUBBER, STR_LITERS, STR_QUANTITY_RUBBER, STR_ABBREV_RUBBER, SPR_CARGO_RUBBER, CC_LIQUID ), - MK( 17, 'SUGR', 32, 16, 5916, 20, 255, true, TE_NONE, + MK( 17, 'SUGR', 32, 16, 4437, 20, 255, true, TE_NONE, STR_0024_SUGAR, STR_0044_SUGAR, STR_TONS, STR_QUANTITY_SUGAR, STR_ABBREV_SUGAR, SPR_CARGO_SUGAR, CC_BULK ), - MK( 18, 'TOYS', 174, 2, 4437, 25, 255, true, TE_NONE, + MK( 18, 'TOYS', 174, 2, 5574, 25, 255, true, TE_NONE, STR_0025_TOYS, STR_0045_TOY, STR_NOTHING, STR_QUANTITY_TOYS, STR_ABBREV_TOYS, SPR_CARGO_TOYS, CC_PIECE_GOODS ), @@ -109,23 +121,23 @@ STR_002A_TOFFEE, STR_004A_TOFFEE, STR_TONS, STR_QUANTITY_TOFFEE, STR_ABBREV_TOFFEE, SPR_CARGO_TOFFEE, CC_BULK ), - MK( 22, 'COLA', 84, 16, 5005, 5, 75, true, TE_NONE, + MK( 22, 'COLA', 84, 16, 4892, 5, 75, true, TE_NONE, STR_0027_COLA, STR_0047_COLA, STR_LITERS, STR_QUANTITY_COLA, STR_ABBREV_COLA, SPR_CARGO_WATERCOLA, CC_LIQUID ), - MK( 23, 'CTCD', 184, 16, 5120, 10, 25, true, TE_NONE, + MK( 23, 'CTCD', 184, 16, 5005, 10, 25, true, TE_NONE, STR_0028_COTTON_CANDY, STR_0048_COTTON_CANDY, STR_TONS, STR_QUANTITY_CANDYFLOSS, STR_ABBREV_CANDYFLOSS, SPR_CARGO_COTTONCANDY, CC_BULK ), - MK( 24, 'BUBL', 10, 1, 5688, 20, 80, true, TE_NONE, + MK( 24, 'BUBL', 10, 1, 5077, 20, 80, true, TE_NONE, STR_0029_BUBBLES, STR_0049_BUBBLE, STR_NOTHING, STR_QUANTITY_BUBBLES, STR_ABBREV_BUBBLES, SPR_CARGO_BUBBLES, CC_PIECE_GOODS ), - MK( 25, 'PLST', 202, 16, 7509, 30, 255, true, TE_NONE, + MK( 25, 'PLST', 202, 16, 4664, 30, 255, true, TE_NONE, STR_002C_PLASTIC, STR_004C_PLASTIC, STR_LITERS, STR_QUANTITY_PLASTIC, STR_ABBREV_PLASTIC, SPR_CARGO_PLASTIC, CC_LIQUID ), - MK( 26, 'FZDR', 48, 2, 5688, 30, 50, true, TE_FOOD, + MK( 26, 'FZDR', 48, 2, 6250, 30, 50, true, TE_FOOD, STR_002D_FIZZY_DRINKS, STR_004D_FIZZY_DRINK, STR_NOTHING, STR_QUANTITY_FIZZY_DRINKS, STR_ABBREV_FIZZY_DRINKS, SPR_CARGO_FIZZYDRINK, CC_PIECE_GOODS ), @@ -136,7 +148,7 @@ static const CargoLabel _default_climate_cargo[NUM_LANDSCAPE][12] = { { 'PASS', 'COAL', 'MAIL', 'OIL_', 'LVST', 'GOOD', 'GRAI', 'WOOD', 'IORE', 'STEL', 'VALU', 'VOID', }, { 'PASS', 'COAL', 'MAIL', 'OIL_', 'LVST', 'GOOD', 'WHEA', 'WOOD', 'VOID', 'PAPR', 'GOLD', 'FOOD', }, - { 'PASS', 'RUBR', 'MAIL', 'OIL_', 'FRUT', 'GOOD', 'MAIZ', 'WOOD', 'CORE', 'WATR', 'DIAM', 'FOOD', }, + { 'PASS', 'RUBR', 'MAIL', 4, 'FRUT', 'GOOD', 'MAIZ', 11, 'CORE', 'WATR', 'DIAM', 'FOOD', }, { 'PASS', 'SUGR', 'MAIL', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR', }, }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/control_codes.h --- a/src/table/control_codes.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/control_codes.h Wed Jun 13 11:45:14 2007 +0000 @@ -26,6 +26,7 @@ SCC_WAYPOINT_NAME, SCC_STATION_NAME, SCC_TOWN_NAME, + SCC_GROUP_NAME, SCC_CURRENCY_COMPACT, SCC_CURRENCY_COMPACT_64, diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/engines.h --- a/src/table/engines.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/engines.h Wed Jun 13 11:45:14 2007 +0000 @@ -19,7 +19,7 @@ * @note the 0x80 in parameter b sets the "is carriage bit" * @note the 5 between d and e is the load amount */ -#define MK(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, e, 0, 8, 0, 0 } +#define MK(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, e, 0, 8, 0, 0, 0 } /** Writes the properties of a train carriage into the EngineInfo struct. * @param a Introduction date @@ -30,7 +30,7 @@ * @see MK * @note the 5 between d and e is the load amount */ -#define MW(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b | 0x80, 5, e, 0, 8, 0, 0 } +#define MW(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b | 0x80, 5, e, 0, 8, 0, 0, 0 } /** Writes the properties of a ship into the EngineInfo struct. * @param a Introduction date @@ -41,7 +41,7 @@ * @see MK * @note the 10 between d and e is the load amount */ -#define MS(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, e, 0, 8, 0, 0 } +#define MS(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, e, 0, 8, 0, 0, 0 } /** Writes the properties of an aeroplane into the EngineInfo struct. * @param a Introduction date @@ -52,7 +52,7 @@ * @see MK * @note the 20 between d and e is the load amount */ -#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, 0, 8, 0, 0 } +#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, 0, 8, 0, 0, 0 } // Climates // T = Temperate @@ -339,20 +339,25 @@ * @param e power (hp) * @param f weight * @param g running_cost_base - * @param h running_cost_class - engclass + * @param h running_cost_class * @param i capacity * @param j cargo_type * @param k ai_rank * @param l railtype + * @param m engclass * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76 */ -#define RVI(a, b, c, d, e, f, g, h, i, j, k, l) { a, b, c, {l}, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 76, 0 } +#define RVI(a, b, c, d, e, f, g, h, i, j, k, l, m) { a, b, c, {l}, d, e, f, g, h, m, i, j, k, 0, 0, 0, 0, 76, 0 } #define M RAILVEH_MULTIHEAD #define W RAILVEH_WAGON #define G RAILVEH_SINGLEHEAD -#define S 0 -#define D 1 -#define E 2 +#define S EC_STEAM +#define D EC_DIESEL +#define E EC_ELECTRIC +#define N EC_MONORAIL +#define V EC_MAGLEV +/* Wagons always have engine type 0, i.e. steam. */ +#define A EC_STEAM #define R RAILTYPE_RAIL #define C RAILTYPE_ELECTRIC @@ -360,132 +365,134 @@ #define L RAILTYPE_MAGLEV const RailVehicleInfo orig_rail_vehicle_info[NUM_TRAIN_ENGINES] = { - // image_index max_speed (kph) running_cost_base - // | flags | power (hp) | running_cost_class & engclass - // | | base_cost | weight | | capacity - // | | | | | | | | | cargo_type - // | | | | | | | | | | - RVI( 2, G, 7, 64, 300, 47, 50, S, 0, 0 , 1, R), // 0 - RVI(19, G, 8, 80, 600, 65, 65, D, 0, 0 , 4, R), // 1 - RVI( 2, G, 10, 72, 400, 85, 90, S, 0, 0 , 7, R), // 2 - RVI( 0, G, 15, 96, 900, 130, 130, S, 0, 0 , 19, R), // 3 - RVI( 1, G, 19, 112, 1000, 140, 145, S, 0, 0 , 20, R), // 4 - RVI(12, G, 16, 120, 1400, 95, 125, D, 0, 0 , 30, R), // 5 - RVI(14, G, 20, 152, 2000, 120, 135, D, 0, 0 , 31, R), // 6 - RVI( 3, G, 14, 88, 1100, 145, 130, S, 0, 0 , 19, R), // 7 - RVI( 0, G, 13, 112, 1000, 131, 120, S, 0, 0 , 20, R), // 8 - RVI( 1, G, 19, 128, 1200, 162, 140, S, 0, 0 , 21, R), // 9 - RVI( 0, G, 22, 144, 1600, 170, 130, S, 0, 0 , 22, R), // 10 - RVI( 8, M, 11, 112, 600/2,32/2, 85/2, D, 38, CT_PASSENGERS , 10, R), // 11 - RVI(10, M, 14, 120, 700/2,38/2, 70/2, D, 40, CT_PASSENGERS , 11, R), // 12 - RVI( 4, G, 15, 128, 1250, 72, 95, D, 0, 0 , 30, R), // 13 - RVI( 5, G, 17, 144, 1750, 101, 120, D, 0, 0 , 31, R), // 14 - RVI( 4, G, 18, 160, 2580, 112, 140, D, 0, 0 , 32, R), // 15 - RVI(14, G, 23, 96, 4000, 150, 135, D, 0, 0 , 33, R), // 16 - RVI(12, G, 16, 112, 2400, 120, 105, D, 0, 0 , 34, R), // 17 - RVI(13, G, 30, 112, 6600, 207, 155, D, 0, 0 , 35, R), // 18 - RVI(15, G, 18, 104, 1500, 110, 105, D, 0, 0 , 29, R), // 19 - RVI(16, M, 35, 160, 3500/2,95/2, 205/2, D, 0, 0 , 45, R), // 20 - RVI(18, G, 21, 104, 2200, 120, 145, D, 0, 0 , 32, R), // 21 - RVI( 6, M, 20, 200, 4500/2,70/2, 190/2, D, 4, CT_MAIL , 50, R), // 22 - RVI(20, G, 26, 160, 3600, 84, 180, E, 0, 0 , 40, C), // 23 - RVI(20, G, 30, 176, 5000, 82, 205, E, 0, 0 , 41, C), // 24 - RVI(21, M, 40, 240, 7000/2,90/2, 240/2, E, 0, 0 , 51, C), // 25 - RVI(23, M, 43, 264, 8000/2,95/2, 250/2, E, 0, 0 , 52, C), // 26 - RVI(33, W, 247, 0, 0, 25, 0, 0, 40, CT_PASSENGERS , 0, R), // 27 - RVI(35, W, 228, 0, 0, 21, 0, 0, 30, CT_MAIL , 0, R), // 28 - RVI(34, W, 176, 0, 0, 18, 0, 0, 30, CT_COAL , 0, R), // 29 - RVI(36, W, 200, 0, 0, 24, 0, 0, 30, CT_OIL , 0, R), // 30 - RVI(37, W, 192, 0, 0, 20, 0, 0, 25, CT_LIVESTOCK , 0, R), // 31 - RVI(38, W, 190, 0, 0, 21, 0, 0, 25, CT_GOODS , 0, R), // 32 - RVI(39, W, 182, 0, 0, 19, 0, 0, 30, CT_GRAIN , 0, R), // 33 - RVI(40, W, 181, 0, 0, 16, 0, 0, 30, CT_WOOD , 0, R), // 34 - RVI(41, W, 179, 0, 0, 19, 0, 0, 30, CT_IRON_ORE , 0, R), // 35 - RVI(42, W, 196, 0, 0, 18, 0, 0, 20, CT_STEEL , 0, R), // 36 - RVI(43, W, 255, 0, 0, 30, 0, 0, 20, CT_VALUABLES , 0, R), // 37 - RVI(44, W, 191, 0, 0, 22, 0, 0, 25, CT_FOOD , 0, R), // 38 - RVI(45, W, 196, 0, 0, 18, 0, 0, 20, CT_PAPER , 0, R), // 39 - RVI(46, W, 179, 0, 0, 19, 0, 0, 30, CT_COPPER_ORE , 0, R), // 40 - RVI(47, W, 199, 0, 0, 25, 0, 0, 25, CT_WATER , 0, R), // 41 - RVI(48, W, 182, 0, 0, 18, 0, 0, 25, CT_FRUIT , 0, R), // 42 - RVI(49, W, 185, 0, 0, 19, 0, 0, 21, CT_RUBBER , 0, R), // 43 - RVI(50, W, 176, 0, 0, 19, 0, 0, 30, CT_SUGAR , 0, R), // 44 - RVI(51, W, 178, 0, 0, 20, 0, 0, 30, CT_COTTON_CANDY, 0, R), // 45 - RVI(52, W, 192, 0, 0, 20, 0, 0, 30, CT_TOFFEE , 0, R), // 46 - RVI(53, W, 190, 0, 0, 21, 0, 0, 20, CT_BUBBLES , 0, R), // 47 - RVI(54, W, 182, 0, 0, 24, 0, 0, 25, CT_COLA , 0, R), // 48 - RVI(55, W, 181, 0, 0, 21, 0, 0, 25, CT_CANDY , 0, R), // 49 - RVI(56, W, 183, 0, 0, 21, 0, 0, 20, CT_TOYS , 0, R), // 50 - RVI(57, W, 196, 0, 0, 18, 0, 0, 22, CT_BATTERIES , 0, R), // 51 - RVI(58, W, 193, 0, 0, 18, 0, 0, 25, CT_FIZZY_DRINKS, 0, R), // 52 - RVI(59, W, 191, 0, 0, 18, 0, 0, 30, CT_PLASTIC , 0, R), // 53 - RVI(25, G, 52, 304, 9000, 95, 230, E, 0, 0 , 60, O), // 54 - RVI(26, M, 60, 336, 10000/2,85/2, 240/2, E, 25, CT_PASSENGERS , 62, O), // 55 - RVI(26, G, 53, 320, 5000, 95, 230, E, 0, 0 , 63, O), // 56 - RVI(60, W, 247, 0, 0, 25, 0, 0, 45, CT_PASSENGERS , 0, O), // 57 - RVI(62, W, 228, 0, 0, 21, 0, 0, 35, CT_MAIL , 0, O), // 58 - RVI(61, W, 176, 0, 0, 18, 0, 0, 35, CT_COAL , 0, O), // 59 - RVI(63, W, 200, 0, 0, 24, 0, 0, 35, CT_OIL , 0, O), // 60 - RVI(64, W, 192, 0, 0, 20, 0, 0, 30, CT_LIVESTOCK , 0, O), // 61 - RVI(65, W, 190, 0, 0, 21, 0, 0, 30, CT_GOODS , 0, O), // 62 - RVI(66, W, 182, 0, 0, 19, 0, 0, 35, CT_GRAIN , 0, O), // 63 - RVI(67, W, 181, 0, 0, 16, 0, 0, 35, CT_WOOD , 0, O), // 64 - RVI(68, W, 179, 0, 0, 19, 0, 0, 35, CT_IRON_ORE , 0, O), // 65 - RVI(69, W, 196, 0, 0, 18, 0, 0, 25, CT_STEEL , 0, O), // 66 - RVI(70, W, 255, 0, 0, 30, 0, 0, 25, CT_VALUABLES , 0, O), // 67 - RVI(71, W, 191, 0, 0, 22, 0, 0, 30, CT_FOOD , 0, O), // 68 - RVI(72, W, 196, 0, 0, 18, 0, 0, 25, CT_PAPER , 0, O), // 69 - RVI(73, W, 179, 0, 0, 19, 0, 0, 35, CT_COPPER_ORE , 0, O), // 70 - RVI(47, W, 199, 0, 0, 25, 0, 0, 30, CT_WATER , 0, O), // 71 - RVI(48, W, 182, 0, 0, 18, 0, 0, 30, CT_FRUIT , 0, O), // 72 - RVI(49, W, 185, 0, 0, 19, 0, 0, 26, CT_RUBBER , 0, O), // 73 - RVI(50, W, 176, 0, 0, 19, 0, 0, 35, CT_SUGAR , 0, O), // 74 - RVI(51, W, 178, 0, 0, 20, 0, 0, 35, CT_COTTON_CANDY, 0, O), // 75 - RVI(52, W, 192, 0, 0, 20, 0, 0, 35, CT_TOFFEE , 0, O), // 76 - RVI(53, W, 190, 0, 0, 21, 0, 0, 25, CT_BUBBLES , 0, O), // 77 - RVI(54, W, 182, 0, 0, 24, 0, 0, 30, CT_COLA , 0, O), // 78 - RVI(55, W, 181, 0, 0, 21, 0, 0, 30, CT_CANDY , 0, O), // 79 - RVI(56, W, 183, 0, 0, 21, 0, 0, 25, CT_TOYS , 0, O), // 80 - RVI(57, W, 196, 0, 0, 18, 0, 0, 27, CT_BATTERIES , 0, O), // 81 - RVI(58, W, 193, 0, 0, 18, 0, 0, 30, CT_FIZZY_DRINKS, 0, O), // 82 - RVI(59, W, 191, 0, 0, 18, 0, 0, 35, CT_PLASTIC , 0, O), // 83 - RVI(28, G, 70, 400, 10000, 105, 250, E, 0, 0 , 70, L), // 84 - RVI(29, G, 74, 448, 12000, 120, 253, E, 0, 0 , 71, L), // 85 - RVI(30, G, 82, 480, 15000, 130, 254, E, 0, 0 , 72, L), // 86 - RVI(31, M, 95, 640, 20000/2,150/2,255/2, E, 0, 0 , 73, L), // 87 - RVI(28, G, 70, 480, 10000, 120, 250, E, 0, 0 , 74, L), // 88 - RVI(60, W, 247, 0, 0, 25, 0, 0, 47, CT_PASSENGERS , 0, L), // 89 - RVI(62, W, 228, 0, 0, 21, 0, 0, 37, CT_MAIL , 0, L), // 90 - RVI(61, W, 176, 0, 0, 18, 0, 0, 37, CT_COAL , 0, L), // 91 - RVI(63, W, 200, 0, 0, 24, 0, 0, 37, CT_OIL , 0, L), // 92 - RVI(64, W, 192, 0, 0, 20, 0, 0, 32, CT_LIVESTOCK , 0, L), // 93 - RVI(65, W, 190, 0, 0, 21, 0, 0, 32, CT_GOODS , 0, L), // 94 - RVI(66, W, 182, 0, 0, 19, 0, 0, 37, CT_GRAIN , 0, L), // 95 - RVI(67, W, 181, 0, 0, 16, 0, 0, 37, CT_WOOD , 0, L), // 96 - RVI(68, W, 179, 0, 0, 19, 0, 0, 37, CT_IRON_ORE , 0, L), // 97 - RVI(69, W, 196, 0, 0, 18, 0, 0, 27, CT_STEEL , 0, L), // 98 - RVI(70, W, 255, 0, 0, 30, 0, 0, 27, CT_VALUABLES , 0, L), // 99 - RVI(71, W, 191, 0, 0, 22, 0, 0, 32, CT_FOOD , 0, L), // 100 - RVI(72, W, 196, 0, 0, 18, 0, 0, 27, CT_PAPER , 0, L), // 101 - RVI(73, W, 179, 0, 0, 19, 0, 0, 37, CT_COPPER_ORE , 0, L), // 102 - RVI(47, W, 199, 0, 0, 25, 0, 0, 32, CT_WATER , 0, L), // 103 - RVI(48, W, 182, 0, 0, 18, 0, 0, 32, CT_FRUIT , 0, L), // 104 - RVI(49, W, 185, 0, 0, 19, 0, 0, 28, CT_RUBBER , 0, L), // 105 - RVI(50, W, 176, 0, 0, 19, 0, 0, 37, CT_SUGAR , 0, L), // 106 - RVI(51, W, 178, 0, 0, 20, 0, 0, 37, CT_COTTON_CANDY, 0, L), // 107 - RVI(52, W, 192, 0, 0, 20, 0, 0, 37, CT_TOFFEE , 0, L), // 108 - RVI(53, W, 190, 0, 0, 21, 0, 0, 27, CT_BUBBLES , 0, L), // 109 - RVI(54, W, 182, 0, 0, 24, 0, 0, 32, CT_COLA , 0, L), // 110 - RVI(55, W, 181, 0, 0, 21, 0, 0, 32, CT_CANDY , 0, L), // 111 - RVI(56, W, 183, 0, 0, 21, 0, 0, 27, CT_TOYS , 0, L), // 112 - RVI(57, W, 196, 0, 0, 18, 0, 0, 29, CT_BATTERIES , 0, L), // 113 - RVI(58, W, 193, 0, 0, 18, 0, 0, 32, CT_FIZZY_DRINKS, 0, L), // 114 - RVI(59, W, 191, 0, 0, 18, 0, 0, 37, CT_PLASTIC , 0, L), // 115 + // image_index max_speed (kph) running_cost_base ai_rank + // | flags | power (hp) | running_cost_class | railtype + // | | base_cost | weight | | capacity | | + // | | | | | | | | | cargo_type | | engclass + // | | | | | | | | | | | | | + RVI( 2, G, 7, 64, 300, 47, 50, S, 0, 0 , 1, R, S), // 0 + RVI(19, G, 8, 80, 600, 65, 65, D, 0, 0 , 4, R, D), // 1 + RVI( 2, G, 10, 72, 400, 85, 90, S, 0, 0 , 7, R, S), // 2 + RVI( 0, G, 15, 96, 900, 130, 130, S, 0, 0 , 19, R, S), // 3 + RVI( 1, G, 19, 112, 1000, 140, 145, S, 0, 0 , 20, R, S), // 4 + RVI(12, G, 16, 120, 1400, 95, 125, D, 0, 0 , 30, R, D), // 5 + RVI(14, G, 20, 152, 2000, 120, 135, D, 0, 0 , 31, R, D), // 6 + RVI( 3, G, 14, 88, 1100, 145, 130, S, 0, 0 , 19, R, S), // 7 + RVI( 0, G, 13, 112, 1000, 131, 120, S, 0, 0 , 20, R, S), // 8 + RVI( 1, G, 19, 128, 1200, 162, 140, S, 0, 0 , 21, R, S), // 9 + RVI( 0, G, 22, 144, 1600, 170, 130, S, 0, 0 , 22, R, S), // 10 + RVI( 8, M, 11, 112, 600/2,32/2, 85/2, D, 38, CT_PASSENGERS , 10, R, D), // 11 + RVI(10, M, 14, 120, 700/2,38/2, 70/2, D, 40, CT_PASSENGERS , 11, R, D), // 12 + RVI( 4, G, 15, 128, 1250, 72, 95, D, 0, 0 , 30, R, D), // 13 + RVI( 5, G, 17, 144, 1750, 101, 120, D, 0, 0 , 31, R, D), // 14 + RVI( 4, G, 18, 160, 2580, 112, 140, D, 0, 0 , 32, R, D), // 15 + RVI(14, G, 23, 96, 4000, 150, 135, D, 0, 0 , 33, R, D), // 16 + RVI(12, G, 16, 112, 2400, 120, 105, D, 0, 0 , 34, R, D), // 17 + RVI(13, G, 30, 112, 6600, 207, 155, D, 0, 0 , 35, R, D), // 18 + RVI(15, G, 18, 104, 1500, 110, 105, D, 0, 0 , 29, R, D), // 19 + RVI(16, M, 35, 160, 3500/2,95/2, 205/2, D, 0, 0 , 45, R, D), // 20 + RVI(18, G, 21, 104, 2200, 120, 145, D, 0, 0 , 32, R, D), // 21 + RVI( 6, M, 20, 200, 4500/2,70/2, 190/2, D, 4, CT_MAIL , 50, R, D), // 22 + RVI(20, G, 26, 160, 3600, 84, 180, E, 0, 0 , 40, C, E), // 23 + RVI(20, G, 30, 176, 5000, 82, 205, E, 0, 0 , 41, C, E), // 24 + RVI(21, M, 40, 240, 7000/2,90/2, 240/2, E, 0, 0 , 51, C, E), // 25 + RVI(23, M, 43, 264, 8000/2,95/2, 250/2, E, 0, 0 , 52, C, E), // 26 + RVI(33, W, 247, 0, 0, 25, 0, 0, 40, CT_PASSENGERS , 0, R, A), // 27 + RVI(35, W, 228, 0, 0, 21, 0, 0, 30, CT_MAIL , 0, R, A), // 28 + RVI(34, W, 176, 0, 0, 18, 0, 0, 30, CT_COAL , 0, R, A), // 29 + RVI(36, W, 200, 0, 0, 24, 0, 0, 30, CT_OIL , 0, R, A), // 30 + RVI(37, W, 192, 0, 0, 20, 0, 0, 25, CT_LIVESTOCK , 0, R, A), // 31 + RVI(38, W, 190, 0, 0, 21, 0, 0, 25, CT_GOODS , 0, R, A), // 32 + RVI(39, W, 182, 0, 0, 19, 0, 0, 30, CT_GRAIN , 0, R, A), // 33 + RVI(40, W, 181, 0, 0, 16, 0, 0, 30, CT_WOOD , 0, R, A), // 34 + RVI(41, W, 179, 0, 0, 19, 0, 0, 30, CT_IRON_ORE , 0, R, A), // 35 + RVI(42, W, 196, 0, 0, 18, 0, 0, 20, CT_STEEL , 0, R, A), // 36 + RVI(43, W, 255, 0, 0, 30, 0, 0, 20, CT_VALUABLES , 0, R, A), // 37 + RVI(44, W, 191, 0, 0, 22, 0, 0, 25, CT_FOOD , 0, R, A), // 38 + RVI(45, W, 196, 0, 0, 18, 0, 0, 20, CT_PAPER , 0, R, A), // 39 + RVI(46, W, 179, 0, 0, 19, 0, 0, 30, CT_COPPER_ORE , 0, R, A), // 40 + RVI(47, W, 199, 0, 0, 25, 0, 0, 25, CT_WATER , 0, R, A), // 41 + RVI(48, W, 182, 0, 0, 18, 0, 0, 25, CT_FRUIT , 0, R, A), // 42 + RVI(49, W, 185, 0, 0, 19, 0, 0, 21, CT_RUBBER , 0, R, A), // 43 + RVI(50, W, 176, 0, 0, 19, 0, 0, 30, CT_SUGAR , 0, R, A), // 44 + RVI(51, W, 178, 0, 0, 20, 0, 0, 30, CT_COTTON_CANDY, 0, R, A), // 45 + RVI(52, W, 192, 0, 0, 20, 0, 0, 30, CT_TOFFEE , 0, R, A), // 46 + RVI(53, W, 190, 0, 0, 21, 0, 0, 20, CT_BUBBLES , 0, R, A), // 47 + RVI(54, W, 182, 0, 0, 24, 0, 0, 25, CT_COLA , 0, R, A), // 48 + RVI(55, W, 181, 0, 0, 21, 0, 0, 25, CT_CANDY , 0, R, A), // 49 + RVI(56, W, 183, 0, 0, 21, 0, 0, 20, CT_TOYS , 0, R, A), // 50 + RVI(57, W, 196, 0, 0, 18, 0, 0, 22, CT_BATTERIES , 0, R, A), // 51 + RVI(58, W, 193, 0, 0, 18, 0, 0, 25, CT_FIZZY_DRINKS, 0, R, A), // 52 + RVI(59, W, 191, 0, 0, 18, 0, 0, 30, CT_PLASTIC , 0, R, A), // 53 + RVI(25, G, 52, 304, 9000, 95, 230, E, 0, 0 , 60, O, N), // 54 + RVI(26, M, 60, 336, 10000/2,85/2, 240/2, E, 25, CT_PASSENGERS , 62, O, N), // 55 + RVI(26, G, 53, 320, 5000, 95, 230, E, 0, 0 , 63, O, N), // 56 + RVI(60, W, 247, 0, 0, 25, 0, 0, 45, CT_PASSENGERS , 0, O, A), // 57 + RVI(62, W, 228, 0, 0, 21, 0, 0, 35, CT_MAIL , 0, O, A), // 58 + RVI(61, W, 176, 0, 0, 18, 0, 0, 35, CT_COAL , 0, O, A), // 59 + RVI(63, W, 200, 0, 0, 24, 0, 0, 35, CT_OIL , 0, O, A), // 60 + RVI(64, W, 192, 0, 0, 20, 0, 0, 30, CT_LIVESTOCK , 0, O, A), // 61 + RVI(65, W, 190, 0, 0, 21, 0, 0, 30, CT_GOODS , 0, O, A), // 62 + RVI(66, W, 182, 0, 0, 19, 0, 0, 35, CT_GRAIN , 0, O, A), // 63 + RVI(67, W, 181, 0, 0, 16, 0, 0, 35, CT_WOOD , 0, O, A), // 64 + RVI(68, W, 179, 0, 0, 19, 0, 0, 35, CT_IRON_ORE , 0, O, A), // 65 + RVI(69, W, 196, 0, 0, 18, 0, 0, 25, CT_STEEL , 0, O, A), // 66 + RVI(70, W, 255, 0, 0, 30, 0, 0, 25, CT_VALUABLES , 0, O, A), // 67 + RVI(71, W, 191, 0, 0, 22, 0, 0, 30, CT_FOOD , 0, O, A), // 68 + RVI(72, W, 196, 0, 0, 18, 0, 0, 25, CT_PAPER , 0, O, A), // 69 + RVI(73, W, 179, 0, 0, 19, 0, 0, 35, CT_COPPER_ORE , 0, O, A), // 70 + RVI(47, W, 199, 0, 0, 25, 0, 0, 30, CT_WATER , 0, O, A), // 71 + RVI(48, W, 182, 0, 0, 18, 0, 0, 30, CT_FRUIT , 0, O, A), // 72 + RVI(49, W, 185, 0, 0, 19, 0, 0, 26, CT_RUBBER , 0, O, A), // 73 + RVI(50, W, 176, 0, 0, 19, 0, 0, 35, CT_SUGAR , 0, O, A), // 74 + RVI(51, W, 178, 0, 0, 20, 0, 0, 35, CT_COTTON_CANDY, 0, O, A), // 75 + RVI(52, W, 192, 0, 0, 20, 0, 0, 35, CT_TOFFEE , 0, O, A), // 76 + RVI(53, W, 190, 0, 0, 21, 0, 0, 25, CT_BUBBLES , 0, O, A), // 77 + RVI(54, W, 182, 0, 0, 24, 0, 0, 30, CT_COLA , 0, O, A), // 78 + RVI(55, W, 181, 0, 0, 21, 0, 0, 30, CT_CANDY , 0, O, A), // 79 + RVI(56, W, 183, 0, 0, 21, 0, 0, 25, CT_TOYS , 0, O, A), // 80 + RVI(57, W, 196, 0, 0, 18, 0, 0, 27, CT_BATTERIES , 0, O, A), // 81 + RVI(58, W, 193, 0, 0, 18, 0, 0, 30, CT_FIZZY_DRINKS, 0, O, A), // 82 + RVI(59, W, 191, 0, 0, 18, 0, 0, 35, CT_PLASTIC , 0, O, A), // 83 + RVI(28, G, 70, 400, 10000, 105, 250, E, 0, 0 , 70, L, V), // 84 + RVI(29, G, 74, 448, 12000, 120, 253, E, 0, 0 , 71, L, V), // 85 + RVI(30, G, 82, 480, 15000, 130, 254, E, 0, 0 , 72, L, V), // 86 + RVI(31, M, 95, 640, 20000/2,150/2,255/2, E, 0, 0 , 73, L, V), // 87 + RVI(28, G, 70, 480, 10000, 120, 250, E, 0, 0 , 74, L, V), // 88 + RVI(60, W, 247, 0, 0, 25, 0, 0, 47, CT_PASSENGERS , 0, L, A), // 89 + RVI(62, W, 228, 0, 0, 21, 0, 0, 37, CT_MAIL , 0, L, A), // 90 + RVI(61, W, 176, 0, 0, 18, 0, 0, 37, CT_COAL , 0, L, A), // 91 + RVI(63, W, 200, 0, 0, 24, 0, 0, 37, CT_OIL , 0, L, A), // 92 + RVI(64, W, 192, 0, 0, 20, 0, 0, 32, CT_LIVESTOCK , 0, L, A), // 93 + RVI(65, W, 190, 0, 0, 21, 0, 0, 32, CT_GOODS , 0, L, A), // 94 + RVI(66, W, 182, 0, 0, 19, 0, 0, 37, CT_GRAIN , 0, L, A), // 95 + RVI(67, W, 181, 0, 0, 16, 0, 0, 37, CT_WOOD , 0, L, A), // 96 + RVI(68, W, 179, 0, 0, 19, 0, 0, 37, CT_IRON_ORE , 0, L, A), // 97 + RVI(69, W, 196, 0, 0, 18, 0, 0, 27, CT_STEEL , 0, L, A), // 98 + RVI(70, W, 255, 0, 0, 30, 0, 0, 27, CT_VALUABLES , 0, L, A), // 99 + RVI(71, W, 191, 0, 0, 22, 0, 0, 32, CT_FOOD , 0, L, A), // 100 + RVI(72, W, 196, 0, 0, 18, 0, 0, 27, CT_PAPER , 0, L, A), // 101 + RVI(73, W, 179, 0, 0, 19, 0, 0, 37, CT_COPPER_ORE , 0, L, A), // 102 + RVI(47, W, 199, 0, 0, 25, 0, 0, 32, CT_WATER , 0, L, A), // 103 + RVI(48, W, 182, 0, 0, 18, 0, 0, 32, CT_FRUIT , 0, L, A), // 104 + RVI(49, W, 185, 0, 0, 19, 0, 0, 28, CT_RUBBER , 0, L, A), // 105 + RVI(50, W, 176, 0, 0, 19, 0, 0, 37, CT_SUGAR , 0, L, A), // 106 + RVI(51, W, 178, 0, 0, 20, 0, 0, 37, CT_COTTON_CANDY, 0, L, A), // 107 + RVI(52, W, 192, 0, 0, 20, 0, 0, 37, CT_TOFFEE , 0, L, A), // 108 + RVI(53, W, 190, 0, 0, 21, 0, 0, 27, CT_BUBBLES , 0, L, A), // 109 + RVI(54, W, 182, 0, 0, 24, 0, 0, 32, CT_COLA , 0, L, A), // 110 + RVI(55, W, 181, 0, 0, 21, 0, 0, 32, CT_CANDY , 0, L, A), // 111 + RVI(56, W, 183, 0, 0, 21, 0, 0, 27, CT_TOYS , 0, L, A), // 112 + RVI(57, W, 196, 0, 0, 18, 0, 0, 29, CT_BATTERIES , 0, L, A), // 113 + RVI(58, W, 193, 0, 0, 18, 0, 0, 32, CT_FIZZY_DRINKS, 0, L, A), // 114 + RVI(59, W, 191, 0, 0, 18, 0, 0, 37, CT_PLASTIC , 0, L, A), // 115 }; #undef L #undef O #undef C #undef R +#undef V +#undef N #undef E #undef D #undef S diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/files.h --- a/src/table/files.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/files.h Wed Jun 13 11:45:14 2007 +0000 @@ -59,7 +59,8 @@ { "autorail.grf", { 0xed, 0x44, 0x7f, 0xbb, 0x19, 0x44, 0x48, 0x4c, 0x07, 0x8a, 0xb1, 0xc1, 0x5c, 0x12, 0x3a, 0x60 } }, { "canalsw.grf", { 0x13, 0x9c, 0x98, 0xcf, 0xb8, 0x7c, 0xd7, 0x1f, 0xca, 0x34, 0xa5, 0x6b, 0x65, 0x31, 0xec, 0x0f } }, { "elrailsw.grf", { 0x4f, 0xf9, 0xac, 0x79, 0x50, 0x28, 0x9b, 0xe2, 0x15, 0x30, 0xa8, 0x1e, 0xd5, 0xfd, 0xe1, 0xda } }, - { "openttd.grf", { 0x10, 0xc1, 0x68, 0x56, 0x9e, 0x1e, 0x0e, 0x85, 0x9d, 0xf8, 0x53, 0x27, 0x48, 0x7e, 0x17, 0x58 } }, + { "openttd.grf", { 0x85, 0x4f, 0xf6, 0xb5, 0xd2, 0xf7, 0xbc, 0x1e, 0xb9, 0xdc, 0x44, 0xef, 0x35, 0x5f, 0x64, 0x9b } }, { "trkfoundw.grf", { 0x12, 0x33, 0x3f, 0xa3, 0xd1, 0x86, 0x8b, 0x04, 0x53, 0x18, 0x9c, 0xee, 0xf9, 0x2d, 0xf5, 0x95 } }, { "roadstops.grf", { 0x8c, 0xd9, 0x45, 0x21, 0x28, 0x82, 0x96, 0x45, 0x33, 0x22, 0x7a, 0xb9, 0x0d, 0xf3, 0x67, 0x4a } }, + { "group.grf", { 0xe8, 0x52, 0x5f, 0x1c, 0x3e, 0xf9, 0x91, 0x9d, 0x0f, 0x70, 0x8c, 0x8a, 0x21, 0xa4, 0xc7, 0x02 } }, }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/industry_land.h --- a/src/table/industry_land.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/industry_land.h Wed Jun 13 11:45:14 2007 +0000 @@ -2,20 +2,30 @@ /** @file industry_land.h */ -struct DrawIndustrySpec1Struct { - byte x; - byte image_1; - byte image_2; - byte image_3; +/** + * This is used to gather some data about animation + * drawing in the industry code + * Image_1-2-3 are in fact only offset in the sprites + * used by the industry. + * To specify an invalid one, either 255 or 0 is used, + * depending of the industry. + */ +struct DrawIndustryAnimationStruct { + int x; ///< coordinate x of the first image offset + byte image_1; ///< image offset 1 + byte image_2; ///< image offset 2 + byte image_3; ///< image offset 3 }; -struct DrawIndustrySpec4Struct { - byte image_1; - byte image_2; - byte image_3; +/** + * Simple structure gathering x,y coordinates for + * industries animations + */ +struct DrawIndustryCoordinates { + byte x; ///< coordinate x of the pair + byte y; ///< coordinate y of the pair }; - /** * Macro to ease the declaration of the array * @param s1 sprite ID of ground sprite @@ -734,9 +744,10 @@ M( 0xf8d, PAL_NONE, 0x12a5 | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE, 0, 0, 16, 16, 50, 1), M( 0xf8d, PAL_NONE, 0x12a5 | (1 << PALETTE_MODIFIER_COLOR), PAL_NONE, 0, 0, 16, 16, 50, 1), }; +#undef M /* this is ONLY used for Sugar Mine*/ -static const DrawIndustrySpec1Struct _draw_industry_spec1[96] = { +static const DrawIndustryAnimationStruct _draw_industry_spec1[96] = { { 8, 4, 0, 0}, { 6, 0, 1, 0}, { 4, 0, 2, 0}, @@ -836,71 +847,77 @@ }; /* this is ONLY used for Sugar Mine*/ -static const byte _drawtile_proc1_x[5] = { - 22, 17, 14, 10, 8 -}; - -/* this is ONLY used for Sugar Mine*/ -static const byte _drawtile_proc1_y[5] = { - 73, 70, 69, 66, 41 +static const DrawIndustryCoordinates _drawtile_proc1[5] = { + {22, 73}, + {17, 70}, + {14, 69}, + {10, 66}, + { 8, 41}, }; -/* this is ONLY used for Toy Factory*/ -static const DrawIndustrySpec4Struct _industry_anim_offs_3[] = { - {255, 255, 0}, - { 0, 255, 0}, - { 1, 255, 0}, - { 2, 255, 0}, - { 3, 255, 0}, - { 4, 255, 0}, - { 5, 255, 0}, - { 6, 255, 0}, - { 7, 255, 0}, - { 8, 255, 0}, - { 9, 255, 0}, - { 10, 255, 0}, - { 11, 255, 0}, - { 12, 255, 0}, - { 13, 255, 0}, - { 14, 255, 0}, - { 15, 255, 0}, - { 16, 255, 0}, - { 17, 255, 0}, - { 18, 255, 0}, - { 18, 255, 1}, - { 18, 255, 2}, - { 18, 255, 4}, - { 18, 255, 6}, - { 18, 255, 8}, - { 18, 255, 11}, - { 18, 255, 14}, - { 18, 255, 17}, - { 18, 255, 20}, - { 18, 255, 24}, - {255, 0, 29}, - {255, 0, 24}, - {255, 0, 20}, - {255, 0, 17}, - {255, 0, 14}, - {255, 0, 11}, - {255, 0, 8}, - {255, 0, 6}, - {255, 0, 4}, - {255, 0, 2}, - {255, 0, 1}, - {255, 1, 0}, - {255, 2, 0}, - {255, 3, 0}, - {255, 4, 0}, - {255, 5, 0}, - {255, 6, 0}, - {255, 7, 0}, - {255, 8, 0}, - {255, 255, 0}, +/** this is ONLY used for Toy Factory. + * 255 means no drawing + * @param img1 offset from base sprite SPR_IT_SUGAR_MINE_SIEVE + * @param img2 offset from base sprite SPR_IT_SUGAR_MINE_CLOUDS + * @param img3 offset from base sprite SPR_IT_SUGAR_MINE_PILE + */ +#define MD( img1, img2, img3) { (50 - img1 * 2), img1, img2, img3 } +static const DrawIndustryAnimationStruct _industry_anim_offs_toys[] = { + MD(255, 255, 0), + MD( 0, 255, 0), + MD( 1, 255, 0), + MD( 2, 255, 0), + MD( 3, 255, 0), + MD( 4, 255, 0), + MD( 5, 255, 0), + MD( 6, 255, 0), + MD( 7, 255, 0), + MD( 8, 255, 0), + MD( 9, 255, 0), + MD( 10, 255, 0), + MD( 11, 255, 0), + MD( 12, 255, 0), + MD( 13, 255, 0), + MD( 14, 255, 0), + MD( 15, 255, 0), + MD( 16, 255, 0), + MD( 17, 255, 0), + MD( 18, 255, 0), + MD( 18, 255, 1), + MD( 18, 255, 2), + MD( 18, 255, 4), + MD( 18, 255, 6), + MD( 18, 255, 8), + MD( 18, 255, 11), + MD( 18, 255, 14), + MD( 18, 255, 17), + MD( 18, 255, 20), + MD( 18, 255, 24), + MD(255, 0, 29), + MD(255, 0, 24), + MD(255, 0, 20), + MD(255, 0, 17), + MD(255, 0, 14), + MD(255, 0, 11), + MD(255, 0, 8), + MD(255, 0, 6), + MD(255, 0, 4), + MD(255, 0, 2), + MD(255, 0, 1), + MD(255, 1, 0), + MD(255, 2, 0), + MD(255, 3, 0), + MD(255, 4, 0), + MD(255, 5, 0), + MD(255, 6, 0), + MD(255, 7, 0), + MD(255, 8, 0), + MD(255, 255, 0), }; +#undef MD /* this is ONLY used for Toffee Quarry*/ -static const byte _industry_anim_offs[] = { +static const byte _industry_anim_offs_toffee[] = { 255, 0, 0, 0, 2, 4, 6, 8, 10, 9, 7, 5, 3, 1, 255, 0, 0, 0, 2, 4, 6, 8, 10, 9, 7, 5, 3, 1, 255, 0, @@ -911,13 +928,22 @@ }; /* this is ONLY used for the Bubble Generator*/ -static const byte _industry_anim_offs_2[] = { +static const byte _industry_anim_offs_bubbles[] = { 68, 69, 71, 74, 77, 80, 83, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, }; -/* those are ONLY used for Power Station*/ -static const byte _coal_plant_sparks_x[] = {11, 11, 14, 13, 18, 15}; -static const byte _coal_plant_sparks_y[] = {23, 11, 6, 3, 1, 0}; +/** + * Movement of the sparks , only used for Power Station + */ +static const DrawIndustryCoordinates _coal_plant_sparks[] = { + {11, 23}, + {11, 11}, + {14, 6}, + {13, 3}, + {18, 1}, + {15, 0}, +}; + diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/sprites.h --- a/src/table/sprites.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/sprites.h Wed Jun 13 11:45:14 2007 +0000 @@ -47,7 +47,7 @@ SPR_ASCII_SPACE_BIG = 450, /* Extra graphic spritenumbers */ - OPENTTD_SPRITES_COUNT = 117, // number of gfx-sprites in openttd.grf + OPENTTD_SPRITES_COUNT = 116, // number of gfx-sprites in openttd.grf SPR_SIGNALS_BASE = 4896, SPR_CANALS_BASE = SPR_SIGNALS_BASE + 486, SPR_SLOPES_BASE = SPR_CANALS_BASE + 70, @@ -62,44 +62,44 @@ SPR_PIN_DOWN = SPR_OPENTTD_BASE + 56, SPR_BOX_EMPTY = SPR_OPENTTD_BASE + 59, SPR_BOX_CHECKED = SPR_OPENTTD_BASE + 60, - SPR_WINDOW_RESIZE = SPR_OPENTTD_BASE + 87, // resize icon - SPR_HOUSE_ICON = SPR_OPENTTD_BASE + 94, + SPR_WINDOW_RESIZE = SPR_OPENTTD_BASE + 86, // resize icon + SPR_HOUSE_ICON = SPR_OPENTTD_BASE + 93, // arrow icons pointing in all 4 directions - SPR_ARROW_DOWN = SPR_OPENTTD_BASE + 88, - SPR_ARROW_UP = SPR_OPENTTD_BASE + 89, - SPR_ARROW_LEFT = SPR_OPENTTD_BASE + 90, - SPR_ARROW_RIGHT = SPR_OPENTTD_BASE + 91, + SPR_ARROW_DOWN = SPR_OPENTTD_BASE + 87, + SPR_ARROW_UP = SPR_OPENTTD_BASE + 88, + SPR_ARROW_LEFT = SPR_OPENTTD_BASE + 89, + SPR_ARROW_RIGHT = SPR_OPENTTD_BASE + 90, SPR_LARGE_SMALL_WINDOW = 682, /* Clone vehicles stuff */ - SPR_CLONE_TRAIN = SPR_OPENTTD_BASE + 92, - SPR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 109, - SPR_CLONE_SHIP = SPR_OPENTTD_BASE + 111, - SPR_CLONE_AIRCRAFT = SPR_OPENTTD_BASE + 113, + SPR_CLONE_TRAIN = SPR_OPENTTD_BASE + 91, + SPR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 108, + SPR_CLONE_SHIP = SPR_OPENTTD_BASE + 110, + SPR_CLONE_AIRCRAFT = SPR_OPENTTD_BASE + 112, - SPR_SELL_TRAIN = SPR_OPENTTD_BASE + 96, - SPR_SELL_ROADVEH = SPR_OPENTTD_BASE + 97, - SPR_SELL_SHIP = SPR_OPENTTD_BASE + 98, - SPR_SELL_AIRCRAFT = SPR_OPENTTD_BASE + 99, - SPR_SELL_ALL_TRAIN = SPR_OPENTTD_BASE + 100, - SPR_SELL_ALL_ROADVEH = SPR_OPENTTD_BASE + 101, - SPR_SELL_ALL_SHIP = SPR_OPENTTD_BASE + 102, - SPR_SELL_ALL_AIRCRAFT = SPR_OPENTTD_BASE + 103, - SPR_REPLACE_TRAIN = SPR_OPENTTD_BASE + 104, - SPR_REPLACE_ROADVEH = SPR_OPENTTD_BASE + 105, - SPR_REPLACE_SHIP = SPR_OPENTTD_BASE + 106, - SPR_REPLACE_AIRCRAFT = SPR_OPENTTD_BASE + 107, - SPR_SELL_CHAIN_TRAIN = SPR_OPENTTD_BASE + 108, + SPR_SELL_TRAIN = SPR_OPENTTD_BASE + 95, + SPR_SELL_ROADVEH = SPR_OPENTTD_BASE + 96, + SPR_SELL_SHIP = SPR_OPENTTD_BASE + 97, + SPR_SELL_AIRCRAFT = SPR_OPENTTD_BASE + 98, + SPR_SELL_ALL_TRAIN = SPR_OPENTTD_BASE + 99, + SPR_SELL_ALL_ROADVEH = SPR_OPENTTD_BASE + 100, + SPR_SELL_ALL_SHIP = SPR_OPENTTD_BASE + 101, + SPR_SELL_ALL_AIRCRAFT = SPR_OPENTTD_BASE + 102, + SPR_REPLACE_TRAIN = SPR_OPENTTD_BASE + 103, + SPR_REPLACE_ROADVEH = SPR_OPENTTD_BASE + 104, + SPR_REPLACE_SHIP = SPR_OPENTTD_BASE + 105, + SPR_REPLACE_AIRCRAFT = SPR_OPENTTD_BASE + 106, + SPR_SELL_CHAIN_TRAIN = SPR_OPENTTD_BASE + 107, - SPR_SHARED_ORDERS_ICON = SPR_OPENTTD_BASE + 115, + SPR_SHARED_ORDERS_ICON = SPR_OPENTTD_BASE + 114, - SPR_WARNING_SIGN = SPR_OPENTTD_BASE + 116, // warning sign (shown if there are any newgrf errors) + SPR_WARNING_SIGN = SPR_OPENTTD_BASE + 115, // warning sign (shown if there are any newgrf errors) /* Network GUI sprites */ SPR_SQUARE = SPR_OPENTTD_BASE + 20, // colored square (used for newgrf compatibility) SPR_LOCK = SPR_OPENTTD_BASE + 19, // lock icon (for password protected servers) - SPR_FLAGS_BASE = SPR_OPENTTD_BASE + 83, // start of the flags block (in same order as enum NetworkLanguage) + SPR_FLAGS_BASE = SPR_OPENTTD_BASE + 82, // start of the flags block (in same order as enum NetworkLanguage) SPR_AIRPORTX_BASE = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // The sprites used for other airport angles SPR_NEWAIRPORT_TARMAC = SPR_AIRPORTX_BASE, @@ -128,6 +128,28 @@ SPR_TRUCK_STOP_DT_X_W = SPR_ROADSTOP_BASE + 6, SPR_TRUCK_STOP_DT_X_E = SPR_ROADSTOP_BASE + 7, + SPR_GROUP_BASE = SPR_ROADSTOP_BASE + 8, // The sprites used for the group interface + SPR_GROUP_CREATE_TRAIN = SPR_GROUP_BASE, + SPR_GROUP_CREATE_ROADVEH = SPR_GROUP_BASE + 1, + SPR_GROUP_CREATE_SHIP = SPR_GROUP_BASE + 2, + SPR_GROUP_CREATE_AIRCRAFT = SPR_GROUP_BASE + 3, + SPR_GROUP_DELETE_TRAIN = SPR_GROUP_BASE + 4, + SPR_GROUP_DELETE_ROADVEH = SPR_GROUP_BASE + 5, + SPR_GROUP_DELETE_SHIP = SPR_GROUP_BASE + 6, + SPR_GROUP_DELETE_AIRCRAFT = SPR_GROUP_BASE + 7, + SPR_GROUP_RENAME_TRAIN = SPR_GROUP_BASE + 8, + SPR_GROUP_RENAME_ROADVEH = SPR_GROUP_BASE + 9, + SPR_GROUP_RENAME_SHIP = SPR_GROUP_BASE + 10, + SPR_GROUP_RENAME_AIRCRAFT = SPR_GROUP_BASE + 11, + SPR_GROUP_REPLACE_ON_TRAIN = SPR_GROUP_BASE + 12, + SPR_GROUP_REPLACE_ON_ROADVEH = SPR_GROUP_BASE + 13, + SPR_GROUP_REPLACE_ON_SHIP = SPR_GROUP_BASE + 14, + SPR_GROUP_REPLACE_ON_AIRCRAFT = SPR_GROUP_BASE + 15, + SPR_GROUP_REPLACE_OFF_TRAIN = SPR_GROUP_BASE + 16, + SPR_GROUP_REPLACE_OFF_ROADVEH = SPR_GROUP_BASE + 17, + SPR_GROUP_REPLACE_OFF_SHIP = SPR_GROUP_BASE + 18, + SPR_GROUP_REPLACE_OFF_AIRCRAFT = SPR_GROUP_BASE + 19, + /* Manager face sprites */ SPR_GRADIENT = 874, // background gradient behind manager face @@ -940,7 +962,6 @@ SPR_IMG_LEVEL_LAND = SPR_OPENTTD_BASE + 61, SPR_IMG_BUILD_CANAL = SPR_OPENTTD_BASE + 58, SPR_IMG_BUILD_LOCK = SPR_CANALS_BASE + 69, - SPR_IMG_PLACE_SIGN = SPR_OPENTTD_BASE + 63, SPR_IMG_PAUSE = 726, SPR_IMG_FASTFORWARD = SPR_OPENTTD_BASE + 54, SPR_IMG_SETTINGS = 751, @@ -1279,10 +1300,10 @@ SPR_CURSOR_TRUCK_STATION = 2726, SPR_CURSOR_ROAD_TUNNEL = 2433, - SPR_CURSOR_CLONE_TRAIN = SPR_OPENTTD_BASE + 93, - SPR_CURSOR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 110, - SPR_CURSOR_CLONE_SHIP = SPR_OPENTTD_BASE + 112, - SPR_CURSOR_CLONE_AIRPLANE = SPR_OPENTTD_BASE + 114, + SPR_CURSOR_CLONE_TRAIN = SPR_OPENTTD_BASE + 92, + SPR_CURSOR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 109, + SPR_CURSOR_CLONE_SHIP = SPR_OPENTTD_BASE + 111, + SPR_CURSOR_CLONE_AIRPLANE = SPR_OPENTTD_BASE + 113, }; /// Animation macro in table/animcursors.h (_animcursors[]) diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/town_land.h --- a/src/table/town_land.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/town_land.h Wed Jun 13 11:45:14 2007 +0000 @@ -1804,7 +1804,7 @@ */ #define MS(mnd, mxd, p, rc, bn, rr, mg, ca1, ca2, ca3, bf, ba, cg1, cg2, cg3) \ {mnd, mxd, p, rc, bn, rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \ - 0, NULL, 0, 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, 0, 2, 0, 0, NULL} + 0, NULL, 0, 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, 0, 2, 0, 0, 0, NULL} /** House specifications from original data */ static const HouseSpec _original_house_specs[] = { /** diff -r 0b2aebc8283e -r 0b8b245a2391 src/table/water_land.h --- a/src/table/water_land.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/table/water_land.h Wed Jun 13 11:45:14 2007 +0000 @@ -47,86 +47,86 @@ }; static const WaterDrawTileStruct _shiplift_display_seq_0[] = { - BEGIN(SPR_CANALS_BASE + 6), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 1 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 1 }, + BEGIN(1), + { 0, 0, 0, 0x10, 1, 0x14, 0 + 1 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 4 + 1 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_1[] = { - BEGIN(SPR_CANALS_BASE + 5), - { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 }, - { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 }, + BEGIN(0), + { 0, 0, 0, 1, 0x10, 0x14, 0 }, + { 0xF, 0, 0, 1, 0x10, 0x14, 4 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_2[] = { - BEGIN(SPR_CANALS_BASE + 7), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 0 + 2 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 4 + 2 }, + BEGIN(2), + { 0, 0, 0, 0x10, 1, 0x14, 0 + 2 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 4 + 2 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_3[] = { - BEGIN(SPR_CANALS_BASE + 8), - { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 0 + 3 }, - { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 4 + 3 }, + BEGIN(3), + { 0, 0, 0, 1, 0x10, 0x14, 0 + 3 }, + { 0xF, 0, 0, 1, 0x10, 0x14, 4 + 3 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_0b[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 1 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 1 }, + { 0, 0, 0, 0x10, 1, 0x14, 8 + 1 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 12 + 1 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_1b[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 }, - { 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 }, + { 0, 0, 0, 0x1, 0x10, 0x14, 8 }, + { 0xF, 0, 0, 0x1, 0x10, 0x14, 12 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_2b[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 8 + 2 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 12 + 2 }, + { 0, 0, 0, 0x10, 1, 0x14, 8 + 2 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 12 + 2 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_3b[] = { BEGIN(0xFDD), - { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 8 + 3 }, - { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 12 + 3 }, + { 0, 0, 0, 1, 0x10, 0x14, 8 + 3 }, + { 0xF, 0, 0, 1, 0x10, 0x14, 12 + 3 }, END(0) }; static const WaterDrawTileStruct _shiplift_display_seq_0t[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 1 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 1 }, + { 0, 0, 0, 0x10, 1, 0x14, 16 + 1 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 20 + 1 }, END(8) }; static const WaterDrawTileStruct _shiplift_display_seq_1t[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 }, - { 0xF, 0, 0, 0x1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 }, + { 0, 0, 0, 0x1, 0x10, 0x14, 16 }, + { 0xF, 0, 0, 0x1, 0x10, 0x14, 20 }, END(8) }; static const WaterDrawTileStruct _shiplift_display_seq_2t[] = { BEGIN(0xFDD), - { 0, 0, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 16 + 2 }, - { 0, 0xF, 0, 0x10, 1, 0x14, SPR_CANALS_BASE + 9 + 20 + 2 }, + { 0, 0, 0, 0x10, 1, 0x14, 16 + 2 }, + { 0, 0xF, 0, 0x10, 1, 0x14, 20 + 2 }, END(8) }; static const WaterDrawTileStruct _shiplift_display_seq_3t[] = { BEGIN(0xFDD), - { 0, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 16 + 3 }, - { 0xF, 0, 0, 1, 0x10, 0x14, SPR_CANALS_BASE + 9 + 20 + 3 }, + { 0, 0, 0, 1, 0x10, 0x14, 16 + 3 }, + { 0xF, 0, 0, 1, 0x10, 0x14, 20 + 3 }, END(8) }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/terraform_gui.cpp --- a/src/terraform_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/terraform_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -104,23 +104,24 @@ TileIndex start_tile = e->we.place.starttile; TileIndex end_tile = e->we.place.tile; - switch (e->we.place.userdata >> 4) { - case GUI_PlaceProc_DemolishArea >> 4: - DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA)); - break; - case GUI_PlaceProc_LevelArea >> 4: - DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO); - break; - case GUI_PlaceProc_RockyArea >> 4: - GenerateRockyArea(end_tile, start_tile); - break; - case GUI_PlaceProc_DesertArea >> 4: - GenerateDesertArea(end_tile, start_tile); - break; - case GUI_PlaceProc_WaterArea >> 4: - DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS)); - break; - default: return false; + switch (e->we.place.select_proc) { + case GUI_PlaceProc_DemolishArea: + DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA)); + break; + case GUI_PlaceProc_LevelArea: + DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO); + break; + case GUI_PlaceProc_RockyArea: + GenerateRockyArea(end_tile, start_tile); + break; + case GUI_PlaceProc_DesertArea: + GenerateDesertArea(end_tile, start_tile); + break; + case GUI_PlaceProc_WaterArea: + DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS)); + break; + default: + return false; } return true; @@ -140,7 +141,7 @@ void PlaceProc_DemolishArea(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DemolishArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_DemolishArea); } static void PlaceProc_RaiseLand(TileIndex tile) @@ -161,7 +162,7 @@ void PlaceProc_LevelLand(TileIndex tile) { - VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_LevelArea); + VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_LevelArea); } static void TerraformClick_Lower(Window *w) @@ -239,12 +240,11 @@ return; case WE_PLACE_DRAG: - VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.userdata & 0xF); + VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method); break; case WE_PLACE_MOUSEUP: - if (e->we.place.pt.x != -1 && - (e->we.place.userdata & 0xF) == VPM_X_AND_Y) { // dragged actions + if (e->we.place.pt.x != -1 && e->we.place.select_method == VPM_X_AND_Y) { GUIPlaceProcDragXY(e); } break; @@ -267,7 +267,7 @@ { WWT_IMGBTN, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC}, { WWT_IMGBTN, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_BUY_LAND, STR_0329_PURCHASE_LAND_FOR_FUTURE}, { WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_PLANTTREES, STR_0185_PLANT_TREES_PLACE_SIGNS}, -{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_PLACE_SIGN, STR_0289_PLACE_SIGN}, +{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_SIGN, STR_0289_PLACE_SIGN}, { WIDGETS_END}, }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/texteff.cpp --- a/src/texteff.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/texteff.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -327,7 +327,7 @@ const TextEffect* te; switch (dpi->zoom) { - case 0: + case ZOOM_LVL_NORMAL: for (te = _text_effect_list; te != endof(_text_effect_list); te++) { if (te->string_id != INVALID_STRING_ID && dpi->left <= te->right && @@ -339,7 +339,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: for (te = _text_effect_list; te != endof(_text_effect_list); te++) { if (te->string_id != INVALID_STRING_ID && dpi->left <= te->right * 2 - te->x && @@ -350,6 +350,13 @@ } } break; + + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/thread.cpp --- a/src/thread.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/thread.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -7,7 +7,7 @@ #include #include "helpers.hpp" -#if defined(__AMIGA__) || defined(__MORPHOS__) || defined(PSP) || defined(NO_THREADS) +#if defined(__AMIGA__) || defined(PSP) || defined(NO_THREADS) OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg) { return NULL; } void *OTTDJoinThread(OTTDThread *t) { return NULL; } void OTTDExitThread() { NOT_REACHED(); }; @@ -65,7 +65,7 @@ _endthread(); } -#elif defined(UNIX) +#elif defined(UNIX) && !defined(MORPHOS) #include @@ -157,4 +157,157 @@ { ExitThread(0); } + + +#elif defined(MORPHOS) + +#include +#include +#include + +#include +#include + +#include + +/* NOTE: this code heavily depends on latest libnix updates. So make + * sure you link with new stuff which supports semaphore locking of + * the IO resources, else it will just go foobar. */ + +struct OTTDThreadStartupMessage { + struct Message msg; ///< standard exec.library message (MUST be the first thing in the message struct!) + OTTDThreadFunc func; ///< function the thread will execute + void *arg; ///< functions arguments for the thread function + void *ret; ///< return value of the thread function + jmp_buf jumpstore; ///< storage for the setjump state +}; + +struct OTTDThread { + struct MsgPort *replyport; + struct OTTDThreadStartupMessage msg; +}; + + +/** + * Default OpenTTD STDIO/ERR debug output is not very useful for this, so we + * utilize serial/ramdebug instead. + */ +#ifndef NO_DEBUG_MESSAGES +void KPutStr(CONST_STRPTR format) +{ + RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL); +} +#else +#define KPutStr(x) #endif + +static void Proxy(void) +{ + struct Task *child = FindTask(NULL); + struct OTTDThreadStartupMessage *msg; + + /* Make sure, we don't block the parent. */ + SetTaskPri(child, -5); + + KPutStr("[Child] Progressing...\n"); + + if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { + /* Make use of setjmp() here, so this point can be reached again from inside + * OTTDExitThread() which can be called from anythere inside msg->func. + * It's a bit ugly and in worst case it leaks some memory. */ + if (setjmp(msg->jumpstore) == 0) { + msg->ret = msg->func(msg->arg); + } else { + KPutStr("[Child] Returned to main()\n"); + } + } + + /* Quit the child, exec.library will reply the startup msg internally. */ + KPutStr("[Child] Done.\n"); +} + +OTTDThread* OTTDCreateThread(OTTDThreadFunc function, void *arg) +{ + OTTDThread *t; + struct Task *parent; + + KPutStr("[OpenTTD] Create thread...\n"); + + t = (struct OTTDThread *)AllocVecTaskPooled(sizeof(struct OTTDThread)); + if (t == NULL) return NULL; + + parent = FindTask(NULL); + + /* Make sure main thread runs with sane priority */ + SetTaskPri(parent, 0); + + /* Things we'll pass down to the child by utilizing NP_StartupMsg */ + t->msg.func = function; + t->msg.arg = arg; + t->msg.ret = NULL; + + t->replyport = CreateMsgPort(); + + if (t->replyport != NULL) { + struct Process *child; + + t->msg.msg.mn_Node.ln_Type = NT_MESSAGE; + t->msg.msg.mn_ReplyPort = t->replyport; + t->msg.msg.mn_Length = sizeof(struct OTTDThreadStartupMessage); + + child = CreateNewProcTags( + NP_CodeType, CODETYPE_PPC, + NP_Entry, Proxy, + NP_StartupMsg, (ULONG)&t->msg, + NP_Priority, 5UL, + NP_Name, (ULONG)"OpenTTD Thread", + NP_PPCStackSize, 131072UL, + TAG_DONE); + + if (child != NULL) { + KPutStr("[OpenTTD] Child process launched.\n"); + return t; + } + DeleteMsgPort(t->replyport); + } + FreeVecTaskPooled(t); + + return NULL; +} + +void* OTTDJoinThread(OTTDThread *t) +{ + struct OTTDThreadStartupMessage *reply; + void *ret; + + KPutStr("[OpenTTD] Join threads...\n"); + + if (t == NULL) return NULL; + + KPutStr("[OpenTTD] Wait for child to quit...\n"); + WaitPort(t->replyport); + + reply = (struct OTTDThreadStartupMessage *)GetMsg(t->replyport); + ret = reply->ret; + + DeleteMsgPort(t->replyport); + FreeVecTaskPooled(t); + + return ret; +} + +void OTTDExitThread() +{ + struct OTTDThreadStartupMessage *msg; + + KPutStr("[Child] Aborting...\n"); + + if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { + KPutStr("[Child] Jumping back...\n"); + longjmp(msg->jumpstore, 0xBEAFCAFE); + } + + NOT_REACHED(); +} + +#endif diff -r 0b2aebc8283e -r 0b8b245a2391 src/town.cpp --- a/src/town.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/town.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -32,7 +32,7 @@ /* We do have a tile that directly belongs to a town */ if (IsTileType(tile, MP_HOUSE) || (IsTileType(tile, MP_STREET) && - (IsLevelCrossing(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile)) == OWNER_TOWN)) { + (GetTileOwner(tile)) == OWNER_TOWN)) { /** @todo check this for level crossings, trams, etc */ t = GetTownByTile(tile); group = t->GetRadiusGroup(tile, true) + 1; DEBUG(eco, 6, "Tile 0x%x belongs to town at 0x%x, level %d", tile, t->xy, group); diff -r 0b2aebc8283e -r 0b8b245a2391 src/town.h --- a/src/town.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/town.h Wed Jun 13 11:45:14 2007 +0000 @@ -234,10 +234,10 @@ CargoID accepts_cargo[3]; ///< 3 input cargo slots BuildingFlags building_flags; ///< some flags that describe the house (size, stadium etc...) HouseZones building_availability; ///< where can it be built (climates, zones) - bool enabled; ///< the house is still avaible (by default, true.newgrf can disable it, though) + bool enabled; ///< the house is available to build (true by default, but can be disabled by newgrf) /* NewHouses properties */ - HouseID substitute_id; ///< which house this one is based on + HouseID substitute_id; ///< which original house this one is based on struct SpriteGroup *spritegroup; ///< pointer to the different sprites of the house HouseID override; ///< which house this one replaces uint16 callback_mask; ///< House callback flags @@ -248,6 +248,7 @@ byte animation_frames; ///< number of animation frames byte animation_speed; ///< amount of time between each of those frames byte processing_time; ///< Periodic refresh multiplier + byte minimum_life; ///< The minimum number of years this house will survive before the town rebuilds it /* grf file related properties*/ uint8 local_id; ///< id defined by the grf file for this house diff -r 0b2aebc8283e -r 0b8b245a2391 src/town_cmd.cpp --- a/src/town_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/town_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -39,6 +39,7 @@ #include "newgrf.h" #include "newgrf_callbacks.h" #include "newgrf_house.h" +#include "newgrf_commons.h" /** * Called if a new block is added to the town-pool @@ -55,6 +56,11 @@ /* Initialize the town-pool */ DEFINE_OLD_POOL(Town, Town, TownPoolNewBlock, NULL) +/** + * Removes a specific town as well as all industries + * under its "juridiction" + * @param t Town to remove + */ void DestroyTown(Town *t) { Industry *i; @@ -121,6 +127,11 @@ return variant; } +/** + * House Tile drawing handler. + * Part of the tile loop process + * @param ti TileInfo of the tile to draw + */ static void DrawTile_Town(TileInfo *ti) { const DrawBuildingsTileStruct *dcts; @@ -188,6 +199,12 @@ return SLOPE_FLAT; } +/** + * Animate a tile for a town + * Only certain houses can be animated + * The newhouses animation superseeds regular ones + * @param tile TileIndex of the house to animate + */ static void AnimateTile_Town(TileIndex tile) { int pos, dest; @@ -234,6 +251,12 @@ static void UpdateTownRadius(Town *t); +/** + * Determines if a town is close to a tile + * @param tile TileIndex of the tile to query + * @param dist maximum distance to be accepted + * @returns true if the tile correspond to the distance criteria + */ static bool IsCloseToTown(TileIndex tile, uint dist) { const Town* t; @@ -244,6 +267,10 @@ return false; } +/** + * Marks the town sign as needing a repaint + * @param t Town requesting repaint + */ static void MarkTownSignDirty(Town *t) { MarkAllViewportsDirty( @@ -254,6 +281,11 @@ ); } +/** + * Resize the sign(label) of the town after changes in + * population (creation or growth or else) + * @param t Town to update + */ void UpdateTownVirtCoord(Town *t) { Point pt; @@ -267,6 +299,11 @@ MarkTownSignDirty(t); } +/** + * Change the towns population + * @param t Town which polulation has changed + * @param mod polulation change (can be positive or negative) + */ static void ChangePopulation(Town *t, int mod) { t->population += mod; @@ -276,6 +313,11 @@ if (_town_sort_order & 2) _town_sort_dirty = true; } +/** + * Determines the world population + * Basically, count population of all towns, one by one + * @return uint32 the calculated population of the world + */ uint32 GetWorldPopulation() { uint32 pop; @@ -286,17 +328,24 @@ return pop; } +/** + * Helper function for house completion stages progression + * @param tile TileIndex of the house (or parts of it) to "grow" + */ static void MakeSingleHouseBigger(TileIndex tile) { assert(IsTileType(tile, MP_HOUSE)); + /* means it is completed, get out. */ if (LiftHasDestination(tile)) return; + /* progress in construction stages */ IncHouseConstructionTick(tile); if (GetHouseConstructionTick(tile) != 0) return; + /* Check and/or */ if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_CONSTRUCTION_STATE_CHANGE)) { - uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, GetHouseType(tile), GetTownByTile(tile), tile); + uint16 callback_res = GetHouseCallback(CBID_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res); } @@ -308,6 +357,9 @@ MarkTileDirtyByTile(tile); } +/** Make the house advances in its construction stages until completion + * @param tile TileIndex of house + */ static void MakeTownHouseBigger(TileIndex tile) { uint flags = GetHouseSpecs(GetHouseType(tile))->building_flags; @@ -317,6 +369,10 @@ if (flags & BUILDING_HAS_4_TILES) MakeSingleHouseBigger(TILE_ADDXY(tile, 1, 1)); } +/** + * Periodic tic handler for houses and town + * @param tile been asked to do its stuff + */ static void TileLoop_Town(TileIndex tile) { Town *t; @@ -335,29 +391,69 @@ } /* If the lift has a destination, it is already an animated tile. */ - if ((hs->building_flags & BUILDING_IS_ANIMATED) && house_id < NEW_HOUSE_OFFSET && !LiftHasDestination(tile) && CHANCE16(1, 2)) AddAnimatedTile(tile); + if ((hs->building_flags & BUILDING_IS_ANIMATED) && + house_id < NEW_HOUSE_OFFSET && + !LiftHasDestination(tile) && + CHANCE16(1, 2)) + AddAnimatedTile(tile); t = GetTownByTile(tile); r = Random(); - if (GB(r, 0, 8) < (t->GetActivity() * _eco->GetActivity() * 8)) { - int amt = hs->population / 8 + 1; - t->new_max_pass += amt; - int moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt); - t->new_act_pass += moved; - } - - if (GB(r, 8, 8) < (t->GetActivity() * _eco->GetActivity() * 8)) { - int amt = hs->mail_generation / 8 + 1; - t->new_max_pass += amt; - int moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt); - t->new_act_pass += moved; + if (HASBIT(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) { + /** @todo Implement economic activity here as well */ + for (uint i = 0; i < 256; i++) { + uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile); + + if (callback == CALLBACK_FAILED) break; + if (callback == 0x20FF) break; + + CargoID cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grffile); + if (cargo == CT_INVALID) continue; + + uint amt = GB(callback, 0, 8); + uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt); + + const CargoSpec *cs = GetCargo(cargo); + switch (cs->town_effect) { + case TE_PASSENGERS: + t->new_max_pass += amt; + t->new_act_pass += moved; + break; + + case TE_MAIL: + t->new_max_mail += amt; + t->new_act_mail += moved; + break; + + default: + break; + } + } + } else { + if (GB(r, 0, 8) < (t->GetActivity() * _eco->GetActivity() * 8)) { + int amt = hs->population / 8 + 1; + t->new_max_pass += amt; + int moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt); + t->new_act_pass += moved; + } + + if (GB(r, 8, 8) < (t->GetActivity() * _eco->GetActivity() * 8)) { + int amt = hs->mail_generation / 8 + 1; + t->new_max_pass += amt; + int moved = MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt); + t->new_act_pass += moved; + } } _current_player = OWNER_TOWN; - if (hs->building_flags & BUILDING_HAS_1_TILE && HASBIT(t->flags12, TOWN_IS_FUNDED) && CanDeleteHouse(tile) && --t->time_until_rebuild == 0) { + if (hs->building_flags & BUILDING_HAS_1_TILE && + HASBIT(t->flags12, TOWN_IS_FUNDED) && + CanDeleteHouse(tile) && + max(_cur_year - GetHouseConstructionYear(tile), 0) >= hs->minimum_life && + --t->time_until_rebuild == 0) { t->time_until_rebuild = GB(r, 16, 8) + 192; ClearTownHouse(t, tile); @@ -369,6 +465,10 @@ _current_player = OWNER_NONE; } +/** + * Unused handler + * @param tile unused + */ static void ClickTile_Town(TileIndex tile) { /* not used */ @@ -408,8 +508,44 @@ static void GetAcceptedCargo_Town(TileIndex tile, AcceptedCargo ac) { HouseSpec *hs = GetHouseSpecs(GetHouseType(tile)); - - for (uint8 i = 0; i < 3; i++) ac[hs->accepts_cargo[i]] = hs->cargo_acceptance[i]; + CargoID accepts[3]; + + /* Set the initial accepted cargo types */ + for (uint8 i = 0; i < lengthof(accepts); i++) { + accepts[i] = hs->accepts_cargo[i]; + } + + /* Check for custom accepted cargo types */ + if (HASBIT(hs->callback_mask, CBM_HOUSE_ACCEPT_CARGO)) { + uint16 callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); + if (callback != CALLBACK_FAILED) { + /* Replace accepted cargo types with translated values from callback */ + accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grffile); + accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grffile); + accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grffile); + } + } + + /* Check for custom cargo acceptance */ + if (HASBIT(hs->callback_mask, CBM_CARGO_ACCEPTANCE)) { + uint16 callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); + if (callback != CALLBACK_FAILED) { + if (accepts[0] != CT_INVALID) ac[accepts[0]] = GB(callback, 0, 4); + if (accepts[1] != CT_INVALID) ac[accepts[1]] = GB(callback, 4, 4); + if (_opt.landscape != LT_TEMPERATE && HASBIT(callback, 12)) { + /* The 'S' bit indicates food instead of goods */ + ac[CT_FOOD] = GB(callback, 8, 4); + } else { + if (accepts[2] != CT_INVALID) ac[accepts[2]] = GB(callback, 8, 4); + } + return; + } + } + + /* No custom acceptance, so fill in with the default values */ + for (uint8 i = 0; i < lengthof(accepts); i++) { + if (accepts[i] != CT_INVALID) ac[accepts[i]] = hs->cargo_acceptance[i]; + } } static void GetTileDesc_Town(TileIndex tile, TileDesc *td) @@ -448,6 +584,14 @@ { 0, 1} }; +/** + * Distance multiplyer + * Defines the possible distances between 2 road tiles + */ +enum RoadBlockTitleDistance { + RB_TILE_DIST1 = 1, ///< 1 tile between + RB_TILE_DIST2, ///< 2 tiles between +}; static bool GrowTown(Town *t); @@ -488,7 +632,7 @@ static RoadBits GetTownRoadMask(TileIndex tile) { - TrackBits b = GetAnyRoadTrackBits(tile); + TrackBits b = GetAnyRoadTrackBits(tile, ROADTYPE_ROAD); RoadBits r = ROAD_NONE; if (b & TRACK_BIT_X) r |= ROAD_X; @@ -500,6 +644,23 @@ return r; } +/** + * Check if a neighboring tile has a road + * + * @param tile curent tile + * @param dir target direction + * @param dist_multi distance multiplyer + * @return true if one of the neighboring tiles at the + * given distance is a road tile else + */ +static bool NeighborIsRoadTile(TileIndex tile, int dir, RoadBlockTitleDistance dist_multi) +{ + return (HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * ToTileIndexDiff(_roadblock_tileadd[dir + 1]))), dir ^ 2) || + HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * ToTileIndexDiff(_roadblock_tileadd[dir + 3]))), dir ^ 2) || + HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * (ToTileIndexDiff(_roadblock_tileadd[dir + 1]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2])))), dir) || + HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * (ToTileIndexDiff(_roadblock_tileadd[dir + 3]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2])))), dir)); +} + static bool IsRoadAllowedHere(TileIndex tile, int dir) { Slope k; @@ -511,7 +672,7 @@ for (;;) { /* Check if there already is a road at this point? */ - if (GetAnyRoadTrackBits(tile) == 0) { + if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) == 0) { /* No, try to build one in the direction. * if that fails clear the land, and if that fails exit. * This is to make sure that we can build a road here later. */ @@ -523,16 +684,17 @@ slope = GetTileSlope(tile, NULL); if (slope == SLOPE_FLAT) { no_slope: - /* Tile has no slope - * Disallow the road if any neighboring tile has a road. */ - if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 1]))), dir ^ 2) || - HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 3]))), dir ^ 2) || - HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 1]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2]))), dir) || - HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 3]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2]))), dir)) - return false; - - /* Otherwise allow */ - return true; + /* Tile has no slope */ + switch (_patches.town_layout) { + default: NOT_REACHED(); + + case TL_ORIGINAL: /* Disallow the road if any neighboring tile has a road (distance: 1) */ + return !NeighborIsRoadTile(tile, dir, RB_TILE_DIST1); + + case TL_BETTER_ROADS: /* Disallow the road if any neighboring tile has a road (distance: 1 and 2). */ + return !(NeighborIsRoadTile(tile, dir, RB_TILE_DIST1) || + NeighborIsRoadTile(tile, dir, RB_TILE_DIST2)); + } } /* If the tile is not a slope in the right direction, then @@ -591,6 +753,127 @@ } } +/** + * Generate the RoadBits of a grid tile + * + * @param t current town + * @param tile tile in reference to the town + * @return the RoadBit of the current tile regarding + * the selected town layout + */ +static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile) +{ + /* align the grid to the downtown */ + TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); ///< Vector from downtown to the tile + + /* lx, ly description: + * @li lx and ly are true if the tile is a crossing tile. + * @li lx xor ly are true if the tile is a straight road tile. + * @li lx and ly are false if the tile is a house tile. + */ + bool lx, ly; + + switch (_patches.town_layout) { + default: NOT_REACHED(); + + case TL_2X2_GRID: + lx = ((grid_pos.x % 3) == 0); + ly = ((grid_pos.y % 3) == 0); + break; + + case TL_3X3_GRID: + lx = ((grid_pos.x % 4) == 0); + ly = ((grid_pos.y % 4) == 0); + break; + } + + /* generate the basic grid structure */ + if (!lx && !ly) { ///< It is a house tile + return ROAD_NONE; + } else if (lx && !ly) { ///< It is a Y-dir road tile + return ROAD_Y; + } else if (!lx && ly) { ///< It is a X-dir road tile + return ROAD_X; + } else { ///< It is a crossing tile + /* Presets for junctions on slopes + * not nice :( */ + switch (GetTileSlope(tile, NULL)) { + case SLOPE_W: + return ROAD_NW | ROAD_SW; + case SLOPE_S: + return ROAD_SE | ROAD_SW; + case SLOPE_SW: + return ROAD_Y | ROAD_SW; + case SLOPE_E: + return ROAD_NE | ROAD_SE; + case SLOPE_SE: + return ROAD_X | ROAD_SE; + case SLOPE_N: + return ROAD_NW | ROAD_NE; + case SLOPE_NW: + return ROAD_X | ROAD_NW; + case SLOPE_NE: + return ROAD_Y | ROAD_NE; + case SLOPE_STEEP_W: + case SLOPE_STEEP_N: + return ROAD_X; + case SLOPE_STEEP_S: + case SLOPE_STEEP_E: + return ROAD_Y; + default: + return ROAD_ALL; + } + } +} + +/** + * Check there are enougth neighbor house tiles next to the current tile + * + * @param tile current tile + * @return true if there are more than 2 house tiles next + * to the current one + */ +static bool NeighborsAreHouseTiles(TileIndex tile) +{ + uint counter = 0; ///< counts the house neighbor tiles + + /* We can't look further than that. */ + if (TileX(tile) < 1 || TileY(tile) < 1) { + return false; + } + + /* Check the tiles E,N,W and S of the current tile. */ + for (uint i = 0; i < 4; i++) { + if (IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])), MP_HOUSE)) { + counter++; + } + + /* If there are enougth neighbor's stop it here */ + if (counter >= 3) { + return true; + } + } + return false; +} + +/** + * Grows the given town. + * There are at the moment 3 possible way's for + * the town expansion: + * @li Generate a random tile and check if there is a road allowed + * @li TL_ORIGINAL + * @li TL_BETTER_ROADS + * @li Check if the town geometry allows a road and which one + * @li TL_2X2_GRID + * @li TL_3X3_GRID + * @li Forbid roads, only build houses + * @li TL_NO_ROADS + * + * @param tile_ptr current tile + * @param mask current tiles RoadBits + * @param block road block + * @param t1 current town + */ static void GrowTownInTile(TileIndex* tile_ptr, RoadBits mask, int block, Town* t1) { RoadBits rcmd; @@ -613,39 +896,81 @@ LevelTownLand(tile); /* Is a road allowed here? */ - if (!IsRoadAllowedHere(tile, block)) return; - - /* Randomize new road block numbers */ - a = block; - b = block ^ 2; - if (CHANCE16(1, 4)) { - do { - a = GB(Random(), 0, 2); - } while (a == b); + switch (_patches.town_layout) { + default: NOT_REACHED(); + + case TL_NO_ROADS: /* Disallow Roads */ + return; + + case TL_3X3_GRID: + case TL_2X2_GRID: + rcmd = GetTownRoadGridElement(t1, tile); + if (rcmd == ROAD_NONE) { + return; + } + break; + + case TL_BETTER_ROADS: + case TL_ORIGINAL: + if (!IsRoadAllowedHere(tile, block)) { + return; + } + + /* Randomize new road block numbers */ + a = block; + b = block ^ 2; + if (CHANCE16(1, 4)) { + do { + a = GB(Random(), 0, 2); + } while (a == b); + } + + if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { + /* A road is not allowed to continue the randomized road, + * return if the road we're trying to build is curved. */ + if (a != (b ^ 2)) { + return; + } + + /* Return if neither side of the new road is a house */ + if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && + !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) { + return; + } + + /* That means that the road is only allowed if there is a house + * at any side of the new road. */ + } + + rcmd = (RoadBits)((1 << a) + (1 << b)); + break; } - if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { - /* A road is not allowed to continue the randomized road, - * return if the road we're trying to build is curved. */ - if (a != (b ^ 2)) return; - - /* Return if neither side of the new road is a house */ - if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && - !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) - return; - - /* That means that the road is only allowed if there is a house - * at any side of the new road. */ - } - rcmd = (RoadBits)((1 << a) + (1 << b)); - } else if (block < 5 && !HASBIT(mask, block ^ 2)) { /* Continue building on a partial road. * Always OK. */ _grow_town_result = 0; - rcmd = (RoadBits)(1 << (block ^ 2)); + + switch (_patches.town_layout) { + default: NOT_REACHED(); + + case TL_NO_ROADS: /* Disallow Roads */ + return; + + case TL_3X3_GRID: + case TL_2X2_GRID: + rcmd = GetTownRoadGridElement(t1, tile); + break; + + case TL_BETTER_ROADS: + case TL_ORIGINAL: + rcmd = (RoadBits)(1 << (block ^ 2)); + break; + } } else { int i; + bool allow_house = false; + TileIndex tmptile2; /* Reached a tunnel/bridge? Then continue at the other side of it. */ if (IsTileType(tile, MP_TUNNELBRIDGE)) { @@ -668,17 +993,51 @@ /* Don't do it if it reaches to water. */ if (IsClearWaterTile(tmptile)) return; - /* Build a house at the edge. 60% chance or - * always ok if no road allowed. */ - if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) { - /* But not if there already is a house there. */ + switch (_patches.town_layout) { + default: NOT_REACHED(); + + case TL_NO_ROADS: + allow_house = true; + break; + + case TL_3X3_GRID: /* Use 2x2 grid afterwards! */ + /* Fill gap if house has enougth neighbors */ + tmptile2 = TILE_ADD(tmptile, ToTileIndexDiff(_roadblock_tileadd[i])); + if (NeighborsAreHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) { + _grow_town_result = -1; + } + + case TL_2X2_GRID: + rcmd = GetTownRoadGridElement(t1, tmptile); + allow_house = (rcmd == ROAD_NONE); + break; + + case TL_BETTER_ROADS: /* Use original afterwards! */ + /* Fill gap if house has enougth neighbors */ + tmptile2 = TILE_ADD(tmptile, ToTileIndexDiff(_roadblock_tileadd[i])); + if (NeighborsAreHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) { + _grow_town_result = -1; + } + + case TL_ORIGINAL: + /* Allow a house at the edge. 60% chance or + * always ok if no road allowed. */ + allow_house = (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)); + break; + } + + + if (allow_house) { + /* Build a house, but not if there already is a house there. */ if (!IsTileType(tmptile, MP_HOUSE)) { /* Level the land if possible */ LevelTownLand(tmptile); /* And build a house. * Set result to -1 if we managed to build it. */ - if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1; + if (BuildTownHouse(t1, tmptile)) { + _grow_town_result = -1; + } } return; } @@ -706,6 +1065,12 @@ return; } + /* Check if the bridge is in the right direction */ + if ((rcmd == ROAD_X && (i == DIAGDIR_NW || i == DIAGDIR_SE)) || + (rcmd == ROAD_Y && (i == DIAGDIR_NE || i == DIAGDIR_SW))) { + goto build_road_and_exit; + } + tmptile = tile; /* Now it contains the direction of the slope */ @@ -748,8 +1113,23 @@ TILE_ASSERT(tile); - /* Number of times to search. */ - _grow_town_result = 10 + t->num_houses * 4 / 9; + /* Number of times to search. + * Better roads, 2X2 and 3X3 grid grow quite fast so we give + * them a little handicap. */ + switch (_patches.town_layout) { + case TL_BETTER_ROADS: + _grow_town_result = 10 + t->num_houses * 2 / 9; + break; + + case TL_3X3_GRID: + case TL_2X2_GRID: + _grow_town_result = 10 + t->num_houses * 1 / 9; + break; + + default: + _grow_town_result = 10 + t->num_houses * 4 / 9; + break; + } do { /* Get a bitmask of the road blocks on a tile */ @@ -823,6 +1203,13 @@ { 0, 0} }; + /* Let the town be a ghost town + * The player wanted it in such a way. Thus there he has it. ;) + * Never reached in editor mode. */ + if (_patches.town_layout == TL_NO_ROADS && _generating_world) { + return false; + } + /* Current player is a town */ old_player = _current_player; _current_player = OWNER_TOWN; @@ -830,7 +1217,7 @@ /* Find a road that we can base the construction on. */ tile = t->xy; for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { - if (GetAnyRoadTrackBits(tile) != 0) { + if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) != 0) { int r = GrowTownAtRoad(t, tile); _current_player = old_player; return r != 0; @@ -844,7 +1231,7 @@ for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) { - if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) { + if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR))) { DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); _current_player = old_player; return true; @@ -1160,7 +1547,7 @@ return NULL; } -static const byte _num_initial_towns[3] = {11, 23, 46}; +static const byte _num_initial_towns[4] = {5, 11, 23, 46}; bool GenerateTowns() { @@ -1304,7 +1691,7 @@ if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue; if (HASBIT(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { - uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, house, t, tile); + uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); if (callback_res != CALLBACK_FAILED && callback_res == 0) continue; } } @@ -1818,7 +2205,7 @@ { if (IsTileType(tile, MP_HOUSE) || ( IsTileType(tile, MP_STREET) && - (IsLevelCrossing(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile)) == OWNER_TOWN + GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN )) { return GetTownByTile(tile); } else { @@ -2014,19 +2401,19 @@ /* Save and load the mapping between the house id on the map, and the grf file * it came from. */ static const SaveLoad _house_id_mapping_desc[] = { - SLE_VAR(HouseIDMapping, grfid, SLE_UINT32), - SLE_VAR(HouseIDMapping, house_id, SLE_UINT8), - SLE_VAR(HouseIDMapping, substitute_id, SLE_UINT8), + SLE_VAR(EntityIDMapping, grfid, SLE_UINT32), + SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8), + SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8), SLE_END() }; static void Save_HOUSEIDS() { - uint i; - - for (i = 0; i != lengthof(_house_id_mapping); i++) { + uint j = _house_mngr.GetMaxMapping(); + + for (uint i = 0; i < j; i++) { SlSetArrayIndex(i); - SlObject(&_house_id_mapping[i], _house_id_mapping_desc); + SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc); } } @@ -2034,11 +2421,12 @@ { int index; - ResetHouseIDMapping(); + _house_mngr.ResetMapping(); + uint max_id = _house_mngr.GetMaxMapping(); while ((index = SlIterateArray()) != -1) { - if ((uint)index >= lengthof(_house_id_mapping)) break; - SlObject(&_house_id_mapping[index], _house_id_mapping_desc); + if ((uint)index >= max_id) break; + SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/town_gui.cpp --- a/src/town_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/town_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -357,7 +357,7 @@ if (w != NULL) { w->flags4 |= WF_DISABLE_VP_SCROLL; - AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetTown(town)->xy, 1); + AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetTown(town)->xy, ZOOM_LVL_TOWN); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/train.h --- a/src/train.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/train.h Wed Jun 13 11:45:14 2007 +0000 @@ -228,4 +228,27 @@ byte FreightWagonMult(CargoID cargo); +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Train(); + * + * As side-effect the vehicle type is set correctly. + */ +struct Train : public Vehicle { + /** Initializes the Vehicle to a train */ + Train() { this->type = VEH_TRAIN; } + + /** We want to 'destruct' the right class. */ + virtual ~Train() {} + + const char *GetTypeString() const { return "train"; } + void MarkDirty(); + void UpdateDeltaXY(Direction direction); + ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; } + WindowClass GetVehicleListWindowClass() const { return WC_TRAINS_LIST; } + void PlayLeaveStationSound() const; +}; + #endif /* TRAIN_H */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/train_cmd.cpp --- a/src/train_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/train_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -37,6 +37,7 @@ #include "yapf/yapf.h" #include "date.h" #include "cargotype.h" +#include "group.h" static bool TrainCheckIfLineEnds(Vehicle *v); static void TrainController(Vehicle *v, bool update_image); @@ -114,7 +115,7 @@ /* Vehicle weight is not added for articulated parts. */ if (!IsArticulatedPart(u)) { /* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */ - vweight += RailVehInfo(u->engine_type)->weight; + vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight); /* powered wagons have extra weight added */ if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON)) @@ -166,6 +167,9 @@ if (IsTrainEngine(u)) first_engine = u->engine_type; + /* Cache wagon override sprite group. NULL is returned if there is none */ + u->u.rail.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->u.rail.first_engine); + if (rvi_u->visual_effect != 0) { u->u.rail.cached_vis_effect = rvi_u->visual_effect; } else { @@ -190,7 +194,7 @@ } if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && - UsesWagonOverride(u) && (u->u.rail.cached_vis_effect < 0x40)) { + UsesWagonOverride(u) && !HASBIT(u->u.rail.cached_vis_effect, 7)) { /* wagon is powered */ SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status } else { @@ -217,6 +221,11 @@ } } + if (u->cargo_type == rvi_u->cargo_type && u->cargo_subtype == 0) { + /* Set cargo capacity if we've not been refitted */ + u->cargo_cap = GetVehicleProperty(u, 0x14, rvi_u->capacity); + } + /* check the vehicle length (callback) */ uint16 veh_len = CALLBACK_FAILED; if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { @@ -535,7 +544,6 @@ u->x_pos = v->x_pos; u->y_pos = v->y_pos; u->z_pos = v->z_pos; - u->z_height = v->z_height; u->u.rail.track = v->u.rail.track; u->u.rail.railtype = v->u.rail.railtype; u->build_year = v->build_year; @@ -552,7 +560,7 @@ u->max_age = 0; u->engine_type = engine_type; u->value = 0; - u->type = VEH_TRAIN; + u = new (u) Train(); u->subtype = 0; SetArticulatedPart(u); u->cur_image = 0xAC2; @@ -567,7 +575,7 @@ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); const RailVehicleInfo *rvi = RailVehInfo(engine); - int32 value = (rvi->base_cost * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8; + int32 value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _eco->GetPrice(CEconomy::BUILD_RAILWAGON)) >> 8; uint num_vehicles = 1 + CountArticulatedParts(engine); @@ -608,7 +616,6 @@ v->y_pos = y; v->z_pos = GetSlopeZ(x, y); v->owner = _current_player; - v->z_height = 6; v->u.rail.track = TRACK_BIT_DEPOT; v->vehstatus = VS_HIDDEN | VS_DEFPAL; @@ -630,16 +637,19 @@ v->u.rail.railtype = rvi->railtype; v->build_year = _cur_year; - v->type = VEH_TRAIN; + v = new (v) Train(); v->cur_image = 0xAC2; v->random_bits = VehicleRandomBits(); + v->group_id = DEFAULT_GROUP; + AddArticulatedParts(vl); _new_vehicle_id = v->index; VehiclePositionChanged(v); TrainConsistChanged(GetFirstVehicleInChain(v)); + UpdateTrainGroupID(GetFirstVehicleInChain(v)); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); if (IsLocalPlayer()) { @@ -668,9 +678,9 @@ } } -static int32 EstimateTrainCost(const RailVehicleInfo* rvi) +static int32 EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi) { - return rvi->base_cost * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5; + return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_eco->GetPrice(CEconomy::BUILD_RAILVEHICLE) >> 3) >> 5; } static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building) @@ -681,7 +691,6 @@ u->x_pos = v->x_pos; u->y_pos = v->y_pos; u->z_pos = v->z_pos; - u->z_height = 6; u->u.rail.track = TRACK_BIT_DEPOT; u->vehstatus = v->vehstatus & ~VS_STOPPED; u->subtype = 0; @@ -696,7 +705,7 @@ u->build_year = v->build_year; if (building) v->value >>= 1; u->value = v->value; - u->type = VEH_TRAIN; + u = new (u) Train(); u->cur_image = 0xAC2; u->random_bits = VehicleRandomBits(); VehiclePositionChanged(u); @@ -731,7 +740,7 @@ if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags); - int32 value = EstimateTrainCost(rvi); + int32 value = EstimateTrainCost(p1, rvi); uint num_vehicles = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + @@ -763,7 +772,6 @@ v->x_pos = x; v->y_pos = y; v->z_pos = GetSlopeZ(x, y); - v->z_height = 6; v->u.rail.track = TRACK_BIT_DEPOT; v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = rvi->image_index; @@ -789,13 +797,15 @@ v->service_interval = _patches.servint_trains; v->date_of_last_service = _date; v->build_year = _cur_year; - v->type = VEH_TRAIN; + v = new (v) Train(); v->cur_image = 0xAC2; v->random_bits = VehicleRandomBits(); v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); + v->group_id = DEFAULT_GROUP; + v->subtype = 0; SetFrontEngine(v); SetTrainEngine(v); @@ -817,6 +827,7 @@ TrainConsistChanged(v); UpdateTrainAcceleration(v); + UpdateTrainGroupID(v); if (!HASBIT(p2, 1)) { // check if the cars should be added to the new vehicle NormalizeTrainVehInDepot(v); @@ -1112,6 +1123,16 @@ for (Vehicle *u = src_head; u != NULL; u = u->next) u->first = NULL; for (Vehicle *u = dst_head; u != NULL; u = u->next) u->first = NULL; + /* If we move the front Engine and if the second vehicle is not an engine + add the whole vehicle to the DEFAULT_GROUP */ + if (IsFrontEngine(src) && !IsDefaultGroupID(src->group_id)) { + const Vehicle *v = GetNextVehicle(src); + + if (v != NULL && !IsTrainEngine(v)) { + DoCommand(tile, DEFAULT_GROUP, v->index, flags, CMD_ADD_VEHICLE_GROUP); + } + } + if (HASBIT(p2, 0)) { /* unlink ALL wagons */ if (src != src_head) { @@ -1141,6 +1162,14 @@ SetFrontEngine(src); assert(src->orders == NULL); src->num_orders = 0; + + // Decrease the engines number of the src engine_type + if (!IsDefaultGroupID(src->group_id) && IsValidGroupID(src->group_id)) { + GetGroup(src->group_id)->num_engines[src->engine_type]--; + } + + // If we move an engine to a new line affect it to the DEFAULT_GROUP + src->group_id = DEFAULT_GROUP; } } else { SetFreeWagon(src); @@ -1202,13 +1231,18 @@ * To do this, CmdMoveRailVehicle must be called once more * we can't loop forever here because next time we reach this line we will have a front engine */ if (src_head != NULL && !IsFrontEngine(src_head) && IsTrainEngine(src_head)) { + /* As in CmdMoveRailVehicle src_head->group_id will be equal to DEFAULT_GROUP + * we need to save the group and reaffect it to src_head */ + const GroupID tmp_g = src_head->group_id; CmdMoveRailVehicle(0, flags, src_head->index | (INVALID_VEHICLE << 16), 1); + SetTrainGroupID(src_head, tmp_g); src_head = NULL; // don't do anything more to this train since the new call will do it } if (src_head != NULL) { NormaliseTrainConsist(src_head); TrainConsistChanged(src_head); + UpdateTrainGroupID(src_head); if (IsFrontEngine(src_head)) { UpdateTrainAcceleration(src_head); InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index); @@ -1223,6 +1257,7 @@ if (dst_head != NULL) { NormaliseTrainConsist(dst_head); TrainConsistChanged(dst_head); + UpdateTrainGroupID(dst_head); if (IsFrontEngine(dst_head)) { UpdateTrainAcceleration(dst_head); InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index); @@ -1269,7 +1304,6 @@ DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT); } - v->u.rail.days_since_order_progr = 0; v->vehstatus ^= VS_STOPPED; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); @@ -1364,6 +1398,8 @@ if (first->next_shared != NULL) { first->next_shared->prev_shared = new_f; new_f->next_shared = first->next_shared; + } else { + RemoveVehicleFromGroup(v); } /* @@ -1394,6 +1430,7 @@ if (first != NULL) { NormaliseTrainConsist(first); TrainConsistChanged(first); + UpdateTrainGroupID(first); if (IsFrontEngine(first)) { InvalidateWindow(WC_VEHICLE_DETAILS, first->index); InvalidateWindow(WC_VEHICLE_REFIT, first->index); @@ -1447,6 +1484,7 @@ first = UnlinkWagon(v, first); DeleteDepotHighlightOfVehicle(v); DeleteVehicle(v); + RemoveVehicleFromGroup(v); } } @@ -1454,6 +1492,7 @@ if (flags & DC_EXEC && first != NULL) { NormaliseTrainConsist(first); TrainConsistChanged(first); + UpdateTrainGroupID(first); if (IsFrontEngine(first)) UpdateTrainAcceleration(first); InvalidateWindow(WC_VEHICLE_DETAILS, first->index); InvalidateWindow(WC_VEHICLE_REFIT, first->index); @@ -1463,9 +1502,9 @@ return cost; } -static void UpdateTrainDeltaXY(Vehicle *v, Direction direction) +void Train::UpdateDeltaXY(Direction direction) { -#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0) +#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0) static const uint32 _delta_xy_table[8] = { MKIT(3, 3, -1, -1), MKIT(3, 7, -1, -3), @@ -1479,16 +1518,16 @@ #undef MKIT uint32 x = _delta_xy_table[direction]; - - v->x_offs = GB(x, 0, 8); - v->y_offs = GB(x, 8, 8); - v->sprite_width = GB(x, 16, 8); - v->sprite_height = GB(x, 24, 8); + this->x_offs = GB(x, 0, 8); + this->y_offs = GB(x, 8, 8); + this->sprite_width = GB(x, 16, 8); + this->sprite_height = GB(x, 24, 8); + this->z_height = 6; } static void UpdateVarsAfterSwap(Vehicle *v) { - UpdateTrainDeltaXY(v, v->direction); + v->UpdateDeltaXY(v->direction); v->cur_image = GetTrainImage(v, v->direction); BeginVehicleMove(v); VehiclePositionChanged(v); @@ -1751,11 +1790,14 @@ * param p2 various bitstuffed elements * - p2 = (bit 0-7) - the new cargo type to refit to * - p2 = (bit 8-15) - the new cargo subtype to refit to + * - p2 = (bit 16) - refit only this vehicle + * @return cost of refit or error */ int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { CargoID new_cid = GB(p2, 0, 8); byte new_subtype = GB(p2, 8, 8); + bool only_this = HASBIT(p2, 16); if (!IsValidVehicleID(p1)) return CMD_ERROR; @@ -1833,7 +1875,7 @@ } } } - } while ((v = v->next) != NULL); + } while ((v = v->next) != NULL && !only_this); _returned_refit_capacity = num; @@ -1966,7 +2008,6 @@ if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders if (flags & DC_EXEC) { if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) { - v->u.rail.days_since_order_progr = 0; v->cur_order_index++; } @@ -2029,7 +2070,6 @@ /* no smoke? */ if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) || disable_effect || - rvi->railtype > RAILTYPE_ELECTRIC || v->vehstatus & VS_HIDDEN) { continue; } @@ -2090,22 +2130,20 @@ static const SoundFx sfx[] = { SND_04_TRAIN, SND_0A_TRAIN_HORN, - SND_0A_TRAIN_HORN + SND_0A_TRAIN_HORN, + SND_47_MAGLEV_2, + SND_41_MAGLEV }; if (PlayVehicleSound(v, VSE_START)) return; EngineID engtype = v->engine_type; - switch (RailVehInfo(engtype)->railtype) { - case RAILTYPE_RAIL: - case RAILTYPE_ELECTRIC: - SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v); - break; - - case RAILTYPE_MONO: SndPlayVehicleFx(SND_47_MAGLEV_2, v); break; - case RAILTYPE_MAGLEV: SndPlayVehicleFx(SND_41_MAGLEV, v); break; - default: NOT_REACHED(); - } + SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v); +} + +void Train::PlayLeaveStationSound() const +{ + TrainPlayLeaveStationSound(this); } static bool CheckTrainStayInDepot(Vehicle *v) @@ -2146,7 +2184,7 @@ v->vehstatus &= ~VS_HIDDEN; v->cur_speed = 0; - UpdateTrainDeltaXY(v, v->direction); + v->UpdateDeltaXY(v->direction); v->cur_image = GetTrainImage(v, v->direction); VehiclePositionChanged(v); UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction)); @@ -2519,62 +2557,17 @@ return !at_waypoint && CheckReverseTrain(v); } -static void MarkTrainDirty(Vehicle *v) +void Train::MarkDirty() { + Vehicle *v = this; do { v->cur_image = GetTrainImage(v, v->direction); MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1); } while ((v = v->next) != NULL); -} - -static void HandleTrainLoading(Vehicle *v, bool mode) -{ - switch (v->current_order.type) { - case OT_LOADING: { - if (mode) return; - - /* don't mark the train as lost if we're loading on the final station. */ - if (v->current_order.flags & OF_NON_STOP) { - v->u.rail.days_since_order_progr = 0; - } - - if (--v->load_unload_time_rem) return; - - if (CanFillVehicle(v) && ( - v->current_order.flags & OF_FULL_LOAD || - (_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)) - )) { - v->u.rail.days_since_order_progr = 0; // Prevent a train lost message for full loading trains - SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC); - if (LoadUnloadVehicle(v, false)) { - InvalidateWindow(WC_TRAINS_LIST, v->owner); - MarkTrainDirty(v); - - /* need to update acceleration and cached values since the goods on the train changed. */ - TrainCargoChanged(v); - UpdateTrainAcceleration(v); - } - return; - } - - TrainPlayLeaveStationSound(v); - - Order b = v->current_order; - v->LeaveStation(); - - /* If this was not the final order, don't remove it from the list. */ - if (!(b.flags & OF_NON_STOP)) return; - break; - } - - case OT_DUMMY: break; - - default: return; - } - - v->u.rail.days_since_order_progr = 0; - v->cur_order_index++; - InvalidateVehicleOrder(v); + + /* need to update acceleration and cached values since the goods on the train changed. */ + TrainCargoChanged(this); + UpdateTrainAcceleration(this); } static int UpdateTrainSpeed(Vehicle *v) @@ -2631,29 +2624,8 @@ ); } - /* Did we reach the final destination? */ - if (v->current_order.type == OT_GOTO_STATION && - v->current_order.dest == station) { - /* Yeah, keep the load/unload flags - * Non Stop now means if the order should be increased. */ - v->BeginLoading(); - v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER; - v->current_order.flags |= OF_NON_STOP; - } else { - /* No, just do a simple load */ - v->BeginLoading(); - v->current_order.flags = 0; - } + v->BeginLoading(); v->current_order.dest = 0; - - SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC); - if (LoadUnloadVehicle(v, true) != 0) { - InvalidateWindow(WC_TRAINS_LIST, v->owner); - TrainCargoChanged(v); - UpdateTrainAcceleration(v); - } - MarkTrainDirty(v); - InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); } static byte AfterSetTrainPos(Vehicle *v, bool new_tile) @@ -3078,7 +3050,7 @@ /* update image of train, as well as delta XY */ Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y); - UpdateTrainDeltaXY(v, newdir); + v->UpdateDeltaXY(newdir); if (update_image) v->cur_image = GetTrainImage(v, newdir); v->x_pos = gp.x; @@ -3130,6 +3102,9 @@ BeginVehicleMove(v); EndVehicleMove(v); + + if (IsFrontEngine(v)) RemoveVehicleFromGroup(v); + DeleteVehicle(v); if (v->u.rail.track != TRACK_BIT_DEPOT && v->u.rail.track != TRACK_BIT_WORMHOLE) @@ -3174,7 +3149,7 @@ if (!(v->vehstatus & VS_HIDDEN)) { v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]); BeginVehicleMove(v); - UpdateTrainDeltaXY(v, v->direction); + v->UpdateDeltaXY(v->direction); v->cur_image = GetTrainImage(v, v->direction); /* Refrain from updating the z position of the vehicle when on a bridge, because AfterSetTrainPos will put the vehicle under @@ -3215,6 +3190,7 @@ if (state >= 4440 && !(v->tick_counter&0x1F)) { DeleteLastWagon(v); + InvalidateWindow(WC_REPLACE_VEHICLE, (v->group_id << 16) | VEH_TRAIN); } } @@ -3376,7 +3352,7 @@ return; } - HandleTrainLoading(v, mode); + v->HandleLoading(mode); if (v->current_order.type == OT_LOADING) return; @@ -3465,6 +3441,8 @@ return; } + if (v->current_order.type == OT_LOADING) v->LeaveStation(); + v->current_order.type = OT_GOTO_DEPOT; v->current_order.flags = OF_NON_STOP; v->current_order.dest = depot->index; diff -r 0b2aebc8283e -r 0b8b245a2391 src/train_gui.cpp --- a/src/train_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/train_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -320,7 +320,7 @@ if (w != NULL) { w->caption_color = v->owner; - AssignWindowViewport(w, 3, 17, 0xE2, 0x66, w->window_number | (1 << 31), 0); + AssignWindowViewport(w, 3, 17, 0xE2, 0x66, w->window_number | (1 << 31), ZOOM_LVL_TRAIN); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/transparency_gui.cpp --- a/src/transparency_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/transparency_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -23,6 +23,7 @@ TTW_WIDGET_BUILDINGS, ///< Make player buildings and structures transparent TTW_WIDGET_BRIDGES, ///< Make bridges transparent TTW_WIDGET_STRUCTURES, ///< Make unmovable structures transparent + TTW_WIDGET_END, ///< End of toggle buttons }; /** Toggle the bits of the transparencies variable @@ -41,7 +42,7 @@ case WE_PAINT: /* must be sure that the widgets show the transparency variable changes * also when we use shortcuts */ - for (uint i = TTW_WIDGET_SIGNS; i < TTW_WIDGET_STRUCTURES; i++) { + for (uint i = TTW_WIDGET_SIGNS; i < TTW_WIDGET_END; i++) { SetWindowWidgetLoweredState(w, i, HASBIT(_transparent_opt, i - TTW_WIDGET_SIGNS)); } DrawWindowWidgets(w); @@ -63,7 +64,7 @@ /* transparency widgets: * transparent signs, trees, houses, industries, player's buildings, bridges and unmovable structures */ -{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_PLACE_SIGN, STR_TRANSPARENT_SIGNS_DESC}, +{ WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_SIGN, STR_TRANSPARENT_SIGNS_DESC}, { WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_PLANTTREES, STR_TRANSPARENT_TREES_DESC}, { WWT_IMGBTN, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_TOWN, STR_TRANSPARENT_HOUSES_DESC}, { WWT_IMGBTN, RESIZE_NONE, 7, 66, 87, 14, 35, SPR_IMG_INDUSTRY, STR_TRANSPARENT_INDUSTRIES_DESC}, diff -r 0b2aebc8283e -r 0b8b245a2391 src/tunnel_map.h --- a/src/tunnel_map.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/tunnel_map.h Wed Jun 13 11:45:14 2007 +0000 @@ -9,8 +9,14 @@ #include "macros.h" #include "map.h" #include "rail.h" +#include "road.h" - +/** + * Is this a tunnel (entrance)? + * @param t the tile that might be a tunnel + * @pre IsTileType(t, MP_TUNNELBRIDGE) + * @return true if and only if this tile is a tunnel (entrance) + */ static inline bool IsTunnel(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); @@ -18,31 +24,60 @@ } +/** + * Is this a tunnel (entrance)? + * @param t the tile that might be a tunnel + * @return true if and only if this tile is a tunnel (entrance) + */ static inline bool IsTunnelTile(TileIndex t) { return IsTileType(t, MP_TUNNELBRIDGE) && IsTunnel(t); } - +/** + * Gets the direction facing out of the tunnel + * @param t the tile to get the tunnel facing direction of + * @pre IsTunnelTile(t) + * @return the direction the tunnel is facing + */ static inline DiagDirection GetTunnelDirection(TileIndex t) { assert(IsTunnelTile(t)); return (DiagDirection)GB(_m[t].m5, 0, 2); } - +/** + * Gets the transport type of the tunnel (road or rail) + * @param t the tunnel entrance tile to get the type of + * @pre IsTunnelTile(t) + * @return the transport type in the tunnel + */ static inline TransportType GetTunnelTransportType(TileIndex t) { assert(IsTunnelTile(t)); return (TransportType)GB(_m[t].m5, 2, 2); } +/** + * Is this tunnel entrance in a snowy or desert area? + * @param t the tunnel entrance tile + * @pre IsTunnelTile(t) + * @return true if and only if the tunnel entrance is in a snowy/desert area + */ static inline bool HasTunnelSnowOrDesert(TileIndex t) { assert(IsTunnelTile(t)); return HASBIT(_m[t].m4, 7); } +/** + * Places this tunnel entrance in a snowy or desert area, + * or takes it out of there. + * @param t the tunnel entrance tile + * @param snow_or_desert is the entrance in snow or desert (true), when + * not in snow and not in desert false + * @pre IsTunnelTile(t) + */ static inline void SetTunnelSnowOrDesert(TileIndex t, bool snow_or_desert) { assert(IsTunnelTile(t)); @@ -54,16 +89,30 @@ bool IsTunnelInWay(TileIndex, uint z); -static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d) +/** + * Makes a road tunnel entrance + * @param t the entrance of the tunnel + * @param o the owner of the entrance + * @param d the direction facing out of the tunnel + * @param r the road type used in the tunnel + */ +static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTypes r) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); _m[t].m2 = 0; - _m[t].m3 = 0; + _m[t].m3 = r; _m[t].m4 = 0; _m[t].m5 = TRANSPORT_ROAD << 2 | d; } +/** + * Makes a rail tunnel entrance + * @param t the entrance of the tunnel + * @param o the owner of the entrance + * @param d the direction facing out of the tunnel + * @param r the rail type used in the tunnel + */ static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailType r) { SetTileType(t, MP_TUNNELBRIDGE); diff -r 0b2aebc8283e -r 0b8b245a2391 src/tunnelbridge_cmd.cpp --- a/src/tunnelbridge_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/tunnelbridge_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -172,12 +172,14 @@ * @param p1 packed start tile coords (~ dx) * @param p2 various bitstuffed elements * - p2 = (bit 0- 7) - bridge type (hi bh) - * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge. + * - p2 = (bit 8-..) - rail type or road types. + * - p2 = (bit 15 ) - set means road bridge. */ int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) { uint bridge_type; RailType railtype; + RoadTypes roadtypes; uint x; uint y; uint sx; @@ -207,9 +209,12 @@ /* type of bridge */ if (HASBIT(p2, 15)) { railtype = INVALID_RAILTYPE; // road bridge + roadtypes = (RoadTypes)GB(p2, 8, 3); + if (!AreValidRoadTypes(roadtypes)) return CMD_ERROR; } else { if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR; railtype = (RailType)GB(p2, 8, 8); + roadtypes = ROADTYPES_NONE; } x = TileX(end_tile); @@ -352,8 +357,8 @@ MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); } else { - MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir); - MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir)); + MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir, roadtypes); + MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), roadtypes); } MarkTileDirtyByTile(tile_start); MarkTileDirtyByTile(tile_end); @@ -442,7 +447,7 @@ /** Build Tunnel. * @param start_tile start tile of tunnel * @param flags type of operation - * @param p1 railtype, 0x200 for road tunnel + * @param p1 railtype or roadtypes. bit 9 set means road tunnel * @param p2 unused */ int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2) @@ -458,8 +463,11 @@ int32 ret; _build_tunnel_endtile = 0; - - if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR; + if (!HASBIT(p1, 9)) { + if (!ValParamRailtype(p1)) return CMD_ERROR; + } else if (!AreValidRoadTypes((RoadTypes)GB(p1, 0, 3))) { + return CMD_ERROR; + } start_tileh = GetTileSlope(start_tile, &start_z); @@ -519,8 +527,8 @@ UpdateSignalsOnSegment(start_tile, direction); YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction))); } else { - MakeRoadTunnel(start_tile, _current_player, direction); - MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction)); + MakeRoadTunnel(start_tile, _current_player, direction, (RoadTypes)GB(p1, 0, 3)); + MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 3)); } } @@ -639,10 +647,11 @@ if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR; endtile = GetOtherBridgeEnd(tile); + byte bridge_height = GetBridgeHeight(tile); - if (!EnsureNoVehicleOnGround(tile) || - !EnsureNoVehicleOnGround(endtile) || - IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) { + if (FindVehicleOnTileZ(tile, bridge_height) != NULL || + FindVehicleOnTileZ(endtile, bridge_height) != NULL || + IsVehicleOnBridge(tile, endtile, bridge_height)) { return CMD_ERROR; } @@ -743,10 +752,11 @@ if (!CheckTileOwnership(tile)) return CMD_ERROR; endtile = GetOtherBridgeEnd(tile); + byte bridge_height = GetBridgeHeight(tile); - if (!EnsureNoVehicleOnGround(tile) || - !EnsureNoVehicleOnGround(endtile) || - IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) { + if (FindVehicleOnTileZ(tile, bridge_height) != NULL || + FindVehicleOnTileZ(endtile, bridge_height) != NULL || + IsVehicleOnBridge(tile, endtile, bridge_height)) { return CMD_ERROR; } @@ -877,9 +887,11 @@ image += GetTunnelDirection(ti->tile) * 2; DrawGroundSprite(image, PAL_NONE); - if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL && GetRailType(ti->tile) == RAILTYPE_ELECTRIC) { + DrawCatenary(ti); + } - AddSortableSpriteToDraw(image+1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); + AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); DrawBridgeMiddle(ti); } else if (IsBridge(ti->tile)) { // XXX is this necessary? const PalSpriteID *psid; @@ -915,7 +927,9 @@ DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE); } - if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL && GetRailType(ti->tile) == RAILTYPE_ELECTRIC) { + DrawCatenary(ti); + } image = psid->sprite; diff -r 0b2aebc8283e -r 0b8b245a2391 src/unix.cpp --- a/src/unix.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/unix.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -53,7 +53,7 @@ #else /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */ const char *s = strchr(path, ':'); - return s[1] == '\0'; + return s != NULL && s[1] == '\0'; #endif } diff -r 0b2aebc8283e -r 0b8b245a2391 src/variables.h --- a/src/variables.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/variables.h Wed Jun 13 11:45:14 2007 +0000 @@ -74,7 +74,6 @@ /* Keep track of current game position */ VARDEF int _saved_scrollpos_x; VARDEF int _saved_scrollpos_y; -VARDEF byte _saved_scrollpos_zoom; /* ********* END OF SAVE REGION */ @@ -127,6 +126,7 @@ bool measure_tooltip; // Show a permanent tooltip when dragging tools byte liveries; // Options for displaying company liveries, 0=none, 1=self, 2=all bool prefer_teamchat; // Choose the chat message target with , true=all players, false=your team + bool advanced_vehicle_list; // Use the "advanced" vehicle list uint8 toolbar_pos; // position of toolbars, 0=left, 1=center, 2=right uint8 window_snap_radius; // Windows snap at each other if closer than this @@ -225,6 +225,10 @@ uint8 town_growth_rate; ///< Town growth rate uint8 larger_towns; ///< The number of cities to build. These start off larger and grow twice as fast uint8 initial_city_size; ///< Multiplier for the initial size of the cities compared to towns + + bool pause_on_newgame; ///< Whether to start new games paused or not. + + TownLayoutByte town_layout; ///< Select town layout }; VARDEF Patches _patches; diff -r 0b2aebc8283e -r 0b8b245a2391 src/vehicle.cpp --- a/src/vehicle.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/vehicle.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -40,6 +40,8 @@ #include "newgrf_engine.h" #include "newgrf_sound.h" #include "helpers.hpp" +#include "group.h" +#include "economy.h" #define INVALID_COORD (-0x8000) #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6)) @@ -89,7 +91,7 @@ * TODO - This is just a temporary stage, this will be removed. */ for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) { v->index = start_item++; - v->type = VEH_INVALID; + v = new (v) InvalidVehicle(); } } @@ -110,7 +112,7 @@ return false; // Crashed vehicles don't need service anymore if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) { - return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type); /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */ + return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type, v->group_id); /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */ } return _patches.servint_ispercent ? @@ -224,6 +226,8 @@ Vehicle *v; FOR_ALL_VEHICLES(v) { + v->UpdateDeltaXY(v->direction); + v->first = NULL; if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE; } @@ -271,7 +275,7 @@ assert(v->orders == NULL); - v->type = VEH_INVALID; + v = new (v) InvalidVehicle(); v->left_coord = INVALID_COORD; v->first = NULL; v->next = NULL; @@ -281,6 +285,8 @@ v->prev_shared = NULL; v->depot_list = NULL; v->random_bits = 0; + v->group_id = DEFAULT_GROUP; + return v; } @@ -577,6 +583,9 @@ if (IsEngineCountable(v)) { GetPlayer(v->owner)->num_engines[v->engine_type]--; if (v->owner == _local_player) InvalidateAutoreplaceWindow(v->engine_type); + + if (IsValidGroupID(v->group_id)) GetGroup(v->group_id)->num_engines[v->engine_type]--; + if (v->type != VEH_TRAIN || IsFrontEngine(v)) DecreaseGroupNumVehicle(v->group_id); } DeleteVehicleNews(v->index, INVALID_STRING_ID); @@ -656,8 +665,6 @@ void CallVehicleTicks() { - Vehicle *v; - #ifdef ENABLE_NETWORK /* hotfix for desync problem: * for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients */ @@ -668,10 +675,16 @@ _first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick + Station *st; + FOR_ALL_STATIONS(st) LoadUnloadStation(st); + + Vehicle *v; FOR_ALL_VEHICLES(v) { _vehicle_tick_procs[v->type](v); switch (v->type) { + default: break; + case VEH_TRAIN: case VEH_ROAD: case VEH_AIRCRAFT: @@ -698,70 +711,6 @@ } } -static bool CanFillVehicle_FullLoadAny(Vehicle *v) -{ - uint32 full = 0, not_full = 0; - bool keep_loading = false; - const GoodsEntry *ge = GetStation(v->last_station_visited)->goods; - - /* special handling of aircraft */ - - /* if the aircraft carries passengers and is NOT full, then - *continue loading, no matter how much mail is in */ - if (v->type == VEH_AIRCRAFT && - IsCargoInClass(v->cargo_type, CC_PASSENGERS) && - v->cargo_cap != v->cargo_count) { - return true; - } - - /* patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded. */ - do { - /* Should never happen, but just in case future additions change this */ - assert(v->cargo_type<32); - - if (v->cargo_cap != 0) { - uint32 mask = 1 << v->cargo_type; - - if (v->cargo_cap == v->cargo_count) { - full |= mask; - } else if (GB(ge[v->cargo_type].waiting_acceptance, 0, 12) > 0 || - (HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING) && (ge[v->cargo_type].waiting_acceptance & 0x8000))) { - /* If there is any cargo waiting, or this vehicle is still unloading - * and the station accepts the cargo, don't leave the station. */ - keep_loading = true; - } else { - not_full |= mask; - } - } - } while ((v = v->next) != NULL); - - /* continue loading if there is a non full cargo type and no cargo type that is full */ - return keep_loading || (not_full && (full & ~not_full) == 0); -} - -bool CanFillVehicle(Vehicle *v) -{ - TileIndex tile = v->tile; - - if (IsTileType(tile, MP_STATION) || - (v->type == VEH_SHIP && ( - IsTileType(TILE_ADDXY(tile, 1, 0), MP_STATION) || - IsTileType(TILE_ADDXY(tile, -1, 0), MP_STATION) || - IsTileType(TILE_ADDXY(tile, 0, 1), MP_STATION) || - IsTileType(TILE_ADDXY(tile, 0, -1), MP_STATION) || - IsTileType(TILE_ADDXY(tile, -2, 0), MP_STATION) - ))) { - - /* If patch is active, use alternative CanFillVehicle-function */ - if (_patches.full_load_any && v->current_order.flags & OF_FULL_LOAD) return CanFillVehicle_FullLoadAny(v); - - do { - if (v->cargo_count != v->cargo_cap) return true; - } while ((v = v->next) != NULL); - } - return false; -} - /** Check if a given engine type can be refitted to a given cargo * @param engine_type Engine type to check * @param cid_to check refit to this cargo-type @@ -1438,14 +1387,13 @@ v = ForceAllocateSpecialVehicle(); if (v != NULL) { - v->type = VEH_SPECIAL; + v = new (v) SpecialVehicle(); v->subtype = type; v->x_pos = x; v->y_pos = y; v->z_pos = z; - v->z_height = v->sprite_width = v->sprite_height = 1; - v->x_offs = v->y_offs = 0; v->tile = 0; + v->UpdateDeltaXY(INVALID_DIR); v->vehstatus = VS_UNCLICKABLE; _effect_init_procs[type](v); @@ -1483,8 +1431,8 @@ (uint)(y -= vp->top) >= (uint)vp->height) return NULL; - x = (x << vp->zoom) + vp->virtual_left; - y = (y << vp->zoom) + vp->virtual_top; + x = ScaleByZoom(x, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y, vp->zoom) + vp->virtual_top; FOR_ALL_VEHICLES(v) { if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 && @@ -1624,7 +1572,7 @@ int32 return_value = CMD_ERROR; uint i; uint stop_command; - byte vehicle_type = GB(p2, 0, 5); + VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5); bool start_stop = HASBIT(p2, 5); bool vehicle_list_window = HASBIT(p2, 6); @@ -1691,7 +1639,7 @@ int32 cost = 0; uint i, sell_command, total_number_vehicles; - byte vehicle_type = GB(p1, 0, 8); + VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8); switch (vehicle_type) { case VEH_TRAIN: sell_command = CMD_SELL_RAIL_WAGON; break; @@ -1740,8 +1688,7 @@ uint16 engine_count = 0; uint i, x = 0, y = 0, z = 0; int32 cost = 0; - byte vehicle_type = GB(p1, 0, 8); - + VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8); if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; @@ -1804,7 +1751,7 @@ { Vehicle *v_front, *v; Vehicle *w_front, *w, *w_rear; - int cost, total_cost = 0; + int32 cost, total_cost = 0; uint32 build_argument = 2; if (!IsValidVehicleID(p1)) return CMD_ERROR; @@ -1842,18 +1789,6 @@ v = v_front; do { - - if (!(flags & DC_EXEC)) { - /* Get the refit cost. - * This is only needed when estimating as when the command is executed, the cost from the refit command is used. - * This needs to be done for every single unit, so it should be done before checking if it's a multiheaded engine. */ - CargoID new_cargo_type = GetEngineCargoType(v->engine_type); - - if (new_cargo_type != v->cargo_type && new_cargo_type != CT_INVALID) { - total_cost += GetRefitCost(v->engine_type); - } - } - if (IsMultiheaded(v) && !IsTrainEngine(v)) { /* we build the rear ends of multiheaded trains with the front ones */ continue; @@ -1869,18 +1804,6 @@ if (flags & DC_EXEC) { w = GetVehicle(_new_vehicle_id); - Vehicle *w2 = w; - Vehicle *v2 = v; - do { - if (v2->cargo_type != w2->cargo_type || v2->cargo_subtype != w2->cargo_subtype) { - /* We can't pay for refitting because we can't estimate refitting costs for a vehicle before it's build. - * If we pay for it anyway, the cost and the estimated cost will not be the same and we will have an assert. - * We need to check the whole chain if it is a train because some newgrf articulated engines can refit some units only (and not the front) */ - total_cost += DoCommand(0, w->index, v2->cargo_type | (v2->cargo_subtype << 8), flags, GetCmdRefitVeh(v)); - break; // We learned that the engine in question needed a refit. No need to check anymore - } - } while (v->type == VEH_TRAIN && (w2 = w2->next) != NULL && (v2 = v2->next) != NULL); - if (v->type == VEH_TRAIN && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) { SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION); } @@ -1904,6 +1827,59 @@ _new_vehicle_id = w_front->index; } + if (flags & DC_EXEC) { + /* Cloned vehicles belong to the same group */ + DoCommand(0, v_front->group_id, w_front->index, flags, CMD_ADD_VEHICLE_GROUP); + } + + + /* Take care of refitting. */ + w = w_front; + v = v_front; + + /* Both building and refitting are influenced by newgrf callbacks, which + * makes it impossible to accurately estimate the cloning costs. In + * particular, it is possible for engines of the same type to be built with + * different numbers of articulated parts, so when refitting we have to + * loop over real vehicles first, and then the articulated parts of those + * vehicles in a different loop. */ + do { + do { + if (flags & DC_EXEC) { + assert(w != NULL); + + if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) { + cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v)); + if (!CmdFailed(cost)) total_cost += cost; + } + + if (w->type == VEH_TRAIN && EngineHasArticPart(w)) { + w = GetNextArticPart(w); + } else { + break; + } + } else { + CargoID initial_cargo = GetEngineCargoType(v->engine_type); + + if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) { + total_cost += GetRefitCost(v->engine_type); + } + } + } while (v->type == VEH_TRAIN && EngineHasArticPart(v) && (v = GetNextArticPart(v)) != NULL); + + if (flags & DC_EXEC) w = GetNextVehicle(w); + } while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL); + + /* Since we can't estimate the cost of cloning a vehicle accurately we must + * check whether the player has enough money manually. */ + if (!CheckPlayerHasMoney(total_cost)) { + if (flags & DC_EXEC) { + /* The vehicle has already been bought, so now it must be sold again. */ + DoCommand(w_front->tile, w_front->index, 1, flags, GetCmdSellVeh(w_front)); + } + return CMD_ERROR; + } + /* Set the expense type last as refitting will make the cost go towards * running costs... */ SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); @@ -1930,7 +1906,7 @@ * @param *wagon_list_length Allocated size of wagon_list. Needs to be set to 0 when wagon_list points to a NULL array * @param *wagon_count The number of engines stored in the list */ -void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count) +void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count) { Vehicle *v; @@ -2009,11 +1985,12 @@
  • VLW_SHARED_ORDERS: index of order to generate a list for
  • VLW_STANDARD: not used
  • VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for
  • +
  • VLW_GROUP_LIST: index of group to generate a list for
  • * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h * @return the number of vehicles added to the list */ -uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, uint32 index, uint16 window_type) +uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type) { const byte subtype = (type != VEH_AIRCRAFT) ? (byte)Train_Front : (byte)AIR_AIRCRAFT; uint n = 0; @@ -2087,6 +2064,19 @@ break; } + case VLW_GROUP_LIST: + FOR_ALL_VEHICLES(v) { + if (v->type == type && ( + (type == VEH_TRAIN && IsFrontEngine(v)) || + (type != VEH_TRAIN && v->subtype <= subtype) + ) && v->owner == owner && v->group_id == index) { + if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, GetNumVehicles() / 4); + + (*sort_list)[n++] = v; + } + } + break; + default: NOT_REACHED(); break; } @@ -2110,7 +2100,7 @@ * @param vlw_flag tells what kind of list requested the goto depot * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot */ -int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id) +int32 SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id) { const Vehicle **sort_list = NULL; uint n, i; @@ -2221,7 +2211,6 @@ if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) { /* Part of orders */ - if (v->type == VEH_TRAIN) v->u.rail.days_since_order_progr = 0; v->cur_order_index++; } else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) { /* Force depot visit */ @@ -2421,7 +2410,7 @@ return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y); } -UnitID GetFreeUnitNumber(byte type) +UnitID GetFreeUnitNumber(VehicleType type) { UnitID unit, max = 0; const Vehicle *u; @@ -2467,31 +2456,19 @@ return unit; } -static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) + +const Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) { - SpriteID map = PAL_NONE; const Player *p = GetPlayer(player); LiveryScheme scheme = LS_DEFAULT; CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type; - /* Check if we should use the colour map callback */ - if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) { - uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v); - /* A return value of 0xC000 is stated to "use the default two-color - * maps" which happens to be the failure action too... */ - if (callback != CALLBACK_FAILED && callback != 0xC000) { - map = GB(callback, 0, 14); - /* If bit 14 is set, then the company colours are applied to the - * map else it's returned as-is. */ - if (!HASBIT(callback, 14)) return map; - } - } - /* The default livery is always available for use, but its in_use flag determines * whether any _other_ liveries are in use. */ if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) { /* Determine the livery scheme to use */ switch (GetEngine(engine_type)->type) { + default: NOT_REACHED(); case VEH_TRAIN: { const RailVehicleInfo *rvi = RailVehInfo(engine_type); @@ -2502,14 +2479,15 @@ { if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type; if (rvi->railveh_type == RAILVEH_WAGON) { - if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) { + if (!GetCargo(cargo_type)->is_freight) { if (parent_engine_type == INVALID_ENGINE) { scheme = LS_PASSENGER_WAGON_STEAM; } else { switch (RailVehInfo(parent_engine_type)->engclass) { - case 0: scheme = LS_PASSENGER_WAGON_STEAM; break; - case 1: scheme = LS_PASSENGER_WAGON_DIESEL; break; - case 2: scheme = LS_PASSENGER_WAGON_ELECTRIC; break; + default: NOT_REACHED(); + case EC_STEAM: scheme = LS_PASSENGER_WAGON_STEAM; break; + case EC_DIESEL: scheme = LS_PASSENGER_WAGON_DIESEL; break; + case EC_ELECTRIC: scheme = LS_PASSENGER_WAGON_ELECTRIC; break; } } } else { @@ -2519,9 +2497,10 @@ bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU); switch (rvi->engclass) { - case 0: scheme = LS_STEAM; break; - case 1: scheme = is_mu ? LS_DMU : LS_DIESEL; break; - case 2: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break; + default: NOT_REACHED(); + case EC_STEAM: scheme = LS_STEAM; break; + case EC_DIESEL: scheme = is_mu ? LS_DMU : LS_DIESEL; break; + case EC_ELECTRIC: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break; } } break; @@ -2563,12 +2542,35 @@ if (!p->livery[scheme].in_use) scheme = LS_DEFAULT; } + return &p->livery[scheme]; +} + + +static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) +{ + SpriteID map = PAL_NONE; + + /* Check if we should use the colour map callback */ + if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) { + uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v); + /* A return value of 0xC000 is stated to "use the default two-color + * maps" which happens to be the failure action too... */ + if (callback != CALLBACK_FAILED && callback != 0xC000) { + map = GB(callback, 0, 14); + /* If bit 14 is set, then the company colours are applied to the + * map else it's returned as-is. */ + if (!HASBIT(callback, 14)) return map; + } + } + bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC); if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START; - map += p->livery[scheme].colour1; - if (twocc) map += p->livery[scheme].colour2 * 16; + const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v); + + map += livery->colour1; + if (twocc) map += livery->colour2 * 16; return map; } @@ -2611,13 +2613,9 @@ SLE_VAR(Vehicle, z_pos, SLE_UINT8), SLE_VAR(Vehicle, direction, SLE_UINT8), - SLE_VAR(Vehicle, cur_image, SLE_UINT16), + SLE_CONDNULL(2, 0, 57), SLE_VAR(Vehicle, spritenum, SLE_UINT8), - SLE_VAR(Vehicle, sprite_width, SLE_UINT8), - SLE_VAR(Vehicle, sprite_height, SLE_UINT8), - SLE_VAR(Vehicle, z_height, SLE_UINT8), - SLE_VAR(Vehicle, x_offs, SLE_INT8), - SLE_VAR(Vehicle, y_offs, SLE_INT8), + SLE_CONDNULL(5, 0, 57), SLE_VAR(Vehicle, engine_type, SLE_UINT16), SLE_VAR(Vehicle, max_speed, SLE_UINT16), @@ -2648,17 +2646,17 @@ /* This next line is for version 4 and prior compatibility.. it temporarily reads type and flags (which were both 4 bits) into type. Later on this is converted correctly */ - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 0, 4), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), /* Orders for version 5 and on */ - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION), /* Refit in current order */ - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION), SLE_REF(Vehicle, orders, REF_ORDER), @@ -2695,6 +2693,8 @@ SLE_REF(Vehicle, next_shared, REF_VEHICLE), SLE_REF(Vehicle, prev_shared, REF_VEHICLE), + SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION), + /* reserve extra space in savegame here. (currently 10 bytes) */ SLE_CONDNULL(10, 2, SL_MAX_VERSION), @@ -2705,13 +2705,13 @@ static const SaveLoad _train_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN, 0), // Train type. VEH_TRAIN in mem, 0 in file. SLE_INCLUDEX(0, INC_VEHICLE_COMMON), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, crash_anim_pos), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, force_proceed), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, railtype), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track), SLE_UINT8), - - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION), - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8), + + SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION), + SLE_CONDNULL(2, 2, 59), SLE_CONDNULL(2, 2, 19), /* reserve extra space in savegame here. (currently 11 bytes) */ @@ -2723,17 +2723,17 @@ static const SaveLoad _roadveh_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_ROAD, 1), // Road type. VEH_ROAD in mem, 1 in file. SLE_INCLUDEX(0, INC_VEHICLE_COMMON), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, state), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, frame), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, blocked_ctr), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr), SLE_UINT8), - - SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8), + + SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION), SLE_CONDNULL(1, 6, SL_MAX_VERSION), - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION), /* reserve extra space in savegame here. (currently 16 bytes) */ SLE_CONDNULL(16, 2, SL_MAX_VERSION), @@ -2743,7 +2743,7 @@ static const SaveLoad _ship_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_SHIP, 2), // Ship type. VEH_SHIP in mem, 2 in file. SLE_INCLUDEX(0, INC_VEHICLE_COMMON), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8), /* reserve extra space in savegame here. (currently 16 bytes) */ SLE_CONDNULL(16, 2, SL_MAX_VERSION), @@ -2754,15 +2754,15 @@ static const SaveLoad _aircraft_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT, 3), // Aircraft type. VEH_AIRCRAFT in mem, 3 in file. SLE_INCLUDEX(0, INC_VEHICLE_COMMON), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, crashed_counter), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, pos), SLE_UINT8), - - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION), - - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state), SLE_UINT8), - - SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8), + + SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), + SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION), + + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8), + + SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION), /* reserve extra space in savegame here. (currently 15 bytes) */ SLE_CONDNULL(15, 2, SL_MAX_VERSION), @@ -2785,16 +2785,12 @@ SLE_VAR(Vehicle, z_pos, SLE_UINT8), SLE_VAR(Vehicle, cur_image, SLE_UINT16), - SLE_VAR(Vehicle, sprite_width, SLE_UINT8), - SLE_VAR(Vehicle, sprite_height, SLE_UINT8), - SLE_VAR(Vehicle, z_height, SLE_UINT8), - SLE_VAR(Vehicle, x_offs, SLE_INT8), - SLE_VAR(Vehicle, y_offs, SLE_INT8), + SLE_CONDNULL(5, 0, 57), SLE_VAR(Vehicle, progress, SLE_UINT8), SLE_VAR(Vehicle, vehstatus, SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk0), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk2), SLE_UINT8), /* reserve extra space in savegame here. (currently 16 bytes) */ SLE_CONDNULL(16, 2, SL_MAX_VERSION), @@ -2820,23 +2816,19 @@ SLE_VAR(Vehicle, z_pos, SLE_UINT8), SLE_VAR(Vehicle, direction, SLE_UINT8), - SLE_VAR(Vehicle, x_offs, SLE_INT8), - SLE_VAR(Vehicle, y_offs, SLE_INT8), - SLE_VAR(Vehicle, sprite_width, SLE_UINT8), - SLE_VAR(Vehicle, sprite_height, SLE_UINT8), - SLE_VAR(Vehicle, z_height, SLE_UINT8), + SLE_CONDNULL(5, 0, 57), SLE_VAR(Vehicle, owner, SLE_UINT8), SLE_VAR(Vehicle, vehstatus, SLE_UINT8), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), - SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), + SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION), SLE_VAR(Vehicle, cur_image, SLE_UINT16), SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30), SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION), SLE_VAR(Vehicle, tick_counter, SLE_UINT8), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16), - SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16), + SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, unk2), SLE_UINT16), /* reserve extra space in savegame here. (currently 16 bytes) */ SLE_CONDNULL(16, 2, SL_MAX_VERSION), @@ -2880,6 +2872,17 @@ v = GetVehicle(index); SlObject(v, (SaveLoad*)_veh_descs[SlReadByte()]); + switch (v->type) { + case VEH_TRAIN: v = new (v) Train(); break; + case VEH_ROAD: v = new (v) RoadVehicle(); break; + case VEH_SHIP: v = new (v) Ship(); break; + case VEH_AIRCRAFT: v = new (v) Aircraft(); break; + case VEH_SPECIAL: v = new (v) SpecialVehicle(); break; + case VEH_DISASTER: v = new (v) DisasterVehicle(); break; + case VEH_INVALID: v = new (v) InvalidVehicle(); break; + default: NOT_REACHED(); + } + /* Old savegames used 'last_station_visited = 0xFF' */ if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF) v->last_station_visited = INVALID_STATION; @@ -2890,6 +2893,9 @@ v->current_order.flags = (v->current_order.type & 0xF0) >> 4; v->current_order.type.m_val &= 0x0F; } + + /* Advanced vehicle lists got added */ + if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP; } /* Check for shared order-lists (we now use pointers for that) */ @@ -2917,15 +2923,80 @@ void Vehicle::BeginLoading() { assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP); + + if (this->current_order.type == OT_GOTO_STATION && + this->current_order.dest == this->last_station_visited) { + /* Arriving at the ordered station. + * Keep the load/unload flags, as we (obviously) still need them. */ + this->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER; + + /* Furthermore add the Non Stop flag to mark that this station + * is the actual destination of the vehicle, which is (for example) + * necessary to be known for HandleTrainLoading to determine + * whether the train is lost or not; not marking a train lost + * that arrives at random stations is bad. */ + this->current_order.flags |= OF_NON_STOP; + } else { + /* This is just an unordered intermediate stop */ + this->current_order.flags = 0; + } + current_order.type = OT_LOADING; GetStation(this->last_station_visited)->loading_vehicles.push_back(this); + + SET_EXPENSES_TYPE(this->GetExpenseType(true)); + VehiclePayment(this); + + InvalidateWindow(this->GetVehicleListWindowClass(), this->owner); + InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, STATUS_BAR); + InvalidateWindow(WC_VEHICLE_DETAILS, this->index); + InvalidateWindow(WC_STATION_VIEW, this->last_station_visited); + + GetStation(this->last_station_visited)->MarkTilesDirty(); + this->MarkDirty(); } void Vehicle::LeaveStation() { - assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP); assert(current_order.type == OT_LOADING); current_order.type = OT_LEAVESTATION; current_order.flags = 0; GetStation(this->last_station_visited)->loading_vehicles.remove(this); } + + +void Vehicle::HandleLoading(bool mode) +{ + switch (this->current_order.type) { + case OT_LOADING: { + /* Not the first call for this tick, or still loading */ + if (mode || !HASBIT(this->vehicle_flags, VF_LOADING_FINISHED)) return; + + this->PlayLeaveStationSound(); + + Order b = this->current_order; + this->LeaveStation(); + + /* If this was not the final order, don't remove it from the list. */ + if (!(b.flags & OF_NON_STOP)) return; + break; + } + + case OT_DUMMY: break; + + default: return; + } + + this->cur_order_index++; + InvalidateVehicleOrder(this); +} + + +void SpecialVehicle::UpdateDeltaXY(Direction direction) +{ + this->x_offs = 0; + this->y_offs = 0; + this->sprite_width = 1; + this->sprite_height = 1; + this->z_height = 1; +} diff -r 0b2aebc8283e -r 0b8b245a2391 src/vehicle.h --- a/src/vehicle.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/vehicle.h Wed Jun 13 11:45:14 2007 +0000 @@ -64,15 +64,18 @@ RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09 ///< Only bits 0 and 3 are used to encode the trackdir for road stops }; -enum { +enum VehicleType { VEH_TRAIN, VEH_ROAD, VEH_SHIP, VEH_AIRCRAFT, VEH_SPECIAL, VEH_DISASTER, + VEH_END, VEH_INVALID = 0xFF, -} ; +}; +template <> struct EnumPropsT : MakeEnumPropsT {}; +typedef TinyEnumT VehicleTypeByte; enum VehStatus { VS_HIDDEN = 0x01, @@ -108,7 +111,6 @@ struct VehicleRail { uint16 last_speed; // NOSAVE: only used in UI uint16 crash_anim_pos; - uint16 days_since_order_progr; /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */ uint16 cached_max_speed; // max speed of the consist. (minimum of the max speed of all vehicles in the consist) @@ -142,6 +144,9 @@ /* Link between the two ends of a multiheaded engine */ Vehicle *other_multiheaded_part; + + /* Cached wagon override spritegroup */ + const struct SpriteGroup *cached_override; }; enum { @@ -201,7 +206,7 @@ struct Vehicle { - byte type; // type, ie roadven,train,ship,aircraft,special + VehicleTypeByte type; ///< Type of vehicle byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) VehicleID index; // NOSAVE: Index in vehicle array @@ -305,6 +310,8 @@ TileIndex cargo_loaded_at_xy; ///< tile index where feeder cargo was loaded uint32 value; + GroupID group_id; ///< Index of group Pool array + union { VehicleRail rail; VehicleAir air; @@ -316,6 +323,141 @@ void BeginLoading(); void LeaveStation(); + + /** + * Handle the loading of the vehicle; when not it skips through dummy + * orders and does nothing in all other cases. + * @param mode is the non-first call for this vehicle in this tick? + */ + void HandleLoading(bool mode = false); + + /** + * An overriden version of new, so you can use the vehicle instance + * instead of a newly allocated piece of memory. + * @param size the size of the variable (unused) + * @param v the vehicle to use as 'storage' backend + * @return the memory that is 'allocated' + */ + void* operator new(size_t size, Vehicle *v) { return v; } + + /** + * 'Free' the memory allocated by the overriden new. + * @param p the memory to 'free' + * @param v the vehicle that was given to 'new' on creation. + * @note This function isn't used (at the moment) and only added + * to please some compiler. + */ + void operator delete(void *p, Vehicle *v) {} + + /** + * 'Free' the memory allocated by the overriden new. + * @param p the memory to 'free' + * @note This function isn't used (at the moment) and only added + * as the above function was needed to please some compiler + * which made it necessary to add this to please yet + * another compiler... + */ + void operator delete(void *p) {} + + /** We want to 'destruct' the right class. */ + virtual ~Vehicle() {} + + /** + * Get a string 'representation' of the vehicle type. + * @return the string representation. + */ + virtual const char* GetTypeString() const = 0; + + /** + * Marks the vehicles to be redrawn and updates cached variables + */ + virtual void MarkDirty() {} + + /** + * Updates the x and y offsets and the size of the sprite used + * for this vehicle. + * @param direction the direction the vehicle is facing + */ + virtual void UpdateDeltaXY(Direction direction) {} + + /** + * Sets the expense type associated to this vehicle type + * @param income whether this is income or (running) expenses of the vehicle + */ + virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; } + + /** + * Invalidates the vehicle list window of this type of vehicle + */ + virtual WindowClass GetVehicleListWindowClass() const { return WC_NONE; } + + /** + * Play the sound associated with leaving the station + */ + virtual void PlayLeaveStationSound() const {} +}; + +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Train(); + * + * As side-effect the vehicle type is set correctly. + * + * A special vehicle is one of the following: + * - smoke + * - electric sparks for trains + * - explosions + * - bulldozer (road works) + * - bubbles (industry) + */ +struct SpecialVehicle : public Vehicle { + /** Initializes the Vehicle to a special vehicle */ + SpecialVehicle() { this->type = VEH_SPECIAL; } + + /** We want to 'destruct' the right class. */ + virtual ~SpecialVehicle() {} + + const char *GetTypeString() const { return "special vehicle"; } + void UpdateDeltaXY(Direction direction); +}; + +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Train(); + * + * As side-effect the vehicle type is set correctly. + */ +struct DisasterVehicle : public Vehicle { + /** Initializes the Vehicle to a disaster vehicle */ + DisasterVehicle() { this->type = VEH_DISASTER; } + + /** We want to 'destruct' the right class. */ + virtual ~DisasterVehicle() {} + + const char *GetTypeString() const { return "disaster vehicle"; } + void UpdateDeltaXY(Direction direction); +}; + +/** + * This class 'wraps' Vehicle; you do not actually instantiate this class. + * You create a Vehicle using AllocateVehicle, so it is added to the pool + * and you reinitialize that to a Train using: + * v = new (v) Train(); + * + * As side-effect the vehicle type is set correctly. + */ +struct InvalidVehicle : public Vehicle { + /** Initializes the Vehicle to a invalid vehicle */ + InvalidVehicle() { this->type = VEH_INVALID; } + + /** We want to 'destruct' the right class. */ + virtual ~InvalidVehicle() {} + + const char *GetTypeString() const { return "invalid vehicle"; } }; #define is_custom_sprite(x) (x >= 0xFD) @@ -345,7 +487,6 @@ byte VehicleRandomBits(); void ResetVehiclePosHash(); -bool CanFillVehicle(Vehicle *v); bool CanRefitTo(EngineID engine_type, CargoID cid_to); CargoID FindFirstRefittableCargo(EngineID engine_type); int32 GetRefitCost(EngineID engine_type); @@ -383,9 +524,7 @@ void ShowAircraftViewWindow(const Vehicle* v); -UnitID GetFreeUnitNumber(byte type); - -int LoadUnloadVehicle(Vehicle *v, bool just_arrived); +UnitID GetFreeUnitNumber(VehicleType type); void TrainConsistChanged(Vehicle *v); void TrainPowerChanged(Vehicle *v); @@ -395,9 +534,9 @@ bool VehicleNeedsService(const Vehicle *v); -uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, byte type, PlayerID owner, uint32 index, uint16 window_type); -void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count); -int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id); +uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type); +void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count); +int32 SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id); bool IsVehicleInDepot(const Vehicle *v); void VehicleEnterDepot(Vehicle *v); @@ -470,10 +609,10 @@ static inline void DeleteVehicle(Vehicle *v) { DestroyVehicle(v); - v->type = VEH_INVALID; + v = new (v) InvalidVehicle(); } -static inline bool IsPlayerBuildableVehicleType(byte type) +static inline bool IsPlayerBuildableVehicleType(VehicleType type) { switch (type) { case VEH_TRAIN: @@ -481,8 +620,9 @@ case VEH_SHIP: case VEH_AIRCRAFT: return true; + + default: return false; } - return false; } static inline bool IsPlayerBuildableVehicleType(const Vehicle *v) @@ -551,6 +691,8 @@ static const VehicleID INVALID_VEHICLE = 0xFFFF; +const struct Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v); + /** * Get the colour map for an engine. This used for unbuilt engines in the user interface. * @param engine_type ID of engine @@ -576,7 +718,7 @@ extern const uint32 _send_to_depot_proc_table[]; /* Functions to find the right command for certain vehicle type */ -static inline uint32 GetCmdBuildVeh(byte type) +static inline uint32 GetCmdBuildVeh(VehicleType type) { return _veh_build_proc_table[type]; } @@ -586,7 +728,7 @@ return GetCmdBuildVeh(v->type); } -static inline uint32 GetCmdSellVeh(byte type) +static inline uint32 GetCmdSellVeh(VehicleType type) { return _veh_sell_proc_table[type]; } @@ -596,7 +738,7 @@ return GetCmdSellVeh(v->type); } -static inline uint32 GetCmdRefitVeh(byte type) +static inline uint32 GetCmdRefitVeh(VehicleType type) { return _veh_refit_proc_table[type]; } @@ -606,7 +748,7 @@ return GetCmdRefitVeh(v->type); } -static inline uint32 GetCmdSendToDepot(byte type) +static inline uint32 GetCmdSendToDepot(VehicleType type) { return _send_to_depot_proc_table[type]; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/vehicle_gui.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -31,6 +31,7 @@ #include "depot.h" #include "helpers.hpp" #include "cargotype.h" +#include "group.h" struct Sorting { Listing aircraft; @@ -41,15 +42,6 @@ static Sorting _sorting; -struct vehiclelist_d { - const Vehicle** sort_list; // List of vehicles (sorted) - Listing *_sorting; // pointer to the appropiate subcategory of _sorting - uint16 length_of_sort_list; // Keeps track of how many vehicle pointers sort list got space for - byte vehicle_type; // The vehicle type that is sorted - list_d l; // General list struct -}; -assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d)); - static bool _internal_sort_order; // descending/ascending typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*); @@ -78,7 +70,7 @@ &VehicleValueSorter, }; -static const StringID _vehicle_sort_listing[] = { +const StringID _vehicle_sort_listing[] = { STR_SORT_BY_NUMBER, STR_SORT_BY_DROPDOWN_NAME, STR_SORT_BY_AGE, @@ -134,7 +126,7 @@ } } -static void BuildVehicleList(vehiclelist_d* vl, PlayerID owner, uint16 index, uint16 window_type) +void BuildVehicleList(vehiclelist_d *vl, PlayerID owner, uint16 index, uint16 window_type) { if (!(vl->l.flags & VL_REBUILD)) return; @@ -146,7 +138,7 @@ vl->l.flags |= VL_RESORT; } -static void SortVehicleList(vehiclelist_d *vl) +void SortVehicleList(vehiclelist_d *vl) { if (!(vl->l.flags & VL_RESORT)) return; @@ -377,6 +369,7 @@ int command = 0; switch (v->type) { + default: NOT_REACHED(); case VEH_TRAIN: command = CMD_REFIT_RAIL_VEHICLE | CMD_MSG(STR_RAIL_CAN_T_REFIT_VEHICLE); break; case VEH_ROAD: command = CMD_REFIT_ROAD_VEH | CMD_MSG(STR_REFIT_ROAD_VEHICLE_CAN_T); break; case VEH_SHIP: command = CMD_REFIT_SHIP | CMD_MSG(STR_9841_CAN_T_REFIT_SHIP); break; @@ -748,16 +741,6 @@ } } -/* - * Start of functions regarding vehicle list windows - */ - -enum { - PLY_WND_PRC__OFFSET_TOP_WIDGET = 26, - PLY_WND_PRC__SIZE_OF_ROW_SMALL = 26, - PLY_WND_PRC__SIZE_OF_ROW_BIG = 36, -}; - enum VehicleListWindowWidgets { VLW_WIDGET_CLOSEBOX = 0, VLW_WIDGET_CAPTION, @@ -808,7 +791,7 @@ uint16 window_type = w->window_number & VLW_MASK; PlayerID player = (PlayerID)GB(w->window_number, 0, 8); - vl->vehicle_type = GB(w->window_number, 11, 5); + vl->vehicle_type = (VehicleType)GB(w->window_number, 11, 5); vl->length_of_sort_list = 0; vl->sort_list = NULL; w->caption_color = player; @@ -925,7 +908,7 @@ vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer } -static void DrawSmallOrderList(const Vehicle *v, int x, int y) +void DrawSmallOrderList(const Vehicle *v, int x, int y) { const Order *order; int sel, i = 0; @@ -1235,7 +1218,7 @@ PlayerVehWndProc }; -static void ShowVehicleListWindowLocal(PlayerID player, uint16 VLW_flag, byte vehicle_type, uint16 unique_number) +static void ShowVehicleListWindowLocal(PlayerID player, uint16 VLW_flag, VehicleType vehicle_type, uint16 unique_number) { Window *w; WindowNumber num; @@ -1272,9 +1255,13 @@ } } -void ShowVehicleListWindow(PlayerID player, byte vehicle_type) +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type) { - ShowVehicleListWindowLocal(player, VLW_STANDARD, vehicle_type, 0); + if (player == _local_player && _patches.advanced_vehicle_list) { + ShowPlayerGroup(player, vehicle_type); + } else { + ShowVehicleListWindowLocal(player, VLW_STANDARD, vehicle_type, 0); + } } void ShowVehicleListWindow(const Vehicle *v) @@ -1283,12 +1270,12 @@ ShowVehicleListWindowLocal(v->owner, VLW_SHARED_ORDERS, v->type, v->orders->index); } -void ShowVehicleListWindow(PlayerID player, byte vehicle_type, StationID station) +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, StationID station) { ShowVehicleListWindowLocal(player, VLW_STATION_LIST, vehicle_type, station); } -void ShowVehicleListWindow(PlayerID player, byte vehicle_type, TileIndex depot_tile) +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, TileIndex depot_tile) { uint16 depot_airport_index; diff -r 0b2aebc8283e -r 0b8b245a2391 src/vehicle_gui.h --- a/src/vehicle_gui.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/vehicle_gui.h Wed Jun 13 11:45:14 2007 +0000 @@ -15,21 +15,35 @@ /* sorter stuff */ void RebuildVehicleLists(); void ResortVehicleLists(); +void SortVehicleList(vehiclelist_d *vl); +void BuildVehicleList(vehiclelist_d *vl, PlayerID owner, uint16 index, uint16 window_type); #define PERIODIC_RESORT_DAYS 10 +extern const StringID _vehicle_sort_listing[]; + +/* Start of functions regarding vehicle list windows */ +enum { + PLY_WND_PRC__OFFSET_TOP_WIDGET = 26, + PLY_WND_PRC__SIZE_OF_ROW_TINY = 13, + PLY_WND_PRC__SIZE_OF_ROW_SMALL = 26, + PLY_WND_PRC__SIZE_OF_ROW_BIG = 36, + PLY_WND_PRC__SIZE_OF_ROW_BIG2 = 39, +}; + /* Vehicle List Window type flags */ enum { VLW_STANDARD = 0 << 8, VLW_SHARED_ORDERS = 1 << 8, VLW_STATION_LIST = 2 << 8, VLW_DEPOT_LIST = 3 << 8, + VLW_GROUP_LIST = 4 << 8, VLW_MASK = 0x700, }; static inline bool ValidVLWFlags(uint16 flags) { - return (flags == VLW_STANDARD || flags == VLW_SHARED_ORDERS || flags == VLW_STATION_LIST || flags == VLW_DEPOT_LIST); + return (flags == VLW_STANDARD || flags == VLW_SHARED_ORDERS || flags == VLW_STATION_LIST || flags == VLW_DEPOT_LIST || flags == VLW_GROUP_LIST); } void PlayerVehWndProc(Window *w, WindowEvent *e); @@ -41,7 +55,7 @@ void DrawShipImage(const Vehicle *v, int x, int y, VehicleID selection); void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection); -void ShowBuildVehicleWindow(TileIndex tile, byte type); +void ShowBuildVehicleWindow(TileIndex tile, VehicleType type); void ChangeVehicleViewWindow(const Vehicle *from_v, const Vehicle *to_v); @@ -49,11 +63,13 @@ uint ShowRefitOptionsList(int x, int y, uint w, EngineID engine); void ShowVehicleListWindow(const Vehicle *v); -void ShowVehicleListWindow(PlayerID player, byte vehicle_type); -void ShowVehicleListWindow(PlayerID player, byte vehicle_type, StationID station); -void ShowVehicleListWindow(PlayerID player, byte vehicle_type, TileIndex depot_tile); +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type); +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, StationID station); +void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type, TileIndex depot_tile); -void ShowReplaceVehicleWindow(byte vehicletype); +void ShowReplaceVehicleWindow(VehicleType vehicletype); +void DrawSmallOrderList(const Vehicle *v, int x, int y); +void ShowReplaceGroupVehicleWindow(GroupID group, VehicleType veh); static inline void DrawVehicleImage(const Vehicle *v, int x, int y, int count, int skip, VehicleID selection) { @@ -66,7 +82,7 @@ } } -static inline uint GetVehicleListHeight(byte type) +static inline uint GetVehicleListHeight(VehicleType type) { return (type == VEH_TRAIN || type == VEH_ROAD) ? 14 : 24; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/video/dedicated_v.cpp --- a/src/video/dedicated_v.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/video/dedicated_v.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -112,7 +112,7 @@ #endif -static void *_dedicated_video_mem; +static Pixel *_dedicated_video_mem; extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm); extern void SwitchMode(int new_mode); @@ -122,7 +122,7 @@ { _screen.width = _screen.pitch = _cur_resolution[0]; _screen.height = _cur_resolution[1]; - _dedicated_video_mem = malloc(_cur_resolution[0]*_cur_resolution[1]); + _dedicated_video_mem = (Pixel *)malloc(_cur_resolution[0] * _cur_resolution[1] * sizeof(Pixel)); SetDebugString("net=6"); @@ -283,7 +283,7 @@ next_tick = cur_ticks + 30; GameLoop(); - _screen.dst_ptr = (Pixel*)_dedicated_video_mem; + _screen.dst_ptr = _dedicated_video_mem; UpdateWindows(); } CSleep(1); diff -r 0b2aebc8283e -r 0b8b245a2391 src/video/null_v.cpp --- a/src/video/null_v.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/video/null_v.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -7,13 +7,13 @@ #include "../window.h" #include "null_v.h" -static void* _null_video_mem = NULL; +static Pixel *_null_video_mem = NULL; static const char* NullVideoStart(const char* const* parm) { _screen.width = _screen.pitch = _cur_resolution[0]; _screen.height = _cur_resolution[1]; - _null_video_mem = malloc(_cur_resolution[0] * _cur_resolution[1]); + _null_video_mem = (Pixel *)malloc(_cur_resolution[0] * _cur_resolution[1] * sizeof(Pixel)); return NULL; } @@ -27,7 +27,7 @@ for (i = 0; i < 1000; i++) { GameLoop(); - _screen.dst_ptr = (Pixel*)_null_video_mem; + _screen.dst_ptr = _null_video_mem; UpdateWindows(); } } diff -r 0b2aebc8283e -r 0b8b245a2391 src/video/sdl_v.cpp --- a/src/video/sdl_v.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/video/sdl_v.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -195,7 +195,7 @@ _screen.width = newscreen->w; _screen.height = newscreen->h; - _screen.pitch = newscreen->pitch; + _screen.pitch = newscreen->pitch / sizeof(Pixel); _sdl_screen = newscreen; InitPalette(); diff -r 0b2aebc8283e -r 0b8b245a2391 src/video/win32_v.cpp --- a/src/video/win32_v.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/video/win32_v.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -212,6 +212,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static uint32 keycode = 0; + static bool console = false; switch (msg) { case WM_CREATE: @@ -363,12 +364,23 @@ } #endif /* UNICODE */ + case WM_DEADCHAR: + console = GB(lParam, 16, 8) == 41; + return 0; + case WM_CHAR: { /* Silently drop all non-text messages as those were handled by WM_KEYDOWN */ if (wParam < VK_SPACE) return 0; uint scancode = GB(lParam, 16, 8); uint charcode = wParam; + /* If the console key is a dead-key, we need to press it twice to get a WM_CHAR message. + * But we then get two WM_CHAR messages, so ignore the first one */ + if (console && scancode == 41) { + console = false; + return 0; + } + #if !defined(UNICODE) wchar_t w; int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1); @@ -659,7 +671,7 @@ if (_wnd.double_size) { w = ALIGN(w, 4); - _wnd.alloced_bits = _wnd.buffer_bits = (Pixel*)malloc(w * h); + _wnd.alloced_bits = _wnd.buffer_bits = (Pixel *)malloc(w * h * sizeof(Pixel)); w *= 2; h *= 2; } diff -r 0b2aebc8283e -r 0b8b245a2391 src/viewport.cpp --- a/src/viewport.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/viewport.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -26,6 +26,8 @@ #define VIEWPORT_DRAW_MEM (65536 * 2) +ZoomLevel _saved_scrollpos_zoom; + /* XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) */ static ViewPort _viewports[25 - 2]; static uint32 _active_viewports; ///< bitmasked variable where each bit signifies if a viewport is in use or not @@ -143,7 +145,7 @@ } void AssignWindowViewport(Window *w, int x, int y, - int width, int height, uint32 follow_flags, byte zoom) + int width, int height, uint32 follow_flags, ZoomLevel zoom) { ViewPort *vp; Point pt; @@ -162,8 +164,8 @@ vp->zoom = zoom; - vp->virtual_width = width << zoom; - vp->virtual_height = height << zoom; + vp->virtual_width = ScaleByZoom(width, zoom); + vp->virtual_height = ScaleByZoom(height, zoom); if (follow_flags & 0x80000000) { const Vehicle *veh; @@ -267,10 +269,10 @@ vp->virtual_left = x; vp->virtual_top = y; - old_left >>= vp->zoom; - old_top >>= vp->zoom; - x >>= vp->zoom; - y >>= vp->zoom; + old_left = UnScaleByZoom(old_left, vp->zoom); + old_top = UnScaleByZoom(old_top, vp->zoom); + x = UnScaleByZoom(x, vp->zoom); + y = UnScaleByZoom(y, vp->zoom); old_left -= x; old_top -= y; @@ -331,8 +333,8 @@ return pt; } - x = ((x << vp->zoom) + vp->virtual_left) >> 2; - y = ((y << vp->zoom) + vp->virtual_top) >> 1; + x = (ScaleByZoom(x, vp->zoom) + vp->virtual_left) >> 2; + y = (ScaleByZoom(y, vp->zoom) + vp->virtual_top) >> 1; a = y-x; b = y+x; @@ -404,10 +406,10 @@ * @param widget_zoom_out widget index for window with zoom-out button */ void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out) { - SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == 0); + SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == ZOOM_LVL_MIN); InvalidateWidget(w, widget_zoom_in); - SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == 2); + SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == ZOOM_LVL_MAX); InvalidateWidget(w, widget_zoom_out); } @@ -669,7 +671,7 @@ z += TILE_HEIGHT; if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT; } - DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z); + DrawGroundSpriteAt(_cur_dpi->zoom <= ZOOM_LVL_DETAIL ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z); } else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) { /* autorail highlight piece under cursor */ uint type = _thd.drawstyle & 0xF; @@ -799,7 +801,7 @@ Town *t; int left, top, right, bottom; - if (!(_display_opt & DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU) + if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU) return; left = dpi->left; @@ -808,7 +810,7 @@ bottom = top + dpi->height; switch (dpi->zoom) { - case 0: + case ZOOM_LVL_NORMAL: FOR_ALL_TOWNS(t) { if (bottom > t->sign.top && top < t->sign.top + 12 && @@ -821,7 +823,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: right += 2; bottom += 2; @@ -837,21 +839,26 @@ } break; - default: NOT_REACHED(); - case 2: - right += 4; - bottom += 5; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + right += ScaleByZoom(1, dpi->zoom); + bottom += ScaleByZoom(1, dpi->zoom) + 1; FOR_ALL_TOWNS(t) { if (bottom > t->sign.top && - top < t->sign.top + 24 && + top < t->sign.top + ScaleByZoom(12, dpi->zoom) && right > t->sign.left && - left < t->sign.left + t->sign.width_2*4) { + left < t->sign.left + ScaleByZoom(t->sign.width_2, dpi->zoom)) { AddStringToDraw(t->sign.left + 5, t->sign.top + 1, STR_TOWN_LABEL_TINY_BLACK, t->index, 0); AddStringToDraw(t->sign.left + 1, t->sign.top - 3, STR_TOWN_LABEL_TINY_WHITE, t->index, 0); } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } } @@ -873,7 +880,7 @@ int left, top, right, bottom; const Station *st; - if (!(_display_opt & DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU) + if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU) return; left = dpi->left; @@ -882,7 +889,7 @@ bottom = top + dpi->height; switch (dpi->zoom) { - case 0: + case ZOOM_LVL_NORMAL: FOR_ALL_STATIONS(st) { if (bottom > st->sign.top && top < st->sign.top + 12 && @@ -893,7 +900,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: right += 2; bottom += 2; FOR_ALL_STATIONS(st) { @@ -906,19 +913,25 @@ } break; - default: NOT_REACHED(); - case 2: - right += 4; - bottom += 5; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + right += ScaleByZoom(1, dpi->zoom); + bottom += ScaleByZoom(1, dpi->zoom) + 1; + FOR_ALL_STATIONS(st) { if (bottom > st->sign.top && - top < st->sign.top + 24 && + top < st->sign.top + ScaleByZoom(12, dpi->zoom) && right > st->sign.left && - left < st->sign.left + st->sign.width_2*4) { + left < st->sign.left + ScaleByZoom(st->sign.width_2, dpi->zoom)) { AddStation(st, STR_STATION_SIGN_TINY, st->sign.width_2 | 0x8000); } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } } @@ -940,7 +953,7 @@ const Sign *si; int left, top, right, bottom; - if (!(_display_opt & DO_SHOW_SIGNS)) + if (!HASBIT(_display_opt, DO_SHOW_SIGNS)) return; left = dpi->left; @@ -949,7 +962,7 @@ bottom = top + dpi->height; switch (dpi->zoom) { - case 0: + case ZOOM_LVL_NORMAL: FOR_ALL_SIGNS(si) { if (bottom > si->sign.top && top < si->sign.top + 12 && @@ -960,7 +973,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: right += 2; bottom += 2; FOR_ALL_SIGNS(si) { @@ -973,19 +986,25 @@ } break; - default: NOT_REACHED(); - case 2: - right += 4; - bottom += 5; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + right += ScaleByZoom(1, dpi->zoom); + bottom += ScaleByZoom(1, dpi->zoom) + 1; + FOR_ALL_SIGNS(si) { if (bottom > si->sign.top && - top < si->sign.top + 24 && + top < si->sign.top + ScaleByZoom(12, dpi->zoom) && right > si->sign.left && - left < si->sign.left + si->sign.width_2 * 4) { + left < si->sign.left + ScaleByZoom(si->sign.width_2, dpi->zoom)) { AddSign(si, STR_2002, si->sign.width_2 | 0x8000); } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } } @@ -1007,7 +1026,7 @@ const Waypoint *wp; int left, top, right, bottom; - if (!(_display_opt & DO_WAYPOINTS)) + if (!HASBIT(_display_opt, DO_WAYPOINTS)) return; left = dpi->left; @@ -1016,7 +1035,7 @@ bottom = top + dpi->height; switch (dpi->zoom) { - case 0: + case ZOOM_LVL_NORMAL: FOR_ALL_WAYPOINTS(wp) { if (bottom > wp->sign.top && top < wp->sign.top + 12 && @@ -1027,7 +1046,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: right += 2; bottom += 2; FOR_ALL_WAYPOINTS(wp) { @@ -1040,19 +1059,25 @@ } break; - default: NOT_REACHED(); - case 2: - right += 4; - bottom += 5; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + right += ScaleByZoom(1, dpi->zoom); + bottom += ScaleByZoom(1, dpi->zoom) + 1; + FOR_ALL_WAYPOINTS(wp) { if (bottom > wp->sign.top && - top < wp->sign.top + 24 && + top < wp->sign.top + ScaleByZoom(12, dpi->zoom) && right > wp->sign.left && - left < wp->sign.left + wp->sign.width_2*4) { + left < wp->sign.left + ScaleByZoom(wp->sign.width_2, dpi->zoom)) { AddWaypoint(wp, STR_WAYPOINT_VIEWPORT_TINY, wp->sign.width_2 | 0x8000); } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } } @@ -1163,25 +1188,25 @@ static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss) { DrawPixelInfo dp; - byte zoom; + ZoomLevel zoom; _cur_dpi = &dp; dp = *dpi; zoom = dp.zoom; - dp.zoom = 0; - - dp.left >>= zoom; - dp.top >>= zoom; - dp.width >>= zoom; - dp.height >>= zoom; + dp.zoom = ZOOM_LVL_NORMAL; + + dp.left = UnScaleByZoom(dp.left, zoom); + dp.top = UnScaleByZoom(dp.top, zoom); + dp.width = UnScaleByZoom(dp.width, zoom); + dp.height = UnScaleByZoom(dp.height, zoom); do { uint16 colour; if (ss->width != 0) { - int x = (ss->x >> zoom) - 1; - int y = (ss->y >> zoom) - 1; + int x = UnScaleByZoom(ss->x, zoom) - 1; + int y = UnScaleByZoom(ss->y, zoom) - 1; int bottom = y + 11; int w = ss->width; @@ -1214,7 +1239,7 @@ colour = 16; } DrawString( - ss->x >> zoom, (ss->y >> zoom) - (ss->width & 0x8000 ? 2 : 0), + UnScaleByZoom(ss->x, zoom), UnScaleByZoom(ss->y, zoom) - (ss->width & 0x8000 ? 2 : 0), ss->string, colour ); @@ -1239,7 +1264,7 @@ _cur_dpi = &vd.dpi; vd.dpi.zoom = vp->zoom; - mask = (-1) << vp->zoom; + mask = ScaleByZoom(-1, vp->zoom); vd.combine_sprites = 0; @@ -1249,8 +1274,8 @@ vd.dpi.top = top & mask; vd.dpi.pitch = old_dpi->pitch; - x = ((vd.dpi.left - (vp->virtual_left&mask)) >> vp->zoom) + vp->left; - y = ((vd.dpi.top - (vp->virtual_top&mask)) >> vp->zoom) + vp->top; + x = UnScaleByZoom(vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; + y = UnScaleByZoom(vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; vd.dpi.dst_ptr = old_dpi->dst_ptr + x - old_dpi->left + (y - old_dpi->top) * old_dpi->pitch; @@ -1293,7 +1318,7 @@ * If we do, the sprite memory will overflow. */ static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom) { - if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) { + if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000) { if ((bottom - top) > (right - left)) { int t = (top + bottom) >> 1; ViewportDrawChk(vp, left, top, right, t); @@ -1305,10 +1330,10 @@ } } else { ViewportDoDraw(vp, - ((left - vp->left) << vp->zoom) + vp->virtual_left, - ((top - vp->top) << vp->zoom) + vp->virtual_top, - ((right - vp->left) << vp->zoom) + vp->virtual_left, - ((bottom - vp->top) << vp->zoom) + vp->virtual_top + ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left, + ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top, + ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left, + ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top ); } } @@ -1396,10 +1421,10 @@ if (top >= vp->virtual_height) return; SetDirtyBlocks( - (left >> vp->zoom) + vp->left, - (top >> vp->zoom) + vp->top, - (right >> vp->zoom) + vp->left, - (bottom >> vp->zoom) + vp->top + UnScaleByZoom(left, vp->zoom) + vp->left, + UnScaleByZoom(top, vp->zoom) + vp->top, + UnScaleByZoom(right, vp->zoom) + vp->left, + UnScaleByZoom(bottom, vp->zoom) + vp->top ); } @@ -1487,10 +1512,10 @@ { const Town *t; - if (!(_display_opt & DO_SHOW_TOWN_NAMES)) return false; + if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES)) return false; switch (vp->zoom) { - case 0: + case ZOOM_LVL_NORMAL: x = x - vp->left + vp->virtual_left; y = y - vp->top + vp->virtual_top; FOR_ALL_TOWNS(t) { @@ -1504,7 +1529,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: x = (x - vp->left + 1) * 2 + vp->virtual_left; y = (y - vp->top + 1) * 2 + vp->virtual_top; FOR_ALL_TOWNS(t) { @@ -1518,19 +1543,26 @@ } break; - default: - x = (x - vp->left + 3) * 4 + vp->virtual_left; - y = (y - vp->top + 3) * 4 + vp->virtual_top; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; + FOR_ALL_TOWNS(t) { if (y >= t->sign.top && - y < t->sign.top + 24 && + y < t->sign.top + ScaleByZoom(12, vp->zoom) && x >= t->sign.left && - x < t->sign.left + t->sign.width_2 * 4) { + x < t->sign.left + ScaleByZoom(t->sign.width_2, vp->zoom)) { ShowTownViewWindow(t->index); return true; } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } return false; @@ -1541,10 +1573,10 @@ { const Station *st; - if (!(_display_opt & DO_SHOW_STATION_NAMES)) return false; + if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES)) return false; switch (vp->zoom) { - case 0: + case ZOOM_LVL_NORMAL: x = x - vp->left + vp->virtual_left; y = y - vp->top + vp->virtual_top; FOR_ALL_STATIONS(st) { @@ -1558,7 +1590,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: x = (x - vp->left + 1) * 2 + vp->virtual_left; y = (y - vp->top + 1) * 2 + vp->virtual_top; FOR_ALL_STATIONS(st) { @@ -1572,19 +1604,26 @@ } break; - default: - x = (x - vp->left + 3) * 4 + vp->virtual_left; - y = (y - vp->top + 3) * 4 + vp->virtual_top; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; + FOR_ALL_STATIONS(st) { if (y >= st->sign.top && - y < st->sign.top + 24 && + y < st->sign.top + ScaleByZoom(12, vp->zoom) && x >= st->sign.left && - x < st->sign.left + st->sign.width_2 * 4) { + x < st->sign.left + ScaleByZoom(st->sign.width_2, vp->zoom)) { ShowStationViewWindow(st->index); return true; } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } return false; @@ -1595,10 +1634,10 @@ { const Sign *si; - if (!(_display_opt & DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false; + if (!HASBIT(_display_opt, DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false; switch (vp->zoom) { - case 0: + case ZOOM_LVL_NORMAL: x = x - vp->left + vp->virtual_left; y = y - vp->top + vp->virtual_top; FOR_ALL_SIGNS(si) { @@ -1612,7 +1651,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: x = (x - vp->left + 1) * 2 + vp->virtual_left; y = (y - vp->top + 1) * 2 + vp->virtual_top; FOR_ALL_SIGNS(si) { @@ -1626,19 +1665,26 @@ } break; - default: - x = (x - vp->left + 3) * 4 + vp->virtual_left; - y = (y - vp->top + 3) * 4 + vp->virtual_top; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; + FOR_ALL_SIGNS(si) { if (y >= si->sign.top && - y < si->sign.top + 24 && + y < si->sign.top + ScaleByZoom(12, vp->zoom) && x >= si->sign.left && - x < si->sign.left + si->sign.width_2 * 4) { + x < si->sign.left + ScaleByZoom(si->sign.width_2, vp->zoom)) { ShowRenameSignWindow(si); return true; } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } return false; @@ -1649,10 +1695,10 @@ { const Waypoint *wp; - if (!(_display_opt & DO_WAYPOINTS)) return false; + if (!HASBIT(_display_opt, DO_WAYPOINTS)) return false; switch (vp->zoom) { - case 0: + case ZOOM_LVL_NORMAL: x = x - vp->left + vp->virtual_left; y = y - vp->top + vp->virtual_top; FOR_ALL_WAYPOINTS(wp) { @@ -1666,7 +1712,7 @@ } break; - case 1: + case ZOOM_LVL_OUT_2X: x = (x - vp->left + 1) * 2 + vp->virtual_left; y = (y - vp->top + 1) * 2 + vp->virtual_top; FOR_ALL_WAYPOINTS(wp) { @@ -1680,19 +1726,26 @@ } break; - default: - x = (x - vp->left + 3) * 4 + vp->virtual_left; - y = (y - vp->top + 3) * 4 + vp->virtual_top; + case ZOOM_LVL_OUT_4X: + case ZOOM_LVL_OUT_8X: + x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; + FOR_ALL_WAYPOINTS(wp) { if (y >= wp->sign.top && - y < wp->sign.top + 24 && + y < wp->sign.top + ScaleByZoom(12, vp->zoom) && x >= wp->sign.left && - x < wp->sign.left + wp->sign.width_2 * 4) { + x < wp->sign.left + ScaleByZoom(wp->sign.width_2, vp->zoom)) { ShowRenameWaypointWindow(wp); return true; } } break; + + case ZOOM_LVL_OUT_16X: + break; + + default: NOT_REACHED(); } return false; @@ -1932,9 +1985,10 @@ } /** highlighting tiles while only going over them with the mouse */ -void VpStartPlaceSizing(TileIndex tile, int user) +void VpStartPlaceSizing(TileIndex tile, byte method, byte process) { - _thd.userdata = user; + _thd.select_method = method; + _thd.select_proc = process; _thd.selend.x = TileX(tile) * TILE_SIZE; _thd.selstart.x = TileX(tile) * TILE_SIZE; _thd.selend.y = TileY(tile) * TILE_SIZE; @@ -2392,7 +2446,8 @@ if (_special_mouse_mode != WSM_SIZING) return true; - e.we.place.userdata = _thd.userdata; + e.we.place.select_method = _thd.select_method; + e.we.place.select_proc = _thd.select_proc; /* stop drag mode if the window has been closed */ w = FindWindowById(_thd.window_class, _thd.window_number); @@ -2414,7 +2469,7 @@ _special_mouse_mode = WSM_NONE; if (_thd.next_drawstyle == HT_RECT) { _thd.place_mode = VHM_RECT; - } else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik + } else if (e.we.place.select_method == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik _thd.place_mode = VHM_RECT; } else if (_thd.next_drawstyle & HT_LINE) { _thd.place_mode = VHM_RAIL; diff -r 0b2aebc8283e -r 0b8b245a2391 src/viewport.h --- a/src/viewport.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/viewport.h Wed Jun 13 11:45:14 2007 +0000 @@ -5,6 +5,8 @@ #ifndef VIEWPORT_H #define VIEWPORT_H +#include "zoom.hpp" + struct ViewPort { int left,top; // screen coordinates for the viewport int width, height; // screen width/height for the viewport @@ -12,7 +14,7 @@ int virtual_left, virtual_top; // virtual coordinates int virtual_width, virtual_height; // these are just width << zoom, height << zoom - byte zoom; + ZoomLevel zoom; }; void SetSelectionRed(bool); @@ -21,7 +23,7 @@ void InitViewports(); void DeleteWindowViewport(Window *w); void AssignWindowViewport(Window *w, int x, int y, - int width, int height, uint32 follow_flags, byte zoom); + int width, int height, uint32 follow_flags, ZoomLevel zoom); ViewPort *IsPtInWindowViewport(const Window *w, int x, int y); Point GetTileBelowCursor(); void UpdateViewportPosition(Window *w); @@ -60,7 +62,7 @@ void SetTileSelectSize(int w, int h); void SetTileSelectBigSize(int ox, int oy, int sx, int sy); -void VpStartPlaceSizing(TileIndex tile, int user); +void VpStartPlaceSizing(TileIndex tile, byte method, byte process); void VpSetPresizeRange(uint from, uint to); void VpSetPlaceSizingLimit(int limit); @@ -135,7 +137,9 @@ WindowClass window_class; WindowNumber window_number; - int userdata; + byte select_method; + byte select_proc; + TileIndex redsq; }; diff -r 0b2aebc8283e -r 0b8b245a2391 src/water_cmd.cpp --- a/src/water_cmd.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/water_cmd.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -25,6 +25,7 @@ #include "train.h" #include "water_map.h" #include "newgrf.h" +#include "newgrf_canal.h" static const SpriteID _water_shore_sprites[] = { 0, @@ -373,39 +374,43 @@ { uint wa; + /* Test for custom graphics, else use the default */ + SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile); + if (dikes_base == 0) dikes_base = SPR_CANALS_BASE + 57; + /* determine the edges around with water. */ wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0; wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1; wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2; wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3; - if (!(wa & 1)) DrawGroundSprite(SPR_CANALS_BASE + 57, PAL_NONE); - if (!(wa & 2)) DrawGroundSprite(SPR_CANALS_BASE + 58, PAL_NONE); - if (!(wa & 4)) DrawGroundSprite(SPR_CANALS_BASE + 59, PAL_NONE); - if (!(wa & 8)) DrawGroundSprite(SPR_CANALS_BASE + 60, PAL_NONE); + if (!(wa & 1)) DrawGroundSprite(dikes_base, PAL_NONE); + if (!(wa & 2)) DrawGroundSprite(dikes_base + 1, PAL_NONE); + if (!(wa & 4)) DrawGroundSprite(dikes_base + 2, PAL_NONE); + if (!(wa & 8)) DrawGroundSprite(dikes_base + 3, PAL_NONE); /* right corner */ switch (wa & 0x03) { - case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 4, PAL_NONE); break; - case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 8, PAL_NONE); break; + case 0: DrawGroundSprite(dikes_base + 4, PAL_NONE); break; + case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(dikes_base + 8, PAL_NONE); break; } /* bottom corner */ switch (wa & 0x06) { - case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 5, PAL_NONE); break; - case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 9, PAL_NONE); break; + case 0: DrawGroundSprite(dikes_base + 5, PAL_NONE); break; + case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(dikes_base + 9, PAL_NONE); break; } /* left corner */ switch (wa & 0x0C) { - case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 6, PAL_NONE); break; - case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 10, PAL_NONE); break; + case 0: DrawGroundSprite(dikes_base + 6, PAL_NONE); break; + case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(dikes_base + 10, PAL_NONE); break; } /* upper corner */ switch (wa & 0x09) { - case 0: DrawGroundSprite(SPR_CANALS_BASE + 57 + 7, PAL_NONE); break; - case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(SPR_CANALS_BASE + 57 + 11, PAL_NONE); break; + case 0: DrawGroundSprite(dikes_base + 7, PAL_NONE); break; + case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(dikes_base + 11, PAL_NONE); break; } } @@ -421,12 +426,30 @@ SpriteID palette, uint base ) { - DrawGroundSprite(wdts++->image, PAL_NONE); + SpriteID image; + SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile); + SpriteID locks_base = GetCanalSprite(CF_LOCKS, ti->tile); + + /* If no custom graphics, use defaults */ + if (water_base == 0) water_base = SPR_CANALS_BASE + 5; + if (locks_base == 0) { + locks_base = SPR_CANALS_BASE + 9; + } else { + /* If using custom graphics, ignore the variation on height */ + base = 0; + } + + image = wdts++->image; + if (image < 4) image += water_base; + DrawGroundSprite(image, PAL_NONE); for (; wdts->delta_x != 0x80; wdts++) { - SpriteID image = wdts->image + base; + SpriteID image = wdts->image; SpriteID pal; + if (image < 24) image += locks_base; + image += base; + if (HASBIT(_transparent_opt, TO_BUILDINGS)) { SETBIT(image, PALETTE_MODIFIER_TRANSPARENT); pal = PALETTE_TO_TRANSPARENT; diff -r 0b2aebc8283e -r 0b8b245a2391 src/win32.cpp --- a/src/win32.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/win32.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -890,6 +890,9 @@ #endif /* UNICODE */ #if defined(UNICODE) + /* Check if a win9x user started the win32 version */ + if (HASBIT(GetVersion(), 31)) error("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again."); + /* For UNICODE we need to convert the commandline to char* _AND_ * save it because argv[] points into this buffer and thus needs to * be available between subsequent calls to FS2OTTD() */ diff -r 0b2aebc8283e -r 0b8b245a2391 src/window.cpp --- a/src/window.cpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/window.cpp Wed Jun 13 11:45:14 2007 +0000 @@ -271,7 +271,7 @@ dp->top = top - (*wz)->top; dp->pitch = _screen.pitch; dp->dst_ptr = _screen.dst_ptr + top * _screen.pitch + left; - dp->zoom = 0; + dp->zoom = ZOOM_LVL_NORMAL; CallWindowEventNP(*wz, WE_PAINT); } } @@ -682,17 +682,12 @@ }; -static SizeRect _awap_r; - -static bool IsGoodAutoPlace1(int left, int top) +static bool IsGoodAutoPlace1(int left, int top, int width, int height, Point &pos) { - int right,bottom; Window* const *wz; - _awap_r.left= left; - _awap_r.top = top; - right = _awap_r.width + left; - bottom = _awap_r.height + top; + int right = width + left; + int bottom = height + top; if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height) return false; @@ -710,19 +705,15 @@ } } + pos.x = left; + pos.y = top; return true; } -static bool IsGoodAutoPlace2(int left, int top) +static bool IsGoodAutoPlace2(int left, int top, int width, int height, Point &pos) { - int width,height; Window* const *wz; - _awap_r.left= left; - _awap_r.top = top; - width = _awap_r.width; - height = _awap_r.height; - if (left < -(width>>2) || left > _screen.width - (width>>1)) return false; if (top < 22 || top > _screen.height - (height>>2)) return false; @@ -739,6 +730,8 @@ } } + pos.x = left; + pos.y = top; return true; } @@ -747,39 +740,36 @@ Window* const *wz; Point pt; - _awap_r.width = width; - _awap_r.height = height; - - if (IsGoodAutoPlace1(0, 24)) goto ok_pos; + if (IsGoodAutoPlace1(0, 24, width, height, pt)) return pt; FOR_ALL_WINDOWS(wz) { const Window *w = *wz; if (w->window_class == WC_MAIN_WINDOW) continue; - if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos; - if (IsGoodAutoPlace1(w->left- width-2,w->top)) goto ok_pos; - if (IsGoodAutoPlace1(w->left,w->top+w->height+2)) goto ok_pos; - if (IsGoodAutoPlace1(w->left,w->top- height-2)) goto ok_pos; - if (IsGoodAutoPlace1(w->left+w->width+2,w->top+w->height-height)) goto ok_pos; - if (IsGoodAutoPlace1(w->left- width-2,w->top+w->height-height)) goto ok_pos; - if (IsGoodAutoPlace1(w->left+w->width-width,w->top+w->height+2)) goto ok_pos; - if (IsGoodAutoPlace1(w->left+w->width-width,w->top- height-2)) goto ok_pos; + if (IsGoodAutoPlace1(w->left + w->width + 2, w->top, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left - width - 2, w->top, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left, w->top + w->height + 2, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left, w->top - height - 2, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left + w->width + 2, w->top + w->height - height, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left - width - 2, w->top + w->height - height, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left + w->width - width, w->top + w->height + 2, width, height, pt)) return pt; + if (IsGoodAutoPlace1(w->left + w->width - width, w->top - height - 2, width, height, pt)) return pt; } FOR_ALL_WINDOWS(wz) { const Window *w = *wz; if (w->window_class == WC_MAIN_WINDOW) continue; - if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos; - if (IsGoodAutoPlace2(w->left- width-2,w->top)) goto ok_pos; - if (IsGoodAutoPlace2(w->left,w->top+w->height+2)) goto ok_pos; - if (IsGoodAutoPlace2(w->left,w->top- height-2)) goto ok_pos; + if (IsGoodAutoPlace2(w->left + w->width + 2, w->top, width, height, pt)) return pt; + if (IsGoodAutoPlace2(w->left - width - 2, w->top, width, height, pt)) return pt; + if (IsGoodAutoPlace2(w->left, w->top + w->height + 2, width, height, pt)) return pt; + if (IsGoodAutoPlace2(w->left, w->top - height - 2, width, height, pt)) return pt; } { - int left=0,top=24; + int left = 0, top = 24; -restart:; +restart: FOR_ALL_WINDOWS(wz) { const Window *w = *wz; @@ -794,11 +784,6 @@ pt.y = top; return pt; } - -ok_pos:; - pt.x = _awap_r.left; - pt.y = _awap_r.top; - return pt; } static Window *LocalAllocateWindowDesc(const WindowDesc *desc, int window_number) @@ -1633,14 +1618,14 @@ /* here allows scrolling in both x and y axis */ #define scrollspeed 3 if (x - 15 < 0) { - WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom; + WP(w, vp_d).scrollpos_x += ScaleByZoom((x - 15) * scrollspeed, vp->zoom); } else if (15 - (vp->width - x) > 0) { - WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom; + WP(w, vp_d).scrollpos_x += ScaleByZoom((15 - (vp->width - x)) * scrollspeed, vp->zoom); } if (y - 15 < 0) { - WP(w, vp_d).scrollpos_y += (y - 15) * scrollspeed << vp->zoom; + WP(w, vp_d).scrollpos_y += ScaleByZoom((y - 15) * scrollspeed, vp->zoom); } else if (15 - (vp->height - y) > 0) { - WP(w,vp_d).scrollpos_y += (15 - (vp->height - y)) * scrollspeed << vp->zoom; + WP(w,vp_d).scrollpos_y += ScaleByZoom((15 - (vp->height - y)) * scrollspeed, vp->zoom); } #undef scrollspeed } @@ -1985,8 +1970,8 @@ ViewPort *vp = w->viewport; vp->width = w->width = neww; vp->height = w->height = newh; - vp->virtual_width = neww << vp->zoom; - vp->virtual_height = newh << vp->zoom; + vp->virtual_width = ScaleByZoom(neww, vp->zoom); + vp->virtual_height = ScaleByZoom(newh, vp->zoom); continue; // don't modify top,left } diff -r 0b2aebc8283e -r 0b8b245a2391 src/window.h --- a/src/window.h Wed Jun 13 11:17:30 2007 +0000 +++ b/src/window.h Wed Jun 13 11:45:14 2007 +0000 @@ -9,7 +9,9 @@ #include "string.h" #include "order.h" #include "rail.h" +#include "road.h" #include "airport.h" +#include "vehicle.h" struct WindowEvent; @@ -133,7 +135,8 @@ Point pt; TileIndex tile; TileIndex starttile; - int userdata; + byte select_method; + byte select_proc; } place; struct { @@ -280,6 +283,11 @@ }; assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d)); +struct chatquerystr_d : public querystr_d { + int dest; +}; +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(chatquerystr_d)); + struct menu_d { byte item_count; ///< follow_vehicle byte sel_index; ///< scrollpos_x @@ -318,10 +326,11 @@ assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d)); struct buildvehicle_d { - byte vehicle_type; + VehicleType vehicle_type; union { RailTypeByte railtype; AirportFTAClass::Flags flags; + RoadTypes roadtypes; } filter; byte sel_index; ///< deprecated value, used for 'unified' ship and road bool descending_sort_order; @@ -342,12 +351,13 @@ bool update_left; bool update_right; bool init_lists; + GroupID sel_group; }; assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d)); struct depot_d { VehicleID sel; - byte type; + VehicleType type; bool generate_list; uint16 engine_list_length; uint16 wagon_list_length; @@ -472,6 +482,28 @@ }; assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(dropdown_d)); +struct vehiclelist_d { + const Vehicle** sort_list; // List of vehicles (sorted) + Listing *_sorting; // pointer to the appropiate subcategory of _sorting + uint16 length_of_sort_list; // Keeps track of how many vehicle pointers sort list got space for + VehicleType vehicle_type; // The vehicle type that is sorted + list_d l; // General list struct +}; +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d)); + +struct grouplist_d { + const Group **sort_list; + list_d l; // General list struct +}; +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(grouplist_d)); + +struct groupveh_d : vehiclelist_d { + GroupID group_sel; + VehicleID vehicle_sel; + + grouplist_d gl; +}; +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(groupveh_d)); /****************** THESE ARE NOT WIDGET TYPES!!!!! *******************/ enum WindowWidgetBehaviours { diff -r 0b2aebc8283e -r 0b8b245a2391 src/yapf/yapf.hpp --- a/src/yapf/yapf.hpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/yapf/yapf.hpp Wed Jun 13 11:45:14 2007 +0000 @@ -7,6 +7,7 @@ #include "track_dir.hpp" +#include "../vehicle.h" #include "../depot.h" #include "../road_map.h" #include "../tunnel_map.h" @@ -14,7 +15,6 @@ #include "../bridge.h" #include "../station.h" #include "../station_map.h" -#include "../vehicle.h" #include "../date.h" #include "../functions.h" #include "../landscape.h" diff -r 0b2aebc8283e -r 0b8b245a2391 src/yapf/yapf_destrail.hpp --- a/src/yapf/yapf_destrail.hpp Wed Jun 13 11:17:30 2007 +0000 +++ b/src/yapf/yapf_destrail.hpp Wed Jun 13 11:45:14 2007 +0000 @@ -86,14 +86,35 @@ public: void SetDestination(Vehicle* v) { - if (v->current_order.type == OT_GOTO_STATION) { - m_destTile = CalcStationCenterTile(v->current_order.dest); - m_dest_station_id = v->current_order.dest; - m_destTrackdirs = INVALID_TRACKDIR_BIT; - } else { - m_destTile = v->dest_tile; - m_dest_station_id = INVALID_STATION; - m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK); + switch (v->current_order.type) { + case OT_GOTO_STATION: + m_destTile = CalcStationCenterTile(v->current_order.dest); + m_dest_station_id = v->current_order.dest; + m_destTrackdirs = INVALID_TRACKDIR_BIT; + break; + + case OT_GOTO_WAYPOINT: { + Waypoint *wp = GetWaypoint(v->current_order.dest); + if (wp == NULL) { + /* Invalid waypoint in orders! */ + DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, player %d)", v->current_order.dest, v->unitnumber, (PlayerID)v->owner); + break; + } + m_destTile = wp->xy; + if (m_destTile != v->dest_tile) { + /* Something is wrong with orders! */ + DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, player %d)", v->dest_tile, v->unitnumber, (PlayerID)v->owner); + } + m_dest_station_id = INVALID_STATION; + m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy))); + break; + } + + default: + m_destTile = v->dest_tile; + m_dest_station_id = INVALID_STATION; + m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK); + break; } CYapfDestinationRailBase::SetDestination(v); } diff -r 0b2aebc8283e -r 0b8b245a2391 src/zoom.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/zoom.hpp Wed Jun 13 11:45:14 2007 +0000 @@ -0,0 +1,50 @@ +/* $Id$ */ + +/** @file zoom.hpp */ + +#ifndef ZOOM_HPP +#define ZOOM_HPP + +enum ZoomLevel { + /* Our possible zoom-levels */ + ZOOM_LVL_NORMAL = 0, + ZOOM_LVL_OUT_2X, + ZOOM_LVL_OUT_4X, + ZOOM_LVL_OUT_8X, + ZOOM_LVL_OUT_16X, + ZOOM_LVL_END, + + /* Here we define in which zoom viewports are */ + ZOOM_LVL_VIEWPORT = ZOOM_LVL_NORMAL, + ZOOM_LVL_NEWS = ZOOM_LVL_NORMAL, + ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_2X, + ZOOM_LVL_TOWN = ZOOM_LVL_OUT_2X, + ZOOM_LVL_AIRCRAFT = ZOOM_LVL_NORMAL, + ZOOM_LVL_SHIP = ZOOM_LVL_NORMAL, + ZOOM_LVL_TRAIN = ZOOM_LVL_NORMAL, + ZOOM_LVL_ROADVEH = ZOOM_LVL_NORMAL, + ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_NORMAL, + + ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_2X, //! All zoomlevels below or equal to this, will result in details on the screen, like road-work, ... + + ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, + ZOOM_LVL_MAX = ZOOM_LVL_OUT_16X, +}; + +extern ZoomLevel _saved_scrollpos_zoom; + +static inline int ScaleByZoom(int value, ZoomLevel zoom) +{ + if (zoom == ZOOM_LVL_NORMAL) return value; + int izoom = (int)zoom - (int)ZOOM_LVL_NORMAL; + return (zoom > ZOOM_LVL_NORMAL) ? value << izoom : value >> izoom; +} + +static inline int UnScaleByZoom(int value, ZoomLevel zoom) +{ + if (zoom == ZOOM_LVL_NORMAL) return value; + int izoom = (int)zoom - (int)ZOOM_LVL_NORMAL; + return (zoom > ZOOM_LVL_NORMAL) ? value >> izoom : value << izoom; +} + +#endif /* ZOOM_HPP */