Skip to content

Commit

Permalink
完善与优化
Browse files Browse the repository at this point in the history
+ 完善了浸液系统
* 将游戏触发器添加到注册表内
* 优化项目结构
  • Loading branch information
WinExp committed Jun 10, 2024
1 parent 96b182e commit 6717232
Show file tree
Hide file tree
Showing 47 changed files with 993 additions and 241 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx8G
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.20.6
yarn_mappings=1.20.6+build.1
loader_version=0.15.10
loader_version=0.15.11

# Mod Properties
mod_id = battlegrounds
Expand All @@ -15,4 +15,4 @@ org.gradle.jvmargs=-Xmx8G

# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version = 0.97.8+1.20.6
fabric_version = 0.99.4+1.20.6
10 changes: 8 additions & 2 deletions src/main/java/com/github/winexp/battlegrounds/Battlegrounds.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import com.github.winexp.battlegrounds.network.payload.s2c.play.FlashPayloadS2C;
import com.github.winexp.battlegrounds.network.payload.s2c.play.config.ModGameConfigPayloadS2C;
import com.github.winexp.battlegrounds.network.payload.s2c.play.vote.*;
import com.github.winexp.battlegrounds.registry.ModRegistries;
import com.github.winexp.battlegrounds.resource.listener.DataPackResourceReloadListener;
import com.github.winexp.battlegrounds.screen.ScreenHandlerType;
import com.github.winexp.battlegrounds.sound.SoundEvents;
import com.github.winexp.battlegrounds.util.task.TaskScheduler;
import com.github.winexp.battlegrounds.util.Constants;
Expand Down Expand Up @@ -67,7 +69,7 @@ public void reload() {
}

private void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
BattlegroundsCommand.registerRoot(dispatcher);
BattlegroundsCommand.registerRoot(dispatcher, registryAccess, environment);
RandomTpCommand.register(dispatcher);
}

Expand Down Expand Up @@ -144,6 +146,8 @@ public void onInitialize() {
// 注册数据包
ResourceManagerHelper resourceManagerHelper = ResourceManagerHelper.get(ResourceType.SERVER_DATA);
resourceManagerHelper.registerReloadListener(new DataPackResourceReloadListener());
// 注册屏幕处理器
ScreenHandlerType.bootstrap();
// 注册方块
Blocks.bootstrap();
// 注册方块实体
Expand All @@ -162,10 +166,12 @@ public void onInitialize() {
StatusEffects.bootstrap();
// 注册附魔
Enchantments.bootstrap();
// 自动冶炼
// 注册自动冶炼方块
SmeltableBlockRegistry.registerDefaults();
// 注册声音事件
SoundEvents.bootstrap();
// 初始化自定义注册表
ModRegistries.bootstrap();
// 注册指令参数类型
this.registerCommandArgumentTypes();
// 尝试重置存档
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import net.minecraft.block.BlockWithEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -40,4 +44,24 @@ public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, net.minecraft.block.entity.BlockEntityType<T> type) {
return world.isClient ? null : validateTicker(type, BlockEntityType.SOAK_TABLE, SoakTableBlockEntity::tick);
}

@Override
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
if (world.isClient) {
return ActionResult.SUCCESS;
} else {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof SoakTableBlockEntity soakTableBlockEntity) {
player.openHandledScreen(soakTableBlockEntity);
}

return ActionResult.CONSUME;
}
}

@Override
protected void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
ItemScatterer.onStateReplaced(state, newState, world, pos);
super.onStateReplaced(state, world, pos, newState, moved);
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
package com.github.winexp.battlegrounds.block.entity;

import com.github.winexp.battlegrounds.component.DataComponentTypes;
import com.github.winexp.battlegrounds.component.SoakComponent;
import com.github.winexp.battlegrounds.item.Items;
import com.github.winexp.battlegrounds.registry.tag.ModItemTags;
import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
import com.github.winexp.battlegrounds.screen.SoakTableScreenHandler;
import com.github.winexp.battlegrounds.sound.SoundEvents;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.LockableContainerBlockEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.sound.SoundCategory;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.commons.lang3.mutable.MutableBoolean;

