summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Silverfish.cpp
blob: 9fb570341c4c456713d6a17ce29e87a9bd394c45 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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<int>(GetPosX() - 10); X <= static_cast<int>(GetPosX() + 10); X++)
	{
		for (int Y = static_cast<int>(GetPosY() - 5); Y <= static_cast<int>(GetPosY() + 5); Y++)
		{
			for (int Z = static_cast<int>(GetPosZ() - 10); Z <= static_cast<int>(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;
}