1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
|
package galacticgreg;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
import net.minecraft.util.Vec3;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraftforge.common.ChestGenHooks;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.eventhandler.EventBus;
import cpw.mods.fml.common.registry.GameRegistry;
import galacticgreg.api.AsteroidBlockComb;
import galacticgreg.api.BlockMetaComb;
import galacticgreg.api.Enums;
import galacticgreg.api.GTOreTypes;
import galacticgreg.api.ISpaceObjectGenerator;
import galacticgreg.api.ModDimensionDef;
import galacticgreg.api.SpecialBlockComb;
import galacticgreg.api.StructureInformation;
import galacticgreg.auxiliary.GTOreGroup;
import galacticgreg.dynconfig.DynamicDimensionConfig;
import galacticgreg.registry.GalacticGregRegistry;
import gregtech.api.util.GTLog;
import gregtech.api.world.GTWorldgen;
import gregtech.common.GTWorldgenerator;
public class WorldGeneratorSpace implements IWorldGenerator {
public static boolean sAsteroids = true;
private final EventBus eventBus = new EventBus();
private World worldObj;
private int chunkX;
private int chunkZ;
private int mSize = 100;
private long mProfilingStart;
private long mProfilingEnd;
public WorldGeneratorSpace() {
GameRegistry.registerWorldGenerator(this, Integer.MAX_VALUE);
}
public void generate(Random pRandom, int pX, int pZ, World pWorld, IChunkProvider pChunkGenerator,
IChunkProvider pChunkProvider) {
pX *= 16;
pZ *= 16;
String tBiome = pWorld.getBiomeGenForCoords(pX + 8, pZ + 8).biomeName;
pRandom = new Random(pRandom.nextInt());
if (tBiome == null) {
tBiome = BiomeGenBase.plains.biomeName;
}
GalacticGreg.Logger
.trace("Triggered generate: [ChunkGenerator %s] [Biome %s]", pChunkGenerator.toString(), tBiome);
ModDimensionDef tDimDef = GalacticGregRegistry.getDimensionTypeByChunkGenerator(pChunkGenerator);
if (tDimDef == null) {
GalacticGreg.Logger.trace(
"Ignoring ChunkGenerator type %s as there is no definition for it in the registry",
pChunkGenerator.toString());
return;
} else {
GalacticGreg.Logger.trace("Selected DimDef: [%s]", tDimDef.getDimIdentifier());
}
/*
* In some later addons maybe, not for now. Ignoring Biome-based worldgen String tBiome =
* pWorld.getBiomeGenForCoords(pX + 8, pZ + 8).biomeName; pRandom = new Random(pRandom.nextInt()); if (tBiome ==
* null) { tBiome = BiomeGenBase.plains.biomeName; }
*/
if (tDimDef.getDimensionType() != Enums.DimensionType.Planet) {
if (tDimDef.getRandomAsteroidMaterial() == null) GalacticGreg.Logger.error(
"Dimension [%s] is set to Asteroids, but no asteroid material is specified! Nothing will generate",
tDimDef.getDimensionName());
else Generate_Asteroids(tDimDef, pRandom, pWorld, pX, pZ);
} else if (tDimDef.getDimensionType() != Enums.DimensionType.Asteroid) {
Generate_OreVeins(tDimDef, pRandom, pWorld, pX, pZ, "", pChunkGenerator, pChunkProvider);
}
Chunk tChunk = pWorld.getChunkFromBlockCoords(pX, pZ);
if (tChunk != null) {
tChunk.isModified = true;
}
}
private void Generate_Asteroids(ModDimensionDef pDimensionDef, Random pRandom, World pWorld, int pX, int pZ) {
GalacticGreg.Logger.trace("Running asteroid-gen in Dim %s", pDimensionDef.getDimIdentifier());
DynamicDimensionConfig.AsteroidConfig tAConf = DynamicDimensionConfig.getAsteroidConfig(pDimensionDef);
if (tAConf == null) {
GalacticGreg.Logger.error(
"Dimension %s is set to asteroid, but no config object can be found. Skipping!",
pDimensionDef.getDimIdentifier());
return;
} else {
GalacticGreg.Logger.trace("Asteroid probability: %d", tAConf.Probability);
}
if ((tAConf.Probability <= 1) || (pRandom.nextInt(tAConf.Probability) == 0)) {
GalacticGreg.Logger.trace("Generating asteroid NOW");
// ---------------------------
if (GalacticGreg.GalacticConfig.ProfileOreGen) mProfilingStart = System.currentTimeMillis();
// -----------------------------
// Get Random position
int tX = pX + pRandom.nextInt(16);
int tY = 50 + pRandom.nextInt(200 - 50);
int tZ = pZ + pRandom.nextInt(16);
// Check if position is free
if ((pWorld.getBlock(tX, tY, tZ)
.isAir(pWorld, tX, tY, tZ))) {
int tCustomAsteroidOffset = -1;
int tGraniteMeta = 0;
// Select Random OreGroup and Asteroid Material
GTOreGroup tOreGroup = WorldgenOreLayerSpace.getRandomOreGroup(pDimensionDef, pRandom, true);
AsteroidBlockComb tABComb = pDimensionDef.getRandomAsteroidMaterial();
if (tABComb == null) return;
// Fill Vars for random Asteroid
Block tFinalAsteroidBlock = tABComb.getBlock();
int tFinalAsteroidBlockMeta = tABComb.getMeta();
int tFinalOreOffset = tABComb.getOreMaterial()
.getOffset();
int tFinalUpdateMode = tABComb.getOreMaterial()
.getUpdateMode();
GalacticGreg.Logger.debug(
"Asteroid will be build with: Block: [%s] OreType: [%s]",
Block.blockRegistry.getNameForObject(tABComb.getBlock()),
tABComb.getOreMaterial()
.toString());
// get random Ore-asteroid generator from the list of registered generators
ISpaceObjectGenerator aGen = pDimensionDef.getRandomSOGenerator(Enums.SpaceObjectType.OreAsteroid);
if (aGen == null) {
GalacticGreg.Logger.ot_error(
"GalacticGreg.Generate_Asteroids.NoSOGenFound",
"No SpaceObjectGenerator has been registered for type ORE_ASTEROID in Dimension %s. Nothing will generate",
pDimensionDef.getDimensionName());
return;
}
aGen.reset();
aGen.setCenterPoint(tX, tY, tZ);
aGen.randomize(tAConf.MinSize, tAConf.MaxSize); // Initialize random values and set size
aGen.calculate(); // Calculate structure
// Random loot-chest somewhere in the asteroid
Vec3 tChestPosition = Vec3.createVectorHelper(0, 0, 0);
boolean tDoLootChest = false;
int tNumLootItems = 0;
if (tAConf.LootChestChance > 0) {
GalacticGreg.Logger.trace("Random loot chest enabled, flipping the coin");
int tChance = pRandom.nextInt(100); // Loot chest is 1 in 100 (Was: 1:1000 which actually never
// happend)
if (tAConf.LootChestChance >= tChance) {
GalacticGreg.Logger.debug("We got a match. Preparing to generate the loot chest");
// Get amount of items for the loot chests, randomize it (1-num) if enabled
if (tAConf.RandomizeNumLootItems) tNumLootItems = pRandom.nextInt(tAConf.NumLootItems - 1) + 1;
else tNumLootItems = tAConf.NumLootItems;
GalacticGreg.Logger
.debug(String.format("Loot chest random item count will be: %d", tNumLootItems));
// try to find any block that is not on the asteroids outer-shell
GalacticGreg.Logger.trace("Starting lookup for valid asteroid-block for the chest");
for (int x = 0; x < 64; x++) // 64 enough? Should be
{
int tRndBlock = pRandom.nextInt(
aGen.getStructure()
.size());
StructureInformation tChestSI = aGen.getStructure()
.get(tRndBlock);
if (tChestSI.getBlockPosition() != Enums.TargetBlockPosition.AsteroidShell) {
GalacticGreg.Logger.debug(
String.format(
"Chest position found [x:%d y:%d z:%d]",
tChestSI.getX(),
tChestSI.getY(),
tChestSI.getZ()));
// Found valid position "Somewhere" in the asteroid, set position...
tChestPosition = Vec3
.createVectorHelper(tChestSI.getX(), tChestSI.getY(), tChestSI.getZ());
// .. and set CreateFlag to true
tDoLootChest = true;
break;
}
}
}
}
// Now build the structure
GalacticGreg.Logger.trace("Now generating Space-Structure");
for (StructureInformation si : aGen.getStructure()) {
// Only replace airblocks
if (pWorld.isAirBlock(si.getX(), si.getY(), si.getZ())) {
// === Loot-chest generator >>
if (tDoLootChest) // If gen-lootchest enabled...
{
// Check if current x/y/z is the location where the chest shall be created
if ((int) tChestPosition.xCoord == si.getX() && (int) tChestPosition.yCoord == si.getY()
&& (int) tChestPosition.zCoord == si.getZ()) {
GalacticGreg.Logger.trace("Now generating LootChest and contents");
// Get items for the configured loot-table
WeightedRandomChestContent[] tRandomLoot = ChestGenHooks
.getItems(DynamicDimensionConfig.getLootChestTable(tAConf), pRandom);
// Get chest-block to spawn
BlockMetaComb tTargetChestType = GalacticGreg.GalacticConfig.CustomLootChest;
// Place down the chest
if (tTargetChestType.getMeta() > 0) pWorld.setBlock(
si.getX(),
si.getY(),
si.getZ(),
tTargetChestType.getBlock(),
tTargetChestType.getMeta(),
2);
else pWorld.setBlock(si.getX(), si.getY(), si.getZ(), tTargetChestType.getBlock());
// Retrieve the TEs IInventory that should've been created
IInventory entityChestInventory = (IInventory) pWorld
.getTileEntity(si.getX(), si.getY(), si.getZ());
// If it's not null...
if (entityChestInventory != null) {
// and if we're on the server...
if (!pWorld.isRemote) {
// Fill the chest with stuffz!
WeightedRandomChestContent.generateChestContents(
pRandom,
tRandomLoot,
entityChestInventory,
tNumLootItems);
GalacticGreg.Logger.trace("Loot chest successfully generated");
}
} else {
// Something made a boo..
GalacticGreg.Logger.warn(
"Could not create lootchest at X[%d] Y[%d] Z[%d]. getTileEntity() returned null",
si.getX(),
si.getY(),
si.getZ());
}
// Make sure we never compare coordinates again (for this asteroid/Structure)
tDoLootChest = false;
// Do some debug logging
GalacticGreg.Logger
.debug("Generated LootChest at X[%d] Y[%d] Z[%d]", si.getX(), si.getY(), si.getZ());
// And skip the rest of this function
continue;
}
}
// << Loot-chest generator ===
// === Ore generator >>
boolean tPlacedOreBlock = false;
// If a valid oregroup has been selected (more than 0 ore-veins are enabled for this dim)
if (tOreGroup != null) {
// GalacticGreg.Logger.trace("tOreGoup is populated, continuing");
// Choose a number between 0 and 100
int ranOre = pRandom.nextInt(100);
int tFinalOreMeta = 0;
// If choosen number is below the configured orechance, do random between and sporadic
if (ranOre < tAConf.OreChance) {
if (pRandom.nextBoolean()) {
// Only take as final value if meta is not zero
if (tOreGroup.SporadicBetweenMeta > 0)
tFinalOreMeta = tOreGroup.SporadicBetweenMeta;
} else {
// Only take as final value if meta is not zero
if (tOreGroup.SporadicAroundMeta > 0) tFinalOreMeta = tOreGroup.SporadicAroundMeta;
}
}
// If choosen number is below the configured orechance, do random primary and secondary
// We use an offset here, so this part is always higher than the first check.
else if (ranOre < tAConf.OreChance + tAConf.OrePrimaryOffset) {
if (pRandom.nextBoolean()) {
// Only take as final value if meta is not zero
if (tOreGroup.PrimaryMeta > 0) tFinalOreMeta = tOreGroup.PrimaryMeta;
} else {
// Only take as final value if meta is not zero
if (tOreGroup.SecondaryMeta > 0) tFinalOreMeta = tOreGroup.SecondaryMeta;
}
}
// if the final oreMeta has been found...
// GalacticGreg.Logger.info("tFinalOreMeta is %d", tFinalOreMeta);
if (tFinalOreMeta > 0) {
// make sure we obey the configured "HiddenOres" setting (No ores on the shell)
if (tAConf.HiddenOres
&& (si.getBlockPosition() == Enums.TargetBlockPosition.AsteroidShell)) {
// Ore would be placed around the shell, which is disabled (hiddenores)
GalacticGreg.Logger.trace(
"Skipping ore-placement event (HiddenOres=true; TargetBlockPosition=AsteroidShell)");
} else {
// try to place the ore block. The result is stored in tPlacedOreBlock
tPlacedOreBlock = TileEntitySpaceOres.setOuterSpaceOreBlock(
pDimensionDef,
pWorld,
si.getX(),
si.getY(),
si.getZ(),
tOreGroup.SecondaryMeta,
true,
tFinalOreOffset);
}
}
}
// << Ore generator ===
// === Additional special blocks >>
// If no ore-block has been placed yet...
if (!tPlacedOreBlock) {
// try to spawn special blocks
boolean tFlag = doGenerateSpecialBlocks(
pDimensionDef,
pRandom,
pWorld,
tAConf,
si.getX(),
si.getY(),
si.getZ(),
si.getBlockPosition());
// No special block placed? Try smallores
if (tFlag) tFlag = doGenerateSmallOreBlock(
pDimensionDef,
pRandom,
pWorld,
tAConf,
si.getX(),
si.getY(),
si.getZ(),
tFinalOreOffset);
// no smallores either? do normal block
if (tFlag) pWorld.setBlock(
si.getX(),
si.getY(),
si.getZ(),
tFinalAsteroidBlock,
tFinalAsteroidBlockMeta,
tFinalUpdateMode);
}
// << Additional special blocks ===
}
}
}
// ---------------------------
// OreGen profiler stuff
if (GalacticGreg.GalacticConfig.ProfileOreGen) {
try {
mProfilingEnd = System.currentTimeMillis();
long tTotalTime = mProfilingEnd - mProfilingStart;
GalacticGreg.Profiler.AddTimeToList(pDimensionDef, tTotalTime);
GalacticGreg.Logger.debug(
"Done with Asteroid-Worldgen in DimensionType %s. Generation took %d ms",
pDimensionDef.getDimensionName(),
tTotalTime);
} catch (Exception ignored) {} // Silently ignore errors
}
// ---------------------------
}
GalacticGreg.Logger.trace("Leaving asteroid-gen for Dim %s", pDimensionDef.getDimIdentifier());
}
/**
* Generate Special Blocks in asteroids if enabled
*
* @param pDimensionDef
* @param pRandom
* @param pWorld
* @param tAConf
* @param eX
* @param eY
* @param eZ
* @return
*/
private boolean doGenerateSpecialBlocks(ModDimensionDef pDimensionDef, Random pRandom, World pWorld,
DynamicDimensionConfig.AsteroidConfig tAConf, int eX, int eY, int eZ,
Enums.TargetBlockPosition pBlockPosition) {
boolean tFlag = true;
// Handler to generate special BlockTypes randomly if activated
if (tAConf.SpecialBlockChance > 0) {
if (pRandom.nextInt(100) < tAConf.SpecialBlockChance) {
SpecialBlockComb bmc = pDimensionDef.getRandomSpecialAsteroidBlock();
if (bmc != null) {
boolean tIsAllowed = false;
switch (bmc.getBlockPosition()) {
case AsteroidCore:
if (pBlockPosition == Enums.TargetBlockPosition.AsteroidCore) tIsAllowed = true;
break;
case AsteroidCoreAndShell:
if (pBlockPosition == Enums.TargetBlockPosition.AsteroidCore
|| pBlockPosition == Enums.TargetBlockPosition.AsteroidShell) tIsAllowed = true;
break;
case AsteroidShell:
if (pBlockPosition == Enums.TargetBlockPosition.AsteroidShell) tIsAllowed = true;
break;
case AsteroidInnerCore:
if (pBlockPosition == Enums.TargetBlockPosition.AsteroidInnerCore) tIsAllowed = true;
break;
default:
break;
}
if (tIsAllowed) {
pWorld.setBlock(eX, eY, eZ, bmc.getBlock(), bmc.getMeta(), 2);
tFlag = false;
}
}
}
}
return tFlag;
}
/**
* Pick a random small-ore block from the list of enabled small ores for this dim
*
* @param pDimDef
* @param pRandom
* @return
*/
private boolean doGenerateSmallOreBlock(ModDimensionDef pDimDef, Random pRandom, World pWorld,
DynamicDimensionConfig.AsteroidConfig pAConf, int pX, int pY, int pZ, int pTargetBlockOffset) {
boolean tFlag = true;
// If smallores are enabled...
if (pAConf.SmallOreChance > 0) {
// ... and we hit the random-chance ...
if (pRandom.nextInt(100) < pAConf.SmallOreChance) {
// Do small ores.
int tRandomWeight;
boolean continueSearch = true;
int tFoundOreMeta = -1;
// First find a small ore...
for (int i = 0; (i < 256) && (continueSearch); i++) {
tRandomWeight = pRandom.nextInt(WorldgenOreLayerSpace.sWeight);
for (GTWorldgen tWorldGen : GalacticGreg.smallOreWorldgenList) {
if (!(tWorldGen instanceof WorldgenOreSmallSpace)) {
continue;
}
// That is enabled for *this* dim...
if (!((WorldgenOreSmallSpace) tWorldGen).isEnabledForDim(pDimDef)) continue;
// And in the correct y-level, of ObeyLimits is true...
if (pAConf.ObeyHeightLimits && !((WorldgenOreSmallSpace) tWorldGen).isAllowedForHeight(pY))
continue;
// Care about weight
tRandomWeight -= ((WorldgenOreSmallSpace) tWorldGen).mAmount;
if (tRandomWeight <= 0) {
// And return found ore meta
tFoundOreMeta = ((WorldgenOreSmallSpace) tWorldGen).mMeta;
continueSearch = false;
}
}
}
if (tFoundOreMeta > -1) {
// Make the oreID a small ore with correct type
int tCustomOffset = (GTOreTypes.SmallOres.getOffset() + pTargetBlockOffset);
// Set the smallOre block
TileEntitySpaceOres
.setOuterSpaceOreBlock(pDimDef, pWorld, pX, pY, pZ, tFoundOreMeta, true, tCustomOffset);
tFlag = false;
}
}
}
return tFlag;
}
/**
* Untested! But should work... Comments are todo
*
* @param pDimensionDef
* @param pRandom
* @param pWorld
* @param pX
* @param pZ
* @param pBiome
* @param pChunkGenerator
* @param pChunkProvider
*/
private void Generate_OreVeins(ModDimensionDef pDimensionDef, Random pRandom, World pWorld, int pX, int pZ,
String pBiome, IChunkProvider pChunkGenerator, IChunkProvider pChunkProvider) {
GalacticGreg.Logger.trace("Running orevein-gen in Dim %s", pDimensionDef.getDimIdentifier());
if (GTWorldgenerator.isOreChunk(pX / 16, pZ / 16)) {
if ((WorldgenOreLayerSpace.sWeight > 0) && (GalacticGreg.oreVeinWorldgenList.size() > 0)) {
boolean temp = true;
int tRandomWeight;
for (int i = 0; (i < 256) && (temp); i++) {
tRandomWeight = pRandom.nextInt(WorldgenOreLayerSpace.sWeight);
for (GTWorldgen tWorldGen : GalacticGreg.oreVeinWorldgenList) {
if (tWorldGen instanceof WorldgenOreLayerSpace)
tRandomWeight -= ((WorldgenOreLayerSpace) tWorldGen).mWeight;
if (tRandomWeight <= 0) {
try {
if (tWorldGen.executeWorldgen(
pWorld,
pRandom,
pBiome,
Integer.MIN_VALUE,
pX,
pZ,
pChunkGenerator,
pChunkProvider)) {
temp = false;
}
} catch (Throwable e) {
e.printStackTrace(GTLog.err);
}
break;
}
}
}
}
// Generate Small Ores
int i = 0;
for (int tX = pX - 16; i < 3; tX += 16) {
int j = 0;
for (int tZ = pZ - 16; j < 3; tZ += 16) {
for (GTWorldgen tWorldGen : GalacticGreg.smallOreWorldgenList) {
try {
tWorldGen.executeWorldgen(
pWorld,
pRandom,
"",
Integer.MIN_VALUE,
tX,
tZ,
pChunkGenerator,
pChunkProvider);
} catch (Throwable e) {
e.printStackTrace(GTLog.err);
}
}
j++;
}
i++;
}
}
GalacticGreg.Logger.trace("Leaving orevein-gen for Dim %s", pDimensionDef.getDimIdentifier());
}
}
|