From 962d418d5baa917908598190ee90b91b21e88532 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 17 Oct 2012 18:59:28 +0000 Subject: [PATCH] (svn r24604) [1.2] -Backport from trunk: - Fix: Do not show profit from refits as cost in the refit window [FS#5297] (r24544) - Fix: Do not limit to reading one UDP packet per game loop (r24532) - Fix: Max script chance was too big (r24531) - Fix: [NewGRF] RandomAction 84 should interpret register 100 as signed (r24528) --- src/lang/english.txt | 6 ++++-- src/network/core/udp.cpp | 23 +++++++++++++---------- src/newgrf_engine.cpp | 12 ++++++++---- src/script/api/script_base.cpp | 4 +++- src/script/api/script_base.hpp | 1 + src/vehicle_base.h | 16 ++++++++++++++++ src/vehicle_gui.cpp | 19 +++++++++++++++---- 7 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 2377c6d390..16e7013ca5 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3262,8 +3262,10 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Capacity # Vehicle refit STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Refit) STR_REFIT_TITLE :{GOLD}Select cargo type to carry: -STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {GOLD}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {GOLD}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Dragging with the mouse allows to select multiple vehicles. Clicking on an empty space will select the whole vehicle. Ctrl+Click will select a vehicle and the following chain STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 4a0029eedc..4c74af3f63 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -117,18 +117,21 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a void NetworkUDPSocketHandler::ReceivePackets() { for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) { - struct sockaddr_storage client_addr; - memset(&client_addr, 0, sizeof(client_addr)); + for (int i = 0; i < 1000; i++) { // Do not infinitely loop when DoSing with UDP + struct sockaddr_storage client_addr; + memset(&client_addr, 0, sizeof(client_addr)); - Packet p(this); - socklen_t client_len = sizeof(client_addr); + Packet p(this); + socklen_t client_len = sizeof(client_addr); - /* Try to receive anything */ - SetNonBlocking(s->second); // Some OSes seem to lose the non-blocking status of the socket - int nbytes = recvfrom(s->second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len); + /* Try to receive anything */ + SetNonBlocking(s->second); // Some OSes seem to lose the non-blocking status of the socket + int nbytes = recvfrom(s->second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len); + + /* Did we get the bytes for the base header of the packet? */ + if (nbytes <= 0) break; // No data, i.e. no packet + if (nbytes <= 2) continue; // Invalid data; try next packet - /* We got some bytes for the base header of the packet. */ - if (nbytes > 2) { NetworkAddress address(client_addr, client_len); p.PrepareToRead(); @@ -136,7 +139,7 @@ void NetworkUDPSocketHandler::ReceivePackets() * Otherwise it will be marked as corrupted later on. */ if (nbytes != p.size) { DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString()); - return; + continue; } /* Handle the packet */ diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 893fc56570..66259464a1 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -349,12 +349,19 @@ static inline const Vehicle *GRV(const ResolverObject *object) case VSG_SCOPE_PARENT: return object->u.vehicle.parent; case VSG_SCOPE_RELATIVE: { if (object->u.vehicle.self == NULL) return NULL; + + int32 count = GB(object->count, 0, 4); + if (count == 0) count = GetRegister(0x100); + const Vehicle *v = NULL; switch (GB(object->count, 6, 2)) { default: NOT_REACHED(); case 0x00: // count back (away from the engine), starting at this vehicle + v = object->u.vehicle.self; + break; case 0x01: // count forward (toward the engine), starting at this vehicle v = object->u.vehicle.self; + count = -count; break; case 0x02: // count back, starting at the engine v = object->u.vehicle.parent; @@ -372,10 +379,7 @@ static inline const Vehicle *GRV(const ResolverObject *object) break; } } - uint32 count = GB(object->count, 0, 4); - if (count == 0) count = GetRegister(0x100); - while (v != NULL && count-- != 0) v = (GB(object->count, 6, 2) == 0x01) ? v->Previous() : v->Next(); - return v; + return v->Move(count); } } } diff --git a/src/script/api/script_base.cpp b/src/script/api/script_base.cpp index 5be6dd9a56..2472fe1c77 100644 --- a/src/script/api/script_base.cpp +++ b/src/script/api/script_base.cpp @@ -11,6 +11,7 @@ #include "../../stdafx.h" #include "script_base.hpp" +#include "script_error.hpp" #include "../../network/network.h" #include "../../core/random_func.hpp" @@ -42,7 +43,8 @@ /* static */ bool ScriptBase::Chance(uint out, uint max) { - return (uint16)Rand() <= (uint16)((65536 * out) / max); + EnforcePrecondition(false, out <= max); + return (uint16)Rand() <= (uint16)((65535 * out) / max); } /* static */ bool ScriptBase::ChanceItem(int unused_param, uint out, uint max) diff --git a/src/script/api/script_base.hpp b/src/script/api/script_base.hpp index 9384cbf80b..a01325820f 100644 --- a/src/script/api/script_base.hpp +++ b/src/script/api/script_base.hpp @@ -59,6 +59,7 @@ public: * After all, it is a random function. * @param out How many times it should return true. * @param max Out of this many times. + * @pre \a out is at most equal to \a max. * @return True if the chance worked out. */ static bool Chance(uint out, uint max); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index b3cb466b7d..89eb83a17a 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -538,6 +538,22 @@ public: return v; } + /** + * Get the vehicle at offset \a n of this vehicle chain. + * @param n Offset from the current vehicle. + * @return The new vehicle or NULL if the offset is out-of-bounds. + */ + inline const Vehicle *Move(int n) const + { + const Vehicle *v = this; + if (n < 0) { + for (int i = 0; i != n && v != NULL; i--) v = v->Previous(); + } else { + for (int i = 0; i != n && v != NULL; i++) v = v->Next(); + } + return v; + } + /** * Get the first order of the vehicles order list. * @return first order of order list. diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index be36c01693..980bfa3275 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -600,14 +600,25 @@ struct RefitWindow : public Window { SetDParam(0, option->cargo); SetDParam(1, _returned_refit_capacity); + Money money = cost.GetCost(); if (_returned_mail_refit_capacity > 0) { SetDParam(2, CT_MAIL); SetDParam(3, _returned_mail_refit_capacity); - SetDParam(4, cost.GetCost()); - return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT; + if (money <= 0) { + SetDParam(4, -money); + return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT; + } else { + SetDParam(4, money); + return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT; + } } else { - SetDParam(2, cost.GetCost()); - return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT; + if (money <= 0) { + SetDParam(2, -money); + return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT; + } else { + SetDParam(2, money); + return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT; + } } }