public static void DetermineIfBusShouldDepart(ref bool __result, ushort vehicleID, ref Vehicle vehicleData) { /* * After reconsidering how everything works, I've decided to make use of * one large static dictionary to store info of alight+board for each bus UID. * * Previously it was found that simply reading the vehicle info is not enough to * determine alight+board count because alighting uses another variable. * Eventually I made use of two Harmony patches to read the alight+board info * and write it to the static dictionary. * * The logic is now sth like this: * * When bus arrives at stop: * Write down alighting+boarding count * Determine if the bus can leave now given the alighting, boarding, and n-th stop info * * It is also determined that storing stop UID is not necessary because * each bus can only stop at one stop at any given point in time. * Stopping at a new stop will simply invalidate the previous stop info. * * This entire system has a nice property that no save-file access is needed. */ if (DepartureChecker.NowIsEligibleForInstantDeparture(vehicleID, ref vehicleData)) { // midway bus stop; implement logic here VehicleBAInfo info = GetInfoForBus(vehicleID); if (info != null && info.Alighted + info.ActualBoarded == 0) { // this bus did not get any alight or board // then depart now __result = true; } else if (vehicleData.m_waitCounter >= 12 && ReversePatch_VehicleAI_CanLeave.BaseVehicleAI_CanLeave(null, vehicleID, ref vehicleData)) { // this bus has alight+board but has waited enough to qualify departure AND all citizens are boarded // then depart now // (the "all citizens boarded" part is more obvious when e.g. Realistic Walking Speed mod is used) __result = true; } } if (__result == false && vehicleData.m_waitCounter > 12 && !ReversePatch_VehicleAI_CanLeave.BaseVehicleAI_CanLeave(null, vehicleID, ref vehicleData)) { // I can't depart because some CIMs have reserved us but run away. // We should correct those bugged CIMs. if (vehicleData.m_waitCounter % 4 == 0) { // Don't check too frequently to reduce CPU stress. CitizenRunawayTable.FixInvalidPublicTransitPassengers(vehicleID, ref vehicleData); } } }
public static VehicleBAInfo GetInfoForBus(ushort vehicleID, bool ensureExists = false) { VehicleBAInfo targetInfo; if (busPickDropTable.TryGetValue(vehicleID, out targetInfo)) { return(targetInfo); } else { if (ensureExists) { targetInfo = new VehicleBAInfo(); busPickDropTable[vehicleID] = targetInfo; return(targetInfo); } else { return(null); } } }