summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/newgrf.cpp107
1 files changed, 59 insertions, 48 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 2e4e01eb8..d64449fea 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -128,6 +128,9 @@ static uint16 cargo_disallowed[TOTAL_NUM_ENGINES];
/* Contains the GRF ID of the owner of a vehicle if it has been reserved */
static uint32 _grm_engines[TOTAL_NUM_ENGINES];
+/* Contains the GRF ID of the owner of a cargo if it has been reserved */
+static uint32 _grm_cargos[NUM_CARGO];
+
/** DEBUG() function dedicated to newGRF debugging messages
* Function is essentialy the same as DEBUG(grf, severity, ...) with the
* addition of file:line information when parsing grf files.
@@ -3541,6 +3544,54 @@ static uint32 GetPatchVariable(uint8 param)
}
+static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
+{
+ uint start = 0;
+ uint size = 0;
+
+ if (op == 6) {
+ /* Return GRFID of set that reserved ID */
+ return grm[_cur_grffile->param[target]];
+ }
+
+ /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
+ if (op == 2 || op == 3) start = _cur_grffile->param[target];
+
+ for (uint i = start; i < num_ids; i++) {
+ if (grm[i] == 0) {
+ size++;
+ } else {
+ if (op == 2 || op == 3) break;
+ start = i + 1;
+ size = 0;
+ }
+
+ if (size == count) break;
+ }
+
+ if (size == count) {
+ /* Got the slot... */
+ if (op == 0 || op == 3) {
+ grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
+ for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
+ }
+ return start;
+ }
+
+ /* Unable to allocate */
+ if (op != 4 && op != 5) {
+ /* Deactivate GRF */
+ grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
+ _cur_grfconfig->status = GCS_DISABLED;
+ _skip_sprites = -1;
+ return UINT_MAX;
+ }
+
+ grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
+ return UINT_MAX;
+}
+
+
/* Action 0x0D */
static void ParamSet(byte *buf, int len)
{
@@ -3611,55 +3662,9 @@ static void ParamSet(byte *buf, int len)
case 0x01: // Road Vehicles
case 0x02: // Ships
case 0x03: // Aircraft
- {
- uint start = 0;
- uint size = 0;
- uint shift = _vehshifts[feature];
-
- if (op == 6) {
- /* Return GRFID of set that reserved ID */
- src1 = _grm_engines[shift + _cur_grffile->param[target]];
- break;
- }
-
- /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
- if (op == 2 || op == 3) start = _cur_grffile->param[target];
-
- for (uint i = start; i < _vehcounts[feature]; i++) {
- if (_grm_engines[shift + i] == 0) {
- size++;
- } else {
- if (op == 2 || op == 3) break;
- start = i + 1;
- size = 0;
- }
-
- if (size == count) break;
- }
-
- if (size == count) {
- /* Got the slot... */
- if (op == 0 || op == 3) {
- grfmsg(2, "ParamSet: GRM: Reserving %d vehicles at %d", count, start);
- for (uint i = 0; i < count; i++) _grm_engines[shift + start + i] = _cur_grffile->grfid;
- }
- src1 = start;
- } else {
- /* Unable to allocate */
- if (op != 4 && op != 5) {
- /* Deactivate GRF */
- grfmsg(0, "ParamSet: GRM: Unable to allocate %d vehicles, deactivating", count);
- _cur_grfconfig->status = GCS_DISABLED;
-
- _skip_sprites = -1;
- return;
- }
-
- grfmsg(1, "ParamSet: GRM: Unable to allocate %d vehicles", count);
- src1 = UINT_MAX;
- }
+ src1 = PerformGRM(&_grm_engines[_vehshifts[feature]], _vehcounts[feature], count, op, target, "vehicles");
+ if (_skip_sprites == -1) return;
break;
- }
case 0x08: // General sprites
switch (op) {
@@ -3688,6 +3693,11 @@ static void ParamSet(byte *buf, int len)
}
break;
+ case 0x0B: // Cargo
+ src1 = PerformGRM(_grm_cargos, NUM_CARGO, count, op, target, "cargos");
+ if (_skip_sprites == -1) return;
+ break;
+
default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
}
}
@@ -4410,6 +4420,7 @@ static void ResetNewGRFData()
/* Reset GRM reservations */
memset(&_grm_engines, 0, sizeof(_grm_engines));
+ memset(&_grm_cargos, 0, sizeof(_grm_cargos));
/* Unload sprite group data */
UnloadWagonOverrides();