the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 266 lines 8.1 kB view raw
1#include "stdafx.h" 2#include "StrongholdFeature.h" 3#include "StrongholdPieces.h" 4#include "net.minecraft.world.level.h" 5#include "net.minecraft.world.level.biome.h" 6#include "net.minecraft.world.level.dimension.h" 7#include "Mth.h" 8#include "FileHeader.h" 9#include "JavaMath.h" 10 11const wstring StrongholdFeature::OPTION_DISTANCE = L"distance"; 12const wstring StrongholdFeature::OPTION_COUNT = L"count"; 13const wstring StrongholdFeature::OPTION_SPREAD = L"spread"; 14 15vector<Biome *> StrongholdFeature::allowedBiomes; 16 17void StrongholdFeature::staticCtor() 18{ 19 allowedBiomes.push_back(Biome::desert); 20 allowedBiomes.push_back(Biome::forest); 21 allowedBiomes.push_back(Biome::extremeHills); 22 allowedBiomes.push_back(Biome::swampland); 23 allowedBiomes.push_back(Biome::taiga); 24 allowedBiomes.push_back(Biome::iceFlats); 25 allowedBiomes.push_back(Biome::iceMountains); 26 allowedBiomes.push_back(Biome::desertHills); 27 allowedBiomes.push_back(Biome::forestHills); 28 allowedBiomes.push_back(Biome::smallerExtremeHills); 29 allowedBiomes.push_back(Biome::taigaHills); 30 allowedBiomes.push_back(Biome::jungle); 31 allowedBiomes.push_back(Biome::jungleHills); 32}; 33 34void StrongholdFeature::_init() 35{ 36 distance = 32; 37 spread = 3; 38 39 // 4J added initialisers 40 for (int i = 0; i < strongholdPos_length; i++) 41 { 42 strongholdPos[i] = NULL; 43 } 44 isSpotSelected = false; 45} 46 47StrongholdFeature::StrongholdFeature() : StructureFeature() 48{ 49 _init(); 50} 51 52StrongholdFeature::StrongholdFeature(unordered_map<wstring, wstring> options) 53{ 54 _init(); 55 56 for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) 57 { 58 if (it->first.compare(OPTION_DISTANCE) == 0) 59 { 60 distance = Mth::getDouble(it->second, distance, 1); 61 } 62 else if (it->first.compare(OPTION_COUNT) == 0) 63 { 64 // 4J-JEV: Removed, we only have the one stronghold. 65 //strongholdPos = new ChunkPos[ Mth::getInt(it->second, strongholdPos_length, 1) ]; 66 assert(false); 67 } 68 else if (it->first.compare(OPTION_SPREAD) == 0) 69 { 70 spread = Mth::getInt(it->second, spread, 1); 71 } 72 } 73} 74 75StrongholdFeature::~StrongholdFeature() 76{ 77 for (int i = 0; i < strongholdPos_length; i++) 78 { 79 delete strongholdPos[i]; 80 } 81} 82 83wstring StrongholdFeature::getFeatureName() 84{ 85 return LargeFeature::STRONGHOLD; 86} 87 88bool StrongholdFeature::isFeatureChunk(int x, int z,bool bIsSuperflat) 89{ 90 if (!isSpotSelected) 91 { 92 Random random; 93 94 random.setSeed(level->getSeed()); 95 double angle = random.nextDouble() * PI * 2.0; 96 int circle = 1; 97 98 // 4J Stu - Changed so that we keep trying more until we have found somewhere in the world to place a stronghold 99 bool hasFoundValidPos = false; 100 int findAttempts = 0; 101 do 102 { 103 for (int i = 0; i < strongholdPos_length; i++) 104 { 105 double dist = 0.0; 106#ifdef _LARGE_WORLDS 107 if(level->dimension->getXZSize() < (2.25f * 32.0f) ) 108 { 109 // Xbox360/PS3 distances 110 dist = (1.25 + random.nextDouble()) * (3 + random.nextInt(4)); 111 } 112 else 113 { 114 // Original Java 115 dist = (1.25 * circle + random.nextDouble()) * (distance * circle); 116 } 117#else 118 // 4J Stu - Design change: Original spawns at *32 chunks rather than *10 chunks from (0,0) but that is outside our world 119 // double dist = (1.25 + random->nextDouble()) * 32.0; 120 // The max of the first part is 2.25, and we have 27 chunks in each direction 121 // Therefore 27/2.25 = 12, which should be the max of the second part 122 // The constant part and random part can be tuned to move the strongholds further from the spawn 123 // 4J Stu - The original (pre-TU9) calculation for selecting a start point could put the stronghold very close to the edge 124 // of the world, causing some parts to fail to generate. If the save is a newer save then we bring that generation in 125 if(level->getOriginalSaveVersion() >= SAVE_FILE_VERSION_MOVED_STRONGHOLD) 126 { 127 // Post TU9 128 // The stronghold cannot extend more than 7 chunks in any direction from the start position 129 // Therefore as long as the the start x/z are less than 20 it will be fully contained 130 dist = (1.25 + random.nextDouble()) * (3 + random.nextInt(4)); 131 } 132 else 133 { 134 // Pre TU9 135 dist = (1.25 + random.nextDouble()) * (5.0 + random.nextInt(7)); 136 } 137#endif 138 139 int selectedX = (int) (Math::round(cos(angle) * dist)); 140 int selectedZ = (int) (Math::round(sin(angle) * dist)); 141 142 TilePos *position = level->getBiomeSource()->findBiome((selectedX << 4) + 8, (selectedZ << 4) + 8, 7 << 4, allowedBiomes, &random); 143 if (position != NULL) 144 { 145 selectedX = position->x >> 4; 146 selectedZ = position->z >> 4; 147 148#ifndef _CONTENT_PACKAGE 149 if(position->x > 2560 || position->x < -2560 || position->z > 2560 || position->z < -2560) 150 { 151 __debugbreak(); 152 } 153#endif 154 155 app.DebugPrintf("Placed stronghold in valid biome at (%d, %d), (%d, %d)\n", selectedX, selectedZ, position->x, position->z); 156 // 4J added 157 app.AddTerrainFeaturePosition(eTerrainFeature_Stronghold,selectedX,selectedZ); 158 159 // 4J Added 160 hasFoundValidPos = true; 161 delete position; 162 } 163 164 delete strongholdPos[i]; 165 strongholdPos[i] = new ChunkPos(selectedX, selectedZ); 166 167 angle += PI * 2.0 / (double) strongholdPos_length; 168 } 169 170 // 4J Stu - We want to make sure that we have at least one stronghold in this world 171 ++findAttempts; 172 173 // 4J Stu - Randomise the angles for retries as well 174#ifdef _LARGE_WORLDS 175 angle = random.nextDouble() * PI * 2.0 * circle / (double) spread; 176#endif 177 } 178 while(!hasFoundValidPos && findAttempts < MAX_STRONGHOLD_ATTEMPTS); 179 180 if(!hasFoundValidPos) 181 { 182 // Even if it's not a valid position we are still creating the last one we tried, so store it in the save so Eye of Ender works 183 // Fix for #81933 - GAMEPLAY: The Eye of Ender occasionally does not appear when used to try and locate the End Portal. 184 app.AddTerrainFeaturePosition(eTerrainFeature_Stronghold,strongholdPos[0]->x,strongholdPos[0]->z); 185 } 186 187 isSpotSelected = true; 188 } 189 190 for (int i = 0; i < strongholdPos_length; i++) 191 { 192 bool forcePlacement = false; 193 LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions(); 194 if( levelGenOptions != NULL ) 195 { 196 forcePlacement = levelGenOptions->isFeatureChunk(x,z,eFeature_Stronghold); 197 } 198 199 ChunkPos *pos = strongholdPos[i]; 200 if (forcePlacement || (pos && x == pos->x && z == pos->z) ) 201 { 202 return true; 203 } 204 } 205 return false; 206} 207 208vector<TilePos> *StrongholdFeature::getGuesstimatedFeaturePositions() 209{ 210 vector<TilePos> *positions = new vector<TilePos>(); 211 for( int i = 0; i < strongholdPos_length; i++ ) 212 { 213 ChunkPos *chunkPos = strongholdPos[i]; 214 if (chunkPos != NULL) 215 { 216 positions->push_back(chunkPos->getMiddleBlockPosition(64)); 217 } 218 } 219 return positions; 220} 221 222StructureStart *StrongholdFeature::createStructureStart(int x, int z) 223{ 224 225 StrongholdStart *start = new StrongholdStart(level, random, x, z); 226 227 // 4J - front() was get(0) 228 while (start->getPieces()->empty() || ((StrongholdPieces::StartPiece *) start->getPieces()->front())->portalRoomPiece == NULL) 229 { 230 delete start; 231 // regenerate stronghold without changing seed 232 start = new StrongholdStart(level, random, x, z); 233 } 234 235 return start; 236 237 // System.out.println("Creating stronghold at (" + x + ", " + z + ")"); 238 // return new StrongholdStart(level, random, x, z); 239} 240 241StrongholdFeature::StrongholdStart::StrongholdStart() 242{ 243 // for reflection 244} 245 246StrongholdFeature::StrongholdStart::StrongholdStart(Level *level, Random *random, int chunkX, int chunkZ) : StructureStart(chunkX, chunkZ) 247{ 248 StrongholdPieces::resetPieces(); 249 250 StrongholdPieces::StartPiece *startRoom = new StrongholdPieces::StartPiece(0, random, (chunkX << 4) + 2, (chunkZ << 4) + 2, level); 251 pieces.push_back(startRoom); 252 startRoom->addChildren(startRoom, &pieces, random); 253 254 vector<StructurePiece *> *pendingChildren = &startRoom->pendingChildren; 255 while (!pendingChildren->empty()) 256 { 257 int pos = random->nextInt((int)pendingChildren->size()); 258 AUTO_VAR(it, pendingChildren->begin() + pos); 259 StructurePiece *structurePiece = *it; 260 pendingChildren->erase(it); 261 structurePiece->addChildren(startRoom, &pieces, random); 262 } 263 264 calculateBoundingBox(); 265 moveBelowSeaLevel(level, random, 10); 266}