/// <summary> /// Copied from original game code at game version 1.5.0-f4. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="data">The data.</param> /// <returns>True if vehicle should return to source.</returns> private static bool GarbageTruckAI_ShouldReturnToSource_Original(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle data) { if ((int)data.m_sourceBuilding != 0) { BuildingManager instance = Singleton <BuildingManager> .instance; if (((int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_productionRate == 0 || (instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_flags & (Building.Flags.Downgrading | Building.Flags.BurnedDown)) != Building.Flags.None) && (int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_fireIntensity == 0) { return(true); } } return(false); }
/// <summary> /// Copied from original game code at game version 1.2.0. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI instance.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="vehicleData">The vehicle data.</param> /// <param name="frameData">The frame data.</param> /// <param name="buildingID">The building identifier.</param> /// <param name="building">The building.</param> private static void GarbageTruckAI_TryCollectGarbage_Original(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ushort buildingID, ref Building building) { if ((double)Vector3.SqrMagnitude(building.CalculateSidewalkPosition() - frameData.m_position) >= 1024.0) { return; } int amountDelta = Math.Min(0, (int)vehicleData.m_transferSize - garbageTruckAI.m_cargoCapacity); if (amountDelta == 0) { return; } building.Info.m_buildingAI.ModifyMaterialBuffer(buildingID, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, ref amountDelta); if (amountDelta == 0) { return; } vehicleData.m_transferSize += (ushort)Math.Max(0, -amountDelta); }
/// <summary> /// Vehicles with no target should always return to source. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI.</param> /// <param name="vehicleId">The vehicle identifier.</param> /// <param name="vehicle">The vehicle.</param> /// <returns>True if vehicle should return to source.</returns> private static bool GarbageTruckAI_ShouldReturnToSource_Override(GarbageTruckAI garbageTruckAI, ushort vehicleId, ref Vehicle vehicle) { Calls++; if (vehicle.m_sourceBuilding == 0) { return(false); } if (vehicle.m_targetBuilding == 0 && (vehicle.m_flags & Vehicle.Flags.TransferToTarget) == ~VehicleHelper.VehicleAll /* && (vehicle.m_flags & Vehicle.Flags.TransferToSource) == ~Vehicle.Flags.All */) { BuildingManager instance = Singleton <BuildingManager> .instance; if (instance.m_buildings.m_buffer[vehicle.m_sourceBuilding].m_fireIntensity == 0) { Returns++; return(true); } } return(GarbageTruckAI_ShouldReturnToSource_Original(garbageTruckAI, vehicleId, ref vehicle)); }
/// <summary> /// Vehicles with no target should always return to source. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI.</param> /// <param name="vehicleId">The vehicle identifier.</param> /// <param name="vehicle">The vehicle.</param> /// <returns>True if vehicle should return to source.</returns> private static bool GarbageTruckAI_ShouldReturnToSource_Override(GarbageTruckAI garbageTruckAI, ushort vehicleId, ref Vehicle vehicle) { Calls++; if (vehicle.m_sourceBuilding == 0) { return false; } if (vehicle.m_targetBuilding == 0 && (vehicle.m_flags & Vehicle.Flags.TransferToTarget) == ~Vehicle.Flags.All /* && (vehicle.m_flags & Vehicle.Flags.TransferToSource) == ~Vehicle.Flags.All */) { BuildingManager instance = Singleton<BuildingManager>.instance; if (instance.m_buildings.m_buffer[vehicle.m_sourceBuilding].m_fireIntensity == 0) { Returns++; return true; } } return GarbageTruckAI_ShouldReturnToSource_Original(garbageTruckAI, vehicleId, ref vehicle); }
/// <summary> /// Copied from original game code at game version 1.5.0-f4. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="data">The data.</param> /// <returns>True if vehicle should return to source.</returns> private static bool GarbageTruckAI_ShouldReturnToSource_Original(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle data) { if ((int)data.m_sourceBuilding != 0) { BuildingManager instance = Singleton<BuildingManager>.instance; if (((int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_productionRate == 0 || (instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_flags & (Building.Flags.Downgrading | Building.Flags.BurnedDown)) != Building.Flags.None) && (int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_fireIntensity == 0) return true; } return false; }
public static bool Prefix(ref GarbageTruckAI __instance, ushort vehicleID, ref Vehicle data, ref bool __result) { if (data.m_targetBuilding == 0) { __result = true; return(false); } int num = 0; if ((data.m_flags & Vehicle.Flags.TransferToTarget) != (Vehicle.Flags) 0) { num = (int)data.m_transferSize; } if ((data.m_flags & Vehicle.Flags.TransferToSource) != (Vehicle.Flags) 0) { num = Mathf.Min(0, (int)data.m_transferSize - __instance.m_cargoCapacity); } BuildingManager instance = Singleton <BuildingManager> .instance; BuildingInfo info = instance.m_buildings.m_buffer[(int)data.m_targetBuilding].Info; info.m_buildingAI.ModifyMaterialBuffer(data.m_targetBuilding, ref instance.m_buildings.m_buffer[(int)data.m_targetBuilding], (TransferManager.TransferReason)data.m_transferType, ref num); ProcessGarbageIncomeArriveAtTarget(vehicleID, ref data, num); if ((data.m_flags & Vehicle.Flags.TransferToTarget) != (Vehicle.Flags) 0) { data.m_transferSize = (ushort)Mathf.Clamp((int)data.m_transferSize - num, 0, (int)data.m_transferSize); } if ((data.m_flags & Vehicle.Flags.TransferToSource) != (Vehicle.Flags) 0) { data.m_transferSize += (ushort)Mathf.Max(0, -num); } // NON-STOCK CODE START //Go back if (data.m_sourceBuilding != 0 && (instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.Outgoing) { BuildingInfo info2 = instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].Info; ushort num2 = instance.FindBuilding(instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position, 200f, info2.m_class.m_service, ItemClass.SubService.None, Building.Flags.Incoming, Building.Flags.Outgoing); if (num2 != 0) { instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].RemoveOwnVehicle(vehicleID, ref data); data.m_sourceBuilding = num2; instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].AddOwnVehicle(vehicleID, ref data); } } //Turn around if ((instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.Incoming) { if (Loader.isRealCityRunning) { double x = instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position.x - instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position.x; double z = instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position.z - instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position.z; x = (x > 0) ? x : -x; z = (z > 0) ? z : -z; double distance = (x + z); int money = (int)(-num * (distance / 4000f)); Singleton <EconomyManager> .instance.AddPrivateIncome(money, ItemClass.Service.Garbage, ItemClass.SubService.None, ItemClass.Level.Level3, 115333); CustomPlayerBuildingAI.canReturn[vehicleID] = true; if (Loader.isRealCityV10) { RealCityUtil.InitDelegate(); if (RealCityUtil.GetRealCityV10()) { RealCityUtil.SetOutsideGovermentMoney(RealCityUtil.GetOutsideGovermentMoney() - money); } } } ushort num3 = instance.FindBuilding(instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position, 200f, info.m_class.m_service, ItemClass.SubService.None, Building.Flags.Outgoing, Building.Flags.Incoming); if (num3 != 0) { BuildingInfo info3 = instance.m_buildings.m_buffer[(int)num3].Info; Randomizer randomizer = new Randomizer((int)vehicleID); Vector3 vector; Vector3 vector2; info3.m_buildingAI.CalculateSpawnPosition(num3, ref instance.m_buildings.m_buffer[(int)num3], ref randomizer, __instance.m_info, out vector, out vector2); Quaternion rotation = Quaternion.identity; Vector3 forward = vector2 - vector; if (forward.sqrMagnitude > 0.01f) { rotation = Quaternion.LookRotation(forward); } data.m_frame0 = new Vehicle.Frame(vector, rotation); data.m_frame1 = data.m_frame0; data.m_frame2 = data.m_frame0; data.m_frame3 = data.m_frame0; data.m_targetPos0 = vector; data.m_targetPos0.w = 2f; data.m_targetPos1 = vector2; data.m_targetPos1.w = 2f; data.m_targetPos2 = data.m_targetPos1; data.m_targetPos3 = data.m_targetPos1; __instance.FrameDataUpdated(vehicleID, ref data, ref data.m_frame0); __instance.SetTarget(vehicleID, ref data, 0); __result = false; return(false); } } /// NON-STOCK CODE END /// __instance.SetTarget(vehicleID, ref data, 0); __result = false; return(false); }
/// <summary> /// Method overriding GarbageTruckAI.TryCollectGarbage. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI instance.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="vehicleData">The vehicle data.</param> /// <param name="frameData">The frame data.</param> /// <param name="buildingID">The building identifier.</param> /// <param name="building">The building.</param> private static void GarbageTruckAI_TryCollectGarbage_Override(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ushort buildingID, ref Building building) { try { Tries++; ////if (Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", vehicleID, buildingID); ////} if (garbageTruckAI == null || vehicleID == 0 || buildingID == 0) { return; } ////Log.InfoList logInfo = null; ////if (Log.LogToFile && Log.LogALot) ////{ //// logInfo = NewGarbageVehicleInfoList(vehicleID, ref vehicleData, buildingID, ref building); ////} if (vehicleData.m_targetBuilding == 0) { ////if (Log.LogToFile && Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", "NoTarget", logInfo); ////} GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); return; } if (vehicleData.m_targetBuilding == buildingID) { ////if (Log.LogToFile && Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", "IsTarget", logInfo); ////} GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); return; } int freeCapacity = garbageTruckAI.m_cargoCapacity - vehicleData.m_transferSize; if (freeCapacity < 0) { freeCapacity = 0; } ////if (logInfo != null) ////{ //// logInfo.Add("FreeCapacity", freeCapacity); ////} int buildingMax; int buildingAmount; building.Info.m_buildingAI.GetMaterialAmount(buildingID, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, out buildingAmount, out buildingMax); ////if (logInfo != null) ////{ //// logInfo.Add("DirtyBuildingAmount", buildingAmount); ////} if (buildingAmount > freeCapacity) { ////if (Log.LogToFile && Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", "NoCapacity", logInfo); ////} Limitations++; return; } Building[] buildings = Singleton<BuildingManager>.instance.m_buildings.m_buffer; Building targetBuilding = buildings[vehicleData.m_targetBuilding]; int targetBuildingAmount; targetBuilding.Info.m_buildingAI.GetMaterialAmount(vehicleData.m_targetBuilding, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, out targetBuildingAmount, out buildingMax); ////if (logInfo != null) ////{ //// logInfo.Add("TargetBuildingAmount", targetBuildingAmount); ////} if (buildingAmount + targetBuildingAmount > freeCapacity) { ////if (Log.LogToFile && Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", "NotEnoughCapacity", logInfo); ////} Limitations++; return; } ////if (Log.LogToFile && Log.LogALot) ////{ //// Log.DevDebug(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", "Default", logInfo); ////} GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); } catch (Exception ex) { Log.Error(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", ex); Detours.Abort(Detours.Methods.GarbageTruckAI_TryCollectGarbage); } }
/// <summary> /// Copied from original game code at game version 1.2.0. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI instance.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="vehicleData">The vehicle data.</param> /// <param name="frameData">The frame data.</param> /// <param name="buildingID">The building identifier.</param> /// <param name="building">The building.</param> private static void GarbageTruckAI_TryCollectGarbage_Original(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ushort buildingID, ref Building building) { if ((double)Vector3.SqrMagnitude(building.CalculateSidewalkPosition() - frameData.m_position) >= 1024.0) return; int amountDelta = Mathf.Min(0, (int)vehicleData.m_transferSize - garbageTruckAI.m_cargoCapacity); if (amountDelta == 0) return; building.Info.m_buildingAI.ModifyMaterialBuffer(buildingID, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, ref amountDelta); if (amountDelta == 0) return; vehicleData.m_transferSize += (ushort)Mathf.Max(0, -amountDelta); }
/// <summary> /// Method overriding GarbageTruckAI.TryCollectGarbage. /// </summary> /// <param name="garbageTruckAI">The garbage truck AI instance.</param> /// <param name="vehicleID">The vehicle identifier.</param> /// <param name="vehicleData">The vehicle data.</param> /// <param name="frameData">The frame data.</param> /// <param name="buildingID">The building identifier.</param> /// <param name="building">The building.</param> private static void GarbageTruckAI_TryCollectGarbage_Override(GarbageTruckAI garbageTruckAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ushort buildingID, ref Building building) { try { Tries++; if (garbageTruckAI == null || vehicleID == 0 || buildingID == 0) { return; } if (vehicleData.m_targetBuilding == 0) { GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); return; } if (vehicleData.m_targetBuilding == buildingID) { GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); return; } int freeCapacity = garbageTruckAI.m_cargoCapacity - vehicleData.m_transferSize; if (freeCapacity < 0) { freeCapacity = 0; } int buildingMax; int buildingAmount; building.Info.m_buildingAI.GetMaterialAmount(buildingID, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, out buildingAmount, out buildingMax); if (buildingAmount > freeCapacity) { Limitations++; return; } Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer; Building targetBuilding = buildings[vehicleData.m_targetBuilding]; int targetBuildingAmount; targetBuilding.Info.m_buildingAI.GetMaterialAmount(vehicleData.m_targetBuilding, ref building, (TransferManager.TransferReason)vehicleData.m_transferType, out targetBuildingAmount, out buildingMax); if (buildingAmount + targetBuildingAmount > freeCapacity) { Limitations++; return; } GarbageTruckAI_TryCollectGarbage_Original(garbageTruckAI, vehicleID, ref vehicleData, ref frameData, buildingID, ref building); } catch (Exception ex) { Log.Error(typeof(GarbageTruckAITryCollectGarbageDetour), "GarbageTruckAI_TryCollectGarbage_Override", ex); Detours.Abort(Detours.Methods.GarbageTruckAI_TryCollectGarbage); } }