Jump to content

Custom Sensor Types with entity brains


Lemon Lord

Recommended Posts

Hello, I cannot figure these out. I've failed to find any examples of this code working but I'm trying to implement a sensor so that my entity flees from specific blocks like how piglins do from soul fire. I realise I could use path nodes for this but I want it to behave in accordance with a custom block tag I've set up.

My sensor is as such:

public class TreemanSensor extends Sensor<LivingEntity> {
	@Override
	public Set<MemoryModuleType<?>> getUsedMemories() {
      // basically just copied over the code from the piglin one until I could spawn TreemanEntity without the game crashing
		return ImmutableSet.of(MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.MOBS, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD, MemoryModuleType.NEAREST_PLAYER_HOLDING_WANTED_ITEM, MemoryModuleType.NEAREST_VISIBLE_HUNTABLE_HOGLIN, MemoryModuleType.NEAREST_VISIBLE_BABY_HOGLIN, MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS, MemoryModuleType.NEAREST_ADULT_PIGLINS, MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, MemoryModuleType.NEAREST_REPELLENT);
	}
	
	@Override
	protected void update(ServerWorld world, LivingEntity treeman) {
		Brain<?> brain = treeman.getBrain();
		brain.setMemory(MemoryModuleType.NEAREST_REPELLENT, findNearestFlame(world, treeman));
	}
	
	public static Optional<BlockPos> findNearestFlame(ServerWorld world, Entity entity) {
		return BlockPos.getClosestMatchingPosition(entity.getPosition(), 8, 4, (pos) -> isFlame(world, pos));
	}
	
	private static boolean isFlame(ServerWorld world, BlockPos pos) {
		BlockState state = world.getBlockState(pos);
		Block block = state.getBlock();
		return AppleBlockTags.TREEMAN_REPELLENTS.contains(block)
				|| block instanceof AbstractFireBlock
				|| (block instanceof CampfireBlock && CampfireBlock.isLit(state));
	}
}

and I have a corresponding SensorType registry object as follows:

public static final RegistryObject<SensorType<TreemanSensor>> TREEMAN_SENSOR_TYPE = SENSOR_TYPES.register("treeman_sensor", ()->new SensorType<>(TreemanSensor::new));

and it seems to register fine. To be clear, that 'SENSOR_TYPES' static value is private and is in a completely separate package to the following entity class. I try to add it to my TreemanEntity using:

protected static final ImmutableList<? extends SensorType<? extends Sensor<? super TreemanEntity>>> SENSOR_TYPES =
  ImmutableList.of(
  SensorType.NEAREST_LIVING_ENTITIES,
  SensorType.NEAREST_PLAYERS,
  RegistryHandler.TREEMAN_SENSOR_TYPE.get());
protected static final ImmutableList<? extends MemoryModuleType<?>> MEMORY_MODULE_TYPES = ImmutableList.of(
  MemoryModuleType.BREED_TARGET,
  MemoryModuleType.MOBS,
  MemoryModuleType.VISIBLE_MOBS,
  MemoryModuleType.NEAREST_VISIBLE_PLAYER,
  MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER,
  MemoryModuleType.LOOK_TARGET,
  MemoryModuleType.WALK_TARGET,
  MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE,
  MemoryModuleType.PATH,
  MemoryModuleType.ATTACK_TARGET,
  MemoryModuleType.ATTACK_COOLING_DOWN,
  MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLIN,
  MemoryModuleType.AVOID_TARGET,
  MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT,
  MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT,
  MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS,
  MemoryModuleType.NEAREST_VISIBLE_ADULT,
  MemoryModuleType.NEAREST_REPELLENT,
  MemoryModuleType.PACIFIED);
	
@Override
protected Brain.BrainCodec<TreemanEntity> getBrainCodec() {
  return Brain.createCodec(MEMORY_MODULE_TYPES, SENSOR_TYPES);
}
	
@Override
protected Brain<?> createBrain(Dynamic<?> dynamicIn) {
  return TreemanTasks.initBrain(this.getBrainCodec().deserialize(dynamicIn));
}

@Override
@SuppressWarnings("unchecked")
public Brain<TreemanEntity> getBrain() {
  return (Brain<TreemanEntity>) super.getBrain();
}

@Override
protected void updateAITasks() {
  this.world.getProfiler().startSection("treemanBrain");
  this.getBrain().tick((ServerWorld) this.world, this);
  this.world.getProfiler().endSection();
}

and that TreemanTasks class is just:

public class TreemanTasks {
	
	protected static Brain<?> initBrain(Brain<TreemanEntity> brain) {
		initCoreTasks(brain);
		initIdleTasks(brain);
		brain.setPersistentActivities(ImmutableSet.of(Activity.CORE));
		brain.setFallbackActivity(Activity.IDLE);
		brain.switchToFallbackActivity();
		return brain;
	}
	
	private static void initCoreTasks(Brain<TreemanEntity> brain) {
		brain.registerActivity(Activity.CORE, 10,
				ImmutableList.<Task<? super TreemanEntity>>of(
						RunAwayTask.func_233963_a_(MemoryModuleType.NEAREST_REPELLENT, 1.0F, 8, true))
		);
	}
	
	private static void initIdleTasks(Brain<TreemanEntity> brain) {
		brain.registerActivity(Activity.IDLE,
				ImmutableList.of(
						Pair.<Integer, Task<? super TreemanEntity>>of(1, new DummyTask(30, 60)))
		);
	}
}

but it just doesn't... do anything. I spawn the mob and it's just 🧍‍♂️. Nothing seems to appear in its memories when I place down a repellent block near it though it doesn't seem piglin entities have anything appear in their memories when fleeing soul flame.

Just kinda lost as to where to go from here, sorry if this was a bit of a read.

Link to comment
Share on other sites

  • 10 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.