// Copied from vanilla. Clunky, but temporary. Want to avoid reflection and its performance overhead, and Harmony 1.2 doesn't have reverse redirection. // TODO - Revist this and remove. static void CalculateGuestVehicles(CommonBuildingAI __instance, 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; do { if (num == 0) { return; } if ((TransferManager.TransferReason)instance.m_vehicles.m_buffer[num].m_transferType == material) { VehicleInfo info = instance.m_vehicles.m_buffer[num].Info; info.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size, out int max); cargo += Mathf.Min(size, max); capacity += max; count++; if ((instance.m_vehicles.m_buffer[num].m_flags & (Vehicle.Flags.Importing | Vehicle.Flags.Exporting)) != 0) { outside++; } } num = instance.m_vehicles.m_buffer[num].m_nextGuestVehicle; }while (++num2 <= 16384); CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); }
public static int GetCollapseTimeReverse(CommonBuildingAI inst) { IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { return(instructions); } _ = Transpiler(null); return(default);
public static void GetColorPostfix(ref CommonBuildingAI __instance, ushort buildingID, ref Building data, InfoManager.InfoMode infoMode, ref Color __result) { if (UserModSettings.Settings.Enabled && UserModSettings.Settings.Buildings_OverrideLights_1 && infoMode == InfoManager.InfoMode.None && __result.a > 0f) { var lightsOn = true; var buildingAI = data.Info.m_buildingAI; var service = data.Info.m_class.m_service; var subService = data.Info.m_class.m_subService; switch (service) { case ItemClass.Service.Commercial: var allowedLightsOff = UserModSettings.Settings.Buildings_OverrideCommercialLights_1 && subService != ItemClass.SubService.CommercialTourist && subService != ItemClass.SubService.CommercialLeisure; lightsOn = !allowedLightsOff || data.HasCitizensInside(CitizenUnit.Flags.Visit | CitizenUnit.Flags.Work); break; case ItemClass.Service.Education: lightsOn = !UserModSettings.Settings.Buildings_OverrideSchoolLights_1 || (!SimulationManager.instance.m_isNightTime && data.HasCitizensInside(CitizenUnit.Flags.Visit | CitizenUnit.Flags.Student | CitizenUnit.Flags.Work)); break; case ItemClass.Service.Office: lightsOn = !UserModSettings.Settings.Buildings_OverrideOfficeLights_1 || data.HasCitizensInside(CitizenUnit.Flags.Work); break; case ItemClass.Service.Industrial: lightsOn = !UserModSettings.Settings.Buildings_OverrideIndustrialLights_1 || data.HasCitizensInside(CitizenUnit.Flags.Work); break; case ItemClass.Service.Residential: if (UserModSettings.Settings.Buildings_OverrideResidentialLights_1) { var citizensInside = data.HasCitizensInside(CitizenUnit.Flags.Home | CitizenUnit.Flags.Visit); var highrise = subService == ItemClass.SubService.ResidentialHigh || subService == ItemClass.SubService.ResidentialHighEco; if (!highrise) { var allAsleep = !citizensInside || !data.AnyCitizenInside(CitizenUnit.Flags.Home | CitizenUnit.Flags.Visit, citizenId => { var citizen = CitizenManager.instance.m_citizens.m_buffer[citizenId]; return(!citizen.Tired()); }); lightsOn = !allAsleep; } else { lightsOn = citizensInside; } } break; } __result.a = lightsOn ? 1f : 0f; } }
/// <summary> /// Simple Prefix patch to toggle excecution of game method based on current settings. /// </summary> /// <param name="__instance">Harmony original instance reference</param> /// <returns>False if the base method shouldn't be called (collapse has been prevented), true otherwise</returns> public static bool Prefix(ref bool __result, CommonBuildingAI __instance) { if (ModSettings.noCollapse && RICOUtils.IsRICOPloppableAI(__instance as PrivateBuildingAI)) { __result = false; // Don't call base method after this. return(false); } // Continue on to base method return(true); }
public override Color GetColor(ushort buildingID, ref Building data, InfoManager.InfoMode infoMode) { if (infoMode == InfoManager.InfoMode.Water) { if ((data.m_flags & Building.Flags.Active) == Building.Flags.None) { return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_inactiveColor); } if (this.m_waterIntake != 0) { return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_activeColor); } //if (this.m_sewageOutlet != 0) //{ // return Singleton<InfoManager>.instance.m_properties.m_modeProperties[(int)infoMode].m_activeColorB; //} return(base.GetColor(buildingID, ref data, infoMode)); } else { if (infoMode == InfoManager.InfoMode.NoisePollution) { int noiseAccumulation = this.m_noiseAccumulation; return(CommonBuildingAI.GetNoisePollutionColor((float)noiseAccumulation)); } if (infoMode != InfoManager.InfoMode.Pollution) { return(base.GetColor(buildingID, ref data, infoMode)); } if (this.m_waterIntake != 0) { float t = Mathf.Clamp01((float)data.m_waterPollution * 0.0117647061f); return(ColorUtils.LinearLerp(Singleton <InfoManager> .instance.m_properties.m_neutralColor, Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_activeColor, t)); } //if (this.m_sewageOutlet != 0) //{ // return Singleton<InfoManager>.instance.m_properties.m_modeProperties[(int)infoMode].m_activeColor; //} return(base.GetColor(buildingID, ref data, infoMode)); } }
private static void HandleFireSpread(CommonBuildingAI CBAI, ushort buildingID, ref Building buildingData, int fireDamage) { unsafe { Quad2 quad2 = new Quad2(); int width = buildingData.Width; int length = buildingData.Length; Vector2 vector2 = VectorUtils.XZ(buildingData.m_position); Vector2 vector21 = new Vector2(Mathf.Cos(buildingData.m_angle), Mathf.Sin(buildingData.m_angle)); Vector2 vector22 = new Vector2(vector21.y, -vector21.x); float single = (float)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 32); quad2.a = (vector2 - (((float)width * 4f + single) * vector21)) - (((float)length * 4f + single) * vector22); quad2.b = (vector2 + (((float)width * 4f + single) * vector21)) - (((float)length * 4f + single) * vector22); quad2.c = (vector2 + (((float)width * 4f + single) * vector21)) + (((float)length * 4f + single) * vector22); quad2.d = (vector2 - (((float)width * 4f + single) * vector21)) + (((float)length * 4f + single) * vector22); Vector2 vector23 = quad2.Min(); Vector2 vector24 = quad2.Max(); float mPosition = buildingData.m_position.y - (float)buildingData.m_baseHeight; //krn //CBAI.m_info is private\instance /use reflection, should do reverse redirect. BuildingInfo bldgInfo; bldgInfo = (BuildingInfo)CBAI.GetType().GetField("m_info", BindingFlags.Instance | BindingFlags.Public).GetValue(CBAI); if (bldgInfo == null && bldgInfo.m_size == null) { Logger.dbgLog("bldgInfo was null"); } float mPosition1 = buildingData.m_position.y + bldgInfo.m_size.y; //org //float mPosition1 = buildingData.m_position.y + this.m_info.m_size.y; //end org float mFireIntensity = (float)(buildingData.m_fireIntensity * (64 - Mathf.Abs(fireDamage - 192))); InstanceID instanceID = new InstanceID() { Building = buildingID }; InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(instanceID); if (group != null) { ushort disaster = group.m_ownerInstance.Disaster; if (disaster != 0) { DisasterManager disasterManager = Singleton <DisasterManager> .instance; DisasterInfo info = disasterManager.m_disasters.m_buffer[disaster].Info; int fireSpreadProbability = info.m_disasterAI.GetFireSpreadProbability(disaster, ref disasterManager.m_disasters.m_buffer[disaster]); mFireIntensity = mFireIntensity * ((float)fireSpreadProbability * 0.01f); } } int num = Mathf.Max((int)((vector23.x - 72f) / 64f + 135f), 0); int num1 = Mathf.Max((int)((vector23.y - 72f) / 64f + 135f), 0); int num2 = Mathf.Min((int)((vector24.x + 72f) / 64f + 135f), 269); int num3 = Mathf.Min((int)((vector24.y + 72f) / 64f + 135f), 269); BuildingManager buildingManager = Singleton <BuildingManager> .instance; for (int i = num1; i <= num3; i++) { for (int j = num; j <= num2; j++) { ushort mBuildingGrid = buildingManager.m_buildingGrid[i * 270 + j]; int num4 = 0; object[] paramcall; while (mBuildingGrid != 0) { //Should we change this 262144? if (mBuildingGrid != buildingID && (float)Singleton <SimulationManager> .instance.m_randomizer.Int32(262144) * single < mFireIntensity) { //Logger.dbgLog("Handlefire1"); paramcall = new object[] { quad2, mPosition, mPosition1, mBuildingGrid, buildingManager.m_buildings.m_buffer[mBuildingGrid], group }; //var x = CBAI.GetType().GetMethod("TrySpreadFire", BindingFlags.Static | BindingFlags.NonPublic).Invoke(CBAI, paramcall); LimitCommonBuildingAI.TrySpreadFire(quad2, mPosition, mPosition1, mBuildingGrid, ref buildingManager.m_buildings.m_buffer[mBuildingGrid], group); //Logger.dbgLog("Handlefire2"); //orginal //CommonBuildingAI.TrySpreadFire(quad2, mPosition, mPosition1, mBuildingGrid, ref buildingManager.m_buildings.m_buffer[mBuildingGrid], group); } mBuildingGrid = buildingManager.m_buildings.m_buffer[mBuildingGrid].m_nextGridBuilding; int num5 = num4 + 1; num4 = num5; if (num5 < 49152) { continue; } CODebugBase <LogChannel> .Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace)); break; } } } Vector3 vector3 = VectorUtils.X_Y(vector21); Vector3 vector31 = VectorUtils.X_Y(vector22); int num6 = Mathf.Max((int)((vector23.x - 32f) / 32f + 270f), 0); int num7 = Mathf.Max((int)((vector23.y - 32f) / 32f + 270f), 0); int num8 = Mathf.Min((int)((vector24.x + 32f) / 32f + 270f), 539); int num9 = Mathf.Min((int)((vector24.y + 32f) / 32f + 270f), 539); TreeManager treeManager = Singleton <TreeManager> .instance; for (int k = num7; k <= num9; k++) { for (int l = num6; l <= num8; l++) { uint mTreeGrid = treeManager.m_treeGrid[k * 540 + l]; int num10 = 0; while (mTreeGrid != 0) { Vector3 position = treeManager.m_trees.m_buffer[mTreeGrid].Position; Vector3 mPosition2 = position - buildingData.m_position; mPosition2 = mPosition2 - (Mathf.Clamp(Vector3.Dot(mPosition2, vector3), (float)(-width) * 4f, (float)width * 4f) * vector3); mPosition2 = mPosition2 - (Mathf.Clamp(Vector3.Dot(mPosition2, vector31), (float)(-length) * 4f, (float)length * 4f) * vector31); float single1 = mPosition2.magnitude; //Should we change this 131072? //Logger.dbgLog("Handlefire3"); if (single1 < 32f && (float)Singleton <SimulationManager> .instance.m_randomizer.Int32(131072) * single1 < mFireIntensity) { treeManager.BurnTree(mTreeGrid, group, (int)buildingData.m_fireIntensity); } mTreeGrid = treeManager.m_trees.m_buffer[mTreeGrid].m_nextGridTree; int num11 = num10 + 1; num10 = num11; if (num11 < LimitTreeManager.Helper.TreeLimit) { continue; } CODebugBase <LogChannel> .Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace)); break; } } } } }
public static bool RenderInstanceCommonBuildingAIPrefix(CommonBuildingAI __instance, RenderManager.CameraInfo cameraInfo, ushort buildingID, ref Building data, int layerMask, ref RenderManager.Instance instance) { if ((data.m_flags & (Building.Flags.Completed | Building.Flags.Collapsed)) != Building.Flags.Completed) { if ((data.m_flags & Building.Flags.Collapsed) != 0) { uint num = (uint)(buildingID << 8) / 49152u; uint num2 = Singleton <SimulationManager> .instance.m_referenceFrameIndex - num; float t = ((float)(double)(num2 & 0xFF) + Singleton <SimulationManager> .instance.m_referenceTimer) * 0.00390625f; Building.Frame frameData = data.GetFrameData(num2 - 512); Building.Frame frameData2 = data.GetFrameData(num2 - 256); instance.m_dataVector0.x = Mathf.Max(0f, (Mathf.Lerp((int)frameData.m_fireDamage, (int)frameData2.m_fireDamage, t) - 127f) * 0.0078125f); instance.m_dataVector0.y = 0f; instance.m_dataVector0.z = (((data.m_flags & Building.Flags.Abandoned) == 0) ? 0f : 1f); float num3 = 0f; Randomizer randomizer = new Randomizer(buildingID); int num4 = randomizer.Int32(4u); if (frameData.m_constructState != 0) { float y = __instance.m_info.m_size.y; float num5 = (float)GetCollapseTimeReverse(__instance); num5 /= Mathf.Max(1f, num5 - 6f); float num6 = Mathf.Lerp((int)frameData.m_constructState, (int)frameData2.m_constructState, t) * 0.003921569f; num3 = 1f - num5 * (1f - num6); instance.m_dataVector0.y = Mathf.Max(instance.m_dataVector0.y, y * num3); if (instance.m_dataVector0.y > 0.1f) { __instance.RenderProps(cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: false, renderNonfixed: true); float angle = data.m_angle; Vector3 position = instance.m_position; Quaternion rotation = instance.m_rotation; Matrix4x4 dataMatrix = instance.m_dataMatrix1; float f = (float)randomizer.Int32(1000u) * ((float)Math.PI / 500f); float num7 = randomizer.Int32(10, 45); float angle2 = (1f - num3) * (1f - num3) * num7; Vector3 axis = new Vector3(Mathf.Cos(f), 0f, Mathf.Sin(f)); float num8 = (y - instance.m_dataVector0.y) * (y - instance.m_dataVector0.y) / y; instance.m_position.x += axis.z * num8 * num7 * 0.01f; instance.m_position.z -= axis.x * num8 * num7 * 0.01f; instance.m_position.y -= num8; instance.m_rotation = Quaternion.AngleAxis(angle2, axis) * Quaternion.AngleAxis(angle * 57.29578f, Vector3.down); instance.m_dataMatrix1.SetTRS(instance.m_position, instance.m_rotation, Vector3.one); instance.m_dataVector0.y = y; #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => __instance.RenderMeshes(cameraInfo, buildingID, ref localData, layerMask, ref localInstance)); #else __instance.RenderMeshes(cameraInfo, buildingID, ref data, layerMask, ref instance); #endif __instance.RenderProps(cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: true, renderNonfixed: false); instance.m_dataVector0.y = y - num8; instance.m_position = position; instance.m_rotation = rotation; instance.m_dataMatrix1 = dataMatrix; } else if ((data.m_flags & Building.Flags.Demolishing) == 0) { RenderDestroyedPropsPrefix(__instance, cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: false, renderNonfixed: true); } } else if ((data.m_flags & Building.Flags.Demolishing) == 0) { RenderDestroyedPropsPrefix(__instance, cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: false, renderNonfixed: true); } float num9 = Mathf.Clamp01(1f - num3); instance.m_dataVector0.x = 0f - instance.m_dataVector0.x; if ((data.m_flags & Building.Flags.Demolishing) == 0 && num9 > 0.01f) { BuildingInfoBase collapsedInfo = __instance.m_info.m_collapsedInfo; if (__instance.m_info.m_mesh != null && collapsedInfo != null) { if (((1 << num4) & __instance.m_info.m_collapsedRotations) == 0) { num4 = ((num4 + 1) & 3); } Vector3 min = __instance.m_info.m_generatedInfo.m_min; Vector3 max = __instance.m_info.m_generatedInfo.m_max; float num10 = (float)data.Width * 4f; float num11 = (float)data.Length * 4f; float num12 = Building.CalculateLocalMeshOffset(__instance.m_info, data.Length); min = Vector3.Max(min - new Vector3(4f, 0f, 4f + num12), new Vector3(0f - num10, 0f, 0f - num11)); max = Vector3.Min(max + new Vector3(4f, 0f, 4f - num12), new Vector3(num10, 0f, num11)); Vector3 vector = (min + max) * 0.5f; Vector3 vector2 = max - min; float x = (((num4 & 1) != 0) ? vector2.z : vector2.x) * num9 / Mathf.Max(1f, collapsedInfo.m_generatedInfo.m_size.x); float z = (((num4 & 1) != 0) ? vector2.x : vector2.z) * num9 / Mathf.Max(1f, collapsedInfo.m_generatedInfo.m_size.z); Quaternion q = Quaternion.AngleAxis((float)num4 * 90f, Vector3.down); instance.m_dataVector0.y = Mathf.Max(instance.m_dataVector0.y, collapsedInfo.m_generatedInfo.m_size.y); Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(vector.x, 0f, vector.z + num12), q, new Vector3(x, num9, z)); collapsedInfo.m_rendered = true; #if UseTask var localInstance = instance; Patcher.Dispatcher.Add(() => BuildingAI.RenderMesh(cameraInfo, __instance.m_info, collapsedInfo, matrix, ref localInstance)); #else BuildingAI.RenderMesh(cameraInfo, __instance.m_info, collapsedInfo, matrix, ref instance); #endif } } if (Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.None) { #if UseTask var localData = data; Patcher.Dispatcher.Add(() => __instance.RenderCollapseEffect(cameraInfo, buildingID, ref localData, num3)); #else __instance.RenderCollapseEffect(cameraInfo, buildingID, ref data, num3); #endif } return(false); } uint num13 = (uint)(buildingID << 8) / 49152u; uint num14 = Singleton <SimulationManager> .instance.m_referenceFrameIndex - num13; float t2 = ((float)(double)(num14 & 0xFF) + Singleton <SimulationManager> .instance.m_referenceTimer) * 0.00390625f; Building.Frame frameData3 = data.GetFrameData(num14 - 512); Building.Frame frameData4 = data.GetFrameData(num14 - 256); float num15 = 0f; BuildingInfo buildingInfo; BuildingInfo buildingInfo2; if ((data.m_flags & Building.Flags.Upgrading) != 0) { BuildingInfo upgradeInfo = __instance.GetUpgradeInfo(buildingID, ref data); if (upgradeInfo != null) { buildingInfo = __instance.m_info; buildingInfo2 = upgradeInfo; } else { buildingInfo = null; buildingInfo2 = __instance.m_info; } } else { buildingInfo = null; buildingInfo2 = __instance.m_info; } float num16 = buildingInfo2.m_size.y; if (buildingInfo != null) { num16 = Mathf.Max(num16, buildingInfo.m_size.y); } float num17 = (float)GetConstructionTimeReverse(__instance); num17 /= Mathf.Max(1f, num17 - 6f); float num18 = Mathf.Max(0.5f, num16 / 60f); float num19 = Mathf.Ceil(num16 / num18 / 6f) * 6f; float num20 = (num19 * 2f + 6f) * num17 * Mathf.Lerp((int)frameData3.m_constructState, (int)frameData4.m_constructState, t2) * 0.003921569f; float num21 = (num20 - 6f) * num18; if (num21 >= buildingInfo2.m_size.y && instance.m_dataInt0 != buildingInfo2.m_prefabDataIndex) { BuildingAI.RefreshInstance(buildingInfo2, cameraInfo, buildingID, ref data, layerMask, ref instance, requireHeightMap: false); } float num22 = (!(num20 > num19)) ? num20 : Mathf.Min(num19, num19 * 2f + 6f - num20); if (frameData4.m_productionState < frameData3.m_productionState) { instance.m_dataVector3.w = Mathf.Lerp((int)frameData3.m_productionState, (float)(int)frameData4.m_productionState + 256f, t2) * 0.00390625f; if (instance.m_dataVector3.w >= 1f) { instance.m_dataVector3.w -= 1f; } } else { instance.m_dataVector3.w = Mathf.Lerp((int)frameData3.m_productionState, (int)frameData4.m_productionState, t2) * 0.00390625f; } if (buildingInfo != null) { instance.m_position = Building.CalculateMeshPosition(buildingInfo, data.m_position, data.m_angle, data.Length); instance.m_rotation = Quaternion.AngleAxis(data.m_angle * 57.29578f, Vector3.down); instance.m_dataMatrix1.SetTRS(instance.m_position, instance.m_rotation, Vector3.one); instance.m_dataColor0 = buildingInfo.m_buildingAI.GetColor(buildingID, ref data, Singleton <InfoManager> .instance.CurrentMode); float num23 = num20 * num18; float num24 = (!(num23 > buildingInfo.m_size.y)) ? buildingInfo.m_size.y : (buildingInfo.m_size.y * 2f - num23); if (num24 > 0f) { instance.m_dataVector0.y = 0f - num24; instance.m_dataVector0.x = num22 * num18; #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => buildingInfo.m_buildingAI.RenderMeshes(cameraInfo, buildingID, ref localData, layerMask, ref localInstance)); #else buildingInfo.m_buildingAI.RenderMeshes(cameraInfo, buildingID, ref data, layerMask, ref instance); #endif num15 = Mathf.Max(num15, instance.m_dataVector0.y); if (instance.m_dataVector0.y >= buildingInfo.m_size.y && instance.m_dataInt0 == buildingInfo.m_prefabDataIndex) { layerMask &= ~(1 << Singleton <TreeManager> .instance.m_treeLayer); buildingInfo.m_buildingAI.RenderProps(cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: true, renderNonfixed: true); } } } float num25 = data.m_angle; int length = data.Length; int num26 = 0; if (buildingInfo != null && buildingInfo2 != null) { if (buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft && buildingInfo2.m_zoningMode == BuildingInfo.ZoningMode.CornerRight) { num25 -= (float)Math.PI / 2f; num26 = -1; length = data.Width; } else if (buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight && buildingInfo2.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft) { num25 += (float)Math.PI / 2f; num26 = 1; length = data.Width; } } instance.m_position = Building.CalculateMeshPosition(buildingInfo2, data.m_position, num25, length); instance.m_rotation = Quaternion.AngleAxis(num25 * 57.29578f, Vector3.down); instance.m_dataMatrix1.SetTRS(instance.m_position, instance.m_rotation, Vector3.one); instance.m_dataColor0 = buildingInfo2.m_buildingAI.GetColor(buildingID, ref data, Singleton <InfoManager> .instance.CurrentMode); if (num21 > 0f) { instance.m_dataVector0.y = 0f - num21; instance.m_dataVector0.x = num22 * num18; #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => buildingInfo2.m_buildingAI.RenderMeshes(cameraInfo, buildingID, ref localData, layerMask, ref localInstance)); #else buildingInfo2.m_buildingAI.RenderMeshes(cameraInfo, buildingID, ref data, layerMask, ref instance); #endif num15 = Mathf.Max(num15, instance.m_dataVector0.y); if (num21 >= buildingInfo2.m_size.y && instance.m_dataInt0 == buildingInfo2.m_prefabDataIndex) { layerMask &= ~(1 << Singleton <TreeManager> .instance.m_treeLayer); buildingInfo2.m_buildingAI.RenderProps(cameraInfo, buildingID, ref data, layerMask, ref instance, renderFixed: true, renderNonfixed: true); } } BuildingManager instance2 = Singleton <BuildingManager> .instance; if (instance2.m_common != null) { BuildingInfoBase construction = instance2.m_common.m_construction; Vector3 vector3 = buildingInfo2.m_generatedInfo.m_max; Vector3 vector4 = buildingInfo2.m_generatedInfo.m_min; if (buildingInfo != null) { Vector3 zero = Vector3.zero; zero.z = 0f - Building.CalculateLocalMeshOffset(buildingInfo2, length); switch (num26) { case -1: { zero.x -= Building.CalculateLocalMeshOffset(buildingInfo, data.Length); Vector3 max3 = buildingInfo.m_generatedInfo.m_max; Vector3 min3 = buildingInfo.m_generatedInfo.m_min; vector3 = Vector3.Max(vector3, new Vector3(max3.z, max3.y, 0f - min3.x) - zero); vector4 = Vector3.Min(vector4, new Vector3(min3.z, min3.y, 0f - max3.x) - zero); break; } case 1: { zero.x += Building.CalculateLocalMeshOffset(buildingInfo, data.Length); Vector3 max2 = buildingInfo.m_generatedInfo.m_max; Vector3 min2 = buildingInfo.m_generatedInfo.m_min; vector3 = Vector3.Max(vector3, new Vector3(max2.z, max2.y, max2.x) - zero); vector4 = Vector3.Min(vector4, new Vector3(min2.z, min2.y, min2.x) - zero); break; } default: zero.z += Building.CalculateLocalMeshOffset(buildingInfo, data.Length); vector3 = Vector3.Max(vector3, buildingInfo.m_generatedInfo.m_max - zero); vector4 = Vector3.Min(vector4, buildingInfo.m_generatedInfo.m_min - zero); break; } } Vector3 vector5 = vector3 - vector4; float x2 = (vector5.x + 1f) / Mathf.Max(1f, construction.m_generatedInfo.m_size.x); float z2 = (vector5.z + 1f) / Mathf.Max(1f, construction.m_generatedInfo.m_size.z); Matrix4x4 matrix2 = Matrix4x4.TRS(new Vector3((vector3.x + vector4.x) * 0.5f, 0f, (vector3.z + vector4.z) * 0.5f), s: new Vector3(x2, num18, z2), q: Quaternion.identity); if (num22 > 0f) { instance.m_dataVector0.y = num22; construction.m_rendered = true; #if UseTask var localInstance = instance; Patcher.Dispatcher.Add(() => BuildingAI.RenderMesh(cameraInfo, buildingInfo2, construction, matrix2, ref localInstance)); #else BuildingAI.RenderMesh(cameraInfo, buildingInfo2, construction, matrix2, ref instance); #endif num15 = Mathf.Max(num15, instance.m_dataVector0.y); } } instance.m_dataVector0.y = num15; return(false); } if (!__instance.m_hideGarbageBins) { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => __instance.RenderGarbageBins(cameraInfo, buildingID, ref localData, layerMask, ref localInstance)); #else __instance.RenderGarbageBins(cameraInfo, buildingID, ref data, layerMask, ref instance); #endif } uint num27 = (uint)(buildingID << 8) / 49152u; uint num28 = Singleton <SimulationManager> .instance.m_referenceFrameIndex - num27; float t3 = ((float)(double)(num28 & 0xFF) + Singleton <SimulationManager> .instance.m_referenceTimer) * 0.00390625f; Building.Frame frameData5 = data.GetFrameData(num28 - 512); Building.Frame frameData6 = data.GetFrameData(num28 - 256); instance.m_dataVector0.x = Mathf.Max(0f, (Mathf.Lerp((int)frameData5.m_fireDamage, (int)frameData6.m_fireDamage, t3) - 127f) * 0.0078125f); instance.m_dataVector0.z = (((data.m_flags & Building.Flags.Abandoned) == 0) ? 0f : 1f); if (frameData6.m_productionState < frameData5.m_productionState) { instance.m_dataVector3.w = Mathf.Lerp((int)frameData5.m_productionState, (float)(int)frameData6.m_productionState + 256f, t3) * 0.00390625f; if (instance.m_dataVector3.w >= 1f) { instance.m_dataVector3.w -= 1f; } } else { instance.m_dataVector3.w = Mathf.Lerp((int)frameData5.m_productionState, (int)frameData6.m_productionState, t3) * 0.00390625f; } RenderInstanceBuildingAIPrefix(__instance, cameraInfo, buildingID, ref data, layerMask, ref instance); if (data.m_fireIntensity != 0 && Singleton <InfoManager> .instance.CurrentMode == InfoManager.InfoMode.None) { #if UseTask var localData = data; var localInstance = instance; var action = new Action(() => { __instance.RenderFireEffect(cameraInfo, buildingID, ref localData, localInstance.m_dataVector0.x); RenderFireEffectPropsReverse(__instance, cameraInfo, buildingID, ref localData, ref localInstance, (float)(int)localData.m_fireIntensity * 0.003921569f, localInstance.m_dataVector0.x, true, true); }); Patcher.Dispatcher.Add(action); #else __instance.RenderFireEffect(cameraInfo, buildingID, ref data, instance.m_dataVector0.x); RenderFireEffectPropsReverse(__instance, cameraInfo, buildingID, ref data, ref instance, (float)(int)data.m_fireIntensity * 0.003921569f, instance.m_dataVector0.x, true, true); #endif } return(false); }
static bool Prefix(CommonBuildingAI __instance, ushort buildingID, ref Building data, int crimeAccumulation, int citizenCount) { int number = 10; if (crimeAccumulation != 0) { ItemClass ic = data.Info.m_class; int percentage = (int)((ic.m_level >= 0) ? ic.m_level : 0); // TODO - Should be replaced by height of building?? // Values to be determined and will not be added to XML yet if (ic.m_service == ItemClass.Service.Residential) { number = 16; if (ic.m_subService == ItemClass.SubService.ResidentialHigh) { crimeAccumulation /= 2; } } else if (ic.m_service == ItemClass.Service.Office) { crimeAccumulation /= 5; // Not enough? } else if (ic.m_subService == ItemClass.SubService.CommercialHigh) { crimeAccumulation /= 3; } // Percentage reduction crimeAccumulation = (crimeAccumulation * (number - percentage)) / number; // ----- End of changes ----- if (Singleton <SimulationManager> .instance.m_isNightTime) { // crime multiplies by 1.25 at night crimeAccumulation = crimeAccumulation * 5 >> 2; } if (data.m_eventIndex != 0) { EventManager instance = Singleton <EventManager> .instance; EventInfo info = instance.m_events.m_buffer[(int)data.m_eventIndex].Info; crimeAccumulation = info.m_eventAI.GetCrimeAccumulation(data.m_eventIndex, ref instance.m_events.m_buffer[(int)data.m_eventIndex], crimeAccumulation); } crimeAccumulation = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)crimeAccumulation); if (!Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.PoliceDepartment)) { crimeAccumulation = 0; } } data.m_crimeBuffer = (ushort)Mathf.Min(citizenCount * 100, (int)data.m_crimeBuffer + crimeAccumulation); //Debugging.writeDebugToFile(data.Info.gameObject.name + " -> number:" + citizenCount + ", crime_buffer: " + data.m_crimeBuffer + " + " + crimeAccumulation); int crimeBuffer = (int)data.m_crimeBuffer; if (citizenCount != 0 && crimeBuffer > citizenCount * 25 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; CalculateGuestVehicles(__instance, buildingID, ref data, TransferManager.TransferReason.Crime, ref num, ref num2, ref num3, ref num4); if (num == 0) { TransferManager.TransferOffer offer = default(TransferManager.TransferOffer); offer.Priority = crimeBuffer / Mathf.Max(1, citizenCount * 10); offer.Building = buildingID; offer.Position = data.m_position; offer.Amount = 1; Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Crime, offer); } } Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Crime); if ((int)data.m_crimeBuffer > citizenCount * 90) { problem = Notification.AddProblems(problem, Notification.Problem.Crime | Notification.Problem.MajorProblem); } else if ((int)data.m_crimeBuffer > citizenCount * 60) { problem = Notification.AddProblems(problem, Notification.Problem.Crime); } data.m_problems = problem; // Don't execute base method after this. return(false); }
public static void CalculateOwnVehicles(CommonBuildingAI ai, ushort buildingID, ref Building data, TransferManager.TransferReason material, ref int count, ref int cargo, ref int capacity, ref int outside) { UnityEngine.Debug.Log("1"); }
public override Color GetColor(ushort buildingID, ref Building data, InfoManager.InfoMode infoMode) { int attractivenessAccumulation = GetAttractivenessAccumulation(buildingID, ref data); switch (infoMode) { case InfoManager.InfoMode.Tours: return(CommonBuildingAI.GetAttractivenessColor(attractivenessAccumulation * 15)); default: if (infoMode == InfoManager.InfoMode.NoisePollution) { int noiseAccumulation = m_noiseAccumulation; return(CommonBuildingAI.GetNoisePollutionColor((float)noiseAccumulation)); } if (infoMode != InfoManager.InfoMode.Connections) { if (infoMode != InfoManager.InfoMode.Entertainment) { return(base.GetColor(buildingID, ref data, infoMode)); } if (Singleton <InfoManager> .instance.CurrentSubMode != InfoManager.SubInfoMode.WaterPower) { return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } if ((data.m_flags & Building.Flags.Active) != Building.Flags.None) { return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_activeColor); } return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_inactiveColor); } else { if (!ShowConsumption(buildingID, ref data)) { return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } if (Singleton <InfoManager> .instance.CurrentSubMode != InfoManager.SubInfoMode.Default) { return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } for (int i = 0; i < m_incomingResources.Length; i++) { if (m_incomingResources[i] != TransferManager.TransferReason.None && (data.m_tempImport != 0 || data.m_finalImport != 0)) { return(Singleton <TransferManager> .instance.m_properties.m_resourceColors[(int)m_incomingResources[i]]); } } return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } case InfoManager.InfoMode.Tourism: { InfoManager.SubInfoMode currentSubMode = Singleton <InfoManager> .instance.CurrentSubMode; if (currentSubMode == InfoManager.SubInfoMode.Default) { if (data.m_tempExport != 0 || data.m_finalExport != 0) { return(CommonBuildingAI.GetTourismColor(Mathf.Max((int)data.m_tempExport, (int)data.m_finalExport))); } return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } else { if (currentSubMode != InfoManager.SubInfoMode.WaterPower) { return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } if (attractivenessAccumulation != 0) { return(CommonBuildingAI.GetAttractivenessColor(attractivenessAccumulation * 100)); } return(Singleton <InfoManager> .instance.m_properties.m_neutralColor); } } case InfoManager.InfoMode.Fishing: if ((data.m_flags & Building.Flags.Active) != Building.Flags.None) { return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_activeColor); } return(Singleton <InfoManager> .instance.m_properties.m_modeProperties[(int)infoMode].m_inactiveColor); } }