1
0
mirror of https://github.com/chylex/Hardcore-Ender-Expansion-2.git synced 2025-02-27 15:46:01 +01:00

Implement Jar o' Dust generation in Tomb Dungeon

This commit is contained in:
chylex 2020-12-30 13:16:02 +01:00
parent 414b11aa0d
commit dd6f4fa4d1
11 changed files with 156 additions and 28 deletions

View File

@ -23,12 +23,12 @@ import java.util.Random
import kotlin.math.max
import kotlin.math.min
enum class TombDungeonLevel(val isFancy: Boolean, private val corridorFactor: Int, val mainRooms: IntRange, val sideRooms: IntRange) {
FIRST (isFancy = false, corridorFactor = 1, mainRooms = 0..0, sideRooms = 0..0),
SECOND(isFancy = false, corridorFactor = 5, mainRooms = 1..1, sideRooms = 1..1),
THIRD (isFancy = false, corridorFactor = 2, mainRooms = 0..0, sideRooms = 2..3),
FOURTH(isFancy = true, corridorFactor = 4, mainRooms = 2..2, sideRooms = 1..1),
LAST (isFancy = true, corridorFactor = 6, mainRooms = 1..1, sideRooms = 0..1);
enum class TombDungeonLevel(val isFancy: Boolean, private val corridorFactor: Int, val mainRooms: IntRange, val sideRooms: IntRange, val dustPerRoom: IntRange) {
FIRST (isFancy = false, corridorFactor = 1, mainRooms = 0..0, sideRooms = 0..0, dustPerRoom = 8..15),
SECOND(isFancy = false, corridorFactor = 5, mainRooms = 1..1, sideRooms = 1..1, dustPerRoom = 9..21),
THIRD (isFancy = false, corridorFactor = 2, mainRooms = 0..0, sideRooms = 2..3, dustPerRoom = 10..32),
FOURTH(isFancy = true, corridorFactor = 4, mainRooms = 2..2, sideRooms = 1..1, dustPerRoom = 15..40),
LAST (isFancy = true, corridorFactor = 6, mainRooms = 1..1, sideRooms = 0..1, dustPerRoom = 20..48);
fun getMainCorridorLength(rand: Random): Int {
return rand.nextInt(45 + (corridorFactor * 2), 57) + (2 * (6 - corridorFactor)) + ((corridorFactor - 1) * rand.nextFloat(12.5F, 14.2F)).floorToInt() + (if (this == LAST) 10 else 0)

View File

@ -21,12 +21,13 @@ import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Side_Cros
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Side_CrossroadsLounge
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Side_Fountain
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Side_Shelves
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_Mass
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_MassSpacious
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_MultiDeep
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_MultiNarrow
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_MultiSpacious
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_Single
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_SingleNarrow
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb_SingleSpacious
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonSecret
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonSecret_CornerShelf
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonSecret_LootChest
@ -314,28 +315,32 @@ object TombDungeonPieces : IStructureDescription {
TombDungeonRoom_Side_Arches("side.arches.nbt", isFancy = true)
)
private fun TOMB(file: String, entranceY: Int): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy = it) }
}
private fun TOMB_MASS(width: Int, depth: Int, border: Boolean, split: Boolean): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_Mass(width, depth, border, split, isFancy = it) }
}
private fun TOMB_MASS_SPACIOUS(file: String): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_MassSpacious(file, entranceY = 1, allowSecrets = false, isFancy = it) }
return { TombDungeonRoom_Tomb_MassSpacious(file, entranceY = 1, isFancy = it) }
}
private fun TOMB_MULTI_NARROW(file: String, tombsPerColumn: Int): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_MultiNarrow(file, tombsPerColumn, entranceY = 1, isFancy = it) }
}
private fun TOMB_MULTI_DEEP(file: String, tombsPerColumn: Int): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_MultiDeep(file, tombsPerColumn, entranceY = 2, allowSecrets = false, isFancy = it) }
return { TombDungeonRoom_Tomb_MultiDeep(file, tombsPerColumn, entranceY = 2, isFancy = it) }
}
private fun TOMB_MULTI_SPACIOUS(file: String, tombsPerColumn: Int): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_MultiSpacious(file, tombsPerColumn, entranceY = 2, allowSecrets = false, isFancy = it) }
return { TombDungeonRoom_Tomb_MultiSpacious(file, tombsPerColumn, entranceY = 2, isFancy = it) }
}
private fun TOMB_SINGLE(file: String): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_Single(file, entranceY = 2, allowSecrets = false, isFancy = it) }
private fun TOMB_SINGLE_NARROW(file: String): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_SingleNarrow(file, entranceY = 2, isFancy = it) }
}
private fun TOMB_SINGLE_SPACIOUS(file: String): (Boolean) -> TombDungeonAbstractPiece {
return { TombDungeonRoom_Tomb_SingleSpacious(file, entranceY = 2, isFancy = it) }
}
fun TOMB_RANDOM(rand: Random, options: WeightedList<(Boolean) -> TombDungeonAbstractPiece>): (Boolean) -> TombDungeonAbstractPiece {
@ -395,10 +400,10 @@ object TombDungeonPieces : IStructureDescription {
)
val PIECE_TOMB_RANDOM_MULTI_NARROW = weightedListOf(
1 to TOMB("tomb.multi.narrow_4x2.nbt", entranceY = 1),
3 to TOMB("tomb.multi.narrow_5x2.nbt", entranceY = 1),
3 to TOMB("tomb.multi.narrow_6x2.nbt", entranceY = 1),
2 to TOMB("tomb.multi.narrow_7x2.nbt", entranceY = 1)
1 to TOMB_MULTI_NARROW("tomb.multi.narrow_4x2.nbt", tombsPerColumn = 4),
3 to TOMB_MULTI_NARROW("tomb.multi.narrow_5x2.nbt", tombsPerColumn = 5),
3 to TOMB_MULTI_NARROW("tomb.multi.narrow_6x2.nbt", tombsPerColumn = 6),
2 to TOMB_MULTI_NARROW("tomb.multi.narrow_7x2.nbt", tombsPerColumn = 7)
)
val PIECE_TOMB_RANDOM_MULTI_DEEP_SHORT = weightedListOf(
@ -420,8 +425,8 @@ object TombDungeonPieces : IStructureDescription {
2 to TOMB_MULTI_SPACIOUS("tomb.multi.spacious_7x2.nbt", tombsPerColumn = 7)
)
val PIECE_TOMB_SINGLE_NARROW = TOMB_SINGLE("tomb.single.narrow.nbt")
val PIECE_TOMB_SINGLE_SPACIOUS = TOMB_SINGLE("tomb.single.spacious.nbt")
val PIECE_TOMB_SINGLE_NARROW = TOMB_SINGLE_NARROW("tomb.single.narrow.nbt")
val PIECE_TOMB_SINGLE_SPACIOUS = TOMB_SINGLE_SPACIOUS("tomb.single.spacious.nbt")
override val ALL_PIECES
get() = arrayOf(

View File

@ -1,7 +1,10 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.block.entity.TileEntityJarODust
import chylex.hee.game.block.with
import chylex.hee.game.block.withFacing
import chylex.hee.game.mechanics.dust.DustLayers
import chylex.hee.game.mechanics.dust.DustType
import chylex.hee.game.world.Pos
import chylex.hee.game.world.distanceSqTo
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
@ -13,11 +16,14 @@ import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.game.world.structure.piece.StructurePiece
import chylex.hee.game.world.structure.trigger.TileEntityStructureTrigger
import chylex.hee.init.ModBlocks
import chylex.hee.system.collection.MutableWeightedList.Companion.mutableWeightedListOf
import chylex.hee.system.facades.Facing6
import chylex.hee.system.math.floorToInt
import chylex.hee.system.migration.BlockSlab
import chylex.hee.system.migration.TileEntityChest
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextItem
import chylex.hee.system.random.nextRounded
import net.minecraft.block.Blocks
import net.minecraft.state.properties.SlabType
import net.minecraft.util.Direction
@ -114,4 +120,46 @@ abstract class TombDungeonAbstractPiece : StructurePiece<TombDungeonLevel>() {
world.addTrigger(pos, TileEntityStructureTrigger(Blocks.CHEST.withFacing(facing), chest))
}
protected fun placeJars(world: IStructureWorld, instance: Instance, availablePositions: List<BlockPos>) {
val rand = world.rand
val level = instance.context ?: TombDungeonLevel.FIRST
val jars = availablePositions
.filter(world::isAir)
.ifEmpty { return }
.shuffled(rand)
.take(1 + rand.nextRounded(0.34F) + rand.nextRounded(0.27F))
.map { it to DustLayers(TileEntityJarODust.DUST_CAPACITY) }
var dustAmount = rand.nextInt(level.dustPerRoom)
val dustTypeCount = if (level.isFancy)
1 + rand.nextRounded(0.4F) + rand.nextRounded(0.25F)
else
1 + rand.nextRounded(0.3F)
val dustTypePool = mutableWeightedListOf(
8 to DustType.SUGAR,
8 to DustType.GUNPOWDER,
7 to DustType.ANCIENT_DUST,
7 to DustType.REDSTONE,
6 to DustType.END_POWDER,
)
val dustTypes = Array(dustTypeCount) {
dustTypePool.removeItem(rand)!!
}
while(dustAmount > 0) {
val takenAmount = if (dustAmount <= 24) dustAmount else rand.nextInt(12, dustAmount - 12)
dustAmount -= takenAmount
rand.nextItem(jars).second.addDust(rand.nextItem(dustTypes), takenAmount)
}
for((jarPos, jarLayers) in jars) {
if (jarLayers.contents.isNotEmpty()) {
world.addTrigger(jarPos, TileEntityStructureTrigger(ModBlocks.JAR_O_DUST, TileEntityJarODust().apply { layers.deserializeNBT(jarLayers.serializeNBT()) }))
}
}
}
}

View File

@ -6,7 +6,7 @@ import chylex.hee.game.world.feature.tombdungeon.connection.TombDungeonConnectio
import chylex.hee.game.world.structure.piece.IStructurePieceConnection
import chylex.hee.system.migration.Facing.SOUTH
open class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom(file, isFancy) {
abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom(file, isFancy) {
final override val secretAttachWeight = if (allowSecrets) 2 else 0
final override val secretAttachY = entranceY

View File

@ -31,6 +31,7 @@ class TombDungeonRoom_Tomb_Mass(width: Int, depth: Int, private val border: Bool
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
val rand = world.rand
val centerX = size.centerX
val maxX = size.maxX
val maxY = size.maxY
@ -53,6 +54,10 @@ class TombDungeonRoom_Tomb_Mass(width: Int, depth: Int, private val border: Bool
world.setBlock(Pos(centerX, 1, maxZ - 1), ModBlocks.DUSTY_STONE)
}
if (rand.nextInt(6) == 0 && (border || split)) {
placeJars(world, instance, listOf(Pos(centerX, 2, 1)))
}
placeCobwebs(world, instance)
}
}

View File

@ -1,11 +1,12 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.NORTH
import chylex.hee.system.random.nextInt
class TombDungeonRoom_Tomb_MassSpacious(file: String, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets, isFancy) {
class TombDungeonRoom_Tomb_MassSpacious(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@ -19,5 +20,16 @@ class TombDungeonRoom_Tomb_MassSpacious(file: String, entranceY: Int, allowSecre
placeChest(world, instance, Pos(chestX, 3, maxZ - 2), NORTH)
}
val jarChance = if (instance.context.let { it == null || it < TombDungeonLevel.THIRD }) 5 else 3
if (rand.nextInt(jarChance) == 0) {
val jarX = if (rand.nextBoolean())
rand.nextInt(1, 3)
else
maxX - rand.nextInt(1, 3)
placeJars(world, instance, listOf(Pos(jarX, 3, maxZ - 2)))
}
}
}

View File

@ -8,7 +8,7 @@ import chylex.hee.system.migration.Facing.WEST
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextRounded
class TombDungeonRoom_Tomb_MultiDeep(file: String, private val tombsPerColumn: Int, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets, isFancy) {
class TombDungeonRoom_Tomb_MultiDeep(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@ -27,5 +27,14 @@ class TombDungeonRoom_Tomb_MultiDeep(file: String, private val tombsPerColumn: I
placeChest(world, instance, pos, facing)
}
}
if (rand.nextBoolean()) {
placeJars(world, instance, (0 until tombsPerColumn).flatMap {
listOf(
Pos(centerX - 4, 3, 4 + (2 * it)),
Pos(centerX + 4, 3, 4 + (2 * it))
)
})
}
}
}

View File

@ -0,0 +1,21 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.structure.IStructureWorld
class TombDungeonRoom_Tomb_MultiNarrow(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
val rand = world.rand
if (rand.nextInt(10) < 4) {
placeJars(world, instance, (0 until tombsPerColumn).flatMap {
listOf(
Pos(centerX - 3, 3, 2 + (2 * it)),
Pos(centerX + 3, 3, 2 + (2 * it))
)
})
}
}
}

View File

@ -8,7 +8,7 @@ import chylex.hee.system.migration.Facing.WEST
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextRounded
class TombDungeonRoom_Tomb_MultiSpacious(file: String, private val tombsPerColumn: Int, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets, isFancy) {
class TombDungeonRoom_Tomb_MultiSpacious(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@ -27,5 +27,14 @@ class TombDungeonRoom_Tomb_MultiSpacious(file: String, private val tombsPerColum
placeChest(world, instance, pos, facing)
}
}
if (rand.nextInt(100) < 65) {
placeJars(world, instance, (0 until tombsPerColumn).flatMap {
listOf(
Pos(centerX - 4, 4, 3 + (3 * it)),
Pos(centerX + 4, 4, 3 + (3 * it))
)
})
}
}
}

View File

@ -4,7 +4,7 @@ import chylex.hee.game.world.Pos
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.SOUTH
class TombDungeonRoom_Tomb_Single(file: String, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets, isFancy) {
open class TombDungeonRoom_Tomb_SingleNarrow(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)

View File

@ -0,0 +1,19 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.structure.IStructureWorld
class TombDungeonRoom_Tomb_SingleSpacious(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb_SingleNarrow(file, entranceY, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
val rand = world.rand
if (rand.nextInt(10) < 7) {
placeJars(world, instance, listOf(
Pos(centerX - 2, 4, if (rand.nextBoolean()) maxZ - 3 else maxZ - 4),
Pos(centerX + 2, 4, if (rand.nextBoolean()) maxZ - 3 else maxZ - 4),
))
}
}
}