feat: REST activity for projection people

This commit is contained in:
xtex 2023-07-03 09:44:05 +08:00
parent 82c6da8ae6
commit e7ed8f44de
Signed by: xtex
GPG Key ID: B918086ED8045B91
6 changed files with 125 additions and 35 deletions

View File

@ -25,7 +25,8 @@ object Quaedam {
val blocks = DeferredRegister.create(ID, Registries.BLOCK)!!
val blockEntities = DeferredRegister.create(ID, Registries.BLOCK_ENTITY_TYPE)!!
val entities = DeferredRegister.create(ID, Registries.ENTITY_TYPE)!!
val schedule = DeferredRegister.create(ID, Registries.SCHEDULE)!!
val schedules = DeferredRegister.create(ID, Registries.SCHEDULE)!!
val sensors = DeferredRegister.create(ID, Registries.SENSOR_TYPE)!!
val projectionEffects = DeferredRegister.create(ID, ProjectionEffectType.registryKey)!!
val creativeModeTab: RegistrySupplier<CreativeModeTab> = creativeModeTabs.register("quaedam") {
@ -45,7 +46,8 @@ object Quaedam {
blocks.register()
blockEntities.register()
entities.register()
schedule.register()
schedules.register()
sensors.register()
projectionEffects.register()
}

View File

@ -4,6 +4,7 @@ import com.mojang.serialization.Dynamic
import dev.architectury.platform.Platform
import dev.architectury.registry.level.entity.EntityAttributeRegistry
import net.fabricmc.api.EnvType
import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.network.protocol.game.DebugPackets
@ -18,11 +19,14 @@ import net.minecraft.world.entity.ai.Brain
import net.minecraft.world.entity.ai.attributes.AttributeModifier
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.entity.npc.InventoryCarrier
import net.minecraft.world.level.Level
import net.minecraft.world.level.ServerLevelAccessor
import quaedam.Quaedam
import quaedam.projection.swarm.ai.ProjectedPersonAI
import quaedam.projection.swarm.ai.ProjectedPersonNavigation
import quaedam.projector.Projector
import kotlin.random.Random
@ -194,4 +198,18 @@ class ProjectedPersonEntity(entityType: EntityType<out PathfinderMob>, level: Le
override fun isBaby() = shape.baby
override fun startSleeping(blockPos: BlockPos) {
super.startSleeping(blockPos)
brain.eraseMemory(MemoryModuleType.WALK_TARGET)
brain.eraseMemory(MemoryModuleType.LOOK_TARGET)
brain.eraseMemory(MemoryModuleType.NEAREST_BED)
brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
}
override fun stopSleeping() {
super.stopSleeping()
brain.setMemory(MemoryModuleType.LAST_WOKEN, level().gameTime)
brain.eraseMemory(MemoryModuleType.HOME)
}
}

View File

@ -0,0 +1,44 @@
package quaedam.projection.swarm.ai
import net.minecraft.core.GlobalPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.sensing.Sensor
import net.minecraft.world.entity.ai.sensing.SensorType
import net.minecraft.world.level.block.BedBlock
import net.minecraft.world.level.block.entity.BedBlockEntity
import net.minecraft.world.level.block.state.properties.BedPart
import quaedam.Quaedam
class BedInChunkSensor : Sensor<Mob>() {
companion object {
val sensor = Quaedam.sensors.register("bed_in_chunk") {
SensorType(::BedInChunkSensor)
}
}
override fun requires() = setOf(MemoryModuleType.NEAREST_BED)
override fun doTick(level: ServerLevel, entity: Mob) {
if (entity.tickCount and 0b11111 == 0 && !entity.isSleeping) { // 32gt
level.getChunkAt(entity.blockPosition()).blockEntities
.filterValues { it is BedBlockEntity }
.keys
.filter { level.getBlockState(it).getValue(BedBlock.PART) == BedPart.HEAD }
.filter { !level.getBlockState(it).getValue(BedBlock.OCCUPIED) }
.minByOrNull { it.distManhattan(entity.blockPosition()) }
?.also { entity.brain.setMemory(MemoryModuleType.NEAREST_BED, it) }
?.also {
if (entity.brain.checkMemory(MemoryModuleType.HOME, MemoryStatus.REGISTERED)) {
entity.brain.setMemory(MemoryModuleType.HOME, GlobalPos.of(level.dimension(), it))
}
}
}
}
}

View File

@ -1,39 +1,22 @@
package quaedam.projection.swarm
package quaedam.projection.swarm.ai
import com.google.common.collect.ImmutableList
import net.minecraft.world.entity.ai.Brain
import net.minecraft.world.entity.ai.behavior.*
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.sensing.SensorType
import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.entity.schedule.Schedule
import net.minecraft.world.entity.schedule.ScheduleBuilder
import quaedam.Quaedam
import quaedam.projection.swarm.ProjectedPersonEntity
import quaedam.utils.weight
import quaedam.utils.weightR
object ProjectedPersonAI {
private val memoryTypes = listOf(
MemoryModuleType.PATH,
MemoryModuleType.LOOK_TARGET,
MemoryModuleType.WALK_TARGET,
MemoryModuleType.ATTACK_TARGET,
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM,
MemoryModuleType.HURT_BY,
MemoryModuleType.ATTACK_COOLING_DOWN,
MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE,
)
private val sensorTypes = listOf(
SensorType.NEAREST_LIVING_ENTITIES,
SensorType.NEAREST_PLAYERS,
SensorType.HURT_BY,
SensorType.NEAREST_ITEMS,
)
val defaultSchedule = Quaedam.schedule.register("projected_person_default") {
val defaultSchedule = Quaedam.schedules.register("projected_person_default") {
ScheduleBuilder(Schedule()).changeActivityAt(10, Activity.IDLE)
.changeActivityAt(10, Activity.IDLE)
.changeActivityAt(2000, Activity.WORK)
@ -46,7 +29,7 @@ object ProjectedPersonAI {
.build()
}
val babySchedule = Quaedam.schedule.register("projected_person_baby") {
val babySchedule = Quaedam.schedules.register("projected_person_baby") {
ScheduleBuilder(Schedule()).changeActivityAt(10, Activity.IDLE)
.changeActivityAt(10, Activity.IDLE)
.changeActivityAt(3200, Activity.PLAY)
@ -56,6 +39,36 @@ object ProjectedPersonAI {
.build()
}
init {
BedInChunkSensor
}
private val memoryTypes by lazy {
listOf(
MemoryModuleType.PATH,
MemoryModuleType.LOOK_TARGET,
MemoryModuleType.WALK_TARGET,
MemoryModuleType.ATTACK_TARGET,
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM,
MemoryModuleType.HURT_BY,
MemoryModuleType.ATTACK_COOLING_DOWN,
MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE,
MemoryModuleType.HOME,
MemoryModuleType.LAST_WOKEN,
)
}
private val sensorTypes by lazy {
listOf(
SensorType.NEAREST_LIVING_ENTITIES,
SensorType.NEAREST_PLAYERS,
SensorType.HURT_BY,
SensorType.NEAREST_ITEMS,
BedInChunkSensor.sensor.get(),
)
}
fun provider(): Brain.Provider<out ProjectedPersonEntity> = Brain.provider(memoryTypes, sensorTypes)
fun initBrain(entity: ProjectedPersonEntity, brain: Brain<ProjectedPersonEntity>) {
@ -84,11 +97,11 @@ object ProjectedPersonAI {
brain.addActivity(
Activity.CORE, ImmutableList.of(
0 weight Swim(0.8f),
0 weight InteractWithDoor.create(),
0 weight LookAtTargetSink(40, 70),
0 weight MoveToTargetSink(),
0 weight WakeUp.create(),
3 weight GoToWantedItem.create(1.2f, false, 7),
3 weight LookAtTargetSink(40, 70),
3 weight MoveToTargetSink(),
3 weight InteractWithDoor.create(),
10 weight GoToWantedItem.create(1.2f, false, 7),
)
)
}
@ -96,7 +109,7 @@ object ProjectedPersonAI {
private fun initIdleActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.IDLE, ImmutableList.of(
3 weight createStrollBehavior(),
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
@ -105,9 +118,9 @@ object ProjectedPersonAI {
private fun initPlayActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.PLAY, ImmutableList.of(
3 weight GoToWantedItem.create(1.75f, true, 32),
5 weight JumpOnBed(1.0f),
5 weight createStrollBehavior(),
7 weight GoToWantedItem.create(1.75f, true, 32),
10 weight JumpOnBed(1.0f),
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
@ -116,7 +129,7 @@ object ProjectedPersonAI {
private fun initWorkActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.WORK, ImmutableList.of(
3 weight createStrollBehavior(),
10 weight createStrollBehavior(),
99 weight UpdateActivityFromSchedule.create(),
)
)
@ -125,7 +138,16 @@ object ProjectedPersonAI {
private fun initRestActivity(brain: Brain<ProjectedPersonEntity>) {
brain.addActivity(
Activity.REST, ImmutableList.of(
3 weight createStrollBehavior(),
0 weight SleepInBed(),
5 weight GoToTargetLocation.create(MemoryModuleType.NEAREST_BED, 1, 1.05f),
5 weight RunOne(
mapOf(
MemoryModuleType.HOME to MemoryStatus.VALUE_ABSENT
),
listOf(
1 weightR createStrollBehavior()
)
),
99 weight UpdateActivityFromSchedule.create(),
)
)

View File

@ -1,9 +1,11 @@
package quaedam.projection.swarm
package quaedam.projection.swarm.ai
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
import net.minecraft.world.level.Level
import net.minecraft.world.level.pathfinder.Path
import quaedam.projection.swarm.ProjectedPersonEntity
import quaedam.projection.swarm.SwarmProjection
import quaedam.projector.Projector
class ProjectedPersonNavigation(val entity: ProjectedPersonEntity, level: Level) : GroundPathNavigation(entity, level) {

View File

@ -2,3 +2,5 @@ accessWidener v2 named
# Custom Registry for ProjectionEffect
accessible method net/minecraft/core/registries/BuiltInRegistries registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry;
accessible class net/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap
# Entity Brain AI
accessible method net/minecraft/world/entity/ai/sensing/SensorType <init> (Ljava/util/function/Supplier;)V