Пример #1
0
        void PhysicsTick()
        {
            lastCheck = ListCheck.Count;
            const uint mask = PhysicsArgs.TypeMask;

            HandlePhysics[]  handlers     = PhysicsHandlers;
            ExtraInfoHandler extraHandler = ExtraInfoPhysics.normalHandler;

            if (physics == 5)
            {
                handlers     = physicsDoorsHandlers;
                extraHandler = ExtraInfoPhysics.doorsHandler;
            }

            PhysInfo C;

            for (int i = 0; i < ListCheck.Count; i++)
            {
                Check chk = ListCheck.Items[i];
                IntToPos(chk.Index, out C.X, out C.Y, out C.Z);
                C.Index = chk.Index; C.Data = chk.data;

                try {
                    if (OnPhysicsUpdateEvent.handlers.Count > 0)
                    {
                        OnPhysicsUpdateEvent.Call(C.X, C.Y, C.Z, C.Data, this);
                    }

                    C.Block = blocks[chk.Index];
                    #if TEN_BIT_BLOCKS
                    BlockID extended = Block.ExtendedBase[C.Block];
                    if (extended > 0)
                    {
                        C.Block = (BlockID)(extended | FastGetExtTile(C.X, C.Y, C.Z));
                    }
                    #else
                    if (C.Block == Block.custom_block)
                    {
                        C.Block = (BlockID)(Block.Extended | FastGetExtTile(C.X, C.Y, C.Z));
                    }
                    #endif

                    if ((C.Data.Raw & mask) == 0 || C.Data.Type1 == PhysicsArgs.Custom || extraHandler(this, ref C))
                    {
                        HandlePhysics handler = handlers[C.Block];
                        if (handler != null)
                        {
                            handler(this, ref C);
                        }
                        else if ((C.Data.Raw & mask) == 0 || !C.Data.HasWait)
                        {
                            C.Data.Data = PhysicsArgs.RemoveFromChecks;
                        }
                    }

                    ListCheck.Items[i].data = C.Data;
                } catch {
                    listCheckExists.Set(C.X, C.Y, C.Z, false);
                    ListCheck.RemoveAt(i);
                }
            }
            RemoveExpiredChecks();

            lastUpdate = ListUpdate.Count;
            if (ListUpdate.Count > 0 && bulkSender == null)
            {
                bulkSender = new BufferedBlockSender(this);
            }

            for (int i = 0; i < ListUpdate.Count; i++)
            {
                Update U = ListUpdate.Items[i];
                try {
                    BlockID block = U.data.Data;
                    U.data.Data = 0;

                    // Is the Ext flag just an indicator for the block update?
                    byte extBits = U.data.ExtBlock;
                    if (extBits != 0 && (U.data.Raw & PhysicsArgs.TypeMask) == 0)
                    {
                        block      |= (BlockID)(extBits << Block.ExtendedShift);
                        U.data.Raw &= ~PhysicsArgs.ExtBits;
                    }

                    if (DoPhysicsBlockchange(U.Index, block, false, U.data, true))
                    {
                        bulkSender.Add(U.Index, block);
                    }
                } catch {
                    Logger.Log(LogType.Warning, "Phys update issue");
                }
            }

            if (bulkSender != null)
            {
                bulkSender.Flush();
            }
            ListUpdate.Clear(); listUpdateExists.Clear();
        }
Пример #2
0
        public void CalcPhysics()
        {
            ushort x, y, z;

            lastCheck = ListCheck.Count;
            const uint mask = PhysicsArgs.TypeMask;

            HandlePhysics[]  handlers     = BlockBehaviour.physicsHandlers;
            ExtraInfoHandler extraHandler = ExtraInfoPhysics.DoNormal;

            if (physics == 5)
            {
                handlers     = BlockBehaviour.physicsDoorsHandlers;
                extraHandler = ExtraInfoPhysics.DoDoorsOnly;
            }

            for (int i = 0; i < ListCheck.Count; i++)
            {
                Check C = ListCheck.Items[i];
                IntToPos(C.b, out x, out y, out z);
                try {
                    if (PhysicsUpdate != null)
                    {
                        PhysicsUpdate(x, y, z, C.data, this);
                    }
                    OnPhysicsUpdateEvent.Call(x, y, z, C.data, this);
                    if ((C.data.Raw & mask) == 0 || extraHandler(this, ref C))
                    {
                        HandlePhysics handler = handlers[blocks[C.b]];
                        if (handler != null)
                        {
                            handler(this, ref C);
                        }
                        else if ((C.data.Raw & mask) == 0 || !C.data.HasWait)
                        {
                            C.data.Data = PhysicsArgs.RemoveFromChecks;
                        }
                    }
                    ListCheck.Items[i] = C;
                } catch {
                    listCheckExists.Set(x, y, z, false);
                    ListCheck.RemoveAt(i);
                }
            }
            RemoveExpiredChecks();

            lastUpdate = ListUpdate.Count;
            if (ListUpdate.Count > 0 && bulkSender == null)
            {
                bulkSender = new BufferedBlockSender(this);
            }

            for (int i = 0; i < ListUpdate.Count; i++)
            {
                Update C = ListUpdate.Items[i];
                try {
                    byte block = C.data.Data, extBlock = 0;
                    C.data.Data = 0;
                    // Is the Ext flag just an indicator for the block update?
                    if (C.data.ExtBlock && (C.data.Raw & PhysicsArgs.TypeMask) == 0)
                    {
                        extBlock        = block; block = Block.custom_block;
                        C.data.ExtBlock = false;
                    }

                    if (DoPhysicsBlockchange(C.b, block, false, C.data, extBlock, true))
                    {
                        bulkSender.Add(C.b, block, extBlock);
                    }
                } catch {
                    Server.s.Log("Phys update issue");
                }
            }

            if (bulkSender != null)
            {
                bulkSender.Send(true);
            }
            ListUpdate.Clear(); listUpdateExists.Clear();
        }
