Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Black Dogs do not spawn near structures as intended. #2

Open
DevArcana opened this issue Apr 15, 2021 · 2 comments
Open

Black Dogs do not spawn near structures as intended. #2

DevArcana opened this issue Apr 15, 2021 · 2 comments
Labels
good first issue Good for newcomers

Comments

@DevArcana
Copy link
Contributor

The spawn for the black dogs is defined like so:

BiomeModifications.addSpawn(BiomeSelectors.foundInOverworld().and(context -> BewitchmentPlus.config.blackDogBiomeCategories.contains(context.getBiome().getCategory().getName())), BWPEntityTypes.BLACK_DOG.getSpawnGroup(), BWPEntityTypes.BLACK_DOG, BewitchmentPlus.config.blackDogWeight, BewitchmentPlus.config.blackDogMinGroupCount, BewitchmentPlus.config.blackDogMaxGroupCount);

This registers them to spawn only on the configured biomes in the config. The default configuration looks like so:

"blackDogBiomeCategories": [
    "plains"
],

Because of this the game will only call the canSpawn method of the black dog entity for locations within the plains biome.

The class BlackDogEntity inherits from BWHostileEntity which inherits from HostileEntity which inherits from HostileEntity.
The dog entity class overrides the canSpawn method as follows:

        @Override
	public boolean canSpawn(WorldAccess world, SpawnReason spawnReason) {
		boolean flag = super.canSpawn(world, spawnReason);
		if (flag && (spawnReason == SpawnReason.SPAWNER || spawnReason == SpawnReason.STRUCTURE || spawnReason == SpawnReason.MOB_SUMMONED || spawnReason == SpawnReason.SPAWN_EGG || spawnReason == SpawnReason.COMMAND || spawnReason == SpawnReason.DISPENSER || spawnReason == SpawnReason.NATURAL)) {
			return true;
		}
		if (world instanceof ServerWorld && BewitchmentPlus.config.blackDogStructureSpawn) {
			BlockPos nearestVillage = ((ServerWorld) world).locateStructure(StructureFeature.VILLAGE, getBlockPos(), 3, false);
			BlockPos nearestPillagerOutpost = ((ServerWorld) world).locateStructure(StructureFeature.PILLAGER_OUTPOST, getBlockPos(), 3, false);
			return (nearestVillage != null && Math.sqrt(nearestVillage.getSquaredDistance(getBlockPos())) < 128) || (nearestPillagerOutpost != null && Math.sqrt(nearestPillagerOutpost.getSquaredDistance(getBlockPos())) < 128);
		}
		return false;
	}

This implementation first calls its super method whose implementation resides in PathAwareEntity and looks like so:

public boolean canSpawn(WorldAccess world, SpawnReason spawnReason) {
      return this.getPathfindingFavor(this.getBlockPos(), world) >= 0.0F;
   }

The method getPathfindingFavor is overriden by HostileEntity:

public float getPathfindingFavor(BlockPos pos, WorldView world) {
      return 0.5F - world.getBrightness(pos);
   }

Next, the following part is checked:

&& (spawnReason == SpawnReason.SPAWNER || spawnReason == SpawnReason.STRUCTURE || spawnReason == SpawnReason.MOB_SUMMONED || spawnReason == SpawnReason.SPAWN_EGG || spawnReason == SpawnReason.COMMAND || spawnReason == SpawnReason.DISPENSER || spawnReason == SpawnReason.NATURAL)

This is unnecessary as the cause of spawning will always be SpawnReason.NATURAL.

So far this logic fullfils the logic of spawning the dogs in the dark in registered biomes. The next part however is the problem:

if (world instanceof ServerWorld && BewitchmentPlus.config.blackDogStructureSpawn) {
			BlockPos nearestVillage = ((ServerWorld) world).locateStructure(StructureFeature.VILLAGE, getBlockPos(), 3, false);
			BlockPos nearestPillagerOutpost = ((ServerWorld) world).locateStructure(StructureFeature.PILLAGER_OUTPOST, getBlockPos(), 3, false);
			return (nearestVillage != null && Math.sqrt(nearestVillage.getSquaredDistance(getBlockPos())) < 128) || (nearestPillagerOutpost != null && Math.sqrt(nearestPillagerOutpost.getSquaredDistance(getBlockPos())) < 128);
		}

This code will be reached only if the getPathfindingFavor method returns 0.0f only. Even under these conditions, this does not impact the probability of spawning of a black dog. As the canSpawn method is only ever called in the plains biome by default, if the structure is in a different biome than the plains, it won't cause dogs to spawn nearby anyway.

@DevArcana
Copy link
Contributor Author

I have a possible implementation that would register all biomes for spawning and instead check the biome and location inside the canSpawn method only. If someone knows a better approach please let me know though. If not, I'll make a PR for this soon.

@Sunconure11 Sunconure11 added the good first issue Good for newcomers label Apr 15, 2021
@DevArcana
Copy link
Contributor Author

Since the PR #3 was merged, I suppose after people confirm it works we can close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants