From 175659bcdcad9133f467cf7500c7f6aba96b78f7 Mon Sep 17 00:00:00 2001 From: xtex Date: Mon, 3 Jul 2023 15:31:00 +0800 Subject: [PATCH] feat: spawn projected people --- .../projection/swarm/SwarmProjectionEffect.kt | 20 ++++++++++++++++++- .../projection/swarm/ai/ExchangeItem.kt | 4 ++-- .../quaedam/projection/swarm/ai/LostItem.kt | 4 ++-- .../projection/swarm/ai/ProjectedPersonAI.kt | 2 +- .../quaedam/projector/ProjectorBlockEntity.kt | 9 ++++++++- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt b/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt index 05120ff..01683ea 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt @@ -3,10 +3,14 @@ package quaedam.projection.swarm import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag 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.projector.ProjectorBlockEntity +import kotlin.math.min data class SwarmProjectionEffect( - var maxCount: Int = 10, + var maxCount: Int = 100, ) : ProjectionEffect() { companion object { @@ -25,6 +29,20 @@ data class SwarmProjectionEffect( } 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) + } + } } } diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ai/ExchangeItem.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/ExchangeItem.kt index b7e96d3..7c87f5d 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ai/ExchangeItem.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/ExchangeItem.kt @@ -29,6 +29,7 @@ class ExchangeItem : Behavior( target = entity.brain.getMemory(NearestVisibleContainer.memory.get()).get() closeAt = null 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) = @@ -54,6 +55,7 @@ class ExchangeItem : Behavior( override fun stop(level: ServerLevel, entity: E, l: Long) { entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET) + entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE) if (closeAt != null) { // opened val chest = level.getBlockEntity(target!!)!! @@ -108,13 +110,11 @@ class ExchangeItem : Behavior( val targetItem = container.getItem(target) if (targetItem.isEmpty) { container.setItem(target, takeItem.copyAndClear()) - println("put all at $target") break } } } val putCount = takeCount - takeItem.count - println("put $putCount") item.shrink(putCount) container.setItem(slot, item) } diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ai/LostItem.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/LostItem.kt index a15f421..5aebe7c 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ai/LostItem.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/LostItem.kt @@ -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.declarative.BehaviorBuilder 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.schedule.Activity -import net.minecraft.world.level.block.Block @Suppress("FunctionName") fun LostItem(chance: Int): OneShot @@ -20,7 +20,7 @@ fun LostItem(chance: Int): OneShot val count = level.random.nextInt(item.count) item.shrink(count) 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 }) diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt index 10d870a..db2f207 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt @@ -76,8 +76,8 @@ object ProjectedPersonAI { listOf( SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, - SensorType.HURT_BY, SensorType.NEAREST_ITEMS, + SensorType.HURT_BY, BedInChunkSensor.sensor.get(), NearestVisibleContainer.sensor.get(), ) diff --git a/common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt b/common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt index 9f5a641..5e41e76 100644 --- a/common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt +++ b/common/src/main/kotlin/quaedam/projector/ProjectorBlockEntity.kt @@ -12,6 +12,7 @@ import net.minecraft.world.level.ChunkPos import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.levelgen.structure.BoundingBox +import net.minecraft.world.phys.AABB import quaedam.projection.ProjectionEffect import quaedam.projection.ProjectionEffectType import quaedam.projection.ProjectionProvider @@ -27,13 +28,19 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) : } val effectArea: BoundingBox by lazy { - val chunk = level!!.getChunk(pos).pos val (minChunk, maxChunk) = effectAreaChunk val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ) val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ) 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 { BoundingBox.fromCorners(pos.offset(-2, -1, -2), pos.offset(2, -2, 2)) }