Exemplo n.º 1
0
        static bool Prefix(int seed, InstanceManager.Group group, Vector3 position, float preRadius, float removeRadius,
                           float destructionRadiusMin, float destructionRadiusMax, float burnRadiusMin, float burnRadiusMax, float probability)
        {
            DisasterType dt = DisasterType.Empty;

            if (probability == 0.02f)
            {
                dt = DisasterType.Earthquake;
            }
            else if (burnRadiusMin == 0 && burnRadiusMax == 0)
            {
                dt = DisasterType.Tornado;
            }

            if (dt == DisasterType.Earthquake)
            {
                DisasterHelpersModified.DestroyBuildings(seed, group, position, preRadius, removeRadius, destructionRadiusMin,
                                                         destructionRadiusMax, burnRadiusMin, burnRadiusMax, 0.04f); // Orig = 0.02f

                return(false);
            }
            else if (dt == DisasterType.Tornado)
            {
                DisasterHelpersModified.DestroyBuildings(seed, group, position, preRadius, removeRadius, destructionRadiusMin,
                                                         destructionRadiusMax, burnRadiusMin, burnRadiusMax, 0.5f); // Orig = 1.0f

                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
            public static bool ShouldWeBurnit(ref InstanceManager.Group group, int rate)
            {
                try
                {
                    if (rate == 0)
                    {
                        //if (Mod.DEBUG_LOG_ON & Mod.DEBUG_LOG_LEVEL > 1)
                        //{
                        //    Logger.dbgLog("rate 0 abort burn");
                        //}
                        return(false);
                    } //disabled and no disaster override matters.
                    else if (rate == 100) //we're not in use, burn.
                    {
                        //if (Mod.DEBUG_LOG_ON & Mod.DEBUG_LOG_LEVEL > 1)
                        //{
                        //    Logger.dbgLog("rate 100 -> burn");
                        //}
                        return(true);
                    }

                    //Allow for\game or user to still "start" the first tree burning of a disaster so long as we're not disabled.
                    if (group != null)
                    {
                        ushort disaster = group.m_ownerInstance.Disaster;
                        if (disaster != 0)
                        {
                            if (Singleton <DisasterManager> .instance.m_disasters.m_buffer[disaster].m_treeFireCount < 1)
                            {
                                return(true);  //allow the very first tree to burn.
                            }
                        }
                    }

                    int tmpint = 100;   //holds our random value.
                    tmpint = SimulationManager.instance.m_randomizer.Int32(100);
                    if (rate <= tmpint) //if true we burn. // 80 < 100; 80% of the time we will burn, 20% fail rate.
                    {
                        if (Mod.DEBUG_LOG_ON & Mod.DEBUG_LOG_LEVEL > 2)
                        {
                            Logger.dbgLog(string.Format(" tree rate:{0} <eq {1} true. return no burn", rate.ToString(), tmpint.ToString()));
                        }

                        return(false);
                    }
                    else
                    {
                        if (Mod.DEBUG_LOG_ON & Mod.DEBUG_LOG_LEVEL > 2)
                        {
                            Logger.dbgLog(string.Format("rate:{0} NOT <eq {1} . returning burn.", rate.ToString(), tmpint.ToString()));
                        }
                        return(true);
                    }
                }
                catch (Exception ex) { Logger.dbgLog("", ex); }
                return(true);  //if error burn.
            }
        private static void DestroyTrees(int seed, InstanceManager.Group group, Vector3 position, float totalRadius, float removeRadius, float destructionRadiusMin, float destructionRadiusMax, float burnRadiusMin, float burnRadiusMax)
        {
            int num  = Mathf.Max((int)((position.x - totalRadius) / 32f + 270f), 0);
            int num2 = Mathf.Max((int)((position.z - totalRadius) / 32f + 270f), 0);
            int num3 = Mathf.Min((int)((position.x + totalRadius) / 32f + 270f), 539);
            int num4 = Mathf.Min((int)((position.z + totalRadius) / 32f + 270f), 539);
            Array32 <global::TreeInstance> trees = Singleton <TreeManager> .instance.m_trees;

            uint[] treeGrid = Singleton <TreeManager> .instance.m_treeGrid;
            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    uint num5 = treeGrid[i * 540 + j];
                    int  num6 = 0;
                    while (num5 != 0u)
                    {
                        uint nextGridTree = trees.m_buffer[(int)((UIntPtr)num5)].m_nextGridTree;
                        global::TreeInstance.Flags flags = (global::TreeInstance.Flags)trees.m_buffer[(int)((UIntPtr)num5)].m_flags;
                        if ((flags & (global::TreeInstance.Flags.Created | global::TreeInstance.Flags.Deleted)) == global::TreeInstance.Flags.Created)
                        {
                            Vector3 position2 = trees.m_buffer[(int)((UIntPtr)num5)].Position;
                            float   num7      = VectorUtils.LengthXZ(position2 - position);
                            if (num7 < totalRadius)
                            {
                                Randomizer randomizer = new Randomizer(num5 | (uint)((uint)seed << 16));
                                float      num8       = (burnRadiusMax - num7) / Mathf.Max(1f, burnRadiusMax - burnRadiusMin);
                                bool       flag       = num7 < removeRadius;
                                bool       flag2      = (float)randomizer.Int32(1000u) < num8 * 1000f;
                                if (flag)
                                {
                                    Singleton <TreeManager> .instance.ReleaseTree(num5);
                                }
                                else if (flag2 && (flags & global::TreeInstance.Flags.FireDamage) == global::TreeInstance.Flags.None)
                                {
                                    Singleton <TreeManager> .instance.BurnTree(num5, group, 128);
                                }
                            }
                        }
                        num5 = nextGridTree;
                        if (++num6 >= LimitTreeManager.Helper.TreeLimit)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        private bool HandleSpecialMeteorRename(ushort disaster, string newName)
        {
            InstanceID instanceId = InfoPanelHelper.GetInstanceID(typeof(MeteorWorldInfoPanel), out WorldInfoPanel panel);

            InstanceManager.Group group = InstanceManager.instance.GetGroup(instanceId);
            if (group == null)
            {
                return(false);
            }

            ushort disasterId = group.m_ownerInstance.Disaster;

            if (disasterId != disaster)
            {
                return(false);
            }

            SetNameField(panel.GetType(), panel, "m_NameField", newName);
            return(true);
        }
Exemplo n.º 5
0
        public override void SimulationStep(ushort disasterID, ref DisasterData data)
        {
            //Begin Disaster AI SimulationStep
            if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None)
            {
                if (!this.IsStillClearing(disasterID, ref data))
                {
                    this.EndDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                if (!this.IsStillActive(disasterID, ref data))
                {
                    this.DeactivateDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (!this.IsStillEmerging(disasterID, ref data))
                {
                    this.ActivateDisaster(disasterID, ref data);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None)
            {
                if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None)
                {
                    if (data.m_broadcastCooldown > 0)
                    {
                        data.m_broadcastCooldown -= 1;
                    }
                    if (data.m_broadcastCooldown == 0)
                    {
                        data.m_broadcastCooldown = 36;
                        if (this.m_info.m_warningBroadcast != null)
                        {
                            Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast);
                        }
                    }
                }
                else
                {
                    StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount);

                    statisticBase.Add(16);
                    InstanceID id = default(InstanceID);
                    id.Disaster = disasterID;
                    InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                    if (data.m_broadcastCooldown >= 200)
                    {
                        if (data.m_broadcastCooldown > 200)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2))
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    else
                    {
                        if (data.m_broadcastCooldown > 0)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 0)
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    if (group == null || group.m_refCount >= 2)
                    {
                        if (data.m_chirpCooldown > 0)
                        {
                            data.m_chirpCooldown -= 1;
                        }
                        else if (this.m_info.m_prefabDataIndex != -1)
                        {
                            string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex);

                            if (Locale.Exists("CHIRP_DISASTER", key))
                            {
                                string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID);

                                Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName);

                                data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24);
                            }
                        }
                    }
                }
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (this.m_info.m_disasterWarningGuide != null && properties != null)
                {
                    this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)))
            {
                this.StartDisaster(disasterID, ref data);
            }
            //End DisasterAI.Simulation Step
            if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                if (currentFrameIndex + 1755u > data.m_activationFrame)
                {
                    Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false);

                    Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                    Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                    //Begin Edit
                    float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                    Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain;
                    Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                    //End Edit
                    Singleton <WeatherManager> .instance.m_targetCloud = 1f;
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                //Begin Edit
                float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain;
                Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                //End Edit
                Singleton <WeatherManager> .instance.m_targetCloud = 1f;
            }
        }
        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;
                        }
                    }
                }
            }
        }
 [MethodImpl(MethodImplOptions.NoInlining)] //to prevent inlining
 private static void TrySpreadFire(Quad2 quad, float minY, float maxY, ushort buildingID, ref Building buildingData, InstanceManager.Group group)
 {
     //this should never get reached.
     if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled())
     {
         Logger.dbgLog("try spread fire");
     }
 }
        public static void DestroyBuildings(int seed, InstanceManager.Group group, Vector3 position, float preRadius, float removeRadius,
                                            float destructionRadiusMin, float destructionRadiusMax, float burnRadiusMin, float burnRadiusMax, float probability)
        {
            int num  = Mathf.Max((int)((position.x - preRadius - 72f) / 64f + 135f), 0);
            int num2 = Mathf.Max((int)((position.z - preRadius - 72f) / 64f + 135f), 0);
            int num3 = Mathf.Min((int)((position.x + preRadius + 72f) / 64f + 135f), 269);
            int num4 = Mathf.Min((int)((position.z + preRadius + 72f) / 64f + 135f), 269);
            Array16 <Building> buildings = Singleton <BuildingManager> .instance.m_buildings;

            ushort[] buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid;
            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num5 = buildingGrid[i * 270 + j];
                    int    num6 = 0;
                    while (num5 != 0)
                    {
                        ushort         nextGridBuilding = buildings.m_buffer[(int)num5].m_nextGridBuilding;
                        Building.Flags flags            = buildings.m_buffer[(int)num5].m_flags;
                        if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Untouchable | Building.Flags.Demolishing)) == Building.Flags.Created)
                        {
                            Vector3 position2 = buildings.m_buffer[(int)num5].m_position;
                            float   num7      = VectorUtils.LengthXZ(position2 - position);
                            if (num7 < preRadius)
                            {
                                Randomizer randomizer = new Randomizer((int)num5 | seed << 16);
                                float      num8       = (destructionRadiusMax - num7) / Mathf.Max(1f, destructionRadiusMax - destructionRadiusMin);
                                float      num9       = (burnRadiusMax - num7) / Mathf.Max(1f, burnRadiusMax - burnRadiusMin);
                                bool       flag       = false;
                                bool       flag2      = (float)randomizer.Int32(10000u) < num8 * probability * 10000f;
                                bool       flag3      = (float)randomizer.Int32(10000u) < num9 * probability * 10000f;
                                if (removeRadius != 0f && num7 - 72f < removeRadius)
                                {
                                    BuildingInfo info = buildings.m_buffer[(int)num5].Info;
                                    if (info.m_circular)
                                    {
                                        float num10 = (float)(buildings.m_buffer[(int)num5].Width + buildings.m_buffer[(int)num5].Length) * 2f;
                                        flag = (num7 < removeRadius + num10);
                                    }
                                    else
                                    {
                                        float   angle   = buildings.m_buffer[(int)num5].m_angle;
                                        Vector2 a       = VectorUtils.XZ(position2);
                                        Vector2 vector  = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
                                        Vector2 vector2 = new Vector2(vector.y, -vector.x);
                                        vector  *= (float)buildings.m_buffer[(int)num5].Width * 4f;
                                        vector2 *= (float)buildings.m_buffer[(int)num5].Length * 4f;
                                        Quad2 quad = default(Quad2);
                                        quad.a = a - vector - vector2;
                                        quad.b = a + vector - vector2;
                                        quad.c = a + vector + vector2;
                                        quad.d = a - vector + vector2;
                                        float num11 = VectorUtils.LengthXZ(position - new Vector3(quad.a.x, position2.y, quad.a.y));
                                        float num12 = VectorUtils.LengthXZ(position - new Vector3(quad.b.x, position2.y, quad.b.y));
                                        float num13 = VectorUtils.LengthXZ(position - new Vector3(quad.c.x, position2.y, quad.c.y));
                                        float num14 = VectorUtils.LengthXZ(position - new Vector3(quad.d.x, position2.y, quad.d.y));
                                        flag = (quad.Intersect(VectorUtils.XZ(position)) || num11 < removeRadius || num12 < removeRadius || num13 < removeRadius || num14 < removeRadius);
                                    }
                                }
                                if (flag)
                                {
                                    BuildingInfo info2 = buildings.m_buffer[(int)num5].Info;
                                    info2.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, true, Mathf.RoundToInt(num9 * 255f));
                                }
                                else if (flag2)
                                {
                                    BuildingInfo    info3 = buildings.m_buffer[(int)num5].Info;
                                    ItemClass.Level lvl   = (ItemClass.Level)buildings.m_buffer[(int)num5].m_level;

                                    float p = 0.5f;

                                    if (info3.m_buildingAI as OfficeBuildingAI != null || info3.m_buildingAI as CommercialBuildingAI != null || info3.m_buildingAI as IndustrialBuildingAI != null)
                                    {
                                        switch (lvl)
                                        {
                                        case ItemClass.Level.Level1:
                                            p = 1f;
                                            break;

                                        case ItemClass.Level.Level2:
                                            p = 0.6f;
                                            break;

                                        case ItemClass.Level.Level3:
                                            p = 0.2f;
                                            break;
                                        }
                                    }
                                    else if (info3.m_buildingAI as ResidentialBuildingAI != null)
                                    {
                                        switch (lvl)
                                        {
                                        case ItemClass.Level.Level1:
                                            p = 1f;
                                            break;

                                        case ItemClass.Level.Level2:
                                            p = 0.8f;
                                            break;

                                        case ItemClass.Level.Level3:
                                            p = 0.6f;
                                            break;

                                        case ItemClass.Level.Level4:
                                            p = 0.4f;
                                            break;

                                        case ItemClass.Level.Level5:
                                            p = 0.2f;
                                            break;
                                        }
                                    }

                                    // Large buildings are tougher
                                    float s = Mathf.Sqrt(buildings.m_buffer[(int)num5].Length * buildings.m_buffer[(int)num5].Width);
                                    if (s > 4)
                                    {
                                        p -= s / 16;
                                    }

                                    // Make shelters a little more useful
                                    if ((flags & Building.Flags.Evacuating) == Building.Flags.Evacuating)
                                    {
                                        p -= 0.2f;
                                    }

                                    if (p > 0 && (float)randomizer.Int32(10000u) < p * 10000f)
                                    {
                                        //Debug.Log("Destroyed: " + info3.name + " (" + info3.m_buildingAI.name + "), level: " + lvl.ToString());
                                        info3.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, false, Mathf.RoundToInt(num9 * 255f));
                                    }
                                }
                                else if (flag3 && (flags & Building.Flags.Collapsed) == Building.Flags.None && buildings.m_buffer[(int)num5].m_fireIntensity == 0)
                                {
                                    BuildingInfo info4 = buildings.m_buffer[(int)num5].Info;
                                    info4.m_buildingAI.BurnBuilding(num5, ref buildings.m_buffer[(int)num5], group, false);
                                }
                            }
                        }
                        num5 = nextGridBuilding;
                        if (++num6 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        public override void SimulationStep(ushort disasterID, ref DisasterData data)
        {
            //Begin Disaster AI SimulationStep
            if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None)
            {
                if (!this.IsStillClearing(disasterID, ref data))
                {
                    this.EndDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                if (!this.IsStillActive(disasterID, ref data))
                {
                    this.DeactivateDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (!this.IsStillEmerging(disasterID, ref data))
                {
                    this.ActivateDisaster(disasterID, ref data);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None)
            {
                if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None)
                {
                    if (data.m_broadcastCooldown > 0)
                    {
                        data.m_broadcastCooldown -= 1;
                    }
                    if (data.m_broadcastCooldown == 0)
                    {
                        data.m_broadcastCooldown = 36;
                        if (this.m_info.m_warningBroadcast != null)
                        {
                            Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast);
                        }
                    }
                }
                else
                {
                    StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount);

                    statisticBase.Add(16);
                    InstanceID id = default(InstanceID);
                    id.Disaster = disasterID;
                    InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                    if (data.m_broadcastCooldown >= 200)
                    {
                        if (data.m_broadcastCooldown > 200)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2))
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    else
                    {
                        if (data.m_broadcastCooldown > 0)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 0)
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    if (group == null || group.m_refCount >= 2)
                    {
                        if (data.m_chirpCooldown > 0)
                        {
                            data.m_chirpCooldown -= 1;
                        }
                        else if (this.m_info.m_prefabDataIndex != -1)
                        {
                            string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex);

                            if (Locale.Exists("CHIRP_DISASTER", key))
                            {
                                string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID);

                                Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName);

                                data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24);
                            }
                        }
                    }
                }
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (this.m_info.m_disasterWarningGuide != null && properties != null)
                {
                    this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)))
            {
                this.StartDisaster(disasterID, ref data);
            }
            //End DisasterAI.Simulation Step
            if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (data.m_activationFrame != 0u)
                {
                    uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    if (currentFrameIndex + 1755u >= data.m_activationFrame)
                    {
                        if ((data.m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None)
                        {
                            Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false);
                        }
                        if ((data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None)
                        {
                            Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                            Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                            //Begin Edit
                            float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                            Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain;
                            Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                            Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain;
                            //end edit
                        }
                    }
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None && (data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None)
            {
                Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                //Begin Edit
                float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain;
                Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain;
                //end edit
                uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                int  num = 100;
                num = Mathf.Min(num, (int)(currentFrameIndex2 - data.m_activationFrame >> 3));
                num = Mathf.Min(num, (int)(data.m_activationFrame + this.m_activeDuration - currentFrameIndex2 >> 3));
                num = (num * (int)data.m_intensity + 50) / 100;
                Randomizer randomizer = new Randomizer(data.m_randomSeed ^ (ulong)(currentFrameIndex2 >> 8));
                int        num2       = randomizer.Int32(Mathf.Max(1, num / 20), Mathf.Max(1, 1 + num / 10));
                float      num3       = this.m_radius * (0.25f + (float)data.m_intensity * 0.0075f);
                InstanceID id         = default(InstanceID);
                id.Disaster = disasterID;
                InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                for (int i = 0; i < num2; i++)
                {
                    float   f              = (float)randomizer.Int32(10000u) * 0.0006283185f;
                    float   num4           = Mathf.Sqrt((float)randomizer.Int32(10000u) * 0.0001f) * num3;
                    uint    startFrame     = currentFrameIndex2 + randomizer.UInt32(256u);
                    Vector3 targetPosition = data.m_targetPosition;
                    targetPosition.x += Mathf.Cos(f) * num4;
                    targetPosition.z += Mathf.Sin(f) * num4;
                    targetPosition.y  = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(targetPosition, false, 0f);

                    Quaternion quaternion = Quaternion.AngleAxis((float)randomizer.Int32(360u), Vector3.up);
                    quaternion *= Quaternion.AngleAxis((float)randomizer.Int32(-15, 15), Vector3.right);
                    Singleton <WeatherManager> .instance.QueueLightningStrike(startFrame, targetPosition, quaternion, group);
                }
            }
        }
Exemplo n.º 10
0
        new protected int HandleCommonConsumption(ushort buildingID, ref Building data, ref Building.Frame frameData, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies)
        {
            int             num      = 100;
            DistrictManager instance = Singleton <DistrictManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating);
            bool flag             = data.m_electricityProblemTimer != 0;
            bool flag2            = false;
            bool flag3            = false;
            int  electricityUsage = 0;
            int  heatingUsage     = 0;
            int  waterUsage       = 0;
            int  sewageUsage      = 0;

            if (electricityConsumption != 0)
            {
                int num2 = Mathf.RoundToInt((20f - Singleton <WeatherManager> .instance.SampleTemperature(data.m_position, false)) * 8f);
                num2 = Mathf.Clamp(num2, 0, 400);
                int num3 = heatingConsumption;
                heatingConsumption = (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                if ((policies & DistrictPolicies.Services.PowerSaving) != DistrictPolicies.Services.None)
                {
                    electricityConsumption = Mathf.Max(1, electricityConsumption * 90 / 100);
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                bool flag4 = false;
                int  num4  = heatingConsumption * 2 - (int)data.m_heatingBuffer;
                if (num4 > 0 && (policies & DistrictPolicies.Services.OnlyElectricity) == DistrictPolicies.Services.None)
                {
                    int num5 = Singleton <WaterManager> .instance.TryFetchHeating(data.m_position, heatingConsumption, num4, out flag4);

                    data.m_heatingBuffer += (ushort)num5;
                }
                if ((int)data.m_heatingBuffer < heatingConsumption)
                {
                    if ((policies & DistrictPolicies.Services.NoElectricity) != DistrictPolicies.Services.None)
                    {
                        flag3 = true;
                        data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                        if (data.m_heatingProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_heatingProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                        }
                    }
                    else
                    {
                        num2 = ((num2 + 50) * (heatingConsumption - (int)data.m_heatingBuffer) + heatingConsumption - 1) / heatingConsumption;
                        electricityConsumption += (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                        if (flag4)
                        {
                            flag3 = true;
                            data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                            if (data.m_heatingProblemTimer >= 3)
                            {
                                problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                            }
                        }
                    }
                    heatingUsage         = (int)data.m_heatingBuffer;
                    data.m_heatingBuffer = 0;
                }
                else
                {
                    heatingUsage          = heatingConsumption;
                    data.m_heatingBuffer -= (ushort)heatingConsumption;
                }
                int num6;
                int a;
                if (this.CanStockpileElectricity(buildingID, ref data, out num6, out a))
                {
                    num4 = num6 + electricityConsumption * 2 - (int)data.m_electricityBuffer;
                    if (num4 > 0)
                    {
                        int num7 = electricityConsumption;
                        if ((int)data.m_electricityBuffer < num6)
                        {
                            num7 += Mathf.Min(a, num6 - (int)data.m_electricityBuffer);
                        }
                        int num8 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, num7, num4);

                        data.m_electricityBuffer += (ushort)num8;
                        if (num8 < num4 && num8 < num7)
                        {
                            flag2   = true;
                            problem = Notification.AddProblems(problem, Notification.Problem.Electricity);
                            if (data.m_electricityProblemTimer < 64)
                            {
                                data.m_electricityProblemTimer = 64;
                            }
                        }
                    }
                }
                else
                {
                    num4 = electricityConsumption * 2 - (int)data.m_electricityBuffer;
                    if (num4 > 0)
                    {
                        int num9 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, electricityConsumption, num4);

                        data.m_electricityBuffer += (ushort)num9;
                    }
                }
                if ((int)data.m_electricityBuffer < electricityConsumption)
                {
                    flag2 = true;
                    data.m_electricityProblemTimer = (byte)Mathf.Min(255, (int)(data.m_electricityProblemTimer + 1));
                    if (data.m_electricityProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_electricityProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity);
                    }
                    electricityUsage         = (int)data.m_electricityBuffer;
                    data.m_electricityBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Electricity))
                    {
                        GuideController properties = Singleton <GuideManager> .instance.m_properties;
                        if (properties != null)
                        {
                            int publicServiceIndex      = ItemClass.GetPublicServiceIndex(ItemClass.Service.Electricity);
                            int electricityCapacity     = instance.m_districts.m_buffer[0].GetElectricityCapacity();
                            int electricityConsumption2 = instance.m_districts.m_buffer[0].GetElectricityConsumption();
                            if (electricityCapacity >= electricityConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded2, ItemClass.Service.Electricity);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded, ItemClass.Service.Electricity);
                            }
                        }
                    }
                }
                else
                {
                    electricityUsage          = electricityConsumption;
                    data.m_electricityBuffer -= (ushort)electricityConsumption;
                }
            }
            else
            {
                heatingConsumption = 0;
            }
            if (!flag2)
            {
                data.m_electricityProblemTimer = 0;
            }
            if (flag != flag2)
            {
                Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID);
            }
            if (!flag3)
            {
                data.m_heatingProblemTimer = 0;
            }
            bool flag5 = false;
            int  num10 = sewageAccumulation;

            if (waterConsumption != 0)
            {
                if ((policies & DistrictPolicies.Services.WaterSaving) != DistrictPolicies.Services.None)
                {
                    waterConsumption = Mathf.Max(1, waterConsumption * 85 / 100);
                    if (sewageAccumulation != 0)
                    {
                        sewageAccumulation = Mathf.Max(1, sewageAccumulation * 85 / 100);
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                int num11;
                int a2;
                if (this.CanStockpileWater(buildingID, ref data, out num11, out a2))
                {
                    int num12 = num11 + waterConsumption * 2 - (int)data.m_waterBuffer;
                    if (num12 > 0)
                    {
                        int num13 = waterConsumption;
                        if ((int)data.m_waterBuffer < num11)
                        {
                            num13 += Mathf.Min(a2, num11 - (int)data.m_waterBuffer);
                        }
                        int num14 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, num13, num12, ref data.m_waterPollution);

                        data.m_waterBuffer += (ushort)num14;
                        if (num14 < num12 && num14 < num13)
                        {
                            flag5   = true;
                            problem = Notification.AddProblems(problem, Notification.Problem.Water);
                            if (data.m_waterProblemTimer < 64)
                            {
                                data.m_waterProblemTimer = 64;
                            }
                        }
                    }
                }
                else
                {
                    int num15 = waterConsumption * 2 - (int)data.m_waterBuffer;
                    if (num15 > 0)
                    {
                        int num16 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, waterConsumption, num15, ref data.m_waterPollution);

                        data.m_waterBuffer += (ushort)num16;
                    }
                }
                if ((int)data.m_waterBuffer < waterConsumption)
                {
                    flag5 = true;
                    data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                    if (data.m_waterProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_waterProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water);
                    }
                    num10              = sewageAccumulation * (waterConsumption + (int)data.m_waterBuffer) / (waterConsumption << 1);
                    waterUsage         = (int)data.m_waterBuffer;
                    data.m_waterBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Water))
                    {
                        GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                        if (properties2 != null)
                        {
                            int publicServiceIndex2 = ItemClass.GetPublicServiceIndex(ItemClass.Service.Water);
                            int waterCapacity       = instance.m_districts.m_buffer[0].GetWaterCapacity();
                            int waterConsumption2   = instance.m_districts.m_buffer[0].GetWaterConsumption();
                            if (waterCapacity >= waterConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded2, ItemClass.Service.Water);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded, ItemClass.Service.Water);
                            }
                        }
                    }
                }
                else
                {
                    num10               = sewageAccumulation;
                    waterUsage          = waterConsumption;
                    data.m_waterBuffer -= (ushort)waterConsumption;
                }
            }
            int num17;
            int b;

            if (this.CanStockpileWater(buildingID, ref data, out num17, out b))
            {
                int num18 = Mathf.Max(0, num17 + num10 * 2 - (int)data.m_sewageBuffer);
                if (num18 < num10)
                {
                    if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5 = true;
                        data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                        if (data.m_waterProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_waterProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        }
                    }
                    sewageUsage         = num18;
                    data.m_sewageBuffer = (ushort)(num17 + num10 * 2);
                }
                else
                {
                    sewageUsage          = num10;
                    data.m_sewageBuffer += (ushort)num10;
                }
                int num19 = num10 + Mathf.Max(num10, b);
                num18 = Mathf.Min(num19, (int)data.m_sewageBuffer);
                if (num18 > 0)
                {
                    int num20 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num19, num18);

                    data.m_sewageBuffer -= (ushort)num20;
                    if (num20 < num19 && num20 < num18 && !flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5   = true;
                        problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        if (data.m_waterProblemTimer < 64)
                        {
                            data.m_waterProblemTimer = 64;
                        }
                    }
                }
            }
            else if (num10 != 0)
            {
                int num21 = Mathf.Max(0, num10 * 2 - (int)data.m_sewageBuffer);
                if (num21 < num10)
                {
                    if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5 = true;
                        data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                        if (data.m_waterProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_waterProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        }
                    }
                    sewageUsage         = num21;
                    data.m_sewageBuffer = (ushort)(num10 * 2);
                }
                else
                {
                    sewageUsage          = num10;
                    data.m_sewageBuffer += (ushort)num10;
                }
                num21 = Mathf.Min(num10 * 2, (int)data.m_sewageBuffer);
                if (num21 > 0)
                {
                    int num22 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num10 * 2, num21);

                    data.m_sewageBuffer -= (ushort)num22;
                }
            }
            if (!flag5)
            {
                data.m_waterProblemTimer = 0;
            }
            if (garbageAccumulation != 0)
            {
                int num23 = (int)(65535 - data.m_garbageBuffer);
                if (num23 < garbageAccumulation)
                {
                    num = 0;
                    data.m_garbageBuffer = (ushort)num23;
                }
                else
                {
                    //start edit
                    StormDrainAI stormDrainAI = data.Info.m_buildingAI as StormDrainAI;
                    if (stormDrainAI == null)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else if (stormDrainAI.m_filter == false)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else
                    {
                        int pollutantAccumulation = Hydraulics.removePollutants(buildingID, Hydraulics.getPollutants(buildingID));
                        data.m_garbageBuffer += (ushort)pollutantAccumulation;
                        //Debug.Log("[RF]CommonBuildingAI.handleCommonConsumption garbagebuffer = " + data.m_garbageBuffer.ToString());
                    }
                    //end edit
                }
            }
            if (garbageAccumulation != 0)
            {
                int num24 = (int)data.m_garbageBuffer;
                if (num24 >= 200 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0 && Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Garbage))
                {
                    int num25 = 0;
                    int num26 = 0;
                    int num27 = 0;
                    int num28 = 0;
                    this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Garbage, ref num25, ref num26, ref num27, ref num28);
                    num24 -= num27 - num26;
                    if (num24 >= 200)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = num24 / 1000;
                        offer.Building = buildingID;
                        offer.Position = data.m_position;
                        offer.Amount   = 1;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Garbage, offer);
                    }
                }
            }
            bool flag6;

            if (this.CanSufferFromFlood(out flag6))
            {
                float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(data.m_position));

                if (num29 > data.m_position.y)
                {
                    bool flag7 = num29 > data.m_position.y + Mathf.Max(4f, this.m_info.m_collisionHeight);
                    if ((!flag6 || flag7) && (data.m_flags & Building.Flags.Flooded) == Building.Flags.None && data.m_fireIntensity == 0)
                    {
                        DisasterManager instance2 = Singleton <DisasterManager> .instance;
                        ushort          num30     = instance2.FindDisaster <FloodBaseAI>(data.m_position);
                        if (num30 == 0)
                        {
                            DisasterInfo disasterInfo = DisasterManager.FindDisasterInfo <GenericFloodAI>();
                            if (disasterInfo != null && instance2.CreateDisaster(out num30, disasterInfo))
                            {
                                instance2.m_disasters.m_buffer[(int)num30].m_intensity      = 10;
                                instance2.m_disasters.m_buffer[(int)num30].m_targetPosition = data.m_position;
                                disasterInfo.m_disasterAI.StartNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]);
                            }
                        }
                        if (num30 != 0)
                        {
                            InstanceID srcID = default(InstanceID);
                            InstanceID dstID = default(InstanceID);
                            srcID.Disaster = num30;
                            dstID.Building = buildingID;
                            Singleton <InstanceManager> .instance.CopyGroup(srcID, dstID);

                            DisasterInfo info = instance2.m_disasters.m_buffer[(int)num30].Info;
                            info.m_disasterAI.ActivateNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]);
                            if ((instance2.m_disasters.m_buffer[(int)num30].m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None)
                            {
                                instance2.DetectDisaster(num30, false);
                                instance2.FollowDisaster(num30);
                            }
                        }
                        data.m_flags |= Building.Flags.Flooded;
                    }
                    if (flag7)
                    {
                        frameData.m_constructState = (byte)Mathf.Max(0, (int)frameData.m_constructState - 1088 / this.GetCollapseTime());
                        data.SetFrameData(Singleton <SimulationManager> .instance.m_currentFrameIndex, frameData);
                        InstanceID id = default(InstanceID);
                        id.Building = buildingID;
                        InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                        if (group != null)
                        {
                            ushort disaster = group.m_ownerInstance.Disaster;
                            if (disaster != 0)
                            {
                                DisasterData[] expr_D18_cp_0 = Singleton <DisasterManager> .instance.m_disasters.m_buffer;
                                ushort         expr_D18_cp_1 = disaster;
                                expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount = (ushort)(expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount + 1);
                            }
                        }
                        if (frameData.m_constructState == 0)
                        {
                            Singleton <InstanceManager> .instance.SetGroup(id, null);
                        }
                        data.m_levelUpProgress = 0;
                        data.m_fireIntensity   = 0;
                        data.m_garbageBuffer   = 0;
                        data.m_flags          |= Building.Flags.Collapsed;
                        num = 0;
                        this.RemovePeople(buildingID, ref data, 90);
                        this.BuildingDeactivated(buildingID, ref data);
                        if (this.m_info.m_hasParkingSpaces != VehicleInfo.VehicleType.None)
                        {
                            Singleton <BuildingManager> .instance.UpdateParkingSpaces(buildingID, ref data);
                        }
                        Singleton <BuildingManager> .instance.UpdateBuildingRenderer(buildingID, true);

                        Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID);

                        GuideController properties3 = Singleton <GuideManager> .instance.m_properties;
                        if (properties3 != null)
                        {
                            Singleton <BuildingManager> .instance.m_buildingFlooded.Deactivate(buildingID, false);

                            Singleton <BuildingManager> .instance.m_buildingFlooded2.Deactivate(buildingID, false);
                        }
                    }
                    else if (!flag6)
                    {
                        if ((data.m_flags & Building.Flags.RoadAccessFailed) == Building.Flags.None)
                        {
                            int num31 = 0;
                            int num32 = 0;
                            int num33 = 0;
                            int num34 = 0;
                            this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.FloodWater, ref num31, ref num32, ref num33, ref num34);
                            if (num31 == 0)
                            {
                                TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                                offer2.Priority = 5;
                                offer2.Building = buildingID;
                                offer2.Position = data.m_position;
                                offer2.Amount   = 1;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.FloodWater, offer2);
                            }
                        }
                        if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodedTolerance / 100f)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                        }
                        else if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodingTolerance / 100f)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                        }
                        GuideController properties4 = Singleton <GuideManager> .instance.m_properties;
                        if (properties4 != null)
                        {
                            if (Singleton <LoadingManager> .instance.SupportsExpansion(Expansion.NaturalDisasters) && Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.WaterPumping))
                            {
                                Singleton <BuildingManager> .instance.m_buildingFlooded2.Activate(properties4.m_buildingFlooded2, buildingID);
                            }
                            else
                            {
                                Singleton <BuildingManager> .instance.m_buildingFlooded.Activate(properties4.m_buildingFlooded, buildingID);
                            }
                        }
                    }
                }
                else if ((data.m_flags & Building.Flags.Flooded) != Building.Flags.None)
                {
                    InstanceID id2 = default(InstanceID);
                    id2.Building = buildingID;
                    Singleton <InstanceManager> .instance.SetGroup(id2, null);

                    data.m_flags &= ~Building.Flags.Flooded;
                }
            }
            byte district = instance.GetDistrict(data.m_position);

            instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage);
            data.m_problems = problem;
            return(num);
        }
