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 "VillageFeature.h"
3#include "VillagePieces.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
8const wstring VillageFeature::OPTION_SIZE_MODIFIER = L"size";
9const wstring VillageFeature::OPTION_SPACING = L"distance";
10
11vector<Biome *> VillageFeature::allowedBiomes;
12
13void VillageFeature::staticCtor()
14{
15 allowedBiomes.push_back( Biome::plains );
16 allowedBiomes.push_back( Biome::desert );
17}
18
19void VillageFeature::_init(int iXZSize)
20{
21 villageSizeModifier = 0;
22 townSpacing = 32;
23 minTownSeparation = 8;
24
25 m_iXZSize=iXZSize;
26}
27
28VillageFeature::VillageFeature(int iXZSize)
29{
30 _init(iXZSize);
31}
32
33VillageFeature::VillageFeature(unordered_map<wstring, wstring> options, int iXZSize)
34{
35 _init(iXZSize);
36
37 for (AUTO_VAR(it,options.begin()); it != options.end(); ++it)
38 {
39 if (it->first.compare(OPTION_SIZE_MODIFIER) == 0)
40 {
41 villageSizeModifier = Mth::getInt(it->second, villageSizeModifier, 0);
42 }
43 else if (it->first.compare(OPTION_SPACING) == 0)
44 {
45 townSpacing = Mth::getInt(it->second, townSpacing, minTownSeparation + 1);
46 }
47 }
48}
49
50wstring VillageFeature::getFeatureName()
51{
52 return L"Village";
53}
54
55bool VillageFeature::isFeatureChunk(int x, int z,bool bIsSuperflat)
56{
57 int townSpacing = this->townSpacing;
58
59 if(!bIsSuperflat
60#ifdef _LARGE_WORLDS
61 && level->dimension->getXZSize() < 128
62#endif
63 )
64 {
65 townSpacing= 16;// 4J change 32;
66 }
67
68 int xx = x;
69 int zz = z;
70 if (x < 0) x -= townSpacing - 1;
71 if (z < 0) z -= townSpacing - 1;
72
73 int xCenterTownChunk = x / townSpacing;
74 int zCenterTownChunk = z / townSpacing;
75 Random *r = level->getRandomFor(xCenterTownChunk, zCenterTownChunk, 10387312);
76 xCenterTownChunk *= townSpacing;
77 zCenterTownChunk *= townSpacing;
78 xCenterTownChunk += r->nextInt(townSpacing - minTownSeparation);
79 zCenterTownChunk += r->nextInt(townSpacing - minTownSeparation);
80 x = xx;
81 z = zz;
82
83 bool forcePlacement = false;
84 LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions();
85 if( levelGenOptions != NULL )
86 {
87 forcePlacement = levelGenOptions->isFeatureChunk(x,z,eFeature_Village);
88 }
89
90 if (forcePlacement || (x == xCenterTownChunk && z == zCenterTownChunk) )
91 {
92 bool biomeOk = level->getBiomeSource()->containsOnly(x * 16 + 8, z * 16 + 8, 0, allowedBiomes);
93 if (biomeOk)
94 {
95 //app.DebugPrintf("Biome ok for Village at %d, %d\n",(x * 16 + 8),(z * 16 + 8));
96 return true;
97 }
98 }
99
100 return false;
101}
102
103StructureStart *VillageFeature::createStructureStart(int x, int z)
104{
105 // 4J added
106 app.AddTerrainFeaturePosition(eTerrainFeature_Village,x,z);
107
108 return new VillageStart(level, random, x, z, villageSizeModifier, m_iXZSize);
109}
110
111VillageFeature::VillageStart::VillageStart()
112{
113 valid = false; // 4J added initialiser
114 m_iXZSize = 0;
115 // for reflection
116}
117
118VillageFeature::VillageStart::VillageStart(Level *level, Random *random, int chunkX, int chunkZ, int villageSizeModifier, int iXZSize)
119{
120 valid = false; // 4J added initialiser
121 m_iXZSize=iXZSize;
122
123 list<VillagePieces::PieceWeight *> *pieceSet = VillagePieces::createPieceSet(random, villageSizeModifier);
124
125 VillagePieces::StartPiece *startRoom = new VillagePieces::StartPiece(level->getBiomeSource(), 0, random, (chunkX << 4) + 2, (chunkZ << 4) + 2, pieceSet, villageSizeModifier, level);
126 pieces.push_back(startRoom);
127 startRoom->addChildren(startRoom, &pieces, random);
128
129 vector<StructurePiece *> *pendingRoads = &startRoom->pendingRoads;
130 vector<StructurePiece *> *pendingHouses = &startRoom->pendingHouses;
131 while (!pendingRoads->empty() || !pendingHouses->empty())
132 {
133
134 // prioritize roads
135 if (pendingRoads->empty())
136 {
137 int pos = random->nextInt((int)pendingHouses->size());
138 AUTO_VAR(it, pendingHouses->begin() + pos);
139 StructurePiece *structurePiece = *it;
140 pendingHouses->erase(it);
141 structurePiece->addChildren(startRoom, &pieces, random);
142 }
143 else
144 {
145 int pos = random->nextInt((int)pendingRoads->size());
146 AUTO_VAR(it, pendingRoads->begin() + pos);
147 StructurePiece *structurePiece = *it;
148 pendingRoads->erase(it);
149 structurePiece->addChildren(startRoom, &pieces, random);
150 }
151 }
152
153 calculateBoundingBox();
154
155 int count = 0;
156 for( AUTO_VAR(it, pieces.begin()); it != pieces.end(); it++ )
157 {
158 StructurePiece *piece = *it;
159 if (dynamic_cast<VillagePieces::VillageRoadPiece *>(piece) == NULL)
160 {
161 count++;
162 }
163 }
164 valid = count > 2;
165}
166
167bool VillageFeature::VillageStart::isValid()
168{
169 // 4J-PB - Adding a bounds check to ensure a village isn't over the edge of our world - we end up with half houses in that case
170 if((boundingBox->x0<(-m_iXZSize/2)) || (boundingBox->x1>(m_iXZSize/2)) || (boundingBox->z0<(-m_iXZSize/2)) || (boundingBox->z1>(m_iXZSize/2)))
171 {
172 valid=false;
173 }
174 return valid;
175}
176
177void VillageFeature::VillageStart::addAdditonalSaveData(CompoundTag *tag)
178{
179 StructureStart::addAdditonalSaveData(tag);
180
181 tag->putBoolean(L"Valid", valid);
182}
183
184void VillageFeature::VillageStart::readAdditonalSaveData(CompoundTag *tag)
185{
186 StructureStart::readAdditonalSaveData(tag);
187 valid = tag->getBoolean(L"Valid");
188}