Skip to content

Commit

Permalink
Tweak rat spawns and fix rats spawning outside of villages
Browse files Browse the repository at this point in the history
  • Loading branch information
doctor4t committed Jul 5, 2021
1 parent 24f7191 commit a610b01
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 29 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Rat's Mischief - Changelog:

### Rat's Mischief 1.1.4 - 1.17
- Tweaked rat spawning mechanics to allow for vertical terrain variations
- Reduced the time interval at which rats try to spawn
- Rats will now spawn in small groups of up to 5
- Added a safety mob spawn cap of maximum 20 rats per village
- Fixed an issue that caused rats to spawn no matter the proximity to a village as long as there were beds, working stations and no villagers

### Rat's Mischief 1.1.3 - 1.17
- Updated to Minecraft 1.17
- The Collection staff will now order rats to collect the block the player clicks on with the staff and no longer works by detecting the block in the player's other hand
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ loader_version=0.11.6
fabric_version=0.35.2+1.17

# Mod Properties
mod_version = 1.1.3
mod_version = 1.1.4
maven_group = io.github.ladysnake
archives_base_name = ratsmischief

Expand All @@ -30,6 +30,6 @@ owners = Ladysnake
license_header = GPL-3.0-or-later
curseforge_id = 431787
curseforge_versions = 1.17
cf_requirements = fabric-api; geckolib-fabric
cf_requirements = fabric-api; geckolib
release_type = release
changelog_url = https://github.com/Ladysnake/Rats-Mischief/blob/1.17/CHANGELOG.md
2 changes: 1 addition & 1 deletion src/main/java/ladysnake/ratsmischief/common/Mischief.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static Item registerItem(Item item, String name) {
public void onInitialize() {
GeckoLib.initialize();

RAT = registerEntity("rat", FabricEntityTypeBuilder.createMob().entityFactory(RatEntity::new).spawnGroup(SpawnGroup.AMBIENT).dimensions(EntityDimensions.changing(0.6F, 0.4F)).trackRangeBlocks(8).spawnRestriction(SpawnRestriction.Location.ON_GROUND, Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, RatEntity::canSpawn).build());
RAT = registerEntity("rat", FabricEntityTypeBuilder.createMob().entityFactory(RatEntity::new).spawnGroup(SpawnGroup.AMBIENT).dimensions(EntityDimensions.changing(0.6F, 0.4F)).trackRangeBlocks(8).spawnRestriction(SpawnRestriction.Location.ON_GROUND, Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, RatEntity::canMobSpawn).build());
FabricDefaultAttributeRegistry.register(RAT, RatEntity.createEntityAttributes());

// ratify and untratify commands
Expand Down
11 changes: 0 additions & 11 deletions src/main/java/ladysnake/ratsmischief/common/entity/RatEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public class RatEntity extends TameableEntity implements IAnimatable, Angerable
public static final Predicate<ItemEntity> PICKABLE_DROP_FILTER = (itemEntity) -> {
return !itemEntity.cannotPickup() && itemEntity.isAlive();
};
public static final int SPAWN_RADIUS = 100;
public static final List<Type> NATURAL_TYPES = ImmutableList.of(
Type.ALBINO, Type.BLACK, Type.GREY, Type.HUSKY, Type.CHOCOLATE, Type.LIGHT_BROWN, Type.RUSSIAN_BLUE
);
Expand Down Expand Up @@ -103,16 +102,6 @@ public static DefaultAttributeContainer.Builder createEntityAttributes() {
return MobEntity.createMobAttributes().add(EntityAttributes.GENERIC_MAX_HEALTH, 8.0D).add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.5D).add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 1).add(EntityAttributes.GENERIC_FOLLOW_RANGE, 32);
}

public static boolean canSpawn(EntityType<RatEntity> entityType, ServerWorldAccess serverWorldAccess, SpawnReason spawnReason, BlockPos blockPos, Random random) {
ServerWorld world = serverWorldAccess.toServerWorld();
if (world.locateStructure(StructureFeature.VILLAGE, blockPos, 5, false) != null) {
List<VillagerEntity> villagersNearby = world.getEntitiesByType(EntityType.VILLAGER, new Box(blockPos.getX() - SPAWN_RADIUS, blockPos.getY() - SPAWN_RADIUS, blockPos.getZ() - SPAWN_RADIUS, blockPos.getX() + SPAWN_RADIUS, blockPos.getY() + SPAWN_RADIUS, blockPos.getZ() + SPAWN_RADIUS), villagerEntity -> true);
return villagersNearby.isEmpty();
}

return false;
}