Exemplo n.º 11
0
        public static bool BurnTree(TreeManager tm, uint treeIndex, InstanceManager.Group group, int fireIntensity)
        {
            unsafe
            {
                //TreeManager tm = Singleton<TreeManager>.instance; see above {this} is passed in bydefault by .net as secret first param.
                TreeManager.BurningTree burningTree = new TreeManager.BurningTree();
                //if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL > 1)
                //{ Logger.dbgLog("request to burn tree: " + treeIndex.ToString() ); }
                if (treeIndex == 0 || (tm.m_trees.m_buffer[treeIndex].m_flags & 64) != 0)
                {
                    return(false);
                }
                if (!Singleton <LoadingManager> .instance.SupportsExpansion(Expansion.NaturalDisasters))
                {
                    return(false);
                }
                TreeFireControl_Loader.FireStats.totalburncalls++;
                //our additions
                if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL > 2)
                {
                    Logger.dbgLog(string.Format("ratetree:{0} ratedistree:{1} fireIntensity:{2}", Mod.config.TreeFireSpreadRate.ToString(), Mod.config.TreeFireDisasterSpreadRate.ToString(), fireIntensity.ToString()));
                }


                if (group != null)
                {
                    ushort disaster = group.m_ownerInstance.Disaster;
                    if (disaster != 0)
                    {
                        if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL > 2)
                        {
                            Logger.dbgLog("burn req is connected to disaster");
                        }
                        TreeFireControl_Loader.FireStats.totalburncallsdisaster++;
                        if (TreeFireControl.TFCTreeManager.Utils.ShouldWeBurnit(ref group, Mod.config.TreeFireDisasterSpreadRate))
                        {
                            //do nothing == burn tree. and count it toward disaster.
                            Singleton <DisasterManager> .instance.m_disasters.m_buffer[disaster].m_treeFireCount = Singleton <DisasterManager> .instance.m_disasters.m_buffer[disaster].m_treeFireCount + 1;
                            //end org
                        }
                        else
                        {
                            //retruned false - block the burn call.
                            TreeFireControl_Loader.FireStats.totalburncallsblockeddisaster++;
                            return(false);
                        }
                    }
                    else //Was not null but not a valid disaster id. handle like normal.
                    {
                        if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL > 2)
                        {
                            Logger.dbgLog("burn req is *not* connected to disaster.");
                        }
                        TreeFireControl_Loader.FireStats.totalburncallsnormal++;
                        if (!TreeFireControl.TFCTreeManager.Utils.ShouldWeBurnit(ref group, Mod.config.TreeFireSpreadRate))
                        {
                            TreeFireControl_Loader.FireStats.totalburncallsblockednormal++;
                            return(false); //no burning. //else let it continue and burn the tree
                        }
                    }
                }
                else //not tied to disasters.
                {
                    if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL > 2)
                    {
                        Logger.dbgLog("burn req is *not* connected to disaster. group null");
                    }
                    TreeFireControl_Loader.FireStats.totalburncallsnormal++;
                    if (!TreeFireControl.TFCTreeManager.Utils.ShouldWeBurnit(ref group, Mod.config.TreeFireSpreadRate))
                    {
                        TreeFireControl_Loader.FireStats.totalburncallsblockednormal++;
                        return(false); //no burning. //else let it continue
                    }
                    //burnlog;
                }

                //cont org
                burningTree.m_treeIndex     = treeIndex;
                burningTree.m_fireIntensity = (byte)fireIntensity;
                burningTree.m_fireDamage    = 4;
                InstanceID instanceID = new InstanceID()
                {
                    Tree = treeIndex
                };
                Singleton <InstanceManager> .instance.SetGroup(instanceID, group);

                tm.m_trees.m_buffer[treeIndex].m_flags = (ushort)(tm.m_trees.m_buffer[treeIndex].m_flags | 192);
                tm.m_burningTrees.Add(burningTree);
                return(true);
            }
        }