feat: spawn projected people

This commit is contained in:
xtex 2023-07-03 15:31:00 +08:00
parent e13d5ff178
commit 175659bcdc
Signed by: xtex
GPG Key ID: B918086ED8045B91
5 changed files with 32 additions and 7 deletions

View File

@ -3,10 +3,14 @@ package quaedam.projection.swarm
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.MobSpawnType
import net.minecraft.world.level.levelgen.Heightmap
import quaedam.projection.ProjectionEffect import quaedam.projection.ProjectionEffect
import quaedam.projector.ProjectorBlockEntity
import kotlin.math.min
data class SwarmProjectionEffect( data class SwarmProjectionEffect(
var maxCount: Int = 10, var maxCount: Int = 100,
) : ProjectionEffect() { ) : ProjectionEffect() {
companion object { companion object {
@ -25,6 +29,20 @@ data class SwarmProjectionEffect(
} }
override fun randomTick(level: ServerLevel, pos: BlockPos) { override fun randomTick(level: ServerLevel, pos: BlockPos) {
val projector = level.getBlockEntity(pos) as ProjectorBlockEntity
val entities = level.getEntitiesOfClass(ProjectedPersonEntity::class.java, projector.effectAreaAABB).size
if (entities < maxCount) {
val area = projector.effectArea
for (i in 0..(min(level.random.nextInt(maxCount - entities), 6))) {
var spawnPos = BlockPos(
level.random.nextInt(area.minX(), area.maxX()),
level.random.nextInt(area.minY(), area.maxY()),
level.random.nextInt(area.minZ(), area.maxZ()),
)
spawnPos = spawnPos.atY(level.getHeight(Heightmap.Types.WORLD_SURFACE, spawnPos.x, spawnPos.z))
ProjectedPersonEntity.entity.get().spawn(level, spawnPos, MobSpawnType.TRIGGERED)
}
}
} }
} }

View File

@ -29,6 +29,7 @@ class ExchangeItem<E> : Behavior<E>(
target = entity.brain.getMemory(NearestVisibleContainer.memory.get()).get() target = entity.brain.getMemory(NearestVisibleContainer.memory.get()).get()
closeAt = null closeAt = null
entity.brain.setMemory(MemoryModuleType.WALK_TARGET, WalkTarget(target!!, 1.0f, 2)) entity.brain.setMemory(MemoryModuleType.WALK_TARGET, WalkTarget(target!!, 1.0f, 2))
entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
} }
override fun canStillUse(level: ServerLevel, entity: E, l: Long) = override fun canStillUse(level: ServerLevel, entity: E, l: Long) =
@ -54,6 +55,7 @@ class ExchangeItem<E> : Behavior<E>(
override fun stop(level: ServerLevel, entity: E, l: Long) { override fun stop(level: ServerLevel, entity: E, l: Long) {
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET) entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET)
entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
if (closeAt != null) { if (closeAt != null) {
// opened // opened
val chest = level.getBlockEntity(target!!)!! val chest = level.getBlockEntity(target!!)!!
@ -108,13 +110,11 @@ class ExchangeItem<E> : Behavior<E>(
val targetItem = container.getItem(target) val targetItem = container.getItem(target)
if (targetItem.isEmpty) { if (targetItem.isEmpty) {
container.setItem(target, takeItem.copyAndClear()) container.setItem(target, takeItem.copyAndClear())
println("put all at $target")
break break
} }
} }
} }
val putCount = takeCount - takeItem.count val putCount = takeCount - takeItem.count
println("put $putCount")
item.shrink(putCount) item.shrink(putCount)
container.setItem(slot, item) container.setItem(slot, item)
} }

View File

@ -4,9 +4,9 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.OneShot import net.minecraft.world.entity.ai.behavior.OneShot
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.npc.InventoryCarrier import net.minecraft.world.entity.npc.InventoryCarrier
import net.minecraft.world.entity.schedule.Activity import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.level.block.Block
@Suppress("FunctionName") @Suppress("FunctionName")
fun <E> LostItem(chance: Int): OneShot<E> fun <E> LostItem(chance: Int): OneShot<E>
@ -20,7 +20,7 @@ fun <E> LostItem(chance: Int): OneShot<E>
val count = level.random.nextInt(item.count) val count = level.random.nextInt(item.count)
item.shrink(count) item.shrink(count)
inventory.setChanged() inventory.setChanged()
Block.popResource(level, entity.blockPosition(), item.copyWithCount(count)) level.addFreshEntity(ItemEntity(level, entity.x, entity.y + 0.25, entity.z, item.copyWithCount(count)))
} }
return@Trigger true return@Trigger true
}) })

View File

@ -76,8 +76,8 @@ object ProjectedPersonAI {
listOf( listOf(
SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_LIVING_ENTITIES,
SensorType.NEAREST_PLAYERS, SensorType.NEAREST_PLAYERS,
SensorType.HURT_BY,
SensorType.NEAREST_ITEMS, SensorType.NEAREST_ITEMS,
SensorType.HURT_BY,
BedInChunkSensor.sensor.get(), BedInChunkSensor.sensor.get(),
NearestVisibleContainer.sensor.get(), NearestVisibleContainer.sensor.get(),
) )

View File

@ -12,6 +12,7 @@ import net.minecraft.world.level.ChunkPos
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.levelgen.structure.BoundingBox import net.minecraft.world.level.levelgen.structure.BoundingBox
import net.minecraft.world.phys.AABB
import quaedam.projection.ProjectionEffect import quaedam.projection.ProjectionEffect
import quaedam.projection.ProjectionEffectType import quaedam.projection.ProjectionEffectType
import quaedam.projection.ProjectionProvider import quaedam.projection.ProjectionProvider
@ -27,13 +28,19 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
} }
val effectArea: BoundingBox by lazy { val effectArea: BoundingBox by lazy {
val chunk = level!!.getChunk(pos).pos
val (minChunk, maxChunk) = effectAreaChunk val (minChunk, maxChunk) = effectAreaChunk
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ) val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ) val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
BoundingBox.fromCorners(minBlock, maxBlock) BoundingBox.fromCorners(minBlock, maxBlock)
} }
val effectAreaAABB by lazy {
val (minChunk, maxChunk) = effectAreaChunk
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
AABB(minBlock, maxBlock)
}
val checkArea: BoundingBox by lazy { val checkArea: BoundingBox by lazy {
BoundingBox.fromCorners(pos.offset(-2, -1, -2), pos.offset(2, -2, 2)) BoundingBox.fromCorners(pos.offset(-2, -1, -2), pos.offset(2, -2, 2))
} }