Skip to content

Commit d8e9e55

Browse files
committed
prevent equip two smart glasses
fix overlay presist when swapping try another auto update solution
1 parent a06ac25 commit d8e9e55

10 files changed

Lines changed: 176 additions & 73 deletions

File tree

src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,31 @@
66
import de.srendi.advancedperipherals.common.addons.computercraft.integrations.IntegrationPeripheralProvider;
77
import de.srendi.advancedperipherals.common.addons.refinedstorage.RSApi;
88
import de.srendi.advancedperipherals.common.configuration.APConfig;
9+
import de.srendi.advancedperipherals.common.items.SmartGlassesItem;
910
import de.srendi.advancedperipherals.common.setup.APRegistration;
1011
import de.srendi.advancedperipherals.common.util.ChunkManager;
1112
import net.minecraft.resources.ResourceLocation;
13+
import net.minecraft.server.level.ServerLevel;
14+
import net.minecraft.world.item.ItemStack;
1215
import net.neoforged.bus.api.IEventBus;
16+
import net.neoforged.bus.api.SubscribeEvent;
1317
import net.neoforged.fml.ModLoadingContext;
18+
import net.neoforged.fml.common.EventBusSubscriber;
1419
import net.neoforged.fml.common.Mod;
1520
import net.neoforged.fml.event.lifecycle.FMLLoadCompleteEvent;
1621
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
22+
import net.neoforged.neoforge.event.entity.living.LivingEquipmentChangeEvent;
1723
import org.apache.logging.log4j.Level;
1824
import org.apache.logging.log4j.LogManager;
1925
import org.apache.logging.log4j.Logger;
2026
import org.jetbrains.annotations.Nullable;
27+
2128
import java.security.MessageDigest;
2229
import java.security.NoSuchAlgorithmException;
2330
import java.util.Random;
2431

2532
@Mod(AdvancedPeripherals.MOD_ID)
33+
@EventBusSubscriber
2634
public class AdvancedPeripherals {
2735

2836
public static final String MOD_ID = "advancedperipherals";
@@ -107,4 +115,12 @@ public void registerCapabilities(RegisterCapabilitiesEvent event) {
107115

108116
IntegrationPeripheralProvider.registerBlockIntegrations(event);
109117
}
118+
119+
@SubscribeEvent
120+
public static void onEquipmentChange(LivingEquipmentChangeEvent event) {
121+
ItemStack stack = event.getFrom();
122+
if (stack.getItem() instanceof SmartGlassesItem glassesItem) {
123+
glassesItem.onUnequip(stack, (ServerLevel) event.getEntity().level(), event.getEntity());
124+
}
125+
}
110126
}

src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/luaapi/APLuaAPI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import java.util.Map;
2020
import java.util.Optional;
2121