import java.util.Objects;

public class SoakTableBlockEntity extends LockableContainerBlockEntity {
private static final double DURATION_MULTIPLIER = 1.0 / 8 / 12;
private static final Text NAME = Text.translatable("container.battlegrounds.soak_table");
private static final int MAX_SOAK_TIME = 15 * 20;
private static final int SOAK_TIME = 2 * 20;
private static final int FUEL_PROPERTY_INDEX = 0;
private static final int SOAK_TIME_PROPERTY_INDEX = 1;
private static final int FUEL_SLOT_INDEX = 0;
private static final int INPUT_SLOT_INDEX = 1;
private static final int POTION_SLOT_INDEX = 2;
private static final int MAX_FUEL = 8;
private static final int FUEL_PER_ITEM = 4;
public static final int INPUT_SLOT_INDEX = 0;
public static final int POTION_SLOT_INDEX = 1;
public static final int FUEL_SLOT_INDEX = 2;
private static final int MAX_FUEL = 3;
private static final int FUEL_PER_ITEM = 1;

private int soakTime;
private int fuel;
private DefaultedList<ItemStack> inventory;
private PropertyDelegate propertyDelegate;
private final PropertyDelegate propertyDelegate;

public SoakTableBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.SOAK_TABLE, pos, state);
Expand Down Expand Up @@ -75,16 +86,42 @@ protected void setHeldStacks(DefaultedList<ItemStack> inventory) {

@Override
protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerInventory) {
return null;
return new SoakTableScreenHandler(syncId, playerInventory, this, this.propertyDelegate);
}

@Override
public int size() {
return this.inventory.size();
}

@Override
protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
super.readNbt(nbt, registryLookup);
this.inventory = DefaultedList.ofSize(this.size(), ItemStack.EMPTY);
Inventories.readNbt(nbt, this.inventory, registryLookup);
this.soakTime = nbt.getShort("soak_time");
this.fuel = nbt.getByte("fuel");
}

@Override
protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
super.writeNbt(nbt, registryLookup);
Inventories.writeNbt(nbt, this.inventory, registryLookup);
nbt.putShort("soak_time", (short) this.soakTime);
nbt.putByte("fuel", (byte) this.fuel);
}

@Override
public boolean isValid(int slot, ItemStack stack) {
if (slot == INPUT_SLOT_INDEX) return stack.isIn(ModItemTags.SOAKABLE);
else if (slot == POTION_SLOT_INDEX) return stack.isOf(Items.POTION);
else if (slot == FUEL_SLOT_INDEX) return stack.isOf(Items.GUNPOWDER);
else return false;
}

