注册Component,添加部分Energy Capability适配

This commit is contained in:
Light_Quanta 2025-03-27 00:11:22 +08:00
parent 69ff0f6151
commit f213642580
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
36 changed files with 1374 additions and 119 deletions

View file

@ -10,8 +10,10 @@ import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.ContainerHelper; import net.minecraft.world.ContainerHelper;
import net.minecraft.world.MenuProvider; import net.minecraft.world.MenuProvider;
@ -27,13 +29,17 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.energy.EnergyStorage; import net.neoforged.neoforge.energy.EnergyStorage;
import net.neoforged.neoforge.energy.IEnergyStorage;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.wrapper.SidedInvWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Energy Data Slot Code based on @GoryMoon's Chargers * Energy Data Slot Code based on @GoryMoon's Chargers
@ -52,40 +58,63 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
protected NonNullList<ItemStack> items = NonNullList.withSize(2, ItemStack.EMPTY); protected NonNullList<ItemStack> items = NonNullList.withSize(2, ItemStack.EMPTY);
private EnergyStorage energyHandler;
// TODO SidedInvWrapper Energy private BlockCapabilityCache<IEnergyStorage, @Nullable Direction> capCache;
// private LazyOptional<?>[] itemHandlers = SidedInvWrapper.create(this, Direction.UP, Direction.DOWN, Direction.NORTH);
@Override
public void onLoad() {
super.onLoad();
if (level != null && !level.isClientSide) {
this.capCache = BlockCapabilityCache.create(
Capabilities.EnergyStorage.BLOCK,
(ServerLevel) level,
this.getBlockPos(),
null
);
}
}
public int fuelTick = 0; public int fuelTick = 0;
public int maxFuelTick = DEFAULT_FUEL_TIME; public int maxFuelTick = DEFAULT_FUEL_TIME;
public boolean showRange = false; public boolean showRange = false;
protected final ContainerEnergyData dataAccess = new ContainerEnergyData() { protected final ContainerEnergyData dataAccess = new ContainerEnergyData() {
public long get(int pIndex) { public int get(int pIndex) {
return switch (pIndex) { return switch (pIndex) {
case 0 -> ChargingStationBlockEntity.this.fuelTick; case 0 -> ChargingStationBlockEntity.this.fuelTick;
case 1 -> ChargingStationBlockEntity.this.maxFuelTick; case 1 -> ChargingStationBlockEntity.this.maxFuelTick;
case 2 -> { case 2 -> {
AtomicInteger energy = new AtomicInteger(); var level = ChargingStationBlockEntity.this.level;
// ChargingStationBlockEntity.this.getCapability(Capabilities.ENERGY).ifPresent(consumer -> energy.set(consumer.getEnergyStored())); if (level == null) yield 0;
yield energy.get();
var cap = level.getCapability(Capabilities.EnergyStorage.BLOCK, ChargingStationBlockEntity.this.getBlockPos(), null);
if (cap == null) yield 0;
yield cap.getEnergyStored();
} }
case 3 -> ChargingStationBlockEntity.this.showRange ? 1 : 0; case 3 -> ChargingStationBlockEntity.this.showRange ? 1 : 0;
default -> 0; default -> 0;
}; };
} }
public void set(int pIndex, long pValue) { public void set(int pIndex, int pValue) {
switch (pIndex) { switch (pIndex) {
case 0: case 0:
ChargingStationBlockEntity.this.fuelTick = (int) pValue; ChargingStationBlockEntity.this.fuelTick = pValue;
break; break;
case 1: case 1:
ChargingStationBlockEntity.this.maxFuelTick = (int) pValue; ChargingStationBlockEntity.this.maxFuelTick = pValue;
break; break;
case 2: case 2:
// ChargingStationBlockEntity.this.getCapability(Capabilities.ENERGY).ifPresent(consumer -> consumer.receiveEnergy((int) pValue, false)); var level = ChargingStationBlockEntity.this.level;
if (level == null) return;
var cap = level.getCapability(Capabilities.EnergyStorage.BLOCK, ChargingStationBlockEntity.this.getBlockPos(), null);
if (cap == null) return;
cap.receiveEnergy((int) pValue, false);
break; break;
case 3: case 3:
ChargingStationBlockEntity.this.showRange = pValue == 1; ChargingStationBlockEntity.this.showRange = pValue == 1;
@ -100,8 +129,6 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
public ChargingStationBlockEntity(BlockPos pos, BlockState state) { public ChargingStationBlockEntity(BlockPos pos, BlockState state) {
super(ModBlockEntities.CHARGING_STATION.get(), pos, state); super(ModBlockEntities.CHARGING_STATION.get(), pos, state);
this.energyHandler = new EnergyStorage(MAX_ENERGY);
} }
public static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, ChargingStationBlockEntity blockEntity) { public static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, ChargingStationBlockEntity blockEntity) {
@ -110,7 +137,9 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
setChanged(pLevel, pPos, pState); setChanged(pLevel, pPos, pState);
} }
var handler = blockEntity.energyHandler; var handler = blockEntity.capCache.getCapability();
if (handler == null) return;
int energy = handler.getEnergyStored(); int energy = handler.getEnergyStored();
if (energy > 0) { if (energy > 0) {
blockEntity.chargeEntity(handler); blockEntity.chargeEntity(handler);
@ -191,7 +220,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
} }
} }
private void chargeEntity(EnergyStorage handler) { private void chargeEntity(IEnergyStorage handler) {
if (this.level == null) return; if (this.level == null) return;
if (this.level.getGameTime() % 20 != 0) return; if (this.level.getGameTime() % 20 != 0) return;
@ -206,7 +235,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
this.setChanged(); this.setChanged();
} }
private void chargeItemStack(EnergyStorage handler) { private void chargeItemStack(IEnergyStorage handler) {
ItemStack stack = this.getItem(SLOT_CHARGE); ItemStack stack = this.getItem(SLOT_CHARGE);
if (stack.isEmpty()) return; if (stack.isEmpty()) return;
@ -220,7 +249,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
this.setChanged(); this.setChanged();
} }
private void chargeBlock(EnergyStorage handler) { private void chargeBlock(IEnergyStorage handler) {
if (this.level == null) return; if (this.level == null) return;
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
@ -248,8 +277,11 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
protected void loadAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) { protected void loadAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
super.loadAdditional(tag, registries); super.loadAdditional(tag, registries);
if (tag.contains("Energy")) { if (tag.contains("Energy") && this.capCache.getCapability() != null) {
// getCapability(Capabilities.ENERGY).ifPresent(handler -> ((EnergyStorage) handler).deserializeNBT(tag.get("Energy"))); var energy = tag.get("Energy");
if (energy instanceof IntTag) {
((EnergyStorage) this.capCache.getCapability()).deserializeNBT(registries, energy);
}
} }
this.fuelTick = tag.getInt("FuelTick"); this.fuelTick = tag.getInt("FuelTick");
this.maxFuelTick = tag.getInt("MaxFuelTick"); this.maxFuelTick = tag.getInt("MaxFuelTick");
@ -262,7 +294,9 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) { protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) {
super.saveAdditional(tag, registries); super.saveAdditional(tag, registries);
// getCapability(Capabilities.ENERGY).ifPresent(handler -> tag.put("Energy", ((EnergyStorage) handler).serializeNBT())); if (this.capCache != null && this.capCache.getCapability() != null) {
tag.put("Energy", IntTag.valueOf(this.capCache.getCapability().getEnergyStored()));
}
tag.putInt("FuelTick", this.fuelTick); tag.putInt("FuelTick", this.fuelTick);
tag.putInt("MaxFuelTick", this.maxFuelTick); tag.putInt("MaxFuelTick", this.maxFuelTick);
tag.putBoolean("ShowRange", this.showRange); tag.putBoolean("ShowRange", this.showRange);
@ -363,35 +397,39 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
return compoundtag; return compoundtag;
} }
public static class EnergyStorageProvider implements ICapabilityProvider<ChargingStationBlockEntity, Direction, IEnergyStorage> {
private final IEnergyStorage energy = new EnergyStorage(MAX_ENERGY);
@Override
public @Nullable IEnergyStorage getCapability(@NotNull ChargingStationBlockEntity object, Direction context) {
return energy;
}
}
public static class ItemHandlerProvider implements ICapabilityProvider<ChargingStationBlockEntity, Direction, IItemHandler> {
private IItemHandler[] itemHandlers;
@Override
public @Nullable IItemHandler getCapability(@NotNull ChargingStationBlockEntity object, Direction context) {
if (context == null || object.isRemoved()) return null;
if (itemHandlers == null) {
this.itemHandlers = new IItemHandler[]{
new SidedInvWrapper(object, Direction.UP),
new SidedInvWrapper(object, Direction.DOWN),
new SidedInvWrapper(object, Direction.NORTH),
};
}
return switch (context) {
case UP -> itemHandlers[0];
case DOWN -> itemHandlers[1];
default -> itemHandlers[2];
};
}
}
// @Override
// public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
// if (cap == Capabilities.ENERGY) {
// return energyHandler.cast();
// }
// if (!this.remove && side != null && cap == Capabilities.ITEM_HANDLER) {
// if (side == Direction.UP) {
// return itemHandlers[0].cast();
// } else if (side == Direction.DOWN) {
// return itemHandlers[1].cast();
// } else {
// return itemHandlers[2].cast();
// }
// }
// return super.getCapability(cap, side);
// }
//
// @Override
// public void invalidateCaps() {
// super.invalidateCaps();
// for (LazyOptional<?> itemHandler : itemHandlers) itemHandler.invalidate();
// energyHandler.invalidate();
// }
//
// @Override
// public void reviveCaps() {
// super.reviveCaps();
// this.itemHandlers = SidedInvWrapper.create(this, Direction.UP, Direction.DOWN, Direction.NORTH);
// this.energyHandler = LazyOptional.of(() -> new EnergyStorage(MAX_ENERGY));
// }
} }