22-
public class APLuaAPI implements ILuaAPI {
22+
public final class APLuaAPI implements ILuaAPI {
2323
public static final APLuaAPI INSTANCE = new APLuaAPI();
2424

2525
private static final String NAME = AdvancedPeripherals.MOD_ID;

src/main/java/de/srendi/advancedperipherals/common/addons/curios/SmartGlassesCurio.java

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package de.srendi.advancedperipherals.common.addons.curios;
22

33
import de.srendi.advancedperipherals.common.items.SmartGlassesItem;
4+
import net.minecraft.server.level.ServerLevel;
45
import net.minecraft.world.entity.EquipmentSlot;
56
import net.minecraft.world.entity.LivingEntity;
67
import net.minecraft.world.entity.player.Player;
78
import net.minecraft.world.item.ItemStack;
9+
import top.theillusivec4.curios.api.CuriosApi;
810
import top.theillusivec4.curios.api.SlotContext;
11+
import top.theillusivec4.curios.api.SlotResult;
912
import top.theillusivec4.curios.api.type.capability.ICurio;
13+
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
1014

1115
public class SmartGlassesCurio implements ICurio {
1216
private final SmartGlassesItem item;
@@ -24,17 +28,71 @@ public ItemStack getStack() {
2428

2529
@Override
2630
public boolean canEquipFromUse(SlotContext context) {
27-
if (context.entity() instanceof Player player && player.isSecondaryUseActive()) {
28-
// open glasses directly
31+
final LivingEntity owner = context.entity();
32+
if (owner instanceof Player player && player.isSecondaryUseActive()) {
33+
// open glasses interface
2934
return false;
3035
}
31-
if (context.entity().getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
36+
if (owner.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
37+
if (isSmartGlasses(context)) {
38+
// allow swap
39+
return true;
40+
}
3241
// try equip glasses to equipment slot first
3342
return false;
3443
}
3544
return true;
3645
}
3746

47+
@Override
48+
public boolean canEquip(SlotContext context) {
49+
if (context.cosmetic()) {
50+
return true;
51+
}
52+
53+
final LivingEntity owner = context.entity();
54+
if (owner.getItemBySlot(EquipmentSlot.HEAD).getItem() instanceof SmartGlassesItem) {
55+
return false;
56+
}
57+
final ICuriosItemHandler curiosInv = CuriosApi.getCuriosInventory(owner).orElse(null);
58+
if (curiosInv == null) {
59+
return false;
60+
}
61+
final SlotResult otherSlot = curiosInv.findFirstCurio((stack) -> stack.getItem() instanceof SmartGlassesItem).orElse(null);
62+
if (otherSlot != null) {
63+
final SlotContext otherContext = otherSlot.slotContext();
64+
// allow swap
65+
if (otherContext.index() != context.index() || !otherContext.identifier().equals(context.identifier())) {
66+
return false;
67+
}
68+
}
69+
return true;
70+
}
71+
72+
private static boolean isSmartGlasses(SlotContext context) {
73+
final LivingEntity owner = context.entity();
74+
if (owner.getItemBySlot(EquipmentSlot.HEAD).getItem() instanceof SmartGlassesItem) {
75+
return false;
76+
}
77+
final ICuriosItemHandler curiosInv = CuriosApi.getCuriosInventory(owner).orElse(null);
78+
if (curiosInv == null) {
79+
return false;
80+
}
81+
final SlotResult slot = curiosInv.findCurio(context.identifier(), context.index()).orElse(null);
82+
if (slot == null) {
83+
return false;
84+
}
85+
return slot.stack().getItem() instanceof SmartGlassesItem;
86+
}
87+
88+
@Override
89+
public void onUnequip(SlotContext context, ItemStack newStack) {
90+
final LivingEntity owner = context.entity();
91+
if (owner.level() instanceof ServerLevel serverLevel) {
92+
this.item.onUnequip(this.stack, serverLevel, owner);
93+
}
94+
}
95+
3896
@Override
3997
public void curioTick(SlotContext context) {
4098
final LivingEntity owner = context.entity();

src/main/java/de/srendi/advancedperipherals/common/items/SmartGlassesItem.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ public Object createCurioCap(ItemStack stack) {
7373
return new SmartGlassesCurio(this, stack);
7474
}
7575

76+
@Override
77+
public boolean canEquip(ItemStack stack, EquipmentSlot armorType, LivingEntity entity) {
78+
if (!super.canEquip(stack, armorType, entity)) {
79+
return false;
80+
}
81+
if (!getEquippedCurios(entity).isEmpty()) {
82+
return false;
83+
}
84+
return true;
85+
}
86+
87+
@Override
88+
public InteractionResultHolder<ItemStack> swapWithEquipmentSlot(Item item, Level level, Player player, InteractionHand hand) {
89+
ItemStack stack = player.getItemInHand(hand);
90+
if (!item.canEquip(stack, EquipmentSlot.HEAD, player)) {
91+
return InteractionResultHolder.pass(stack);
92+
}
93+
return super.swapWithEquipmentSlot(item, level, player, hand);
94+
}
95+
7696
private boolean postInventoryTick(ItemStack stack, ServerLevel level, Entity entity, SmartGlassesComputer computer) {
7797
computer.setPosition(level, entity != null ? entity.blockPosition() : computer.getPosition());
7898

@@ -168,6 +188,21 @@ public void onEquippedTick(ItemStack stack, Level level, LivingEntity entity, bo
168188
}
169189
}
170190

191+
public void onUnequip(ItemStack stack, ServerLevel level, LivingEntity entity) {
192+
SmartGlassesComputer computer = getServerComputer(level.getServer(), stack);
193+
if (computer == null) {
194+
return;
195+
}
196+
197+
SmartGlassesSideAccess smartGlassesModuleAccess = computer.getSmartGlassesModuleAccess();
198+
for (int i = 0; i < SmartGlassesSlot.MODULE_SLOTS; i++) {
199+
IModule module = computer.getModuleBySlot(i);
200+
if (module != null) {
201+
module.onUnequipped(smartGlassesModuleAccess);
202+
}
203+
}
204+
}
205+
171206
@Override
172207
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
173208
if (!(entity.level() instanceof ServerLevel serverLevel)) {

src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import de.srendi.advancedperipherals.AdvancedPeripherals;
44
import de.srendi.advancedperipherals.common.network.toclient.KeyboardMouseCapturePacket;
5-
import de.srendi.advancedperipherals.common.network.toclient.OverlayModuleClientRequestPacket;
65
import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectAddPacket;
76
import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectBulkAddPacket;
87
import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectBulkSyncPacket;
@@ -33,7 +32,6 @@ public class APNetworking {
3332

3433
private static void init(PayloadRegistrar registrar) {
3534
registrar.playToClient(KeyboardMouseCapturePacket.TYPE, makeReader(KeyboardMouseCapturePacket::new), KeyboardMouseCapturePacket::handle);
36-
registrar.playToClient(OverlayModuleClientRequestPacket.TYPE, makeReader(OverlayModuleClientRequestPacket::new), OverlayModuleClientRequestPacket::handle);
3735
registrar.playToClient(RenderableObjectAddPacket.TYPE, makeReader(RenderableObjectAddPacket::new), RenderableObjectAddPacket::handle);
3836
registrar.playToClient(RenderableObjectBulkAddPacket.TYPE, makeReader(RenderableObjectBulkAddPacket::new), RenderableObjectBulkAddPacket::handle);
3937
registrar.playToClient(RenderableObjectBulkSyncPacket.TYPE, makeReader(RenderableObjectBulkSyncPacket::new), RenderableObjectBulkSyncPacket::handle);

src/main/java/de/srendi/advancedperipherals/common/network/toclient/OverlayModuleClientRequestPacket.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesAPI.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import java.util.function.BooleanSupplier;
99

10-
public class SmartGlassesAPI implements ILuaAPI {
10+
public final class SmartGlassesAPI implements ILuaAPI {
1111
private final BooleanSupplier equipped;
1212

1313
private SmartGlassesAPI(BooleanSupplier equipped) {
@@ -34,7 +34,7 @@ public String[] getNames() {
3434
* @return if the smart glasses is equipped
3535
*/
3636
@LuaFunction(mainThread = true)
37-
public boolean isEquipped() {
37+
public final boolean isEquipped() {
3838
return this.equipped.getAsBoolean();
3939
}
4040
}

src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesComputer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ public void setModuleStack(int slot, ItemStack stack) {
228228
this.moduleItems.set(slot, stack);
229229
this.modulesUpdated = true;
230230

231+
boolean isEquipped = this.isEquipped();
232+
231233
SmartGlassesSideAccess smartGlassesModuleAccess = this.getSmartGlassesModuleAccess();
232234
IModule oldModule = this.modules[slot];
233235
if (stack.getItem() instanceof IModuleItem moduleItem) {
@@ -236,11 +238,15 @@ public void setModuleStack(int slot, ItemStack stack) {
236238
if (oldModule.getId().equals(newModule.getId())) {
237239
return;
238240
}
239-
oldModule.onUnequipped(smartGlassesModuleAccess);
241+
if (isEquipped) {
242+
oldModule.onUnequipped(smartGlassesModuleAccess);
243+
}
240244
}
241245
this.modules[slot] = newModule;
242246
} else if (oldModule != null) {
243-
oldModule.onUnequipped(smartGlassesModuleAccess);
247+
if (isEquipped) {
248+
oldModule.onUnequipped(smartGlassesModuleAccess);
249+
}
244250
this.modules[slot] = null;
245251
}
246252
this.modulePeripheral.updateModules(Stream.of(this.modules).filter(Objects::nonNull).toList());

src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/IModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public interface IModule {
2828
*/
2929
default void serverTick(SmartGlassesSideAccess smartGlassesAccess) {}
3030

31+
/**
32+
* Invoke when the module is removed from smart glasses, or smart glasses is unequipped from the entity's head slot.
33+
*
34+
* @param smartGlassesAccess smart glasses computer access
35+
*/
3136
default void onUnequipped(SmartGlassesSideAccess smartGlassesAccess) {}
3237

3338
/**

0 commit comments

Comments
 (0)