other features

This commit is contained in:
gnembon committed 2019-05-22 15:21:07 -03:00
1 parent 39727cb524
commit b257e6f984
19 files changed
+501 -18

No files matched your search

+5 -4
View File
@@ -55,6 +55,7 @@ public class CarpetSettings
//those don't have to mimic defaults - defaults will be ' //those don't have to mimic defaults - defaults will be '
//static store //static store
public static int n_pushLimit = 12; public static int n_pushLimit = 12;
public static int n_maxEntityCollisions = 0;
public static boolean b_hopperCounters = false; public static boolean b_hopperCounters = false;
public static boolean b_shulkerSpawningInEndCities = false; public static boolean b_shulkerSpawningInEndCities = false;
public static boolean b_fastRedstoneDust = false; public static boolean b_fastRedstoneDust = false;
@@ -64,6 +65,7 @@ public class CarpetSettings
public static boolean b_huskSpawningInTemples = false; public static boolean b_huskSpawningInTemples = false;
public static boolean b_stackableShulkerBoxes = false; public static boolean b_stackableShulkerBoxes = false;
public static boolean b_fillUpdates = true; public static boolean b_fillUpdates = true;
public static boolean b_lagFreeSpawning = false;
private static CarpetSettingEntry rule(String s1, String s2, String s3) { return CarpetSettingEntry.create(s1,s2,s3);} private static CarpetSettingEntry rule(String s1, String s2, String s3) { return CarpetSettingEntry.create(s1,s2,s3);}
@@ -143,16 +145,14 @@ public class CarpetSettings
rule("fillLimit", "creative","Customizable fill/clone volume limit") rule("fillLimit", "creative","Customizable fill/clone volume limit")
.choices("32768","32768 250000 1000000").setNotStrict(), .choices("32768","32768 250000 1000000").setNotStrict(),
rule("maxEntityCollisions", "optimizations", "Customizable maximal entity collision limits, 0 for no limits") rule("maxEntityCollisions", "optimizations", "Customizable maximal entity collision limits, 0 for no limits")
.choices("0","0 1 20").setNotStrict(), .choices("0","0 1 20").setNotStrict().numAccelerate(),
//???rule("pistonGhostBlocksFix", "fix", "Fix for piston ghost blocks") //???rule("pistonGhostBlocksFix", "fix", "Fix for piston ghost blocks")
// .extraInfo("true(serverOnly) option works with all clients, including vanilla", // .extraInfo("true(serverOnly) option works with all clients, including vanilla",
// "clientAndServer option requires compatible carpet clients and messes up flying machines") // "clientAndServer option requires compatible carpet clients and messes up flying machines")
// .choices("false","false true clientAndServer"), // .choices("false","false true clientAndServer"),
//???rule("waterFlow", "optimizations", "fixes water flowing issues") //???rule("waterFlow", "optimizations", "fixes water flowing issues")
// .choices("vanilla","vanilla optimized correct"), // .choices("vanilla","vanilla optimized correct"),
rule("sleepingThreshold", "experimental", "The percentage of required sleeping players to skip the night") rule("onePlayerSleeping", "survival", "One player is required on the server to cause night to pass"),
.extraInfo("Use values from 0 to 100, 100 for default (all players needed)")
.choices("100","0 10 50 100").setNotStrict(),
rule("customMOTD", "creative","Sets a different motd message on client trying to connect to the server") rule("customMOTD", "creative","Sets a different motd message on client trying to connect to the server")
.extraInfo("use '_' to use the startup setting from server.properties") .extraInfo("use '_' to use the startup setting from server.properties")
.choices("_","_").setNotStrict().validate((s) -> .choices("_","_").setNotStrict().validate((s) ->
@@ -196,6 +196,7 @@ public class CarpetSettings
rule("placementRotationFix", "fix", "fixes block placement rotation issue when player rotates quickly while placing blocks"), rule("placementRotationFix", "fix", "fixes block placement rotation issue when player rotates quickly while placing blocks"),
rule("leadFix", "fix", "Fixes leads breaking/becoming invisible in unloaded chunks") rule("leadFix", "fix", "Fixes leads breaking/becoming invisible in unloaded chunks")
.extraInfo("You may still get visibly broken leash links on the client side, but server side the link is still there."), .extraInfo("You may still get visibly broken leash links on the client side, but server side the link is still there."),
rule("lagFreeSpawning", "optimizations", "Spawning requires much less CPU and Memory").boolAccelerate()
}; };
for (CarpetSettingEntry rule: RuleList) for (CarpetSettingEntry rule: RuleList)
{ {
@@ -0,0 +1,12 @@
package carpet.fakes;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Random;
public interface CoralFeatureInterface
{
boolean growSpecific(World worldIn, Random random, BlockPos pos, BlockState blockUnder);
}
@@ -0,0 +1,11 @@
package carpet.fakes;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import java.util.Map;
public interface WorldInterface
{
Map<EntityType, Entity> getPrecookedMobs();
}
@@ -7,8 +7,9 @@ import net.minecraft.util.math.Vec3d;
public class TNTLogHelper public class TNTLogHelper
{ {
public boolean initialized;
private double primedX, primedY, primedZ; private double primedX, primedY, primedZ;
Vec3d primedAngle; private Vec3d primedAngle;
/** /**
* Runs when the TNT is primed. Expects the position and motion angle of the TNT. * Runs when the TNT is primed. Expects the position and motion angle of the TNT.
*/ */
@@ -18,6 +19,7 @@ public class TNTLogHelper
primedY = y; primedY = y;
primedZ = z; primedZ = z;
primedAngle = motion; primedAngle = motion;
initialized = true;
} }
/** /**
* Runs when the TNT explodes. Expects the position of the TNT. * Runs when the TNT explodes. Expects the position of the TNT.
@@ -0,0 +1,28 @@
package carpet.mixins;
import carpet.utils.WoolTool;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CarpetBlock;
import net.minecraft.item.ItemPlacementContext;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(CarpetBlock.class)
public abstract class CarpetBlockMixin extends Block
{
public CarpetBlockMixin(Settings block$Settings_1)
{
super(block$Settings_1);
}
public BlockState getPlacementState(ItemPlacementContext context)
{
BlockState state = super.getPlacementState(context);
if (context.getPlayer() != null && !context.getWorld().isClient)
{
WoolTool.carpetPlacedAction(((CarpetBlock)(Object)this).getColor(), context.getPlayer(), context.getBlockPos(), context.getWorld());
}
return state;
}
}
@@ -0,0 +1,81 @@
package carpet.mixins;
import carpet.CarpetSettings;
import carpet.fakes.CoralFeatureInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CoralBlock;
import net.minecraft.block.CoralParentBlock;
import net.minecraft.block.Fertilizable;
import net.minecraft.block.MaterialColor;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.FluidTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.CoralClawFeature;
import net.minecraft.world.gen.feature.CoralFeature;
import net.minecraft.world.gen.feature.CoralMushroomFeature;
import net.minecraft.world.gen.feature.CoralTreeFeature;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import java.util.Random;
@Mixin(CoralBlock.class)
@Interface(iface = Fertilizable.class, prefix = "fert$")
public abstract class CoralBlockMixin implements Fertilizable
{
public boolean isFertilizable(BlockView var1, BlockPos var2, BlockState var3, boolean var4)
{
return CarpetSettings.getBool("renewableCoral") && var3.get(CoralParentBlock.WATERLOGGED) && var1.getFluidState(var2.up()).matches(FluidTags.WATER);
}
public boolean canGrow(World var1, Random var2, BlockPos var3, BlockState var4)
{
return (double)var1.random.nextFloat() < 0.15D;
}
public void grow(World worldIn, Random random, BlockPos pos, BlockState blockUnder)
{
CoralFeature coral;
int variant = random.nextInt(3);
if (variant == 0)
coral = new CoralClawFeature(DefaultFeatureConfig::deserialize);
else if (variant == 1)
coral = new CoralTreeFeature(DefaultFeatureConfig::deserialize);
else
coral = new CoralMushroomFeature(DefaultFeatureConfig::deserialize);
MaterialColor color = blockUnder.getTopMaterialColor(worldIn, pos);
BlockState proper_block = blockUnder;
for (Block block: BlockTags.CORAL_BLOCKS.values())
{
proper_block = block.getDefaultState();
if (proper_block.getTopMaterialColor(worldIn,pos) == color)
{
break;
}
}
worldIn.setBlockState(pos, Blocks.WATER.getDefaultState(), 4);
if (!((CoralFeatureInterface)coral).growSpecific(worldIn, random, pos, proper_block))
{
worldIn.setBlockState(pos, blockUnder, 3);
}
else
{
if (worldIn.random.nextInt(10)==0)
{
BlockPos randomPos = pos.add(worldIn.random.nextInt(16)-8,worldIn.random.nextInt(8),worldIn.random.nextInt(16)-8 );
if (BlockTags.CORAL_BLOCKS.contains(worldIn.getBlockState(randomPos).getBlock()))
{
worldIn.setBlockState(randomPos, Blocks.WET_SPONGE.getDefaultState(), 3);
}
}
}
}
}
@@ -0,0 +1,25 @@
package carpet.mixins;
import carpet.fakes.CoralFeatureInterface;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.CoralFeature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Random;
@Mixin(CoralFeature.class)
public abstract class CoralFeatureMixin implements CoralFeatureInterface
{
@Shadow protected abstract boolean spawnCoral(IWorld var1, Random var2, BlockPos var3, BlockState var4);
@Override
public boolean growSpecific(World worldIn, Random random, BlockPos pos, BlockState blockUnder)
{
return spawnCoral(worldIn, random, pos, blockUnder);
}
}
@@ -0,0 +1,24 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.world.gen.feature.KelpFeature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Random;
@Mixin(KelpFeature.class)
public class KelpFeatureMixin
{
@Redirect(method = "method_13460", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I"))
private int getRandom(Random random, int bound)
{
if (bound==10)
return random.nextInt(bound);
int limit = CarpetSettings.getInt("kelpGenerationGrowLimit");
if (limit == 0)
return random.nextInt(bound);
return 25-limit+random.nextInt(Math.min(23,limit+1));
}
}
@@ -0,0 +1,64 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(LivingEntity.class)
public abstract class LivingEntity_maxCollisionsMixin extends Entity
{
public LivingEntity_maxCollisionsMixin(EntityType<?> entityType_1, World world_1)
{
super(entityType_1, world_1);
}
@Shadow protected abstract void pushAway(Entity entity_1);
@Inject(method = "tickPushing", cancellable = true, at = @At("HEAD"))
private void tickPushingReplacement(CallbackInfo ci)
{
List<Entity> list_1 = this.world.getEntities((Entity)this, this.getBoundingBox(), EntityPredicates.canBePushedBy(this));
if (!list_1.isEmpty()) {
int int_1 = this.world.getGameRules().getInteger("maxEntityCramming");
int int_2;
if (int_1 > 0 && list_1.size() > int_1 - 1 && this.random.nextInt(4) == 0) {
int_2 = 0;
for(int int_3 = 0; int_3 < list_1.size(); ++int_3) {
if (!((Entity)list_1.get(int_3)).hasVehicle()) {
++int_2;
}
}
if (int_2 > int_1 - 1) {
this.damage(DamageSource.CRAMMING, 6.0F);
}
}
int limit = list_1.size();
if (CarpetSettings.n_maxEntityCollisions > 0)
limit = Math.min(limit, CarpetSettings.n_maxEntityCollisions);
for(int_2 = 0; int_2 < limit; ++int_2) {
Entity entity_1 = (Entity)list_1.get(int_2);
this.pushAway(entity_1);
}
}
ci.cancel();
}
}
@@ -0,0 +1,18 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.block.piston.PistonHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(PistonHandler.class)
public class PistonHandler_pushLimitMixin
{
@ModifyConstant(method = "tryMove", constant = @Constant(intValue = 12), expect = 3)
private int pushLimit(int original)
{
return CarpetSettings.n_pushLimit;
}
}
@@ -0,0 +1,18 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.block.PoweredRailBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(PoweredRailBlock.class)
public class PoweredRailBlock_powerLimitMixin
{
@ModifyConstant(method = "isPoweredByOtherRails(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;ZI)Z",
constant = @Constant(intValue = 8))
private int powerLimit(int original)
{
return CarpetSettings.railPowerLimitAdjusted;
}
}
@@ -5,6 +5,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.PrimedTntEntity; import net.minecraft.entity.PrimedTntEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -24,6 +25,25 @@ public abstract class PrimedTntEntityMixin extends Entity
super(entityType_1, world_1); super(entityType_1, world_1);
} }
@Inject(method = "<init>(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)V", at = @At("RETURN"))
private void initTNTLoggerPrime(EntityType<? extends PrimedTntEntity> entityType_1, World world_1, CallbackInfo ci)
{
if (LoggerRegistry.__tnt && !world_1.isClient)
{
logHelper = new TNTLogHelper();
}
}
@Inject(method = "tick", at = @At("HEAD"))
private void initTracker(CallbackInfo ci)
{
if (LoggerRegistry.__tnt && logHelper != null && !logHelper.initialized)
{
logHelper.onPrimed(x, y, z, getVelocity());
}
}
@Inject(method = "<init>(Lnet/minecraft/world/World;DDDLnet/minecraft/entity/LivingEntity;)V", @Inject(method = "<init>(Lnet/minecraft/world/World;DDDLnet/minecraft/entity/LivingEntity;)V",
at = @At(value = "RETURN")) at = @At(value = "RETURN"))
private void initTNTLogger(World world_1, double double_1, double double_2, double double_3, private void initTNTLogger(World world_1, double double_1, double double_2, double double_3,
@@ -31,12 +51,6 @@ public abstract class PrimedTntEntityMixin extends Entity
{ {
if(CarpetSettings.getBool("tntPrimerMomentumRemoved")) if(CarpetSettings.getBool("tntPrimerMomentumRemoved"))
this.setVelocity(new Vec3d(0.0, 0.20000000298023224D, 0.0)); this.setVelocity(new Vec3d(0.0, 0.20000000298023224D, 0.0));
if (LoggerRegistry.__tnt)
{
logHelper = new TNTLogHelper();
logHelper.onPrimed(double_1, double_2, double_3, getVelocity());
}
} }
@Inject(method = "explode", at = @At(value = "HEAD")) @Inject(method = "explode", at = @At(value = "HEAD"))
@@ -25,7 +25,7 @@ public abstract class ProjectileEntityMixin extends Entity
logHelper = new TrajectoryLogHelper("projectiles"); logHelper = new TrajectoryLogHelper("projectiles");
} }
@Inject(method = "tick", at = @At("RETURN")) @Inject(method = "tick", at = @At("HEAD"))
private void tickCheck(CallbackInfo ci) private void tickCheck(CallbackInfo ci)
{ {
if (LoggerRegistry.__projectiles && logHelper != null) if (LoggerRegistry.__projectiles && logHelper != null)
@@ -1,5 +1,6 @@
package carpet.mixins; package carpet.mixins;
import carpet.fakes.WorldInterface;
import carpet.utils.SpawnReporter; import carpet.utils.SpawnReporter;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.entity.EntityCategory; import net.minecraft.entity.EntityCategory;
@@ -56,6 +57,7 @@ public abstract class ServerChunkManagerMixin
Object2IntMap object2IntMap_1) Object2IntMap object2IntMap_1)
{ {
DimensionType dim = this.world.dimension.getType(); DimensionType dim = this.world.dimension.getType();
((WorldInterface)world).getPrecookedMobs().clear();
SpawnReporter.mobCounts.put(dim, (Object2IntMap<EntityCategory>)object2IntMap_1); SpawnReporter.mobCounts.put(dim, (Object2IntMap<EntityCategory>)object2IntMap_1);
SpawnReporter.chunkCounts.put(dim, int_2); SpawnReporter.chunkCounts.put(dim, int_2);
@@ -0,0 +1,54 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
@Mixin(ServerWorld.class)
public class ServerWorld_onePlayerSleepingMixin
{
@Shadow @Final private List<ServerPlayerEntity> players;
@Shadow private boolean allPlayersSleeping;
@Inject(method = "updatePlayersSleeping", cancellable = true, at = @At("HEAD"))
private void updateOnePlayerSleeping(CallbackInfo ci)
{
if(CarpetSettings.getBool("onePlayerSleeping"))
{
allPlayersSleeping = false;
for (ServerPlayerEntity p : players)
if (!p.isSpectator() && p.isSleeping())
{
allPlayersSleeping = true;
ci.cancel();
return;
}
ci.cancel();
}
}
@Redirect(method = "tick", at = @At(
value = "INVOKE",
target = "Ljava/util/stream/Stream;noneMatch(Ljava/util/function/Predicate;)Z"
))
private boolean noneMatchSleep(Stream<ServerPlayerEntity> stream, Predicate<ServerPlayerEntity> predicate)
{
if (CarpetSettings.getBool("onePlayerSleeping"))
return stream.anyMatch((p) -> !p.isSpectator() && p.isSleepingLongEnough());
return stream.noneMatch(predicate);
}
}
@@ -1,24 +1,82 @@
package carpet.mixins; package carpet.mixins;
import carpet.CarpetSettings; import carpet.CarpetSettings;
import carpet.fakes.WorldInterface;
import carpet.utils.SpawnReporter; import carpet.utils.SpawnReporter;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BoundingBox;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.SpawnHelper; import net.minecraft.world.SpawnHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Map;
@Mixin(SpawnHelper.class) @Mixin(SpawnHelper.class)
public abstract class SpawnHelperMixin public class SpawnHelperMixin
{ {
// in World: private static Map<EntityType, Entity> precookedMobs= new HashMap<>();
@Redirect(method = "spawnEntitiesInChunk", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/World;doesNotCollide(Lnet/minecraft/util/math/BoundingBox;)Z"
))
private static boolean doesNotCollide(World world, BoundingBox bb)
{
//.doesNotCollide is VERY expensive. On the other side - most worlds are not made of trapdoors in
// various configurations, but solid and 'passable' blocks, like air, water grass, etc.
// checking if in the BB of the entity are only passable blocks is very cheap and covers most cases
// in case something more complex happens - we default to full block collision check
if (CarpetSettings.b_lagFreeSpawning)
{
BlockPos.Mutable blockpos = new BlockPos.Mutable();
for (int x = (int)bb.minX, maxx = (int)Math.ceil(bb.maxX); x < maxx; x++)
for (int z = (int)bb.minZ, maxz = (int)Math.ceil(bb.maxZ); z < maxz; z++)
for (int y = (int)bb.minY, maxy = (int)Math.ceil(bb.maxY); y < maxy; y++)
{
blockpos.set(x, y, z);
if (world.getBlockState(blockpos).getCollisionShape(world, blockpos) != VoxelShapes.empty())
return world.doesNotCollide(bb);
}
return true;
}
return world.doesNotCollide(bb);
}
@Redirect(method = "spawnEntitiesInChunk", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/EntityType;create(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;"
))
private static Entity create(EntityType<?> entityType, World world_1)
{
if (CarpetSettings.b_lagFreeSpawning)
{
Map<EntityType, Entity> precookedMobs = ((WorldInterface)world_1).getPrecookedMobs();
if (precookedMobs.containsKey(entityType))
//this mob has been <init>'s but not used yet
return precookedMobs.get(entityType);
Entity e = entityType.create(world_1);
precookedMobs.put(entityType, e);
return e;
}
return entityType.create(world_1);
}
@Redirect(method = "spawnEntitiesInChunk", at = @At( @Redirect(method = "spawnEntitiesInChunk", at = @At(
value = "INVOKE", value = "INVOKE",
target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"
)) ))
private static boolean catchEntitySpawn(World world, Entity entity_1) private static boolean spawnEntity(World world, Entity entity_1)
{ {
if (CarpetSettings.b_lagFreeSpawning)
// we used the mob - next time we will create a new one when needed
((WorldInterface) world).getPrecookedMobs().remove(entity_1.getType());
if (SpawnReporter.track_spawns > 0L && SpawnReporter.local_spawns != null) if (SpawnReporter.track_spawns > 0L && SpawnReporter.local_spawns != null)
{ {
SpawnReporter.registerSpawn( SpawnReporter.registerSpawn(
@@ -31,6 +89,4 @@ public abstract class SpawnHelperMixin
return world.spawnEntity(entity_1); return world.spawnEntity(entity_1);
return false; return false;
} }
} }
@@ -0,0 +1,54 @@
package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LightningEntity;
import net.minecraft.entity.mob.SkeletonHorseEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.command.SummonCommand;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.LocalDifficulty;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(SummonCommand.class)
public class SummonCommandMixin
{
@Inject(method = "execute", locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true, at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/world/ServerWorld;addLightning(Lnet/minecraft/entity/LightningEntity;)V",
shift = At.Shift.BEFORE
))
private static void addRiders(ServerCommandSource source, Identifier identifier_1, Vec3d vec3d_1, CompoundTag compoundTag_1, boolean arg4, CallbackInfoReturnable<Integer> cir, CompoundTag compoundTag_2, LightningEntity lightningEntity_1)
{
// [CM] SummonNaturalLightning - if statement around
if (CarpetSettings.getBool("summonNaturalLightning") && !source.getWorld().isClient)
{
ServerWorld world = source.getWorld();
BlockPos at = new BlockPos(vec3d_1);
LocalDifficulty localDifficulty_1 = source.getWorld().getLocalDifficulty(at);
boolean boolean_2 = world.getGameRules().getBoolean("doMobSpawning") && world.random.nextDouble() < (double)localDifficulty_1.getLocalDifficulty() * 0.01D;
if (boolean_2) {
SkeletonHorseEntity skeletonHorseEntity_1 = (SkeletonHorseEntity) EntityType.SKELETON_HORSE.create(world);
skeletonHorseEntity_1.setTrapped(true);
skeletonHorseEntity_1.setBreedingAge(0);
skeletonHorseEntity_1.setPosition(vec3d_1.x, vec3d_1.y, vec3d_1.z);
world.spawnEntity(skeletonHorseEntity_1);
}
world.addLightning(lightningEntity_1);
source.sendFeedback(new TranslatableComponent("commands.summon.success", new Object[]{lightningEntity_1.getDisplayName()}), true);
cir.setReturnValue(1);
cir.cancel();
}
}
}
@@ -1,9 +1,11 @@
package carpet.mixins; package carpet.mixins;
import carpet.fakes.WorldInterface;
import carpet.helpers.TickSpeed; import carpet.helpers.TickSpeed;
import carpet.utils.CarpetProfiler; import carpet.utils.CarpetProfiler;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.profiler.Profiler; import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -14,15 +16,24 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
@Mixin(World.class) @Mixin(World.class)
public abstract class World_tickMixin public abstract class World_tickMixin implements WorldInterface
{ {
CarpetProfiler.ProfilerToken currentSection; CarpetProfiler.ProfilerToken currentSection;
CarpetProfiler.ProfilerToken entitySection; CarpetProfiler.ProfilerToken entitySection;
Map<EntityType, Entity> precookedMobs = new HashMap<>();
public Map<EntityType, Entity> getPrecookedMobs()
{
return precookedMobs;
}
@Inject(method = "tickBlockEntities", at = @At("HEAD")) @Inject(method = "tickBlockEntities", at = @At("HEAD"))
private void startBlockEntities(CallbackInfo ci) { private void startBlockEntities(CallbackInfo ci) {
currentSection = CarpetProfiler.start_section((World) (Object) this, "Tile Entities", CarpetProfiler.TYPE.GENERAL); currentSection = CarpetProfiler.start_section((World) (Object) this, "Tile Entities", CarpetProfiler.TYPE.GENERAL);
+9 -1
View File
@@ -5,7 +5,6 @@
"mixins": [ "mixins": [
"CommandManagerMixin", "CommandManagerMixin",
"FillCommandMixin", "FillCommandMixin",
"CloneCommandMixin", "CloneCommandMixin",
"SetBlockCommandMixin", "SetBlockCommandMixin",
@@ -32,6 +31,15 @@
"PlayerActionC2SPacketMixin", "PlayerActionC2SPacketMixin",
"ServerPlayerEntityMixin", "ServerPlayerEntityMixin",
"PlayerManagerMixin", "PlayerManagerMixin",
"CarpetBlockMixin",
"SummonCommandMixin",
"PistonHandler_pushLimitMixin",
"PoweredRailBlock_powerLimitMixin",
"LivingEntity_maxCollisionsMixin",
"ServerWorld_onePlayerSleepingMixin",
"KelpFeatureMixin",
"CoralBlockMixin",
"CoralFeatureMixin",
"ServerChunkManagerMixin", "ServerChunkManagerMixin",
"SpawnHelperMixin", "SpawnHelperMixin",