public static Type getRandomNaturalType(Random random) {
return NATURAL_TYPES.get(random.nextInt(NATURAL_TYPES.size()));
}
Expand Down
46 changes: 31 additions & 15 deletions src/main/java/ladysnake/ratsmischief/common/world/RatSpawner.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,55 @@
import ladysnake.ratsmischief.common.Mischief;
import ladysnake.ratsmischief.common.entity.RatEntity;
import net.minecraft.entity.EntityData;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.SpawnRestriction;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.world.GameRules;
import net.minecraft.world.SpawnHelper;
import net.minecraft.world.gen.Spawner;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.poi.PointOfInterestStorage;
import net.minecraft.world.poi.PointOfInterestType;

import java.util.List;
import java.util.Random;

public class RatSpawner implements Spawner {
public static final int SPAWN_RADIUS = 100;
private int ticksUntilNextSpawn;


public int spawn(ServerWorld world, boolean spawnMonsters, boolean spawnAnimals) {
if (spawnAnimals && world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING)) {
--this.ticksUntilNextSpawn;
if (this.ticksUntilNextSpawn <= 0) {
this.ticksUntilNextSpawn = 300;
this.ticksUntilNextSpawn = 200;
Random random = world.random;
world.getPlayers().forEach(serverPlayerEntity -> {
int i = (8 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1);
int j = (8 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1);
BlockPos blockPos = serverPlayerEntity.getBlockPos().add(i, 0, j);
if (world.isRegionLoaded(blockPos.getX() - 10, blockPos.getY() - 10, blockPos.getZ() - 10, blockPos.getX() + 10, blockPos.getY() + 10, blockPos.getZ() + 10)) {
if (SpawnHelper.canSpawn(SpawnRestriction.Location.ON_GROUND, world, blockPos, Mischief.RAT)) {
this.spawnInHouse(world, blockPos);
int x = (8 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1);
int y = (random.nextInt(4)) * (random.nextBoolean() ? -1 : 1);
int z = (8 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1);
BlockPos blockPos = serverPlayerEntity.getBlockPos().add(x, y, z);

// test early if the rat can spawn
if (RatEntity.canMobSpawn(Mischief.RAT, world, SpawnReason.NATURAL, blockPos, world.getRandom())) {
BlockPos villagePos = world.locateStructure(StructureFeature.VILLAGE, blockPos, 5, false);
// if a village was found and it's close enough
if (villagePos != null && blockPos.getManhattanDistance(villagePos) <= 300) {
List<VillagerEntity> villagersNearby = world.getEntitiesByType(EntityType.VILLAGER, new Box(blockPos.getX() - SPAWN_RADIUS, blockPos.getY() - SPAWN_RADIUS, blockPos.getZ() - SPAWN_RADIUS, blockPos.getX() + SPAWN_RADIUS, blockPos.getY() + SPAWN_RADIUS, blockPos.getZ() + SPAWN_RADIUS), villagerEntity -> true);

if (villagersNearby.isEmpty() && world.isRegionLoaded(blockPos.getX() - 10, blockPos.getY() - 10, blockPos.getZ() - 10, blockPos.getX() + 10, blockPos.getY() + 10, blockPos.getZ() + 10)) {
if (SpawnHelper.canSpawn(SpawnRestriction.Location.ON_GROUND, world, blockPos, Mischief.RAT)) {
for (int i = 0; i <= random.nextInt(5); i++) {
this.spawnInHouse(world, blockPos);
}
}
}
}
}
});
Expand All @@ -47,19 +65,17 @@ private void spawnInHouse(ServerWorld world, BlockPos pos) {
long bedCount = world.getPointOfInterestStorage().count(PointOfInterestType.HOME.getCompletionCondition(), pos, 48, PointOfInterestStorage.OccupationStatus.HAS_SPACE);
List<RatEntity> list = world.getNonSpectatingEntities(RatEntity.class, (new Box(pos)).expand(96.0, 16.0D, 96.0D));

if (list.size() < bedCount * 3) {
if (list.size() < bedCount * 3 && list.size() < 20) {
this.spawn(world, pos);
}
}

private void spawn(ServerWorld world, BlockPos pos) {
if (RatEntity.canSpawn(Mischief.RAT, world, SpawnReason.NATURAL, pos, world.getRandom())) {
RatEntity ratEntity = Mischief.RAT.create(world);
if (ratEntity != null) {
ratEntity.initialize(world, world.getLocalDifficulty(pos), SpawnReason.NATURAL, (EntityData) null, (NbtCompound) null);
ratEntity.refreshPositionAndAngles(pos, 0.0F, 0.0F);
world.spawnEntityAndPassengers(ratEntity);
}
RatEntity ratEntity = Mischief.RAT.create(world);
if (ratEntity != null) {
ratEntity.initialize(world, world.getLocalDifficulty(pos), SpawnReason.NATURAL, (EntityData) null, (NbtCompound) null);
ratEntity.refreshPositionAndAngles(pos, 0.0F, 0.0F);
world.spawnEntityAndPassengers(ratEntity);
}
}
}

0 comments on commit a610b01

Please sign in to comment.