View file

@ -5,12 +5,17 @@ import com.atsuishio.superbwarfare.init.ModBlockEntities;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.capabilities.BlockCapabilityCache;
import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.energy.IEnergyStorage; import net.neoforged.neoforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
@ -21,17 +26,30 @@ public class CreativeChargingStationBlockEntity extends BlockEntity {
public static final int CHARGE_RADIUS = 8; public static final int CHARGE_RADIUS = 8;
private final IEnergyStorage energyHandler; private BlockCapabilityCache<IEnergyStorage, @Nullable Direction> capCache;
@Override
public void onLoad() {
super.onLoad();
if (level != null && !level.isClientSide) {
this.capCache = BlockCapabilityCache.create(
Capabilities.EnergyStorage.BLOCK,
(ServerLevel) level,
this.getBlockPos(),
null
);
}
}
public CreativeChargingStationBlockEntity(BlockPos pos, BlockState state) { public CreativeChargingStationBlockEntity(BlockPos pos, BlockState state) {
super(ModBlockEntities.CREATIVE_CHARGING_STATION.get(), pos, state); super(ModBlockEntities.CREATIVE_CHARGING_STATION.get(), pos, state);
this.energyHandler = new InfinityEnergyStorage();
} }
public static void serverTick(CreativeChargingStationBlockEntity blockEntity) { public static void serverTick(CreativeChargingStationBlockEntity blockEntity) {
if (blockEntity.level == null) return; if (blockEntity.level == null) return;
if (blockEntity.energyHandler != null) { if (blockEntity.capCache != null) {
blockEntity.chargeEntity(); blockEntity.chargeEntity();
blockEntity.chargeBlock(); blockEntity.chargeBlock();
} }
@ -72,4 +90,14 @@ public class CreativeChargingStationBlockEntity extends BlockEntity {
return ClientboundBlockEntityDataPacket.create(this); return ClientboundBlockEntityDataPacket.create(this);
} }
public static class EnergyStorageProvider implements ICapabilityProvider<CreativeChargingStationBlockEntity, Direction, IEnergyStorage> {
private final IEnergyStorage energy = new InfinityEnergyStorage();
@Override
public @Nullable IEnergyStorage getCapability(@NotNull CreativeChargingStationBlockEntity object, Direction context) {
if (object.isRemoved()) return null;
return energy;
}
}
} }

View file

@ -59,7 +59,7 @@ public class FuMO25BlockEntity extends BlockEntity implements MenuProvider, GeoB
protected final ContainerEnergyData dataAccess = new ContainerEnergyData() { protected final ContainerEnergyData dataAccess = new ContainerEnergyData() {
// TODO energy // TODO energy
@Override @Override
public long get(int pIndex) { public int get(int pIndex) {
return switch (pIndex) { return switch (pIndex) {
// case 0 -> FuMO25BlockEntity.this.energyHandler.map(EnergyStorage::getEnergyStored).orElse(0); // case 0 -> FuMO25BlockEntity.this.energyHandler.map(EnergyStorage::getEnergyStored).orElse(0);
case 1 -> FuMO25BlockEntity.this.type.ordinal(); case 1 -> FuMO25BlockEntity.this.type.ordinal();
@ -71,15 +71,15 @@ public class FuMO25BlockEntity extends BlockEntity implements MenuProvider, GeoB
} }
@Override @Override
public void set(int pIndex, long pValue) { public void set(int pIndex, int pValue) {
switch (pIndex) { switch (pIndex) {
case 0 -> { case 0 -> {
} }
// FuMO25BlockEntity.this.energyHandler.ifPresent(handler -> handler.receiveEnergy((int) pValue, false)); // FuMO25BlockEntity.this.energyHandler.ifPresent(handler -> handler.receiveEnergy((int) pValue, false));
case 1 -> FuMO25BlockEntity.this.type = FuncType.values()[(int) pValue]; case 1 -> FuMO25BlockEntity.this.type = FuncType.values()[(int) pValue];
case 2 -> FuMO25BlockEntity.this.time = (int) pValue; case 2 -> FuMO25BlockEntity.this.time = pValue;
case 3 -> FuMO25BlockEntity.this.powered = pValue == 1; case 3 -> FuMO25BlockEntity.this.powered = pValue == 1;
case 4 -> FuMO25BlockEntity.this.tick = (int) pValue; case 4 -> FuMO25BlockEntity.this.tick = pValue;
} }
} }

View file

@ -1,13 +1,51 @@
package com.atsuishio.superbwarfare.capability; package com.atsuishio.superbwarfare.capability;
import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity;
import com.atsuishio.superbwarfare.block.entity.CreativeChargingStationBlockEntity;
import com.atsuishio.superbwarfare.capability.energy.BlockEnergyStorageProvider;
import com.atsuishio.superbwarfare.capability.energy.ItemEnergyProvider;
import com.atsuishio.superbwarfare.capability.laser.LaserCapability; import com.atsuishio.superbwarfare.capability.laser.LaserCapability;
import com.atsuishio.superbwarfare.capability.laser.LaserCapabilityProvider;
import com.atsuishio.superbwarfare.capability.player.PlayerVariable; import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
import com.atsuishio.superbwarfare.capability.player.PlayerVariablesProvider;
import com.atsuishio.superbwarfare.init.ModBlockEntities;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.item.BatteryItem;
import com.atsuishio.superbwarfare.item.CreativeChargingStationBlockItem;
import net.minecraft.world.entity.EntityType;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.EntityCapability; import net.neoforged.neoforge.capabilities.EntityCapability;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD)
public class ModCapabilities { public class ModCapabilities {
public static final EntityCapability<LaserCapability, Void> LASER_CAPABILITY = EntityCapability.createVoid(ModUtils.loc("laser_capability"), LaserCapability.class); public static final EntityCapability<LaserCapability, Void> LASER_CAPABILITY = EntityCapability.createVoid(ModUtils.loc("laser_capability"), LaserCapability.class);
public static final EntityCapability<PlayerVariable, Void> PLAYER_VARIABLE = EntityCapability.createVoid(ModUtils.loc("player_variable"), PlayerVariable.class); public static final EntityCapability<PlayerVariable, Void> PLAYER_VARIABLE = EntityCapability.createVoid(ModUtils.loc("player_variable"), PlayerVariable.class);
@SubscribeEvent
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
event.registerEntity(ModCapabilities.LASER_CAPABILITY, EntityType.PLAYER, new LaserCapabilityProvider());
event.registerEntity(ModCapabilities.PLAYER_VARIABLE, EntityType.PLAYER, new PlayerVariablesProvider());
// 充电站
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.CHARGING_STATION.value(), new BlockEnergyStorageProvider<>(ChargingStationBlockEntity.MAX_ENERGY));
// TODO HANDLER
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, ModBlockEntities.CHARGING_STATION.value(), new ChargingStationBlockEntity.ItemHandlerProvider());
// 创造模式充电站
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModBlockEntities.CREATIVE_CHARGING_STATION.value(), new CreativeChargingStationBlockEntity.EnergyStorageProvider());
event.registerItem(Capabilities.EnergyStorage.ITEM, new CreativeChargingStationBlockItem.EnergyStorageProvider(), ModItems.CREATIVE_CHARGING_STATION.value());
// 电池
for (var item : ModItems.ITEMS.getEntries()) {
if (item.get() instanceof BatteryItem battery) {
event.registerItem(Capabilities.EnergyStorage.ITEM, new ItemEnergyProvider(battery.maxEnergy), battery);
}
}
}
} }

