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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#pragma once
#include "BlockHandler.h"
#include "../FastRandom.h"
class cBlockCocoaPodHandler :
public cBlockHandler
{
using Super = cBlockHandler;
public:
cBlockCocoaPodHandler(BLOCKTYPE a_BlockType):
Super(a_BlockType)
{
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override
{
// Check that we're attached to a jungle log block:
eBlockFace BlockFace = MetaToBlockFace(a_Chunk.GetMeta(a_RelPos));
auto LogPos = AddFaceDirection(a_RelPos, BlockFace, true);
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
a_Chunk.UnboundedRelGetBlock(LogPos, BlockType, BlockMeta);
return ((BlockType == E_BLOCK_LOG) && ((BlockMeta & 0x03) == E_META_LOG_JUNGLE));
}
virtual void OnUpdate(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
cBlockPluginInterface & a_PluginInterface,
cChunk & a_Chunk,
const Vector3i a_RelPos
) override
{
if (GetRandomProvider().RandBool(0.20))
{
Grow(a_Chunk, a_RelPos);
}
}
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
// If fully grown, give 3 items, otherwise just one:
auto growState = a_BlockMeta >> 2;
return cItem(E_ITEM_DYE, ((growState >= 2) ? 3 : 1), E_META_DYE_BROWN);
}
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override
{
auto meta = a_Chunk.GetMeta(a_RelPos);
auto typeMeta = meta & 0x03;
auto growState = meta >> 2;
if (growState >= 2)
{
return 0;
}
auto newState = std::min(growState + a_NumStages, 2);
a_Chunk.SetMeta(a_RelPos, static_cast<NIBBLETYPE>(newState << 2 | typeMeta));
return newState - growState;
}
static eBlockFace MetaToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x03)
{
case 0: return BLOCK_FACE_ZM;
case 1: return BLOCK_FACE_XP;
case 2: return BLOCK_FACE_ZP;
case 3: return BLOCK_FACE_XM;
default:
{
ASSERT(!"Bad meta");
return BLOCK_FACE_NONE;
}
}
}
static NIBBLETYPE BlockFaceToMeta(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
case BLOCK_FACE_ZM: return 0;
case BLOCK_FACE_XM: return 3;
case BLOCK_FACE_XP: return 1;
case BLOCK_FACE_ZP: return 2;
case BLOCK_FACE_NONE:
case BLOCK_FACE_YM:
case BLOCK_FACE_YP:
{
ASSERT(!"Unknown face");
return 0;
}
}
UNREACHABLE("Unsupported block face");
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
return 34;
}
} ;
|