XpNoCooldown and combineXpOrbs refactor (#1149)
* - Fix xpNoCooldown to work as it did in 1.17- - Remove XPcombine - Use vanilla merge methods * Remove debug code * fix: rollback sort carpet.mixins.json * rework: nerf xp cooldown absorption a little * remove: combineXpOrbs fix: xpCooldown * revert renames * fix newlines * fix: wrong implementation for absorption * add missing `private` keyword * fix: player xp cooldown set wrongly * fix: injection point to be within condition
This commit is contained in:
1 parent
4af1d66450
commit
28a5e7acf1
6 files changed
+54
-204
No files matched your search
@@ -184,10 +184,6 @@ public class CarpetSettings
|
|||||||
@Rule( desc = "Players absorb XP instantly, without delay", category = CREATIVE )
|
@Rule( desc = "Players absorb XP instantly, without delay", category = CREATIVE )
|
||||||
public static boolean xpNoCooldown = false;
|
public static boolean xpNoCooldown = false;
|
||||||
|
|
||||||
|
|
||||||
@Rule( desc = "XP orbs combine with other into bigger orbs", category = FEATURE )
|
|
||||||
public static boolean combineXPOrbs = false;
|
|
||||||
|
|
||||||
@Rule(
|
@Rule(
|
||||||
desc = "Empty shulker boxes can stack to 64 when dropped on the ground",
|
desc = "Empty shulker boxes can stack to 64 when dropped on the ground",
|
||||||
extra = ".. or when manipulated inside the inventories",
|
extra = ".. or when manipulated inside the inventories",
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
package carpet.helpers;
|
|
||||||
|
|
||||||
import carpet.fakes.ExperienceOrbInterface;
|
|
||||||
import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.ExperienceOrbEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
|
|
||||||
public class XPcombine
|
|
||||||
{
|
|
||||||
public static void searchForOtherXPNearby(ExperienceOrbEntity first)
|
|
||||||
{
|
|
||||||
for (ExperienceOrbEntity entityxp : first.world.getNonSpectatingEntities(ExperienceOrbEntity.class, first.getBoundingBox().expand(0.5D, 0.0D, 0.5D)))
|
|
||||||
{
|
|
||||||
combineItems(first, entityxp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static long tone = 0;
|
|
||||||
private static int lastTickCombine = 0;
|
|
||||||
private static boolean combineItems(ExperienceOrbEntity first, ExperienceOrbEntity other)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
first == other || first.world.isClient || first.getServer().getTicks() == lastTickCombine
|
|
||||||
|| !first.isAlive() || !other.isAlive()
|
|
||||||
|| first.getExperienceAmount() > 15000 || other.getExperienceAmount() > 15000
|
|
||||||
//|| first.pickupDelay == 32767 || other.pickupDelay == 32767
|
|
||||||
|| first.age == -32768 || other.age == -32768
|
|
||||||
|| ((ExperienceOrbInterface)first).getCombineDelay() != 0 || ((ExperienceOrbInterface)other).getCombineDelay() != 0
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = getTextureByXP(first.getExperienceAmount());
|
|
||||||
((ExperienceOrbInterface) first).setAmount(
|
|
||||||
first.getExperienceAmount()*((ExperienceOrbInterface) first).getCount() +
|
|
||||||
other.getExperienceAmount()*((ExperienceOrbInterface) other).getCount());
|
|
||||||
((ExperienceOrbInterface) first).setCount(1);
|
|
||||||
//((ExperienceOrbInterface) first).setCombineDelay(Math.max(first.pickupDelay, other.pickupDelay));
|
|
||||||
first.age = Math.min(first.age, other.age);
|
|
||||||
other.discard(); //discard
|
|
||||||
|
|
||||||
|
|
||||||
ExperienceOrbEntity newOrb;
|
|
||||||
if (getTextureByXP(first.getExperienceAmount()) != size)
|
|
||||||
{
|
|
||||||
newOrb = new ExperienceOrbEntity(EntityType.EXPERIENCE_ORB, first.world);
|
|
||||||
newOrb.refreshPositionAndAngles(first.getX(), first.getY(), first.getZ(), first.getYaw(), first.getPitch());
|
|
||||||
((ExperienceOrbInterface)newOrb).setAmount(first.getExperienceAmount());
|
|
||||||
|
|
||||||
first.world.spawnEntity(newOrb);
|
|
||||||
first.discard(); // discard
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((ExperienceOrbInterface) first).setCombineDelay(50);
|
|
||||||
newOrb = first;
|
|
||||||
}
|
|
||||||
newOrb.setVelocity(first.getVelocity().add(new Vec3d(
|
|
||||||
(first.world.random.nextDouble() * 1.0D - 0.5D),
|
|
||||||
(first.world.random.nextDouble() * 0.5D),
|
|
||||||
(first.world.random.nextDouble() * 1.0D - 0.5D)
|
|
||||||
)));
|
|
||||||
float pitch = (float)Math.pow(2.0D, (tone%13)/12.0D )/2.0F;
|
|
||||||
tone+=2;
|
|
||||||
if(tone%13 == 0 || tone%13 == 1 || tone%13 == 6) tone --;
|
|
||||||
lastTickCombine = newOrb.getServer().getTicks();
|
|
||||||
for (PlayerEntity p : newOrb.world.getPlayers())
|
|
||||||
{
|
|
||||||
ServerPlayerEntity sp = (ServerPlayerEntity)p;
|
|
||||||
if (sp.squaredDistanceTo(newOrb) < 256.0D)
|
|
||||||
{
|
|
||||||
sp.networkHandler.sendPacket(new PlaySoundIdS2CPacket(
|
|
||||||
Registry.SOUND_EVENT.getId(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP),
|
|
||||||
SoundCategory.PLAYERS, newOrb.getPos(),
|
|
||||||
pitch-newOrb.world.random.nextFloat()/2f,
|
|
||||||
pitch));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// COPY FROM CLIENT CODE
|
|
||||||
private static int getTextureByXP(int xpValue)
|
|
||||||
{
|
|
||||||
if (xpValue >= 2477)
|
|
||||||
{
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 1237)
|
|
||||||
{
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 617)
|
|
||||||
{
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 307)
|
|
||||||
{
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 149)
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 73)
|
|
||||||
{
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 37)
|
|
||||||
{
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 17)
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
else if (xpValue >= 7)
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return xpValue >= 3 ? 1 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +1,44 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.CarpetSettings;
|
import carpet.CarpetSettings;
|
||||||
import carpet.fakes.ExperienceOrbInterface;
|
|
||||||
import carpet.helpers.XPcombine;
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.ExperienceOrbEntity;
|
import net.minecraft.entity.ExperienceOrbEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
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 java.util.Map;
|
|
||||||
|
|
||||||
@Mixin(ExperienceOrbEntity.class)
|
@Mixin(ExperienceOrbEntity.class)
|
||||||
public abstract class ExperienceOrbEntityMixin implements ExperienceOrbInterface
|
public abstract class ExperienceOrbEntityMixin {
|
||||||
{
|
@Shadow
|
||||||
@Shadow private int amount;
|
private int pickingCount;
|
||||||
|
|
||||||
@Shadow private int pickingCount;
|
@Shadow
|
||||||
|
private int amount;
|
||||||
|
|
||||||
@Shadow protected abstract int getMendingRepairCost(int repairAmount);
|
@Shadow
|
||||||
|
protected abstract int repairPlayerGears(PlayerEntity player, int amount);
|
||||||
|
|
||||||
@Shadow protected abstract int getMendingRepairAmount(int experienceAmount);
|
@Inject(
|
||||||
|
method = "onPlayerCollision",
|
||||||
public void setAmount(int amount) { this.amount = amount; }
|
|
||||||
|
|
||||||
public int combineDelay = 50;
|
|
||||||
|
|
||||||
public int getCombineDelay() { return combineDelay; }
|
|
||||||
public void setCombineDelay(int what) { combineDelay = what; }
|
|
||||||
|
|
||||||
@Inject(method = "tick",
|
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "FIELD",
|
||||||
target = "Lnet/minecraft/entity/ExperienceOrbEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V",
|
target = "net/minecraft/entity/player/PlayerEntity.experiencePickUpDelay:I",
|
||||||
shift = At.Shift.AFTER
|
ordinal = 0
|
||||||
))
|
)
|
||||||
void checkCombineAtTick(CallbackInfo ci)
|
)
|
||||||
{
|
private void addXP(PlayerEntity player, CallbackInfo ci) {
|
||||||
if (CarpetSettings.combineXPOrbs)
|
if (CarpetSettings.xpNoCooldown) {
|
||||||
{
|
player.experiencePickUpDelay = 0;
|
||||||
if (getCombineDelay() > 0)
|
// reducing the count to 1 and leaving vanilla to deal with it
|
||||||
{
|
while (this.pickingCount > 1) {
|
||||||
setCombineDelay(getCombineDelay()-1);
|
int remainder = this.repairPlayerGears(player, this.amount);
|
||||||
|
if (remainder > 0) {
|
||||||
|
player.addExperience(remainder);
|
||||||
|
}
|
||||||
|
this.pickingCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCombineDelay() == 0)
|
|
||||||
{
|
|
||||||
XPcombine.searchForOtherXPNearby((ExperienceOrbEntity) (Object) this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return pickingCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCount(int i) {
|
|
||||||
pickingCount = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "onPlayerCollision", at = @At("HEAD"))
|
|
||||||
void removeDelay(PlayerEntity playerEntity_1, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
if (CarpetSettings.xpNoCooldown)
|
|
||||||
playerEntity_1.experiencePickUpDelay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "onPlayerCollision", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;addExperience(I)V"))
|
|
||||||
void addXP(PlayerEntity playerEntity, int experience)
|
|
||||||
{
|
|
||||||
playerEntity.addExperience(experience);
|
|
||||||
if (CarpetSettings.xpNoCooldown) while(pickingCount > 1)
|
|
||||||
{
|
|
||||||
pickingCount --;
|
|
||||||
playerEntity.addExperience(experience);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package carpet.mixins;
|
||||||
|
|
||||||
|
import carpet.CarpetSettings;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
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.Redirect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(PlayerEntity.class)
|
||||||
|
public abstract class PlayerEntity_xpNoCooldownMixin {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract void collideWithEntity(Entity entity);
|
||||||
|
|
||||||
|
@Redirect(method = "tickMovement",at = @At(value = "INVOKE", target = "java/util/List.add(Ljava/lang/Object;)Z"))
|
||||||
|
public boolean processXpOrbCollisions(List<Entity> instance, Object e) {
|
||||||
|
Entity entity = (Entity) e;
|
||||||
|
if (CarpetSettings.xpNoCooldown) {
|
||||||
|
this.collideWithEntity(entity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return instance.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,4 +3,4 @@ accessWidener v1 named
|
|||||||
accessible class net/minecraft/server/world/ThreadedAnvilChunkStorage$TicketManager
|
accessible class net/minecraft/server/world/ThreadedAnvilChunkStorage$TicketManager
|
||||||
accessible class net/minecraft/server/world/ServerLightingProvider$Stage
|
accessible class net/minecraft/server/world/ServerLightingProvider$Stage
|
||||||
accessible class net/minecraft/recipe/Ingredient$Entry
|
accessible class net/minecraft/recipe/Ingredient$Entry
|
||||||
accessible class net/minecraft/world/chunk/light/BlockLightStorage$Data
|
accessible class net/minecraft/world/chunk/light/BlockLightStorage$Data
|
||||||
@@ -78,6 +78,7 @@
|
|||||||
"MinecraftServer_scarpetMixin",
|
"MinecraftServer_scarpetMixin",
|
||||||
"PlayerListHeaderS2CPacketMixin",
|
"PlayerListHeaderS2CPacketMixin",
|
||||||
"ExperienceOrbEntityMixin",
|
"ExperienceOrbEntityMixin",
|
||||||
|
"PlayerEntity_xpNoCooldownMixin",
|
||||||
"PlayerActionC2SPacketMixin",
|
"PlayerActionC2SPacketMixin",
|
||||||
"ServerPlayerEntityMixin",
|
"ServerPlayerEntityMixin",
|
||||||
"PlayerManager_coreMixin",
|
"PlayerManager_coreMixin",
|
||||||
|
|||||||
Reference in new issue
Block a user