Compare commits

...

3 Commits

Author SHA1 Message Date
cb9ae35260
fix: lost item 2023-07-03 15:47:02 +08:00
94be2a823f
fix: sleeping 2023-07-03 15:41:17 +08:00
175659bcdc
feat: spawn projected people 2023-07-03 15:31:00 +08:00
5 changed files with 39 additions and 15 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,8 +20,10 @@ 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
} else {
return@Trigger false
} }
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(),
) )
@ -110,6 +110,7 @@ object ProjectedPersonAI {
private fun initCoreActivity(brain: Brain<ProjectedPersonEntity>) { private fun initCoreActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity( brain.addActivity(
Activity.CORE, ImmutableList.of( Activity.CORE, ImmutableList.of(
0 weight UpdateActivityFromSchedule.create(),
0 weight Swim(0.8f), 0 weight Swim(0.8f),
0 weight WakeUp.create(), 0 weight WakeUp.create(),
0 weight StopAttackingIfTargetInvalid.create(), 0 weight StopAttackingIfTargetInvalid.create(),
@ -130,7 +131,6 @@ object ProjectedPersonAI {
brain.addActivity( brain.addActivity(
Activity.IDLE, ImmutableList.of( Activity.IDLE, ImmutableList.of(
10 weight createStrollBehavior(), 10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
) )
) )
} }
@ -141,7 +141,6 @@ object ProjectedPersonAI {
7 weight GoToWantedItem.create(1.75f, true, 32), 7 weight GoToWantedItem.create(1.75f, true, 32),
10 weight JumpOnBed(1.0f), 10 weight JumpOnBed(1.0f),
10 weight createStrollBehavior(), 10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
) )
) )
} }
@ -149,9 +148,8 @@ object ProjectedPersonAI {
private fun initWorkActivity(brain: Brain<ProjectedPersonEntity>) { private fun initWorkActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity( brain.addActivity(
Activity.WORK, ImmutableList.of( Activity.WORK, ImmutableList.of(
7 weight ExchangeItem(), 5 weight ExchangeItem(),
10 weight createStrollBehavior(), 10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
) )
) )
} }
@ -160,8 +158,8 @@ object ProjectedPersonAI {
brain.addActivity( brain.addActivity(
Activity.REST, ImmutableList.of( Activity.REST, ImmutableList.of(
0 weight SleepInBed(), 0 weight SleepInBed(),
5 weight GoToTargetLocation.create(MemoryModuleType.NEAREST_BED, 1, 1.05f), 3 weight GoToTargetLocation.create(MemoryModuleType.NEAREST_BED, 1, 1.05f),
5 weight RunOne( 3 weight RunOne(
mapOf( mapOf(
MemoryModuleType.HOME to MemoryStatus.VALUE_ABSENT MemoryModuleType.HOME to MemoryStatus.VALUE_ABSENT
), ),
@ -169,7 +167,6 @@ object ProjectedPersonAI {
1 weightR createStrollBehavior() 1 weightR createStrollBehavior()
) )
), ),
99 weight UpdateActivityFromSchedule.create(),
) )
) )
} }

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))
} }