View file

@ -0,0 +1,24 @@
package com.atsuishio.superbwarfare.capability.energy;
import net.minecraft.core.Direction;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.energy.EnergyStorage;
import net.neoforged.neoforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
// TODO 共用实例问题
// TODO 序列化问题
public class BlockEnergyStorageProvider<T> implements ICapabilityProvider<T, Direction, IEnergyStorage> {
private final IEnergyStorage energy;
public BlockEnergyStorageProvider(int maxEnergy) {
this.energy = new EnergyStorage(maxEnergy);
}
@Override
public @Nullable IEnergyStorage getCapability(@NotNull T object, Direction context) {
return energy;
}
}

View file

@ -5,18 +5,17 @@ import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.energy.EnergyStorage; import net.neoforged.neoforge.energy.EnergyStorage;
import net.neoforged.neoforge.energy.IEnergyStorage; import net.neoforged.neoforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ItemEnergyProvider implements ICapabilityProvider<ItemStack, Void, IEnergyStorage> { public class ItemEnergyProvider implements ICapabilityProvider<ItemStack, Void, IEnergyStorage> {
private final ItemStack stack;
private final EnergyStorage energyStorage; private final EnergyStorage energyStorage;
public ItemEnergyProvider(ItemStack stack, int energyCapacity) { public ItemEnergyProvider(int energyCapacity) {
this.stack = stack;
this.energyStorage = new EnergyStorage(energyCapacity); this.energyStorage = new EnergyStorage(energyCapacity);
} }
@Override @Override
public @org.jetbrains.annotations.Nullable IEnergyStorage getCapability(@NotNull ItemStack object, Void context) { public @Nullable IEnergyStorage getCapability(@NotNull ItemStack object, Void context) {
return energyStorage; return energyStorage;
} }
} }

View file

@ -1,21 +1,14 @@
package com.atsuishio.superbwarfare.capability.laser; package com.atsuishio.superbwarfare.capability.laser;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.capability.ModCapabilities;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.capabilities.ICapabilityProvider; import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.common.util.INBTSerializable; import net.neoforged.neoforge.common.util.INBTSerializable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability; import org.jetbrains.annotations.UnknownNullability;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD)
public class LaserCapabilityProvider implements ICapabilityProvider<Player, Void, LaserCapability>, INBTSerializable<CompoundTag> { public class LaserCapabilityProvider implements ICapabilityProvider<Player, Void, LaserCapability>, INBTSerializable<CompoundTag> {
private final LaserCapability instance = new LaserCapability(); private final LaserCapability instance = new LaserCapability();
@ -34,9 +27,4 @@ public class LaserCapabilityProvider implements ICapabilityProvider<Player, Void
public void deserializeNBT(HolderLookup.@NotNull Provider provider, @NotNull CompoundTag nbt) { public void deserializeNBT(HolderLookup.@NotNull Provider provider, @NotNull CompoundTag nbt) {
instance.deserializeNBT(provider, nbt); instance.deserializeNBT(provider, nbt);
} }
@SubscribeEvent
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
event.registerEntity(ModCapabilities.LASER_CAPABILITY, EntityType.PLAYER, new LaserCapabilityProvider());
}
} }

View file

@ -1,21 +1,15 @@
package com.atsuishio.superbwarfare.capability.player; package com.atsuishio.superbwarfare.capability.player;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.capability.ModCapabilities;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.capabilities.ICapabilityProvider; import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.common.util.INBTSerializable; import net.neoforged.neoforge.common.util.INBTSerializable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability; import org.jetbrains.annotations.UnknownNullability;
@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD)
public class PlayerVariablesProvider implements ICapabilityProvider<Player, Void, PlayerVariable>, INBTSerializable<CompoundTag> { public class PlayerVariablesProvider implements ICapabilityProvider<Player, Void, PlayerVariable>, INBTSerializable<CompoundTag> {
private final PlayerVariable playerVariables = new PlayerVariable(); private final PlayerVariable playerVariables = new PlayerVariable();
@ -34,9 +28,4 @@ public class PlayerVariablesProvider implements ICapabilityProvider<Player, Void
playerVariables.readFromNBT(nbt); playerVariables.readFromNBT(nbt);
} }
@SubscribeEvent
public static void init(RegisterCapabilitiesEvent event) {
event.registerEntity(ModCapabilities.PLAYER_VARIABLE, EntityType.PLAYER, new PlayerVariablesProvider());
}
} }

View file

@ -0,0 +1,38 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.network.chat.Component;
public class ClientBocekImageTooltip extends ClientGunImageTooltip {
public ClientBocekImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
protected Component getDamageComponent() {
boolean slug = false;
// TODO perk
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug) {
// slug = true;
// }
//
// double total = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// if (slug) {
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(total) + (TooltipTool.heBullet(stack) ? " + " +
// FormatTool.format1D(0.8 * total * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : "")).withStyle(ChatFormatting.GREEN));
// } else {
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(total * 0.1, " * 10")).withStyle(ChatFormatting.GREEN))
// .append(Component.literal(" / ").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(total)).withStyle(ChatFormatting.GREEN));
// }
return Component.literal("");
}
}

View file

@ -0,0 +1,82 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.util.Mth;
import net.neoforged.neoforge.capabilities.Capabilities;
import org.jetbrains.annotations.NotNull;
public class ClientCellImageTooltip extends ClientGunImageTooltip {
public ClientCellImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
public void renderImage(@NotNull Font font, int x, int y, GuiGraphics guiGraphics) {
guiGraphics.pose().pushPose();
if (shouldRenderEnergyTooltip()) {
renderEnergyTooltip(font, guiGraphics, x, y);
}
guiGraphics.pose().popPose();
}
protected boolean shouldRenderEnergyTooltip() {
return stack.getCapability(Capabilities.EnergyStorage.ITEM) != null;
}
protected void renderEnergyTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getEnergyComponent(), x, y, 0xFFFFFF);
}
protected Component getEnergyComponent() {
var storage = stack.getCapability(Capabilities.EnergyStorage.ITEM);
assert storage != null;
int energy = storage.getEnergyStored();
int maxEnergy = storage.getMaxEnergyStored();
float percentage = Mth.clamp((float) energy / maxEnergy, 0, 1);
MutableComponent component = Component.literal("");
ChatFormatting format;
if (percentage <= .2f) {
format = ChatFormatting.RED;
} else if (percentage <= .6f) {
format = ChatFormatting.YELLOW;
} else {
format = ChatFormatting.GREEN;
}
int count = (int) (percentage * 50);
for (int i = 0; i < count; i++) {
component.append(Component.literal("|").withStyle(format));
}
component.append(Component.literal("").withStyle(ChatFormatting.RESET));
for (int i = 0; i < 50 - count; i++) {
component.append(Component.literal("|").withStyle(ChatFormatting.GRAY));
}
component.append(Component.literal(" " + energy + "/" + maxEnergy + " FE").withStyle(ChatFormatting.GRAY));
return component;
}
@Override
public int getHeight() {
int height = super.getHeight();
if (shouldRenderEnergyTooltip()) height -= 10;
return height;
}
@Override
public int getWidth(@NotNull Font font) {
int width = super.getWidth(font);
if (shouldRenderEnergyTooltip())
width = Math.max(width, font.width(getEnergyComponent().getVisualOrderText()) + 10);
return width;
}
}

