feat: 新的强化深板岩可获得机制
This commit is contained in:
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));
|
||||
}
|
||||
}
|
||||
+56
@@ -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));
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -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)
|
||||
),
|
||||
|
||||
+99
-6
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user