the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 356 lines 10 kB view raw
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*/