View file

@ -0,0 +1,68 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import org.jetbrains.annotations.NotNull;
public class ClientChargingStationImageTooltip extends ClientGunImageTooltip {
public ClientChargingStationImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
public void renderImage(@NotNull Font font, int x, int y, GuiGraphics guiGraphics) {
guiGraphics.pose().pushPose();
renderEnergyTooltip(font, guiGraphics, x, y);
guiGraphics.pose().popPose();
}
protected void renderEnergyTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getEnergyComponent(), x, y, 0xFFFFFF);
}
protected Component getEnergyComponent() {
// TODO 电量渲染
// CompoundTag tag = BlockItem.getBlockEntityData(stack);
// int energy = tag == null ? 0 : tag.getInt("Energy");
// int maxEnergy = ChargingStationBlockItem.MAX_ENERGY;
// float percentage = Mth.clamp((float) energy / maxEnergy, 0, 1);
MutableComponent component = Component.literal("");
ChatFormatting format;
// if (percentage <= .2f) {
// format = ChatFormatting.RED;
// } else if (percentage <= .6f) {
// format = ChatFormatting.YELLOW;
// } else {
// format = ChatFormatting.GREEN;
// }
//
// int count = (int) (percentage * 50);
// for (int i = 0; i < count; i++) {
// component.append(Component.literal("|").withStyle(format));
// }
// component.append(Component.literal("").withStyle(ChatFormatting.RESET));
// for (int i = 0; i < 50 - count; i++) {
// component.append(Component.literal("|").withStyle(ChatFormatting.GRAY));
// }
//
// component.append(Component.literal(" " + energy + "/" + maxEnergy + " FE").withStyle(ChatFormatting.GRAY));
return component;
}
@Override
public int getHeight() {
return super.getHeight() - 10;
}
@Override
public int getWidth(@NotNull Font font) {
return Math.max(super.getWidth(font), font.width(getEnergyComponent().getVisualOrderText()) + 10);
}
}

View file

@ -0,0 +1,108 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.util.Mth;
import net.neoforged.neoforge.capabilities.Capabilities;
import org.jetbrains.annotations.NotNull;
public class ClientEnergyImageTooltip extends ClientGunImageTooltip {
public ClientEnergyImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
public void renderImage(@NotNull Font font, int x, int y, GuiGraphics guiGraphics) {
guiGraphics.pose().pushPose();
renderDamageAndRpmTooltip(font, guiGraphics, x, y);
renderLevelAndUpgradePointTooltip(font, guiGraphics, x, y + 10);
int yo = 20;
if (shouldRenderBypassAndHeadshotTooltip()) {
renderBypassAndHeadshotTooltip(font, guiGraphics, x, y + yo);
yo += 10;
}
if (shouldRenderEnergyTooltip()) {
yo += 10;
renderEnergyTooltip(font, guiGraphics, x, y + yo);
yo += 10;
}
if (shouldRenderEditTooltip()) {
renderWeaponEditTooltip(font, guiGraphics, x, y + yo);
yo += 20;
}
if (shouldRenderPerks()) {
if (!Screen.hasShiftDown()) {
renderPerksShortcut(font, guiGraphics, x, y + yo);
} else {
renderPerks(font, guiGraphics, x, y + yo);
}
}
guiGraphics.pose().popPose();
}
protected boolean shouldRenderEnergyTooltip() {
return stack.getCapability(Capabilities.EnergyStorage.ITEM) != null;
}
protected void renderEnergyTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getEnergyComponent(), x, y, 0xFFFFFF);
}
protected Component getEnergyComponent() {
var storage = stack.getCapability(Capabilities.EnergyStorage.ITEM);
assert storage != null;
int energy = storage.getEnergyStored();
int maxEnergy = storage.getMaxEnergyStored();
float percentage = Mth.clamp((float) energy / maxEnergy, 0, 1);
MutableComponent component = Component.literal("");
ChatFormatting format;
if (percentage <= .2f) {
format = ChatFormatting.RED;
} else if (percentage <= .6f) {
format = ChatFormatting.YELLOW;
} else {
format = ChatFormatting.GREEN;
}
int count = (int) (percentage * 50);
for (int i = 0; i < count; i++) {
component.append(Component.literal("|").withStyle(format));
}
component.append(Component.literal("").withStyle(ChatFormatting.RESET));
for (int i = 0; i < 50 - count; i++) {
component.append(Component.literal("|").withStyle(ChatFormatting.GRAY));
}
component.append(Component.literal(" " + energy + "/" + maxEnergy + " FE").withStyle(ChatFormatting.GRAY));
return component;
}
@Override
public int getHeight() {
int height = super.getHeight();
if (shouldRenderEnergyTooltip()) height += 20;
return height;
}
@Override
public int getWidth(@NotNull Font font) {
int width = super.getWidth(font);
if (shouldRenderEnergyTooltip())
width = Math.max(width, font.width(getEnergyComponent().getVisualOrderText()) + 10);
return width;
}
}

View file

