diff --git a/common/src/main/kotlin/quaedam/Quaedam.kt b/common/src/main/kotlin/quaedam/Quaedam.kt index a61fed5..fc7cab7 100644 --- a/common/src/main/kotlin/quaedam/Quaedam.kt +++ b/common/src/main/kotlin/quaedam/Quaedam.kt @@ -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 = creativeModeTabs.register("quaedam") { @@ -45,7 +46,8 @@ object Quaedam { blocks.register() blockEntities.register() entities.register() - schedule.register() + schedules.register() + sensors.register() projectionEffects.register() } diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonEntity.kt b/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonEntity.kt index 57abf3f..7833966 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonEntity.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonEntity.kt @@ -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, 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) + } + } \ No newline at end of file diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ai/BedInChunkSensor.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/BedInChunkSensor.kt new file mode 100644 index 0000000..992b594 --- /dev/null +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/BedInChunkSensor.kt @@ -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() { + + 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)) + } + } + } + } + +} \ No newline at end of file diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonAI.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt similarity index 64% rename from common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonAI.kt rename to common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt index 9ed5a76..52af9c5 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonAI.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonAI.kt @@ -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 = Brain.provider(memoryTypes, sensorTypes) fun initBrain(entity: ProjectedPersonEntity, brain: Brain) { @@ -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) { 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) { 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) { 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) { 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(), ) ) diff --git a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonNavigation.kt b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonNavigation.kt similarity index 82% rename from common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonNavigation.kt rename to common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonNavigation.kt index d10779f..bd70541 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/ProjectedPersonNavigation.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/ai/ProjectedPersonNavigation.kt @@ -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) { diff --git a/common/src/main/resources/quaedam.accesswidener b/common/src/main/resources/quaedam.accesswidener index 0bc82f2..e7940ef 100644 --- a/common/src/main/resources/quaedam.accesswidener +++ b/common/src/main/resources/quaedam.accesswidener @@ -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 (Ljava/util/function/Supplier;)V