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 "net.minecraft.network.packet.h"
3#include "net.minecraft.world.entity.h"
4#include "net.minecraft.world.entity.player.h"
5#include "net.minecraft.world.level.h"
6#include "net.minecraft.world.level.chunk.h"
7#include "net.minecraft.world.level.dimension.h"
8#include "net.minecraft.world.level.material.h"
9#include "net.minecraft.world.level.saveddata.h"
10#include "net.minecraft.world.level.storage.h"
11#include "net.minecraft.world.level.tile.h"
12#include "net.minecraft.world.item.h"
13#include "MapItem.h"
14#include "net.minecraft.world.inventory.h"
15#include "JavaMath.h"
16
17MapItem::MapItem(int id) : ComplexItem(id)
18{
19 setStackedByData(true);
20}
21
22shared_ptr<MapItemSavedData> MapItem::getSavedData(short idNum, Level *level)
23{
24 std::wstring id = wstring( L"map_" ) + _toString(idNum);
25 shared_ptr<MapItemSavedData> mapItemSavedData = dynamic_pointer_cast<MapItemSavedData>(level->getSavedData(typeid(MapItemSavedData), id));
26
27 if (mapItemSavedData == NULL)
28 {
29 // 4J Stu - This call comes from ClientConnection, but i don't see why we should be trying to work out
30 // the id again when it's passed as a param. In any case that won't work with the new map setup
31 //int aux = level->getFreeAuxValueFor(L"map");
32 int aux = idNum;
33
34 id = wstring( L"map_" ) + _toString(aux);
35 mapItemSavedData = shared_ptr<MapItemSavedData>( new MapItemSavedData(id) );
36
37 level->setSavedData(id, (shared_ptr<SavedData> ) mapItemSavedData);
38 }
39
40 return mapItemSavedData;
41}
42
43shared_ptr<MapItemSavedData> MapItem::getSavedData(shared_ptr<ItemInstance> itemInstance, Level *level)
44{
45 MemSect(31);
46 std::wstring id = wstring( L"map_" ) + _toString(itemInstance->getAuxValue() );
47 MemSect(0);
48 shared_ptr<MapItemSavedData> mapItemSavedData = dynamic_pointer_cast<MapItemSavedData>( level->getSavedData(typeid(MapItemSavedData), id ) );
49
50 bool newData = false;
51 if (mapItemSavedData == NULL)
52 {
53 // 4J Stu - I don't see why we should be trying to work out the id again when it's passed as a param.
54 // In any case that won't work with the new map setup
55 //itemInstance->setAuxValue(level->getFreeAuxValueFor(L"map"));
56
57 id = wstring( L"map_" ) + _toString(itemInstance->getAuxValue() );
58 mapItemSavedData = shared_ptr<MapItemSavedData>( new MapItemSavedData(id) );
59
60 newData = true;
61 }
62
63 mapItemSavedData->scale = 3;
64#ifndef _LARGE_WORLDS
65 // 4J-PB - for Xbox maps, we'll centre them on the origin of the world, since we can fit the whole world in our map
66 mapItemSavedData->x = 0;
67 mapItemSavedData->z = 0;
68#endif
69
70 if( newData )
71 {
72#ifdef _LARGE_WORLDS
73 int scale = MapItemSavedData::MAP_SIZE * 2 * (1 << mapItemSavedData->scale);
74 mapItemSavedData->x = Math::round((float) level->getLevelData()->getXSpawn() / scale) * scale;
75 mapItemSavedData->z = Math::round(level->getLevelData()->getZSpawn() / scale) * scale;
76#endif
77 mapItemSavedData->dimension = (byte) level->dimension->id;
78
79 mapItemSavedData->setDirty();
80
81 level->setSavedData(id, (shared_ptr<SavedData> ) mapItemSavedData);
82 }
83
84 return mapItemSavedData;
85}
86
87void MapItem::update(Level *level, shared_ptr<Entity> player, shared_ptr<MapItemSavedData> data)
88{
89 if ( (level->dimension->id != data->dimension) || !player->instanceof(eTYPE_PLAYER) )
90 {
91 // Wrong dimension, abort
92 return;
93 }
94
95 int w = MapItem::IMAGE_WIDTH;
96 int h = MapItem::IMAGE_HEIGHT;
97
98 int scale = 1 << data->scale;
99
100 int xo = data->x;
101 int zo = data->z;
102
103 int xp = Mth::floor(player->x - xo) / scale + w / 2;
104 int zp = Mth::floor(player->z - zo) / scale + h / 2;
105
106 int rad = 128 / scale;
107 if (level->dimension->hasCeiling)
108 {
109 rad /= 2;
110 }
111 shared_ptr<MapItemSavedData::HoldingPlayer> hp = data->getHoldingPlayer(dynamic_pointer_cast<Player>(player));
112 hp->step++;
113
114 for (int x = xp - rad + 1; x < xp + rad; x++)
115 {
116 if ((x & 15) != (hp->step & 15)) continue;
117
118 int yd0 = 255;
119 int yd1 = 0;
120
121 double ho = 0;
122 for (int z = zp - rad - 1; z < zp + rad; z++)
123 {
124 if (x < 0 || z < -1 || x >= w || z >= h) continue;
125
126 int xd = x - xp;
127 int zd = z - zp;
128
129 bool ditherBlack = xd * xd + zd * zd > (rad - 2) * (rad - 2);
130
131 int xx = (xo / scale + x - w / 2) * scale;
132 int zz = (zo / scale + z - h / 2) * scale;
133
134 int count[256];
135 memset( count,0,sizeof(int)*256);
136
137 LevelChunk *lc = level->getChunkAt(xx, zz);
138 if(lc->isEmpty()) continue;
139 int xso = ((xx)) & 15;
140 int zso = ((zz)) & 15;
141 int liquidDepth = 0;
142
143 double hh = 0;
144 if (level->dimension->hasCeiling)
145 {
146 int ss = xx + zz * 231871;
147 ss = ss * ss * 31287121 + ss * 11;
148 if (((ss >> 20) & 1) == 0) count[Tile::dirt_Id] += 10;
149 else count[Tile::stone_Id] += 10;
150 hh = 100;
151 }
152 else
153 {
154 for (int xs = 0; xs < scale; xs++)
155 {
156 for (int zs = 0; zs < scale; zs++)
157 {
158 int yy = lc->getHeightmap(xs + xso, zs + zso) + 1;
159 int t = 0;
160 if (yy > 1)
161 {
162 bool ok = false;
163 do
164 {
165 ok = true;
166 t = lc->getTile(xs + xso, yy - 1, zs + zso);
167 if (t == 0) ok = false;
168 else if (yy > 0 && t > 0 && Tile::tiles[t]->material->color == MaterialColor::none)
169 {
170 ok = false;
171 }
172
173 if (!ok)
174 {
175 yy--;
176 if (yy <= 0) break;
177 t = lc->getTile(xs + xso, yy - 1, zs + zso);
178 }
179
180 } while (yy > 0 && !ok);
181
182 if (yy > 0 && t != 0 && Tile::tiles[t]->material->isLiquid())
183 {
184 int y = yy - 1;
185 int below = 0;
186 do
187 {
188 below = lc->getTile(xs + xso, y--, zs + zso);
189 liquidDepth++;
190 } while (y > 0 && below != 0 && Tile::tiles[below]->material->isLiquid());
191 }
192 }
193 hh += yy / (double) (scale * scale);
194
195 count[t]++;
196 }
197 }
198 }
199 liquidDepth /= scale * scale;
200
201 int best = 0;
202 int tBest = 0;
203 for (int j = 0; j < 256; j++)
204 {
205 if (count[j] > best)
206 {
207 tBest = j;
208 best = count[j];
209 }
210 }
211
212 double diff = ((hh - ho) * 4 / (scale + 4)) + (((x + z) & 1) - 0.5) * 0.4;
213 int br = 1;
214 if (diff > +0.6) br = 2;
215 if (diff < -0.6) br = 0;
216
217 int col = 0;
218 if (tBest > 0)
219 {
220 MaterialColor *mc = Tile::tiles[tBest]->material->color;
221 if (mc == MaterialColor::water)
222 {
223 diff = (liquidDepth * 0.1) + ((x + z) & 1) * 0.2;
224 br = 1;
225 if (diff < 0.5) br = 2;
226 if (diff > 0.9) br = 0;
227 }
228 col = mc->id;
229 }
230
231 ho = hh;
232
233 if (z < 0) continue;
234 if (xd * xd + zd * zd >= rad * rad) continue;
235 if (ditherBlack && ((x + z) & 1) == 0)
236 {
237 continue;
238 }
239 byte oldColor = data->colors[x + z * w];
240 byte newColor = (byte) (col * 4 + br);
241 if (oldColor != newColor)
242 {
243 if (yd0 > z) yd0 = z;
244 if (yd1 < z) yd1 = z;
245 data->colors[x + z * w] = newColor;
246 }
247 }
248 if (yd0 <= yd1)
249 {
250 data->setDirty(x, yd0, yd1);
251 }
252 }
253}
254
255void MapItem::inventoryTick(shared_ptr<ItemInstance> itemInstance, Level *level, shared_ptr<Entity> owner, int slot, bool selected)
256{
257 if (level->isClientSide) return;
258
259 shared_ptr<MapItemSavedData> data = getSavedData(itemInstance, level);
260 if ( owner->instanceof(eTYPE_PLAYER) )
261 {
262 shared_ptr<Player> player = dynamic_pointer_cast<Player>(owner);
263
264 // 4J Stu - If the player has a map that belongs to another player, then merge the data over and change this map id to the owners id
265 int ownersAuxValue = level->getAuxValueForMap(player->getXuid(), data->dimension, data->x, data->z, data->scale);
266 if(ownersAuxValue != itemInstance->getAuxValue() )
267 {
268 shared_ptr<MapItemSavedData> ownersData = getSavedData(ownersAuxValue,level);
269
270 ownersData->x = data->x;
271 ownersData->z = data->z;
272 ownersData->scale = data->scale;
273 ownersData->dimension = data->dimension;
274
275 itemInstance->setAuxValue( ownersAuxValue );
276 ownersData->tickCarriedBy(player, itemInstance );
277 ownersData->mergeInMapData(data);
278 player->inventoryMenu->broadcastChanges();
279
280 data = ownersData;
281 }
282 else
283 {
284 data->tickCarriedBy(player, itemInstance);
285 }
286 }
287
288 if (selected)
289 {
290 update(level, owner, data);
291 }
292}
293
294shared_ptr<Packet> MapItem::getUpdatePacket(shared_ptr<ItemInstance> itemInstance, Level *level, shared_ptr<Player> player)
295{
296 charArray data = MapItem::getSavedData(itemInstance, level)->getUpdatePacket(itemInstance, level, player);
297
298 if (data.data == NULL || data.length == 0) return nullptr;
299
300 shared_ptr<Packet> retval = shared_ptr<Packet>(new ComplexItemDataPacket((short) Item::map->id, (short) itemInstance->getAuxValue(), data));
301 delete data.data;
302 return retval;
303}
304
305void MapItem::onCraftedBy(shared_ptr<ItemInstance> itemInstance, Level *level, shared_ptr<Player> player)
306{
307 wchar_t buf[64];
308
309 int mapScale = 3;
310#ifdef _LARGE_WORLDS
311 int scale = MapItemSavedData::MAP_SIZE * 2 * (1 << mapScale);
312 int centreXC = (int) (Math::round(player->x / scale) * scale);
313 int centreZC = (int) (Math::round(player->z / scale) * scale);
314#else
315 // 4J-PB - for Xbox maps, we'll centre them on the origin of the world, since we can fit the whole world in our map
316 int centreXC = 0;
317 int centreZC = 0;
318#endif
319
320 itemInstance->setAuxValue(level->getAuxValueForMap(player->getXuid(), player->dimension, centreXC, centreZC, mapScale));
321
322 swprintf(buf,64,L"map_%d", itemInstance->getAuxValue());
323 std::wstring id = wstring(buf);
324
325 shared_ptr<MapItemSavedData> data = getSavedData(itemInstance->getAuxValue(), level);
326 // 4J Stu - We only have one map per player per dimension, so don't reset the one that they have
327 // when a new one is created
328 if( data == NULL )
329 {
330 data = shared_ptr<MapItemSavedData>( new MapItemSavedData(id) );
331 }
332 level->setSavedData(id, (shared_ptr<SavedData> ) data);
333
334 data->scale = mapScale;
335 // 4J-PB - for Xbox maps, we'll centre them on the origin of the world, since we can fit the whole world in our map
336 data->x = centreXC;
337 data->z = centreZC;
338 data->dimension = (byte) level->dimension->id;
339 data->setDirty();
340}
341
342// 4J - Don't want
343/*
344void appendHoverText(ItemInstance itemInstance, Player player, List<String> lines, boolean advanced) {
345 MapItemSavedData data = getSavedData(itemInstance, player.level);
346
347 if (advanced) {
348 if (data == null) {
349 lines.add("Unknown map");
350 } else {
351 lines.add("Scaling at 1:" + (1 << data.scale));
352 lines.add("(Level " + data.scale + "/" + MapItemSavedData.MAX_SCALE + ")");
353 }
354 }
355}
356*/