virtual */
| 316 | |
| 317 | |
| 318 | /* virtual */ ScopeResolver *VehicleResolverObject::GetScope(VarSpriteGroupScope scope, uint8_t relative) |
| 319 | { |
| 320 | switch (scope) { |
| 321 | case VSG_SCOPE_SELF: return &this->self_scope; |
| 322 | case VSG_SCOPE_PARENT: return &this->parent_scope; |
| 323 | case VSG_SCOPE_RELATIVE: { |
| 324 | int32_t count = GB(relative, 0, 4); |
| 325 | if (this->self_scope.v != nullptr && (relative != this->cached_relative_count || count == 0)) { |
| 326 | /* Note: This caching only works as long as the VSG_SCOPE_RELATIVE cannot be used in |
| 327 | * VarAct2 with procedure calls. */ |
| 328 | if (count == 0) count = this->GetRegister(0x100); |
| 329 | |
| 330 | const Vehicle *v = nullptr; |
| 331 | switch (GB(relative, 6, 2)) { |
| 332 | default: NOT_REACHED(); |
| 333 | case 0x00: // count back (away from the engine), starting at this vehicle |
| 334 | v = this->self_scope.v; |
| 335 | break; |
| 336 | case 0x01: // count forward (toward the engine), starting at this vehicle |
| 337 | v = this->self_scope.v; |
| 338 | count = -count; |
| 339 | break; |
| 340 | case 0x02: // count back, starting at the engine |
| 341 | v = this->parent_scope.v; |
| 342 | break; |
| 343 | case 0x03: { // count back, starting at the first vehicle in this chain of vehicles with the same ID, as for vehicle variable 41 |
| 344 | const Vehicle *self = this->self_scope.v; |
| 345 | for (const Vehicle *u = self->First(); u != self; u = u->Next()) { |
| 346 | if (u->engine_type != self->engine_type) { |
| 347 | v = nullptr; |
| 348 | } else { |
| 349 | if (v == nullptr) v = u; |
| 350 | } |
| 351 | } |
| 352 | if (v == nullptr) v = self; |
| 353 | break; |
| 354 | } |
| 355 | } |
| 356 | this->relative_scope.SetVehicle(v->Move(count)); |
| 357 | } |
| 358 | return &this->relative_scope; |
| 359 | } |
| 360 | default: return ResolverObject::GetScope(scope, relative); |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | /** |
| 365 | * Determines the livery of an engine. |
no test coverage detected