Пример #3
0
        /// <summary> Retrieves the default physics block handler for the given block. </summary>
        internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props)
        {
            switch (block)
            {
            case Block.Door_Log_air:   return(DoorPhysics.Do);

            case Block.Door_TNT_air:   return(DoorPhysics.Do);

            case Block.Door_Green_air: return(DoorPhysics.Do);

            case Block.SnakeTail: return(SnakePhysics.DoTail);

            case Block.Snake: return(SnakePhysics.Do);

            case Block.RocketHead: return(RocketPhysics.Do);

            case Block.Fireworks: return(FireworkPhysics.Do);

            case Block.ZombieBody: return(ZombiePhysics.Do);

            case Block.ZombieHead: return(ZombiePhysics.DoHead);

            case Block.Creeper: return(ZombiePhysics.Do);

            case Block.Water: return(SimpleLiquidPhysics.DoWater);

            case Block.Deadly_ActiveWater: return(SimpleLiquidPhysics.DoWater);

            case Block.Lava: return(SimpleLiquidPhysics.DoLava);

            case Block.Deadly_ActiveLava: return(SimpleLiquidPhysics.DoLava);

            case Block.WaterDown: return(ExtLiquidPhysics.DoWaterfall);

            case Block.LavaDown: return(ExtLiquidPhysics.DoLavafall);

            case Block.WaterFaucet: return((Level lvl, ref PhysInfo C) =>
                                           ExtLiquidPhysics.DoFaucet(lvl, ref C, Block.WaterDown));

            case Block.LavaFaucet: return((Level lvl, ref PhysInfo C) =>
                                          ExtLiquidPhysics.DoFaucet(lvl, ref C, Block.LavaDown));

            case Block.FiniteWater: return(FinitePhysics.DoWaterOrLava);

            case Block.FiniteLava: return(FinitePhysics.DoWaterOrLava);

            case Block.FiniteFaucet: return(FinitePhysics.DoFaucet);

            case Block.Magma: return(ExtLiquidPhysics.DoMagma);

            case Block.Geyser: return(ExtLiquidPhysics.DoGeyser);

            case Block.FastLava: return(SimpleLiquidPhysics.DoFastLava);

            case Block.Deadly_FastLava: return(SimpleLiquidPhysics.DoFastLava);

            case Block.Air: return(AirPhysics.DoAir);

            case Block.Leaves: return(LeafPhysics.DoLeaf);

            case Block.Sapling: return(OtherPhysics.DoShrub);

            case Block.Fire: return(FirePhysics.Do);

            case Block.LavaFire: return(FirePhysics.Do);

            case Block.Sand: return(OtherPhysics.DoFalling);

            case Block.Gravel: return(OtherPhysics.DoFalling);

            case Block.FloatWood: return(OtherPhysics.DoFloatwood);

            case Block.Sponge: return((Level lvl, ref PhysInfo C) =>
                                      OtherPhysics.DoSponge(lvl, ref C, false));

            case Block.LavaSponge: return((Level lvl, ref PhysInfo C) =>
                                          OtherPhysics.DoSponge(lvl, ref C, true));

            // Special blocks that are not saved
            case Block.Air_Flood: return((Level lvl, ref PhysInfo C) =>
                                         AirPhysics.DoFlood(lvl, ref C, AirFlood.Full, Block.Air_Flood));

            case Block.Air_FloodLayer: return((Level lvl, ref PhysInfo C) =>
                                              AirPhysics.DoFlood(lvl, ref C, AirFlood.Layer, Block.Air_FloodLayer));

            case Block.Air_FloodDown: return((Level lvl, ref PhysInfo C) =>
                                             AirPhysics.DoFlood(lvl, ref C, AirFlood.Down, Block.Air_FloodDown));

            case Block.Air_FloodUp: return((Level lvl, ref PhysInfo C) =>
                                           AirPhysics.DoFlood(lvl, ref C, AirFlood.Up, Block.Air_FloodUp));

            case Block.TNT_Small: return(TntPhysics.DoSmallTnt);

            case Block.TNT_Big: return(TntPhysics.DoBigTnt);

            case Block.TNT_Nuke: return(TntPhysics.DoNukeTnt);

            case Block.TNT_Explosion: return(TntPhysics.DoTntExplosion);

            case Block.Train: return(TrainPhysics.Do);
            }

            HandlePhysics animalAI = AnimalAIHandler(props[block].AnimalAI);

            if (animalAI != null)
            {
                return(animalAI);
            }
            if (props[block].oDoorBlock != Block.Invalid)
            {
                return(DoorPhysics.oDoor);
            }
            if (props[block].GrassBlock != Block.Invalid)
            {
                return(OtherPhysics.DoDirtGrow);
            }
            if (props[block].DirtBlock != Block.Invalid)
            {
                return(OtherPhysics.DoGrassDie);
            }

            // TODO: should this be checking WaterKills/LavaKills
            // Adv physics updating anything placed next to water or lava
            if ((block >= Block.Red && block <= Block.RedMushroom) || block == Block.Wood || block == Block.Log || block == Block.Bookshelf)
            {
                return(OtherPhysics.DoOther);
            }
            return(null);
        }
