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(); }
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(); }
/// <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); }
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(); }