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

View File

@ -29,6 +29,7 @@ class ExchangeItem<E> : Behavior<E>(
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<E> : Behavior<E>(
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<E> : Behavior<E>(
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)
}

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.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 <E> LostItem(chance: Int): OneShot<E>
@ -20,8 +20,10 @@ fun <E> LostItem(chance: Int): OneShot<E>
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
} else {
return@Trigger false
}
return@Trigger true
})
}

View File

@ -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(),
)
@ -110,6 +110,7 @@ object ProjectedPersonAI {
private fun initCoreActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.CORE, ImmutableList.of(
0 weight UpdateActivityFromSchedule.create(),
0 weight Swim(0.8f),
0 weight WakeUp.create(),
0 weight StopAttackingIfTargetInvalid.create(),
@ -130,7 +131,6 @@ object ProjectedPersonAI {
brain.addActivity(
Activity.IDLE, ImmutableList.of(
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
}
@ -141,7 +141,6 @@ object ProjectedPersonAI {
7 weight GoToWantedItem.create(1.75f, true, 32),
10 weight JumpOnBed(1.0f),
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
}
@ -149,9 +148,8 @@ object ProjectedPersonAI {
private fun initWorkActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.WORK, ImmutableList.of(
7 weight ExchangeItem(),
5 weight ExchangeItem(),
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
}
@ -160,8 +158,8 @@ object ProjectedPersonAI {
brain.addActivity(
Activity.REST, ImmutableList.of(
0 weight SleepInBed(),
5 weight GoToTargetLocation.create(MemoryModuleType.NEAREST_BED, 1, 1.05f),
5 weight RunOne(
3 weight GoToTargetLocation.create(MemoryModuleType.NEAREST_BED, 1, 1.05f),
3 weight RunOne(
mapOf(
MemoryModuleType.HOME to MemoryStatus.VALUE_ABSENT
),
@ -169,7 +167,6 @@ object ProjectedPersonAI {
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.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))
}