public bool ExtSimulationStep(ushort instanceId, ref CitizenInstance instanceData, ref ExtCitizenInstance extInstance, Vector3 physicsLodRefPos) { IExtCitizenInstanceManager extCitInstMan = Constants.ManagerFactory.ExtCitizenInstanceManager; #if DEBUG bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 || DebugSettings.CitizenInstanceId == instanceId) && (DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == instanceData.m_citizen) && (DebugSettings.SourceBuildingId == 0 || DebugSettings.SourceBuildingId == instanceData.m_sourceBuilding) && (DebugSettings.TargetBuildingId == 0 || DebugSettings.TargetBuildingId == instanceData.m_targetBuilding); bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug; bool extendedLogParkingAi = DebugSwitch.ExtendedParkingAILog.Get() && citizenDebug; #else var logParkingAi = false; var extendedLogParkingAi = false; #endif #if DEBUG ExtPathMode logPathMode = extInstance.pathMode; #else var logPathMode = 0; #endif switch (extInstance.pathMode) { // check if the citizen has reached a parked car or target case ExtPathMode.WalkingToParkedCar: case ExtPathMode.ApproachingParkedCar: { Citizen[] citizensBuffer = Singleton <CitizenManager> .instance.m_citizens.m_buffer; ushort parkedVehicleId = citizensBuffer[instanceData.m_citizen].m_parkedVehicle; if (parkedVehicleId == 0) { // citizen is reaching their parked car but does not own a parked car Log._DebugOnlyWarningIf( logParkingAi, () => $"CustomHumanAI.ExtSimulationStep({instanceId}): " + $"Citizen instance {instanceId} was walking to / reaching " + $"their parked car ({logPathMode}) but parked " + "car has disappeared. RESET."); extCitInstMan.Reset(ref extInstance); instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); InvalidPath(instanceId, ref instanceData); return(true); } VehicleParked[] parkedVehicles = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer; ParkedCarApproachState approachState = AdvancedParkingManager.Instance.CitizenApproachingParkedCarSimulationStep( instanceId, ref instanceData, ref extInstance, physicsLodRefPos, ref parkedVehicles[parkedVehicleId]); switch (approachState) { case ParkedCarApproachState.None: default: break; case ParkedCarApproachState.Approaching: // citizen approaches their parked car return(true); case ParkedCarApproachState.Approached: { // citizen reached their parked car Log._DebugIf( extendedLogParkingAi, () => $"CustomHumanAI.CustomSimulationStep({instanceId}): " + $"Citizen instance {instanceId} arrived at parked car. " + $"PathMode={logPathMode}"); if (instanceData.m_path != 0) { Singleton <PathManager> .instance.ReleasePath(instanceData.m_path); instanceData.m_path = 0; } instanceData.m_flags &= CitizenInstance.Flags.Created | CitizenInstance.Flags.Cheering | CitizenInstance.Flags.Deleted | CitizenInstance.Flags.Underground | CitizenInstance.Flags.CustomName | CitizenInstance.Flags.Character | CitizenInstance.Flags.BorrowCar | CitizenInstance.Flags.HangAround | CitizenInstance.Flags.InsideBuilding | CitizenInstance.Flags.WaitingPath | CitizenInstance.Flags.TryingSpawnVehicle | CitizenInstance.Flags.CannotUseTransport | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.OnPath | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.AtTarget | CitizenInstance.Flags.RequireSlowStart | CitizenInstance.Flags.Transition | CitizenInstance.Flags.RidingBicycle | CitizenInstance.Flags.OnBikeLane | CitizenInstance.Flags.CannotUseTaxi | CitizenInstance.Flags.CustomColor | CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating | CitizenInstance.Flags.TargetFlags; if (StartPathFind(instanceId, ref instanceData)) { return(true); } else { instanceData.Unspawn(instanceId); extCitInstMan.Reset(ref extInstance); return(true); } } case ParkedCarApproachState.Failure: { Log._DebugIf( logParkingAi, () => $"CustomHumanAI.ExtSimulationStep({instanceId}): " + $"Citizen instance {instanceId} failed to arrive at " + $"parked car. PathMode={logPathMode}"); // repeat path-finding instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); InvalidPath(instanceId, ref instanceData); return(true); } } break; } case ExtPathMode.WalkingToTarget: case ExtPathMode.TaxiToTarget: { AdvancedParkingManager.Instance.CitizenApproachingTargetSimulationStep( instanceId, ref instanceData, ref extInstance); break; } } return(false); }
internal bool ExtSimulationStep(ushort instanceID, ref CitizenInstance instanceData, ref ExtCitizenInstance extInstance, Vector3 physicsLodRefPos) { // check if the citizen has reached a parked car or target if (extInstance.pathMode == ExtPathMode.WalkingToParkedCar || extInstance.pathMode == ExtPathMode.ApproachingParkedCar) { ushort parkedVehicleId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[instanceData.m_citizen].m_parkedVehicle; if (parkedVehicleId == 0) { // citizen is reaching their parked car but does not own a parked car #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log.Warning($"CustomHumanAI.CustomSimulationStep({instanceID}): Citizen instance {instanceID} was walking to / reaching their parked car ({extInstance.pathMode}) but parked car has disappeared. RESET."); } #endif extInstance.Reset(); instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); this.InvalidPath(instanceID, ref instanceData); return(true); } else { ParkedCarApproachState approachState = AdvancedParkingManager.Instance.CitizenApproachingParkedCarSimulationStep(instanceID, ref instanceData, ref extInstance, physicsLodRefPos, ref Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId]); switch (approachState) { case ParkedCarApproachState.None: default: break; case ParkedCarApproachState.Approaching: // citizen approaches their parked car return(true); case ParkedCarApproachState.Approached: // citizen reached their parked car #if DEBUG if (GlobalConfig.Instance.Debug.Switches[4]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Citizen instance {instanceID} arrived at parked car. PathMode={extInstance.pathMode}"); } #endif if (instanceData.m_path != 0) { Singleton <PathManager> .instance.ReleasePath(instanceData.m_path); instanceData.m_path = 0; } instanceData.m_flags = instanceData.m_flags & (CitizenInstance.Flags.Created | CitizenInstance.Flags.Cheering | CitizenInstance.Flags.Deleted | CitizenInstance.Flags.Underground | CitizenInstance.Flags.CustomName | CitizenInstance.Flags.Character | CitizenInstance.Flags.BorrowCar | CitizenInstance.Flags.HangAround | CitizenInstance.Flags.InsideBuilding | CitizenInstance.Flags.WaitingPath | CitizenInstance.Flags.TryingSpawnVehicle | CitizenInstance.Flags.CannotUseTransport | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.OnPath | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.AtTarget | CitizenInstance.Flags.RequireSlowStart | CitizenInstance.Flags.Transition | CitizenInstance.Flags.RidingBicycle | CitizenInstance.Flags.OnBikeLane | CitizenInstance.Flags.CannotUseTaxi | CitizenInstance.Flags.CustomColor | CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating | CitizenInstance.Flags.TargetFlags); if (!this.StartPathFind(instanceID, ref instanceData)) { instanceData.Unspawn(instanceID); extInstance.Reset(); } return(true); case ParkedCarApproachState.Failure: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Citizen instance {instanceID} failed to arrive at parked car. PathMode={extInstance.pathMode}"); } #endif // repeat path-finding instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); this.InvalidPath(instanceID, ref instanceData); return(true); } } } else if ((extInstance.pathMode == ExtCitizenInstance.ExtPathMode.WalkingToTarget || extInstance.pathMode == ExtCitizenInstance.ExtPathMode.PublicTransportToTarget || extInstance.pathMode == ExtCitizenInstance.ExtPathMode.TaxiToTarget) ) { AdvancedParkingManager.Instance.CitizenApproachingTargetSimulationStep(instanceID, ref instanceData, ref extInstance); } return(false); }