feat: 新的强化深板岩可获得机制

This commit is contained in:
Disy authored and zly2006 committed 2024-07-11 12:14:03 +08:00
1 parent 22d2225b9c
commit ba13ab4f71
10 files changed
+204 -51

No files matched your search

@@ -2,6 +2,7 @@ package com.github.zly2006.carpetslsaddition;
import carpet.CarpetExtension;
import carpet.CarpetServer;
import com.github.zly2006.carpetslsaddition.block.entity.SLSDeepSlateBlockEntity;
import com.github.zly2006.carpetslsaddition.command.BotCommand;
import com.github.zly2006.carpetslsaddition.command.HatCommand;
import com.github.zly2006.carpetslsaddition.command.SitCommand;
@@ -14,6 +15,8 @@ import com.mojang.brigadier.CommandDispatcher;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.Version;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
@@ -42,6 +45,7 @@ public class ServerMain implements ModInitializer, CarpetExtension {
public void onInitialize() {
INSTANCE = this;
CarpetServer.manageExtension(this);
registerBlockEntities();
}
@Override
@@ -86,4 +90,8 @@ public class ServerMain implements ModInitializer, CarpetExtension {
SitCommand.register(dispatcher);
BotCommand.register(dispatcher);
}
public void registerBlockEntities() {
SLSDeepSlateBlockEntity.BLOCK_ENTITY_TYPE = SLSDeepSlateBlockEntity.createType(BlockEntityType.Builder.create(SLSDeepSlateBlockEntity::new, Blocks.DEEPSLATE));
}
}
@@ -0,0 +1,56 @@
package com.github.zly2006.carpetslsaddition.block.entity;
import com.mojang.datafixers.types.Type;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import static net.minecraft.nbt.NbtElement.BYTE_TYPE;
/**
* 没有很好的让深板岩保留BlockEntity的方案,暂时不使用
*/
@Deprecated
public class SLSDeepSlateBlockEntity extends BlockEntity {
public static BlockEntityType<SLSDeepSlateBlockEntity> BLOCK_ENTITY_TYPE;
private boolean deepSlateCore = false;
public SLSDeepSlateBlockEntity(BlockPos pos, BlockState state) {
super(SLSDeepSlateBlockEntity.BLOCK_ENTITY_TYPE, pos, state);
}
@Override
protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
super.readNbt(nbt, registryLookup);
if (nbt.contains("deep_slate_core", BYTE_TYPE)) {
deepSlateCore = nbt.getBoolean("deep_slate_core");
}
}
@Override
protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
super.writeNbt(nbt, registryLookup);
nbt.putBoolean("deep_slate_core", deepSlateCore);
}
public boolean isDeepSlateCore() {
return deepSlateCore;
}
public void setDeepSlateCore(boolean deepSlateCore) {
this.deepSlateCore = deepSlateCore;
}
public static BlockEntityType<SLSDeepSlateBlockEntity> createType(BlockEntityType.Builder<SLSDeepSlateBlockEntity> builder) {
Type<?> type = Util.getChoiceType(TypeReferences.BLOCK_ENTITY, "sls_deepslate");
return Registry.register(Registries.BLOCK_ENTITY_TYPE, "sls_deepslate", builder.build(type));
}
}
@@ -1,6 +1,7 @@
package com.github.zly2006.carpetslsaddition.mixin.carpet;
import carpet.patches.EntityPlayerMPFake;
import carpet.utils.Translations;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.util.access.SLSBotAccessor;
@@ -64,7 +65,7 @@ public abstract class MixinEntityPlayerMPFake extends ServerPlayerEntity impleme
if (liveTime > SLSCarpetSettings.botMaxOnlineTime * 1000) {
ServerMain.server.getPlayerManager().broadcast(
Text.translatable("carpet.slsa.bot.bot_timeout", this.getNameForScoreboard(), getFormattedTime(SLSCarpetSettings.botMaxOnlineTime))
Text.literal(Translations.tr("carpet.slsa.bot.bot_timeout").formatted(this.getNameForScoreboard(), getFormattedTime(SLSCarpetSettings.botMaxOnlineTime)))
.setStyle(
Style.EMPTY.withColor(Formatting.RED)
),
@@ -1,32 +1,125 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import carpet.utils.Translations;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.block.entity.SLSDeepSlateBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import static net.minecraft.nbt.NbtElement.COMPOUND_TYPE;
@Mixin(FallingBlockEntity.class)
public abstract class MixinFallingBlockEntity extends Entity {
@Shadow private BlockState block;
@Shadow private boolean destroyedOnLanding;
public MixinFallingBlockEntity(EntityType<?> type, World world) {
super(type, world);
}
@Inject(method = "handleFallDamage", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getOtherEntities(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/Box;Ljava/util/function/Predicate;)Ljava/util/List;", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT)
private void handleFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource, CallbackInfoReturnable<Boolean> cir, int i, Predicate<Entity> predicate, DamageSource damageSource2, float f) {
if (SLSCarpetSettings.obtainableReinforcedDeepSlate) {
predicate = entity -> entity instanceof ItemEntity;
this.getWorld().getOtherEntities(this, this.getBoundingBox(), predicate).forEach((entity) -> entity.damage(damageSource2, f));
@Inject(method = "handleFallDamage", at = @At(value = "TAIL"))
private void handleFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource, CallbackInfoReturnable<Boolean> cir) {
if (!SLSCarpetSettings.obtainableReinforcedDeepSlate || !this.block.isIn(BlockTags.ANVIL)) {
return;
}
Predicate<Entity> deepSlatePredicated = (entity) -> {
if (entity instanceof ItemEntity itemEntity) {
var itemStack = itemEntity.getStack();
return itemStack.isOf(Items.DEEPSLATE) && itemStack.getCount() >= 64;
}
return false;
};
this.getWorld().getOtherEntities(this, this.getBoundingBox(), deepSlatePredicated).forEach((entity) -> {
var deepSlateEntity = (ItemEntity) entity; // deepSlatePredicated保证转换的安性
var stackNbtComponent = deepSlateEntity.getStack().getOrDefault(DataComponentTypes.BLOCK_ENTITY_DATA, NbtComponent.DEFAULT);
if (!tryCreateDeepSlateCore(deepSlateEntity, stackNbtComponent)) {
((ItemEntity) entity).setStack(new ItemStack(Items.REINFORCED_DEEPSLATE, 1));
}
markSuccessfulForged();
});
}
/**
* 尝试创造一个深板岩核心
* @param itemEntity 深板岩物品实体,不应传入非深板岩的物品
* @param itemComponent 深板岩物品的Block Entity数据
* @return 是否创建成功
*/
@Unique
private boolean tryCreateDeepSlateCore(ItemEntity itemEntity, NbtComponent itemComponent) {
AtomicBoolean success = new AtomicBoolean(true);
var itemStack = itemEntity.getStack().copy();
itemComponent.apply( blockEntityData -> {
if (blockEntityData.getBoolean("deep_slate_core")) {
success.set(false);
return;
}
blockEntityData.putBoolean("deep_slate_core", true);
BlockItem.setBlockEntityData(itemStack, SLSDeepSlateBlockEntity.BLOCK_ENTITY_TYPE, blockEntityData);
itemStack.set(
DataComponentTypes.CUSTOM_NAME,
Text.literal(Translations.tr("carpet.slsa.block.deep_slate_core"))
.setStyle(Style.EMPTY.withColor(Formatting.LIGHT_PURPLE))
);
itemStack.setCount(1);
var pos = itemEntity.getPos();
itemEntity.discard();
var coreEntity = new ItemEntity(this.getWorld(), pos.getX(), pos.getY(), pos.getZ(), itemStack);
coreEntity.setPickupDelay(40);
float f = this.random.nextFloat() * 0.5F;
float g = this.random.nextFloat() * (float) (Math.PI * 2);
coreEntity.setVelocity(-MathHelper.sin(g) * f, 0.2F, MathHelper.cos(g) * f);
this.getWorld().spawnEntity(coreEntity);
});
return success.get();
}
@Unique
private void markSuccessfulForged() {
this.getWorld().playSoundAtBlockCenter(this.getBlockPos(), SoundEvents.BLOCK_ANVIL_USE, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
this.destroyedOnLanding = true;
}
}
@@ -1,40 +0,0 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
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.callback.CallbackInfoReturnable;
@Mixin(ItemEntity.class)
public abstract class MixinItemEntity extends Entity {
public MixinItemEntity(EntityType<?> type, World world) {
super(type, world);
}
@Shadow
public abstract ItemStack getStack();
@Shadow
public abstract void setStack(ItemStack stack);
@Inject(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/ItemEntity;discard()V"), cancellable = true)
private void damage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
if (source.getTypeRegistryEntry().matchesKey(DamageTypes.FALLING_ANVIL) && SLSCarpetSettings.obtainableReinforcedDeepSlate) {
if ((getStack().isOf(Items.DEEPSLATE) || getStack().isOf(Items.COBBLED_DEEPSLATE))
&& getStack().getCount() == 64) {
setStack(new ItemStack(Items.REINFORCED_DEEPSLATE));
cir.setReturnValue(true);
}
}
}
}
@@ -0,0 +1,31 @@
package com.github.zly2006.carpetslsaddition.mixin.item;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Item.class)
public class MixinItem {
@Redirect(
method = "hasGlint",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/item/ItemStack;hasEnchantments()Z"
)
)
public boolean hasGlint(ItemStack itemStack) {
if (!itemStack.isOf(Items.DEEPSLATE)) {
return itemStack.hasEnchantments();
}
return itemStack.getOrDefault(
DataComponentTypes.BLOCK_ENTITY_DATA,
NbtComponent.DEFAULT
).copyNbt().getBoolean("deep_slate_core") || itemStack.hasEnchantments();
}
}