@ -0,0 +1,435 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import com.atsuishio.superbwarfare.init.ModKeyMappings;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
// TODO perk相关信息渲染
public class ClientGunImageTooltip implements ClientTooltipComponent {
protected final int width;
protected final int height;
protected final ItemStack stack;
public ClientGunImageTooltip(GunImageComponent tooltip) {
this.width = tooltip.width;
this.height = tooltip.height;
this.stack = tooltip.stack;
}
@Override
public void renderImage(@NotNull Font font, int x, int y, GuiGraphics guiGraphics) {
guiGraphics.pose().pushPose();
renderDamageAndRpmTooltip(font, guiGraphics, x, y);
renderLevelAndUpgradePointTooltip(font, guiGraphics, x, y + 10);
int yo = 20;
if (shouldRenderBypassAndHeadshotTooltip()) {
renderBypassAndHeadshotTooltip(font, guiGraphics, x, y + yo);
yo += 10;
}
if (shouldRenderEditTooltip()) {
renderWeaponEditTooltip(font, guiGraphics, x, y + yo);
yo += 20;
}
if (shouldRenderPerks()) {
if (!Screen.hasShiftDown()) {
renderPerksShortcut(font, guiGraphics, x, y + yo);
} else {
renderPerks(font, guiGraphics, x, y + yo);
}
}
guiGraphics.pose().popPose();
}
protected boolean shouldRenderBypassAndHeadshotTooltip() {
// return GunsTool.getGunDoubleTag(stack, "BypassesArmor", 0) > 0 || GunsTool.getGunDoubleTag(stack, "Headshot", 0) > 0;
return false;
}
protected boolean shouldRenderEditTooltip() {
// if (this.stack.getItem() instanceof GunItem gunItem) {
// return gunItem.isCustomizable(stack);
// }
return false;
}
protected boolean shouldRenderPerks() {
// return PerkHelper.getPerkByType(stack, Perk.Type.AMMO) != null || PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE) != null || PerkHelper.getPerkByType(stack, Perk.Type.FUNCTIONAL) != null;
return false;
}
/**
* 渲染武器伤害和射速
*/
protected void renderDamageAndRpmTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getDamageComponent(), x, y, 0xFFFFFF);
int xo = font.width(getDamageComponent().getVisualOrderText());
guiGraphics.drawString(font, getRpmComponent(), x + xo + 16, y, 0xFFFFFF);
}
/**
* 获取武器伤害的文本组件
*/
protected Component getDamageComponent() {
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage) + (TooltipTool.heBullet(stack) ? " + "
// + FormatTool.format1D(0.8 * damage * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : "")).withStyle(ChatFormatting.GREEN));
return Component.literal("");
}
/**
* 获取武器射速的文本组件
*/
protected Component getRpmComponent() {
// if (this.stack.getItem() instanceof GunItem gunItem && gunItem.isAutoWeapon(this.stack)) {
// return Component.translatable("des.superbwarfare.guns.rpm").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format0D(GunsTool.getGunIntTag(stack, "RPM", 0)))
// .withStyle(ChatFormatting.GREEN));
// }
return Component.literal("");
}
/**
* 渲染武器等级和强化点数
*/
protected void renderLevelAndUpgradePointTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getLevelComponent(), x, y, 0xFFFFFF);
int xo = font.width(getLevelComponent().getVisualOrderText());
guiGraphics.drawString(font, getUpgradePointComponent(), x + xo + 16, y, 0xFFFFFF);
}
/**
* 获取武器等级文本组件
*/
protected Component getLevelComponent() {
// int level = GunsTool.getGunIntTag(stack, "Level", 0);
// double rate = GunsTool.getGunDoubleTag(stack, "Exp", 0) / (20 * Math.pow(level, 2) + 160 * level + 20);
ChatFormatting formatting;
// if (level < 10) {
// formatting = ChatFormatting.WHITE;
// } else if (level < 20) {
// formatting = ChatFormatting.AQUA;
// } else if (level < 30) {
// formatting = ChatFormatting.LIGHT_PURPLE;
// } else if (level < 40) {
// formatting = ChatFormatting.GOLD;
// } else {
// formatting = ChatFormatting.RED;
// }
// return Component.translatable("des.superbwarfare.guns.level").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(level + "").withStyle(formatting).withStyle(ChatFormatting.BOLD))
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" (" + FormatTool.DECIMAL_FORMAT_2ZZZ.format(rate * 100) + "%)").withStyle(ChatFormatting.GRAY));
return Component.literal("");
}
/**
* 获取武器强化点数文本组件
*/
protected Component getUpgradePointComponent() {
// int upgradePoint = Mth.floor(GunsTool.getGunDoubleTag(stack, "UpgradePoint", 0));
// return Component.translatable("des.superbwarfare.guns.upgrade_point").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(String.valueOf(upgradePoint)).withStyle(ChatFormatting.WHITE).withStyle(ChatFormatting.BOLD));
return Component.literal("");
}
/**
* 渲染武器穿甲比例和爆头倍率
*/
protected void renderBypassAndHeadshotTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getBypassComponent(), x, y, 0xFFFFFF);
int xo = font.width(getBypassComponent().getVisualOrderText());
guiGraphics.drawString(font, getHeadshotComponent(), x + xo + 16, y, 0xFFFFFF);
}
/**
* 获取武器穿甲比例文本组件
*/
protected Component getBypassComponent() {
double perkBypassArmorRate = 0;
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
//
// if (perk instanceof AmmoPerk ammoPerk) {
// int level = PerkHelper.getItemPerkLevel(perk, stack);
// perkBypassArmorRate = ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0);
// }
// double bypassRate = Math.max(GunsTool.getGunDoubleTag(stack, "BypassesArmor", 0) + perkBypassArmorRate, 0);
// return Component.translatable("des.superbwarfare.guns.bypass").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format2D(bypassRate * 100, "%")).withStyle(ChatFormatting.GOLD));
return Component.literal("");
}
/**
* 获取武器爆头倍率文本组件
*/
protected Component getHeadshotComponent() {
// double headshot = GunsTool.getGunDoubleTag(stack, "Headshot", 0);
// return Component.translatable("des.superbwarfare.guns.headshot").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(headshot, "x")).withStyle(ChatFormatting.AQUA));
return Component.literal("");
}
/**
* 渲染武器改装信息
*/
protected void renderWeaponEditTooltip(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.drawString(font, getEditComponent(), x, y + 10, 0xFFFFFF);
}
/**
* 获取武器改装信息文本组件
*/
protected Component getEditComponent() {
return Component.translatable("des.superbwarfare.guns.edit", "[" + ModKeyMappings.EDIT_MODE.getKey().getDisplayName().getString() + "]")
.withStyle(ChatFormatting.LIGHT_PURPLE).withStyle(ChatFormatting.ITALIC);
}
/**
* 渲染武器模组缩略图
*/
protected void renderPerksShortcut(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.pose().pushPose();
int xOffset = -20;
// Perk ammoPerk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (ammoPerk != null && PerkHelper.getPerkItem(ammoPerk).isPresent()) {
// xOffset += 20;
//
// var ammoItem = PerkHelper.getPerkItem(ammoPerk).get().get();
// ItemStack perkStack = ammoItem.getDefaultInstance();
//
// CompoundTag ammoTag = PerkHelper.getPerkTag(stack, Perk.Type.AMMO);
// if (!ammoTag.isEmpty()) {
// int level = PerkHelper.getItemPerkLevel(ammoPerk, stack);
// perkStack.setCount(level);
// }
// guiGraphics.renderItem(perkStack, x + xOffset, y + 2);
// guiGraphics.renderItemDecorations(font, perkStack, x + xOffset, y + 2);
// }
//
// Perk funcPerk = PerkHelper.getPerkByType(stack, Perk.Type.FUNCTIONAL);
// if (funcPerk != null && PerkHelper.getPerkItem(funcPerk).isPresent()) {
// xOffset += 20;
//
// var funcItem = PerkHelper.getPerkItem(funcPerk).get().get();
// ItemStack perkStack = funcItem.getDefaultInstance();
//
// CompoundTag funcTag = PerkHelper.getPerkTag(stack, Perk.Type.FUNCTIONAL);
// if (!funcTag.isEmpty()) {
// int level = PerkHelper.getItemPerkLevel(funcPerk, stack);
// perkStack.setCount(level);
// }
//
// guiGraphics.renderItem(perkStack, x + xOffset, y + 2);
// guiGraphics.renderItemDecorations(font, perkStack, x + xOffset, y + 2);
// }
//
// Perk damagePerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE);
// if (damagePerk != null && PerkHelper.getPerkItem(damagePerk).isPresent()) {
// xOffset += 20;
//
// var damageItem = PerkHelper.getPerkItem(damagePerk).get().get();
// ItemStack perkStack = damageItem.getDefaultInstance();
//
// CompoundTag damageTag = PerkHelper.getPerkTag(stack, Perk.Type.DAMAGE);
// if (!damageTag.isEmpty()) {
// int level = PerkHelper.getItemPerkLevel(damagePerk, stack);
// perkStack.setCount(level);
// }
//
// guiGraphics.renderItem(perkStack, x + xOffset, y + 2);
// guiGraphics.renderItemDecorations(font, perkStack, x + xOffset, y + 2);
// }
guiGraphics.pose().popPose();
}
/**
* 渲染武器模组详细信息
*/
protected void renderPerks(Font font, GuiGraphics guiGraphics, int x, int y) {
guiGraphics.pose().pushPose();
guiGraphics.drawString(font, Component.translatable("perk.superbwarfare.tips").withStyle(ChatFormatting.GOLD).withStyle(ChatFormatting.UNDERLINE), x, y + 10, 0xFFFFFF);
int yOffset = -5;
// Perk ammoPerk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (ammoPerk != null && PerkHelper.getPerkItem(ammoPerk).isPresent()) {
// yOffset += 25;
// var ammoItem = PerkHelper.getPerkItem(ammoPerk).get().get();
// guiGraphics.renderItem(ammoItem.getDefaultInstance(), x, y + 4 + yOffset);
//
// CompoundTag ammoTag = PerkHelper.getPerkTag(stack, Perk.Type.AMMO);
// if (!ammoTag.isEmpty()) {
// var ids = ammoTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var ammoComponent = Component.translatable("item.superbwarfare." + id).withStyle(ChatFormatting.YELLOW)
// .append(Component.literal(" ").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" Lvl. " + ammoTag.getInt("level")).withStyle(ChatFormatting.WHITE));
// var ammoDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
//
// guiGraphics.drawString(font, ammoComponent, x + 20, y + yOffset + 2, 0xFFFFFF);
// guiGraphics.drawString(font, ammoDesComponent, x + 20, y + yOffset + 12, 0xFFFFFF);
// }
// }
// }
//
// Perk funcPerk = PerkHelper.getPerkByType(stack, Perk.Type.FUNCTIONAL);
// if (funcPerk != null && PerkHelper.getPerkItem(funcPerk).isPresent()) {
// yOffset += 25;
// var funcItem = PerkHelper.getPerkItem(funcPerk).get().get();
// guiGraphics.renderItem(funcItem.getDefaultInstance(), x, y + 4 + yOffset);
//
// CompoundTag funcTag = PerkHelper.getPerkTag(stack, Perk.Type.FUNCTIONAL);
// if (!funcTag.isEmpty()) {
// var ids = funcTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var funcComponent = Component.translatable("item.superbwarfare." + id).withStyle(ChatFormatting.GREEN)
// .append(Component.literal(" ").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" Lvl. " + funcTag.getInt("level")).withStyle(ChatFormatting.WHITE));
// var funcDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
//
// guiGraphics.drawString(font, funcComponent, x + 20, y + yOffset + 2, 0xFFFFFF);
// guiGraphics.drawString(font, funcDesComponent, x + 20, y + yOffset + 12, 0xFFFFFF);
// }
// }
// }
//
// Perk damagePerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE);
// if (damagePerk != null && PerkHelper.getPerkItem(damagePerk).isPresent()) {
// yOffset += 25;
// var damageItem = PerkHelper.getPerkItem(damagePerk).get().get();
// guiGraphics.renderItem(damageItem.getDefaultInstance(), x, y + 4 + yOffset);
//
// CompoundTag damageTag = PerkHelper.getPerkTag(stack, Perk.Type.DAMAGE);
// if (!damageTag.isEmpty()) {
// var ids = damageTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var damageComponent = Component.translatable("item.superbwarfare." + id).withStyle(ChatFormatting.RED)
// .append(Component.literal(" ").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" Lvl. " + damageTag.getInt("level")).withStyle(ChatFormatting.WHITE));
// var damageDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
//
// guiGraphics.drawString(font, damageComponent, x + 20, y + yOffset + 2, 0xFFFFFF);
// guiGraphics.drawString(font, damageDesComponent, x + 20, y + yOffset + 12, 0xFFFFFF);
// }
// }
// }
guiGraphics.pose().popPose();
}
protected int getDefaultMaxWidth(Font font) {
int width = font.width(getDamageComponent().getVisualOrderText()) + font.width(getRpmComponent().getVisualOrderText()) + 16;
width = Math.max(width, font.width(getLevelComponent().getVisualOrderText()) + font.width(getUpgradePointComponent().getVisualOrderText()) + 16);
if (shouldRenderBypassAndHeadshotTooltip()) {
width = Math.max(width, font.width(getBypassComponent().getVisualOrderText()) + font.width(getHeadshotComponent().getVisualOrderText()) + 16);
}
if (shouldRenderEditTooltip()) {
width = Math.max(width, font.width(getEditComponent().getVisualOrderText()) + 16);
}
return width + 4;
}
protected int getMaxPerkDesWidth(Font font) {
if (!shouldRenderPerks()) return 0;
int width = 0;
// CompoundTag ammoTag = PerkHelper.getPerkTag(stack, Perk.Type.AMMO);
// if (!ammoTag.isEmpty()) {
// var ids = ammoTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var ammoDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
// width = Math.max(width, font.width(ammoDesComponent));
// }
// }
//
// CompoundTag funcTag = PerkHelper.getPerkTag(stack, Perk.Type.FUNCTIONAL);
// if (!funcTag.isEmpty()) {
// var ids = funcTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var funcDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
// width = Math.max(width, font.width(funcDesComponent));
// }
// }
//
// CompoundTag damageTag = PerkHelper.getPerkTag(stack, Perk.Type.DAMAGE);
// if (!damageTag.isEmpty()) {
// var ids = damageTag.getString("id").split(":");
// if (ids.length > 1) {
// String id = ids[1];
// var damageDesComponent = Component.translatable("des.superbwarfare." + id).withStyle(ChatFormatting.GRAY);
// width = Math.max(width, font.width(damageDesComponent));
// }
// }
return width + 25;
}
@Override
public int getHeight() {
int height = Math.max(20, this.height);
if (shouldRenderBypassAndHeadshotTooltip()) height += 10;
if (shouldRenderEditTooltip()) height += 20;
if (shouldRenderPerks()) {
if (!Screen.hasShiftDown()) {
height += 16;
} else {
height += 16;
// if (PerkHelper.getPerkByType(stack, Perk.Type.AMMO) != null) {
// height += 25;
// }
// if (PerkHelper.getPerkByType(stack, Perk.Type.FUNCTIONAL) != null) {
// height += 25;
// }
// if (PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE) != null) {
// height += 25;
// }
}
}
return height;
}
@Override
public int getWidth(@NotNull Font font) {
if (Screen.hasShiftDown()) {
int width = getMaxPerkDesWidth(font);
return width == 0 ? Math.max(this.width, getDefaultMaxWidth(font)) : Math.max(width, getDefaultMaxWidth(font));
} else {
return getDefaultMaxWidth(font);
}
}
}

