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

Implement Undread spawning in Forgotten Tombs

This commit is contained in:
chylex 2020-12-30 00:11:12 +01:00
parent 14fbcac4e0
commit 414b11aa0d
3 changed files with 109 additions and 2 deletions
src/main/java/chylex/hee/game

View File

@ -22,6 +22,8 @@ import net.minecraft.block.BlockState
import net.minecraft.enchantment.EnchantmentHelper
import net.minecraft.enchantment.Enchantments
import net.minecraft.entity.Entity
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
import net.minecraft.entity.EntityType
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockReader
import net.minecraft.world.World
@ -133,6 +135,10 @@ class BlockDustyStoneUnstable(builder: BlockBuilder) : BlockDustyStone(builder),
super.onFallenUpon(world, pos, entity, fallDistance)
}
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, placementType: PlacementType, entityType: EntityType<*>?): Boolean {
return super.canCreatureSpawn(state, world, pos, placementType, entityType) && getCrumbleStartPos(world, pos) == null
}
private fun isNonCreative(entity: Entity): Boolean {
return entity !is EntityPlayer || !entity.isCreative
}

View File

@ -4,18 +4,30 @@ import chylex.hee.client.MC
import chylex.hee.client.render.lightmaps.ILightmap
import chylex.hee.client.render.lightmaps.ILightmap.Companion.calcLightFactor
import chylex.hee.client.render.territory.components.SkyPlaneTopFoggy
import chylex.hee.game.entity.living.EntityMobUndread
import chylex.hee.game.entity.lookPosVec
import chylex.hee.game.entity.selectAllEntities
import chylex.hee.game.particle.ParticleDust
import chylex.hee.game.particle.spawner.ParticleSpawnerCustom
import chylex.hee.game.particle.spawner.properties.IOffset.InBox
import chylex.hee.game.particle.spawner.properties.IShape.Point
import chylex.hee.game.world.Pos
import chylex.hee.game.world.allInCenteredBoxMutable
import chylex.hee.game.world.center
import chylex.hee.game.world.distanceSqTo
import chylex.hee.game.world.isFullBlock
import chylex.hee.game.world.offsetUntil
import chylex.hee.game.world.territory.ITerritoryDescription
import chylex.hee.game.world.territory.ITerritoryTicker
import chylex.hee.game.world.territory.TerritoryDifficulty
import chylex.hee.game.world.territory.TerritoryInstance
import chylex.hee.game.world.territory.TerritoryType
import chylex.hee.game.world.territory.generators.Generator_ForgottenTombs
import chylex.hee.game.world.territory.properties.TerritoryColors
import chylex.hee.game.world.territory.properties.TerritoryEnvironment
import chylex.hee.game.world.territory.storage.TerritoryEntry
import chylex.hee.game.world.totalTime
import chylex.hee.init.ModEntities
import chylex.hee.system.color.IntColor.Companion.RGB
import chylex.hee.system.facades.Resource
import chylex.hee.system.forge.Side
@ -23,16 +35,30 @@ import chylex.hee.system.forge.Sided
import chylex.hee.system.math.LerpedFloat
import chylex.hee.system.math.Vec
import chylex.hee.system.math.Vec3
import chylex.hee.system.math.floorToInt
import chylex.hee.system.math.offsetTowards
import chylex.hee.system.math.square
import chylex.hee.system.migration.EntityPlayer
import chylex.hee.system.migration.Potions
import chylex.hee.system.random.nextFloat
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextItem
import net.minecraft.client.renderer.Vector3f
import net.minecraft.entity.EntitySpawnPlacementRegistry
import net.minecraft.entity.SpawnReason.NATURAL
import net.minecraft.util.Direction.UP
import net.minecraft.util.math.RayTraceContext
import net.minecraft.util.math.RayTraceContext.BlockMode
import net.minecraft.util.math.RayTraceContext.FluidMode
import net.minecraft.util.math.RayTraceResult.Type
import net.minecraft.world.Difficulty
import net.minecraft.world.LightType.BLOCK
import net.minecraft.world.LightType.SKY
import net.minecraft.world.World
import java.util.Random
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
object Territory_ForgottenTombs : ITerritoryDescription {
@ -156,4 +182,77 @@ object Territory_ForgottenTombs : ITerritoryDescription {
}
}
}
override fun initialize(instance: TerritoryInstance, entry: TerritoryEntry, tickers: MutableList<ITerritoryTicker>) {
super.initialize(instance, entry, tickers)
tickers.add(object : ITerritoryTicker {
override fun tick(world: World) {
if (world.difficulty == Difficulty.PEACEFUL || world.totalTime % 20L != 0L) {
return
}
val players = instance.players.filter { it.isAlive && !it.isSpectator }
if (players.isEmpty()) {
return
}
val maxUndreadsInTerritory = min(40, 10 + (10 * players.size))
val allUndreads = world.selectAllEntities.filter { it is EntityMobUndread && TerritoryInstance.fromPos(it) == instance }
if (allUndreads.size >= maxUndreadsInTerritory) {
return
}
val rand = world.rand
val maxY = TerritoryType.FORGOTTEN_TOMBS.height.last - Generator_ForgottenTombs.EntranceCave.ELLIPSOID_Y_OFFSET - 30 // roughly where the first level starts
val maxSpawns = min(3, maxUndreadsInTerritory - allUndreads.size)
for(spawn in 1..maxSpawns) {
val pickedPlayer = rand.nextItem(players)
val playerY = pickedPlayer.posY
if (playerY > maxY) {
continue
}
val playerDepth = maxY - pickedPlayer.posY
val maxUndreadsInDepth = 2 + (playerDepth * 0.28).floorToInt()
if (allUndreads.count { abs(it.posY - playerY) < 8 } >= maxUndreadsInDepth) {
continue
}
val spawnAttempts = 2 + (playerDepth * 0.1).floorToInt().coerceAtMost(5)
for(attempt in 1..spawnAttempts) {
val testPos = Pos(pickedPlayer).add(
rand.nextInt(-19, 19),
rand.nextInt(-8, 8),
rand.nextInt(-19, 19)
).offsetUntil(UP, -5..3) {
EntitySpawnPlacementRegistry.func_223515_a(ModEntities.UNDREAD, world, NATURAL, it, rand) &&
world.hasNoCollisions(ModEntities.UNDREAD.getBoundingBoxWithSizeApplied(it.x + 0.5, it.y.toDouble(), it.z + 0.5))
}
if (testPos == null || players.any { testPos.distanceSqTo(it) < square(15) }) {
continue
}
if (players.any { world.rayTraceBlocks(RayTraceContext(it.lookPosVec, testPos.center, BlockMode.OUTLINE, FluidMode.NONE, it)).type == Type.MISS }) {
continue
}
EntityMobUndread(world).apply {
setLocationAndAngles(testPos.x + 0.5, testPos.y.toDouble(), testPos.z + 0.5, rand.nextFloat(0F, 360F), 0F)
world.addEntity(this)
}
break
}
}
}
})
}
}

View File

@ -72,14 +72,16 @@ object Generator_ForgottenTombs : ITerritoryGenerator {
return TerritoryGenerationInfo(spawnPoint)
}
private object EntranceCave {
object EntranceCave {
const val RADIUS_XZ = 65
const val RADIUS_Y = 35
private const val EXTRA_ELEVATION = 2
const val ELLIPSOID_Y_OFFSET = (2 * RADIUS_Y) - EXTRA_ELEVATION
fun generate(world: SegmentedWorld, rand: Random, size: Size): BlockPos {
val ellipsoidBottom = size.maxY + EXTRA_ELEVATION - (2 * RADIUS_Y)
val ellipsoidBottom = size.maxY - ELLIPSOID_Y_OFFSET
val ellipsoidCenter = Pos(size.centerX, ellipsoidBottom + RADIUS_Y, size.centerZ + (size.z / 6))
Cutout.generate(world, rand, ellipsoidCenter)