mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
(svn r24691) -Codechange: Add resolver classes for vehicles.
This commit is contained in:
parent
c70c67d5b0
commit
7b18c31f37
@ -340,34 +340,59 @@ static byte MapAircraftMovementAction(const Aircraft *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Vehicle Resolver Functions */
|
/* virtual */ uint32 VehicleScopeResolver::GetRandomBits() const
|
||||||
static inline const Vehicle *GRV(const ResolverObject *object)
|
|
||||||
{
|
{
|
||||||
switch (object->scope) {
|
return this->v == NULL ? 0 : this->v->random_bits;
|
||||||
default: NOT_REACHED();
|
}
|
||||||
case VSG_SCOPE_SELF: return object->u.vehicle.self;
|
|
||||||
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);
|
/* virtual */ uint32 VehicleScopeResolver::GetTriggers() const
|
||||||
|
{
|
||||||
|
return this->v == NULL ? 0 : this->v->waiting_triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */ void VehicleScopeResolver::SetTriggers(int triggers) const
|
||||||
|
{
|
||||||
|
/* Evil cast to get around const-ness. This used to be achieved by an
|
||||||
|
* innocent looking function pointer cast... Currently I cannot see a
|
||||||
|
* way of avoiding this without removing consts deep within gui code.
|
||||||
|
*/
|
||||||
|
Vehicle *v = const_cast<Vehicle *>(this->v);
|
||||||
|
|
||||||
|
/* This function must only be called when processing triggers -- any
|
||||||
|
* other time is an error. */
|
||||||
|
assert(this->ro->trigger != 0);
|
||||||
|
|
||||||
|
if (v != NULL) v->waiting_triggers = triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */ ScopeResolver *VehicleResolverObject::GetScope(VarSpriteGroupScope scope, byte relative)
|
||||||
|
{
|
||||||
|
switch (scope) {
|
||||||
|
case VSG_SCOPE_SELF: return &this->self_scope;
|
||||||
|
case VSG_SCOPE_PARENT: return &this->parent_scope;
|
||||||
|
case VSG_SCOPE_RELATIVE: {
|
||||||
|
int32 count = GB(relative, 0, 4);
|
||||||
|
if (this->self_scope.v != NULL && (relative != this->cached_relative_count || count == 0)) {
|
||||||
|
/* Note: This caching only works as long as the VSG_SCOPE_RELATIVE cannot be used in
|
||||||
|
* VarAct2 with procedure calls. */
|
||||||
if (count == 0) count = GetRegister(0x100);
|
if (count == 0) count = GetRegister(0x100);
|
||||||
|
|
||||||
const Vehicle *v = NULL;
|
const Vehicle *v = NULL;
|
||||||
switch (GB(object->count, 6, 2)) {
|
switch (GB(relative, 6, 2)) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
case 0x00: // count back (away from the engine), starting at this vehicle
|
case 0x00: // count back (away from the engine), starting at this vehicle
|
||||||
v = object->u.vehicle.self;
|
v = this->self_scope.v;
|
||||||
break;
|
break;
|
||||||
case 0x01: // count forward (toward the engine), starting at this vehicle
|
case 0x01: // count forward (toward the engine), starting at this vehicle
|
||||||
v = object->u.vehicle.self;
|
v = this->self_scope.v;
|
||||||
count = -count;
|
count = -count;
|
||||||
break;
|
break;
|
||||||
case 0x02: // count back, starting at the engine
|
case 0x02: // count back, starting at the engine
|
||||||
v = object->u.vehicle.parent;
|
v = this->parent_scope.v;
|
||||||
break;
|
break;
|
||||||
case 0x03: { // count back, starting at the first vehicle in this chain of vehicles with the same ID, as for vehicle variable 41
|
case 0x03: { // count back, starting at the first vehicle in this chain of vehicles with the same ID, as for vehicle variable 41
|
||||||
const Vehicle *self = object->u.vehicle.self;
|
const Vehicle *self = this->self_scope.v;
|
||||||
for (const Vehicle *u = self->First(); u != self; u = u->Next()) {
|
for (const Vehicle *u = self->First(); u != self; u = u->Next()) {
|
||||||
if (u->engine_type != self->engine_type) {
|
if (u->engine_type != self->engine_type) {
|
||||||
v = NULL;
|
v = NULL;
|
||||||
@ -379,39 +404,13 @@ static inline const Vehicle *GRV(const ResolverObject *object)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v->Move(count);
|
this->relative_scope.SetVehicle(v->Move(count));
|
||||||
|
}
|
||||||
|
return &this->relative_scope;
|
||||||
|
}
|
||||||
|
default: return &this->default_scope; // XXX ResolverObject::GetScope(scope, relative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32 VehicleGetRandomBits(const ResolverObject *object)
|
|
||||||
{
|
|
||||||
return GRV(object) == NULL ? 0 : GRV(object)->random_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32 VehicleGetTriggers(const ResolverObject *object)
|
|
||||||
{
|
|
||||||
return GRV(object) == NULL ? 0 : GRV(object)->waiting_triggers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void VehicleSetTriggers(const ResolverObject *object, int triggers)
|
|
||||||
{
|
|
||||||
/* Evil cast to get around const-ness. This used to be achieved by an
|
|
||||||
* innocent looking function pointer cast... Currently I cannot see a
|
|
||||||
* way of avoiding this without removing consts deep within gui code.
|
|
||||||
*/
|
|
||||||
Vehicle *v = const_cast<Vehicle *>(GRV(object));
|
|
||||||
|
|
||||||
/* This function must only be called when processing triggers -- any
|
|
||||||
* other time is an error. */
|
|
||||||
assert(object->trigger != 0);
|
|
||||||
|
|
||||||
if (v != NULL) v->waiting_triggers = triggers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the livery of an engine.
|
* Determines the livery of an engine.
|
||||||
@ -464,7 +463,7 @@ static uint32 PositionHelper(const Vehicle *v, bool consecutive)
|
|||||||
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte variable, uint32 parameter, bool *available)
|
static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, byte variable, uint32 parameter, bool *available)
|
||||||
{
|
{
|
||||||
/* Calculated vehicle parameters */
|
/* Calculated vehicle parameters */
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
@ -547,7 +546,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte
|
|||||||
/* Unlike everywhere else the cargo translation table is only used since grf version 8, not 7.
|
/* Unlike everywhere else the cargo translation table is only used since grf version 8, not 7.
|
||||||
* Note: The grffile == NULL case only happens if this function is called for default vehicles.
|
* Note: The grffile == NULL case only happens if this function is called for default vehicles.
|
||||||
* And this is only done by CheckCaches(). */
|
* And this is only done by CheckCaches(). */
|
||||||
const GRFFile *grffile = object->grffile;
|
const GRFFile *grffile = object->ro->grffile;
|
||||||
uint8 common_bitnum = (common_cargo_type == CT_INVALID) ? 0xFF :
|
uint8 common_bitnum = (common_cargo_type == CT_INVALID) ? 0xFF :
|
||||||
(grffile == NULL || grffile->grf_version < 8) ? CargoSpec::Get(common_cargo_type)->bitnum : grffile->cargo_map[common_cargo_type];
|
(grffile == NULL || grffile->grf_version < 8) ? CargoSpec::Get(common_cargo_type)->bitnum : grffile->cargo_map[common_cargo_type];
|
||||||
|
|
||||||
@ -618,7 +617,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte
|
|||||||
case 0x4A: {
|
case 0x4A: {
|
||||||
if (v->type != VEH_TRAIN) return 0;
|
if (v->type != VEH_TRAIN) return 0;
|
||||||
RailType rt = GetTileRailType(v->tile);
|
RailType rt = GetTileRailType(v->tile);
|
||||||
return (HasPowerOnRail(Train::From(v)->railtype, rt) ? 0x100 : 0) | GetReverseRailTypeTranslation(rt, object->grffile);
|
return (HasPowerOnRail(Train::From(v)->railtype, rt) ? 0x100 : 0) | GetReverseRailTypeTranslation(rt, object->ro->grffile);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x4B: // Long date of last service
|
case 0x4B: // Long date of last service
|
||||||
@ -644,8 +643,8 @@ static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte
|
|||||||
if (!v->IsGroundVehicle() || parameter == 0x61) return 0;
|
if (!v->IsGroundVehicle() || parameter == 0x61) return 0;
|
||||||
|
|
||||||
/* Only allow callbacks that don't change properties to avoid circular dependencies. */
|
/* Only allow callbacks that don't change properties to avoid circular dependencies. */
|
||||||
if (object->callback == CBID_NO_CALLBACK || object->callback == CBID_RANDOM_TRIGGER || object->callback == CBID_TRAIN_ALLOW_WAGON_ATTACH ||
|
if (object->ro->callback == CBID_NO_CALLBACK || object->ro->callback == CBID_RANDOM_TRIGGER || object->ro->callback == CBID_TRAIN_ALLOW_WAGON_ATTACH ||
|
||||||
object->callback == CBID_VEHICLE_START_STOP_CHECK || object->callback == CBID_VEHICLE_32DAY_CALLBACK || object->callback == CBID_VEHICLE_COLOUR_MAPPING) {
|
object->ro->callback == CBID_VEHICLE_START_STOP_CHECK || object->ro->callback == CBID_VEHICLE_32DAY_CALLBACK || object->ro->callback == CBID_VEHICLE_COLOUR_MAPPING) {
|
||||||
Vehicle *u = v->Move((int32)GetRegister(0x10F));
|
Vehicle *u = v->Move((int32)GetRegister(0x10F));
|
||||||
if (u == NULL) return 0;
|
if (u == NULL) return 0;
|
||||||
|
|
||||||
@ -757,7 +756,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte
|
|||||||
case 0x1C: return v->y_pos;
|
case 0x1C: return v->y_pos;
|
||||||
case 0x1D: return GB(v->y_pos, 8, 8);
|
case 0x1D: return GB(v->y_pos, 8, 8);
|
||||||
case 0x1E: return v->z_pos;
|
case 0x1E: return v->z_pos;
|
||||||
case 0x1F: return object->u.vehicle.info_view ? DIR_W : v->direction;
|
case 0x1F: return object->info_view ? DIR_W : v->direction;
|
||||||
case 0x28: return 0; // cur_image is a potential desyncer due to Action1 in static NewGRFs.
|
case 0x28: return 0; // cur_image is a potential desyncer due to Action1 in static NewGRFs.
|
||||||
case 0x29: return 0; // cur_image is a potential desyncer due to Action1 in static NewGRFs.
|
case 0x29: return 0; // cur_image is a potential desyncer due to Action1 in static NewGRFs.
|
||||||
case 0x32: return v->vehstatus;
|
case 0x32: return v->vehstatus;
|
||||||
@ -872,17 +871,15 @@ static uint32 VehicleGetVariable(Vehicle *v, const ResolverObject *object, byte
|
|||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, uint32 parameter, bool *available)
|
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
||||||
{
|
{
|
||||||
Vehicle *v = const_cast<Vehicle*>(GRV(object));
|
if (this->v == NULL) {
|
||||||
|
|
||||||
if (v == NULL) {
|
|
||||||
/* Vehicle does not exist, so we're in a purchase list */
|
/* Vehicle does not exist, so we're in a purchase list */
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
case 0x43: return GetCompanyInfo(_current_company, LiveryHelper(object->u.vehicle.self_type, NULL)); // Owner information
|
case 0x43: return GetCompanyInfo(_current_company, LiveryHelper(this->self_type, NULL)); // Owner information
|
||||||
case 0x46: return 0; // Motion counter
|
case 0x46: return 0; // Motion counter
|
||||||
case 0x47: { // Vehicle cargo info
|
case 0x47: { // Vehicle cargo info
|
||||||
const Engine *e = Engine::Get(object->u.vehicle.self_type);
|
const Engine *e = Engine::Get(this->self_type);
|
||||||
CargoID cargo_type = e->GetDefaultCargoType();
|
CargoID cargo_type = e->GetDefaultCargoType();
|
||||||
if (cargo_type != CT_INVALID) {
|
if (cargo_type != CT_INVALID) {
|
||||||
const CargoSpec *cs = CargoSpec::Get(cargo_type);
|
const CargoSpec *cs = CargoSpec::Get(cargo_type);
|
||||||
@ -891,7 +888,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, ui
|
|||||||
return 0x000000FF;
|
return 0x000000FF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 0x48: return Engine::Get(object->u.vehicle.self_type)->flags; // Vehicle Type Info
|
case 0x48: return Engine::Get(this->self_type)->flags; // Vehicle Type Info
|
||||||
case 0x49: return _cur_year; // 'Long' format build year
|
case 0x49: return _cur_year; // 'Long' format build year
|
||||||
case 0x4B: return _date; // Long date of last service
|
case 0x4B: return _date; // Long date of last service
|
||||||
case 0x92: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 0xFFFF); // Date of last service
|
case 0x92: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 0xFFFF); // Date of last service
|
||||||
@ -905,13 +902,13 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, ui
|
|||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VehicleGetVariable(v, object, variable, parameter, available);
|
return VehicleGetVariable(const_cast<Vehicle*>(this->v), this, variable, parameter, available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const SpriteGroup *VehicleResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
|
/* virtual */ const SpriteGroup *VehicleResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
||||||
{
|
{
|
||||||
const Vehicle *v = object->u.vehicle.self;
|
const Vehicle *v = this->self_scope.v;
|
||||||
|
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
if (group->num_loading > 0) return group->loading[0];
|
if (group->num_loading > 0) return group->loading[0];
|
||||||
@ -931,30 +928,34 @@ static const SpriteGroup *VehicleResolveReal(const ResolverObject *object, const
|
|||||||
return in_motion ? group->loaded[set] : group->loading[set];
|
return in_motion ? group->loaded[set] : group->loading[set];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VehicleScopeResolver::VehicleScopeResolver(ResolverObject *ro, EngineID engine_type, const Vehicle *v, bool info_view)
|
||||||
static inline void NewVehicleResolver(ResolverObject *res, EngineID engine_type, const Vehicle *v)
|
: ScopeResolver(ro)
|
||||||
{
|
{
|
||||||
res->GetRandomBits = &VehicleGetRandomBits;
|
this->v = v;
|
||||||
res->GetTriggers = &VehicleGetTriggers;
|
this->self_type = engine_type;
|
||||||
res->SetTriggers = &VehicleSetTriggers;
|
this->info_view = info_view;
|
||||||
res->GetVariable = &VehicleGetVariable;
|
|
||||||
res->ResolveRealMethod = &VehicleResolveReal;
|
|
||||||
|
|
||||||
res->u.vehicle.self = v;
|
|
||||||
res->u.vehicle.parent = (v != NULL) ? v->First() : v;
|
|
||||||
|
|
||||||
res->u.vehicle.self_type = engine_type;
|
|
||||||
res->u.vehicle.info_view = false;
|
|
||||||
|
|
||||||
res->callback = CBID_NO_CALLBACK;
|
|
||||||
res->callback_param1 = 0;
|
|
||||||
res->callback_param2 = 0;
|
|
||||||
res->ResetState();
|
|
||||||
|
|
||||||
const Engine *e = Engine::Get(engine_type);
|
|
||||||
res->grffile = (e != NULL ? e->GetGRF() : NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the grf file associated with an engine type.
|
||||||
|
* @param engine_type Engine to query.
|
||||||
|
* @return grf file associated with the engine.
|
||||||
|
*/
|
||||||
|
static const GRFFile *GetEngineGrfFile(EngineID engine_type)
|
||||||
|
{
|
||||||
|
const Engine *e = Engine::Get(engine_type);
|
||||||
|
return (e != NULL) ? e->GetGRF() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle *v, bool info_view,
|
||||||
|
CallbackID callback, uint32 callback_param1, uint32 callback_param2)
|
||||||
|
: ResolverObject(GetEngineGrfFile(engine_type), callback, callback_param1, callback_param2),
|
||||||
|
self_scope(this, engine_type, v, info_view),
|
||||||
|
parent_scope(this, engine_type, ((v != NULL) ? v->First() : v), info_view),
|
||||||
|
relative_scope(this, engine_type, v, info_view),
|
||||||
|
cached_relative_count(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the SpriteGroup for the specified vehicle.
|
* Retrieve the SpriteGroup for the specified vehicle.
|
||||||
@ -1001,14 +1002,8 @@ static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *
|
|||||||
|
|
||||||
SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type)
|
SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type)
|
||||||
{
|
{
|
||||||
const SpriteGroup *group;
|
VehicleResolverObject object(engine, v, false, CBID_NO_CALLBACK, image_type);
|
||||||
ResolverObject object;
|
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v), &object);
|
||||||
|
|
||||||
NewVehicleResolver(&object, engine, v);
|
|
||||||
|
|
||||||
object.callback_param1 = image_type;
|
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v), &object);
|
|
||||||
if (group == NULL || group->GetNumResults() == 0) return 0;
|
if (group == NULL || group->GetNumResults() == 0) return 0;
|
||||||
|
|
||||||
return group->GetResult() + (direction % group->GetNumResults());
|
return group->GetResult() + (direction % group->GetNumResults());
|
||||||
@ -1023,13 +1018,7 @@ SpriteID GetRotorOverrideSprite(EngineID engine, const Aircraft *v, bool info_vi
|
|||||||
assert(e->type == VEH_AIRCRAFT);
|
assert(e->type == VEH_AIRCRAFT);
|
||||||
assert(!(e->u.air.subtype & AIR_CTOL));
|
assert(!(e->u.air.subtype & AIR_CTOL));
|
||||||
|
|
||||||
ResolverObject object;
|
VehicleResolverObject object(engine, v, info_view, CBID_NO_CALLBACK, image_type);
|
||||||
|
|
||||||
NewVehicleResolver(&object, engine, v);
|
|
||||||
|
|
||||||
object.callback_param1 = image_type;
|
|
||||||
object.u.vehicle.info_view = info_view;
|
|
||||||
|
|
||||||
const SpriteGroup *group = GetWagonOverrideSpriteSet(engine, CT_DEFAULT, engine);
|
const SpriteGroup *group = GetWagonOverrideSpriteSet(engine, CT_DEFAULT, engine);
|
||||||
group = SpriteGroup::Resolve(group, &object);
|
group = SpriteGroup::Resolve(group, &object);
|
||||||
|
|
||||||
@ -1063,16 +1052,8 @@ bool UsesWagonOverride(const Vehicle *v)
|
|||||||
*/
|
*/
|
||||||
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
|
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
|
||||||
{
|
{
|
||||||
const SpriteGroup *group;
|
VehicleResolverObject object(engine, v, false, callback, param1, param2);
|
||||||
ResolverObject object;
|
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
|
||||||
|
|
||||||
NewVehicleResolver(&object, engine, v);
|
|
||||||
|
|
||||||
object.callback = callback;
|
|
||||||
object.callback_param1 = param1;
|
|
||||||
object.callback_param2 = param2;
|
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
|
|
||||||
if (group == NULL) return CALLBACK_FAILED;
|
if (group == NULL) return CALLBACK_FAILED;
|
||||||
|
|
||||||
return group->GetCallbackResult();
|
return group->GetCallbackResult();
|
||||||
@ -1090,18 +1071,10 @@ uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, Eng
|
|||||||
*/
|
*/
|
||||||
uint16 GetVehicleCallbackParent(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
|
uint16 GetVehicleCallbackParent(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
|
||||||
{
|
{
|
||||||
const SpriteGroup *group;
|
VehicleResolverObject object(engine, v, false, callback, param1, param2);
|
||||||
ResolverObject object;
|
object.parent_scope.SetVehicle(parent);
|
||||||
|
|
||||||
NewVehicleResolver(&object, engine, v);
|
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
|
||||||
|
|
||||||
object.callback = callback;
|
|
||||||
object.callback_param1 = param1;
|
|
||||||
object.callback_param2 = param2;
|
|
||||||
|
|
||||||
object.u.vehicle.parent = parent;
|
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
|
|
||||||
if (group == NULL) return CALLBACK_FAILED;
|
if (group == NULL) return CALLBACK_FAILED;
|
||||||
|
|
||||||
return group->GetCallbackResult();
|
return group->GetCallbackResult();
|
||||||
@ -1126,21 +1099,16 @@ uint GetEngineProperty(EngineID engine, PropertyID property, uint orig_value, co
|
|||||||
|
|
||||||
static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first)
|
static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first)
|
||||||
{
|
{
|
||||||
const SpriteGroup *group;
|
|
||||||
ResolverObject object;
|
|
||||||
byte new_random_bits;
|
|
||||||
|
|
||||||
/* We can't trigger a non-existent vehicle... */
|
/* We can't trigger a non-existent vehicle... */
|
||||||
assert(v != NULL);
|
assert(v != NULL);
|
||||||
|
|
||||||
NewVehicleResolver(&object, v->engine_type, v);
|
VehicleResolverObject object(v->engine_type, v, false, CBID_RANDOM_TRIGGER);
|
||||||
object.callback = CBID_RANDOM_TRIGGER;
|
|
||||||
object.trigger = trigger;
|
object.trigger = trigger;
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
|
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
|
||||||
if (group == NULL) return;
|
if (group == NULL) return;
|
||||||
|
|
||||||
new_random_bits = Random();
|
byte new_random_bits = Random();
|
||||||
uint32 reseed = object.GetReseedSum(); // The scope only affects triggers, not the reseeding
|
uint32 reseed = object.GetReseedSum(); // The scope only affects triggers, not the reseeding
|
||||||
v->random_bits &= ~reseed;
|
v->random_bits &= ~reseed;
|
||||||
v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed;
|
v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed;
|
||||||
@ -1295,26 +1263,13 @@ void CommitVehicleListOrderChanges()
|
|||||||
_list_order_changes.Reset();
|
_list_order_changes.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve an engine's spec and such so we can get a variable.
|
|
||||||
* @param ro The resolver object to fill.
|
|
||||||
* @param index The vehicle to get the data from.
|
|
||||||
*/
|
|
||||||
void GetVehicleResolver(ResolverObject *ro, uint index)
|
|
||||||
{
|
|
||||||
Vehicle *v = Vehicle::Get(index);
|
|
||||||
NewVehicleResolver(ro, v->engine_type, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill the grf_cache of the given vehicle.
|
* Fill the grf_cache of the given vehicle.
|
||||||
* @param v The vehicle to fill the cache for.
|
* @param v The vehicle to fill the cache for.
|
||||||
*/
|
*/
|
||||||
void FillNewGRFVehicleCache(const Vehicle *v)
|
void FillNewGRFVehicleCache(const Vehicle *v)
|
||||||
{
|
{
|
||||||
ResolverObject ro;
|
VehicleResolverObject ro(v->engine_type, v);
|
||||||
memset(&ro, 0, sizeof(ro));
|
|
||||||
GetVehicleResolver(&ro, v->index);
|
|
||||||
|
|
||||||
/* These variables we have to check; these are the ones with a cache. */
|
/* These variables we have to check; these are the ones with a cache. */
|
||||||
static const int cache_entries[][2] = {
|
static const int cache_entries[][2] = {
|
||||||
|
@ -18,6 +18,37 @@
|
|||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
#include "engine_type.h"
|
#include "engine_type.h"
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
|
#include "newgrf_spritegroup.h"
|
||||||
|
|
||||||
|
struct VehicleScopeResolver : public ScopeResolver {
|
||||||
|
const struct Vehicle *v;
|
||||||
|
EngineID self_type;
|
||||||
|
bool info_view; ///< Indicates if the item is being drawn in an info window
|
||||||
|
|
||||||
|
VehicleScopeResolver(ResolverObject *ro, EngineID engine_type, const Vehicle *v, bool info_view);
|
||||||
|
|
||||||
|
void SetVehicle(const Vehicle *v) { this->v = v; }
|
||||||
|
|
||||||
|
/* virtual */ uint32 GetRandomBits() const;
|
||||||
|
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
||||||
|
/* virtual */ uint32 GetTriggers() const;
|
||||||
|
/* virtual */ void SetTriggers(int triggers) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VehicleResolverObject : public ResolverObject {
|
||||||
|
VehicleScopeResolver self_scope;
|
||||||
|
VehicleScopeResolver parent_scope;
|
||||||
|
|
||||||
|
VehicleScopeResolver relative_scope;
|
||||||
|
byte cached_relative_count;
|
||||||
|
|
||||||
|
VehicleResolverObject(EngineID engine_type, const Vehicle *v, bool info_view = false,
|
||||||
|
CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
|
||||||
|
|
||||||
|
/* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
|
||||||
|
|
||||||
|
/* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
|
||||||
|
};
|
||||||
|
|
||||||
static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29;
|
static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29;
|
||||||
static const uint ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 32;
|
static const uint ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 32;
|
||||||
|
@ -350,15 +350,6 @@ struct ResolverObject {
|
|||||||
|
|
||||||
const GRFFile *grffile; ///< GRFFile the resolved SpriteGroup belongs to
|
const GRFFile *grffile; ///< GRFFile the resolved SpriteGroup belongs to
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
const struct Vehicle *self;
|
|
||||||
const struct Vehicle *parent;
|
|
||||||
EngineID self_type;
|
|
||||||
bool info_view; ///< Indicates if the item is being drawn in an info window
|
|
||||||
} vehicle;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
uint32 (*GetRandomBits)(const struct ResolverObject*);
|
uint32 (*GetRandomBits)(const struct ResolverObject*);
|
||||||
uint32 (*GetTriggers)(const struct ResolverObject*);
|
uint32 (*GetTriggers)(const struct ResolverObject*);
|
||||||
void (*SetTriggers)(const struct ResolverObject*, int);
|
void (*SetTriggers)(const struct ResolverObject*, int);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
/** @file newgrf_debug_data.h Data 'tables' for NewGRF debugging. */
|
/** @file newgrf_debug_data.h Data 'tables' for NewGRF debugging. */
|
||||||
|
|
||||||
#include "../newgrf_house.h"
|
#include "../newgrf_house.h"
|
||||||
|
#include "../newgrf_engine.h"
|
||||||
|
|
||||||
/* Helper for filling property tables */
|
/* Helper for filling property tables */
|
||||||
#define NIP(prop, base, variable, type, name) { name, cpp_offsetof(base, variable), cpp_sizeof(base, variable), prop, type }
|
#define NIP(prop, base, variable, type, name) { name, cpp_offsetof(base, variable), cpp_sizeof(base, variable), prop, type }
|
||||||
@ -69,7 +70,13 @@ class NIHVehicle : public NIHelper {
|
|||||||
const void *GetSpec(uint index) const { return Vehicle::Get(index)->GetEngine(); }
|
const void *GetSpec(uint index) const { return Vehicle::Get(index)->GetEngine(); }
|
||||||
void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); }
|
void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); }
|
||||||
uint32 GetGRFID(uint index) const { return Vehicle::Get(index)->GetGRFID(); }
|
uint32 GetGRFID(uint index) const { return Vehicle::Get(index)->GetGRFID(); }
|
||||||
void Resolve(ResolverObject *ro, uint32 index) const { extern void GetVehicleResolver(ResolverObject *ro, uint index); GetVehicleResolver(ro, index); }
|
|
||||||
|
/* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const
|
||||||
|
{
|
||||||
|
Vehicle *v = Vehicle::Get(index);
|
||||||
|
VehicleResolverObject ro(v->engine_type, v);
|
||||||
|
return ro.GetScope(ro.scope)->GetVariable(var, param, avail);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NIFeature _nif_vehicle = {
|
static const NIFeature _nif_vehicle = {
|
||||||
|
Loading…
Reference in New Issue
Block a user