View file

@ -0,0 +1,28 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.network.chat.Component;
public class ClientLauncherImageTooltip extends ClientGunImageTooltip {
public ClientLauncherImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
protected Component getDamageComponent() {
// TODO GunInfo
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack);
// if (perkLevel > 0) damage *= 1.1f + perkLevel * 0.1f;
//
// double explosionDamage = GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage)).withStyle(ChatFormatting.GREEN)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" + " + FormatTool.format1D(explosionDamage)).withStyle(ChatFormatting.GOLD)));
return Component.literal("");
}
}

View file

@ -0,0 +1,28 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.network.chat.Component;
public class ClientSecondaryCataclysmImageTooltip extends ClientEnergyImageTooltip {
public ClientSecondaryCataclysmImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
protected Component getDamageComponent() {
// TODO GunInfo
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// int perkLevel = PerkHelper.getItemPerkLevel(ModPerks.MICRO_MISSILE.get(), stack);
// if (perkLevel > 0) damage *= 1.1f + perkLevel * 0.1f;
//
// double explosionDamage = GunsTool.getGunDoubleTag(stack, "ExplosionDamage", 0);
//
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage)).withStyle(ChatFormatting.GREEN)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(" + " + FormatTool.format1D(explosionDamage)).withStyle(ChatFormatting.GOLD)));
return Component.literal("");
}
}

View file

@ -0,0 +1,37 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.network.chat.Component;
import net.neoforged.neoforge.capabilities.Capabilities;
public class ClientSentinelImageTooltip extends ClientEnergyImageTooltip {
public ClientSentinelImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
protected Component getDamageComponent() {
var cap = stack.getCapability(Capabilities.EnergyStorage.ITEM);
// TODO GunInfo
if (cap != null && cap.getEnergyStored() > 0) {
// double damage = (GunsTool.getGunDoubleTag(stack, "Damage", 0) +
// GunsTool.getGunDoubleTag(stack, "ChargedDamage", 0))
// * TooltipTool.perkDamage(stack);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage) + (TooltipTool.heBullet(stack) ? " + " +
// FormatTool.format1D(0.8 * damage * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : ""))
// .withStyle(ChatFormatting.AQUA).withStyle(ChatFormatting.BOLD));
} else {
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage) + (TooltipTool.heBullet(stack) ?
// FormatTool.format1D(0.4 * damage * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : "")).withStyle(ChatFormatting.GREEN));
}
return Component.literal("");
}
}

View file

