diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-12-20 03:14:17 +0100 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-12-21 14:52:06 +0100 |
commit | e7331fe8205f798a7b453961feb38aea64d55b47 (patch) | |
tree | edf094c393bbd8633f91b8260cc1313f4b15a91d /src/Mobs/Silverfish.cpp | |
parent | Comment and code style fix (diff) | |
download | cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar.gz cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar.bz2 cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar.lz cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar.xz cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.tar.zst cuberite-e7331fe8205f798a7b453961feb38aea64d55b47.zip |
Diffstat (limited to 'src/Mobs/Silverfish.cpp')
-rw-r--r-- | src/Mobs/Silverfish.cpp | 99 |
1 files changed, 70 insertions, 29 deletions
diff --git a/src/Mobs/Silverfish.cpp b/src/Mobs/Silverfish.cpp index 9fb570341..43686344b 100644 --- a/src/Mobs/Silverfish.cpp +++ b/src/Mobs/Silverfish.cpp @@ -8,53 +8,94 @@ #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 + // Call on our brethren to attack! + // TODO: stop this if /gamerule mobGriefing is set to false - // If the entity didn't take andy damage - if (!SuperResult) + // If the entity didn't take any damage, bail: + if (!Super::DoTakeDamage(a_TDI)) { - return SuperResult; + return false; } - // 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))) + // Or, conversely took lethal damage, bail: + if (m_Health <= 0) { - return SuperResult; + return true; } - // If attacker is player or splash potion - bool ShouldSpawn = ( - (a_TDI.DamageType == dtPoison) || (a_TDI.DamageType == dtPotionOfHarming) || - a_TDI.Attacker->IsPlayer() - ); - - if (!ShouldSpawn) + if (a_TDI.Attacker == nullptr) { - return SuperResult; + if ((a_TDI.DamageType != dtPoison) && (a_TDI.DamageType != dtPotionOfHarming)) + { + // Bail if attacker doesn't exist and it wasn't a splash potion: + return true; + } } - auto Blocks = sSetBlockVector(); - for (int X = static_cast<int>(GetPosX() - 10); X <= static_cast<int>(GetPosX() + 10); X++) + else if (!a_TDI.Attacker->IsPlayer()) + { + // Bail if it wasn't a player attack: + return true; + } + + auto & Random = GetRandomProvider(); + + // Tries to spawn another Silverfish, returning if the search should continue. + auto CheckInfested = [this, &Random, Position = GetPosition().Floor()](const Vector3i Offset) mutable + { + const auto Block = Position + Offset; + if (m_World->GetBlock(Block) == E_BLOCK_SILVERFISH_EGG) + { + m_World->DigBlock(Block); + return Random.RandBool(); + } + return false; + }; + + // Search the faces of an increasingly large cube (so the positions closest get looked at first) + // of min 3, max 10, for infested blocks and spawn additional reinforcements: + for (int CubeSideLength = 3; CubeSideLength <= 10; CubeSideLength++) { - for (int Y = static_cast<int>(GetPosY() - 5); Y <= static_cast<int>(GetPosY() + 5); Y++) + const int HalfSide = CubeSideLength / 2; + + for (int OffsetX = -HalfSide; OffsetX <= HalfSide; OffsetX++) { - for (int Z = static_cast<int>(GetPosZ() - 10); Z <= static_cast<int>(GetPosZ() + 10); Z++) + for (int OffsetZ = -HalfSide; OffsetZ <= HalfSide; OffsetZ++) { - Blocks.emplace_back(sSetBlock({X, Y, Z}, 0, 0)); + if (CheckInfested({ OffsetX, +HalfSide, OffsetZ }) || CheckInfested({ OffsetX, -HalfSide, OffsetZ })) + { + return true; + } } } - } - m_World->GetBlocks(Blocks, true); - for (const auto & BlockInfo : Blocks) - { - if (BlockInfo.m_BlockType == E_BLOCK_SILVERFISH_EGG) + + for (int OffsetX = -HalfSide; OffsetX <= HalfSide; OffsetX++) { - m_World->DigBlock(BlockInfo.GetAbsolutePos(), nullptr); + for (int OffsetY = -HalfSide + 1; OffsetY <= HalfSide - 1; OffsetY++) + { + if (CheckInfested({ OffsetX, OffsetY, +HalfSide }) || CheckInfested({ OffsetX, OffsetY, -HalfSide })) + { + return true; + } + } + } + + for (int OffsetZ = -HalfSide + 1; OffsetZ <= HalfSide - 1; OffsetZ++) + { + for (int OffsetY = -HalfSide + 1; OffsetY <= HalfSide - 1; OffsetY++) + { + if (CheckInfested({ +HalfSide, OffsetY, OffsetZ }) || CheckInfested({ -HalfSide, OffsetY, OffsetZ })) + { + return true; + } + } } } - return SuperResult; + return true; } |