mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-16 00:12:51 +00:00
(svn r10495) -Codechange: Add the Action 00 property handlers for Industries and Industry tiles
This commit is contained in:
parent
e84363b4db
commit
7ca5c337ca
436
src/newgrf.cpp
436
src/newgrf.cpp
@ -41,6 +41,7 @@
|
||||
#include "cargotype.h"
|
||||
#include "industry.h"
|
||||
#include "newgrf_canal.h"
|
||||
#include "table/build_industry.h"
|
||||
#include "newgrf_commons.h"
|
||||
#include "newgrf_townname.h"
|
||||
|
||||
@ -1677,6 +1678,363 @@ static bool SoundEffectChangeInfo(uint sid, int numinfo, int prop, byte **bufp,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, byte **bufp, int len)
|
||||
{
|
||||
byte *buf = *bufp;
|
||||
bool ret = false;
|
||||
|
||||
if (indtid + numinfo > NUM_INDUSTRYTILES) {
|
||||
grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Allocate industry tile specs if they haven't been allocated already. */
|
||||
if (_cur_grffile->indtspec == NULL) {
|
||||
_cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
|
||||
|
||||
/* Reset any overrides that have been set. */
|
||||
_industile_mngr.ResetOverride();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numinfo; i++) {
|
||||
IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
|
||||
|
||||
if (prop != 0x08 && tsp == NULL) {
|
||||
grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (prop) {
|
||||
case 0x08: { // Substitute industry tile type
|
||||
IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i];
|
||||
byte subs_id = grf_load_byte(&buf);
|
||||
|
||||
if (subs_id == 0xFF) {
|
||||
/* Instead of defining a new industry, a substitute industry id
|
||||
* of 0xFF disables the old industry with the current id. */
|
||||
tsp->enabled = false;
|
||||
continue;
|
||||
} else if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
|
||||
/* The substitute id must be one of the original industry tile. */
|
||||
grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Allocate space for this industry. */
|
||||
if (*tilespec == NULL) {
|
||||
int tempid;
|
||||
*tilespec = CallocT<IndustryTileSpec>(1);
|
||||
tsp = *tilespec;
|
||||
|
||||
memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
|
||||
tsp->enabled = true;
|
||||
tsp->grf_prop.local_id = indtid + i;
|
||||
tsp->grf_prop.subst_id = subs_id;
|
||||
tsp->grf_prop.grffile = _cur_grffile;
|
||||
tempid = _industile_mngr.AddEntityID(indtid + i, _cur_grffile->grfid, subs_id); // pre-reserve the tile slot
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x09: { // Industry tile override
|
||||
byte ovrid = grf_load_byte(&buf);
|
||||
|
||||
/* The industry being overridden must be an original industry. */
|
||||
if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
|
||||
grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
|
||||
return false;
|
||||
}
|
||||
|
||||
tsp->grf_prop.override = ovrid;
|
||||
_industile_mngr.Add(indtid + i, ovrid);
|
||||
} break;
|
||||
|
||||
case 0x0A: // Tile acceptance
|
||||
case 0x0B:
|
||||
case 0x0C: {
|
||||
uint16 acctp = grf_load_word(&buf);
|
||||
tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
|
||||
tsp->acceptance[prop - 0x0A] = GetCargoTranslation(GB(acctp, 8, 8), _cur_grffile);
|
||||
} break;
|
||||
|
||||
case 0x0D: // Land shape flags
|
||||
tsp->slopes_refused = (Slope)grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x0E: // Callback flags
|
||||
tsp->callback_flags = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x0F: // Animation information
|
||||
grf_load_word(&buf); // TODO
|
||||
break;
|
||||
|
||||
case 0x10: // Animation speed
|
||||
grf_load_byte(&buf); // TODO
|
||||
break;
|
||||
|
||||
case 0x11: // Triggers for callback 25
|
||||
grf_load_byte(&buf); // TODO
|
||||
break;
|
||||
|
||||
case 0x12: // Special flags
|
||||
grf_load_byte(&buf); // TODO
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len)
|
||||
{
|
||||
byte *buf = *bufp;
|
||||
bool ret = false;
|
||||
|
||||
if (indid + numinfo > NUM_INDUSTRYTYPES) {
|
||||
grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
|
||||
return false;
|
||||
}
|
||||
|
||||
grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
|
||||
|
||||
/* Allocate industry specs if they haven't been allocated already. */
|
||||
if (_cur_grffile->industryspec == NULL) {
|
||||
_cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
|
||||
|
||||
/* Reset any overrides that have been set. */
|
||||
_industry_mngr.ResetOverride();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numinfo; i++) {
|
||||
IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
|
||||
|
||||
if (prop != 0x08 && indsp == NULL) {
|
||||
grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (prop) {
|
||||
case 0x08: { // Substitute industry type
|
||||
IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
|
||||
byte subs_id = grf_load_byte(&buf);
|
||||
|
||||
if (subs_id == 0xFF) {
|
||||
/* Instead of defining a new industry, a substitute industry id
|
||||
* of 0xFF disables the old industry with the current id. */
|
||||
_industry_specs[indid + i].enabled = false;
|
||||
continue;
|
||||
} else if (subs_id >= NEW_INDUSTRYOFFSET) {
|
||||
/* The substitute id must be one of the original industry. */
|
||||
grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Allocate space for this industry.
|
||||
* Only need to do it once. If ever it is called again, it should not
|
||||
* do anything */
|
||||
if (*indspec == NULL) {
|
||||
*indspec = CallocT<IndustrySpec>(1);
|
||||
indsp = *indspec;
|
||||
|
||||
memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
|
||||
indsp->enabled = true;
|
||||
indsp->grf_prop.local_id = indid + i;
|
||||
indsp->grf_prop.subst_id = subs_id;
|
||||
indsp->grf_prop.grffile = _cur_grffile;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x09: { // Industry type override
|
||||
byte ovrid = grf_load_byte(&buf);
|
||||
|
||||
/* The industry being overridden must be an original industry. */
|
||||
if (ovrid >= NEW_INDUSTRYOFFSET) {
|
||||
grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
|
||||
return false;
|
||||
}
|
||||
indsp->grf_prop.override = ovrid;
|
||||
_industry_mngr.Add(indid + i, ovrid);
|
||||
} break;
|
||||
|
||||
case 0x0A: { // Set industry layout(s)
|
||||
indsp->num_table = grf_load_byte(&buf); // Number of layaouts
|
||||
uint32 defsize = grf_load_dword(&buf); // Total size of the definition
|
||||
IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(indsp->num_table); // Table with tiles to compose an industry
|
||||
IndustryTileTable *itt = CallocT<IndustryTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
|
||||
int size;
|
||||
IndustryTileTable *copy_from;
|
||||
|
||||
for (byte j = 0; j < indsp->num_table; j++) {
|
||||
for (int k = 0;; k++) {
|
||||
itt[k].ti.x = grf_load_byte(&buf); // Offsets from northermost tile
|
||||
|
||||
if (itt[k].ti.x == 0xFE && k == 0) {
|
||||
/* This means we have to borrow the layout from an old industry */
|
||||
IndustryType type = grf_load_byte(&buf); //industry holding required layout
|
||||
byte laynbr = grf_load_byte(&buf); //layout number to borrow
|
||||
|
||||
copy_from = (IndustryTileTable*)_origin_industry_specs[type].table[laynbr];
|
||||
for (size = 1;; size++) {
|
||||
if (_origin_industry_specs[type].table[laynbr + (size - 1)]->ti.x == -0x80 &&
|
||||
_origin_industry_specs[type].table[laynbr + (size - 1)]->ti.y == 0) break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
itt[k].ti.y = grf_load_byte(&buf); // Or table definition finalisation
|
||||
|
||||
if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
|
||||
/* Not the same terminator. The one we are using is rather
|
||||
x= -80, y = x . So, adjust it. */
|
||||
itt[k].ti.x = -0x80;
|
||||
itt[k].ti.y = 0;
|
||||
itt[k].gfx = 0;
|
||||
|
||||
size = k + 1;
|
||||
copy_from = itt;
|
||||
break;
|
||||
}
|
||||
|
||||
itt[k].gfx = grf_load_byte(&buf);
|
||||
|
||||
if (itt[k].gfx == 0xFE) {
|
||||
/* Use a new tile from this GRF */
|
||||
int local_tile_id = grf_load_word(&buf);
|
||||
|
||||
/* Read the ID from the _industile_mngr. */
|
||||
int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
|
||||
|
||||
if (tempid == INVALID_INDUSTRYTILE) {
|
||||
grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
|
||||
} else {
|
||||
/* Declared as been valid, can be used */
|
||||
itt[k].gfx = tempid;
|
||||
size = k + 1;
|
||||
copy_from = itt;
|
||||
}
|
||||
}
|
||||
}
|
||||
tile_table[j] = CallocT<IndustryTileTable>(size);
|
||||
memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
|
||||
}
|
||||
/* Install final layout construction in the industry spec */
|
||||
indsp->table = tile_table;
|
||||
SETBIT(indsp->cleanup_flag, 1);
|
||||
free(itt);
|
||||
} break;
|
||||
|
||||
case 0x0B: // Industry production flags
|
||||
indsp->life_type = (IndustryLifeType)grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x0C: // Industry closure message
|
||||
indsp->closure_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
break;
|
||||
|
||||
case 0x0D: // Production increase message
|
||||
indsp->production_up_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
break;
|
||||
|
||||
case 0x0E: // Production decrease message
|
||||
indsp->production_down_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
break;
|
||||
|
||||
case 0x0F: // Fund cost multiplier
|
||||
indsp->cost_multiplier = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x10: // Production cargo types
|
||||
for (byte j = 0; j < 2; j++) {
|
||||
indsp->produced_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x11: // Acceptance cargo types
|
||||
for (byte j = 0; j < 3; j++) {
|
||||
indsp->accepts_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
|
||||
}
|
||||
grf_load_byte(&buf); // Unnused, eat it up
|
||||
break;
|
||||
|
||||
case 0x12: // Production multipliers
|
||||
case 0x13:
|
||||
indsp->production_rate[prop - 0x12] = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x14: // Minimal amount of cargo distributed
|
||||
indsp->minimal_cargo = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x15: { // Random sound effects
|
||||
indsp->number_of_sounds = grf_load_byte(&buf);
|
||||
uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
|
||||
|
||||
for (uint8 j = 0; j < indsp->number_of_sounds; j++) sounds[j] = grf_load_byte(&buf);
|
||||
indsp->random_sounds = sounds;
|
||||
SETBIT(indsp->cleanup_flag, 0);
|
||||
} break;
|
||||
|
||||
case 0x16: // Conflicting industry types
|
||||
for (byte j = 0; j < 3; j++) indsp->conflicting[j] = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x17: // Probability in random game
|
||||
indsp->appear_ingame[_opt.landscape] = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x18: // Probability during gameplay
|
||||
indsp->appear_creation[_opt.landscape] = grf_load_byte(&buf);
|
||||
break;
|
||||
|
||||
case 0x19: // Map color
|
||||
indsp->map_colour = MapDOSColour(grf_load_byte(&buf));
|
||||
break;
|
||||
|
||||
case 0x1A: // Special industry flags to define special behavior
|
||||
indsp->behaviour = (IndustyBehaviour)grf_load_dword(&buf);
|
||||
break;
|
||||
|
||||
case 0x1B: // New industry text ID
|
||||
indsp->new_industry_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
break;
|
||||
|
||||
case 0x1C: // Input cargo multipliers for the three input cargo types
|
||||
case 0x1D:
|
||||
case 0x1E: {
|
||||
uint32 multiples = grf_load_dword(&buf);
|
||||
indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0,15);
|
||||
indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 15,15);
|
||||
} break;
|
||||
|
||||
case 0x1F: // Industry name
|
||||
indsp->name = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
break;
|
||||
|
||||
case 0x20: // Prospecting success chance
|
||||
indsp->prospecting_chance = grf_load_dword(&buf);
|
||||
break;
|
||||
|
||||
case 0x21: // Callback flags
|
||||
case 0x22: { // Callback additional flags
|
||||
byte aflag = grf_load_byte(&buf);
|
||||
SB(indsp->callback_flags, (prop - 0x21) * 8, 8, aflag);
|
||||
} break;
|
||||
|
||||
default:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Action 0x00 */
|
||||
static void FeatureChangeInfo(byte *buf, int len)
|
||||
{
|
||||
@ -1705,8 +2063,8 @@ static void FeatureChangeInfo(byte *buf, int len)
|
||||
/* GSF_BRIDGE */ BridgeChangeInfo,
|
||||
/* GSF_TOWNHOUSE */ TownHouseChangeInfo,
|
||||
/* GSF_GLOBALVAR */ GlobalVarChangeInfo,
|
||||
/* GSF_INDUSTRYTILES */NULL,
|
||||
/* GSF_INDUSTRIES */ NULL,
|
||||
/* GSF_INDUSTRYTILES */IndustrytilesChangeInfo,
|
||||
/* GSF_INDUSTRIES */ IndustriesChangeInfo,
|
||||
/* GSF_CARGOS */ NULL, /* Cargo is handled during reservation */
|
||||
/* GSF_SOUNDFX */ SoundEffectChangeInfo,
|
||||
};
|
||||
@ -2562,6 +2920,53 @@ static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
|
||||
}
|
||||
}
|
||||
|
||||
static void IndustryMapSpriteGroup(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, "IndustryMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
|
||||
groupid, _cur_grffile->spritegroups_count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
uint8 id = buf[3 + i];
|
||||
IndustrySpec *indsp = _cur_grffile->industryspec[id];
|
||||
|
||||
if (indsp == NULL) {
|
||||
grfmsg(1, "IndustryMapSpriteGroup: Too many industries defined, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
indsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
|
||||
}
|
||||
}
|
||||
|
||||
static void IndustrytileMapSpriteGroup(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, "IndustrytileMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
|
||||
groupid, _cur_grffile->spritegroups_count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
uint8 id = buf[3 + i];
|
||||
IndustryTileSpec *indtsp = _cur_grffile->indtspec[id];
|
||||
|
||||
if (indtsp == NULL) {
|
||||
grfmsg(1, "IndustrytileMapSpriteGroup: Too many industry tiles defined, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
indtsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
|
||||
}
|
||||
}
|
||||
|
||||
static void CargoMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
|
||||
{
|
||||
@ -2651,6 +3056,14 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||
TownHouseMapSpriteGroup(buf, idcount, cidcount);
|
||||
return;
|
||||
|
||||
case GSF_INDUSTRIES:
|
||||
IndustryMapSpriteGroup(buf, idcount, cidcount);
|
||||
return;
|
||||
|
||||
case GSF_INDUSTRYTILES:
|
||||
IndustrytileMapSpriteGroup(buf, idcount, cidcount);
|
||||
return;
|
||||
|
||||
case GSF_CARGOS:
|
||||
CargoMapSpriteGroup(buf, idcount, cidcount);
|
||||
return;
|
||||
@ -4781,6 +5194,25 @@ static void FinaliseIndustriesArray()
|
||||
IndustrySpec *indsp = file->industryspec[i];
|
||||
|
||||
if (indsp != NULL && indsp->enabled) {
|
||||
StringID strid;
|
||||
/* process the conversion of text at the end, so to be sure everything will be fine
|
||||
* and available. Check if it does not return undefind marker, which is a very good sign of a
|
||||
* substitute industry who has not changed the string been examined, thus using it as such */
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
|
||||
if (strid != STR_UNDEFINED) indsp->name = strid;
|
||||
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
|
||||
if (strid != STR_UNDEFINED) indsp->closure_text = strid;
|
||||
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
|
||||
if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
|
||||
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
|
||||
if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
|
||||
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
|
||||
if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
|
||||
|
||||
_industry_mngr.SetEntitySpec(indsp);
|
||||
_loaded_newgrf_features.has_newindustries = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user