@ -0,0 +1,37 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import net.minecraft.network.chat.Component;
public class ClientShotgunImageTooltip extends ClientGunImageTooltip {
public ClientShotgunImageTooltip(GunImageComponent tooltip) {
super(tooltip);
}
@Override
protected Component getDamageComponent() {
boolean slug = false;
// TODO perk
// var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO);
// if (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug) {
// slug = true;
// }
//
// if (slug) {
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * GunsTool.getGunIntTag(stack, "ProjectileAmount", 1) * TooltipTool.perkDamage(stack);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage) + (TooltipTool.heBullet(stack) ? " + " +
// FormatTool.format1D(0.8 * damage * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : "")).withStyle(ChatFormatting.GREEN));
// } else {
// double damage = GunsTool.getGunDoubleTag(stack, "Damage", 0) * TooltipTool.perkDamage(stack);
// return Component.translatable("des.superbwarfare.guns.damage").withStyle(ChatFormatting.GRAY)
// .append(Component.literal("").withStyle(ChatFormatting.RESET))
// .append(Component.literal(FormatTool.format1D(damage) + " * " + FormatTool.format0D(GunsTool.getGunIntTag(stack, "ProjectileAmount", 1))).withStyle(ChatFormatting.GREEN));
// }
return Component.literal("");
}
}

View file

