mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 22:28:56 +00:00
(svn r10442) -Codechange: implement the industry production callback.
This commit is contained in:
parent
9bc6a1cc8e
commit
86c14c239f
@ -35,6 +35,7 @@
|
|||||||
#include "newgrf_engine.h"
|
#include "newgrf_engine.h"
|
||||||
#include "newgrf_sound.h"
|
#include "newgrf_sound.h"
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
|
#include "newgrf_industries.h"
|
||||||
#include "unmovable.h"
|
#include "unmovable.h"
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
@ -1239,7 +1240,7 @@ static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pie
|
|||||||
|
|
||||||
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
||||||
best->incoming_cargo_waiting[accepted_cargo_index] = min(num_pieces + best->incoming_cargo_waiting[accepted_cargo_index], 0xFFFF);
|
best->incoming_cargo_waiting[accepted_cargo_index] = min(num_pieces + best->incoming_cargo_waiting[accepted_cargo_index], 0xFFFF);
|
||||||
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) {} ///< @todo Perform some magic
|
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) IndustryProductionCallback(ind, 0);
|
||||||
} else {
|
} else {
|
||||||
best->produced_cargo_waiting[0] = min(best->produced_cargo_waiting[0] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][0] / 256), 0xFFFF);
|
best->produced_cargo_waiting[0] = min(best->produced_cargo_waiting[0] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][0] / 256), 0xFFFF);
|
||||||
best->produced_cargo_waiting[1] = min(best->produced_cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF);
|
best->produced_cargo_waiting[1] = min(best->produced_cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "tree_map.h"
|
#include "tree_map.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
|
#include "newgrf_industries.h"
|
||||||
#include "newgrf_industrytiles.h"
|
#include "newgrf_industrytiles.h"
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
|
|
||||||
@ -965,6 +966,8 @@ static void ProduceIndustryGoods(Industry *i)
|
|||||||
|
|
||||||
/* produce some cargo */
|
/* produce some cargo */
|
||||||
if ((i->counter & 0xFF) == 0) {
|
if ((i->counter & 0xFF) == 0) {
|
||||||
|
if (HASBIT(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
|
||||||
|
|
||||||
IndustyBehaviour indbehav = indsp->behaviour;
|
IndustyBehaviour indbehav = indsp->behaviour;
|
||||||
i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
|
i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
|
||||||
i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
|
i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
|
||||||
|
@ -2287,6 +2287,35 @@ static void NewSpriteGroup(byte *buf, int len)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GSF_INDUSTRIES: {
|
||||||
|
if (type > 1) {
|
||||||
|
grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
group = AllocateSpriteGroup();
|
||||||
|
group->type = SGT_INDUSTRY_PRODUCTION;
|
||||||
|
group->g.indprod.version = type;
|
||||||
|
if (type == 0) {
|
||||||
|
for (uint i = 0; i < 3; i++) {
|
||||||
|
group->g.indprod.substract_input[i] = grf_load_word(&buf);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < 2; i++) {
|
||||||
|
group->g.indprod.add_output[i] = grf_load_word(&buf);
|
||||||
|
}
|
||||||
|
group->g.indprod.again = grf_load_byte(&buf);
|
||||||
|
} else {
|
||||||
|
for (uint i = 0; i < 3; i++) {
|
||||||
|
group->g.indprod.substract_input[i] = grf_load_byte(&buf);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < 2; i++) {
|
||||||
|
group->g.indprod.add_output[i] = grf_load_byte(&buf);
|
||||||
|
}
|
||||||
|
group->g.indprod.again = grf_load_byte(&buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Loading of Tile Layout and Production Callback groups would happen here */
|
/* Loading of Tile Layout and Production Callback groups would happen here */
|
||||||
default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
|
default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
|
|||||||
case 0x42: { // waiting cargo, but only if those two callback flags are set
|
case 0x42: { // waiting cargo, but only if those two callback flags are set
|
||||||
uint16 callback = indspec->callback_flags;
|
uint16 callback = indspec->callback_flags;
|
||||||
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
if (HASBIT(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HASBIT(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
||||||
return max(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0x7FFF);
|
return max(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -263,3 +263,40 @@ uint16 GetIndustryCallback(uint16 callback, uint32 param1, uint32 param2, Indust
|
|||||||
|
|
||||||
return group->g.callback.result;
|
return group->g.callback.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32 DerefIndProd(uint field, bool use_register)
|
||||||
|
{
|
||||||
|
return use_register ? (int32)GetRegister(field) : field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the industry production callback and apply it to the industry.
|
||||||
|
* @param ind the industry this callback has to be called for
|
||||||
|
* @param reason the reason it is called (0 = incoming cargo, 1 = periodic tick callback)
|
||||||
|
*/
|
||||||
|
void IndustryProductionCallback(Industry *ind, int reason)
|
||||||
|
{
|
||||||
|
ResolverObject object;
|
||||||
|
NewIndustryResolver(&object, INVALID_TILE, ind);
|
||||||
|
object.callback_param2 = reason;
|
||||||
|
|
||||||
|
for (uint loop = 0;; loop++) {
|
||||||
|
SB(object.callback_param2, 8, 16, loop);
|
||||||
|
const SpriteGroup *group = Resolve(GetIndustrySpec(ind->type)->grf_prop.spritegroup, &object);
|
||||||
|
if (group == NULL || group->type != SGT_INDUSTRY_PRODUCTION) break;
|
||||||
|
|
||||||
|
bool deref = (group->g.indprod.version == 1);
|
||||||
|
|
||||||
|
for (uint i = 0; i < 3; i++) {
|
||||||
|
ind->incoming_cargo_waiting[i] = clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->g.indprod.substract_input[i], deref), 0, 0xFFFF);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < 2; i++) {
|
||||||
|
ind->produced_cargo_waiting[i] = clamp(ind->produced_cargo_waiting[i] + DerefIndProd(group->g.indprod.add_output[i], deref), 0, 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 again = DerefIndProd(group->g.indprod.again, deref);
|
||||||
|
if (again == 0) break;
|
||||||
|
|
||||||
|
SB(object.callback_param2, 24, 8, again);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available);
|
uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available);
|
||||||
uint16 GetIndustryCallback(uint16 callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
|
uint16 GetIndustryCallback(uint16 callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
|
||||||
uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i);
|
uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i);
|
||||||
|
void IndustryProductionCallback(Industry *ind, int reason);
|
||||||
|
|
||||||
/* in newgrf_industrytiles.cpp*/
|
/* in newgrf_industrytiles.cpp*/
|
||||||
uint32 IndustryTileGetRandomBits(const ResolverObject *object);
|
uint32 IndustryTileGetRandomBits(const ResolverObject *object);
|
||||||
|
@ -76,7 +76,7 @@ void InitializeSpriteGroupPool()
|
|||||||
_spritegroup_count = 0;
|
_spritegroup_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 _temp_store[0x110];
|
uint32 _temp_store[0x110];
|
||||||
|
|
||||||
|
|
||||||
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||||
|
@ -8,6 +8,19 @@
|
|||||||
#include "town.h"
|
#include "town.h"
|
||||||
#include "industry.h"
|
#include "industry.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of a so-called newgrf "register".
|
||||||
|
* @param i index of the register
|
||||||
|
* @pre i < 0x110
|
||||||
|
* @return the value of the register
|
||||||
|
*/
|
||||||
|
static inline uint32 GetRegister(uint i)
|
||||||
|
{
|
||||||
|
assert(i < 0x110);
|
||||||
|
extern uint32 _temp_store[0x110];
|
||||||
|
return _temp_store[i];
|
||||||
|
}
|
||||||
|
|
||||||
struct SpriteGroup;
|
struct SpriteGroup;
|
||||||
|
|
||||||
|
|
||||||
@ -135,6 +148,13 @@ struct TileLayoutSpriteGroup {
|
|||||||
struct DrawTileSprites *dts;
|
struct DrawTileSprites *dts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IndustryProductionSpriteGroup {
|
||||||
|
uint8 version;
|
||||||
|
uint16 substract_input[3];
|
||||||
|
uint16 add_output[2];
|
||||||
|
uint8 again;
|
||||||
|
};
|
||||||
|
|
||||||
/* List of different sprite group types */
|
/* List of different sprite group types */
|
||||||
enum SpriteGroupType {
|
enum SpriteGroupType {
|
||||||
SGT_INVALID,
|
SGT_INVALID,
|
||||||
@ -144,6 +164,7 @@ enum SpriteGroupType {
|
|||||||
SGT_CALLBACK,
|
SGT_CALLBACK,
|
||||||
SGT_RESULT,
|
SGT_RESULT,
|
||||||
SGT_TILELAYOUT,
|
SGT_TILELAYOUT,
|
||||||
|
SGT_INDUSTRY_PRODUCTION,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Common wrapper for all the different sprite group types */
|
/* Common wrapper for all the different sprite group types */
|
||||||
@ -157,6 +178,7 @@ struct SpriteGroup {
|
|||||||
CallbackResultSpriteGroup callback;
|
CallbackResultSpriteGroup callback;
|
||||||
ResultSpriteGroup result;
|
ResultSpriteGroup result;
|
||||||
TileLayoutSpriteGroup layout;
|
TileLayoutSpriteGroup layout;
|
||||||
|
IndustryProductionSpriteGroup indprod;
|
||||||
} g;
|
} g;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user