* Trigger station randomisation * @param st station being triggered * @param trigger_tile specific tile of platform to trigger * @param trigger trigger type * @param cargo_type cargo type causing trigger */
| 947 | * @param cargo_type cargo type causing trigger |
| 948 | */ |
| 949 | void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoType cargo_type) |
| 950 | { |
| 951 | /* List of coverage areas for each animation trigger */ |
| 952 | static const TriggerArea tas[] = { |
| 953 | TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM |
| 954 | }; |
| 955 | |
| 956 | assert(st != nullptr); |
| 957 | |
| 958 | /* Check the cached cargo trigger bitmask to see if we need |
| 959 | * to bother with any further processing. |
| 960 | * Note: cached_cargo_triggers must be non-zero even for cargo-independent triggers. */ |
| 961 | if (st->cached_cargo_triggers == 0) return; |
| 962 | if (IsValidCargoType(cargo_type) && !HasBit(st->cached_cargo_triggers, cargo_type)) return; |
| 963 | |
| 964 | uint32_t whole_reseed = 0; |
| 965 | |
| 966 | /* Bitmask of completely empty cargo types to be matched. */ |
| 967 | CargoTypes empty_mask{}; |
| 968 | if (trigger == StationRandomTrigger::CargoTaken) { |
| 969 | empty_mask = GetEmptyMask(Station::From(st)); |
| 970 | } |
| 971 | |
| 972 | /* Store triggers now for var 5F */ |
| 973 | st->waiting_random_triggers.Set(trigger); |
| 974 | StationRandomTriggers used_random_triggers; |
| 975 | |
| 976 | /* Check all tiles over the station to check if the specindex is still in use */ |
| 977 | for (TileIndex tile : GetRailTileArea(st, trigger_tile, tas[static_cast<size_t>(trigger)])) { |
| 978 | if (st->TileBelongsToRailStation(tile)) { |
| 979 | const StationSpec *ss = GetStationSpec(tile); |
| 980 | if (ss == nullptr) continue; |
| 981 | |
| 982 | /* Cargo taken "will only be triggered if all of those |
| 983 | * cargo types have no more cargo waiting." */ |
| 984 | if (trigger == StationRandomTrigger::CargoTaken) { |
| 985 | if ((ss->cargo_triggers & ~empty_mask) != 0) continue; |
| 986 | } |
| 987 | |
| 988 | if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) { |
| 989 | StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0); |
| 990 | object.SetWaitingRandomTriggers(st->waiting_random_triggers); |
| 991 | |
| 992 | object.ResolveRerandomisation(); |
| 993 | |
| 994 | used_random_triggers.Set(object.GetUsedRandomTriggers()); |
| 995 | |
| 996 | uint32_t reseed = object.GetReseedSum(); |
| 997 | if (reseed != 0) { |
| 998 | whole_reseed |= reseed; |
| 999 | reseed >>= 16; |
| 1000 | |
| 1001 | /* Set individual tile random bits */ |
| 1002 | uint8_t random_bits = GetStationTileRandomBits(tile); |
| 1003 | random_bits &= ~reseed; |
| 1004 | random_bits |= Random() & reseed; |
| 1005 | SetStationTileRandomBits(tile, random_bits); |
| 1006 |
no test coverage detected