@ -0,0 +1,33 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.tooltip.component.*;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class TooltipRegistry {
@SubscribeEvent
public static void registerTooltip(RegisterClientTooltipComponentFactoriesEvent event) {
event.register(GunImageComponent.class, ClientGunImageTooltip::new);
event.register(ShotgunImageComponent.class, ClientShotgunImageTooltip::new);
event.register(BocekImageComponent.class, ClientBocekImageTooltip::new);
event.register(EnergyImageComponent.class, ClientEnergyImageTooltip::new);
event.register(CellImageComponent.class, ClientCellImageTooltip::new);
event.register(SentinelImageComponent.class, ClientSentinelImageTooltip::new);
event.register(LauncherImageComponent.class, ClientLauncherImageTooltip::new);
event.register(SecondaryCataclysmImageComponent.class, ClientSecondaryCataclysmImageTooltip::new);
event.register(ChargingStationImageComponent.class, ClientChargingStationImageTooltip::new);
}
@SubscribeEvent
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
// TODO block entity renderer
// event.registerBlockEntityRenderer(ModBlockEntities.CONTAINER.get(), context -> new ContainerBlockEntityRenderer());
// event.registerBlockEntityRenderer(ModBlockEntities.FUMO_25.get(), context -> new FuMO25BlockEntityRenderer());
// event.registerBlockEntityRenderer(ModBlockEntities.CHARGING_STATION.get(), context -> new ChargingStationBlockEntityRenderer());
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class BocekImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public BocekImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public BocekImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class CellImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public CellImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public CellImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,18 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class ChargingStationImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public ChargingStationImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public ChargingStationImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class EnergyImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public EnergyImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public EnergyImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,22 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
public class GunImageComponent implements TooltipComponent {
public int width;
public int height;
public ItemStack stack;
public GunImageComponent(int width, int height, ItemStack stack) {
this.width = width;
this.height = height;
this.stack = stack;
}
public GunImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class LauncherImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public LauncherImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public LauncherImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class SecondaryCataclysmImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public SecondaryCataclysmImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public SecondaryCataclysmImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class SentinelImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public SentinelImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public SentinelImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.item.ItemStack;
public class ShotgunImageComponent extends GunImageComponent {
public int width;
public int height;
public ItemStack stack;
public ShotgunImageComponent(int width, int height, ItemStack stack) {
super(width, height, stack);
}
public ShotgunImageComponent(ItemStack stack) {
this(32, 16, stack);
}
}

View file

@ -155,11 +155,11 @@ public class ModItems {
public static final DeferredHolder<Item, Item> SCHEELITE = ITEMS.register("scheelite", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> SCHEELITE = ITEMS.register("scheelite", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, Item> RAW_SILVER = ITEMS.register("raw_silver", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> RAW_SILVER = ITEMS.register("raw_silver", () -> new Item(new Item.Properties()));
// public static final DeferredHolder<Item, Item> DOG_TAG = ITEMS.register("dog_tag", DogTag::new); // public static final DeferredHolder<Item, Item> DOG_TAG = ITEMS.register("dog_tag", DogTag::new);
// public static final DeferredHolder<Item, Item> CELL = ITEMS.register("cell", () -> new BatteryItem(24000, new Item.Properties())); public static final DeferredHolder<Item, Item> CELL = ITEMS.register("cell", () -> new BatteryItem(24000, new Item.Properties()));
// public static final DeferredHolder<Item, Item> BATTERY = ITEMS.register("battery", () -> new BatteryItem(100000, new Item.Properties())); public static final DeferredHolder<Item, Item> BATTERY = ITEMS.register("battery", () -> new BatteryItem(100000, new Item.Properties()));
// public static final DeferredHolder<Item, Item> SMALL_BATTERY_PACK = ITEMS.register("small_battery_pack", () -> new BatteryItem(500000, new Item.Properties())); public static final DeferredHolder<Item, Item> SMALL_BATTERY_PACK = ITEMS.register("small_battery_pack", () -> new BatteryItem(500000, new Item.Properties()));
// public static final DeferredHolder<Item, Item> MEDIUM_BATTERY_PACK = ITEMS.register("medium_battery_pack", () -> new BatteryItem(5000000, new Item.Properties())); public static final DeferredHolder<Item, Item> MEDIUM_BATTERY_PACK = ITEMS.register("medium_battery_pack", () -> new BatteryItem(5000000, new Item.Properties()));
// public static final DeferredHolder<Item, Item> LARGE_BATTERY_PACK = ITEMS.register("large_battery_pack", () -> new BatteryItem(20000000, new Item.Properties())); public static final DeferredHolder<Item, Item> LARGE_BATTERY_PACK = ITEMS.register("large_battery_pack", () -> new BatteryItem(20000000, new Item.Properties()));
// public static final DeferredHolder<Item, Item> TRANSCRIPT = ITEMS.register("transcript", Transcript::new); // public static final DeferredHolder<Item, Item> TRANSCRIPT = ITEMS.register("transcript", Transcript::new);
public static final DeferredHolder<Item, FiringParameters> FIRING_PARAMETERS = ITEMS.register("firing_parameters", FiringParameters::new); public static final DeferredHolder<Item, FiringParameters> FIRING_PARAMETERS = ITEMS.register("firing_parameters", FiringParameters::new);
@ -245,7 +245,7 @@ public class ModItems {
public static final DeferredHolder<Item, Item> DRAGON_TEETH = block(ModBlocks.DRAGON_TEETH); public static final DeferredHolder<Item, Item> DRAGON_TEETH = block(ModBlocks.DRAGON_TEETH);
public static final DeferredHolder<Item, Item> REFORGING_TABLE = block(ModBlocks.REFORGING_TABLE); public static final DeferredHolder<Item, Item> REFORGING_TABLE = block(ModBlocks.REFORGING_TABLE);
public static final DeferredHolder<Item, Item> CHARGING_STATION = block(ModBlocks.CHARGING_STATION); public static final DeferredHolder<Item, Item> CHARGING_STATION = block(ModBlocks.CHARGING_STATION);
public static final DeferredHolder<Item, Item> CREATIVE_CHARGING_STATION = BLOCKS.register("creative_charging_station", CreativeChargingStationBlockItem::new); public static final DeferredHolder<Item, CreativeChargingStationBlockItem> CREATIVE_CHARGING_STATION = BLOCKS.register("creative_charging_station", CreativeChargingStationBlockItem::new);
public static final DeferredHolder<Item, Item> LEAD_BLOCK = block(ModBlocks.LEAD_BLOCK); public static final DeferredHolder<Item, Item> LEAD_BLOCK = block(ModBlocks.LEAD_BLOCK);
public static final DeferredHolder<Item, Item> STEEL_BLOCK = block(ModBlocks.STEEL_BLOCK); public static final DeferredHolder<Item, Item> STEEL_BLOCK = block(ModBlocks.STEEL_BLOCK);
public static final DeferredHolder<Item, Item> TUNGSTEN_BLOCK = block(ModBlocks.TUNGSTEN_BLOCK); public static final DeferredHolder<Item, Item> TUNGSTEN_BLOCK = block(ModBlocks.TUNGSTEN_BLOCK);

View file

@ -1,6 +1,7 @@
package com.atsuishio.superbwarfare.init; package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.item.BatteryItem;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
@ -93,7 +94,21 @@ public class ModTabs {
() -> CreativeModeTab.builder() () -> CreativeModeTab.builder()
.title(Component.translatable("item_group.superbwarfare.item")) .title(Component.translatable("item_group.superbwarfare.item"))
.icon(() -> new ItemStack(ModItems.FIRING_PARAMETERS.get())) .icon(() -> new ItemStack(ModItems.FIRING_PARAMETERS.get()))
.displayItems((param, output) -> ModItems.ITEMS.getEntries().forEach(registryObject -> output.accept(registryObject.get()))) .displayItems((param, output) -> ModItems.ITEMS.getEntries().forEach(registryObject -> {
// TODO container, armor plate
// if (registryObject.get() == ModItems.CONTAINER.get()) {
if (false) {
// CONTAINER_ENTITIES.stream().map(Supplier::get).forEach(output::accept);
} else {
output.accept(registryObject.get());
// if (registryObject.get() == ModItems.ARMOR_PLATE.get()) {
// output.accept(ArmorPlate.getInfiniteInstance());
// }
if (registryObject.get() instanceof BatteryItem batteryItem) {
output.accept(batteryItem.makeFullEnergyStack());
}
}
}))
.build()); .build());
public static final DeferredHolder<CreativeModeTab, CreativeModeTab> BLOCK_TAB = TABS.register("block", public static final DeferredHolder<CreativeModeTab, CreativeModeTab> BLOCK_TAB = TABS.register("block",

View file

@ -0,0 +1,58 @@
package com.atsuishio.superbwarfare.item;
import com.atsuishio.superbwarfare.client.tooltip.component.CellImageComponent;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.capabilities.Capabilities;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public class BatteryItem extends Item {
public int maxEnergy;
public BatteryItem(int maxEnergy, Properties properties) {
super(properties.stacksTo(1));
this.maxEnergy = maxEnergy;
}
@Override
public boolean isBarVisible(ItemStack pStack) {
var cap = pStack.getCapability(Capabilities.EnergyStorage.ITEM);
if (cap == null) return false;
return cap.getEnergyStored() != cap.getMaxEnergyStored();
}
@Override
public int getBarWidth(ItemStack pStack) {
var energy = 0;
var cap = pStack.getCapability(Capabilities.EnergyStorage.ITEM);
if (cap != null) {
energy = cap.getEnergyStored();
}
return Math.round((float) energy * 13.0F / maxEnergy);
}
@Override
public int getBarColor(@NotNull ItemStack pStack) {
return 0xFFFF00;
}
@Override
public @NotNull Optional<TooltipComponent> getTooltipImage(@NotNull ItemStack pStack) {
return Optional.of(new CellImageComponent(pStack));
}
public ItemStack makeFullEnergyStack() {
ItemStack stack = new ItemStack(this);
var cap = stack.getCapability(Capabilities.EnergyStorage.ITEM);
if (cap == null) return stack;
cap.receiveEnergy(maxEnergy, false);
return stack;
}
}

View file

@ -1,8 +1,15 @@
package com.atsuishio.superbwarfare.item; package com.atsuishio.superbwarfare.item;
import com.atsuishio.superbwarfare.capability.energy.InfinityEnergyStorage;
import com.atsuishio.superbwarfare.init.ModBlocks; import com.atsuishio.superbwarfare.init.ModBlocks;
import com.atsuishio.superbwarfare.init.ModItems;
import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Rarity; import net.minecraft.world.item.Rarity;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CreativeChargingStationBlockItem extends BlockItem { public class CreativeChargingStationBlockItem extends BlockItem {
@ -10,14 +17,15 @@ public class CreativeChargingStationBlockItem extends BlockItem {
super(ModBlocks.CREATIVE_CHARGING_STATION.get(), new Properties().rarity(Rarity.EPIC).stacksTo(1)); super(ModBlocks.CREATIVE_CHARGING_STATION.get(), new Properties().rarity(Rarity.EPIC).stacksTo(1));
} }
// TODO capability public static class EnergyStorageProvider implements ICapabilityProvider<ItemStack, Void, IEnergyStorage> {
// @Override
// public ICapabilityProvider initCapabilities(ItemStack stack, CompoundTag tag) { private final IEnergyStorage energy = new InfinityEnergyStorage();
// return new ICapabilityProvider() {
// @Override @Override
// public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) { public @Nullable IEnergyStorage getCapability(@NotNull ItemStack object, Void context) {
// return ForgeCapabilities.ENERGY.orEmpty(cap, LazyOptional.of(InfinityEnergyStorage::new)); if (object.getItem() != ModItems.CREATIVE_CHARGING_STATION.get()) return null;
// } return energy;
// }; }
// } }
} }

View file

@ -39,6 +39,7 @@ public class ChargingStationMenu extends EnergyMenu {
this.addSlot(new Slot(container, 0, 44, 54)); this.addSlot(new Slot(container, 0, 44, 54));
this.addSlot(new ChargingSlot(container, 1, 116, 54)); this.addSlot(new ChargingSlot(container, 1, 116, 54));
this.addDataSlots(containerData);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) { for (int j = 0; j < 9; ++j) {

View file

@ -48,12 +48,10 @@ public abstract class EnergyMenu extends AbstractContainerMenu {
} }
public void setData(int id, int data) { public void setData(int id, int data) {
super.setData(id, data);
this.containerEnergyDataSlots.get(id).set(data); this.containerEnergyDataSlots.get(id).set(data);
} }
public void setData(int id, long data) {
this.containerEnergyDataSlots.get(id).set(data);
}
// @SubscribeEvent // @SubscribeEvent
// public static void onContainerOpened(PlayerContainerEvent.Open event) { // public static void onContainerOpened(PlayerContainerEvent.Open event) {

View file

@ -1,10 +1,12 @@
package com.atsuishio.superbwarfare.network.dataslot; package com.atsuishio.superbwarfare.network.dataslot;
public interface ContainerEnergyData { import net.minecraft.world.inventory.ContainerData;
long get(int pIndex); public interface ContainerEnergyData extends ContainerData {
void set(int pIndex, long pValue); int get(int pIndex);
void set(int pIndex, int pValue);
int getCount(); int getCount();
} }

View file

@ -5,29 +5,31 @@ package com.atsuishio.superbwarfare.network.dataslot;
*/ */
public abstract class ContainerEnergyDataSlot { public abstract class ContainerEnergyDataSlot {
private long prevValue; private int prevValue;
public ContainerEnergyDataSlot() { public ContainerEnergyDataSlot() {
} }
public static ContainerEnergyDataSlot forContainer(final ContainerEnergyData data, final int index) { public static ContainerEnergyDataSlot forContainer(final ContainerEnergyData data, final int index) {
return new ContainerEnergyDataSlot() { return new ContainerEnergyDataSlot() {
public long get() { public int get() {
return data.get(index); return data.get(index);
} }
public void set(long value) { @Override
public void set(int value) {
data.set(index, value); data.set(index, value);
} }
}; };
} }
public abstract long get(); public abstract int get();
public abstract void set(long value); public abstract void set(int value);
public boolean checkAndClearUpdateFlag() { public boolean checkAndClearUpdateFlag() {
long tmp = this.get(); int tmp = this.get();
boolean changed = tmp != this.prevValue; boolean changed = tmp != this.prevValue;
this.prevValue = tmp; this.prevValue = tmp;
return changed; return changed;

View file

@ -5,19 +5,19 @@ package com.atsuishio.superbwarfare.network.dataslot;
*/ */
public class SimpleEnergyData implements ContainerEnergyData { public class SimpleEnergyData implements ContainerEnergyData {
private final long[] data; private final int[] data;
public SimpleEnergyData(int size) { public SimpleEnergyData(int size) {
this.data = new long[size]; this.data = new int[size];
} }
@Override @Override
public long get(int index) { public int get(int index) {
return this.data[index]; return this.data[index];
} }
@Override @Override
public void set(int index, long value) { public void set(int index, int value) {
this.data[index] = value; this.data[index] = value;
} }