summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockStairs.h
blob: 8d259eee3a0676e340129ded517572418639bb0b (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
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
141
142
143
144
145
146
147
148
149
150
151
152

#pragma once

#include "BlockHandler.h"





class cBlockStairsHandler :
	public cBlockHandler
{
public:
	cBlockStairsHandler(BLOCKTYPE a_BlockType) :
		cBlockHandler(a_BlockType)
	{

	}
	
	
	virtual bool GetPlacementBlockTypeMeta(
		cWorld * a_World, cPlayer * a_Player,
		int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, 
		int a_CursorX, int a_CursorY, int a_CursorZ,
		BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
	) override
	{
		a_BlockType = m_BlockType;
		a_BlockMeta = RotationToMetaData(a_Player->GetRotation());
		switch (a_BlockFace)
		{
			case BLOCK_FACE_TOP:    break;
			case BLOCK_FACE_BOTTOM: a_BlockMeta = a_BlockMeta | 0x4; break;  // When placing onto a bottom face, always place an upside-down stairs block
			case BLOCK_FACE_EAST:
			case BLOCK_FACE_NORTH:
			case BLOCK_FACE_SOUTH:
			case BLOCK_FACE_WEST:
			{
				// When placing onto a sideways face, check cursor, if in top half, make it an upside-down stairs block
				if (a_CursorY > 8)
				{
					a_BlockMeta |= 0x4;
				}
				break;
			}
		}
		return true;
	}
	
	// TODO: step sound
	
	
	static NIBBLETYPE RotationToMetaData(double a_Rotation)
	{
		a_Rotation += 90 + 45; // So its not aligned with axis
		if (a_Rotation > 360)
		{
			a_Rotation -= 360;
		}
		if ((a_Rotation >= 0) && (a_Rotation < 90))
		{
			return 0x0;
		}
		else if ((a_Rotation >= 180) && (a_Rotation < 270))
		{
			return 0x1;
		}
		else if ((a_Rotation >= 90) && (a_Rotation < 180))
		{
			return 0x2;
		}
		else
		{
			return 0x3;
		}
	}


	virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
	{
		// Bits 3 and 4 stay, the rest is swapped around according to a table:
		NIBBLETYPE TopBits = (a_Meta & 0x0c);
		switch (a_Meta & 0x03)
		{
			case 0x00: return TopBits | 0x03;  // East -> North
			case 0x01: return TopBits | 0x02;  // West -> South
			case 0x02: return TopBits | 0x00;  // South -> East
			case 0x03: return TopBits | 0x01;  // North -> West
		}
		// Not reachable, but to avoid a compiler warning:
		return 0;
	}


	virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
	{
		// Bits 3 and 4 stay, the rest is swapped around according to a table:
		NIBBLETYPE TopBits = (a_Meta & 0x0c);
		switch (a_Meta & 0x03)
		{
			case 0x00: return TopBits | 0x02;  // East -> South
			case 0x01: return TopBits | 0x03;  // West -> North
			case 0x02: return TopBits | 0x01;  // South -> West
			case 0x03: return TopBits | 0x00;  // North -> East
		}
		// Not reachable, but to avoid a compiler warning:
		return 0;
	}


	virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
	{
		// Bits 3 and 4 stay, the rest is swapped around according to a table:
		NIBBLETYPE TopBits = (a_Meta & 0x0c);
		switch (a_Meta & 0x03)
		{
			case 0x00: return TopBits | 0x00;  // East -> East
			case 0x01: return TopBits | 0x01;  // West -> West
			case 0x02: return TopBits | 0x03;  // South -> North
			case 0x03: return TopBits | 0x02;  // North -> South
		}
		// Not reachable, but to avoid a compiler warning:
		return 0;
	}


	virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
	{
		// Toggle bit 3:
		return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
	}


	virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
	{
		// Bits 3 and 4 stay, the rest is swapped around according to a table:
		NIBBLETYPE TopBits = (a_Meta & 0x0c);
		switch (a_Meta & 0x03)
		{
			case 0x00: return TopBits | 0x01;  // East -> West
			case 0x01: return TopBits | 0x00;  // West -> East
			case 0x02: return TopBits | 0x02;  // South -> South
			case 0x03: return TopBits | 0x03;  // North -> North
		}
		// Not reachable, but to avoid a compiler warning:
		return 0;
	}
} ;