public static void tick(World world, BlockPos pos, BlockState state, SoakTableBlockEntity blockEntity) {
ItemStack fuelStack = blockEntity.inventory.get(FUEL_SLOT_INDEX);
ItemStack inputStack = blockEntity.inventory.get(INPUT_SLOT_INDEX);
if (blockEntity.fuel + FUEL_PER_ITEM <= MAX_FUEL && fuelStack.isOf(Items.GUNPOWDER)) {
int amount = Math.min((MAX_FUEL - blockEntity.fuel) / FUEL_PER_ITEM, fuelStack.getCount());
blockEntity.fuel += amount * FUEL_PER_ITEM;
Expand All @@ -95,12 +132,50 @@ public static void tick(World world, BlockPos pos, BlockState state, SoakTableBl
if (blockEntity.soakTime > 0) {
blockEntity.soakTime--;
if (blockEntity.soakTime == 0 && canCraft) {
blockEntity.fuel--;
craft(world, pos, blockEntity.inventory);
markDirty(world, pos, state);
} else if (!canCraft && inputStack.isIn(ModItemTags.SOAKABLE)) {
blockEntity.soakTime = 0;
markDirty(world, pos, state);
}
} else if (canCraft && blockEntity.fuel > 0) {
blockEntity.soakTime = SOAK_TIME;
markDirty(world, pos, state);
}
}

private static boolean canCraft(DefaultedList<ItemStack> inventory) {
return inventory.get(INPUT_SLOT_INDEX).isIn(ModItemTags.SOAKABLE)
&& !inventory.get(POTION_SLOT_INDEX).isIn(ConventionalItemTags.POTIONS);
private static void craft(World world, BlockPos pos, DefaultedList<ItemStack> slots) {
ItemStack potionStack = slots.get(POTION_SLOT_INDEX);
ItemStack inputStack = slots.get(INPUT_SLOT_INDEX);
SoakComponent.Builder builder = inputStack.contains(DataComponentTypes.IMMERSE_DATA)
? new SoakComponent.Builder(SoakComponent.SoakType.IMMERSE, DURATION_MULTIPLIER, Objects.requireNonNull(inputStack.get(DataComponentTypes.IMMERSE_DATA)))
: new SoakComponent.Builder(SoakComponent.SoakType.IMMERSE, DURATION_MULTIPLIER);
builder.addAll(Objects.requireNonNull(potionStack.get(DataComponentTypes.POTION_CONTENTS)).getEffects());
inputStack.set(DataComponentTypes.IMMERSE_DATA, builder.build());
slots.set(INPUT_SLOT_INDEX, inputStack);
slots.set(POTION_SLOT_INDEX, new ItemStack(Items.GLASS_BOTTLE));
world.playSound(null, pos, SoundEvents.BLOCK_BREWING_STAND_BREW, SoundCategory.BLOCKS, 1.0F, 1.0F);
}

public static boolean canCraft(DefaultedList<ItemStack> inventory) {
ItemStack inputStack = inventory.get(INPUT_SLOT_INDEX);
ItemStack potionStack = inventory.get(POTION_SLOT_INDEX);
boolean immerseCheckFlag = inputStack.contains(DataComponentTypes.IMMERSE_DATA);
MutableBoolean isPotionInstant = new MutableBoolean(false);
MutableBoolean isPotionAlready = new MutableBoolean(false);
if (potionStack.contains(DataComponentTypes.POTION_CONTENTS)) {
Objects.requireNonNull(potionStack.get(DataComponentTypes.POTION_CONTENTS)).forEachEffect(effect -> {
if (effect.getEffectType().value().isInstant()) isPotionInstant.setValue(true);

if (immerseCheckFlag) {
SoakComponent component = inputStack.get(DataComponentTypes.IMMERSE_DATA);
assert component != null;
if (component.contains(effect)) isPotionAlready.setValue(true);
}
});
} else return false;
return inputStack.isIn(ModItemTags.SOAKABLE)
&& potionStack.isOf(Items.POTION) && !isPotionInstant.getValue() && !isPotionAlready.getValue();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.winexp.battlegrounds.client;

import com.github.winexp.battlegrounds.client.gui.screen.SoakScreen;
import com.github.winexp.battlegrounds.client.gui.screen.vote.VoteScreen;
import com.github.winexp.battlegrounds.client.network.ModClientConfigurationNetworkHandler;
import com.github.winexp.battlegrounds.client.network.ModClientPlayNetworkHandler;
Expand All @@ -11,6 +12,7 @@
import com.github.winexp.battlegrounds.entity.EntityTypes;
import com.github.winexp.battlegrounds.event.ClientVoteEvents;
import com.github.winexp.battlegrounds.item.Items;
import com.github.winexp.battlegrounds.screen.ScreenHandlerType;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand All @@ -19,13 +21,14 @@
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.sound.SoundEvents;

@Environment(EnvType.CLIENT)
public class BattlegroundsClient implements ClientModInitializer {
private void registerRenderer() {
private static void registerRenderer() {
// 实体渲染器
EntityRendererRegistry.register(EntityTypes.CHANNELING_ARROW, ChannelingArrowEntityRenderer::new);
EntityRendererRegistry.register(EntityTypes.FLASH_BANG, FlyingItemEntityRenderer::new);
Expand All @@ -36,6 +39,10 @@ private void registerRenderer() {
WorldRenderEvents.BEFORE_BLOCK_OUTLINE.register(ClientConstants.RUPERTS_TEAR_BLOCK_OUTLINE_RENDERER);
}

private static void registerHandledScreen() {
HandledScreens.register(ScreenHandlerType.SOAK, SoakScreen::new);
}

@Override
public void onInitializeClient() {
// 注册事件
Expand All @@ -58,7 +65,8 @@ public void onInitializeClient() {
});
ClientTickEvents.END_CLIENT_TICK.register(VoteScreen::globalTick);
// 注册实体渲染器
this.registerRenderer();
registerRenderer();
registerHandledScreen();
// 注册网络包相关
ModClientConfigurationNetworkHandler.register();
ModClientPlayNetworkHandler.register();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.github.winexp.battlegrounds.client.gui.screen;

import com.github.winexp.battlegrounds.screen.SoakTableScreenHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

@Environment(EnvType.CLIENT)
public class SoakScreen extends HandledScreen<SoakTableScreenHandler> {
private static final Identifier TEXTURE = new Identifier("textures/gui/container/brewing_stand.png");

public SoakScreen(SoakTableScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}

@Override
protected void init() {
super.init();
this.titleX = (this.backgroundWidth - this.textRenderer.getWidth(this.title)) / 2;
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
this.drawMouseoverTooltip(context, mouseX, mouseY);
}

@Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
int i = (this.width - this.backgroundWidth) / 2;
int j = (this.height - this.backgroundHeight) / 2;
context.drawTexture(TEXTURE, i, j, 0, 0, this.backgroundWidth, this.backgroundHeight);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@
import java.util.Objects;

public class RupertsTearBlockOutlineRenderer implements WorldRenderEvents.BeforeBlockOutline {
private static final double LERP_DELTA = 0.016;
private static final double LERP_DELTA = 0.015;
private static final long LERP_DURATION = 1000 * 1000;
private static final Vec3d NaN = new Vec3d(Double.NaN, Double.NaN, Double.NaN);
private static final Vec3d VEC3D_NaN = new Vec3d(Double.NaN, Double.NaN, Double.NaN);

private Vec3d prevPos = NaN;
private Vec3d prevPos = VEC3D_NaN;
private long prevTime = System.nanoTime();

private void resetData() {
this.prevPos = NaN;
this.prevPos = VEC3D_NaN;
}

@Override
Expand All @@ -58,19 +58,19 @@ public boolean beforeBlockOutline(WorldRenderContext context, HitResult hitResul
Vec3d begin = entity.getCameraPosVec(tickDelta);
Vec3d rotation = entity.getRotationVec(tickDelta);
Vec3d end = begin.add(rotation.multiply(RupertsTearItem.MAX_DISTANCE));
long currentTime = System.nanoTime();
BlockRaycastResult raycastResult = MathUtil.raycastBlock(entity, begin, end, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, MathUtil.NONE_ABORT_PREDICATE, MathUtil.NONE_STRENGTH_FUNCTION);
BlockHitResult blockHitResult = raycastResult.hitResult();
BlockPos blockPos = blockHitResult.getBlockPos();
long currentTime = System.nanoTime();
float colorR, colorG, colorB, colorA;
if (blockHitResult.getType() == HitResult.Type.MISS
|| !world.getWorldBorder().contains(blockPos)) {
this.resetData();
return true;
}
if (RupertsTearItem.isSafe(world, blockHitResult)) {
colorR = 0.4F;
colorG = 0.4F;
colorR = 0.45F;
colorG = 0.45F;
colorB = 1.0F;
colorA = 0.9F;
} else {
Expand Down
Loading

0 comments on commit 6717232

Please sign in to comment.