Пример #4
0
        public void CalcPhysics()
        {
            ushort x, y, z;

            lastCheck = ListCheck.Count;
            const uint mask = PhysicsArgs.TypeMask;

            HandlePhysics[]  handlers     = physicsHandlers;
            ExtraInfoHandler extraHandler = ExtraInfoPhysics.DoNormal;

            if (physics == 5)
            {
                handlers     = physicsDoorsHandlers;
                extraHandler = ExtraInfoPhysics.DoDoorsOnly;
            }

            for (int i = 0; i < ListCheck.Count; i++)
            {
                Check C = ListCheck.Items[i];
                IntToPos(C.b, out x, out y, out z);
                try {
                    if (OnPhysicsUpdateEvent.handlers.Count > 0)
                    {
                        OnPhysicsUpdateEvent.Call(x, y, z, C.data, this);
                    }

                    if ((C.data.Raw & mask) == 0 || extraHandler(this, ref C))
                    {
                        int idx = blocks[C.b];
                        if (idx == Block.custom_block)
                        {
                            idx = Block.Count + GetExtTileNoCheck(x, y, z);
                        }

                        HandlePhysics handler = handlers[idx];
                        if (handler != null)
                        {
                            handler(this, ref C);
                        }
                        else if ((C.data.Raw & mask) == 0 || !C.data.HasWait)
                        {
                            C.data.Data = PhysicsArgs.RemoveFromChecks;
                        }
                    }
                    ListCheck.Items[i] = C;
                } catch {
                    listCheckExists.Set(x, y, z, false);
                    ListCheck.RemoveAt(i);
                }
            }
            RemoveExpiredChecks();

            lastUpdate = ListUpdate.Count;
            if (ListUpdate.Count > 0 && bulkSender == null)
            {
                bulkSender = new BufferedBlockSender(this);
            }

            ExtBlock block;

            for (int i = 0; i < ListUpdate.Count; i++)
            {
                Update C = ListUpdate.Items[i];
                try {
                    block.BlockID = C.data.Data;
                    block.ExtID   = 0;
                    C.data.Data   = 0;
                    // Is the Ext flag just an indicator for the block update?
                    if (C.data.ExtBlock && (C.data.Raw & PhysicsArgs.TypeMask) == 0)
                    {
                        block.ExtID     = block.BlockID;
                        block.BlockID   = Block.custom_block;
                        C.data.ExtBlock = false;
                    }

                    if (DoPhysicsBlockchange(C.b, block, false, C.data, true))
                    {
                        bulkSender.Add(C.b, block.BlockID, block.ExtID);
                    }
                } catch {
                    Logger.Log(LogType.Warning, "Phys update issue");
                }
            }

            if (bulkSender != null)
            {
                bulkSender.Send(true);
            }
            ListUpdate.Clear(); listUpdateExists.Clear();
        }