the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "..\..\..\Minecraft.World\StringHelpers.h"
3#include "..\..\..\Minecraft.World\net.minecraft.world.phys.h"
4#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
5#include "..\..\..\Minecraft.World\net.minecraft.world.level.dimension.h"
6#include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.h"
7#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
8#include "ApplySchematicRuleDefinition.h"
9#include "LevelGenerationOptions.h"
10#include "ConsoleSchematicFile.h"
11
12ApplySchematicRuleDefinition::ApplySchematicRuleDefinition(LevelGenerationOptions *levelGenOptions)
13{
14 m_levelGenOptions = levelGenOptions;
15 m_location = Vec3::newPermanent(0,0,0);
16 m_locationBox = NULL;
17 m_totalBlocksChanged = 0;
18 m_totalBlocksChangedLighting = 0;
19 m_rotation = ConsoleSchematicFile::eSchematicRot_0;
20 m_completed = false;
21 m_dimension = 0;
22 m_schematic = NULL;
23}
24
25ApplySchematicRuleDefinition::~ApplySchematicRuleDefinition()
26{
27 app.DebugPrintf("Deleting ApplySchematicRuleDefinition.\n");
28 if(!m_completed) m_levelGenOptions->releaseSchematicFile(m_schematicName);
29 m_schematic = NULL;
30 delete m_location;
31}
32
33void ApplySchematicRuleDefinition::writeAttributes(DataOutputStream *dos, UINT numAttrs)
34{
35 GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
36
37 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_filename);
38 dos->writeUTF(m_schematicName);
39 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x);
40 dos->writeUTF(_toString(m_location->x));
41 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y);
42 dos->writeUTF(_toString(m_location->y));
43 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z);
44 dos->writeUTF(_toString(m_location->z));
45 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_rot);
46
47 switch (m_rotation)
48 {
49 case ConsoleSchematicFile::eSchematicRot_0: dos->writeUTF(_toString( 0 )); break;
50 case ConsoleSchematicFile::eSchematicRot_90: dos->writeUTF(_toString( 90 )); break;
51 case ConsoleSchematicFile::eSchematicRot_180: dos->writeUTF(_toString( 180 )); break;
52 case ConsoleSchematicFile::eSchematicRot_270: dos->writeUTF(_toString( 270 )); break;
53 }
54}
55
56void ApplySchematicRuleDefinition::addAttribute(const wstring &attributeName, const wstring &attributeValue)
57{
58 if(attributeName.compare(L"filename") == 0)
59 {
60 m_schematicName = attributeValue;
61 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter filename=%s\n",m_schematicName.c_str());
62
63 if(!m_schematicName.empty())
64 {
65 if(m_schematicName.substr( m_schematicName.length() - 4, m_schematicName.length()).compare(L".sch") != 0)
66 {
67 m_schematicName.append(L".sch");
68 }
69 m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
70 }
71 }
72 else if(attributeName.compare(L"x") == 0)
73 {
74 m_location->x = _fromString<int>(attributeValue);
75 if( ((int)abs(m_location->x))%2 != 0) m_location->x -=1;
76 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter x=%f\n",m_location->x);
77 }
78 else if(attributeName.compare(L"y") == 0)
79 {
80 m_location->y = _fromString<int>(attributeValue);
81 if( ((int)abs(m_location->y))%2 != 0) m_location->y -= 1;
82 if(m_location->y < 0) m_location->y = 0;
83 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter y=%f\n",m_location->y);
84 }
85 else if(attributeName.compare(L"z") == 0)
86 {
87 m_location->z = _fromString<int>(attributeValue);
88 if(((int)abs(m_location->z))%2 != 0) m_location->z -= 1;
89 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter z=%f\n",m_location->z);
90 }
91 else if(attributeName.compare(L"rot") == 0)
92 {
93 int degrees = _fromString<int>(attributeValue);
94
95 while(degrees < 0) degrees += 360;
96 while(degrees >= 360) degrees -= 360;
97 float quad = degrees/90;
98 degrees = (int)(quad + 0.5f);
99 switch(degrees)
100 {
101 case 1:
102 m_rotation = ConsoleSchematicFile::eSchematicRot_90;
103 break;
104 case 2:
105 m_rotation = ConsoleSchematicFile::eSchematicRot_180;
106 break;
107 case 3:
108 case 4:
109 m_rotation = ConsoleSchematicFile::eSchematicRot_270;
110 break;
111 case 0:
112 default:
113 m_rotation = ConsoleSchematicFile::eSchematicRot_0;
114 break;
115 };
116
117 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter rot=%d\n",m_rotation);
118 }
119 else if(attributeName.compare(L"dim") == 0)
120 {
121 m_dimension = _fromString<int>(attributeValue);
122 if(m_dimension > 1 || m_dimension < -1) m_dimension = 0;
123 //app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter dimension=%d\n",m_dimension);
124 }
125 else
126 {
127 GameRuleDefinition::addAttribute(attributeName, attributeValue);
128 }
129}
130
131void ApplySchematicRuleDefinition::updateLocationBox()
132{
133 if(m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
134
135 m_locationBox = AABB::newPermanent(0,0,0,0,0,0);
136
137 m_locationBox->x0 = m_location->x;
138 m_locationBox->y0 = m_location->y;
139 m_locationBox->z0 = m_location->z;
140
141 m_locationBox->y1 = m_location->y + m_schematic->getYSize();
142
143 switch(m_rotation)
144 {
145 case ConsoleSchematicFile::eSchematicRot_90:
146 case ConsoleSchematicFile::eSchematicRot_270:
147 m_locationBox->x1 = m_location->x + m_schematic->getZSize();
148 m_locationBox->z1 = m_location->z + m_schematic->getXSize();
149 break;
150 case ConsoleSchematicFile::eSchematicRot_0:
151 case ConsoleSchematicFile::eSchematicRot_180:
152 default:
153 m_locationBox->x1 = m_location->x + m_schematic->getXSize();
154 m_locationBox->z1 = m_location->z + m_schematic->getZSize();
155 break;
156 };
157}
158
159void ApplySchematicRuleDefinition::processSchematic(AABB *chunkBox, LevelChunk *chunk)
160{
161 if( m_completed ) return;
162 if(chunk->level->dimension->id != m_dimension) return;
163
164 PIXBeginNamedEvent(0, "Processing ApplySchematicRuleDefinition");
165 if(m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
166
167 if(m_locationBox == NULL) updateLocationBox();
168 if(chunkBox->intersects( m_locationBox ))
169 {
170 m_locationBox->y1 = min((double)Level::maxBuildHeight, m_locationBox->y1 );
171
172#ifdef _DEBUG
173 app.DebugPrintf("Applying schematic %ls to chunk (%d,%d)\n",m_schematicName.c_str(),chunk->x, chunk->z);
174#endif
175 PIXBeginNamedEvent(0,"Applying blocks and data");
176 m_totalBlocksChanged += m_schematic->applyBlocksAndData(chunk, chunkBox, m_locationBox, m_rotation);
177 PIXEndNamedEvent();
178
179 // Add the tileEntities
180 PIXBeginNamedEvent(0,"Applying tile entities");
181 m_schematic->applyTileEntities(chunk, chunkBox, m_locationBox, m_rotation);
182 PIXEndNamedEvent();
183
184 // TODO This does not take into account things that go outside the bounds of the world
185 int targetBlocks = (m_locationBox->x1 - m_locationBox->x0)
186 * (m_locationBox->y1 - m_locationBox->y0)
187 * (m_locationBox->z1 - m_locationBox->z0);
188 if( (m_totalBlocksChanged == targetBlocks) && (m_totalBlocksChangedLighting == targetBlocks) )
189 {
190 m_completed = true;
191 //m_levelGenOptions->releaseSchematicFile(m_schematicName);
192 //m_schematic = NULL;
193 }
194 }
195 PIXEndNamedEvent();
196}
197
198void ApplySchematicRuleDefinition::processSchematicLighting(AABB *chunkBox, LevelChunk *chunk)
199{
200 if( m_completed ) return;
201 if(chunk->level->dimension->id != m_dimension) return;
202
203 PIXBeginNamedEvent(0, "Processing ApplySchematicRuleDefinition (lighting)");
204 if(m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
205
206 if(m_locationBox == NULL) updateLocationBox();
207 if(chunkBox->intersects( m_locationBox ))
208 {
209 m_locationBox->y1 = min((double)Level::maxBuildHeight, m_locationBox->y1 );
210
211#ifdef _DEBUG
212 app.DebugPrintf("Applying schematic %ls to chunk (%d,%d)\n",m_schematicName.c_str(),chunk->x, chunk->z);
213#endif
214 PIXBeginNamedEvent(0,"Patching lighting");
215 m_totalBlocksChangedLighting += m_schematic->applyLighting(chunk, chunkBox, m_locationBox, m_rotation);
216 PIXEndNamedEvent();
217
218 // TODO This does not take into account things that go outside the bounds of the world
219 int targetBlocks = (m_locationBox->x1 - m_locationBox->x0)
220 * (m_locationBox->y1 - m_locationBox->y0)
221 * (m_locationBox->z1 - m_locationBox->z0);
222 if( (m_totalBlocksChanged == targetBlocks) && (m_totalBlocksChangedLighting == targetBlocks) )
223 {
224 m_completed = true;
225 //m_levelGenOptions->releaseSchematicFile(m_schematicName);
226 //m_schematic = NULL;
227 }
228 }
229 PIXEndNamedEvent();
230}
231
232bool ApplySchematicRuleDefinition::checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1)
233{
234 if( m_locationBox == NULL ) updateLocationBox();
235 return m_locationBox->intersects(x0,y0,z0,x1,y1,z1);
236}
237
238int ApplySchematicRuleDefinition::getMinY()
239{
240 if( m_locationBox == NULL ) updateLocationBox();
241 return m_locationBox->y0;
242}
243
244void ApplySchematicRuleDefinition::reset()
245{
246 m_totalBlocksChanged = 0;
247 m_totalBlocksChangedLighting = 0;
248 m_completed = false;
249}