Skip to content

Commit

Permalink
village spawn game nerf feature
Browse files Browse the repository at this point in the history
  • Loading branch information
MehVahdJukaar committed Jul 27, 2024
1 parent df1dcb6 commit 7687628
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
- Creative players can break any block with a pickarang
- Added unique pickarang damage type and death message
- Added a (temporary) beach zombie villager texture
- Added new game nerf feature that allows villages to spawn more rarely around spawn and have also a greater chance of being zombie ones
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.Level;

import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride;
import net.minecraft.world.level.levelgen.structure.structures.JigsawStructure;
import org.violetmoon.quark.base.Quark;
import org.violetmoon.zeta.config.Config;
import org.violetmoon.zeta.event.bus.LoadEvent;
Expand Down Expand Up @@ -88,6 +92,13 @@ public class GameNerfsModule extends ZetaModule {
@Config(description = "Makes tripwire hooks unable to be duplicated")
public static boolean disableTripwireHookDupe = true;

@Config(description = "Makes villages spawn less often when close to spawn")
public static boolean villageSpawnNerf = false;

@Config(description = "Distance at which villages will spawn as normal. Effect scales linearly from world spawn")
public static int villageSpawnNerfDistance = 7000;


@Config
public static List<String> nonGriefingEntities = Arrays.asList("minecraft:creeper", "minecraft:enderman");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.violetmoon.quark.mixin.mixins;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.pools.EmptyPoolElement;
import net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement;
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.violetmoon.quark.content.experimental.module.GameNerfsModule;
import org.violetmoon.quark.mixin.mixins.accessor.AccessorChunkAccess;
import org.violetmoon.quark.mixin.mixins.accessor.AccessorSinglePoolElement;

import java.util.Optional;

@Mixin(JigsawPlacement.class)
public class ChunkGeneratorMixin {

@WrapOperation(method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;I)Ljava/util/Optional;",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/level/levelgen/structure/pools/StructureTemplatePool;getRandomTemplate(Lnet/minecraft/util/RandomSource;)Lnet/minecraft/world/level/levelgen/structure/pools/StructurePoolElement;"))
private static StructurePoolElement quark$reduceVillagesFrequency(
StructureTemplatePool instance, RandomSource pRandom, Operation<StructurePoolElement> operation,
@Local(argsOnly = true) Holder<StructureTemplatePool> structure, @Local(ordinal = 0, argsOnly = true) Optional<ResourceLocation> startPool, @Local(argsOnly = true) BlockPos pos, @Local(argsOnly = true) Structure.GenerationContext context) {
var original = operation.call(instance, pRandom);
if (GameNerfsModule.villageSpawnNerf) {
Optional<String> left = quark$getPoolId(original);
if (left.isPresent()) {
String id = left.get();
if (id.contains("village") && id.contains("town_centers")) {
if (context.heightAccessor() instanceof ProtoChunk pc &&
((AccessorChunkAccess) pc).getLevelHeightAccessor() instanceof ServerLevel sl) {
BlockPos spawn = sl.getSharedSpawnPos();
double spawnDistanceSq = spawn.distSqr(pos);
RandomSource r = RandomSource.create(pos.asLong());
float maxDist = GameNerfsModule.villageSpawnNerfDistance;
double probability = 1 - (spawnDistanceSq / (maxDist * maxDist));
if (r.nextDouble() < probability) {
int tries = 0;
while (!id.contains("zombie")) {
if (tries++ > 4) {
return EmptyPoolElement.INSTANCE;
}
original = operation.call(instance, pRandom);
Optional<String> s = quark$getPoolId(original);
if (s.isPresent()) {
id = s.get();
}
tries++;
}
}
}
}
}
}
return original;
}

@Unique
private static Optional<String> quark$getPoolId(StructurePoolElement le) {
if (le instanceof AccessorSinglePoolElement se) {
Optional<ResourceLocation> left = se.getTemplate().left();
return left.map(ResourceLocation::getPath);
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.violetmoon.quark.mixin.mixins.accessor;

import com.mojang.datafixers.util.Either;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(ChunkAccess.class)
public interface AccessorChunkAccess {

@Accessor("levelHeightAccessor")
LevelHeightAccessor getLevelHeightAccessor();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.violetmoon.quark.mixin.mixins.accessor;

import com.mojang.datafixers.util.Either;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import org.checkerframework.checker.units.qual.A;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(SinglePoolElement.class)
public interface AccessorSinglePoolElement {

@Accessor("template")
Either<ResourceLocation, StructureTemplate> getTemplate();

}
3 changes: 3 additions & 0 deletions src/main/resources/quark.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"BlockItemMixin",
"BoatMixin",
"CeilingHangingSignBlockMixin",
"ChunkGeneratorMixin",
"ClimateParameterPointMixin",
"ConcretePowderBlockMixin",
"CreativeModeTabsMixin",
Expand Down Expand Up @@ -76,9 +77,11 @@
"accessor.AccessorAbstractArrow",
"accessor.AccessorAbstractChestedHorse",
"accessor.AccessorBlockItem",
"accessor.AccessorChunkAccess",
"accessor.AccessorLivingEntity",
"accessor.AccessorMerchantOffer",
"accessor.AccessorServerGamePacketListener",
"accessor.AccessorSinglePoolElement",
"accessor.AccessorTemptingSensor",
"self.IZetaBlockMixin_FAKE",
"self.IZetaItemMixin_FAKE"
Expand Down

0 comments on commit 7687628

Please sign in to comment.