public static void SimulationStep(ref TransportLine thisLine, ushort lineID) { //begin mod(+): change for initialization if (!TransportLineMod._init) { return; } //end mod TransportInfo info = thisLine.Info; if (thisLine.Complete) { //begin mod(*): moved this section to a separate method int num2 = CountLineActiveVehicles(lineID); //end mod bool flag1 = !Singleton <SimulationManager> .instance.m_isNightTime ? (thisLine.m_flags & TransportLine.Flags.DisabledDay) == TransportLine.Flags.None : (thisLine.m_flags & TransportLine.Flags.DisabledNight) == TransportLine.Flags.None; uint range = 0; float num5 = 0.0f; int num6 = 0; bool flag2 = false; if ((int)thisLine.m_stops != 0) { NetManager instance = Singleton <NetManager> .instance; ushort stops = thisLine.m_stops; ushort num3 = stops; int num4 = 0; while ((int)num3 != 0) { ushort num7 = 0; if (flag1) { instance.m_nodes.m_buffer[(int)num3].m_flags &= NetNode.Flags.OneWayOutTrafficLights | NetNode.Flags.UndergroundTransition | NetNode.Flags.Created | NetNode.Flags.Deleted | NetNode.Flags.Original | NetNode.Flags.End | NetNode.Flags.Middle | NetNode.Flags.Bend | NetNode.Flags.Junction | NetNode.Flags.Moveable | NetNode.Flags.Untouchable | NetNode.Flags.Outside | NetNode.Flags.Temporary | NetNode.Flags.Double | NetNode.Flags.Fixed | NetNode.Flags.OnGround | NetNode.Flags.Ambiguous | NetNode.Flags.Water | NetNode.Flags.Sewage | NetNode.Flags.ForbidLaneConnection | NetNode.Flags.LevelCrossing | NetNode.Flags.OneWayIn | NetNode.Flags.Heating | NetNode.Flags.Electricity | NetNode.Flags.Collapsed | NetNode.Flags.DisableOnlyMiddle | NetNode.Flags.AsymForward | NetNode.Flags.AsymBackward | NetNode.Flags.CustomTrafficLights; } else { instance.m_nodes.m_buffer[(int)num3].m_flags |= NetNode.Flags.Disabled; } for (int index = 0; index < 8; ++index) { ushort segment = instance.m_nodes.m_buffer[(int)num3].GetSegment(index); if ((int)segment != 0 && (int)instance.m_segments.m_buffer[(int)segment].m_startNode == (int)num3) { num6 += Mathf.Max((int)instance.m_segments.m_buffer[(int)segment].m_trafficLightState0, (int)instance.m_segments.m_buffer[(int)segment].m_trafficLightState1); num5 += instance.m_segments.m_buffer[(int)segment].m_averageLength; num7 = instance.m_segments.m_buffer[(int)segment].m_endNode; if ((instance.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.PathLength) == NetSegment.Flags.None) { flag2 = true; break; } break; } } ++range; num3 = num7; if ((int)num3 != (int)stops) { if (++num4 >= 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } else { break; } } } if (!flag2) { thisLine.m_totalLength = num5; } if ((int)range != 0) { thisLine.m_averageInterval = (byte)Mathf.Min((float)byte.MaxValue, (float)(((long)num6 + (long)(range >> 1)) / (long)range)); } //begin mod(-): let's count maintenance once a week //end mod TransferManager.TransferReason vehicleReason = info.m_vehicleReason; if (vehicleReason != TransferManager.TransferReason.None) { //begin mod: calculate target vehicle count or read saved value int num3 = 0; if (TransportLineMod._lineData[(int)lineID].BudgetControl || info.m_class.m_service == ItemClass.Service.Disaster) { num3 = !flag1 ? 0 : (!flag2 ? thisLine.CalculateTargetVehicleCount() : num2); TransportLineMod._lineData[(int)lineID].TargetVehicleCount = num3; } else if (flag1) { num3 = TransportLineMod._lineData[(int)lineID].TargetVehicleCount; } //end mod if (range != 0 && num2 < num3) { ushort stop = thisLine.GetStop(Singleton <SimulationManager> .instance.m_randomizer .Int32((uint)thisLine.CountStops(lineID))); if (info.m_vehicleReason != TransferManager.TransferReason.None && (int)stop != 0) { //begin mod(+): save offer as variable and directly invoke spawn if it's not evac line TransferManager.TransferOffer offer = new TransferManager.TransferOffer { Priority = num3 - num2 + 1, TransportLine = lineID, Position = Singleton <NetManager> .instance.m_nodes.m_buffer[(int)stop] .m_position, Amount = 1, Active = false }; if (info.m_class.m_service == ItemClass.Service.Disaster) { Singleton <TransferManager> .instance.AddIncomingOffer(vehicleReason, offer); } else { HandleVehicleSpawn(lineID, info, num3, num2, offer); } //end mod } } else if (num2 > num3) { //begin mod(*): encapsulate into method TransportLineMod.RemoveActiveVehicle(lineID, false, num2); //end mod } } } if ((Singleton <SimulationManager> .instance.m_currentFrameIndex & 4095U) < 3840U) { return; } thisLine.m_passengers.Update(); Singleton <TransportManager> .instance.m_passengers[(int)info.m_transportType].Add(ref thisLine.m_passengers); thisLine.m_passengers.Reset(); //begin mod(+): update statistics + fetch maintenance costs if (thisLine.Complete) { ushort stops1 = thisLine.m_stops; ushort stop1 = stops1; do { NetManagerMod.m_cachedNodeData[(int)stop1].StartNewWeek(); stop1 = TransportLine.GetNextStop(stop1); } while ((int)stops1 != (int)stop1 && (int)stop1 != 0); var itemClass = info.m_class; PrefabData[] prefabs = VehiclePrefabs.instance.GetPrefabs(itemClass.m_service, itemClass.m_subService, itemClass.m_level); int amount = 0; CountLineActiveVehicles(lineID, (num3) => { Vehicle vehicle = VehicleManager.instance.m_vehicles.m_buffer[num3]; PrefabData prefabData = Array.Find(prefabs, item => item.PrefabDataIndex == vehicle.Info.m_prefabDataIndex); if (prefabData != null) { amount += prefabData.MaintenanceCost; VehicleManagerMod.m_cachedVehicleData[num3].StartNewWeek(prefabData.MaintenanceCost); } }); if (amount != 0) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, amount, info.m_class); } //end mod } }
public static VehicleInfo GetRandomVehicleInfo(VehicleManager manager, ref Randomizer r, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Level level, ushort sourceBuildingId, ushort targetBuildingId, TransferManager.TransferReason material) { if (material == TransferManager.TransferReason.Goods) { var selectVehicle = default(VehicleInfo); #if DEBUG var log = $"\n\tGet vehicle: source={sourceBuildingId}; target={targetBuildingId};"; if (CheckRules(sourceBuildingId, targetBuildingId, ref log)) #else if (CheckRules(sourceBuildingId, targetBuildingId)) #endif { var transferIndex = GetTransferIndex(service, subService, level); var noBigTrucks = GetVehicle(transferIndex); if (noBigTrucks.Any()) { var selectIndex = r.Int32((uint)noBigTrucks.Count); selectVehicle = noBigTrucks[selectIndex]; } #if DEBUG else { log += "No one no big truck"; } #endif } selectVehicle ??= manager.GetRandomVehicleInfo(ref r, service, subService, level); #if DEBUG log += $"\n\t{(selectVehicle != null ? $"Selected vehicle: { selectVehicle.name}" : "Vehicle not found")}"; SingletonMod <Mod> .Logger.Debug(log); #endif return(selectVehicle); } else { return(manager.GetRandomVehicleInfo(ref r, service, subService, level)); } }
public bool CustomCreateVehicle(out ushort vehicleId, ref Randomizer r, VehicleInfo info, Vector3 position, TransferManager.TransferReason type, bool transferToSource, bool transferToTarget) { ushort vehId; if (this.m_vehicles.CreateItem(out vehId, ref r)) { vehicleId = vehId; Vehicle.Frame frame = new Vehicle.Frame(position, Quaternion.identity); this.m_vehicles.m_buffer[(int)vehicleId].m_flags = Vehicle.Flags.Created; if (transferToSource) { this.m_vehicles.m_buffer[vehicleId].m_flags = (this.m_vehicles.m_buffer[vehicleId].m_flags | Vehicle.Flags.TransferToSource); } if (transferToTarget) { this.m_vehicles.m_buffer[vehicleId].m_flags = (this.m_vehicles.m_buffer[vehicleId].m_flags | Vehicle.Flags.TransferToTarget); } this.m_vehicles.m_buffer[(int)vehicleId].Info = info; this.m_vehicles.m_buffer[(int)vehicleId].m_frame0 = frame; this.m_vehicles.m_buffer[(int)vehicleId].m_frame1 = frame; this.m_vehicles.m_buffer[(int)vehicleId].m_frame2 = frame; this.m_vehicles.m_buffer[(int)vehicleId].m_frame3 = frame; this.m_vehicles.m_buffer[(int)vehicleId].m_targetPos0 = Vector4.zero; this.m_vehicles.m_buffer[(int)vehicleId].m_targetPos1 = Vector4.zero; this.m_vehicles.m_buffer[(int)vehicleId].m_targetPos2 = Vector4.zero; this.m_vehicles.m_buffer[(int)vehicleId].m_targetPos3 = Vector4.zero; this.m_vehicles.m_buffer[(int)vehicleId].m_sourceBuilding = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_targetBuilding = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_transferType = (byte)type; this.m_vehicles.m_buffer[(int)vehicleId].m_transferSize = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_waitCounter = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_blockCounter = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_nextGridVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_nextOwnVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_nextGuestVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_nextLineVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_transportLine = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_leadingVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_trailingVehicle = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_cargoParent = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_firstCargo = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_nextCargo = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_citizenUnits = 0u; this.m_vehicles.m_buffer[(int)vehicleId].m_path = 0u; this.m_vehicles.m_buffer[(int)vehicleId].m_lastFrame = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_pathPositionIndex = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_lastPathOffset = 0; this.m_vehicles.m_buffer[(int)vehicleId].m_gateIndex = 0; info.m_vehicleAI.CreateVehicle(vehicleId, ref this.m_vehicles.m_buffer[vehicleId]); info.m_vehicleAI.FrameDataUpdated(vehicleId, ref this.m_vehicles.m_buffer[vehicleId], ref this.m_vehicles.m_buffer[vehicleId].m_frame0); this.m_vehicleCount = (int)(this.m_vehicles.ItemCount() - 1u); VehicleStateManager.Instance().DetermineVehicleType(vehicleId, ref this.m_vehicles.m_buffer[vehicleId]); // NON-STOCK CODE return(true); } vehicleId = 0; return(false); }
public override void ModifyMaterialBuffer(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int amountDelta) { System.Random rnd = new(); index = rnd.Next(0, m_incomingResources.Length); switch (material) { case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingF: case TransferManager.TransferReason.ShoppingG: case TransferManager.TransferReason.ShoppingH: { int outputAmountBuffer = MarketBuffers[buildingID].outputAmountBuffer[index]; amountDelta = Mathf.Clamp(amountDelta, -outputAmountBuffer, 0); MarketBuffers[buildingID].outputAmountBuffer[index] = (ushort)(outputAmountBuffer + amountDelta); MarketBuffers[buildingID].amountSold1[index] = (byte)Mathf.Clamp((int)MarketBuffers[buildingID].amountSold1[index] + (-amountDelta + 99) / 100, 0, 255); data.m_outgoingProblemTimer = 0; int num = (-amountDelta * m_goodsSellPrice + 50) / 100; if (num != 0) { Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.ResourcePrice, num, m_info.m_class); } break; } default: if (material != TransferManager.TransferReason.Shopping) { var found = false; for (int i = 0; i < m_incomingResources.Length; i++) { if (material == m_incomingResources[i]) { index = i; if (!MarketBuffers.ContainsKey(buildingID)) { AddMarketBufferToBuildingData(buildingID); } var marketBuffer = MarketBuffers[buildingID]; int goodsCapacity = m_goodsCapacity; amountDelta = Mathf.Clamp(amountDelta, 0, goodsCapacity - (int)marketBuffer.inputAmountBuffer[i]); marketBuffer.inputAmountBuffer[i] = (ushort)((int)marketBuffer.inputAmountBuffer[i] + amountDelta); MarketBuffers[buildingID] = marketBuffer; found = true; break; } } if (!found) { base.ModifyMaterialBuffer(buildingID, ref data, material, ref amountDelta); } } break; } }
public static bool Prefix(ushort vehicleID, ref Vehicle data, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { return(DistrictHelper.VehicleTransfer(ref data, material, offer)); }
/// <summary> /// Copied from original game code at game version 1.7.2-f1. /// </summary> public static void TransferManager_AddIncomingOffer_Original(TransferManager transferManager, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { TransferManagerHelper.CheckInstance(transferManager); for (int priority = offer.Priority; priority >= 0; --priority) { int index = (int)material * 8 + priority; int num = (int)TransferManagerHelper.IncomingCount[index]; if (num < 256) { TransferManagerHelper.IncomingOffers[index * 256 + num] = offer; TransferManagerHelper.IncomingCount[index] = (ushort)(num + 1); TransferManagerHelper.IncomingAmount[(int)material] += offer.Amount; break; } } }
public static void SimulationStepActive(CommercialBuildingAI thisAI, ushort buildingID, ref Building buildingData, ref Building.Frame frameData) { //This is a mess because I pulled it directly from the decompiled code and patched it up slightly. //It works though, and that's all I'm bothered about for now. if (thisAI) { DistrictManager instance1 = Singleton <DistrictManager> .instance; byte district = instance1.GetDistrict(buildingData.m_position); DistrictPolicies.Services policies = instance1.m_districts.m_buffer[(int)district].m_servicePolicies; DistrictPolicies.Taxation taxationPolicies = instance1.m_districts.m_buffer[(int)district].m_taxationPolicies; DistrictPolicies.CityPlanning cityPlanningPolicies = instance1.m_districts.m_buffer[(int)district].m_cityPlanningPolicies; instance1.m_districts.m_buffer[(int)district].m_servicePoliciesEffect |= policies & (DistrictPolicies.Services.PowerSaving | DistrictPolicies.Services.WaterSaving | DistrictPolicies.Services.SmokeDetectors | DistrictPolicies.Services.Recycling | DistrictPolicies.Services.RecreationalUse | DistrictPolicies.Services.ExtraInsulation | DistrictPolicies.Services.NoElectricity | DistrictPolicies.Services.OnlyElectricity); switch (thisAI.m_info.m_class.m_subService) { case ItemClass.SubService.CommercialLow: if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow)) != (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow)) { instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow); } instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness; break; case ItemClass.SubService.CommercialHigh: if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh)) != (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh)) { instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh); } instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness; break; case ItemClass.SubService.CommercialLeisure: instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure; instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises; break; case ItemClass.SubService.CommercialTourist: instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.LightningRods; break; } Citizen.BehaviourData behaviour = new Citizen.BehaviourData(); int aliveWorkerCount = 0; int totalWorkerCount = 0; int workPlaceCount = 0; int num1 = NewPrivateBuildingAI.HandleWorkers(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount, ref workPlaceCount); if ((buildingData.m_flags & Building.Flags.Evacuating) != Building.Flags.None) { num1 = 0; } int width = buildingData.Width; int length = buildingData.Length; int num2 = MaxIncomingLoadSize(thisAI); int aliveCount = 0; int totalCount = 0; GetVisitBehaviour(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveCount, ref totalCount); int visitCount = thisAI.CalculateVisitplaceCount(new Randomizer((int)buildingID), width, length); int num3 = Mathf.Max(0, visitCount - totalCount); int a1 = visitCount * 500; int num4 = Mathf.Max(a1, num2 * 4); TransferManager.TransferReason incomingTransferReason = GetIncomingTransferReason(thisAI); TransferManager.TransferReason outgoingTransferReason = GetOutgoingTransferReason(thisAI, buildingID); if (num1 != 0) { int num5 = num4; if (incomingTransferReason != TransferManager.TransferReason.None) { num5 = Mathf.Min(num5, (int)buildingData.m_customBuffer1); } if (outgoingTransferReason != TransferManager.TransferReason.None) { num5 = Mathf.Min(num5, num4 - (int)buildingData.m_customBuffer2); } int num6 = Mathf.Max(0, Mathf.Min(num1, (num5 * 200 + num4 - 1) / num4)); int a2 = (visitCount * num6 + 9) / 10; if (Singleton <SimulationManager> .instance.m_isNightTime) { a2 = a2 + 1 >> 1; } int num7 = Mathf.Max(0, Mathf.Min(a2, num5)); if (incomingTransferReason != TransferManager.TransferReason.None) { buildingData.m_customBuffer1 -= (ushort)num7; } if (outgoingTransferReason != TransferManager.TransferReason.None) { buildingData.m_customBuffer2 += (ushort)num7; } num1 = (num7 + 9) / 10; } int electricityConsumption; int waterConsumption; int sewageAccumulation; int garbageAccumulation; int incomeAccumulation; thisAI.GetConsumptionRates(new Randomizer((int)buildingID), num1, out electricityConsumption, out waterConsumption, out sewageAccumulation, out garbageAccumulation, out incomeAccumulation); int heatingConsumption = 0; if (electricityConsumption != 0 && instance1.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation)) { if ((policies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None) { heatingConsumption = Mathf.Max(1, electricityConsumption * 3 + 8 >> 4); incomeAccumulation = incomeAccumulation * 95 / 100; } else { heatingConsumption = Mathf.Max(1, electricityConsumption + 2 >> 2); } } if (garbageAccumulation != 0 && (policies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None) { garbageAccumulation = Mathf.Max(1, garbageAccumulation * 85 / 100); incomeAccumulation = incomeAccumulation * 95 / 100; } int taxRate; switch (thisAI.m_info.m_class.m_subService) { case ItemClass.SubService.CommercialLeisure: taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies); if ((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) { taxRate = 0; } if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None && Singleton <SimulationManager> .instance.m_isNightTime) { electricityConsumption = electricityConsumption + 1 >> 1; waterConsumption = waterConsumption + 1 >> 1; sewageAccumulation = sewageAccumulation + 1 >> 1; garbageAccumulation = garbageAccumulation + 1 >> 1; incomeAccumulation = 0; break; } break; case ItemClass.SubService.CommercialTourist: taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies); break; default: taxRate = Singleton <EconomyManager> .instance.GetTaxRate(thisAI.m_info.m_class, taxationPolicies); break; } if (num1 != 0) { int num5 = HandleCommonConsumption(thisAI, buildingID, ref buildingData, ref frameData, ref electricityConsumption, ref heatingConsumption, ref waterConsumption, ref sewageAccumulation, ref garbageAccumulation, policies); num1 = (num1 * num5 + 99) / 100; if (num1 != 0) { int amount1 = incomeAccumulation; if (amount1 != 0) { if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow) { if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness) != DistrictPolicies.CityPlanning.None) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 12, thisAI.m_info.m_class); amount1 *= 2; } } else if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness) != DistrictPolicies.CityPlanning.None) { Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 25, thisAI.m_info.m_class); amount1 *= 3; } if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None) { amount1 = (amount1 * 105 + 99) / 100; } int num6 = Singleton <EconomyManager> .instance.AddPrivateIncome(amount1, ItemClass.Service.Commercial, thisAI.m_info.m_class.m_subService, thisAI.m_info.m_class.m_level, taxRate); int amount2 = (behaviour.m_touristCount * num6 + (aliveCount >> 1)) / Mathf.Max(1, aliveCount); int amount3 = Mathf.Max(0, num6 - amount2); if (amount3 != 0) { Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.CitizenIncome, amount3, thisAI.m_info.m_class); } if (amount2 != 0) { Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.TourismIncome, amount2, thisAI.m_info.m_class); } } int groundPollution; int noisePollution; thisAI.GetPollutionRates(num1, cityPlanningPolicies, out groundPollution, out noisePollution); if (groundPollution != 0 && Singleton <SimulationManager> .instance.m_randomizer.Int32(3U) == 0) { Singleton <NaturalResourceManager> .instance.TryDumpResource(NaturalResourceManager.Resource.Pollution, groundPollution, groundPollution, buildingData.m_position, 60f); } if (noisePollution != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, noisePollution, buildingData.m_position, 60f); } if (num5 < 100) { buildingData.m_flags |= Building.Flags.RateReduced; } else { buildingData.m_flags &= ~Building.Flags.RateReduced; } buildingData.m_flags |= Building.Flags.Active; } else { buildingData.m_flags &= ~(Building.Flags.RateReduced | Building.Flags.Active); } } else { electricityConsumption = 0; heatingConsumption = 0; waterConsumption = 0; sewageAccumulation = 0; garbageAccumulation = 0; buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating); buildingData.m_flags &= ~(Building.Flags.RateReduced | Building.Flags.Active); } int health = 0; int wellbeing = 0; float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f; if (behaviour.m_healthAccumulation != 0) { if (aliveWorkerCount + aliveCount != 0) { health = (behaviour.m_healthAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount); } Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Health, behaviour.m_healthAccumulation, buildingData.m_position, radius); } if (behaviour.m_wellbeingAccumulation != 0) { if (aliveWorkerCount + aliveCount != 0) { wellbeing = (behaviour.m_wellbeingAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount); } Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Wellbeing, behaviour.m_wellbeingAccumulation, buildingData.m_position, radius); } int num8 = Citizen.GetHappiness(health, wellbeing) * 15 / 100; int a3 = aliveWorkerCount * 20 / workPlaceCount; if ((buildingData.m_problems & Notification.Problem.MajorProblem) == Notification.Problem.None) { num8 += 20; } if (buildingData.m_problems == Notification.Problem.None) { num8 += 25; } int num9 = num8 + Mathf.Min(a3, (int)buildingData.m_customBuffer1 * a3 / num4) + (a3 - Mathf.Min(a3, (int)buildingData.m_customBuffer2 * a3 / num4)); int num10 = (int)(8 - thisAI.m_info.m_class.m_level); int num11 = (int)(11 - thisAI.m_info.m_class.m_level); if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh) { ++num10; ++num11; } if (taxRate < num10) { num9 += num10 - taxRate; } if (taxRate > num11) { num9 -= taxRate - num11; } if (taxRate >= num11 + 4) { if ((int)buildingData.m_taxProblemTimer != 0 || Singleton <SimulationManager> .instance.m_randomizer.Int32(32U) == 0) { int num5 = taxRate - num11 >> 2; buildingData.m_taxProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_taxProblemTimer + num5); if ((int)buildingData.m_taxProblemTimer >= 96) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh | Notification.Problem.MajorProblem); } else if ((int)buildingData.m_taxProblemTimer >= 32) { buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh); } } } else { buildingData.m_taxProblemTimer = (byte)Mathf.Max(0, (int)buildingData.m_taxProblemTimer - 1); buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh); } int entertainment; int attractiveness; GetAccumulation(thisAI, new Randomizer((int)buildingID), num1, taxRate, cityPlanningPolicies, taxationPolicies, out entertainment, out attractiveness); if (entertainment != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Entertainment, entertainment, buildingData.m_position, radius); } if (attractiveness != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, attractiveness); } int happiness = Mathf.Clamp(num9, 0, 100); buildingData.m_health = (byte)health; buildingData.m_happiness = (byte)happiness; buildingData.m_citizenCount = (byte)(aliveWorkerCount + aliveCount); HandleDead(thisAI, buildingID, ref buildingData, ref behaviour, totalWorkerCount + totalCount); int crimeAccumulation = behaviour.m_crimeAccumulation / 10; if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLeisure) { crimeAccumulation = crimeAccumulation * 5 + 3 >> 2; } if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None) { crimeAccumulation = crimeAccumulation * 3 + 3 >> 2; } HandleCrime(thisAI, buildingID, ref buildingData, crimeAccumulation, (int)buildingData.m_citizenCount); int num12 = (int)buildingData.m_crimeBuffer; if (aliveWorkerCount != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Density, aliveWorkerCount, buildingData.m_position, radius); int num5 = (behaviour.m_educated0Count * 100 + behaviour.m_educated1Count * 50 + behaviour.m_educated2Count * 30) / aliveWorkerCount + 50; buildingData.m_fireHazard = (byte)num5; } else { buildingData.m_fireHazard = (byte)0; } int crimeRate = (int)buildingData.m_citizenCount == 0 ? 0 : (num12 + ((int)buildingData.m_citizenCount >> 1)) / (int)buildingData.m_citizenCount; int count = 0; int cargo = 0; int capacity = 0; int outside = 0; if (incomingTransferReason != TransferManager.TransferReason.None) { CalculateGuestVehicles(thisAI, buildingID, ref buildingData, incomingTransferReason, ref count, ref cargo, ref capacity, ref outside); buildingData.m_tempImport = (byte)Mathf.Clamp(outside, (int)buildingData.m_tempImport, (int)byte.MaxValue); } buildingData.m_tempExport = (byte)Mathf.Clamp(behaviour.m_touristCount, (int)buildingData.m_tempExport, (int)byte.MaxValue); SimulationManager _simulationManager = Singleton <SimulationManager> .instance; if ((long)((_simulationManager.m_currentFrameIndex & 3840U) >> 8) == (long)((int)buildingID & 15) && (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow || thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh) && ((int)Singleton <ZoneManager> .instance.m_lastBuildIndex == (int)_simulationManager.m_currentBuildIndex && (buildingData.m_flags & Building.Flags.Upgrading) == Building.Flags.None)) { CheckBuildingLevel(thisAI, buildingID, ref buildingData, ref frameData, ref behaviour, aliveCount); } if ((buildingData.m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) == Building.Flags.None) { return; } Notification.Problem problems1 = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoCustomers | Notification.Problem.NoGoods); //Begin edited section if ((int)buildingData.m_customBuffer2 > num4 - (a1 >> 1) && aliveCount <= visitCount >> 1) { if (_simulationManager.m_currentDayTimeHour > 19 && _simulationManager.m_currentDayTimeHour < 20) { buildingData.m_outgoingProblemTimer = (byte)Mathf.Min(byte.MaxValue, buildingData.m_outgoingProblemTimer + 1); if (buildingData.m_outgoingProblemTimer >= 192) { problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers | Notification.Problem.MajorProblem); } else if (buildingData.m_outgoingProblemTimer >= 128) { problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers); } } else { buildingData.m_outgoingProblemTimer = 0; } } else { buildingData.m_outgoingProblemTimer = (byte)0; } if (!CityEventManager.instance.EventStartsWithin(3D) && !CityEventManager.instance.EventTakingPlace() && !CityEventManager.instance.EventJustEnded()) { if ((int)buildingData.m_customBuffer1 == 0) { buildingData.m_incomingProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_incomingProblemTimer + 1); problems1 = (int)buildingData.m_incomingProblemTimer >= 64 ? Notification.AddProblems(problems1, Notification.Problem.NoGoods | Notification.Problem.MajorProblem) : Notification.AddProblems(problems1, Notification.Problem.NoGoods); } else { buildingData.m_incomingProblemTimer = (byte)0; } float currentHour = _simulationManager.m_currentDayTimeHour; //Artifically shop at night to keep industry happy. Will give the effect of industry stocking up commercial over night. //Note: ModifyMaterialBuffer is expensive, so if there's any performance impact with the mod now, it'll most likely be this. if ((currentHour > 20f || currentHour < 4f)) { if (_simulationManager.m_randomizer.Int32(80) < 2) { //Simulate 2 people buying things int amount = -200; thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount); } } else if (Experiments.ExperimentsToggle.AllowActiveCommercialFix && _simulationManager.m_randomizer.Int32(40) < 5) //Added in as a potential fix to random inactive buildings. Lack of customers still shuts down commercial. { int amount = -50; thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount); } } else { buildingData.m_incomingProblemTimer = 0; } //End edited section buildingData.m_problems = problems1; instance1.m_districts.m_buffer[(int)district].AddCommercialData(ref behaviour, health, happiness, crimeRate, workPlaceCount, aliveWorkerCount, Mathf.Max(0, workPlaceCount - totalWorkerCount), visitCount, aliveCount, num3, (int)thisAI.m_info.m_class.m_level, electricityConsumption, heatingConsumption, waterConsumption, sewageAccumulation, garbageAccumulation, incomeAccumulation, Mathf.Min(100, (int)buildingData.m_garbageBuffer / 50), (int)buildingData.m_waterPollution * 100 / (int)byte.MaxValue, (int)buildingData.m_finalImport, (int)buildingData.m_finalExport, thisAI.m_info.m_class.m_subService); if ((int)buildingData.m_fireIntensity == 0 && incomingTransferReason != TransferManager.TransferReason.None) { int num5 = num4 - (int)buildingData.m_customBuffer1 - capacity - (num2 >> 1); if (num5 >= 0) { Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, new TransferManager.TransferOffer() { Priority = num5 * 8 / num2, Building = buildingID, Position = buildingData.m_position, Amount = 1, Active = false }); } } if ((int)buildingData.m_fireIntensity == 0 && outgoingTransferReason != TransferManager.TransferReason.None) { int num5 = (int)buildingData.m_customBuffer2 - aliveCount * 100; if (num5 >= 100 && num3 > 0) { Singleton <TransferManager> .instance.AddOutgoingOffer(outgoingTransferReason, new TransferManager.TransferOffer() { Priority = Mathf.Max(1, num5 * 8 / num4), Building = buildingID, Position = buildingData.m_position, Amount = Mathf.Min(num5 / 100, num3), Active = false }); } } PrivateBuildingAI baseAI = thisAI as PrivateBuildingAI; //Because we don't have access to base here. if (baseAI != null) { NewPrivateBuildingAI.SimulationStepActive(baseAI, buildingID, ref buildingData, ref frameData); } HandleFire(thisAI, buildingID, ref buildingData, ref frameData, policies); } else { Debug.LogError("Commercial building " + buildingID + " has no AI! This could have been bad."); } }
public static bool Prefix(TransferManager.TransferReason material, ref TransferManager.TransferOffer offer) { switch (material) { case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingF: case TransferManager.TransferReason.ShoppingG: case TransferManager.TransferReason.ShoppingH: case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: case TransferManager.TransferReason.TouristA: case TransferManager.TransferReason.TouristB: case TransferManager.TransferReason.TouristC: case TransferManager.TransferReason.TouristD: if (RealCity.realCityV10) { if (MainDataStore.outsideTouristMoney < 0) { if (Singleton <BuildingManager> .instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI) { return(false); } } if (MainDataStore.noTourist) { if (Singleton <BuildingManager> .instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI) { return(false); } } } break; case TransferManager.TransferReason.Oil: case TransferManager.TransferReason.Ore: case TransferManager.TransferReason.Coal: case TransferManager.TransferReason.Petrol: case TransferManager.TransferReason.Food: case TransferManager.TransferReason.Grain: case TransferManager.TransferReason.Lumber: case TransferManager.TransferReason.Logs: case TransferManager.TransferReason.Goods: case TransferManager.TransferReason.LuxuryProducts: case TransferManager.TransferReason.AnimalProducts: case TransferManager.TransferReason.Flours: case TransferManager.TransferReason.Petroleum: case TransferManager.TransferReason.Plastics: case TransferManager.TransferReason.Metals: case TransferManager.TransferReason.Glass: case TransferManager.TransferReason.PlanedTimber: case TransferManager.TransferReason.Paper: if (MainDataStore.noExport) { if (Singleton <BuildingManager> .instance.m_buildings.m_buffer[offer.Building].Info.m_buildingAI is OutsideConnectionAI) { return(false); } } break; default: return(true); } if (offer.Citizen != 0) { var instance = Singleton <CitizenManager> .instance; ushort homeBuilding = instance.m_citizens.m_buffer[offer.Citizen].m_homeBuilding; uint citizenUnit = CitizenData.GetCitizenUnit(homeBuilding); uint containingUnit = instance.m_citizens.m_buffer[offer.Citizen].GetContainingUnit((uint)offer.Citizen, citizenUnit, CitizenUnit.Flags.Home); if (!instance.m_citizens.m_buffer[offer.Citizen].m_flags.IsFlagSet(Citizen.Flags.Tourist)) { if (CitizenUnitData.familyMoney[containingUnit] < MainDataStore.maxGoodPurchase * RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping)) { //Reject poor citizen to building return(false); } } } else if (offer.Building != 0) { var instance = Singleton <BuildingManager> .instance; var buildingID = offer.Building; var buildingData = instance.m_buildings.m_buffer[buildingID]; if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) { RealCityIndustrialBuildingAI.InitDelegate(); RealCityCommonBuildingAI.InitDelegate(); var industrialBuildingAI = buildingData.Info.m_buildingAI as IndustrialBuildingAI; TransferManager.TransferReason incomingTransferReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); TransferManager.TransferReason secondaryIncomingTransferReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID); int maxIncomingLoadSize = RealCityIndustrialBuildingAI.MaxIncomingLoadSize((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); int num = 0; int num1 = 0; int incomingCargoCapacity = 0; int value = 0; if (incomingTransferReason != TransferManager.TransferReason.None) { if (secondaryIncomingTransferReason != TransferManager.TransferReason.None) { RealCityCommonBuildingAI.CalculateGuestVehicles1((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, secondaryIncomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); } else { RealCityCommonBuildingAI.CalculateGuestVehicles((IndustrialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); } } int productionCapacity = industrialBuildingAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); int consumptionDivider = RealCityIndustrialBuildingAI.GetConsumptionDivider((IndustrialBuildingAI)(buildingData.Info.m_buildingAI)); int fullCapacity = Mathf.Max(productionCapacity * 500 / consumptionDivider, maxIncomingLoadSize * 4); int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; incomingAmontNeeded -= 8000; if (incomingAmontNeeded < 0) { return(false); } else { if (material == incomingTransferReason) { //first remove. //game bug, will send 2 incomingTransferReason per period TransferManager.TransferOffer offer1 = default; offer1.Building = buildingID; Singleton <TransferManager> .instance.RemoveIncomingOffer(incomingTransferReason, offer1); } } } else if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) { RealCityCommercialBuildingAI.InitDelegate(); RealCityCommonBuildingAI.InitDelegate(); var commercialBuildingAI = buildingData.Info.m_buildingAI as CommercialBuildingAI; int maxIncomingLoadSize = RealCityCommercialBuildingAI.MaxIncomingLoadSize((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); int visitplaceCount = commercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer((int)buildingID), buildingData.m_width, buildingData.m_length); int fullCapacity = Mathf.Max(visitplaceCount * 500, maxIncomingLoadSize * 4); int num = 0; int num1 = 0; int incomingCargoCapacity = 0; int value = 0; TransferManager.TransferReason incomingTransferReason = RealCityCommercialBuildingAI.GetIncomingTransferReason((CommercialBuildingAI)(buildingData.Info.m_buildingAI)); if (incomingTransferReason != TransferManager.TransferReason.None) { if (incomingTransferReason == TransferManager.TransferReason.Goods || incomingTransferReason == TransferManager.TransferReason.Food) { RealCityCommonBuildingAI.CalculateGuestVehicles1((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, TransferManager.TransferReason.LuxuryProducts, ref num, ref num1, ref incomingCargoCapacity, ref value); } else { RealCityCommonBuildingAI.CalculateGuestVehicles((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, incomingTransferReason, ref num, ref num1, ref incomingCargoCapacity, ref value); } buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255); } int incomingAmontNeeded = fullCapacity - (int)buildingData.m_customBuffer1 - incomingCargoCapacity; incomingAmontNeeded -= 6000; if (incomingAmontNeeded < 0) { return(false); } } } return(true); }
public static void AddBufferStatusFish(this DistrictPark districtPark, TransferManager.TransferReason material, int amount, int incoming, int capacity) { switch (material) { case TransferManager.TransferReason.AnimalProducts: m_animalProductsData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Flours: m_floursData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Paper: m_paperData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.PlanedTimber: m_planedTimberData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Petroleum: m_petroleumData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Plastics: m_plasticsData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Glass: m_glassData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Metals: m_metalsData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.LuxuryProducts: m_luxuryProductsData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Fish: m_fishData.Add(amount, incoming, capacity); break; default: switch (material) { case TransferManager.TransferReason.Oil: m_oilData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Ore: m_oreData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Logs: m_logsData.Add(amount, incoming, capacity); break; case TransferManager.TransferReason.Grain: m_grainData.Add(amount, incoming, capacity); break; } break; } }
public static bool Prefix(ref TransferManager.TransferReason __result) { __result = TransferManager.TransferReason.None; return(false); }
public static bool Prefix(ref TransferManager.TransferReason material, ref TransferManager.TransferOffer offer) { switch (material) { case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingF: case TransferManager.TransferReason.ShoppingG: case TransferManager.TransferReason.ShoppingH: case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: break; default: return(true); } var instance = Singleton <BuildingManager> .instance; var buildingID = offer.Building; if (buildingID != 0) { var buildingData = instance.m_buildings.m_buffer[buildingID]; if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Commercial) { Citizen.BehaviourData behaviour = default; int aliveVisitCount = 0; int totalVisitCount = 0; RealCityCommercialBuildingAI.InitDelegate(); RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); var AI = buildingData.Info.m_buildingAI as CommercialBuildingAI; var maxCount = AI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(buildingID), buildingData.m_width, buildingData.m_length); var amount = Math.Min(buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount, maxCount - totalVisitCount); if ((amount <= 0) || (maxCount <= totalVisitCount)) { buildingData.m_flags &= ~Building.Flags.Active; //no resource return(false); } else { offer.Amount = amount; return(true); } } else if (instance.m_buildings.m_buffer[buildingID].Info.m_class.m_service == ItemClass.Service.Fishing) { Citizen.BehaviourData behaviour = default; int aliveVisitCount = 0; int totalVisitCount = 0; RealCityMarketAI.InitDelegate(); RealCityMarketAI.GetVisitBehaviour((MarketAI)(buildingData.Info.m_buildingAI), buildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; if (amount <= 0) { buildingData.m_flags &= ~Building.Flags.Active; //no resource return(false); } else { return(true); } } } //Remove cotenancy if (material == TransferManager.TransferReason.Single0 || material == TransferManager.TransferReason.Single0B) { material = TransferManager.TransferReason.Family0; } else if (material == TransferManager.TransferReason.Single1 || material == TransferManager.TransferReason.Single1B) { material = TransferManager.TransferReason.Family1; } else if (material == TransferManager.TransferReason.Single2 || material == TransferManager.TransferReason.Single2B) { material = TransferManager.TransferReason.Family2; } else if (material == TransferManager.TransferReason.Single3 || material == TransferManager.TransferReason.Single3B) { material = TransferManager.TransferReason.Family3; } return(true); }
private static bool StartTransferOverride(ushort buildingID, ref Building data, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { SVMUtils.doLog("START TRANSFER: {0} , {1}", typeof(OutsideConnectionAI), material); ServiceSystemDefinition def = null; switch (material) { case TransferManager.TransferReason.DummyTrain: if (offer.Building != buildingID) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { def = ServiceSystemDefinition.CARG_TRAIN; } else { def = ServiceSystemDefinition.REG_TRAIN; } goto OfferProcessing; } break; case TransferManager.TransferReason.DummyShip: if (offer.Building != buildingID) { if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0) { def = ServiceSystemDefinition.CARG_SHIP; } else { def = ServiceSystemDefinition.REG_SHIP; } goto OfferProcessing; } break; case TransferManager.TransferReason.DummyPlane: if (offer.Building != buildingID) { def = ServiceSystemDefinition.REG_PLANE; goto OfferProcessing; } break; } SVMUtils.doLog("END TRANSFER: {0} , {1} (not set)", typeof(OutsideConnectionAI), material); return(true); OfferProcessing: SVMUtils.doLog("[{1}] SSD = {0}", def, material); VehicleInfo randomVehicleInfo = ServiceSystemDefinition.availableDefinitions[def].GetAModel(offer.Building); SVMUtils.doLog("[{1}] Veh = {0}", randomVehicleInfo?.ToString() ?? "<NULL>", material); if (randomVehicleInfo != null) { Array16 <Vehicle> vehicles = Singleton <VehicleManager> .instance.m_vehicles; if (Singleton <VehicleManager> .instance.CreateVehicle(out ushort vehId, ref Singleton <SimulationManager> .instance.m_randomizer, randomVehicleInfo, data.m_position, material, false, true)) { Vehicle[] expr_BB7_cp_0 = vehicles.m_buffer; ushort expr_BB7_cp_1 = vehId; expr_BB7_cp_0[(int)expr_BB7_cp_1].m_flags = (expr_BB7_cp_0[(int)expr_BB7_cp_1].m_flags | Vehicle.Flags.DummyTraffic); Vehicle[] expr_BD6_cp_0 = vehicles.m_buffer; ushort expr_BD6_cp_1 = vehId; expr_BD6_cp_0[(int)expr_BD6_cp_1].m_flags = (expr_BD6_cp_0[(int)expr_BD6_cp_1].m_flags & ~Vehicle.Flags.WaitingCargo); randomVehicleInfo.m_vehicleAI.SetSource(vehId, ref vehicles.m_buffer[(int)vehId], buildingID); randomVehicleInfo.m_vehicleAI.StartTransfer(vehId, ref vehicles.m_buffer[(int)vehId], material, offer); SVMUtils.doLog("END TRANSFER: {0} , {1} (found)", typeof(OutsideConnectionAI), material); return(false); } } SVMUtils.doLog("END TRANSFER: {0} , {1} (not found)", typeof(OutsideConnectionAI), material); return(true); }
public static void ProcessGasBuildingIncoming(ushort buildingID, ref Building buildingData) { int num27 = 0; int num28 = 0; int num29 = 0; int value = 0; int num34 = 0; TransferManager.TransferReason incomingTransferReason = default(TransferManager.TransferReason); //Petrol incomingTransferReason = TransferManager.TransferReason.Petrol; num27 = 0; num28 = 0; num29 = 0; value = 0; num34 = 0; if (incomingTransferReason != TransferManager.TransferReason.None && buildingData.m_flags.IsFlagSet(Building.Flags.Completed)) { CalculateGuestVehicles(buildingID, ref buildingData, incomingTransferReason, ref num27, ref num28, ref num29, ref value); buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255); } num34 = 50000 - MainDataStore.petrolBuffer[buildingID] - num29; if (buildingData.m_flags.IsFlagSet(Building.Flags.Active) && buildingData.m_flags.IsFlagSet(Building.Flags.Completed)) { if (num34 >= 0) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = 7; offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = (int)(num34 / 8000); offer.Active = false; if (offer.Amount > 0) { Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, offer); } } } if ((MainDataStore.resourceCategory[buildingID] == 3) || (MainDataStore.resourceCategory[buildingID] == 1)) { //Fuel incomingTransferReason = (TransferManager.TransferReason) 126; num34 = MainDataStore.petrolBuffer[buildingID] - MainDataStore.finalVehicleForFuelCount[buildingID] * 400; if ((MainDataStore.resourceCategory[buildingID] == 1)) { num34 >>= 1; } if (buildingData.m_flags.IsFlagSet(Building.Flags.Active) && buildingData.m_flags.IsFlagSet(Building.Flags.Completed)) { if (num34 >= 0) { System.Random rand = new System.Random(); TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = rand.Next(8); offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = (int)((num34 - 0) / 400); offer.Active = false; if ((int)(num34 / 400) > 0) { Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, offer); } } } } if ((MainDataStore.resourceCategory[buildingID] == 2) || (MainDataStore.resourceCategory[buildingID] == 1)) { //Fuel for Heavy incomingTransferReason = (TransferManager.TransferReason) 127; num34 = MainDataStore.petrolBuffer[buildingID] - MainDataStore.finalVehicleForFuelCount[buildingID] * 400; if ((MainDataStore.resourceCategory[buildingID] == 1)) { num34 >>= 1; } if (buildingData.m_flags.IsFlagSet(Building.Flags.Active) && buildingData.m_flags.IsFlagSet(Building.Flags.Completed)) { if (num34 >= 0) { System.Random rand = new System.Random(); TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = rand.Next(8); offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = (int)((num34 - 0) / 400); offer.Active = false; if ((int)(num34 / 400) > 0) { Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, offer); } } } } }
protected static void CalculateGuestVehicles(ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside) { VehicleManager instance = Singleton <VehicleManager> .instance; ushort num = data.m_guestVehicles; int num2 = 0; while (num != 0) { if ((TransferManager.TransferReason)instance.m_vehicles.m_buffer[(int)num].m_transferType == material) { VehicleInfo info = instance.m_vehicles.m_buffer[(int)num].Info; int a; int num3; info.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[(int)num], out a, out num3); cargo += Mathf.Min(a, num3); capacity += num3; count++; if ((instance.m_vehicles.m_buffer[(int)num].m_flags & (Vehicle.Flags.Importing | Vehicle.Flags.Exporting)) != (Vehicle.Flags) 0) { outside++; } } num = instance.m_vehicles.m_buffer[(int)num].m_nextGuestVehicle; if (++num2 > Singleton <VehicleManager> .instance.m_vehicles.m_size) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } }
public static float GetPrice(bool isSelling, ushort buildingID, Building data) { RealCityIndustrialBuildingAI.InitDelegate(); float price = 0f; if (!isSelling) { if (!(data.Info.m_buildingAI is IndustrialExtractorAI)) { switch (data.Info.m_class.m_subService) { case ItemClass.SubService.CommercialHigh: case ItemClass.SubService.CommercialLow: case ItemClass.SubService.CommercialEco: case ItemClass.SubService.CommercialLeisure: case ItemClass.SubService.CommercialTourist: CommercialBuildingAI commercialBuildingAI = data.Info.m_buildingAI as CommercialBuildingAI; if (commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Food || commercialBuildingAI.m_incomingResource == TransferManager.TransferReason.Goods) { //SecondaryIncoming : FirstIncoming = 1:3 price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource) + (RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.LuxuryProducts))) / 4f; } else { price = RealCityIndustryBuildingAI.GetResourcePrice(commercialBuildingAI.m_incomingResource); } break; case ItemClass.SubService.IndustrialForestry: case ItemClass.SubService.IndustrialFarming: case ItemClass.SubService.IndustrialOil: case ItemClass.SubService.IndustrialOre: TransferManager.TransferReason tempReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); price = RealCityIndustryBuildingAI.GetResourcePrice(tempReason); break; case ItemClass.SubService.IndustrialGeneric: TransferManager.TransferReason firstReason = RealCityIndustrialBuildingAI.GetIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); TransferManager.TransferReason secondReason = RealCityIndustrialBuildingAI.GetSecondaryIncomingTransferReason((IndustrialBuildingAI)(data.Info.m_buildingAI), buildingID); //SecondaryIncoming : FirstIncoming = 1:3 price = (3f * RealCityIndustryBuildingAI.GetResourcePrice(firstReason) + (RealCityIndustryBuildingAI.GetResourcePrice(secondReason))) / 4f; break; default: price = 0; break; } } } else { if (data.Info.m_buildingAI is IndustrialExtractorAI) { switch (data.Info.m_class.m_subService) { case ItemClass.SubService.IndustrialForestry: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Logs); break; case ItemClass.SubService.IndustrialFarming: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Grain); break; case ItemClass.SubService.IndustrialOil: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Oil); break; case ItemClass.SubService.IndustrialOre: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Ore); break; default: price = 0; break; } } else { switch (data.Info.m_class.m_subService) { case ItemClass.SubService.IndustrialForestry: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Lumber); break; case ItemClass.SubService.IndustrialFarming: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Food); break; case ItemClass.SubService.IndustrialOil: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Petrol); break; case ItemClass.SubService.IndustrialOre: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Coal); break; case ItemClass.SubService.IndustrialGeneric: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Goods); break; case ItemClass.SubService.CommercialHigh: case ItemClass.SubService.CommercialLow: case ItemClass.SubService.CommercialEco: case ItemClass.SubService.CommercialLeisure: case ItemClass.SubService.CommercialTourist: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.Shopping); break; default: price = RealCityIndustryBuildingAI.GetResourcePrice(TransferManager.TransferReason.None); break; } } } return(price); }
public static void AddExportAmountFish(this DistrictPark districtPark, TransferManager.TransferReason material, int amount) { switch (material) { case TransferManager.TransferReason.AnimalProducts: m_animalProductsData.m_tempExport = m_animalProductsData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Flours: m_floursData.m_tempExport = m_floursData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Paper: m_paperData.m_tempExport = m_paperData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.PlanedTimber: m_planedTimberData.m_tempExport = m_planedTimberData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Petroleum: m_petroleumData.m_tempExport = m_petroleumData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Plastics: m_plasticsData.m_tempExport = m_plasticsData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Glass: m_glassData.m_tempExport = m_glassData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Metals: m_metalsData.m_tempExport = m_metalsData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.LuxuryProducts: m_luxuryProductsData.m_tempExport = m_luxuryProductsData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Fish: m_fishData.m_tempExport = m_fishData.m_tempExport + (uint)amount; break; default: switch (material) { case TransferManager.TransferReason.Oil: m_oilData.m_tempExport = m_oilData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Ore: m_oreData.m_tempExport = m_oreData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Logs: m_logsData.m_tempExport = m_logsData.m_tempExport + (uint)amount; break; case TransferManager.TransferReason.Grain: m_grainData.m_tempExport = m_grainData.m_tempExport + (uint)amount; break; } break; } }
/// <summary> /// Blocks offers that should be handled by the mod. /// </summary> /// <param name="transferManager">The transfer manager.</param> /// <param name="material">The material.</param> /// <param name="offer">The offer.</param> public static void TransferManager_AddIncomingOffer_Override(TransferManager transferManager, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { Calls++; if ((material == TransferManager.TransferReason.Dead && Global.CleanHearseTransferOffers) || (material == TransferManager.TransferReason.Garbage && Global.CleanGarbageTruckTransferOffers) || (material == TransferManager.TransferReason.Sick && Global.CleanAmbulanceTransferOffers)) { Blocked++; return; } TransferManager_AddIncomingOffer_Original(transferManager, material, offer); }
private void RefreshDisplayData() { if (refeshOnce || (BuildingData.lastBuildingID != WorldInfoPanel.GetCurrentInstanceID().Building)) { if (isVisible) { BuildingData.lastBuildingID = WorldInfoPanel.GetCurrentInstanceID().Building; Building buildingData = Singleton <BuildingManager> .instance.m_buildings.m_buffer[BuildingData.lastBuildingID]; if (buildingData.Info.m_class.m_service == ItemClass.Service.Residential) { Hide(); } else { float averageEmployeeFee = CaculateEmployeeOutcome(buildingData, out int totalWorkerCount); int landRentFee = CaculateLandFee(buildingData, BuildingData.lastBuildingID); string incomeType = RealCityPrivateBuildingAI.GetProductionType(false, BuildingData.lastBuildingID, buildingData); string outgoingType = RealCityPrivateBuildingAI.GetProductionType(true, BuildingData.lastBuildingID, buildingData); float incomePrice = RealCityPrivateBuildingAI.GetPrice(false, BuildingData.lastBuildingID, buildingData); float outgoingPrice = RealCityPrivateBuildingAI.GetPrice(true, BuildingData.lastBuildingID, buildingData); buildingMoney.text = string.Format(Localization.Get("BUILDING_MONEY") + " [{0}]", BuildingData.buildingMoney[BuildingData.lastBuildingID]); buildingNetAsset.text = string.Format(Localization.Get("BUILDING_NETASSET") + " [{0}]", (BuildingData.buildingMoney[BuildingData.lastBuildingID] + buildingData.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(BuildingData.lastBuildingID, buildingData)))); buildingIncomeBuffer.text = string.Format(Localization.Get("MATERIAL_BUFFER") + " [{0}]" + " " + incomeType, buildingData.m_customBuffer1); buildingOutgoingBuffer.text = string.Format(Localization.Get("PRODUCTION_BUFFER") + " [{0}]" + " " + outgoingType, buildingData.m_customBuffer2); employFee.text = Localization.Get("AVERAGE_EMPLOYFEE") + " " + averageEmployeeFee.ToString() + " " + Localization.Get("PROFIT_SHARING"); landRent.text = string.Format(Localization.Get("BUILDING_LANDRENT") + " [{0:N2}]", landRentFee); buyPrice.text = string.Format(Localization.Get("BUY_PRICE") + " " + incomeType + "[{0:N2}]", incomePrice); sellPrice.text = string.Format(Localization.Get("SELL_PRICE") + " " + outgoingType + " [{0:N2}]", outgoingPrice); float consumptionDivider = 0f; if (buildingData.Info.m_class.m_subService == ItemClass.SubService.IndustrialGeneric) { consumptionDivider = RealCityPrivateBuildingAI.GetComsumptionDivider(buildingData, BuildingData.lastBuildingID) * 4f; comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " [1:{0:N2}]", consumptionDivider); } else { if ((buildingData.Info.m_buildingAI is IndustrialExtractorAI) || buildingData.Info.m_class.m_service == ItemClass.Service.Office) { comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " N/A"); } else { consumptionDivider = RealCityPrivateBuildingAI.GetComsumptionDivider(buildingData, BuildingData.lastBuildingID); comsuptionDivide.text = string.Format(Localization.Get("MATERIAL_DIV_PRODUCTION") + " [1:{0:N2}]", consumptionDivider); } } int m_sellTax = RealCityPrivateBuildingAI.GetTaxRate(buildingData); sellTax.text = string.Format(Localization.Get("SELL_TAX") + " [{0}%]", m_sellTax); if (consumptionDivider == 0f) { profit.text = string.Format(Localization.Get("PROFIT") + " N/A"); } else { float profitRatio = (outgoingPrice * (1f - m_sellTax / 100f) - (incomePrice / consumptionDivider)) / outgoingPrice; if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) { profit.text = string.Format(Localization.Get("PROFIT") + " [{0}%]" + Localization.Get("EXCLUDE_VISIT_INCOME"), (int)(profitRatio * 100f)); } else { profit.text = string.Format(Localization.Get("PROFIT") + " [{0}%]", (int)(profitRatio * 100f)); } } int usedCar = 0; int num = 0; int num1 = 0; int num2 = 0; int car = 0; if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial) { TransferManager.TransferReason tempReason = default(TransferManager.TransferReason); if (buildingData.Info.m_buildingAI is IndustrialExtractorAI) { RealCityIndustrialExtractorAI.InitDelegate(); var industrialExtractorAI = (IndustrialExtractorAI)buildingData.Info.m_buildingAI; int productionCapacity = industrialExtractorAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length); car = Mathf.Max(1, productionCapacity / 6); tempReason = RealCityIndustrialExtractorAI.GetOutgoingTransferReason((IndustrialExtractorAI)buildingData.Info.m_buildingAI); RealCityCommonBuildingAI.InitDelegate(); RealCityCommonBuildingAI.CalculateOwnVehicles((IndustrialExtractorAI)buildingData.Info.m_buildingAI, BuildingData.lastBuildingID, ref buildingData, tempReason, ref usedCar, ref num, ref num1, ref num2); } else { RealCityIndustrialBuildingAI.InitDelegate(); var industrialBuildingAI = (IndustrialBuildingAI)buildingData.Info.m_buildingAI; int productionCapacity = industrialBuildingAI.CalculateProductionCapacity((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length); car = Mathf.Max(1, productionCapacity / 6); tempReason = RealCityIndustrialBuildingAI.GetOutgoingTransferReason((IndustrialBuildingAI)buildingData.Info.m_buildingAI); RealCityCommonBuildingAI.InitDelegate(); RealCityCommonBuildingAI.CalculateOwnVehicles((IndustrialBuildingAI)buildingData.Info.m_buildingAI, BuildingData.lastBuildingID, ref buildingData, tempReason, ref usedCar, ref num, ref num1, ref num2); } usedcar.text = string.Format(Localization.Get("CAR_USED") + " [{0}/{1}]", usedCar, car); } else if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) { Citizen.BehaviourData behaviour = default; int aliveVisitCount = 0; int totalVisitCount = 0; RealCityCommercialBuildingAI.InitDelegate(); RealCityCommercialBuildingAI.GetVisitBehaviour((CommercialBuildingAI)(buildingData.Info.m_buildingAI), BuildingData.lastBuildingID, ref buildingData, ref behaviour, ref aliveVisitCount, ref totalVisitCount); var amount = buildingData.m_customBuffer2 / MainDataStore.maxGoodPurchase - totalVisitCount + aliveVisitCount; var commercialBuildingAI = buildingData.Info.m_buildingAI as CommercialBuildingAI; var maxCount = commercialBuildingAI.CalculateVisitplaceCount((ItemClass.Level)buildingData.m_level, new Randomizer(BuildingData.lastBuildingID), buildingData.m_width, buildingData.m_length); usedcar.text = string.Format("FORDEBUG" + " [{0}/{1}/{2}/{3}]", aliveVisitCount, totalVisitCount, maxCount, amount); } else { usedcar.text = Localization.Get("CAR_USED") + " 0/0"; } BringToFront(); refeshOnce = false; } } } }
public override string GetLocalizedStatus(ushort vehicleID, ref Vehicle data, out InstanceID target) { if ((data.m_flags & Vehicle.Flags.TransferToTarget) != 0) { ushort targetBuilding = data.m_targetBuilding; if ((data.m_flags & Vehicle.Flags.GoingBack) != 0) { target = InstanceID.Empty; TransferManager.TransferReason transferType = (TransferManager.TransferReason)data.m_transferType; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_RETURN")); } if ((data.m_flags & Vehicle.Flags.WaitingTarget) != 0) { target = InstanceID.Empty; return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_UNLOAD")); } if (targetBuilding != 0) { Building.Flags flags = Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuilding].m_flags; TransferManager.TransferReason transferType = (TransferManager.TransferReason)data.m_transferType; if ((data.m_flags & Vehicle.Flags.Exporting) != 0 || (flags & Building.Flags.IncomingOutgoing) != 0) { target = InstanceID.Empty; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_EXPORT", transferType.ToString())); } if ((data.m_flags & Vehicle.Flags.Importing) != 0) { target = InstanceID.Empty; target.Building = targetBuilding; if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_IMPORT", transferType.ToString())); } target = InstanceID.Empty; target.Building = targetBuilding; if (transferType == (TransferManager.TransferReason) 110) { return(Localization.Get("TRANSFER_CONSTRUCTION")); } else if (transferType == (TransferManager.TransferReason) 111) { return(Localization.Get("TRANSFER_OPERATION")); } else if (transferType == (TransferManager.TransferReason) 113) { return(Localization.Get("FOR_FUEL")); } else { return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CARGOTRUCK_DELIVER", transferType.ToString())); } } } target = InstanceID.Empty; return(ColossalFramework.Globalization.Locale.Get("VEHICLE_STATUS_CONFUSED")); }
public override void StartTransfer(uint citizenID, ref Citizen data, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { // Check and replace the offer if needed Randomizer randomizer = Singleton <SimulationManager> .instance.m_randomizer; ushort offerBuilding = offer.Building; if (Utils.TargetBuildingUndesired_Tourists(offerBuilding)) { // 90% chance not visiting undesired building if (randomizer.Int32(100U) > 9) // TODO: MAYBE CUSTOMIZE THIS CHANCE { TransferManager.TransferOffer newOffer = Utils.FindOffer(material, true); offer = newOffer; } Debug.Log("Tourist's StartTransfer method called, and replaced with new offer"); } // just copied the entire original code if (data.m_flags == Citizen.Flags.None || data.Dead || data.Sick) { return; } switch (material) { case TransferManager.TransferReason.EvacuateA: case TransferManager.TransferReason.EvacuateB: case TransferManager.TransferReason.EvacuateC: case TransferManager.TransferReason.EvacuateD: case TransferManager.TransferReason.EvacuateVipA: case TransferManager.TransferReason.EvacuateVipB: case TransferManager.TransferReason.EvacuateVipC: case TransferManager.TransferReason.EvacuateVipD: data.m_flags |= Citizen.Flags.Evacuating; if (this.StartMoving(citizenID, ref data, data.m_visitBuilding, offer)) { data.SetVisitplace(citizenID, offer.Building, 0U); break; } data.SetVisitplace(citizenID, offer.Building, 0U); if (data.m_visitBuilding == (ushort)0 || (int)data.m_visitBuilding != (int)offer.Building) { break; } data.CurrentLocation = Citizen.Location.Visit; break; case TransferManager.TransferReason.TouristA: case TransferManager.TransferReason.TouristB: case TransferManager.TransferReason.TouristC: case TransferManager.TransferReason.TouristD: label_6: data.m_flags &= Citizen.Flags.Unemployed | Citizen.Flags.Wealth | Citizen.Flags.Location | Citizen.Flags.NoElectricity | Citizen.Flags.NoWater | Citizen.Flags.NoSewage | Citizen.Flags.BadHealth | Citizen.Flags.Created | Citizen.Flags.Tourist | Citizen.Flags.Sick | Citizen.Flags.Dead | Citizen.Flags.Student | Citizen.Flags.MovingIn | Citizen.Flags.DummyTraffic | Citizen.Flags.Criminal | Citizen.Flags.Arrested | Citizen.Flags.Collapsed | Citizen.Flags.Education1 | Citizen.Flags.Education2 | Citizen.Flags.Education3 | Citizen.Flags.NeedGoods | Citizen.Flags.Original | Citizen.Flags.CustomName; if (!this.StartMoving(citizenID, ref data, data.m_visitBuilding, offer)) { break; } data.SetVisitplace(citizenID, offer.Building, 0U); break; default: switch (material - 51) { case TransferManager.TransferReason.Garbage: case TransferManager.TransferReason.Crime: case TransferManager.TransferReason.Sick: case TransferManager.TransferReason.Dead: case TransferManager.TransferReason.Worker0: case TransferManager.TransferReason.Worker1: case TransferManager.TransferReason.Worker2: case TransferManager.TransferReason.Worker3: case TransferManager.TransferReason.Student1: case TransferManager.TransferReason.Student2: goto label_6; default: switch (material - 30) { case TransferManager.TransferReason.Garbage: case TransferManager.TransferReason.Worker2: goto label_6; case TransferManager.TransferReason.Crime: return; case TransferManager.TransferReason.Sick: return; case TransferManager.TransferReason.Dead: case TransferManager.TransferReason.Worker0: case TransferManager.TransferReason.Worker1: data.m_flags &= Citizen.Flags.Unemployed | Citizen.Flags.Wealth | Citizen.Flags.Location | Citizen.Flags.NoElectricity | Citizen.Flags.NoWater | Citizen.Flags.NoSewage | Citizen.Flags.BadHealth | Citizen.Flags.Created | Citizen.Flags.Tourist | Citizen.Flags.Sick | Citizen.Flags.Dead | Citizen.Flags.Student | Citizen.Flags.MovingIn | Citizen.Flags.DummyTraffic | Citizen.Flags.Criminal | Citizen.Flags.Arrested | Citizen.Flags.Collapsed | Citizen.Flags.Education1 | Citizen.Flags.Education2 | Citizen.Flags.Education3 | Citizen.Flags.NeedGoods | Citizen.Flags.Original | Citizen.Flags.CustomName; if (!this.StartMoving(citizenID, ref data, data.m_visitBuilding, offer)) { return; } data.SetVisitplace(citizenID, (ushort)0, 0U); return; default: return; } } } }
public static void CalculateGuestVehicles(CommercialBuildingAI thisAI, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside) { Debug.LogWarning("CalculateGuestVehicles is not overridden!"); }
public static bool StartTransferDepot(U __instance, ushort buildingID, ref Building data, TransferManager.TransferReason reason, TransferManager.TransferOffer offer) { return(StartTransfer(__instance, buildingID, ref data, reason, offer)); }
protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount) { var GetOutgoingTransferReason = typeof(MarketAI).GetMethod("GetOutgoingTransferReason", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort) }, null); base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount); float num = (float)buildingData.Width * -4f; float num2 = (float)buildingData.Width * 4f; float num3 = (float)buildingData.Length * -4f; float num4 = (float)buildingData.Length * 4f; if (!MarketBuffers.ContainsKey(buildingID)) { AddMarketBufferToBuildingData(buildingID); } var marketBuffer = MarketBuffers[buildingID]; if (m_info.m_subBuildings != null) { for (int i = 0; i < m_info.m_subBuildings.Length; i++) { if (m_info.m_subBuildings[i].m_buildingInfo != null) { float num5 = (float)m_info.m_subBuildings[i].m_buildingInfo.m_cellWidth; float num6 = (float)m_info.m_subBuildings[i].m_buildingInfo.m_cellLength; float x = m_info.m_subBuildings[i].m_position.x; float num7 = -m_info.m_subBuildings[i].m_position.z; num = Mathf.Min(num, x - num5 * 4f); num2 = Mathf.Max(num2, x + num5 * 4f); num3 = Mathf.Min(num3, num7 - num6 * 4f); num4 = Mathf.Max(num4, num7 + num6 * 4f); } } } float num8 = num4 - num3; float angle = buildingData.m_angle; float num9 = -(num + num2) * 0.5f; float num10 = -(num3 + num4) * 0.5f; float num11 = num8 * 0.25f - (num3 + num4) * 0.5f; float num12 = Mathf.Sin(angle); float num13 = Mathf.Cos(angle); Vector3 position = buildingData.m_position - new Vector3(num13 * num9 + num12 * num10, 0f, num12 * num9 - num13 * num10); Vector3 position2 = buildingData.m_position - new Vector3(num13 * num9 + num12 * num11, 0f, num12 * num9 - num13 * num11); float currentRange = GetCurrentRange(buildingID, ref buildingData); Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoCustomers | Notification.Problem.NoGoods | Notification.Problem.NoFishingGoods); int num14 = productionRate * m_healthCareAccumulation / 100; if (num14 != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.HealthCare, num14, buildingData.m_position, m_healthCareRadius); } if (finalProductionRate != 0) { if (m_entertainmentAccumulation != 0) { int rate = productionRate * GetEntertainmentAccumulation(buildingID, ref buildingData) / 100; Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Entertainment, rate, position, currentRange); } if (m_attractivenessAccumulation != 0) { int num15 = GetAttractivenessAccumulation(buildingID, ref buildingData); Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, num15); num15 = productionRate * num15 * 15 / 100; Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, num15, position2, num8); } if (m_noiseAccumulation != 0) { Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, m_noiseAccumulation, buildingData.m_position, m_noiseRadius); } base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount + totalVisitorCount); int goodsCapacity = m_goodsCapacity; TransferManager.TransferReason outgoingTransferReason = (TransferManager.TransferReason)GetOutgoingTransferReason.Invoke(this, new object[] { buildingID }); int[] productionRateArr = new int[m_incomingResources.Length]; if (productionRate != 0) { for (int i = 0; i < m_incomingResources.Length; i++) { productionRateArr[i] = productionRate; int num16 = goodsCapacity; if (m_incomingResources[i] != TransferManager.TransferReason.None) { num16 = Mathf.Min(num16, (int)marketBuffer.inputAmountBuffer[i]); } if (outgoingTransferReason != TransferManager.TransferReason.None) { num16 = Mathf.Min(num16, goodsCapacity - (int)marketBuffer.outputAmountBuffer[i]); } productionRateArr[i] = Mathf.Max(0, Mathf.Min(productionRateArr[i], (num16 * 200 + goodsCapacity - 1) / goodsCapacity)); int num17 = (visitPlaceCount * productionRateArr[i] + 9) / 10; if (Singleton <SimulationManager> .instance.m_isNightTime) { num17 = num17 + 1 >> 1; } num17 = Mathf.Max(0, Mathf.Min(num17, num16)); if (m_incomingResources[i] != TransferManager.TransferReason.None) { marketBuffer.inputAmountBuffer[i] -= (ushort)num17; } if (outgoingTransferReason != TransferManager.TransferReason.None) { marketBuffer.outputAmountBuffer[i] += (ushort)num17; } productionRateArr[i] += (num17 + 9) / 10; } } int num18 = 0; int num19 = 0; int num20 = 0; int value = 0; for (int i = 0; i < m_incomingResources.Length; i++) { if (marketBuffer.inputAmountBuffer[i] > 0) { isAmount = true; break; } if (i == m_incomingResources.Length - 1 && isAmount) { isAmount = false; } } for (int i = 0; i < m_incomingResources.Length; i++) { if (m_incomingResources[i] != TransferManager.TransferReason.None) { base.CalculateGuestVehicles(buildingID, ref buildingData, m_incomingResources[i], ref num18, ref num19, ref num20, ref value); buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255); } } buildingData.m_tempExport = (byte)Mathf.Clamp(behaviour.m_touristCount, (int)buildingData.m_tempExport, 255); buildingData.m_adults = (byte)productionRateArr[0]; int num21 = visitPlaceCount * 500; for (int k = 0; k < m_incomingResources.Length; k++) { if ((int)marketBuffer.outputAmountBuffer[k] > goodsCapacity - (num21 >> 1) && aliveVisitorCount <= visitPlaceCount >> 1) { buildingData.m_outgoingProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_outgoingProblemTimer + 1)); if (buildingData.m_outgoingProblemTimer >= 192) { problem = Notification.AddProblems(problem, Notification.Problem.NoCustomers | Notification.Problem.MajorProblem); } else if (buildingData.m_outgoingProblemTimer >= 128) { problem = Notification.AddProblems(problem, Notification.Problem.NoCustomers); } } else { buildingData.m_outgoingProblemTimer = 0; } } for (int i = 0; i < m_incomingResources.Length; i++) { if (marketBuffer.inputAmountBuffer[i] == 0 && !isAmount && m_incomingResources[i] != TransferManager.TransferReason.None) { buildingData.m_incomingProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_incomingProblemTimer + 1)); Notification.Problem problem2 = (m_incomingResources[i] != TransferManager.TransferReason.Fish) ? Notification.Problem.NoGoods : Notification.Problem.NoFishingGoods; if (buildingData.m_incomingProblemTimer < 64) { problem = Notification.AddProblems(problem, problem2); } else { problem = Notification.AddProblems(problem, Notification.Problem.MajorProblem | problem2); } } else { buildingData.m_incomingProblemTimer = 0; } } for (int i = 0; i < m_incomingResources.Length; i++) { if (buildingData.m_fireIntensity == 0 && m_incomingResources[i] != TransferManager.TransferReason.None) { int num22 = goodsCapacity - (int)marketBuffer.inputAmountBuffer[i] - num20; int num23 = m_goodsCapacity / 4; num22 -= num23 >> 1; if (num22 >= 0) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = num22 * 8 / num23; offer.Building = buildingID; offer.Position = buildingData.m_position; offer.Amount = 1; offer.Active = false; Singleton <TransferManager> .instance.AddIncomingOffer(m_incomingResources[i], offer); } } } if (buildingData.m_fireIntensity == 0 && outgoingTransferReason != TransferManager.TransferReason.None) { for (int k = 0; k < m_incomingResources.Length; k++) { int num24 = (int)marketBuffer.outputAmountBuffer[k] - aliveVisitorCount * 100; int num25 = Mathf.Max(0, visitPlaceCount - totalVisitorCount); if (num24 >= 100 && num25 > 0) { TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer); offer2.Priority = Mathf.Max(1, num24 * 8 / goodsCapacity); offer2.Building = buildingID; offer2.Position = buildingData.m_position; offer2.Amount = Mathf.Min(num24 / 100, num25); offer2.Active = false; Singleton <TransferManager> .instance.AddOutgoingOffer(outgoingTransferReason, offer2); } } } MarketBuffers[buildingID] = marketBuffer; } buildingData.m_problems = problem; }
public static bool StartTransfer(U __instance, ushort buildingID, ref Building data, TransferManager.TransferReason material, TransferManager.TransferOffer offer) { var managedReasons = instance?.GetManagedReasons(__instance, offer); if (!managedReasons?.Keys.Contains(material) ?? true) { return(true); } SVMUtils.doLog("START TRANSFER: {0} , {1}", typeof(U), material); foreach (var tr in managedReasons) { if (instance.ProcessOffer(buildingID, data, material, offer, tr.Key, tr.Value, __instance)) { return(false); } } SVMUtils.doLog("END TRANSFER: {0} , {1}", typeof(U), material); return(true); }
public static void FindEvacuationPlace(TouristAI thisAI, uint citizenID, ushort sourceBuilding, TransferManager.TransferReason reason) { Debug.LogWarning("FindEvacuationPlace is not overridden!"); }
protected virtual bool ProcessOffer(ushort buildingID, Building data, TransferManager.TransferReason material, TransferManager.TransferOffer offer, TransferManager.TransferReason trTarget, Tuple <VehicleInfo.VehicleType, bool, bool> tup, U instance) { if (material == trTarget) { ServiceSystemDefinition def = ServiceSystemDefinition.from(instance.m_info, tup.First); if (def == null) { SVMUtils.doLog("SSD Não definido para: {0} {1} {2} {3}", instance.m_info.m_class.m_service, instance.m_info.m_class.m_subService, instance.m_info.m_class.m_level, tup.First); return(false); } SVMUtils.doLog("[{1}] SSD = {0}", def, material); VehicleInfo randomVehicleInfo = ServiceSystemDefinition.availableDefinitions[def].GetAModel(buildingID); SVMUtils.doLog("[{1}] Veh = {0}", randomVehicleInfo?.ToString() ?? "<NULL>", material); if (randomVehicleInfo != null) { Array16 <Vehicle> vehicles = Singleton <VehicleManager> .instance.m_vehicles; instance.CalculateSpawnPosition(buildingID, ref data, ref Singleton <SimulationManager> .instance.m_randomizer, randomVehicleInfo, out Vector3 position, out Vector3 vector2); if (Singleton <VehicleManager> .instance.CreateVehicle(out ushort num, ref Singleton <SimulationManager> .instance.m_randomizer, randomVehicleInfo, position, material, tup.Second, tup.Third)) { randomVehicleInfo.m_vehicleAI.SetSource(num, ref vehicles.m_buffer[(int)num], buildingID); randomVehicleInfo.m_vehicleAI.StartTransfer(num, ref vehicles.m_buffer[(int)num], material, offer); return(true); } } } return(false); }
/// <summary> /// Finds an evacuation place for the specified citizen. /// </summary> /// /// <param name="citizenId">The citizen ID to find an evacuation place for.</param> /// /// <param name="reason">The evacuation reason.</param> protected void FindEvacuationPlace(uint citizenId, TransferManager.TransferReason reason) => TransferMgr.AddOutgoingOfferFromCurrentPosition(citizenId, reason);
public static bool Prefix(ref int __result, TransferManager.TransferReason material, ItemClass.Service sourceService = ItemClass.Service.None) { bool canRisePrice = true; switch (material) { case TransferManager.TransferReason.AnimalProducts: __result = 270; break; case TransferManager.TransferReason.Flours: __result = 270; break; case TransferManager.TransferReason.Paper: __result = 280; break; case TransferManager.TransferReason.PlanedTimber: __result = 280; break; case TransferManager.TransferReason.Petroleum: __result = 300; break; case TransferManager.TransferReason.Plastics: __result = 300; break; case TransferManager.TransferReason.Glass: __result = 290; break; case TransferManager.TransferReason.Metals: __result = 290; break; case TransferManager.TransferReason.LuxuryProducts: __result = 350; break; case TransferManager.TransferReason.Oil: __result = 200; break; case TransferManager.TransferReason.Ore: __result = 190; break; case TransferManager.TransferReason.Logs: __result = 180; break; case TransferManager.TransferReason.Grain: __result = 170; break; case TransferManager.TransferReason.Goods: if (sourceService == ItemClass.Service.Fishing) { __result = 500; } else { __result = 0; } break; case TransferManager.TransferReason.Fish: __result = 150; canRisePrice = false; break; case TransferManager.TransferReason.Petrol: __result = 0; break; case TransferManager.TransferReason.Food: __result = 0; break; case TransferManager.TransferReason.Lumber: __result = 0; break; case TransferManager.TransferReason.Coal: __result = 0; break; case TransferManager.TransferReason.Shopping: case TransferManager.TransferReason.ShoppingB: case TransferManager.TransferReason.ShoppingC: case TransferManager.TransferReason.ShoppingD: case TransferManager.TransferReason.ShoppingE: case TransferManager.TransferReason.ShoppingH: if (sourceService == ItemClass.Service.Fishing) { __result = 200; canRisePrice = false; } else { __result = 0; } break; case TransferManager.TransferReason.Entertainment: case TransferManager.TransferReason.EntertainmentB: case TransferManager.TransferReason.EntertainmentC: case TransferManager.TransferReason.EntertainmentD: __result = 0; break; default: __result = 0; break; } if (RealCity.reduceVehicle) { if (canRisePrice) { __result <<= MainDataStore.reduceCargoDivShift; } } __result = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, __result); return(false); }