// from CitizenAI public static bool FindPathPosition(ushort instanceID, ref CitizenInstance citizenData, Vector3 pos, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, out PathUnit.Position position) { position = default(PathUnit.Position); float num = 1E+10f; PathUnit.Position position2; PathUnit.Position position3; float num2; float num3; if (CustomPathManager.FindPathPosition(pos, ItemClass.Service.Road, laneTypes, vehicleTypes, allowUnderground, 32f, out position2, out position3, out num2, out num3, RoadManager.VehicleType.PassengerCar) && num2 < num) { num = num2; position = position2; } PathUnit.Position position4; PathUnit.Position position5; float num4; float num5; if (CustomPathManager.FindPathPosition(pos, ItemClass.Service.Beautification, laneTypes, vehicleTypes, allowUnderground, 32f, out position4, out position5, out num4, out num5, RoadManager.VehicleType.PassengerCar) && num4 < num) { num = num4; position = position4; } PathUnit.Position position6; PathUnit.Position position7; float num6; float num7; if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None && CustomPathManager.FindPathPosition(pos, ItemClass.Service.PublicTransport, laneTypes, vehicleTypes, allowUnderground, 32f, out position6, out position7, out num6, out num7, RoadManager.VehicleType.PassengerCar) && num6 < num) { position = position6; } return position.m_segment != 0; }
protected new bool StartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo) { NetInfo.LaneType laneType = NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None; bool randomParking = false; if (vehicleInfo != null) { if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton<DistrictManager>.instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u) { SimulationManager instance = Singleton<SimulationManager>.instance; if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0) { laneType |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); vehicleType |= vehicleInfo.m_vehicleType; } } } else { laneType |= NetInfo.LaneType.Vehicle; vehicleType |= vehicleInfo.m_vehicleType; if (citizenData.m_targetBuilding != 0 && Singleton<BuildingManager>.instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info.m_class.m_service > ItemClass.Service.Office) { randomParking = true; } } } PathUnit.Position vehiclePosition = default(PathUnit.Position); ushort parkedVehicle = Singleton<CitizenManager>.instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle; if (parkedVehicle != 0) { Vector3 position = Singleton<VehicleManager>.instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position; PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition); } bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None; PathUnit.Position startPosA; PathUnit.Position endPosA; if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) && this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA)) { if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) { laneType |= NetInfo.LaneType.PublicTransport; } PathUnit.Position position2 = default(PathUnit.Position); uint path; if (Singleton<PathManager>.instance.CreatePath(ExtendedVehicleType.PassengerCar, out path, ref Singleton<SimulationManager>.instance.m_randomizer, Singleton<SimulationManager>.instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false, randomParking)) { if (citizenData.m_path != 0u) { Singleton<PathManager>.instance.ReleasePath(citizenData.m_path); } citizenData.m_path = path; citizenData.m_flags |= CitizenInstance.Flags.WaitingPath; return true; } } return false; }
public override void SimulationStep(ushort instanceID, ref CitizenInstance citizenData, ref CitizenInstance.Frame frameData, bool lodPhysics) { base.SimulationStep(instanceID, ref citizenData, ref frameData, lodPhysics); if ((citizenData.m_flags & CitizenInstance.Flags.WaitingTransport) != CitizenInstance.Flags.None && citizenData.m_waitCounter > 0) { if (Singleton<SimulationManager>.instance.m_randomizer.Int32(3) == 0) { citizenData.m_waitCounter = (byte)(citizenData.m_waitCounter - 1); } else { AddCommuteWait(citizenData.m_citizen, 1); } } }
protected override VehicleInfo GetVehicleInfo(ushort instanceID, ref CitizenInstance citizenData, bool forceProbability) { if (citizenData.m_citizen == 0u) { return null; } int num; int num2; int num3; if (forceProbability || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { num = 100; num2 = 0; num3 = 0; } else { num = this.GetCarProbability (); num2 = this.GetBikeProbability (); num3 = this.GetTaxiProbability (); } Randomizer randomizer = new Randomizer (citizenData.m_citizen); bool flag = randomizer.Int32 (100u) < num; bool flag2 = randomizer.Int32 (100u) < num2; bool flag3 = randomizer.Int32 (100u) < num3; ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = ItemClass.SubService.ResidentialLow; if (!flag && flag3) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } VehicleInfo randomVehicleInfo = Singleton<VehicleManager>.instance.GetRandomVehicleInfo (ref randomizer, service, subService, ItemClass.Level.Level1); VehicleInfo randomVehicleInfo2 = Singleton<VehicleManager>.instance.GetRandomVehicleInfo (ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2); if (flag2 && randomVehicleInfo2 != null) { return randomVehicleInfo2; } if ((flag || flag3) && randomVehicleInfo != null) { return randomVehicleInfo; } return null; }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider) { if (otherID == instanceID) { return otherData.m_nextGridInstance; } if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground)) { return otherData.m_nextGridInstance; } CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData (); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3 (position, b); Vector3 vector = segment2.Min (); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max (); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + info.m_radius; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a.y = 0f; b2.y = 0f; Vector3 vector3 = a - b2; Vector3 vector4 = new Vector3 (segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3.normalized * (num4 * num5); pushDivider += num5; } } return otherData.m_nextGridInstance; }
public bool CustomFindPathPosition(ushort instanceID, ref CitizenInstance citizenData, Vector3 pos, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, out PathUnit.Position position) { return(CustomPathManager.FindCitizenPathPosition(pos, laneTypes, vehicleTypes, (citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None, allowUnderground, out position)); }
/// <summary> /// Check if resident is confused. /// </summary> /// <param name="data">The citizen instance.</param> /// <returns>True if resident is confused.</returns> private static bool ResidentConfused(ref CitizenInstance data) { // From ResidentAI.GetLocalizedStatus from original game code at version 1.4.1-f2. ////CitizenManager instance1 = Singleton<CitizenManager>.instance; ////uint num1 = data.m_citizen; ////bool flag1 = false; ////ushort num2 = (ushort)0; ////ushort num3 = (ushort)0; ////ushort vehicleID = (ushort)0; ////if ((int)num1 != 0) ////{ //// num2 = instance1.m_citizens.m_buffer[(IntPtr)num1].m_homeBuilding; //// num3 = instance1.m_citizens.m_buffer[(IntPtr)num1].m_workBuilding; //// vehicleID = instance1.m_citizens.m_buffer[(IntPtr)num1].m_vehicle; //// flag1 = (instance1.m_citizens.m_buffer[(IntPtr)num1].m_flags & Citizen.Flags.Student) != Citizen.Flags.None; ////} ushort num4 = data.m_targetBuilding; if ((int)num4 != 0) { ////bool flag2 = (Singleton<BuildingManager>.instance.m_buildings.m_buffer[(int)num4].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None; ////bool flag3 = (int)data.m_path == 0 && (data.m_flags & CitizenInstance.Flags.HangAround) != CitizenInstance.Flags.None; ////if ((int)vehicleID != 0) ////{ //// VehicleManager instance2 = Singleton<VehicleManager>.instance; //// VehicleInfo info = instance2.m_vehicles.m_buffer[(int)vehicleID].Info; //// if (info.m_class.m_service == ItemClass.Service.Residential && info.m_vehicleType != VehicleInfo.VehicleType.Bicycle) //// { //// if ((int)info.m_vehicleAI.GetOwnerID(vehicleID, ref instance2.m_vehicles.m_buffer[(int)vehicleID]).Citizen == (int)num1) //// { //// if (flag2) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_DRIVINGTO_OUTSIDE"); //// } //// if ((int)num4 == (int)num2) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_DRIVINGTO_HOME"); //// } //// if ((int)num4 == (int)num3) //// { //// target = InstanceID.Empty; //// return Locale.Get(!flag1 ? "CITIZEN_STATUS_DRIVINGTO_WORK" : "CITIZEN_STATUS_DRIVINGTO_SCHOOL"); //// } //// target = InstanceID.Empty; //// target.Building = num4; //// return Locale.Get("CITIZEN_STATUS_DRIVINGTO"); //// } //// } //// else if (info.m_class.m_service == ItemClass.Service.PublicTransport) //// { //// if ((data.m_flags & CitizenInstance.Flags.WaitingTaxi) != CitizenInstance.Flags.None) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_WAITING_TAXI"); //// } //// if (flag2) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_OUTSIDE"); //// } //// if ((int)num4 == (int)num2) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_HOME"); //// } //// if ((int)num4 == (int)num3) //// { //// target = InstanceID.Empty; //// return Locale.Get(!flag1 ? "CITIZEN_STATUS_TRAVELLINGTO_WORK" : "CITIZEN_STATUS_TRAVELLINGTO_SCHOOL"); //// } //// target = InstanceID.Empty; //// target.Building = num4; //// return Locale.Get("CITIZEN_STATUS_TRAVELLINGTO"); //// } ////} ////if (flag2) ////{ //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_GOINGTO_OUTSIDE"); ////} ////if ((int)num4 == (int)num2) ////{ //// if (flag3) //// { //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_AT_HOME"); //// } //// target = InstanceID.Empty; //// return Locale.Get("CITIZEN_STATUS_GOINGTO_HOME"); ////} ////if ((int)num4 == (int)num3) ////{ //// if (flag3) //// { //// target = InstanceID.Empty; //// return Locale.Get(!flag1 ? "CITIZEN_STATUS_AT_WORK" : "CITIZEN_STATUS_AT_SCHOOL"); //// } //// target = InstanceID.Empty; //// return Locale.Get(!flag1 ? "CITIZEN_STATUS_GOINGTO_WORK" : "CITIZEN_STATUS_GOINGTO_SCHOOL"); ////} ////if (flag3) ////{ //// target = InstanceID.Empty; //// target.Building = num4; //// return Locale.Get("CITIZEN_STATUS_VISITING"); ////} ////target = InstanceID.Empty; ////target.Building = num4; ////return Locale.Get("CITIZEN_STATUS_GOINGTO"); return false; } ////target = InstanceID.Empty; ////return Locale.Get("CITIZEN_STATUS_CONFUSED"); return true; }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref Vehicle otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { return otherData.m_nextGridVehicle; } if ((otherData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (otherData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None)) { return otherData.m_nextGridVehicle; } Segment3 segment2 = otherData.m_segment; Vector3 vector = Vector3.Min (segment2.Min (), otherData.m_targetPos1); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = Vector3.Max (segment2.Max (), otherData.m_targetPos1); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b = segment2.Position (t); a.y = 0f; b.y = 0f; Vector3 vector3 = Vector3.Normalize (a - b); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } float magnitude = otherData.GetLastFrameVelocity ().magnitude; if (magnitude > 0.1f) { float num6 = this.m_info.m_radius + 3f; segment2.a = segment2.b; segment2.b += Vector3.ClampMagnitude (((Vector3)otherData.m_targetPos1) - segment2.b, magnitude * 4f); num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 > num * num && num2 < num6 * num6) { float num7 = num6 - Mathf.Sqrt (num2); float num8 = 1f - num2 / (num6 * num6); Vector3 a2 = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a2.y = 0f; b2.y = 0f; Vector3 vector5 = a2 - b2; pushAmount += vector5.normalized * (num7 * num8); pushDivider += num8; } } } return otherData.m_nextGridVehicle; }
protected override bool StartPathFind(ushort instanceID, ref CitizenInstance citizenData) { if (citizenData.m_citizen != 0u) { CitizenManager instance = Singleton<CitizenManager>.instance; VehicleManager instance2 = Singleton<VehicleManager>.instance; ushort vehicle = instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].m_vehicle; if (vehicle != 0) { VehicleInfo info = instance2.m_vehicles.m_buffer[(int)vehicle].Info; if (info != null) { uint citizen = info.m_vehicleAI.GetOwnerID(vehicle, ref instance2.m_vehicles.m_buffer[(int)vehicle]).Citizen; if (citizen == citizenData.m_citizen) { info.m_vehicleAI.SetTarget(vehicle, ref instance2.m_vehicles.m_buffer[(int)vehicle], 0); return false; } else { instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].SetVehicle(citizenData.m_citizen, 0, 0u); } } instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].SetVehicle(citizenData.m_citizen, 0, 0u); return false; } } if (citizenData.m_targetBuilding != 0) { VehicleInfo vehicleInfo = base.GetVehicleInfo(instanceID, ref citizenData, false); BuildingManager instance3 = Singleton<BuildingManager>.instance; BuildingInfo info2 = instance3.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info; Randomizer randomizer = new Randomizer((int)instanceID << 8 | (int)citizenData.m_targetSeed); Vector3 vector; Vector3 endPos; Vector2 vector2; CitizenInstance.Flags flags; info2.m_buildingAI.CalculateUnspawnPosition(citizenData.m_targetBuilding, ref instance3.m_buildings.m_buffer[(int)citizenData.m_targetBuilding], ref randomizer, this.m_info, instanceID, out vector, out endPos, out vector2, out flags); if (!base.StartPathFind(instanceID, ref citizenData, citizenData.m_targetPos, endPos, vehicleInfo)) { if (vehicleInfo == null) { vehicleInfo = base.GetVehicleInfo(instanceID, ref citizenData, true); var result = base.StartPathFind(instanceID, ref citizenData, citizenData.m_targetPos, endPos, vehicleInfo); return result; } else { return false; } } else { return true; } } return false; }
public bool ExtStartPathFind(ushort instanceID, ref CitizenInstance instanceData, ref ExtCitizenInstance extInstance, ref ExtCitizen extCitizen, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo, bool enableTransport, bool ignoreCost) { #if DEBUG bool citDebug = GlobalConfig.Instance.Debug.CitizenId == 0 || GlobalConfig.Instance.Debug.CitizenId == instanceData.m_citizen; bool debug = GlobalConfig.Instance.Debug.Switches[2] && citDebug; bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && citDebug; if (debug) { Log.Warning($"CustomCitizenAI.ExtStartPathFind({instanceID}): called for citizen {instanceData.m_citizen}, startPos={startPos}, endPos={endPos}, sourceBuilding={instanceData.m_sourceBuilding}, targetBuilding={instanceData.m_targetBuilding}, pathMode={extInstance.pathMode}, enableTransport={enableTransport}, ignoreCost={ignoreCost}"); } #endif // NON-STOCK CODE START CitizenManager citizenManager = Singleton <CitizenManager> .instance; ushort parkedVehicleId = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_parkedVehicle; ushort homeId = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_homeBuilding; CarUsagePolicy carUsageMode = CarUsagePolicy.Allowed; #if BENCHMARK using (var bm = new Benchmark(null, "ParkingAI.Preparation")) { #endif if (Options.prohibitPocketCars) { switch (extInstance.pathMode) { case ExtPathMode.RequiresWalkingPathToParkedCar: case ExtPathMode.CalculatingWalkingPathToParkedCar: case ExtPathMode.WalkingToParkedCar: case ExtPathMode.ApproachingParkedCar: if (parkedVehicleId == 0) { /* * Parked vehicle not present but citizen wants to reach it * -> Reset path mode */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode} but no parked vehicle present. Change to 'None'."); } #endif extInstance.Reset(); } else { /* * Parked vehicle is present and citizen wants to reach it * -> Prohibit car usage */ #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'CalculatingWalkingPathToParkedCar'."); } #endif extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToParkedCar; carUsageMode = CarUsagePolicy.Forbidden; } break; case ExtPathMode.RequiresWalkingPathToTarget: case ExtPathMode.CalculatingWalkingPathToTarget: case ExtPathMode.WalkingToTarget: /* * Citizen walks to target * -> Reset path mode */ #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'CalculatingWalkingPathToTarget'."); } #endif extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToTarget; carUsageMode = CarUsagePolicy.Forbidden; break; case ExtPathMode.RequiresCarPath: case ExtPathMode.RequiresMixedCarPathToTarget: case ExtPathMode.DrivingToTarget: case ExtPathMode.DrivingToKnownParkPos: case ExtPathMode.DrivingToAltParkPos: case ExtPathMode.CalculatingCarPathToAltParkPos: case ExtPathMode.CalculatingCarPathToKnownParkPos: case ExtPathMode.CalculatingCarPathToTarget: if (parkedVehicleId == 0) { /* * Citizen wants to drive to target but parked vehicle is not present * -> Reset path mode */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode} but no parked vehicle present. Change to 'None'."); } #endif extInstance.Reset(); } else { /* * Citizen wants to drive to target and parked vehicle is present * -> Force parked car usage */ #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'RequiresCarPath'."); } #endif extInstance.pathMode = ExtPathMode.RequiresCarPath; carUsageMode = CarUsagePolicy.ForcedParked; startPos = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position; // force to start from the parked car } break; default: #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'None'."); } #endif extInstance.Reset(); break; } if (extInstance.pathMode == ExtPathMode.None) { if ((instanceData.m_flags & CitizenInstance.Flags.OnTour) != CitizenInstance.Flags.None || ignoreCost) { /* * Citizen is on a walking tour or is a mascot * -> Prohibit car usage */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen ignores cost ({ignoreCost}) or is on a walking tour ({(instanceData.m_flags & CitizenInstance.Flags.OnTour) != CitizenInstance.Flags.None}): Setting path mode to 'CalculatingWalkingPathToTarget'"); } #endif carUsageMode = CarUsagePolicy.Forbidden; extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToTarget; } else { /* * Citizen is not on a walking tour and is not a mascot * -> Check if citizen is located at an outside connection and make them obey Parking AI restrictions */ if (instanceData.m_sourceBuilding != 0) { ItemClass.Service sourceBuildingService = Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_sourceBuilding].Info.m_class.m_service; if ( (Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_sourceBuilding].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None && (startPos - Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_sourceBuilding].m_position).magnitude <= GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance ) { if (sourceBuildingService == ItemClass.Service.Road) { if (vehicleInfo != null) { /* * Citizen is located at a road outside connection and can spawn a car * -> Force car usage */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is located at a road outside connection: Setting path mode to 'RequiresCarPath' and carUsageMode to 'ForcedPocket'"); } #endif extInstance.pathMode = ExtPathMode.RequiresCarPath; carUsageMode = CarUsagePolicy.ForcedPocket; } else { /* * Citizen is located at a non-road outside connection and cannot spawn a car * -> Path-finding fails */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is located at a road outside connection but does not have a car template: ABORTING PATH-FINDING"); } #endif return(false); } } else { /* * Citizen is located at a non-road outside connection * -> Prohibit car usage */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is located at a non-road outside connection: Setting path mode to 'CalculatingWalkingPathToTarget'"); } #endif extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToTarget; carUsageMode = CarUsagePolicy.Forbidden; } } } } } if ((carUsageMode == CarUsagePolicy.Allowed || carUsageMode == CarUsagePolicy.ForcedParked) && parkedVehicleId != 0) { /* * Reuse parked vehicle info */ vehicleInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info; /* * Check if the citizen should return their car back home */ if (extInstance.pathMode == ExtPathMode.None && // initiating a new path homeId != 0 && // home building present instanceData.m_targetBuilding == homeId // current target is home ) { /* * citizen travels back home * -> check if their car should be returned */ if ((extCitizen.lastTransportMode & ExtCitizen.ExtTransportMode.Car) != ExtCitizen.ExtTransportMode.None) { /* * citizen travelled by car * -> return car back home */ extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar; carUsageMode = CarUsagePolicy.Forbidden; #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen used their car before and is not at home. Forcing to walk to parked car."); } #endif } else { /* * citizen travelled by other means of transport * -> check distance between home and parked car. if too far away: force to take the car back home */ float distHomeToParked = (Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position - Singleton <BuildingManager> .instance.m_buildings.m_buffer[homeId].m_position).magnitude; if (distHomeToParked > GlobalConfig.Instance.ParkingAI.MaxParkedCarDistanceToHome) { /* * force to take car back home */ extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar; carUsageMode = CarUsagePolicy.Forbidden; #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen wants to go home and parked car is too far away ({distHomeToParked}). Forcing walking to parked car."); } #endif } } } } /* * The following holds: * - pathMode is now either CalculatingWalkingPathToParkedCar, CalculatingWalkingPathToTarget, RequiresCarPath or None. * - if pathMode is CalculatingWalkingPathToParkedCar or RequiresCarPath: parked car is present and citizen is not on a walking tour * - carUsageMode is valid * - if pathMode is RequiresCarPath: carUsageMode is either ForcedParked or ForcedPocket */ /* * modify path-finding constraints (vehicleInfo, endPos) if citizen is forced to walk */ if (extInstance.pathMode == ExtPathMode.CalculatingWalkingPathToParkedCar || extInstance.pathMode == ExtPathMode.CalculatingWalkingPathToTarget) { /* * vehicle must not be used since we need a walking path to either * 1. a parked car or * 2. the target building */ if (extInstance.pathMode == ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar) { /* * walk to parked car * -> end position is parked car */ endPos = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position; #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen shall go to parked vehicle @ {endPos}"); } #endif } } } #if BENCHMARK } #endif #if DEBUG if (fineDebug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is allowed to drive their car? {carUsageMode}"); } #endif // NON-STOCK CODE END /* * semi-stock code: determine path-finding parameters (laneTypes, vehicleTypes, extVehicleType, etc.) */ NetInfo.LaneType laneTypes = NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleTypes = VehicleInfo.VehicleType.None; bool randomParking = false; bool combustionEngine = false; ExtVehicleType extVehicleType = ExtVehicleType.None; if (vehicleInfo != null) { if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { if ((instanceData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u) { SimulationManager instance = Singleton <SimulationManager> .instance; if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0) { laneTypes |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); vehicleTypes |= vehicleInfo.m_vehicleType; extVehicleType = ExtVehicleType.Taxi; // NON-STOCK CODE // NON-STOCK CODE START if (Options.prohibitPocketCars) { extInstance.pathMode = ExtPathMode.TaxiToTarget; } // NON-STOCK CODE END } } } else // NON-STOCK CODE START if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Car) { if (carUsageMode != CarUsagePolicy.Forbidden) { extVehicleType = ExtVehicleType.PassengerCar; laneTypes |= NetInfo.LaneType.Vehicle; vehicleTypes |= vehicleInfo.m_vehicleType; combustionEngine = vehicleInfo.m_class.m_subService == ItemClass.SubService.ResidentialLow; } } else if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { extVehicleType = ExtVehicleType.Bicycle; laneTypes |= NetInfo.LaneType.Vehicle; vehicleTypes |= vehicleInfo.m_vehicleType; } // NON-STOCK CODE END } // NON-STOCK CODE START ExtPathType extPathType = ExtPathType.None; PathUnit.Position endPosA = default(PathUnit.Position); bool calculateEndPos = true; bool allowRandomParking = true; #if BENCHMARK using (var bm = new Benchmark(null, "ParkingAI.Main")) { #endif if (Options.prohibitPocketCars) { // Parking AI if (extInstance.pathMode == ExtCitizenInstance.ExtPathMode.RequiresCarPath) { #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Setting startPos={startPos} for citizen instance {instanceID}. CurrentDepartureMode={extInstance.pathMode}"); } #endif if ( instanceData.m_targetBuilding == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.None ) { /* * the citizen is starting their journey and the target is not an outside connection * -> find a suitable parking space near the target */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Finding parking space at target for citizen instance {instanceID}. CurrentDepartureMode={extInstance.pathMode} parkedVehicleId={parkedVehicleId}"); } #endif // find a parking space in the vicinity of the target bool calcEndPos; Vector3 parkPos; if ( AdvancedParkingManager.Instance.FindParkingSpaceForCitizen(endPos, vehicleInfo, ref extInstance, homeId, instanceData.m_targetBuilding == homeId, 0, false, out parkPos, ref endPosA, out calcEndPos) && extInstance.CalculateReturnPath(parkPos, endPos) ) { // success extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingCarPathToKnownParkPos; calculateEndPos = calcEndPos; // if true, the end path position still needs to be calculated allowRandomParking = false; // find a direct path to the calculated parking position #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Finding known parking space for citizen instance {instanceID}, parked vehicle {parkedVehicleId} succeeded and return path {extInstance.returnPathId} ({extInstance.returnPathState}) is calculating. PathMode={extInstance.pathMode}"); } #endif /*if (! extInstance.CalculateReturnPath(parkPos, endPos)) { * // TODO retry? * if (debug) * Log._Debug($"CustomCitizenAI.CustomStartPathFind: [PFFAIL] Could not calculate return path for citizen instance {instanceID}, parked vehicle {parkedVehicleId}. Calling OnPathFindFailed."); * CustomHumanAI.OnPathFindFailure(extInstance); * return false; * }*/ } } if (extInstance.pathMode == ExtPathMode.RequiresCarPath) { /* * no known parking space found (pathMode has not been updated in the block above) * -> calculate direct path to target */ #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen instance {instanceID} is still at CurrentPathMode={extInstance.pathMode} (no parking space found?). Setting it to CalculatingCarPath. parkedVehicleId={parkedVehicleId}"); } #endif extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingCarPathToTarget; } } /* * determine path type from path mode */ extPathType = extInstance.GetPathType(); /* * the following holds: * - pathMode is now either CalculatingWalkingPathToParkedCar, CalculatingWalkingPathToTarget, CalculatingCarPathToTarget, CalculatingCarPathToKnownParkPos or None. */ } #if BENCHMARK } #endif /* * enable random parking if exact parking space was not calculated yet */ if (extVehicleType == ExtVehicleType.PassengerCar || extVehicleType == ExtVehicleType.Bicycle) { if (allowRandomParking && instanceData.m_targetBuilding != 0 && ( Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].Info.m_class.m_service > ItemClass.Service.Office || (instanceData.m_flags & CitizenInstance.Flags.TargetIsNode) != 0 )) { randomParking = true; } } // NON-STOCK CODE END /* * determine the path position of the parked vehicle */ PathUnit.Position parkedVehiclePathPos = default(PathUnit.Position); if (parkedVehicleId != 0 && extVehicleType == ExtVehicleType.PassengerCar) { Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position; CustomPathManager.FindPathPositionWithSpiralLoop(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out parkedVehiclePathPos); } bool allowUnderground = (instanceData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None; #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Requesting path-finding for citizen instance {instanceID}, citizen {instanceData.m_citizen}, extVehicleType={extVehicleType}, extPathType={extPathType}, startPos={startPos}, endPos={endPos}, sourceBuilding={instanceData.m_sourceBuilding}, targetBuilding={instanceData.m_targetBuilding} pathMode={extInstance.pathMode}"); } #endif /* * determine start & end path positions */ bool foundEndPos = !calculateEndPos || FindPathPosition(instanceID, ref instanceData, endPos, Options.prohibitPocketCars && (instanceData.m_targetBuilding == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.None) ? NetInfo.LaneType.Pedestrian : laneTypes, vehicleTypes, false, out endPosA); // NON-STOCK CODE: with Parking AI enabled, the end position must be a pedestrian position bool foundStartPos = false; PathUnit.Position startPosA; if (Options.prohibitPocketCars && (extInstance.pathMode == ExtPathMode.CalculatingCarPathToTarget || extInstance.pathMode == ExtPathMode.CalculatingCarPathToKnownParkPos)) { /* * citizen will enter their car now * -> find a road start position */ foundStartPos = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, laneTypes & ~NetInfo.LaneType.Pedestrian, vehicleTypes, allowUnderground, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out startPosA); } else { foundStartPos = FindPathPosition(instanceID, ref instanceData, startPos, laneTypes, vehicleTypes, allowUnderground, out startPosA); } /* * start path-finding */ if (foundStartPos && // TODO probably fails if vehicle is parked too far away from road foundEndPos // NON-STOCK CODE ) { if (enableTransport) { /* * public transport usage is allowed for this path */ if ((instanceData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) { /* * citizen may use public transport */ laneTypes |= NetInfo.LaneType.PublicTransport; uint citizenId = instanceData.m_citizen; if (citizenId != 0u && (citizenManager.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Evacuating) != Citizen.Flags.None) { laneTypes |= NetInfo.LaneType.EvacuationTransport; } } else if (Options.prohibitPocketCars) // TODO check for incoming connection /* * citizen tried to use public transport but waiting time was too long * -> add public transport demand for source building */ { if (instanceData.m_sourceBuilding != 0) { #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen instance {instanceID} cannot uses public transport from building {instanceData.m_sourceBuilding} to {instanceData.m_targetBuilding}. Incrementing public transport demand."); } #endif ExtBuildingManager.Instance.ExtBuildings[instanceData.m_sourceBuilding].AddPublicTransportDemand((uint)GlobalConfig.Instance.ParkingAI.PublicTransportDemandWaitingIncrement, true); } } } PathUnit.Position dummyPathPos = default(PathUnit.Position); uint path; // NON-STOCK CODE START PathCreationArgs args; args.extPathType = extPathType; args.extVehicleType = extVehicleType; args.vehicleId = 0; args.spawned = (instanceData.m_flags & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None; args.buildIndex = Singleton <SimulationManager> .instance.m_currentBuildIndex; args.startPosA = startPosA; args.startPosB = dummyPathPos; args.endPosA = endPosA; args.endPosB = dummyPathPos; args.vehiclePosition = parkedVehiclePathPos; args.laneTypes = laneTypes; args.vehicleTypes = vehicleTypes; args.maxLength = 20000f; args.isHeavyVehicle = false; args.hasCombustionEngine = combustionEngine; args.ignoreBlocked = false; args.ignoreFlooded = false; args.ignoreCosts = ignoreCost; args.randomParking = randomParking; args.stablePath = false; args.skipQueue = false; if ((instanceData.m_flags & CitizenInstance.Flags.OnTour) != 0) { args.stablePath = true; args.maxLength = 160000f; //args.laneTypes &= ~(NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); } else { args.stablePath = false; args.maxLength = 20000f; } bool res = CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args); // NON-STOCK CODE END if (res) { #if DEBUG if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Path-finding starts for citizen instance {instanceID}, path={path}, extVehicleType={extVehicleType}, extPathType={extPathType}, startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, laneType={laneTypes}, vehicleType={vehicleTypes}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}, vehiclePos.m_segment={parkedVehiclePathPos.m_segment}, vehiclePos.m_lane={parkedVehiclePathPos.m_lane}, vehiclePos.m_offset={parkedVehiclePathPos.m_offset}"); } #endif if (instanceData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(instanceData.m_path); } instanceData.m_path = path; instanceData.m_flags |= CitizenInstance.Flags.WaitingPath; return(true); } } #if DEBUG if (Options.prohibitPocketCars) { if (debug) { Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): CustomCitizenAI.CustomStartPathFind: [PFFAIL] failed for citizen instance {instanceID} (CurrentPathMode={extInstance.pathMode}). startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, startPosA.offset={startPosA.m_offset}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}, endPosA.offset={endPosA.m_offset}, foundStartPos={foundStartPos}, foundEndPos={foundEndPos}"); } } #endif return(false); }
public string CustomGetLocalizedStatus(ushort instanceID, ref CitizenInstance data, out InstanceID target) { if ((data.m_flags & (CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) != CitizenInstance.Flags.None) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_CONFUSED")); } CitizenManager citMan = Singleton <CitizenManager> .instance; uint citizenId = data.m_citizen; bool isStudent = false; ushort homeId = 0; ushort workId = 0; ushort vehicleId = 0; if (citizenId != 0u) { homeId = citMan.m_citizens.m_buffer[citizenId].m_homeBuilding; workId = citMan.m_citizens.m_buffer[citizenId].m_workBuilding; vehicleId = citMan.m_citizens.m_buffer[citizenId].m_vehicle; isStudent = ((citMan.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Student) != Citizen.Flags.None); } ushort targetBuilding = data.m_targetBuilding; if (targetBuilding == 0) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_CONFUSED")); } bool isOutsideConnection = (Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuilding].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None; bool hangsAround = data.m_path == 0u && (data.m_flags & CitizenInstance.Flags.HangAround) != CitizenInstance.Flags.None; String ret = ""; if (vehicleId != 0) { VehicleManager instance2 = Singleton <VehicleManager> .instance; VehicleInfo info = instance2.m_vehicles.m_buffer[(int)vehicleId].Info; if (info.m_class.m_service == ItemClass.Service.Residential && info.m_vehicleType != VehicleInfo.VehicleType.Bicycle) { if (info.m_vehicleAI.GetOwnerID(vehicleId, ref instance2.m_vehicles.m_buffer[(int)vehicleId]).Citizen == citizenId) { if (isOutsideConnection) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO_OUTSIDE")); } if (targetBuilding == homeId) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO_HOME")); } else if (targetBuilding == workId) { target = InstanceID.Empty; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_DRIVINGTO_WORK" : "CITIZEN_STATUS_DRIVINGTO_SCHOOL")); } else { target = InstanceID.Empty; target.Building = targetBuilding; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO")); } } } else if (info.m_class.m_service == ItemClass.Service.PublicTransport || info.m_class.m_service == ItemClass.Service.Disaster) { if ((data.m_flags & CitizenInstance.Flags.WaitingTaxi) != CitizenInstance.Flags.None) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_WAITING_TAXI")); } if (isOutsideConnection) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_OUTSIDE")); } if (targetBuilding == homeId) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_HOME")); } if (targetBuilding == workId) { target = InstanceID.Empty; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_TRAVELLINGTO_WORK" : "CITIZEN_STATUS_TRAVELLINGTO_SCHOOL")); } target = InstanceID.Empty; target.Building = targetBuilding; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO")); } } if (isOutsideConnection) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_GOINGTO_OUTSIDE")); } if (targetBuilding == homeId) { if (hangsAround) { target = InstanceID.Empty; return(Locale.Get("CITIZEN_STATUS_AT_HOME")); } target = InstanceID.Empty; ret = Locale.Get("CITIZEN_STATUS_GOINGTO_HOME"); } else if (targetBuilding == workId) { if (hangsAround) { target = InstanceID.Empty; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_AT_WORK" : "CITIZEN_STATUS_AT_SCHOOL")); } target = InstanceID.Empty; ret = Locale.Get((!isStudent) ? "CITIZEN_STATUS_GOINGTO_WORK" : "CITIZEN_STATUS_GOINGTO_SCHOOL"); } else { if (hangsAround) { target = InstanceID.Empty; target.Building = targetBuilding; return(Locale.Get("CITIZEN_STATUS_VISITING")); } target = InstanceID.Empty; target.Building = targetBuilding; ret = Locale.Get("CITIZEN_STATUS_GOINGTO"); } // NON-STOCK CODE START if (Options.prohibitPocketCars) { ret = AdvancedParkingManager.Instance.EnrichLocalizedCitizenStatus(ret, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID]); } // NON-STOCK CODE END return(ret); }
// CitizenAI public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo) { NetInfo.LaneType laneType = NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None; if (vehicleInfo != null) { if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton<DistrictManager>.instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u) { SimulationManager instance = Singleton<SimulationManager>.instance; if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0) { laneType |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); vehicleType |= vehicleInfo.m_vehicleType; } } } else { laneType |= NetInfo.LaneType.Vehicle; vehicleType |= vehicleInfo.m_vehicleType; } } PathUnit.Position vehiclePosition = default(PathUnit.Position); ushort parkedVehicle = Singleton<CitizenManager>.instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle; if (parkedVehicle != 0) { Vector3 position = Singleton<VehicleManager>.instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position; PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition); } bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None; PathUnit.Position startPosA; PathUnit.Position endPosA; if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) && this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA)) { // NON-STOCK CODE START // Citizen.Wealth wealthLevel = Singleton<CitizenManager>.instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel; byte districtId = Singleton<DistrictManager>.instance.GetDistrict(startPos); DistrictPolicies.Services servicePolicies = Singleton<DistrictManager>.instance.m_districts.m_buffer[(int)districtId].m_servicePolicies; int transportUsageProb = (servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None ? FREE_TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel] : TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel]; //bool mayUseTransport = false; if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) { // STOCK CODE if (vehicleInfo == null || (instanceID % 100)+1 <= transportUsageProb) { laneType |= NetInfo.LaneType.PublicTransport; // STOCK CODE //mayUseTransport = true; //Log._Debug($"CustomCitizenAI: citizen {instanceID} can use public transport"); } } // NON-STOCK CODE END // PathUnit.Position position2 = default(PathUnit.Position); uint path; // NON-STOCK CODE START // ExtVehicleType? extVehicleType = null; if (vehicleInfo != null) extVehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicleInfo(vehicleInfo); //Log._Debug($"CustomCitizenAI: citizen instance {instanceID}, id {citizenData.m_citizen}. {vehicleType} {extVehicleType} mayUseTransport={mayUseTransport} wealthLevel={wealthLevel}"); bool res = false; if (Options.disableSomething5 || extVehicleType == null) // NON-STOCK CODE END // res = Singleton<CustomPathManager>.instance.CreatePath(out path, ref Singleton<SimulationManager>.instance.m_randomizer, Singleton<SimulationManager>.instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false, false); // NON-STOCK CODE START // else res = Singleton<CustomPathManager>.instance.CreatePath((ExtVehicleType)extVehicleType, out path, ref Singleton<SimulationManager>.instance.m_randomizer, Singleton<SimulationManager>.instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false); // NON-STOCK CODE END // if (res) { if (citizenData.m_path != 0u) { Singleton<PathManager>.instance.ReleasePath(citizenData.m_path); } citizenData.m_path = path; citizenData.m_flags |= CitizenInstance.Flags.WaitingPath; return true; } } return false; }
private static ushort CheckCitizen(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max) { Log.Error("CustomCarAI.CheckCitizen called"); return(0); }
public VehicleInfo CustomGetVehicleInfo(ushort instanceID, ref CitizenInstance citizenData, bool forceCar) { if (citizenData.m_citizen == 0u) { return(null); } // NON-STOCK CODE START bool forceTaxi = false; if (Options.prohibitPocketCars) { if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceID].pathMode == ExtPathMode.TaxiToTarget) { forceTaxi = true; } } // NON-STOCK CODE END Citizen.AgeGroup ageGroup = CustomCitizenAI.GetAgeGroup(citizenData.Info.m_agePhase); int carProb; int bikeProb; int taxiProb; // NON-STOCK CODE START if (forceTaxi) { carProb = 0; bikeProb = 0; taxiProb = 100; } else // NON-STOCK CODE END if (forceCar || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { carProb = 100; bikeProb = 0; taxiProb = 0; } else { carProb = GetCarProbability(instanceID, ref citizenData, ageGroup); bikeProb = GetBikeProbability(instanceID, ref citizenData, ageGroup); taxiProb = GetTaxiProbability(instanceID, ref citizenData, ageGroup); } Randomizer randomizer = new Randomizer(citizenData.m_citizen); bool useCar = randomizer.Int32(100u) < carProb; bool useBike = randomizer.Int32(100u) < bikeProb; bool useTaxi = randomizer.Int32(100u) < taxiProb; ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = ItemClass.SubService.ResidentialLow; if (!useCar && useTaxi) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } // NON-STOCK CODE START VehicleInfo carInfo = null; if (Options.prohibitPocketCars && useCar && !useTaxi) { ushort parkedVehicleId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].m_parkedVehicle; if (parkedVehicleId != 0) { #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomResidentAI.GetVehicleInfo: Citizen instance {instanceID} owns a parked vehicle {parkedVehicleId}. Reusing vehicle info."); } #endif carInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info; } } if (carInfo == null && (useCar || useTaxi)) { // NON-STOCK CODE END carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, service, subService, ItemClass.Level.Level1); } VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, (ageGroup != Citizen.AgeGroup.Child)?ItemClass.Level.Level2 : ItemClass.Level.Level1); if (useBike && bikeInfo != null) { return(bikeInfo); } if ((useCar || useTaxi) && carInfo != null) { return(carInfo); } return(null); }
public VehicleInfo CustomGetVehicleInfo(ushort instanceId, ref CitizenInstance citizenData, bool forceCar, out VehicleInfo trailer) { #if DEBUG bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 || DebugSettings.CitizenInstanceId == instanceId) && (DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == citizenData.m_citizen) && (DebugSettings.SourceBuildingId == 0 || DebugSettings.SourceBuildingId == citizenData.m_sourceBuilding) && (DebugSettings.TargetBuildingId == 0 || DebugSettings.TargetBuildingId == citizenData.m_targetBuilding); bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug; #else var logParkingAi = false; #endif trailer = null; if (citizenData.m_citizen == 0u) { return(null); } // NON-STOCK CODE START bool forceTaxi = false; if (Options.parkingAI) { if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceId].pathMode == ExtPathMode.TaxiToTarget) { forceTaxi = true; } } // NON-STOCK CODE END Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel; int carProb; int bikeProb; int taxiProb; // NON-STOCK CODE START if (forceTaxi) { carProb = 0; bikeProb = 0; taxiProb = 100; } else // NON-STOCK CODE END if (forceCar || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { carProb = 100; bikeProb = 0; taxiProb = 0; } else { carProb = GetCarProbability(); bikeProb = GetBikeProbability(); taxiProb = GetTaxiProbability(); } Randomizer randomizer = new Randomizer(citizenData.m_citizen); bool useCar = randomizer.Int32(100u) < carProb; bool useBike = !useCar && randomizer.Int32(100u) < bikeProb; bool useTaxi = !useCar && !useBike && randomizer.Int32(100u) < taxiProb; bool useCamper = false; bool useElectricCar = false; if (useCar) { int camperProb = GetCamperProbability(wealthLevel); useCamper = randomizer.Int32(100u) < camperProb; if (!useCamper) { int electricProb = GetElectricCarProbability(wealthLevel); useElectricCar = randomizer.Int32(100u) < electricProb; } } ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = useElectricCar ? ItemClass.SubService.ResidentialLowEco : ItemClass.SubService.ResidentialLow; if (useTaxi) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } // NON-STOCK CODE START VehicleInfo carInfo = null; if (Options.parkingAI && useCar && !useTaxi) { ushort parkedVehicleId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen] .m_parkedVehicle; if (parkedVehicleId != 0) { Log._DebugIf( logParkingAi, () => $"CustomTouristAI.CustomGetVehicleInfo({instanceId}): " + $"Citizen instance {instanceId} owns a parked vehicle {parkedVehicleId}. " + $"Reusing vehicle info."); carInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info; } } if (carInfo == null && (useCar || useTaxi)) { // NON-STOCK CODE END if (useCamper) { Randomizer randomizer2 = randomizer; carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, service, subService, ItemClass.Level.Level2); if (carInfo == null || carInfo.m_vehicleAI is CarTrailerAI) { trailer = carInfo; randomizer = randomizer2; carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, service, subService, ItemClass.Level.Level1); } } else { carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, service, subService, ItemClass.Level.Level1); } } if (useBike) { VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2); if (bikeInfo != null) { return(bikeInfo); } } if ((useCar || useTaxi) && carInfo != null) { return(carInfo); } return(null); }
private void ReleaseCitizenInstanceImplementation(ushort instanceId, ref CitizenInstance instanceData) { Log.Error("CustomCitizenManager.ReleaseCitizenInstanceImplementation called."); }
private int GetElectricCarProbability(ushort instanceID, ref CitizenInstance citizenData, Citizen.AgePhase agePhase) { Log.Error("CustomResidentAI.GetElectricCarProbability called!"); return(20); }
public static bool RenderInstance(ref CitizenInstance instance, RenderManager.CameraInfo cameraInfo, ushort instanceID) { if ((instance.m_flags & CitizenInstance.Flags.Character) == CitizenInstance.Flags.None) return false; CitizenInfo info = instance.Info; if ((UnityEngine.Object)info == (UnityEngine.Object)null) return false; uint num = Singleton<SimulationManager>.instance.m_referenceFrameIndex - ((uint)instanceID << 4) / 65536U; CitizenInstance.Frame frameData1 = instance.GetFrameData(num - 32U); float maxDistance = Mathf.Min(RenderManager.LevelOfDetailFactor * 800f, info.m_maxRenderDistance + cameraInfo.m_height * 0.5f); if (!cameraInfo.CheckRenderDistance(frameData1.m_position, maxDistance) || !cameraInfo.Intersect(frameData1.m_position, 10f)) return false; CitizenInstance.Frame frameData2 = instance.GetFrameData(num - 16U); float t = (float)(((double)(num & 15U) + (double)Singleton<SimulationManager>.instance.m_referenceTimer) * (1.0 / 16.0)); bool flag1 = frameData2.m_underground && frameData1.m_underground; bool flag2 = frameData2.m_insideBuilding && frameData1.m_insideBuilding; bool flag3 = frameData2.m_transition || frameData1.m_transition; if (flag2 && !flag3 || flag1 && !flag3 && (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) == 0) return false; //begin mod info = GetUpdatedInfo(instance, instanceID); //end mod Vector3 vector3 = new Bezier3() { a = frameData1.m_position, b = (frameData1.m_position + frameData1.m_velocity * 0.333f), c = (frameData2.m_position - frameData2.m_velocity * 0.333f), d = frameData2.m_position }.Position(t); Quaternion quaternion = Quaternion.Lerp(frameData1.m_rotation, frameData2.m_rotation, t); Color color = info.m_citizenAI.GetColor(instanceID, ref instance, Singleton<InfoManager>.instance.CurrentMode); if (cameraInfo.CheckRenderDistance(vector3, info.m_lodRenderDistance)) { InstanceID id = InstanceID.Empty; id.CitizenInstance = instanceID; CitizenInfo citizenInfo = info.ObtainPrefabInstance<CitizenInfo>(id, (int)byte.MaxValue); if ((UnityEngine.Object)citizenInfo != (UnityEngine.Object)null) { Vector3 velocity = Vector3.Lerp(frameData1.m_velocity, frameData2.m_velocity, t); //begin mod if (info.m_subCulture == Citizen.SubCulture.Generic) { citizenInfo.m_citizenAI.SetRenderParameters(cameraInfo, instanceID, ref instance, vector3, quaternion, velocity, color, (flag1 || flag3) && (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) != 0); } else { citizenInfo.SetRenderParameters(vector3, quaternion, velocity, color, 5, (flag1 || flag3) && (cameraInfo.m_layerMask & 1 << Singleton<CitizenManager>.instance.m_undergroundLayer) != 0); } //end mod return true; } } if (flag1 || flag3) { info.m_undergroundLodLocations[info.m_undergroundLodCount].SetTRS(vector3, quaternion, Vector3.one); info.m_undergroundLodColors[info.m_undergroundLodCount] = color; info.m_undergroundLodMin = Vector3.Min(info.m_undergroundLodMin, vector3); info.m_undergroundLodMax = Vector3.Max(info.m_undergroundLodMax, vector3); if (++info.m_undergroundLodCount == info.m_undergroundLodLocations.Length) CitizenInstance.RenderUndergroundLod(cameraInfo, info); } if (!flag1 || flag3) { info.m_lodLocations[info.m_lodCount].SetTRS(vector3, quaternion, Vector3.one); info.m_lodColors[info.m_lodCount] = color; info.m_lodMin = Vector3.Min(info.m_lodMin, vector3); info.m_lodMax = Vector3.Max(info.m_lodMax, vector3); if (++info.m_lodCount == info.m_lodLocations.Length) CitizenInstance.RenderLod(cameraInfo, info); } return true; }
} // end RemoveWorkerBuilding /// <summary> /// Promote the workers to fit the education bill better. /// </summary> /// <param name="buildingID"></param> /// <param name="data"></param> /// <param name="workersRequired"></param> /// <param name="instance"></param> /// <param name="citizenUnitArray"></param> /// <param name="citizenArray"></param> private static void PromoteWorkers(ushort buildingID, ref Building data, ref int[] workersRequired) { if (workersRequired[0] == 0 && workersRequired[1] == 0 && workersRequired[2] == 0 && workersRequired[3] == 0) { // We are okay with employees, or it's residential. Return return; } //Debugging.writeDebugToFile(buildingID + ". Workers needed: " + workersRequired[0] + ", " + workersRequired[1] + ", " + workersRequired[2] + ", " + workersRequired[3]); // Crime and garbage are reset data.m_crimeBuffer = 0; data.m_garbageBuffer = 0; int loopCounter = 0; uint previousUnit = data.m_citizenUnits; uint currentUnit = data.m_citizenUnits; while (currentUnit != 0u) { // If this unit matches what we one, send the citizens away or remove citzens uint nextUnit = citizenUnitArray[currentUnit].m_nextUnit; // Only think about removing if it matches the flag if ((ushort)(CitizenUnit.Flags.Work & citizenUnitArray[currentUnit].m_flags) != 0) { // Send unit away like empty building for (int i = 0; i < 5; i++) { uint citizen = citizenUnitArray[(int)((UIntPtr)currentUnit)].GetCitizen(i); if (citizen != 0u) { // Do not shift back where possible. There should be enough staff turnover that the spaces aren't worth the intensive checking int citizenIndex = (int)((UIntPtr)citizen); ushort citizenInstanceIndex = citizenArray[citizenIndex].m_instance; CitizenInstance citData = citizenManager.m_instances.m_buffer[(int)citizenInstanceIndex]; // Get education level. Perform checks Citizen cit = citizenArray[(int)((UIntPtr)citizen)]; int education = (int)cit.EducationLevel; // -ve workersRequired means excess workers. Ignoring three schools // Checks if the citizen should be promoted or fire // Remove excess 0, 1, 2. However, give 20 - 50 % change to go up an education level. Don't touch lvl 3 educated (they'll disappear fast given the chance) if ((cit.EducationLevel != Citizen.Education.ThreeSchools) && (workersRequired[education] < 0 && workersRequired[education + 1] > 0)) { // Need to be above 50 to be promoted. However, each level is harder to get to, effectively (50, 65, 80) int number = Singleton <SimulationManager> .instance.m_randomizer.Int32(0, 100) - (education * 15); if (number > 50) { if (cit.EducationLevel == Citizen.Education.Uneducated) { cit.Education1 = true; workersRequired[0]++; workersRequired[1]--; } else if (cit.EducationLevel == Citizen.Education.OneSchool) { cit.Education2 = true; workersRequired[1]++; workersRequired[2]--; } else if (cit.EducationLevel == Citizen.Education.TwoSchools) { cit.Education3 = true; workersRequired[2]++; workersRequired[3]--; } } else { workersRequired[education]++; citizenManager.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_workBuilding = 0; RemoveFromCitizenUnit(currentUnit, i); } } else if (workersRequired[education] < 0) { workersRequired[education]++; citizenManager.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_workBuilding = 0; RemoveFromCitizenUnit(currentUnit, i); } // end if } // end citizen } // end for } // Flag match previousUnit = currentUnit; currentUnit = nextUnit; if (++loopCounter > 524288) { currentUnit = 0u; // Bail out loop } } // end while } // end PromoteWorkers
private bool IsValid(ref CitizenInstance citizenInstance) { if ((citizenInstance.m_flags & CitizenInstance.Flags.Deleted) != CitizenInstance.Flags.None) { return false; } if (citizenInstance.m_path == 0) { return false; } return true; }
public static bool Prefix(ResidentAI __instance, ref VehicleInfo __result, ushort instanceID, ref CitizenInstance citizenData, bool forceProbability, out VehicleInfo trailer) { #if DEBUG bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 || DebugSettings.CitizenInstanceId == instanceID) && (DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == citizenData.m_citizen) && (DebugSettings.SourceBuildingId == 0 || DebugSettings.SourceBuildingId == citizenData.m_sourceBuilding) && (DebugSettings.TargetBuildingId == 0 || DebugSettings.TargetBuildingId == citizenData.m_targetBuilding); bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug; #else var logParkingAi = false; #endif trailer = null; if (citizenData.m_citizen == 0u) { __result = null; return(false); } // NON-STOCK CODE START bool forceTaxi = false; if (Options.parkingAI) { if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceID] .pathMode == ExtPathMode.TaxiToTarget) { forceTaxi = true; } } // NON-STOCK CODE END Citizen.AgeGroup ageGroup = Constants.ManagerFactory.ExtCitizenManager.GetAgeGroup(citizenData.Info.m_agePhase); int carProb; int bikeProb; int taxiProb; // NON-STOCK CODE START if (forceTaxi) { carProb = 0; bikeProb = 0; taxiProb = 100; } else // NON-STOCK CODE END if (forceProbability || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { carProb = 100; bikeProb = 0; taxiProb = 0; } else { carProb = GetCarProbability(__instance, instanceID, ref citizenData, ageGroup); bikeProb = GetBikeProbability(__instance, instanceID, ref citizenData, ageGroup); taxiProb = GetTaxiProbability(__instance, instanceID, ref citizenData, ageGroup); } Randomizer randomizer = new Randomizer(citizenData.m_citizen); bool useCar = randomizer.Int32(100u) < carProb; bool useBike = !useCar && randomizer.Int32(100u) < bikeProb; bool useTaxi = !useCar && !useBike && randomizer.Int32(100u) < taxiProb; bool useElectricCar = false; if (useCar) { int electricProb = GetElectricCarProbability(__instance, instanceID, ref citizenData, __instance.m_info.m_agePhase); useElectricCar = randomizer.Int32(100u) < electricProb; } ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = useElectricCar ? ItemClass.SubService.ResidentialLowEco : ItemClass.SubService.ResidentialLow; if (useTaxi) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } // NON-STOCK CODE START VehicleInfo carInfo = null; if (Options.parkingAI && useCar) { ushort parkedVehicleId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen] .m_parkedVehicle; if (parkedVehicleId != 0) { Log._DebugIf( logParkingAi, () => $"CustomResidentAI.CustomGetVehicleInfo({instanceID}): " + $"Citizen instance {instanceID} owns a parked vehicle {parkedVehicleId}. " + $"Reusing vehicle info."); carInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info; } } if (carInfo == null && (useCar || useTaxi)) { // NON-STOCK CODE END carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, service, subService, ItemClass.Level.Level1); } if (useBike) { ItemClass.Level ageGroupLvl = ageGroup != Citizen.AgeGroup.Child ? ItemClass.Level.Level2 : ItemClass.Level.Level1; VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo( ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ageGroupLvl); if (bikeInfo != null) { __result = bikeInfo; return(false); } } if ((useCar || useTaxi) && carInfo != null) { __result = carInfo; return(false); } __result = null; return(false); }
protected override void ArriveAtDestination(ushort instanceID, ref CitizenInstance citizenData, bool success) { uint citizen = citizenData.m_citizen; if (citizen != 0) { CitizenManager instance = Singleton<CitizenManager>.instance; if (success) { instance.m_citizens.m_buffer[citizen].SetLocationByBuilding(citizen, citizenData.m_targetBuilding); if (citizenData.m_sourceBuilding != 0 && instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Work) { ReachedDestination(citizen, citizenData); } else if (citizenData.m_sourceBuilding != 0 && instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Visit) { ReachedDestination(citizen, citizenData); } } } base.ArriveAtDestination(instanceID, ref citizenData, success); }
public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) { if (_terminated) { return; } if (!_helper.GameLoaded) { return; } try { if (!_initialized) { if (!IsOverwatched()) { _helper.NotifyPlayer("Skylines Overwatch not found. Terminating..."); _terminated = true; return; } else { _helper.NotifyPlayer($"Skylines Overwatch found, initialising {this.GetType()}"); } SkylinesOverwatch.Settings.Instance.Enable.AnimalMonitor = true; _initialized = true; _helper.NotifyPlayer("Initialized"); } else { CitizenManager instance = Singleton <CitizenManager> .instance; ushort[] seagulls = SkylinesOverwatch.Data.Instance.Seagulls; foreach (ushort i in seagulls) { CitizenInstance seagull = instance.m_instances.m_buffer[(int)i]; if (seagull.Info != null) { seagull.Info.m_maxRenderDistance = float.NegativeInfinity; ((BirdAI)seagull.Info.m_citizenAI).m_randomEffect = null; } SkylinesOverwatch.Helper.Instance.RequestAnimalRemoval(i); } } } catch (Exception e) { string error = String.Format("Failed to {0}\r\n", !_initialized ? "initialize" : "update"); error += String.Format("Error: {0}\r\n", e.Message); error += "\r\n"; error += "==== STACK TRACE ====\r\n"; error += e.StackTrace; _helper.Log(error); _terminated = true; } base.OnUpdate(realTimeDelta, simulationTimeDelta); }
private int GetBikeProbability(ushort instanceID, ref CitizenInstance citizenData, Citizen.AgeGroup ageGroup) { Log.Error("CustomResidentAI.GetBikeProbability called!"); return(20); }
// CitizenAI public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo) { CitizenManager citMan = Singleton <CitizenManager> .instance; if (citMan.m_citizens.m_buffer[citizenData.m_citizen].CurrentLocation == Citizen.Location.Home) { currentTransportMode[instanceID] = TransportMode.None; // reset currently used transport mode at home } SimulationManager simManager = Singleton <SimulationManager> .instance; Citizen.Wealth wealthLevel = citMan.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel; bool couldUseTaxi = false; // could cim use a taxi if it was not forbidden because of randomization? bool couldUseCar = false; bool couldUseBike = false; bool wouldAffordTaxiVoluntarily = false; bool randomParking = false; if (vehicleInfo != null) { if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u) { couldUseTaxi = true; if (currentTransportMode[instanceID] == TransportMode.Taxi || (currentTransportMode[instanceID] == TransportMode.None && ((simManager.m_isNightTime && simManager.m_randomizer.Int32(100) < NIGHT_TAXI_USAGE_PROBABILITY[(int)wealthLevel]) || (!simManager.m_isNightTime && simManager.m_randomizer.Int32(100) < DAY_TAXI_USAGE_PROBABILITY[(int)wealthLevel])))) { wouldAffordTaxiVoluntarily = true; // NON-STOCK CODE } } } else { // NON-STOCK CODE START if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { couldUseBike = true; } else if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Car) { couldUseCar = true; } // NON-STOCK CODE END if (citizenData.m_targetBuilding != 0 && Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info.m_class.m_service > ItemClass.Service.Office) { randomParking = true; } } } byte districtId = Singleton <DistrictManager> .instance.GetDistrict(startPos); DistrictPolicies.Services servicePolicies = Singleton <DistrictManager> .instance.m_districts.m_buffer[(int)districtId].m_servicePolicies; int transportUsageProb = (servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None ? FREE_TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel] : TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel]; bool useTaxi = false; bool useBike = false; bool useCar = false; bool usePublicTransport = false; if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) // STOCK CODE { if (currentTransportMode[instanceID] == TransportMode.PublicTransport || useTaxi || (currentTransportMode[instanceID] == TransportMode.None && simManager.m_randomizer.Int32(100) < transportUsageProb)) { usePublicTransport = true; } } ushort parkedVehicle = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].m_parkedVehicle; bool couldUseParkedCar = false; // cims are not allowed to use pocket cars (unless we have no choice) PathUnit.Position vehiclePosition = default(PathUnit.Position); if (parkedVehicle != 0) { Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position; if (PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition)) { couldUseParkedCar = true; } } if (couldUseBike) { // everyone who has a bike may use it useBike = true; } if (!usePublicTransport) { if (couldUseParkedCar && currentTransportMode[instanceID] == TransportMode.Car) { useCar = true; } else if ((wouldAffordTaxiVoluntarily && currentTransportMode[instanceID] == TransportMode.Taxi) || couldUseTaxi) { useTaxi = true; } else if (couldUseCar) { // pocket car fallback useCar = true; } } ExtVehicleType extVehicleType = ExtVehicleType.None; NetInfo.LaneType laneType = NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None; if (usePublicTransport) { currentTransportMode[instanceID] = TransportMode.PublicTransport; laneType |= NetInfo.LaneType.PublicTransport; extVehicleType |= ExtVehicleType.PublicTransport; } if (useBike && vehicleInfo != null) { laneType |= NetInfo.LaneType.Vehicle; vehicleType |= vehicleInfo.m_vehicleType; extVehicleType |= ExtVehicleType.Bicycle; } if (useTaxi && vehicleInfo != null) { currentTransportMode[instanceID] = TransportMode.Taxi; laneType |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); vehicleType |= vehicleInfo.m_vehicleType; extVehicleType |= ExtVehicleType.Taxi; } if (useCar && vehicleInfo != null) { currentTransportMode[instanceID] = TransportMode.Car; laneType |= NetInfo.LaneType.Vehicle; vehicleType |= vehicleInfo.m_vehicleType; extVehicleType |= ExtVehicleType.PassengerCar; } //Log._Debug($"Citizen {instanceID}: usePublicTransport={usePublicTransport} useCar={useCar} useTaxi={useTaxi} useBike={useBike} vehicleInfo.vehicleType={vehicleInfo?.m_vehicleType} laneType={laneType} vehicleType={vehicleType} extVehicleType={extVehicleType}"); bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None; PathUnit.Position startPosA; PathUnit.Position endPosA; if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) && this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA)) { PathUnit.Position position2 = default(PathUnit.Position); uint path; #if DEBUG //Log._Debug($"CustomCitizenAI: citizen instance {instanceID}, id {citizenData.m_citizen}. vehicleType={vehicleType} laneType={laneType} extVehicleType={extVehicleType} usePublicTransport={usePublicTransport} useTaxi={useTaxi} useBike={useBike} useCar={useCar} wealthLevel={wealthLevel}"); #endif // NON-STOCK CODE END // if (Singleton <CustomPathManager> .instance.CreatePath(false, (ExtVehicleType)extVehicleType, null, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false, randomParking)) { if (citizenData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(citizenData.m_path); } citizenData.m_path = path; citizenData.m_flags |= CitizenInstance.Flags.WaitingPath; return(true); } } return(false); }
/// <summary> /// Check if prisoner is confused. /// </summary> /// <param name="data">The citizen instance.</param> /// <returns>True if prisoner is confused.</returns> private static bool PrisonerConfused(ref CitizenInstance data) { // From PrisonerAI.GetLocalizedStatus from original game code at version 1.4.1-f2. ushort num = data.m_targetBuilding; if ((int)num != 0) { ////target = InstanceID.Empty; ////target.Building = num; ////return Locale.Get("CITIZEN_STATUS_VISITING"); return false; } ////target = InstanceID.Empty; ////return Locale.Get("CITIZEN_STATUS_CONFUSED"); return true; }
// CitizenAI public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo) { NetInfo.LaneType laneType = NetInfo.LaneType.Pedestrian; VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None; if (vehicleInfo != null) { if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u) { SimulationManager instance = Singleton <SimulationManager> .instance; if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0) { laneType |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle); vehicleType |= vehicleInfo.m_vehicleType; } } } else { laneType |= NetInfo.LaneType.Vehicle; vehicleType |= vehicleInfo.m_vehicleType; } } PathUnit.Position vehiclePosition = default(PathUnit.Position); ushort parkedVehicle = Singleton <CitizenManager> .instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle; if (parkedVehicle != 0) { Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position; PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition); } bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None; PathUnit.Position startPosA; PathUnit.Position endPosA; if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) && this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA)) { // NON-STOCK CODE START // Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel; byte districtId = Singleton <DistrictManager> .instance.GetDistrict(startPos); DistrictPolicies.Services servicePolicies = Singleton <DistrictManager> .instance.m_districts.m_buffer[(int)districtId].m_servicePolicies; int transportUsageProb = (servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None ? FREE_TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel] : TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel]; //bool mayUseTransport = false; if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None) // STOCK CODE { if (vehicleInfo == null || (instanceID % 100) + 1 <= transportUsageProb) { laneType |= NetInfo.LaneType.PublicTransport; // STOCK CODE //mayUseTransport = true; //Log._Debug($"CustomCitizenAI: citizen {instanceID} can use public transport"); } } // NON-STOCK CODE END // PathUnit.Position position2 = default(PathUnit.Position); uint path; // NON-STOCK CODE START // ExtVehicleType?extVehicleType = null; if (vehicleInfo != null) { extVehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicleInfo(vehicleInfo); } //Log._Debug($"CustomCitizenAI: citizen instance {instanceID}, id {citizenData.m_citizen}. {vehicleType} {extVehicleType} mayUseTransport={mayUseTransport} wealthLevel={wealthLevel}"); bool res = false; if (extVehicleType == null) { // NON-STOCK CODE END // res = Singleton <CustomPathManager> .instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false); } // NON-STOCK CODE START // else { res = Singleton <CustomPathManager> .instance.CreatePath((ExtVehicleType)extVehicleType, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false); } // NON-STOCK CODE END // if (res) { if (citizenData.m_path != 0u) { Singleton <PathManager> .instance.ReleasePath(citizenData.m_path); } citizenData.m_path = path; citizenData.m_flags |= CitizenInstance.Flags.WaitingPath; return(true); } } return(false); }
private String GetStockLocalizedStatus(ushort instanceID, ref CitizenInstance data, out bool addCustomStatus, out InstanceID target) { if ((data.m_flags & (CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) != CitizenInstance.Flags.None) { target = InstanceID.Empty; addCustomStatus = false; return(Locale.Get("CITIZEN_STATUS_CONFUSED")); } CitizenManager citMan = Singleton <CitizenManager> .instance; uint citizenId = data.m_citizen; bool isStudent = false; ushort homeId = 0; ushort workId = 0; ushort vehicleId = 0; if (citizenId != 0u) { homeId = citMan.m_citizens.m_buffer[citizenId].m_homeBuilding; workId = citMan.m_citizens.m_buffer[citizenId].m_workBuilding; vehicleId = citMan.m_citizens.m_buffer[citizenId].m_vehicle; isStudent = ((citMan.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Student) != Citizen.Flags.None); } ushort targetBuilding = data.m_targetBuilding; if (targetBuilding == 0) { target = InstanceID.Empty; addCustomStatus = false; return(Locale.Get("CITIZEN_STATUS_CONFUSED")); } if ((data.m_flags & CitizenInstance.Flags.TargetIsNode) != CitizenInstance.Flags.None) { if (vehicleId != 0) { VehicleManager vehManager = Singleton <VehicleManager> .instance; VehicleInfo vehicleInfo = vehManager.m_vehicles.m_buffer[vehicleId].Info; if (vehicleInfo.m_class.m_service == ItemClass.Service.Residential && vehicleInfo.m_vehicleType != VehicleInfo.VehicleType.Bicycle) { if (vehicleInfo.m_vehicleAI.GetOwnerID(vehicleId, ref vehManager.m_vehicles.m_buffer[vehicleId]).Citizen == citizenId) { target = InstanceID.Empty; target.NetNode = targetBuilding; addCustomStatus = true; return(ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_DRIVINGTO")); } } else if (vehicleInfo.m_class.m_service == ItemClass.Service.PublicTransport || vehicleInfo.m_class.m_service == ItemClass.Service.Disaster) { ushort transportLine = Singleton <NetManager> .instance.m_nodes.m_buffer[targetBuilding].m_transportLine; if ((data.m_flags & CitizenInstance.Flags.WaitingTaxi) != 0) { target = InstanceID.Empty; addCustomStatus = true; return(ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_WAITING_TAXI")); } if (vehManager.m_vehicles.m_buffer[vehicleId].m_transportLine != transportLine) { target = InstanceID.Empty; target.NetNode = targetBuilding; addCustomStatus = true; return(ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_TRAVELLINGTO")); } } } if ((data.m_flags & CitizenInstance.Flags.OnTour) != 0) { target = InstanceID.Empty; target.NetNode = targetBuilding; addCustomStatus = true; return(ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_VISITING")); } target = InstanceID.Empty; target.NetNode = targetBuilding; addCustomStatus = true; return(ColossalFramework.Globalization.Locale.Get("CITIZEN_STATUS_GOINGTO")); } bool isOutsideConnection = (Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuilding].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None; bool hangsAround = data.m_path == 0u && (data.m_flags & CitizenInstance.Flags.HangAround) != CitizenInstance.Flags.None; if (vehicleId != 0) { VehicleManager vehicleMan = Singleton <VehicleManager> .instance; VehicleInfo vehicleInfo = vehicleMan.m_vehicles.m_buffer[(int)vehicleId].Info; if (vehicleInfo.m_class.m_service == ItemClass.Service.Residential && vehicleInfo.m_vehicleType != VehicleInfo.VehicleType.Bicycle) { if (vehicleInfo.m_vehicleAI.GetOwnerID(vehicleId, ref vehicleMan.m_vehicles.m_buffer[(int)vehicleId]).Citizen == citizenId) { if (isOutsideConnection) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO_OUTSIDE")); } if (targetBuilding == homeId) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO_HOME")); } else if (targetBuilding == workId) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_DRIVINGTO_WORK" : "CITIZEN_STATUS_DRIVINGTO_SCHOOL")); } else { target = InstanceID.Empty; target.Building = targetBuilding; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_DRIVINGTO")); } } } else if (vehicleInfo.m_class.m_service == ItemClass.Service.PublicTransport || vehicleInfo.m_class.m_service == ItemClass.Service.Disaster) { if ((data.m_flags & CitizenInstance.Flags.WaitingTaxi) != CitizenInstance.Flags.None) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_WAITING_TAXI")); } if (isOutsideConnection) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_OUTSIDE")); } if (targetBuilding == homeId) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO_HOME")); } if (targetBuilding == workId) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_TRAVELLINGTO_WORK" : "CITIZEN_STATUS_TRAVELLINGTO_SCHOOL")); } target = InstanceID.Empty; target.Building = targetBuilding; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_TRAVELLINGTO")); } } if (isOutsideConnection) { target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_GOINGTO_OUTSIDE")); } if (targetBuilding == homeId) { if (hangsAround) { target = InstanceID.Empty; addCustomStatus = false; return(Locale.Get("CITIZEN_STATUS_AT_HOME")); } target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_GOINGTO_HOME")); } else if (targetBuilding == workId) { if (hangsAround) { target = InstanceID.Empty; addCustomStatus = false; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_AT_WORK" : "CITIZEN_STATUS_AT_SCHOOL")); } target = InstanceID.Empty; addCustomStatus = true; return(Locale.Get((!isStudent) ? "CITIZEN_STATUS_GOINGTO_WORK" : "CITIZEN_STATUS_GOINGTO_SCHOOL")); } else { if (hangsAround) { target = InstanceID.Empty; target.Building = targetBuilding; addCustomStatus = false; return(Locale.Get("CITIZEN_STATUS_VISITING")); } target = InstanceID.Empty; target.Building = targetBuilding; addCustomStatus = true; return(Locale.Get("CITIZEN_STATUS_GOINGTO")); } }
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.ExtSimulationStep({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.ExtSimulationStep({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); }
protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider) { Segment3 segment = new Segment3 (sourcePos, targetPos); Vector3 min = segment.Min (); min.x -= this.m_info.m_radius; min.z -= this.m_info.m_radius; Vector3 max = segment.Max (); max.x += this.m_info.m_radius; max.y += this.m_info.m_height; max.z += this.m_info.m_radius; CitizenManager instance = Singleton<CitizenManager>.instance; int num = Mathf.Max ((int)((min.x - 3f) / 8f + 1080f), 0); int num2 = Mathf.Max ((int)((min.z - 3f) / 8f + 1080f), 0); int num3 = Mathf.Min ((int)((max.x + 3f) / 8f + 1080f), 2159); int num4 = Mathf.Min ((int)((max.z + 3f) / 8f + 1080f), 2159); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_citizenGrid [i * 2160 + j]; int num6 = 0; while (num5 != 0) { num5 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider); if (++num6 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } VehicleManager instance2 = Singleton<VehicleManager>.instance; int num7 = Mathf.Max ((int)((min.x - 10f) / 32f + 270f), 0); int num8 = Mathf.Max ((int)((min.z - 10f) / 32f + 270f), 0); int num9 = Mathf.Min ((int)((max.x + 10f) / 32f + 270f), 539); int num10 = Mathf.Min ((int)((max.z + 10f) / 32f + 270f), 539); for (int k = num8; k <= num10; k++) { for (int l = num7; l <= num9; l++) { ushort num11 = instance2.m_vehicleGrid [k * 540 + l]; int num12 = 0; while (num11 != 0) { num11 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider); if (++num12 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (int m = num8; m <= num10; m++) { for (int n = num7; n <= num9; n++) { ushort num13 = instance2.m_parkedGrid [m * 540 + n]; int num14 = 0; while (num13 != 0) { num13 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider); if (++num14 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (buildingID != 0) { BuildingManager instance3 = Singleton<BuildingManager>.instance; BuildingInfo info = instance3.m_buildings.m_buffer [(int)buildingID].Info; if (info.m_props != null) { Vector3 position = instance3.m_buildings.m_buffer [(int)buildingID].m_position; float angle = instance3.m_buildings.m_buffer [(int)buildingID].m_angle; int length = instance3.m_buildings.m_buffer [(int)buildingID].Length; Matrix4x4 matrix4x = default(Matrix4x4); matrix4x.SetTRS (Building.CalculateMeshPosition (info, position, angle, length), Quaternion.AngleAxis (angle * 57.29578f, Vector3.down), Vector3.one); for (int num15 = 0; num15 < info.m_props.Length; num15++) { BuildingInfo.Prop prop = info.m_props [num15]; Randomizer randomizer = new Randomizer ((int)buildingID << 6 | prop.m_index); if (randomizer.Int32 (100u) < prop.m_probability && length >= prop.m_requiredLength) { Vector3 vector = matrix4x.MultiplyPoint (prop.m_position); if (vector.x >= min.x - 2f && vector.x <= max.x + 2f) { if (vector.z >= min.z - 2f && vector.z <= max.z + 2f) { PropInfo propInfo = prop.m_finalProp; TreeInfo treeInfo = prop.m_finalTree; float num16 = 0f; float num17 = 0f; if (propInfo != null) { propInfo = propInfo.GetVariation (ref randomizer); if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer) { goto IL_7D3; } num16 = propInfo.m_generatedInfo.m_size.x * 0.5f; num17 = propInfo.m_generatedInfo.m_size.y; } else { if (treeInfo != null) { treeInfo = treeInfo.GetVariation (ref randomizer); num16 = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f; num17 = treeInfo.m_generatedInfo.m_size.y; } } if (!prop.m_fixedHeight) { vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector); } else { if (info.m_requireHeightMap) { vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector) + prop.m_position.y; } } if (vector.y + num17 >= min.y && vector.y <= max.y) { num16 = this.m_info.m_radius + num16; float num19; float num18 = segment.DistanceSqr (vector, out num19); if (num18 < num16 * num16) { float num20 = num16 - Mathf.Sqrt (num18); float num21 = 1f - num18 / (num16 * num16); Vector3 a = segment.Position (num19 * 0.9f); a.y = 0f; vector.y = 0f; Vector3 vector2 = Vector3.Normalize (a - vector); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector3 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector2, rhs) * 0.5f); if (Vector3.Dot (vector2, vector3) >= 0f) { vector2 += vector3; } else { vector2 -= vector3; } pushAmount += vector2 * (num20 * num21); pushDivider += num21; } } } } } IL_7D3: ; } } } }
public void CustomSimulationStep(ushort instanceID, ref CitizenInstance instanceData, Vector3 physicsLodRefPos) { uint citizenId = instanceData.m_citizen; if ((instanceData.m_flags & (CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) != CitizenInstance.Flags.None && (instanceData.m_flags & CitizenInstance.Flags.Character) == CitizenInstance.Flags.None) { Singleton <CitizenManager> .instance.ReleaseCitizenInstance(instanceID); if (citizenId != 0u) { Singleton <CitizenManager> .instance.ReleaseCitizen(citizenId); } return; } if ((instanceData.m_flags & CitizenInstance.Flags.WaitingPath) != CitizenInstance.Flags.None) { PathManager pathManager = Singleton <PathManager> .instance; byte pathFindFlags = pathManager.m_pathUnits.m_buffer[instanceData.m_path].m_pathFindFlags; // NON-STOCK CODE START ExtPathState mainPathState = ExtPathState.Calculating; if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || instanceData.m_path == 0) { mainPathState = ExtPathState.Failed; } else if ((pathFindFlags & PathUnit.FLAG_READY) != 0) { mainPathState = ExtPathState.Ready; } #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path={instanceData.m_path}, mainPathState={mainPathState}"); } #endif ExtSoftPathState finalPathState = ExtSoftPathState.None; #if BENCHMARK using (var bm = new Benchmark(null, "ConvertPathStateToSoftPathState+UpdateCitizenPathState")) { #endif finalPathState = ExtCitizenInstance.ConvertPathStateToSoftPathState(mainPathState); if (Options.prohibitPocketCars) { finalPathState = AdvancedParkingManager.Instance.UpdateCitizenPathState(instanceID, ref instanceData, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID], ref Singleton <CitizenManager> .instance.m_citizens.m_buffer[instanceData.m_citizen], mainPathState); #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Applied Parking AI logic. Path={instanceData.m_path}, mainPathState={mainPathState}, finalPathState={finalPathState}, extCitizenInstance={ExtCitizenInstanceManager.Instance.ExtInstances[instanceID]}"); } #endif } #if BENCHMARK } #endif switch (finalPathState) { case ExtSoftPathState.Ready: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding succeeded for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.PathfindSuccess"); } #endif this.Spawn(instanceID, ref instanceData); instanceData.m_pathPositionIndex = 255; instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); // NON-STOCK CODE START (transferred from ResidentAI.PathfindSuccess) if (citizenId != 0 && (Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].m_flags & (Citizen.Flags.Tourist | Citizen.Flags.MovingIn | Citizen.Flags.DummyTraffic)) == Citizen.Flags.MovingIn) { StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.MoveRate); statisticBase.Add(1); } // NON-STOCK CODE END this.PathfindSuccess(instanceID, ref instanceData); break; case ExtSoftPathState.Ignore: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding result shall be ignored for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- ignoring"); } #endif return; case ExtSoftPathState.Calculating: default: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding result undetermined for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- continue"); } #endif break; case ExtSoftPathState.FailedHard: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): HARD path-finding failure for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.PathfindFailure"); } #endif instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering); Singleton <PathManager> .instance.ReleasePath(instanceData.m_path); instanceData.m_path = 0u; this.PathfindFailure(instanceID, ref instanceData); return; case ExtSoftPathState.FailedSoft: #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): SOFT path-finding failure for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.InvalidPath"); } #endif // path mode has been updated, 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; } // NON-STOCK CODE END } // NON-STOCK CODE START #if BENCHMARK using (var bm = new Benchmark(null, "ExtSimulationStep")) { #endif if (Options.prohibitPocketCars) { if (ExtSimulationStep(instanceID, ref instanceData, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID], physicsLodRefPos)) { return; } } #if BENCHMARK } #endif // NON-STOCK CODE END base.SimulationStep(instanceID, ref instanceData, physicsLodRefPos); CitizenManager citizenManager = Singleton <CitizenManager> .instance; VehicleManager vehicleManager = Singleton <VehicleManager> .instance; ushort vehicleId = 0; if (instanceData.m_citizen != 0u) { vehicleId = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_vehicle; } if (vehicleId != 0) { VehicleInfo vehicleInfo = vehicleManager.m_vehicles.m_buffer[(int)vehicleId].Info; if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { vehicleInfo.m_vehicleAI.SimulationStep(vehicleId, ref vehicleManager.m_vehicles.m_buffer[(int)vehicleId], vehicleId, ref vehicleManager.m_vehicles.m_buffer[(int)vehicleId], 0); vehicleId = 0; } } if (vehicleId == 0 && (instanceData.m_flags & (CitizenInstance.Flags.Character | CitizenInstance.Flags.WaitingPath | CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) == CitizenInstance.Flags.None) { instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown); this.ArriveAtDestination(instanceID, ref instanceData, false); citizenManager.ReleaseCitizenInstance(instanceID); } }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref VehicleParked otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; Vector3 position = otherData.m_position; Vector3 b = otherData.m_rotation * new Vector3 (0f, 0f, Mathf.Max (0.5f, info.m_generatedInfo.m_size.z * 0.5f - 1f)); Segment3 segment2; segment2.a = position - b; segment2.b = position + b; Vector3 vector = segment2.Min (); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = segment2.Max (); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a.y = 0f; b2.y = 0f; Vector3 vector3 = Vector3.Normalize (a - b2); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } } return otherData.m_nextGridParked; }
/// <summary> /// Makes the given citizen instance enter their parked car. /// </summary> /// <param name="instanceID">Citizen instance id</param> /// <param name="instanceData">Citizen instance data</param> /// <param name="parkedVehicleId">Parked vehicle id</param> /// <param name="vehicleId">Vehicle id</param> /// <returns>true if entering the car succeeded, false otherwise</returns> public static bool EnterParkedCar(ushort instanceID, ref CitizenInstance instanceData, ushort parkedVehicleId, out ushort vehicleId) { #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): parkedVehicleId={parkedVehicleId})"); } #endif VehicleManager vehManager = Singleton <VehicleManager> .instance; NetManager netManager = Singleton <NetManager> .instance; CitizenManager citManager = Singleton <CitizenManager> .instance; Vector3 parkedVehPos = vehManager.m_parkedVehicles.m_buffer[parkedVehicleId].m_position; Quaternion parkedVehRot = vehManager.m_parkedVehicles.m_buffer[parkedVehicleId].m_rotation; VehicleInfo vehicleInfo = vehManager.m_parkedVehicles.m_buffer[parkedVehicleId].Info; PathUnit.Position vehLanePathPos; if (!CustomPathManager._instance.m_pathUnits.m_buffer[instanceData.m_path].GetPosition(0, out vehLanePathPos)) { #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): Could not get first car path position of citizen instance {instanceID}!"); } #endif vehicleId = 0; return(false); } uint vehLaneId = PathManager.GetLaneID(vehLanePathPos); #if DEBUG if (GlobalConfig.Instance.Debug.Switches[4]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): Determined vehicle position for citizen instance {instanceID}: seg. {vehLanePathPos.m_segment}, lane {vehLanePathPos.m_lane}, off {vehLanePathPos.m_offset} (lane id {vehLaneId})"); } #endif Vector3 vehLanePos; float vehLaneOff; netManager.m_lanes.m_buffer[vehLaneId].GetClosestPosition(parkedVehPos, out vehLanePos, out vehLaneOff); byte vehLaneOffset = (byte)Mathf.Clamp(Mathf.RoundToInt(vehLaneOff * 255f), 0, 255); // movement vector from parked vehicle position to road position Vector3 forwardVector = parkedVehPos + Vector3.ClampMagnitude(vehLanePos - parkedVehPos, 5f); if (vehManager.CreateVehicle(out vehicleId, ref Singleton <SimulationManager> .instance.m_randomizer, vehicleInfo, parkedVehPos, TransferManager.TransferReason.None, false, false)) { // update frame data Vehicle.Frame frame = vehManager.m_vehicles.m_buffer[(int)vehicleId].m_frame0; frame.m_rotation = parkedVehRot; vehManager.m_vehicles.m_buffer[vehicleId].m_frame0 = frame; vehManager.m_vehicles.m_buffer[vehicleId].m_frame1 = frame; vehManager.m_vehicles.m_buffer[vehicleId].m_frame2 = frame; vehManager.m_vehicles.m_buffer[vehicleId].m_frame3 = frame; vehicleInfo.m_vehicleAI.FrameDataUpdated(vehicleId, ref vehManager.m_vehicles.m_buffer[vehicleId], ref frame); // update vehicle target position vehManager.m_vehicles.m_buffer[vehicleId].m_targetPos0 = new Vector4(vehLanePos.x, vehLanePos.y, vehLanePos.z, 2f); // update other fields vehManager.m_vehicles.m_buffer[vehicleId].m_flags = (vehManager.m_vehicles.m_buffer[vehicleId].m_flags | Vehicle.Flags.Stopped); vehManager.m_vehicles.m_buffer[vehicleId].m_path = instanceData.m_path; vehManager.m_vehicles.m_buffer[vehicleId].m_pathPositionIndex = 0; vehManager.m_vehicles.m_buffer[vehicleId].m_lastPathOffset = vehLaneOffset; vehManager.m_vehicles.m_buffer[vehicleId].m_transferSize = (ushort)(instanceData.m_citizen & 65535u); if (!vehicleInfo.m_vehicleAI.TrySpawn(vehicleId, ref vehManager.m_vehicles.m_buffer[vehicleId])) { #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): Could not spawn a {vehicleInfo.m_vehicleType} for citizen instance {instanceID}!"); } #endif return(false); } // change instances InstanceID parkedVehInstance = InstanceID.Empty; parkedVehInstance.ParkedVehicle = parkedVehicleId; InstanceID vehInstance = InstanceID.Empty; vehInstance.Vehicle = vehicleId; Singleton <InstanceManager> .instance.ChangeInstance(parkedVehInstance, vehInstance); // set vehicle id for citizen instance instanceData.m_path = 0u; citManager.m_citizens.m_buffer[instanceData.m_citizen].SetParkedVehicle(instanceData.m_citizen, 0); citManager.m_citizens.m_buffer[instanceData.m_citizen].SetVehicle(instanceData.m_citizen, vehicleId, 0u); // update citizen instance flags instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath; instanceData.m_flags &= ~CitizenInstance.Flags.EnteringVehicle; instanceData.m_flags &= ~CitizenInstance.Flags.TryingSpawnVehicle; instanceData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; instanceData.m_waitCounter = 0; // unspawn citizen instance instanceData.Unspawn(instanceID); #if DEBUG if (GlobalConfig.Instance.Debug.Switches[4]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): Citizen instance {instanceID} is now entering vehicle {vehicleId}. Set vehicle target position to {vehLanePos} (segment={vehLanePathPos.m_segment}, lane={vehLanePathPos.m_lane}, offset={vehLanePathPos.m_offset})"); } #endif return(true); } else { // failed to find a road position #if DEBUG if (GlobalConfig.Instance.Debug.Switches[2]) { Log._Debug($"CustomHumanAI.EnterParkedCar({instanceID}): Could not find a road position for citizen instance {instanceID} near parked vehicle {parkedVehicleId}!"); } #endif return(false); } }
private static CitizenInfo GetUpdatedInfo(CitizenInstance instance, ushort instanceID) { CitizenInfo originalInfo = instance.Info; if (originalInfo == null || originalInfo.GetService() != ItemClass.Service.Residential) { return originalInfo; } var originalAI = originalInfo.m_citizenAI; if (originalAI is ServicePersonAI || originalAI is AnimalAI) { return originalInfo; } if (originalInfo.m_agePhase == Citizen.AgePhase.Teen0 || originalInfo.m_agePhase == Citizen.AgePhase.Teen1 || originalInfo.m_agePhase > Citizen.AgePhase.Adult3) { return originalInfo; } var citizenID = instance.m_citizen; var citizen = CitizenManager.instance.m_citizens.m_buffer[citizenID]; if (citizen.m_instance != instanceID || instance.m_flags.IsFlagSet(CitizenInstance.Flags.RidingBicycle) || instance.m_flags.IsFlagSet(CitizenInstance.Flags.OnBikeLane)) { return originalInfo; } var workBuilding = BuildingManager.instance.m_buildings.m_buffer[citizen.m_workBuilding]; if (workBuilding.m_flags != Building.Flags.None && originalInfo.m_agePhase != Citizen.AgePhase.Child) { if (workBuilding.Info.m_buildingAI is FireStationAI) { return originalInfo.m_gender == Citizen.Gender.Male ? _fireman : _paramedic; } if (workBuilding.Info.m_buildingAI is HospitalAI || workBuilding.Info.m_buildingAI is PoliceStationAI) { return originalInfo.m_gender == Citizen.Gender.Female ? _paramedic : _policeOfficer; } if (workBuilding.Info.m_buildingAI is CemeteryAI && originalInfo.m_gender == Citizen.Gender.Male) { return _hearseDriver; } if (workBuilding.Info.m_buildingAI is PlayerBuildingAI && originalInfo.m_gender == Citizen.Gender.Male) { return _policeOfficer; } } if (!_isDlcEnabled) { return originalInfo; } var r1 = new Randomizer(citizenID); var value = r1.Int32(15); Citizen.SubCulture subCulture; switch (value) { case 0: subCulture = Citizen.SubCulture.Hippie; break; case 1: subCulture = Citizen.SubCulture.Hipster; break; case 2: subCulture = Citizen.SubCulture.Redneck; break; default: return originalInfo; } var r2 = new Randomizer(citizenID); var info = Singleton<CitizenManager>.instance.GetGroupCitizenInfo(ref r2, originalInfo.GetService(), originalInfo.m_gender, subCulture, originalInfo.m_agePhase); if (info == null || info.m_citizenAI.GetType() != originalAI.GetType()) { info = originalInfo; } return info; }
private void ArriveAtDestination(ushort instanceID, ref CitizenInstance citizenData, bool success) { Log.Error($"HumanAI.ArriveAtDestination is not overriden!"); }
private string GetServiceType(ref CitizenInstance inst) { if ((inst.m_flags & CitizenInstance.Flags.RidingBicycle) == CitizenInstance.Flags.RidingBicycle) { return "Citizen/Cycle"; } else { return "Citizen/Foot"; } }
private void PathfindSuccess(ushort instanceID, ref CitizenInstance data) { Log.Error($"HumanAI.PathfindSuccess is not overriden!"); }
private ushort CheckCitizen(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max) { if ((vehicleData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (otherData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (vehicleData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((otherData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None)) { return otherData.m_nextGridInstance; } CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData(); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3(position, b); Vector3 vector = segment2.Min(); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max(); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; float num; float num2; if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius)) { float num3 = lastLen + nextLen * num; if (num3 >= 0.01f) { num3 -= 2f; float b2 = Mathf.Max(1f, CustomCarAI.CalculateMaxSpeed(num3, 0f, maxBraking)); maxSpeed = Mathf.Min(maxSpeed, b2); } } return otherData.m_nextGridInstance; }
public override void LateUpdate() { if (FavCimsMainClass.UnLoading) return; if (this.MyInstanceID.IsEmpty || !FavCimsCore.RowID.ContainsKey (citizenINT)) { if(this.MyFamily != null) { this.MyFamily.Hide(); this.MyFamily.MyInstanceID = InstanceID.Empty; this.MyFamily = null; } GameObject.Destroy (this.gameObject); return; } if (this.DeadOrGone || this.HomeLess) { this.OtherInfoButton.isEnabled = false; this.OtherInfoButton.tooltip = FavCimsLang.text ("Citizen_Details_NoUnit"); }else if(GetTemplate() == -1 && (this.MyFamily == null || this.MyFamily.MyInstanceID != MyInstanceID)) { if(this.MyFamily != null && this.MyFamily.MyInstanceID != MyInstanceID) { this.MyFamily = null; } this.OtherInfoButton.isEnabled = false; this.OtherInfoButton.tooltip = FavCimsLang.text ("Citizen_Details_fullTemplate"); } else { if(this.MyFamily != null && this.MyFamily.MyInstanceID == this.MyInstanceID && this.MyFamily.isVisible) { this.OtherInfoButton.normalBgSprite = "CityInfoFocused"; }else{ this.OtherInfoButton.normalBgSprite = "CityInfo"; } this.OtherInfoButton.isEnabled = true; this.OtherInfoButton.tooltip = FavCimsLang.text ("Citizen_Details"); } uint citizen = this.MyInstanceID.Citizen; //Is dead? if((citizen != 0) && this.MyCitizen.m_citizens.m_buffer[citizen].Dead && !this.CitizenIsDead) { this.CitizenIsDead = true; this.CitizenRowData ["deathrealage"] = "0"; } if (this.execute) { try { this.CitizenName = this.MyInstance.GetName (this.MyInstanceID); citizenINT = (int)((UIntPtr)citizen); if (this.CitizenName != null && this.CitizenName.Length > 0 && this.CitizenName != this.MyInstancedName) { this.MyInstancedName = this.CitizenName; } this.citizenInfo = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].GetCitizenInfo (citizen); this.FavCimsRowCloseButton.tooltip = FavCimsLang.text ("FavStarButton_disable_tooltip"); if (this.FavCimsCitizenSingleRowPanel != null && citizen != 0 && this.CitizenName == this.MyInstancedName && FavCimsCore.RowID.ContainsKey (citizenINT)) { //Citizen Gender this.CitizenRowData ["gender"] = Citizen.GetGender (citizen).ToString (); //Name this.CitizenRowData ["name"] = this.MyCitizen.GetCitizenName (citizen); this.FavCimsCitizenName.text = this.CitizenRowData ["name"]; if (this.CitizenRowData ["gender"] == "Female") { this.FavCimsCitizenName.textColor = new Color32 (255, 102, 204, 213); //r,g,b,a } if (this.CitizenDistrict == 0) { this.FavCimsCitizenName.tooltip = FavCimsLang.text ("NowInThisDistrict") + FavCimsLang.text ("DistrictNameNoDistrict"); } else { this.FavCimsCitizenName.tooltip = FavCimsLang.text ("NowInThisDistrict") + MyDistrict.GetDistrictName (this.CitizenDistrict); } //Citizen Health this.tmp_health = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_health; this.CitizenRowData ["health"] = Citizen.GetHealthLevel (this.tmp_health).ToString (); //Citizen Education var tmp_education = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].EducationLevel; this.CitizenRowData ["education"] = tmp_education.ToString (); this.FavCimsEducation.text = FavCimsLang.text ("Education_" + this.CitizenRowData ["education"] + "_" + this.CitizenRowData ["gender"]); if (this.CitizenRowData ["education"] == "ThreeSchools") { this.FavCimsEducation.textColor = new Color32 (102, 204, 0, 60); //r,g,b,a } else if (this.CitizenRowData ["education"] == "TwoSchools") { this.FavCimsEducation.textColor = new Color32 (255, 204, 0, 32); } else if (this.CitizenRowData ["education"] == "OneSchool") { this.FavCimsEducation.textColor = new Color32 (255, 102, 0, 16); //r,g,b,a } else { this.FavCimsEducation.textColor = new Color32 (153, 0, 0, 0); //r,g,b,a } //Citizen Wellbeing this.tmp_wellbeing = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_wellbeing; this.CitizenRowData ["wellbeing"] = Citizen.GetWellbeingLevel (tmp_education, this.tmp_wellbeing).ToString (); //Citizen Happiness this.tmp_happiness = Citizen.GetHappiness (this.tmp_health, this.tmp_wellbeing); //this.CitizenRowData ["happiness"] = Citizen.GetHappinessLevel (this.tmp_happiness).ToString (); //Bad, Poor, Good, Excellent, Suberb this.CitizenRowData ["happiness_icon"] = GetHappinessString (Citizen.GetHappinessLevel (this.tmp_happiness)); this.FavCimsHappyIcon.normalBgSprite = this.CitizenRowData ["happiness_icon"]; this.FavCimsHappyIcon.tooltip = FavCimsLang.text (this.CitizenRowData ["happiness_icon"]); //Age Group (Age Phase) this.tmp_age = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_age; this.CitizenRowData ["agegroup"] = Citizen.GetAgeGroup (this.tmp_age).ToString (); this.FavCimsAgePhase.text = FavCimsLang.text ("AgePhase_" + this.CitizenRowData ["agegroup"] + "_" + this.CitizenRowData ["gender"]); //Real Age this.RealAge = FavCimsCore.CalculateCitizenAge (this.tmp_age); if (this.RealAge <= 12) { //CHILD this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (102, 204, 0, 60); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (102, 204, 0, 60); //r,g,b,a } else if (this.RealAge <= 19) { //TEEN this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (0, 102, 51, 100); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (0, 102, 51, 100); //r,g,b,a } else if (this.RealAge <= 25) { //YOUNG this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (255, 204, 0, 32); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (255, 204, 0, 32); //r,g,b,a } else if (this.RealAge <= 65) { //ADULT this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (255, 102, 0, 16); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (255, 102, 0, 16); //r,g,b,a } else if (this.RealAge <= 90) { //SENIOR this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (153, 0, 0, 0); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (153, 0, 0, 0); //r,g,b,a } else { //FINAL this.FavCimsRealAge.text = this.RealAge.ToString (); this.FavCimsRealAge.textColor = new Color32 (255, 0, 0, 0); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (255, 0, 0, 0); //r,g,b,a } //Citizen Home this.CitizenHome = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_homeBuilding; if (this.CitizenHome != 0) { this.HomeLess = false; this.CitizenHomeID.Building = this.CitizenHome; this.FavCimsCitizenHome.text = this.MyBuilding.GetBuildingName (this.CitizenHome, this.MyInstanceID); this.FavCimsCitizenHome.isEnabled = true; this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTexture; this.HomeInfo = this.MyBuilding.m_buildings.m_buffer [CitizenHomeID.Index].Info; if (this.HomeInfo.m_class.m_service == ItemClass.Service.Residential) { this.FavCimsCitizenHome.tooltip = null; if (this.HomeInfo.m_class.m_subService == ItemClass.SubService.ResidentialHigh) { this.FavCimsCitizenHome.textColor = new Color32 (0, 102, 51, 100); //r,g,b,a this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTextureHigh; this.FavCimsCitizenHome.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", ItemClass.SubService.ResidentialHigh.ToString ()); } else if (this.HomeInfo.m_class.m_subService == ItemClass.SubService.ResidentialLow) { this.FavCimsCitizenHome.textColor = new Color32 (0, 153, 0, 80); //r,g,b,a this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTexture; this.FavCimsCitizenHome.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", ItemClass.SubService.ResidentialLow.ToString ()); } switch (this.HomeInfo.m_class.m_level) { case ItemClass.Level.Level5: this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [5]; break; case ItemClass.Level.Level4: this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [4]; break; case ItemClass.Level.Level3: this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [3]; break; case ItemClass.Level.Level2: this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [2]; break; default: this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [1]; break; } /* if (this.HomeInfo.m_class.m_level == ItemClass.Level.Level5) { this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [5]; } else if (this.HomeInfo.m_class.m_level == ItemClass.Level.Level4) { this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [4]; } else if (this.HomeInfo.m_class.m_level == ItemClass.Level.Level3) { this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [3]; } else if (this.HomeInfo.m_class.m_level == ItemClass.Level.Level2) { this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [2]; } else { this.FavCimsCitizenResidentialLevelSprite.texture = TextureDB.FavCimsResidentialLevel [1]; } */ //District this.HomeDistrict = (int)MyDistrict.GetDistrict (this.MyBuilding.m_buildings.m_buffer [CitizenHomeID.Index].m_position); if (this.HomeDistrict == 0) { this.FavCimsCitizenHomeSprite.tooltip = FavCimsLang.text ("DistrictLabel") + FavCimsLang.text ("DistrictNameNoDistrict"); } else { this.FavCimsCitizenHomeSprite.tooltip = FavCimsLang.text ("DistrictLabel") + MyDistrict.GetDistrictName (this.HomeDistrict); } } } else { this.FavCimsCitizenHome.text = FavCimsLang.text ("Citizen_HomeLess"); this.FavCimsCitizenHome.isEnabled = false; this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTextureHomeless; this.FavCimsCitizenHomeSprite.tooltip = FavCimsLang.text ("DistrictNameNoDistrict"); this.FavCimsCitizenHome.tooltip = FavCimsLang.text ("Citizen_HomeLess_tooltip"); this.FavCimsCitizenResidentialLevelSprite.texture = null; this.HomeLess = true; } //Working Place this.WorkPlace = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_workBuilding; if (this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].GetCurrentSchoolLevel (citizen) != ItemClass.Level.None) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsWorkingPlaceTextureStudent; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; this.FavCimsWorkingPlace.tooltip = Locale.Get ("CITIZEN_SCHOOL_LEVEL", this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].GetCurrentSchoolLevel (citizen).ToString ()); } else if (this.WorkPlace == 0) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; if (this.tmp_age >= 180) { //In Pensione this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsWorkingPlaceTextureRetired; this.FavCimsWorkingPlace.text = FavCimsLang.text ("Citizen_Retired"); this.FavCimsWorkingPlace.isEnabled = false; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Citizen_Retired_tooltip"); this.FavCimsWorkingPlaceSprite.tooltip = null; this.FavCimsWorkingPlaceButtonGamDefImg.tooltip = null; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; } else { this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsWorkingPlaceTexture; //unemployed this.FavCimsWorkingPlace.text = Locale.Get ("CITIZEN_OCCUPATION_UNEMPLOYED"); this.FavCimsWorkingPlace.isEnabled = false; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Unemployed_tooltip"); this.FavCimsWorkingPlaceSprite.tooltip = null; this.FavCimsWorkingPlaceButtonGamDefImg.tooltip = null; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; } } if (this.WorkPlace != 0) { this.WorkPlaceID.Building = this.WorkPlace; this.FavCimsWorkingPlace.text = this.MyBuilding.GetBuildingName (this.WorkPlace, this.MyInstanceID); this.FavCimsWorkingPlace.isEnabled = true; this.WorkInfo = this.MyBuilding.m_buildings.m_buffer [WorkPlaceID.Index].Info; if (this.WorkInfo.m_class.m_service == ItemClass.Service.Commercial) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; if (this.WorkInfo.m_class.m_subService == ItemClass.SubService.CommercialHigh) { this.FavCimsWorkingPlace.textColor = new Color32 (0, 51, 153, 147); //r,g,b,a this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsCitizenCommercialHighTexture; this.FavCimsWorkingPlace.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", ItemClass.SubService.CommercialHigh.ToString ()); } else { this.FavCimsWorkingPlace.textColor = new Color32 (0, 153, 204, 130); //r,g,b,a this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsCitizenCommercialLowTexture; this.FavCimsWorkingPlace.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", ItemClass.SubService.CommercialLow.ToString ()); } switch (this.WorkInfo.m_class.m_level) { case ItemClass.Level.Level3: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [3]; break; case ItemClass.Level.Level2: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [2]; break; default: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [1]; break; } /* if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level3) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [3]; } else if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level2) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [2]; } else { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [1]; } */ } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Industrial) { this.FavCimsWorkingPlace.textColor = new Color32 (255, 204, 0, 32); //r,g,b,a this.FavCimsWorkingPlace.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", "Industrial"); switch (this.WorkInfo.m_class.m_subService) { case ItemClass.SubService.IndustrialFarming: this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyFarming"; break; case ItemClass.SubService.IndustrialForestry: this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ResourceForestry"; break; case ItemClass.SubService.IndustrialOil: this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyOil"; break; case ItemClass.SubService.IndustrialOre: this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyOre"; break; default: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsCitizenIndustrialGenericTexture; break; } /* if (this.WorkInfo.m_class.m_subService == ItemClass.SubService.IndustrialFarming) { this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyFarming"; } else if (this.WorkInfo.m_class.m_subService == ItemClass.SubService.IndustrialForestry) { this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ResourceForestry"; } else if (this.WorkInfo.m_class.m_subService == ItemClass.SubService.IndustrialOil) { this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyOil"; } else if (this.WorkInfo.m_class.m_subService == ItemClass.SubService.IndustrialOre) { this.FavCimsWorkingPlaceSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyOre"; } else { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsCitizenIndustrialGenericTexture; } */ switch (this.WorkInfo.m_class.m_level) { case ItemClass.Level.Level3: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [3]; break; case ItemClass.Level.Level2: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [2]; break; default: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [1]; break; } /* if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level3) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [3]; } else if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level2) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [2]; } else { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [1]; } */ } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Office) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = null; this.FavCimsWorkingPlace.textColor = new Color32 (0, 204, 255, 128); //r,g,b,a this.FavCimsWorkingPlaceSprite.texture = TextureDB.FavCimsCitizenOfficeTexture; this.FavCimsWorkingPlace.tooltip = Locale.Get ("ZONEDBUILDING_TITLE", "Office"); switch (this.WorkInfo.m_class.m_level) { case ItemClass.Level.Level3: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [3]; break; case ItemClass.Level.Level2: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [2]; break; default: this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsCommercialLevel [1]; break; } /* if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level3) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [3]; } else if (this.WorkInfo.m_class.m_level == ItemClass.Level.Level2) { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [2]; } else { this.FavCimsCitizenWorkPlaceLevelSprite.texture = TextureDB.FavCimsIndustrialLevel [1]; } */ } else { this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; this.FavCimsWorkingPlace.textColor = new Color32 (153, 102, 51, 20); //r,g,b,a switch (this.WorkInfo.m_class.m_service) { case ItemClass.Service.FireDepartment: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "InfoIconFireSafety"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "FireDepartment"); break; case ItemClass.Service.HealthCare: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconHealthcareFocused"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Healthcare"); break; case ItemClass.Service.PoliceDepartment: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconPolice"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Police"); break; case ItemClass.Service.Garbage: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyRecycling"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Garbage"); break; case ItemClass.Service.Electricity: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyPowerSaving"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Electricity_job"); break; case ItemClass.Service.Education: this.FavCimsWorkingPlace.textColor = new Color32 (0, 102, 51, 100); //r,g,b,a this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "InfoIconEducationPressed"; break; case ItemClass.Service.Beautification: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "SubBarBeautificationParksnPlazas"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Beautification"); break; case ItemClass.Service.Government: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconGovernment"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Government_job"); break; case ItemClass.Service.Water: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyWaterSaving"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Water_job"); break; case ItemClass.Service.PublicTransport: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyFreePublicTransport"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "PublicTransport"); break; case ItemClass.Service.Monument: this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "FeatureMonumentLevel6"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Monuments"); break; default: this.FavCimsWorkingPlace.textColor = new Color32 (255, 204, 0, 32); //r,g,b,a this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyNone"; this.FavCimsWorkingPlace.tooltip = null; break; } /* if (this.WorkInfo.m_class.m_service == ItemClass.Service.FireDepartment) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "InfoIconFireSafety"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "FireDepartment"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.HealthCare) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconHealthcareFocused"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Healthcare"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.PoliceDepartment) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconPolice"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Police"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Garbage) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyRecycling"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Garbage"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Electricity) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyPowerSaving"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Electricity_job"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Education) { this.FavCimsWorkingPlace.textColor = new Color32 (0, 102, 51, 100); //r,g,b,a this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "InfoIconEducationPressed"; } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Beautification) { //parchi this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "SubBarBeautificationParksnPlazas"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Beautification"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Government) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "ToolbarIconGovernment"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Government_job"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Water) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyWaterSaving"; this.FavCimsWorkingPlace.tooltip = FavCimsLang.text ("Water_job"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.PublicTransport) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyFreePublicTransport"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "PublicTransport"); } else if (this.WorkInfo.m_class.m_service == ItemClass.Service.Monument) { this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "FeatureMonumentLevel6"; this.FavCimsWorkingPlace.tooltip = Locale.Get ("SERVICE_DESC", "Monuments"); } else if (this.WorkInfo.m_class.m_service != ItemClass.Service.None) { this.FavCimsWorkingPlace.textColor = new Color32 (255, 204, 0, 32); //r,g,b,a this.FavCimsWorkingPlaceButtonGamDefImg.normalBgSprite = "IconPolicyNone"; this.FavCimsWorkingPlace.tooltip = null; } */ this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; } //District this.WorkDistrict = (int)MyDistrict.GetDistrict (this.MyBuilding.m_buildings.m_buffer [WorkPlaceID.Index].m_position); if (this.WorkDistrict == 0) { this.FavCimsWorkingPlaceSprite.tooltip = FavCimsLang.text ("DistrictLabel") + FavCimsLang.text ("DistrictNameNoDistrict"); } else { this.FavCimsWorkingPlaceSprite.tooltip = FavCimsLang.text ("DistrictLabel") + MyDistrict.GetDistrictName (this.WorkDistrict); } } else { this.FavCimsWorkingPlace.isEnabled = false; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; this.FavCimsWorkingPlaceButtonGamDefImg.tooltip = null; this.FavCimsWorkingPlaceSprite.tooltip = null; } this.InstanceCitizenID = this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index].m_instance; this.citizenInstance = this.MyCitizen.m_instances.m_buffer [InstanceCitizenID]; if (this.citizenInstance.m_targetBuilding != 0) { this.CitizenVehicle = this.MyCitizen.m_citizens.m_buffer [citizen].m_vehicle; this.MyVehicleID = InstanceID.Empty; GoingOutside = (MyBuilding.m_buildings.m_buffer [this.citizenInstance.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None; if (this.CitizenVehicle != 0) { this.MyVehicleID.Vehicle = this.CitizenVehicle; this.FavCimsLastActivityVehicleButton.isEnabled = true; this.VehInfo = this.MyVehicle.m_vehicles.m_buffer [this.CitizenVehicle].Info; this.CitizenVehicleName = this.MyVehicle.GetVehicleName (this.CitizenVehicle); if (this.VehInfo.m_class.m_service == ItemClass.Service.Residential) { //sta usando una macchina if (this.VehInfo.m_vehicleAI.GetOwnerID (this.CitizenVehicle, ref MyVehicle.m_vehicles.m_buffer [this.CitizenVehicle]).Citizen == citizen) { //sta usando la sua macchina. if (GoingOutside) LeaveCity = true; this.FavCimsLastActivityVehicleButton.normalBgSprite = "IconCitizenVehicle"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "IconTouristVehicle"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName; } } else if (this.VehInfo.m_class.m_service == ItemClass.Service.PublicTransport) { //sta usando un mezzo pubblico if (GoingOutside) LeaveCity = true; switch (this.VehInfo.m_class.m_subService) { case ItemClass.SubService.PublicTransportBus: this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportBus"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportBusHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportBusFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportBusPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Bus"); break; case ItemClass.SubService.PublicTransportMetro: this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportMetro"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportMetroHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportMetroFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportMetroPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Metro"); break; case ItemClass.SubService.PublicTransportPlane: this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportPlane"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportPlaneHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportPlaneFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportPlanePressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Plane"); break; case ItemClass.SubService.PublicTransportShip: this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportShip"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportShipHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportShipFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportShipPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Ship"); break; case ItemClass.SubService.PublicTransportTrain: this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportTrain"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportTrainHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportTrainFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportTrainPressed"; if (this.CitizenVehicleName == "VEHICLE_TITLE[Train Passenger]:0") this.CitizenVehicleName = Locale.Get ("VEHICLE_TITLE", "Train Engine"); this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Train"); break; } /* if (this.VehInfo.m_class.m_subService == ItemClass.SubService.PublicTransportBus) { this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportBus"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportBusHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportBusFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportBusPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Bus"); } else if (this.VehInfo.m_class.m_subService == ItemClass.SubService.PublicTransportMetro) { this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportMetro"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportMetroHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportMetroFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportMetroPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Metro"); } else if (this.VehInfo.m_class.m_subService == ItemClass.SubService.PublicTransportPlane) { this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportPlane"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportPlaneHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportPlaneFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportPlanePressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Plane"); } else if (this.VehInfo.m_class.m_subService == ItemClass.SubService.PublicTransportShip) { this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportShip"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportShipHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportShipFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportShipPressed"; this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Ship"); } else if (this.VehInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTrain) { this.FavCimsLastActivityVehicleButton.normalBgSprite = "SubBarPublicTransportTrain"; this.FavCimsLastActivityVehicleButton.hoveredBgSprite = "SubBarPublicTransportTrainHovered"; this.FavCimsLastActivityVehicleButton.focusedBgSprite = "SubBarPublicTransportTrainFocused"; this.FavCimsLastActivityVehicleButton.pressedBgSprite = "SubBarPublicTransportTrainPressed"; if (this.CitizenVehicleName == "VEHICLE_TITLE[Train Passenger]:0") this.CitizenVehicleName = Locale.Get ("VEHICLE_TITLE", "Train Engine"); this.FavCimsLastActivityVehicleButton.tooltip = this.CitizenVehicleName + " - " + Locale.Get ("SUBSERVICE_DESC", "Train"); } */ } } else { if (GoingOutside) LeaveCity = true; this.FavCimsLastActivityVehicleButton.disabledBgSprite = "InfoIconPopulationDisabled"; this.FavCimsLastActivityVehicleButton.isEnabled = false; this.FavCimsLastActivityVehicleButton.tooltip = FavCimsLang.text ("Vehicle_on_foot"); } } else { this.FavCimsLastActivityVehicleButton.disabledBgSprite = "InfoIconPopulationDisabled"; this.FavCimsLastActivityVehicleButton.isEnabled = false; this.FavCimsLastActivityVehicleButton.tooltip = null; } //Citizen Status this.CitizenStatus = citizenInfo.m_citizenAI.GetLocalizedStatus (citizen, ref this.MyCitizen.m_citizens.m_buffer [MyInstanceID.Index], out this.MyTargetID); this.CitizenTarget = this.MyBuilding.GetBuildingName (this.MyTargetID.Building, this.MyInstanceID); this.FavCimsLastActivity.text = this.CitizenStatus + " " + this.CitizenTarget; if (!this.MyTargetID.IsEmpty) { //District this.TargetDistrict = (int)MyDistrict.GetDistrict (this.MyBuilding.m_buildings.m_buffer [MyTargetID.Index].m_position); if (this.TargetDistrict == 0) { this.FavCimsLastActivity.tooltip = FavCimsLang.text ("DistrictLabel") + FavCimsLang.text ("DistrictNameNoDistrict"); } else { this.FavCimsLastActivity.tooltip = FavCimsLang.text ("DistrictLabel") + MyDistrict.GetDistrictName (this.TargetDistrict); } } //Now in this District this.CitizenDistrict = (int)MyDistrict.GetDistrict (citizenInstance.GetSmoothPosition (InstanceCitizenID)); //Il carro funebre lo ha caricato //if (((citizen != 0) && MyCitizen.m_citizens.m_buffer[citizen].Dead) && (MyCitizen.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Moving)) { if(this.CitizenIsDead) { //try //{ this.FavCimsHappyIcon.normalBgSprite = "NotificationIconDead"; this.FavCimsHappyIcon.tooltip = FavCimsLang.text ("People_Life_Status_Dead"); if(this.CitizenRowData ["deathrealage"] == "0") this.CitizenRowData ["deathrealage"] = this.RealAge.ToString(); this.FavCimsRealAge.text = this.CitizenRowData ["deathrealage"]; if (this.DeathDate == null) { this.DeathDate = GameTime.FavCimsDate (FavCimsLang.text ("time_format"),"n/a"); this.DeathTime = GameTime.FavCimsTime (); } this.FavCimsCitizenName.tooltip = FavCimsLang.text ("People_Life_Status_Dead") + " " + FavCimsLang.text ("People_Life_Status_Dead_date") + " " + this.DeathDate + " " + FavCimsLang.text ("People_Life_Status_Dead_time") + " " + this.DeathTime; if(MyCitizen.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Moving) { this.hearse = this.MyCitizen.m_citizens.m_buffer [citizen].m_vehicle; if(hearse != 0) { this.CitizenDead.Citizen = citizen; this.MyVehicleID.Vehicle = hearse; this.FavCimsLastActivityVehicleButton.normalBgSprite = "NotificationIconVerySick"; this.FavCimsLastActivityVehicleButton.isEnabled = true; this.FavCimsLastActivityVehicleButton.playAudioEvents = true; this.FavCimsLastActivityVehicleButton.tooltip = Locale.Get ("VEHICLE_TITLE", "Hearse"); this.FavCimsLastActivity.text = FavCimsLang.text("Citizen_on_hearse"); } } else if(MyCitizen.m_citizens.m_buffer[citizen].CurrentLocation != Citizen.Location.Moving && this.hearse == 0) { //Verificare con unspawn //aspetta il carro funebre this.FavCimsLastActivity.text = FavCimsLang.text("Citizen_wait_hearse"); this.FavCimsLastActivityVehicleButton.disabledBgSprite = "NotificationIconVerySick"; this.FavCimsLastActivityVehicleButton.isEnabled = false; } else { //lo stanno seppellendo this.FavCimsLastActivity.text = FavCimsLang.text("Citizen_hisfuneral"); this.FavCimsLastActivityVehicleButton.disabledBgSprite = "NotificationIconVerySick"; this.FavCimsLastActivityVehicleButton.isEnabled = false; } //}catch (Exception e) { // Debug.Log("error + " + e.ToString()); //} } } else { if(this.rowLang == null || this.rowLang != FavCimsLang.GameLanguage) this.DeadOrGone = false; if (!this.DeadOrGone) { this.rowLang = FavCimsLang.GameLanguage; this.DeadOrGone = true; if (this.FavCimsCitizenSingleRowPanel != null && FavCimsCore.RowID.ContainsKey (citizenINT) && this.MyInstancedName.Length > 0) { if(this.DeathDate != null) { this.DeathDate = GameTime.FavCimsDate (FavCimsLang.text ("time_format"), this.DeathDate); } if (this.DeathDate == null) { this.DeathDate = GameTime.FavCimsDate (FavCimsLang.text ("time_format"),"n/a"); this.DeathTime = GameTime.FavCimsTime (); } //if(this.citflags != null) //Debug.Log(this.citflags); //Debug.Log(this.FavCimsCitizenName.text + " is dead on date " + this.DeathDate + " at time " + this.DeathTime); this.FavCimsCitizenName.disabledTextColor = new Color32 (51, 51, 51, 160); //r,g,b,a this.FavCimsCitizenName.isEnabled = false; this.FavCimsEducation.textColor = new Color32 (51, 51, 51, 160); //r,g,b,a this.FavCimsRealAge.textColor = new Color32 (51, 51, 51, 160); //r,g,b,a this.FavCimsAgePhase.textColor = new Color32 (51, 51, 51, 160); //r,g,b,a if (!LeaveCity && (this.CitizenIsDead || this.RealAge > 65)) { //Dead Peoples (this.CitizenDead == this.MyInstanceID || this.RealAge > 65) try { //Citizen Life Status //this.CitizenRowData ["lifestatus"] = "People_Life_Status_Dead"; //Happiness x.x //this.CitizenRowData ["happiness_icon"] = "NotificationIconDead"; this.FavCimsHappyIcon.normalBgSprite = "NotificationIconDead"; this.FavCimsHappyIcon.tooltip = FavCimsLang.text ("People_Life_Status_Dead"); //Name //this.CitizenRowData ["name"] = this.MyInstancedName; this.FavCimsCitizenName.text = this.MyInstancedName; this.FavCimsCitizenName.tooltip = FavCimsLang.text ("People_Life_Status_Dead") + " " + FavCimsLang.text ("People_Life_Status_Dead_date") + " " + this.DeathDate + " " + FavCimsLang.text ("People_Life_Status_Dead_time") + " " + this.DeathTime; //Info Button this.OtherInfoButton.isEnabled = false; //AgePhase //this.CitizenRowData ["agegroup"] = "Dead"; this.FavCimsAgePhase.text = FavCimsLang.text ("AgePhaseDead_" + this.CitizenRowData ["gender"]); //Home this.FavCimsCitizenHome.text = FavCimsLang.text ("Home_Location_Dead"); this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTextureDead; this.FavCimsCitizenHome.tooltip = null; this.FavCimsCitizenHome.isEnabled = false; this.FavCimsCitizenResidentialLevelSprite.texture = null; this.FavCimsCitizenHomeSprite.tooltip = null; //Working Place this.FavCimsWorkingPlace.isEnabled = false; this.FavCimsWorkingPlace.tooltip = null; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; this.FavCimsWorkingPlaceSprite.tooltip = null; this.FavCimsWorkingPlaceButtonGamDefImg.tooltip = null; //Last Activity this.FavCimsLastActivity.isEnabled = false; this.FavCimsLastActivityVehicleButton.isEnabled = false; this.FavCimsLastActivityVehicleButton.disabledBgSprite = "NotificationIconDead"; this.FavCimsLastActivityVehicleButton.tooltip = null; this.FavCimsLastActivity.tooltip = null; this.FavCimsLastActivity.text = FavCimsLang.text("Citizen_buried"); this.CitizenRowData.Clear (); }catch (Exception e) { Debug.Error("error " + e.ToString()); } } else { //Citizen Life Status //this.CitizenRowData ["lifestatus"] = "People_Life_Status_IsGone"; //Happiness ==> //this.CitizenRowData ["happiness_icon"] = ""; this.FavCimsHappyIcon.normalBgSprite = ""; this.FavCimsHappyIcon.tooltip = null; //Happiness Icon Override (For leaving people) this.FavCimsHappyOverride.texture = TextureDB.FavCimsHappyOverride_texture; this.FavCimsHappyOverride.relativePosition = new Vector3 (0, 0); this.FavCimsHappyOverride.tooltip = FavCimsLang.text ("People_Life_Status_IsGone"); //Name //this.CitizenRowData ["name"] = this.MyInstancedName; this.FavCimsCitizenName.text = this.MyInstancedName; this.FavCimsCitizenName.tooltip = FavCimsLang.text ("People_Life_Status_IsGone") + " " + FavCimsLang.text ("People_Life_Status_Dead_date") + " " + this.DeathDate + " " + FavCimsLang.text ("People_Life_Status_Dead_time") + " " + this.DeathTime; //Info Button this.OtherInfoButton.isEnabled = false; //Home this.FavCimsCitizenHome.text = FavCimsLang.text ("HomeOutsideTheCity"); this.FavCimsCitizenHomeSprite.texture = TextureDB.FavCimsCitizenHomeTextureHomeless; this.FavCimsCitizenHome.tooltip = null; this.FavCimsCitizenHome.isEnabled = false; this.FavCimsCitizenResidentialLevelSprite.texture = null; this.FavCimsCitizenHomeSprite.tooltip = null; //Working Place this.FavCimsWorkingPlace.isEnabled = false; this.FavCimsWorkingPlace.tooltip = null; this.FavCimsCitizenWorkPlaceLevelSprite.texture = null; //Last Activity //Ha lasciato la citta'. this.FavCimsLastActivity.isEnabled = false; this.FavCimsLastActivityVehicleButton.isEnabled = false; this.FavCimsLastActivityVehicleButton.disabledBgSprite = "NotificationIconDead"; this.FavCimsLastActivity.tooltip = null; this.CitizenRowData.Clear (); } } else { try { if(this.MyFamily != null) { this.MyFamily.Hide(); this.MyFamily.MyInstanceID = InstanceID.Empty; this.MyFamily = null; } GameObject.Destroy (this.gameObject); } catch { /*(Exception e)*/ //Debug.Log ("CitizenName Error Destroy Object" + e.ToString ()); } } } } } catch { /*(Exception e)*/ //Debug.Error ("Update Row Error" + e.ToString ()); } } return; }
internal void FamilyPet(uint m_citizen) { if (m_citizen == 0) return; try { //Family Pets this.CitizenInstance = this.MyCitizen.m_citizens.m_buffer[m_citizen].m_instance; //if (this.CitizenInstance != 0) { this.Pet = (ushort)Array.FindIndex (MyCitizen.m_instances.m_buffer, element => element.m_targetBuilding == this.CitizenInstance); this.PetInstance = this.MyCitizen.m_instances.m_buffer [this.Pet]; //if (this.PetInstance.Info.m_citizenAI.m_info.GetService() == h //Citizen.Flags.DummyTraffic //Vehicle.Flags.WaitingTarget if (this.PetInstance.Info.m_citizenAI.IsAnimal ()) { this.DogOwner = m_citizen; this.MyPetID.CitizenInstance = this.Pet; if (!this.MyPetID.IsEmpty) { InstanceID MyPetTargetID; string petname = MyCitizen.GetInstanceName (Pet); CitizenInfo petinfo = PetInstance.Info; string petstatus = petinfo.m_citizenAI.GetLocalizedStatus (Pet, ref PetInstance, out MyPetTargetID); this.BubbleFamilyBarDogButton.texture = TextureDB.BubbleDog; this.BubbleFamilyBarDogButton.tooltip = petname + " - " + petstatus + " " + this.MyCitizen.GetCitizenName (m_citizen); this.BubbleFamilyBarDogButton.playAudioEvents = true; } } else { this.DogOwner = 0; this.BubbleFamilyBarDogButton.texture = TextureDB.BubbleDogDisabled; this.BubbleFamilyBarDogButton.tooltip = null; this.BubbleFamilyBarDogButton.playAudioEvents = false; this.MyPetID = InstanceID.Empty; } //} else { //return; //} } catch /*(Exception e)*/ { //Debug.Log("Family Dog Error - " + e.ToString()); } }
private bool GetAnimal() { _animal = _instance.m_instances.m_buffer[(int)_id]; if (_animal.Info == null) return false; if (!_animal.Info.m_citizenAI.IsAnimal()) return false; if ((_animal.m_flags & CitizenInstance.Flags.Created) == CitizenInstance.Flags.None) return false; if (float.IsNegativeInfinity(_animal.Info.m_maxRenderDistance)) return false; return true; }
protected void ReachedDestination(uint citizen, CitizenInstance citizenData) { BuildingManager manager2 = Singleton<BuildingManager>.instance; BuildingInfo info = manager2.m_buildings.m_buffer[citizenData.m_sourceBuilding].Info; int amountDelta = 50; info.m_buildingAI.ModifyMaterialBuffer(citizenData.m_sourceBuilding, ref manager2.m_buildings.m_buffer[citizenData.m_sourceBuilding], TransferManager.TransferReason.Worker0, ref amountDelta); //Logger.dbgLog(citizen.ToString() + " chappy was:" + commuteHappinness[citizen].ToString() + " *3.0 + cwait:"+ commuteWait[citizen].ToString() + " // 4 will be: " + (((int)commuteHappinness[citizen] * 3.0 + (int)commuteWait[citizen]) / 4.0).ToString()); commuteHappinness[citizen] = (byte)Mathf.Clamp((int)( ( (int)commuteHappinness[citizen] * 3.0 + (int)commuteWait[citizen]) / 4.0), 0, 255); commuteWait[citizen] = 0; // if (commuteHappinness[citizen] > 0) // { // Logger.dbgLog(citizen.ToString() + " chappy now:" + commuteHappinness[citizen].ToString() + "cwait:" + commuteWait[citizen].ToString()); // } }
private bool TryJoinVehicle(ushort instanceID, ref CitizenInstance citizenData, ushort vehicleID, ref Vehicle vehicleData) { if ((vehicleData.m_flags & Vehicle.Flags.Stopped) == Vehicle.Flags.None) { return false; } CitizenManager instance = Singleton<CitizenManager>.instance; uint num = vehicleData.m_citizenUnits; int num2 = 0; while (num != 0u) { uint nextUnit = instance.m_units.m_buffer [(int)((UIntPtr)num)].m_nextUnit; for (int i = 0; i < 5; i++) { uint citizen = instance.m_units.m_buffer [(int)((UIntPtr)num)].GetCitizen (i); if (citizen != 0u) { ushort instance2 = instance.m_citizens.m_buffer [(int)((UIntPtr)citizen)].m_instance; if (instance2 != 0 && instance.m_instances.m_buffer [(int)instance2].m_targetBuilding == citizenData.m_targetBuilding) { instance.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetVehicle (citizenData.m_citizen, vehicleID, 0u); if (instance.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].m_vehicle == vehicleID) { if (citizenData.m_path != 0u) { Singleton<PathManager>.instance.ReleasePath (citizenData.m_path); citizenData.m_path = 0u; } return true; } } break; } } num = nextUnit; if (++num2 > 524288) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } return false; }
private void Spawn(ushort instanceID, ref CitizenInstance data) { Log.Error($"HumanAI.Spawn is not overriden!"); }
public static bool PreGetColor(ushort instanceID, ref CitizenInstance data, InfoManager.InfoMode infoMode, ref Color __result) => ACEColorGenUtils.GetColorGeneric <CitizenAssetFolderRuleXml, CitizenCityDataRuleXml, CitizenInfo>( ref __result, instanceID, ref AssetColorExpanderMod.Controller.CachedColor[(int)CacheOrder.CITIZEN], infoMode, ColorParametersGetter, Accepts, (x, y) => instanceID);
// CHECKME: check if this method allows to make people get away from traffic private static ushort CheckCitizen(Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max) { CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData(); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3(position, b); Vector3 vector = segment2.Min(); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max(); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; float num; float num2; if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius)) { float num3 = lastLen + nextLen * num; if (num3 >= 0.01f) { num3 -= 2f; float b2 = Mathf.Max(1f, CalculateMaxSpeed(num3, 0f, maxBraking)); maxSpeed = Mathf.Min(maxSpeed, b2); } } return otherData.m_nextGridInstance; }
private void GetBuildingTargetPosition(ushort instanceID, ref CitizenInstance citizenData, float minSqrDistance) { Log.Error($"HumanAI.GetBuildingTargetPosition is not overriden!"); }
protected override VehicleInfo GetVehicleInfo(ushort instanceID, ref CitizenInstance citizenData, bool forceProbability, out VehicleInfo trailer) { Randomizer r = new Randomizer(citizenData.m_citizen); trailer = (VehicleInfo)null; if (citizenData.m_citizen == 0U) { return((VehicleInfo)null); } try { if (!Utils.GetOutsideConnections().Contains(citizenData.m_sourceBuilding)) // tourist is NOT at an outside connection { Debug.LogWarning("Spawned only bikes for the toursit"); return(Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2)); // bikes } } catch (Exception e) { Debug.Log("error when trying to spawn only bikes" + e); } // otherwise use original game code, they are just trying to drive to the city Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel; int num1; int num2; int num3; if (forceProbability || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None) { num1 = 100; num2 = 0; num3 = wealthLevel == Citizen.Wealth.Low ? 20 : wealthLevel == Citizen.Wealth.Medium ? 30 : 40; // camper prob } else { num1 = 20; // car prob num2 = 20; // bike prob num3 = 0; } bool flag1 = r.Int32(100U) < num1; bool flag2 = r.Int32(100U) < num2; bool flag3 = r.Int32(100U) < num3; bool flag4; bool flag5; if (flag1) { int electricCarProbability = wealthLevel == Citizen.Wealth.Low ? 10 : wealthLevel == Citizen.Wealth.Medium ? 15 : 20;; flag4 = false; flag5 = r.Int32(100U) < electricCarProbability; } else { int taxiProbability = 20; flag4 = r.Int32(100U) < taxiProbability; flag5 = false; } ItemClass.Service service = ItemClass.Service.Residential; ItemClass.SubService subService = !flag5 ? ItemClass.SubService.ResidentialLow : ItemClass.SubService.ResidentialLowEco; if (!flag1 && flag4) { service = ItemClass.Service.PublicTransport; subService = ItemClass.SubService.PublicTransportTaxi; } VehicleInfo randomVehicleInfo1; if (flag3) { Randomizer randomizer = r; randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level2); if (randomVehicleInfo1 == null || randomVehicleInfo1.m_vehicleAI is CarTrailerAI) { trailer = randomVehicleInfo1; r = randomizer; randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level1); } } else { randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level1); } VehicleInfo randomVehicleInfo2 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2); if (flag2 && randomVehicleInfo2 != null) // Bikes { return(randomVehicleInfo2); } if ((flag1 || flag4) && randomVehicleInfo1 != null) { return(randomVehicleInfo1); } return((VehicleInfo)null); }
//private void _SetSource(ushort instanceID, ref CitizenInstance data, ushort sourceBuilding) // copied from original code //{ // if ((int)sourceBuilding != (int)data.m_sourceBuilding) // { // if (data.m_sourceBuilding != (ushort)0) // Singleton<BuildingManager>.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].RemoveSourceCitizen(instanceID, ref data); // data.m_sourceBuilding = sourceBuilding; // if (data.m_sourceBuilding != (ushort)0) // Singleton<BuildingManager>.instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].AddSourceCitizen(instanceID, ref data); // } // if (sourceBuilding == (ushort)0) // return; // BuildingManager instance = Singleton<BuildingManager>.instance; // BuildingInfo info = instance.m_buildings.m_buffer[(int)sourceBuilding].Info; // data.Unspawn(instanceID); // Randomizer randomizer = new Randomizer((int)instanceID); // Vector3 position; // Vector3 target; // info.m_buildingAI.CalculateSpawnPosition(sourceBuilding, ref instance.m_buildings.m_buffer[(int)sourceBuilding], ref randomizer, this.m_info, out position, out target); // Quaternion quaternion = Quaternion.identity; // Vector3 forward = target - position; // if ((double)forward.sqrMagnitude > 0.00999999977648258) // quaternion = Quaternion.LookRotation(forward); // data.m_frame0.m_velocity = Vector3.zero; // data.m_frame0.m_position = position; // data.m_frame0.m_rotation = quaternion; // data.m_frame1 = data.m_frame0; // data.m_frame2 = data.m_frame0; // data.m_frame3 = data.m_frame0; // data.m_targetPos = new Vector4(target.x, target.y, target.z, 1f); // Color32 eventCitizenColor = Singleton<EventManager>.instance.GetEventCitizenColor(instance.m_buildings.m_buffer[(int)sourceBuilding].m_eventIndex, data.m_citizen); // if (eventCitizenColor.a != byte.MaxValue) // return; // data.m_color = eventCitizenColor; // data.m_flags |= CitizenInstance.Flags.CustomColor; //} private void _SetTarget(ushort instanceID, ref CitizenInstance data, ushort targetIndex, bool targetIsNode) { if ((int)targetIndex != (int)data.m_targetBuilding || targetIsNode != ((data.m_flags & CitizenInstance.Flags.TargetIsNode) != CitizenInstance.Flags.None)) { if (data.m_targetBuilding != (ushort)0) { if ((data.m_flags & CitizenInstance.Flags.TargetIsNode) != CitizenInstance.Flags.None) { Singleton <NetManager> .instance.m_nodes.m_buffer[(int)data.m_targetBuilding].RemoveTargetCitizen(instanceID, ref data); ushort num = 0; if (targetIsNode) { num = Singleton <NetManager> .instance.m_nodes.m_buffer[(int)data.m_targetBuilding].m_transportLine; } if ((data.m_flags & CitizenInstance.Flags.OnTour) != CitizenInstance.Flags.None) { ushort transportLine = Singleton <NetManager> .instance.m_nodes.m_buffer[(int)data.m_targetBuilding].m_transportLine; uint citizen = data.m_citizen; if (transportLine != (ushort)0 && (int)transportLine != (int)num && citizen != 0U) { TransportInfo info = Singleton <TransportManager> .instance.m_lines.m_buffer[(int)transportLine].Info; if (info != null && info.m_vehicleType == VehicleInfo.VehicleType.None) { data.m_flags &= ~CitizenInstance.Flags.OnTour; } } } if (!targetIsNode) { data.m_flags &= ~CitizenInstance.Flags.TargetIsNode; } } else { Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_targetBuilding].RemoveTargetCitizen(instanceID, ref data); } } data.m_targetBuilding = targetIndex; if (targetIsNode) { data.m_flags |= CitizenInstance.Flags.TargetIsNode; } if (data.m_targetBuilding != (ushort)0) { if ((data.m_flags & CitizenInstance.Flags.TargetIsNode) != CitizenInstance.Flags.None) { Singleton <NetManager> .instance.m_nodes.m_buffer[(int)data.m_targetBuilding].AddTargetCitizen(instanceID, ref data); } else { Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_targetBuilding].AddTargetCitizen(instanceID, ref data); } data.m_targetSeed = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(256U); } } if ((data.m_flags & CitizenInstance.Flags.TargetIsNode) == CitizenInstance.Flags.None && IsRoadConnection(targetIndex) || IsRoadConnection(data.m_sourceBuilding)) { data.m_flags |= CitizenInstance.Flags.BorrowCar; } else { data.m_flags &= ~CitizenInstance.Flags.BorrowCar; } if (targetIndex != (ushort)0 && (data.m_flags & (CitizenInstance.Flags.Character | CitizenInstance.Flags.TargetIsNode)) == CitizenInstance.Flags.None) { Color32 eventCitizenColor = Singleton <EventManager> .instance.GetEventCitizenColor(Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetIndex].m_eventIndex, data.m_citizen); if (eventCitizenColor.a == byte.MaxValue) { data.m_color = eventCitizenColor; data.m_flags |= CitizenInstance.Flags.CustomColor; } } if (this.StartPathFind(instanceID, ref data)) { return; } data.Unspawn(instanceID); } // copied from original code
protected override bool SpawnVehicle(ushort instanceID, ref CitizenInstance citizenData, PathUnit.Position pathPos) { VehicleManager instance = Singleton<VehicleManager>.instance; float num = 20f; int num2 = Mathf.Max ((int)((citizenData.m_targetPos.x - num) / 32f + 270f), 0); int num3 = Mathf.Max ((int)((citizenData.m_targetPos.z - num) / 32f + 270f), 0); int num4 = Mathf.Min ((int)((citizenData.m_targetPos.x + num) / 32f + 270f), 539); int num5 = Mathf.Min ((int)((citizenData.m_targetPos.z + num) / 32f + 270f), 539); for (int i = num3; i <= num5; i++) { for (int j = num2; j <= num4; j++) { ushort num6 = instance.m_vehicleGrid [i * 540 + j]; int num7 = 0; while (num6 != 0) { if (this.TryJoinVehicle (instanceID, ref citizenData, num6, ref instance.m_vehicles.m_buffer [(int)num6])) { citizenData.m_flags |= CitizenInstance.Flags.EnteringVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.TryingSpawnVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; citizenData.m_waitCounter = 0; return true; } num6 = instance.m_vehicles.m_buffer [(int)num6].m_nextGridVehicle; if (++num7 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } NetManager instance2 = Singleton<NetManager>.instance; CitizenManager instance3 = Singleton<CitizenManager>.instance; Vector3 vector = Vector3.zero; Quaternion rotation = Quaternion.identity; ushort num8 = instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle; if (num8 != 0) { vector = instance.m_parkedVehicles.m_buffer [(int)num8].m_position; rotation = instance.m_parkedVehicles.m_buffer [(int)num8].m_rotation; } VehicleInfo vehicleInfo = this.GetVehicleInfo (instanceID, ref citizenData, false); if (vehicleInfo == null || vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle (citizenData.m_citizen, 0); if ((citizenData.m_flags & CitizenInstance.Flags.TryingSpawnVehicle) == CitizenInstance.Flags.None) { citizenData.m_flags |= CitizenInstance.Flags.TryingSpawnVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; citizenData.m_waitCounter = 0; } return true; } if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi) { instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle (citizenData.m_citizen, 0); if ((citizenData.m_flags & CitizenInstance.Flags.WaitingTaxi) == CitizenInstance.Flags.None) { citizenData.m_flags |= CitizenInstance.Flags.WaitingTaxi; citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; citizenData.m_waitCounter = 0; } return true; } uint laneID = PathManager.GetLaneID (pathPos); Vector3 vector2 = citizenData.m_targetPos; if (num8 != 0 && Vector3.SqrMagnitude (vector - vector2) < 1024f) { vector2 = vector; } else { num8 = 0; } Vector3 a; float num9; instance2.m_lanes.m_buffer [(int)((UIntPtr)laneID)].GetClosestPosition (vector2, out a, out num9); byte lastPathOffset = (byte)Mathf.Clamp (Mathf.RoundToInt (num9 * 255f), 0, 255); a = vector2 + Vector3.ClampMagnitude (a - vector2, 5f); ushort num10; if (instance.CreateVehicle (out num10, ref Singleton<SimulationManager>.instance.m_randomizer, vehicleInfo, vector2, TransferManager.TransferReason.None, false, false)) { Vehicle.Frame frame = instance.m_vehicles.m_buffer [(int)num10].m_frame0; if (num8 != 0) { frame.m_rotation = rotation; } else { Vector3 forward = a - citizenData.GetLastFrameData ().m_position; if (forward.sqrMagnitude > 0.01f) { frame.m_rotation = Quaternion.LookRotation (forward); } } instance.m_vehicles.m_buffer [(int)num10].m_frame0 = frame; instance.m_vehicles.m_buffer [(int)num10].m_frame1 = frame; instance.m_vehicles.m_buffer [(int)num10].m_frame2 = frame; instance.m_vehicles.m_buffer [(int)num10].m_frame3 = frame; vehicleInfo.m_vehicleAI.FrameDataUpdated (num10, ref instance.m_vehicles.m_buffer [(int)num10], ref frame); instance.m_vehicles.m_buffer [(int)num10].m_targetPos0 = new Vector4 (a.x, a.y, a.z, 2f); Vehicle[] expr_4E5_cp_0 = instance.m_vehicles.m_buffer; ushort expr_4E5_cp_1 = num10; expr_4E5_cp_0 [(int)expr_4E5_cp_1].m_flags = (expr_4E5_cp_0 [(int)expr_4E5_cp_1].m_flags | Vehicle.Flags.Stopped); instance.m_vehicles.m_buffer [(int)num10].m_path = citizenData.m_path; instance.m_vehicles.m_buffer [(int)num10].m_pathPositionIndex = citizenData.m_pathPositionIndex; instance.m_vehicles.m_buffer [(int)num10].m_lastPathOffset = lastPathOffset; instance.m_vehicles.m_buffer [(int)num10].m_transferSize = (ushort)(citizenData.m_citizen & 65535u); vehicleInfo.m_vehicleAI.TrySpawn (num10, ref instance.m_vehicles.m_buffer [(int)num10]); if (num8 != 0) { InstanceID empty = InstanceID.Empty; empty.ParkedVehicle = num8; InstanceID empty2 = InstanceID.Empty; empty2.Vehicle = num10; Singleton<InstanceManager>.instance.ChangeInstance (empty, empty2); } citizenData.m_path = 0u; instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle (citizenData.m_citizen, 0); instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetVehicle (citizenData.m_citizen, num10, 0u); citizenData.m_flags |= CitizenInstance.Flags.EnteringVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.TryingSpawnVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; citizenData.m_waitCounter = 0; return true; } instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle (citizenData.m_citizen, 0); if ((citizenData.m_flags & CitizenInstance.Flags.TryingSpawnVehicle) == CitizenInstance.Flags.None) { citizenData.m_flags |= CitizenInstance.Flags.TryingSpawnVehicle; citizenData.m_flags &= ~CitizenInstance.Flags.BoredOfWaiting; citizenData.m_waitCounter = 0; } return true; }
public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo, bool enableTransport, bool ignoreCost) { return(ExtStartPathFind(instanceID, ref citizenData, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID], ref ExtCitizenManager.Instance.ExtCitizens[Singleton <CitizenManager> .instance.m_instances.m_buffer[instanceID].m_citizen], startPos, endPos, vehicleInfo, enableTransport, ignoreCost)); }