--- a/src/newgrf_engine.cpp Wed Jun 13 11:17:30 2007 +0000
+++ b/src/newgrf_engine.cpp Wed Jun 13 11:45:14 2007 +0000
@@ -63,22 +63,22 @@
memcpy(wo->train_id, train_id, trains);
}
-static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
+const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
{
const WagonOverrides *wos = &_engine_wagon_overrides[engine];
- int i;
/* XXX: This could turn out to be a timesink on profiles. We could
* always just dedicate 65535 bytes for an [engine][train] trampoline
* for O(1). Or O(logMlogN) and searching binary tree or smt. like
* that. --pasky */
- for (i = 0; i < wos->overrides_count; i++) {
+ for (int i = 0; i < wos->overrides_count; i++) {
const WagonOverride *wo = &wos->overrides[i];
- int j;
- for (j = 0; j < wo->trains; j++) {
- if (wo->train_id[j] == overriding_engine && (wo->cargo == cargo || wo->cargo == CT_DEFAULT)) return wo->group;
+ if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue;
+
+ for (int j = 0; j < wo->trains; j++) {
+ if (wo->train_id[j] == overriding_engine) return wo->group;
}
}
return NULL;
@@ -246,7 +246,7 @@
{
const Station *st = GetStation(v->u.air.targetairport);
const AirportFTAClass *afc = st->Airport();
- byte amdflag = afc->MovingData(v->u.air.pos)->flag;
+ uint16 amdflag = afc->MovingData(v->u.air.pos)->flag;
switch (v->u.air.state) {
case HANGAR:
@@ -313,7 +313,7 @@
}
case FLYING:
- return AMS_TTDP_FLIGHT_TO_TOWER;
+ return amdflag & AMED_HOLD ? AMS_TTDP_FLIGHT_APPROACH : AMS_TTDP_FLIGHT_TO_TOWER;
case LANDING: // Descent
return AMS_TTDP_FLIGHT_DESCENT;
@@ -468,6 +468,22 @@
}
+static uint8 LiveryHelper(EngineID engine, const Vehicle *v)
+{
+ const Livery *l;
+
+ if (v == NULL) {
+ l = GetEngineLivery(engine, _current_player, INVALID_ENGINE, NULL);
+ } else if (v->type == VEH_TRAIN) {
+ l = GetEngineLivery((v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ? v->u.rail.first_engine : v->engine_type, v->owner, v->u.rail.first_engine, v);
+ } else {
+ l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v);
+ }
+
+ return l->colour1 + l->colour2 * 16;
+}
+
+
static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
{
const Vehicle *v = GRV(object);
@@ -475,7 +491,7 @@
if (v == NULL) {
/* Vehicle does not exist, so we're in a purchase list */
switch (variable) {
- case 0x43: return _current_player; // Owner information
+ case 0x43: return _current_player | (LiveryHelper(object->u.vehicle.self_type, NULL) << 24); // Owner information
case 0x46: return 0; // Motion counter
case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; // Vehicle Type Info
case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year
@@ -544,7 +560,7 @@
}
case 0x43: // Player information
- return v->owner;
+ return v->owner | (GetPlayer(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24);
case 0x44: // Aircraft information
if (v->type != VEH_AIRCRAFT) return UINT_MAX;
@@ -573,6 +589,25 @@
return (altitude << 8) | airporttype;
}
+ case 0x45: { // Curvature info
+ /* Format: xxxTxBxF
+ * F - previous wagon to current wagon, 0 if vehicle is first
+ * B - current wagon to next wagon, 0 if wagon is last
+ * T - previous wagon to next wagon, 0 in an S-bend
+ */
+ if (v->type != VEH_TRAIN) return 0;
+
+ const Vehicle *u_p = GetPrevVehicleInChain(v);
+ const Vehicle *u_n = v->next;
+ DirDiff f = (u_p == NULL) ? DIRDIFF_SAME : DirDifference(u_p->direction, v->direction);
+ DirDiff b = (u_n == NULL) ? DIRDIFF_SAME : DirDifference(v->direction, u_n->direction);
+ DirDiff t = ChangeDirDiff(f, b);
+
+ return ((t > DIRDIFF_REVERSE ? t | 8 : t) << 16) |
+ ((b > DIRDIFF_REVERSE ? b | 8 : b) << 8) |
+ ( f > DIRDIFF_REVERSE ? f | 8 : f);
+ }
+
case 0x46: // Motion counter
return v->motion_counter;
@@ -735,6 +770,8 @@
case 0x66: return MapAircraftMovementAction(v); // Current movement action
}
break;
+
+ default: break;
}
DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, v->type);
@@ -815,8 +852,7 @@
cargo = v->cargo_type;
if (v->type == VEH_TRAIN) {
- group = GetWagonOverrideSpriteSet(engine, cargo, v->u.rail.first_engine);
-
+ group = v->u.rail.cached_override;
if (group != NULL) return group;
}
}
@@ -877,7 +913,7 @@
bool UsesWagonOverride(const Vehicle* v)
{
assert(v->type == VEH_TRAIN);
- return GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->u.rail.first_engine) != NULL;
+ return v->u.rail.cached_override != NULL;
}
/**
@@ -936,7 +972,7 @@
}
-/* Callback 36 handler */
+/* Callback 36 handlers */
uint GetVehicleProperty(const Vehicle *v, uint8 property, uint orig_value)
{
uint16 callback = GetVehicleCallback(CBID_VEHICLE_MODIFY_PROPERTY, property, 0, v->engine_type, v);
@@ -946,6 +982,15 @@
}
+uint GetEngineProperty(EngineID engine, uint8 property, uint orig_value)
+{
+ uint16 callback = GetVehicleCallback(CBID_VEHICLE_MODIFY_PROPERTY, property, 0, engine, NULL);
+ if (callback != CALLBACK_FAILED) return callback;
+
+ return orig_value;
+}
+
+
static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first)
{
const SpriteGroup *group;