From 7b42204b245e558c0f0d330acd5a642582dd7991 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 7 Oct 2012 10:08:57 +0000 Subject: All blockticking is now done in cBlockHandlers git-svn-id: http://mc-server.googlecode.com/svn/trunk@942 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2008/MCServer.vcproj | 4 + source/Blocks/BlockDirt.h | 2 +- source/Blocks/BlockFarmland.h | 99 ++++++++++++++++++++ source/Blocks/BlockHandler.cpp | 205 +++++++++++++++++------------------------ source/Chunk.cpp | 100 +------------------- 5 files changed, 194 insertions(+), 216 deletions(-) create mode 100644 source/Blocks/BlockFarmland.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 9c8212131..7db83a44e 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1734,6 +1734,10 @@ RelativePath="..\source\blocks\BlockEntity.h" > + + diff --git a/source/Blocks/BlockDirt.h b/source/Blocks/BlockDirt.h index b048b6318..31d981cb2 100644 --- a/source/Blocks/BlockDirt.h +++ b/source/Blocks/BlockDirt.h @@ -26,7 +26,7 @@ public: } - void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override { if (m_BlockType != E_BLOCK_GRASS) { diff --git a/source/Blocks/BlockFarmland.h b/source/Blocks/BlockFarmland.h new file mode 100644 index 000000000..fb2d91a86 --- /dev/null +++ b/source/Blocks/BlockFarmland.h @@ -0,0 +1,99 @@ + +// BlockFarmland.h + +// Declares the cBlcokFarmlandHandler representing the block handler for farmland + + + + + +#pragma once + +#include "BlockHandler.h" +#include "../BlockArea.h" + + + + + +class cBlockFarmlandHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockFarmlandHandler(void) : + super(E_BLOCK_FARMLAND) + { + } + + + virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + // TODO: Rain hydrates farmland, too. Check world weather, don't search for water if raining. + // NOTE: The desert biomes do not get precipitation, so another check needs to be made. + + // Search for water in a close proximity: + // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles + cBlockArea Area; + if (!Area.Read(a_World, a_BlockX - 4, a_BlockX + 4, a_BlockY, a_BlockY + 1, a_BlockZ - 4, a_BlockZ + 4)) + { + // Too close to the world edge, cannot check surroudnings; don't tick at all + return; + } + bool Found = false; + int NumBlocks = Area.GetBlockCount(); + BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); + for (int i = 0; i < NumBlocks; i++) + { + if ( + (BlockTypes[i] == E_BLOCK_WATER) || + (BlockTypes[i] == E_BLOCK_STATIONARY_WATER) + ) + { + Found = true; + break; + } + } + + NIBBLETYPE BlockMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (Found) + { + // Water was found, hydrate the block until hydration reaches 7: + if (BlockMeta < 7) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ++BlockMeta); + } + return; + } + + // Water wasn't found, de-hydrate block: + if (BlockMeta > 0) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, --BlockMeta); + return; + } + + // Farmland too dry. If nothing is growing on top, turn back to dirt: + switch (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) + { + case E_BLOCK_CROPS: + case E_BLOCK_MELON_STEM: + case E_BLOCK_PUMPKIN_STEM: + { + // Produce on top, don't revert + break; + } + default: + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); + break; + } + } + } +} ; + + + + diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index ab8dcda8a..977bff87f 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" #include "BlockHandler.h" #include "../Item.h" @@ -42,23 +43,24 @@ #include "BlockOre.h" #include "BlockNote.h" #include "BlockBed.h" +#include "BlockFarmland.h" -bool cBlockHandler::m_HandlerInitialized = false; -cBlockHandler *cBlockHandler::m_BlockHandler[256]; +bool cBlockHandler::m_HandlerInitialized = false; +cBlockHandler * cBlockHandler::m_BlockHandler[256]; -cBlockHandler *cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) +cBlockHandler * cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) { if (!m_HandlerInitialized) { - //We have to initialize + // We have to initialize memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); m_HandlerInitialized = true; } @@ -74,123 +76,85 @@ cBlockHandler *cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) -cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) +cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) { switch(a_BlockType) { - case E_BLOCK_SAND: - return new cBlockSandHandler(a_BlockType); - case E_BLOCK_GRAVEL: - return new cBlockGravelHandler(a_BlockType); - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - return new cBlockDoorHandler(a_BlockType); - case E_BLOCK_FIRE: - return new cBlockFireHandler(a_BlockType); - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - return new cBlockRedstoneTorchHandler(a_BlockType); - case E_BLOCK_REDSTONE_WIRE: - return new cBlockRedstoneHandler(a_BlockType); - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - return new cBlockPistonHandler(a_BlockType); - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - return new cBlockRedstoneRepeaterHandler(a_BlockType); - case E_BLOCK_WORKBENCH: - return new cBlockWorkbenchHandler(a_BlockType); - case E_BLOCK_SNOW: - return new cBlockSnowHandler(a_BlockType); - case E_BLOCK_TALL_GRASS: - return new cBlockTallGrassHandler(a_BlockType); - case E_BLOCK_VINES: - return new cBlockVineHandler(a_BlockType); - case ::E_BLOCK_WOOL: - return new cBlockClothHandler(a_BlockType); - case E_BLOCK_WOODEN_SLAB: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - return new cBlockSlabHandler(a_BlockType); - case E_BLOCK_LOG: - case E_BLOCK_PLANKS: - return new cBlockWoodHandler(a_BlockType); - case E_BLOCK_TORCH: - return new cBlockTorchHandler(a_BlockType); - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - return new cBlockDirtHandler(a_BlockType); - case E_BLOCK_LEAVES: - return new cBlockLeavesHandler(a_BlockType); - case E_BLOCK_SAPLING: - return new cBlockSaplingHandler(a_BlockType); - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_LAVA: - return new cBlockFluidHandler(a_BlockType); - case E_BLOCK_DISPENSER: - return new cBlockDispenserHandler(a_BlockType); - case E_BLOCK_FURNACE: - case E_BLOCK_LIT_FURNACE: - return new cBlockFurnaceHandler(a_BlockType); - case E_BLOCK_CHEST: - return new cBlockChestHandler(a_BlockType); - case E_BLOCK_ICE: - return new cBlockIceHandler(a_BlockType); - case E_BLOCK_LADDER: - return new cBlockLadderHandler(a_BlockType); - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_BRICK_STAIRS: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_WOODEN_STAIRS: - case E_BLOCK_SPRUCE_WOOD_STAIRS: - case E_BLOCK_BIRCH_WOOD_STAIRS: - case E_BLOCK_JUNGLE_WOOD_STAIRS: - return new cBlockStairsHandler(a_BlockType); - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - return new cBlockSignHandler(a_BlockType); - case E_BLOCK_CROPS: - return new cBlockCropsHandler(a_BlockType); - case E_BLOCK_SUGARCANE: - return new cBlockSugarcaneHandler(a_BlockType); - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - return new cBlockFlowerHandler(a_BlockType); - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_RED_MUSHROOM: - return new cBlockMushroomHandler(a_BlockType); - case E_BLOCK_CACTUS: - return new cBlockCactusHandler(a_BlockType); - case E_BLOCK_MELON_STEM: - case E_BLOCK_PUMPKIN_STEM: - return new cBlockStemsHandler(a_BlockType); - case E_BLOCK_GLOWSTONE: - return new cBlockGlowstoneHandler(a_BlockType); - case E_BLOCK_DIAMOND_ORE: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_EMERALD_ORE: - case E_BLOCK_IRON_ORE: - case E_BLOCK_LAPIS_ORE: - case E_BLOCK_COAL_ORE: - return new cBlockOreHandler(a_BlockType); - case E_BLOCK_STONE: - case E_BLOCK_COBBLESTONE: - return new cBlockStoneHandler(a_BlockType); - case E_BLOCK_MELON: - return new cBlockMelonHandler(a_BlockType); - case E_BLOCK_NOTE_BLOCK: - return new cBlockNoteHandler(a_BlockType); - case E_BLOCK_BED: - return new cBlockBedHandler(a_BlockType); - default: - return new cBlockHandler(a_BlockType); - break; + // Block handlers, alphabetically sorted: + case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); + case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_BROWN_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); + case E_BLOCK_CACTUS: return new cBlockCactusHandler (a_BlockType); + case E_BLOCK_CHEST: return new cBlockChestHandler (a_BlockType); + case E_BLOCK_COAL_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_COBBLESTONE: return new cBlockStoneHandler (a_BlockType); + case E_BLOCK_COBBLESTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_CROPS: return new cBlockCropsHandler (a_BlockType); + case E_BLOCK_DIAMOND_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType); + case E_BLOCK_DISPENSER: return new cBlockDispenserHandler (a_BlockType); + case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_EMERALD_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler; + case E_BLOCK_FIRE: return new cBlockFireHandler (a_BlockType); + case E_BLOCK_FURNACE: return new cBlockFurnaceHandler (a_BlockType); + case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType); + case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType); + case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType); + case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType); + case E_BLOCK_IRON_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_IRON_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType); + case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_LAVA: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); + case E_BLOCK_LOG: return new cBlockWoodHandler (a_BlockType); + case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); + case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType); + case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); + case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); + case E_BLOCK_PLANKS: return new cBlockWoodHandler (a_BlockType); + case E_BLOCK_PUMPKIN_STEM: return new cBlockStemsHandler (a_BlockType); + case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType); + case E_BLOCK_REDSTONE_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType); + case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (a_BlockType); + case E_BLOCK_REDSTONE_TORCH_ON: return new cBlockRedstoneTorchHandler (a_BlockType); + case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType); + case E_BLOCK_RED_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); + case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType); + case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType); + case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType); + case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType); + case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); + case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_STATIONARY_LAVA: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType); + case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType); + case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType); + case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); + case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType); + case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); + case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); + case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); + case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); + case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType); + case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType); + case E_BLOCK_WORKBENCH: return new cBlockWorkbenchHandler (a_BlockType); + case E_BLOCK_YELLOW_FLOWER: return new cBlockFlowerHandler (a_BlockType); + + default: return new cBlockHandler(a_BlockType); } } @@ -200,10 +164,11 @@ cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) void cBlockHandler::Deinit() { - for(int i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) { delete m_BlockHandler[i]; } + memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); // Don't leave any dangling pointers around, just in case m_HandlerInitialized = false; } @@ -220,7 +185,7 @@ cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType) -void cBlockHandler::OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { } diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 50bba66cf..0dec50230 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -530,107 +530,17 @@ void cChunk::TickBlocks(MTRand & a_TickRandom) continue; // It's all air up here } - unsigned int Index = MakeIndexNoCheck( m_BlockTickX, m_BlockTickY, m_BlockTickZ ); - BLOCKTYPE BlockType = m_BlockTypes[Index]; - switch (BlockType) - { - case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break; - - default: - { - cBlockHandler * Handler = BlockHandler(BlockType); - ASSERT(Handler != NULL); // Happenned on server restart, FS #243 - Handler->OnUpdate(m_World, m_BlockTickX + m_PosX * Width, m_BlockTickY, m_BlockTickZ + m_PosZ * Width); - break; - } - } - } -} - - - - - -void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ) -{ - // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining. - // NOTE: The desert biomes do not get precipitation, so another check needs to be made. - - // Search for water in a close proximity: - // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles - bool Found = false; - for (int y = a_RelY; y <= a_RelY + 1; y++) - { - for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++) - { - for (int x = a_RelX - 4; x <= a_RelX + 4; x++) - { - BLOCKTYPE BlockType; - NIBBLETYPE Meta; // unused - - if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta)) - { - // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all - return; - } - if ( - (BlockType == E_BLOCK_WATER) || - (BlockType == E_BLOCK_STATIONARY_WATER) - ) - { - Found = true; - break; - } - } // for x - if (Found) - { - break; - } - } // for z - if (Found) - { - break; - } - } // for y - - NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ); - - if (Found) - { - // Water was found, hydrate the block until hydration reaches 7: - if (BlockMeta < 7) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta); - } - return; - } - - // Water wasn't found, de-hydrate block: - if (BlockMeta > 0) - { - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta); - return; - } - - // Farmland too dry. If nothing is growing on top, turn back to dirt: - - switch (GetBlock(a_RelX, a_RelY + 1, a_RelZ)) - { - case E_BLOCK_CROPS: - case E_BLOCK_MELON_STEM: - case E_BLOCK_PUMPKIN_STEM: - break; - default: - FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); - break; - } + unsigned int Index = MakeIndexNoCheck(m_BlockTickX, m_BlockTickY, m_BlockTickZ); + cBlockHandler * Handler = BlockHandler(m_BlockTypes[Index]); + ASSERT(Handler != NULL); // Happenned on server restart, FS #243 + Handler->OnUpdate(m_World, m_BlockTickX + m_PosX * Width, m_BlockTickY, m_BlockTickZ + m_PosZ * Width); + } // for i - tickblocks } - void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) { // Convert the stem BlockType into produce BlockType -- cgit v1.2.3