From c080f819d2af3cc8c71d39c222a249e4df5e6f67 Mon Sep 17 00:00:00 2001 From: 12xx12 <44411062+12xx12@users.noreply.github.com> Date: Sun, 11 Oct 2020 17:27:41 +0200 Subject: [PATCH] Adding Silverfish Spawning Blocks (#4946) * added breaking, spawning, animation * checkstyle * added undocumented API symbols * added changes suggested by @peterbell10 * added natural ore like generation * fixed spawning two silverfishes * fixed clang * fixed clang try 2 * updated comment unified offset * final clang fix * added spawning for more silverfishes if one was damaged * fixed spawning on one hit kill * fixed spawning on one hit kill fixed spawning by potion damage * fixed clang * fixed broken build * fixed broken build * I should read the error message properly fixed build now? * added small changes suggested by @peterbell10 Co-authored-by: 12xx12 <12xx12100@gmail.com> --- Server/Plugins/APIDump/APIDesc.lua | 12 ++++ src/BlockType.h | 9 ++- src/Blocks/BlockHandler.cpp | 3 +- src/Blocks/BlockInfested.h | 88 ++++++++++++++++++++++++++++++ src/Blocks/CMakeLists.txt | 1 + src/Generating/FinishGen.cpp | 35 +++++++++--- src/Mobs/CMakeLists.txt | 1 + src/Mobs/Silverfish.cpp | 60 ++++++++++++++++++++ src/Mobs/Silverfish.h | 3 +- 9 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 src/Blocks/BlockInfested.h create mode 100644 src/Mobs/Silverfish.cpp diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index f339aa6d1..6cfcb9c15 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -16867,6 +16867,18 @@ end { Notes = "" }, + E_META_SILVERFISH_EGG_CHISELED_STONE_BRICK = + { + Notes = "A flag in the metadata of the silverfish egg that the block is made from chiseled stone bricks" + }, + E_META_SILVERFISH_EGG_CRACKED_STONE_BRICK = + { + Notes = "A flag in the metadata of the silverfish egg that the block is made from cracked stone bricks" + }, + E_META_SILVERFISH_EGG_MOSSY_STONE_BRICK = + { + Notes = "A flag in the metadata of the silverfish egg that the block is made from mossy stone bricks" + }, E_META_SPONGE_DRY = { Notes = "A flag in the metadata of sponges that indicates that the sponge is dry.", diff --git a/src/BlockType.h b/src/BlockType.h index 95207dbee..4db75b252 100644 --- a/src/BlockType.h +++ b/src/BlockType.h @@ -804,9 +804,12 @@ enum ENUM_BLOCK_META : NIBBLETYPE E_META_SAPLING_DARK_OAK = 5, // E_BLOCK_SILVERFISH_EGG metas: - E_META_SILVERFISH_EGG_STONE = 0, - E_META_SILVERFISH_EGG_COBBLESTONE = 1, - E_META_SILVERFISH_EGG_STONE_BRICK = 2, + E_META_SILVERFISH_EGG_STONE = 0, + E_META_SILVERFISH_EGG_COBBLESTONE = 1, + E_META_SILVERFISH_EGG_STONE_BRICK = 2, + E_META_SILVERFISH_EGG_MOSSY_STONE_BRICK = 3, + E_META_SILVERFISH_EGG_CRACKED_STONE_BRICK = 4, + E_META_SILVERFISH_EGG_CHISELED_STONE_BRICK = 5, // E_BLOCK_SNOW metas: E_META_SNOW_LAYER_ONE = 0, diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 8925449e6..6342c80fb 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -56,6 +56,7 @@ #include "BlockMelon.h" #include "BlockMobHead.h" #include "BlockMobSpawner.h" +#include "BlockInfested.h" #include "BlockMushroom.h" #include "BlockMycelium.h" #include "BlockNetherWart.h" @@ -297,7 +298,7 @@ namespace constexpr cDefaultBlockHandler BlockHugeRedMushroomHandler (E_BLOCK_HUGE_RED_MUSHROOM); constexpr cBlockIceHandler BlockIceHandler (E_BLOCK_ICE); constexpr cBlockComparatorHandler BlockInactiveComparatorHandler (E_BLOCK_INACTIVE_COMPARATOR); - constexpr cDefaultBlockHandler BlockInfestedBlockHandler (E_BLOCK_SILVERFISH_EGG); + constexpr cBlockInfestedHandler BlockInfestedBlockHandler (E_BLOCK_SILVERFISH_EGG); constexpr cDefaultBlockHandler BlockIronBarsHandler (E_BLOCK_IRON_BARS); constexpr cDefaultBlockHandler BlockIronBlockHandler (E_BLOCK_IRON_BLOCK); constexpr cBlockDoorHandler BlockIronDoorHandler (E_BLOCK_IRON_DOOR); diff --git a/src/Blocks/BlockInfested.h b/src/Blocks/BlockInfested.h new file mode 100644 index 000000000..d2b634dd0 --- /dev/null +++ b/src/Blocks/BlockInfested.h @@ -0,0 +1,88 @@ + +// BlockInfested.h + +#include "../Entities/Player.h" + +/* This Block Handler describes the blocks spawning silver fishes. Mojang calls them monster egg */ + +class cBlockInfestedHandler final: + public cBlockHandler +{ + using Super = cBlockHandler; + +public: + + using Super::Super; + + static void SpawnSilverfish(cWorldInterface & a_WorldInterface, Vector3i a_BlockPos) + { + auto Pos = Vector3f(a_BlockPos.x - 0.5f, a_BlockPos.y - 0.5f, a_BlockPos.z - 0.5f); + // TODO: only display animation if the difficulty allows mob spawns - Add when difficulty is implemented + // Spawn Silverfish + a_WorldInterface.SpawnMob(Pos.x, Pos.y, Pos.z, mtSilverfish, false); + // Play particle + a_WorldInterface.GetBroadcastManager().BroadcastParticleEffect("explode", Pos, Vector3f(), 0.1f, 50); + } + +private: + + virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, const cEntity * a_Digger, const cItem * a_Tool) const override + { + switch (a_BlockMeta) + { + case E_META_SILVERFISH_EGG_STONE: + { + if (ToolHasSilkTouch(a_Tool)) + { + return cItem(E_BLOCK_STONE); + } + else + { + return cItem(E_BLOCK_COBBLESTONE); + } + } + case E_META_SILVERFISH_EGG_COBBLESTONE: return cItem(E_BLOCK_COBBLESTONE); + case E_META_SILVERFISH_EGG_STONE_BRICK: return cItem(E_BLOCK_STONE_BRICKS); + case E_META_SILVERFISH_EGG_MOSSY_STONE_BRICK: return cItem(E_BLOCK_STONE_BRICKS, 1, E_META_STONE_BRICK_MOSSY); + case E_META_SILVERFISH_EGG_CRACKED_STONE_BRICK: return cItem(E_BLOCK_STONE_BRICKS, 1, E_META_STONE_BRICK_CRACKED); + case E_META_SILVERFISH_EGG_CHISELED_STONE_BRICK: return cItem(E_BLOCK_STONE_BRICKS, 1, E_META_STONE_BRICK_ORNAMENT); + } + return {}; + } + + + + + + virtual void OnBroken( + cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, + Vector3i a_BlockPos, + BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, + const cEntity * a_Digger + ) const override + { + if (a_Digger != nullptr) + { + if (a_Digger->IsPlayer()) + { + const auto Player = static_cast(a_Digger); + if (Player->IsGameModeCreative()) + { + return; + } + } + if (a_Digger->IsMob()) + { + return; + } + } + SpawnSilverfish(a_WorldInterface, a_BlockPos); + } + + + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override + { + return 11; + } +} ; + diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index d9d6e58f1..e20bda584 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -59,6 +59,7 @@ target_sources( BlockMelon.h BlockMobHead.h BlockMobSpawner.h + BlockInfested.h BlockMushroom.h BlockMycelium.h BlockNetherrack.h diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 4077fd98e..78b28bff5 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1615,14 +1615,15 @@ const cFinishGenOres::OreInfos & cFinishGenOres::DefaultOverworldOres(void) { static OreInfos res { - // OreType, OreMeta, MaxHeight, NumNests, NestSize - {E_BLOCK_COAL_ORE, 0, 127, 20, 16}, - {E_BLOCK_IRON_ORE, 0, 64, 20, 8}, - {E_BLOCK_GOLD_ORE, 0, 32, 2, 8}, - {E_BLOCK_REDSTONE_ORE, 0, 16, 8, 7}, - {E_BLOCK_DIAMOND_ORE, 0, 15, 1, 7}, - {E_BLOCK_LAPIS_ORE, 0, 30, 1, 6}, - {E_BLOCK_EMERALD_ORE, 0, 32, 11, 1}, + // OreType, OreMeta, MaxHeight, NumNests, NestSize + {E_BLOCK_COAL_ORE, 0, 127, 20, 16}, + {E_BLOCK_IRON_ORE, 0, 64, 20, 8}, + {E_BLOCK_GOLD_ORE, 0, 32, 2, 8}, + {E_BLOCK_REDSTONE_ORE, 0, 16, 8, 7}, + {E_BLOCK_DIAMOND_ORE, 0, 15, 1, 7}, + {E_BLOCK_LAPIS_ORE, 0, 30, 1, 6}, + {E_BLOCK_EMERALD_ORE, 0, 32, 11, 1}, + {E_BLOCK_SILVERFISH_EGG, 0, 64, 7, 9}, }; return res; } @@ -1792,6 +1793,24 @@ void cFinishGenOreNests::GenerateOre( } } + if (a_OreType == E_BLOCK_SILVERFISH_EGG) + { + const auto BiomeSampleOne = a_ChunkDesc.GetBiome( 4, 4); + const auto BiomeSampleTwo = a_ChunkDesc.GetBiome( 4, 12); + const auto BiomeSampleThree = a_ChunkDesc.GetBiome(12, 4); + const auto BiomeSampleFour = a_ChunkDesc.GetBiome(12, 12); + + if ( + !IsBiomeMountain(BiomeSampleOne) && + !IsBiomeMountain(BiomeSampleTwo) && + !IsBiomeMountain(BiomeSampleThree) && + !IsBiomeMountain(BiomeSampleFour) + ) + { + return; + } + } + auto chunkX = a_ChunkDesc.GetChunkX(); auto chunkZ = a_ChunkDesc.GetChunkZ(); auto & blockTypes = a_ChunkDesc.GetBlockTypes(); diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt index 6508e1814..932b90b29 100644 --- a/src/Mobs/CMakeLists.txt +++ b/src/Mobs/CMakeLists.txt @@ -26,6 +26,7 @@ target_sources( Pig.cpp Rabbit.cpp Sheep.cpp + Silverfish.cpp Skeleton.cpp Slime.cpp SnowGolem.cpp diff --git a/src/Mobs/Silverfish.cpp b/src/Mobs/Silverfish.cpp new file mode 100644 index 000000000..9fb570341 --- /dev/null +++ b/src/Mobs/Silverfish.cpp @@ -0,0 +1,60 @@ + +#include "Globals.h" + +#include "Silverfish.h" + +#include "../World.h" +#include "../Chunk.h" +#include "../Blocks/BlockHandler.h" +#include "../Blocks/BlockInfested.h" + +bool cSilverfish::DoTakeDamage(TakeDamageInfo &a_TDI) +{ + bool SuperResult = Super::DoTakeDamage(a_TDI); + // Todo: stop this if /gamerule mobGriefing is set to false + + // If the entity didn't take andy damage + if (!SuperResult) + { + return SuperResult; + } + + // Entity does receive lethal damage or Attacker doesn't exist + if ((m_Health < a_TDI.FinalDamage) || + ((a_TDI.Attacker == nullptr) && (a_TDI.DamageType != dtPoison) && (a_TDI.DamageType != dtPotionOfHarming))) + { + return SuperResult; + } + + // If attacker is player or splash potion + bool ShouldSpawn = ( + (a_TDI.DamageType == dtPoison) || (a_TDI.DamageType == dtPotionOfHarming) || + a_TDI.Attacker->IsPlayer() + ); + + if (!ShouldSpawn) + { + return SuperResult; + } + auto Blocks = sSetBlockVector(); + for (int X = static_cast(GetPosX() - 10); X <= static_cast(GetPosX() + 10); X++) + { + for (int Y = static_cast(GetPosY() - 5); Y <= static_cast(GetPosY() + 5); Y++) + { + for (int Z = static_cast(GetPosZ() - 10); Z <= static_cast(GetPosZ() + 10); Z++) + { + Blocks.emplace_back(sSetBlock({X, Y, Z}, 0, 0)); + } + } + } + m_World->GetBlocks(Blocks, true); + for (const auto & BlockInfo : Blocks) + { + if (BlockInfo.m_BlockType == E_BLOCK_SILVERFISH_EGG) + { + m_World->DigBlock(BlockInfo.GetAbsolutePos(), nullptr); + } + } + + return SuperResult; +} diff --git a/src/Mobs/Silverfish.h b/src/Mobs/Silverfish.h index 435061f72..78137701a 100644 --- a/src/Mobs/Silverfish.h +++ b/src/Mobs/Silverfish.h @@ -18,8 +18,9 @@ public: Super("Silverfish", mtSilverfish, "entity.silverfish.hurt", "entity.silverfish.death", "entity.silverfish.ambient", 0.3, 0.4) { } - CLASS_PROTODEF(cSilverfish) + + virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; } ;