From 45932e5e4b11f06f4b3b7871576cacc800782b28 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 19 Aug 2021 17:02:18 +0700 Subject: [PATCH] Android features registry and impl, better android networking --- .../mc/otm/OverdriveThatMatters.java | 3 + .../java/ru/dbotthepony/mc/otm/Registry.java | 45 +++- .../mc/otm/block/BlockAndroidStation.java | 3 +- .../entity/BlockEntityAndroidStation.java | 2 +- .../mc/otm/capability/IAndroidCapability.java | 30 --- .../mc/otm/capability/MatteryCapability.java | 1 + .../capability/android/AndroidAirBags.java | 7 + .../capability/android/AndroidCapability.java | 217 ++++++++++++++---- .../android/AndroidCapabilityPlayer.java | 85 +++---- .../capability/android/AndroidFeature.java | 43 ++++ .../android/AndroidFeatureType.java | 24 ++ .../android/IAndroidCapability.java | 43 ++++ .../dbotthepony/mc/otm/client/AndroidGui.java | 4 +- .../ru/dbotthepony/mc/otm/item/ItemPill.java | 2 +- .../mc/otm/menu/AndroidStationMenu.java | 2 +- .../AndroidCapabilityChangePacket.java | 105 --------- ...tAndroidCapabilityChangePacketHandler.java | 18 -- .../mc/otm/network/MatteryNetworking.java | 41 +++- .../network/android/AndroidBatteryPacket.java | 38 +++ .../network/android/AndroidEnergyPacket.java | 45 ++++ .../network/android/AndroidFeaturePacket.java | 58 +++++ .../network/android/AndroidStatusPacket.java | 41 ++++ 22 files changed, 587 insertions(+), 270 deletions(-) delete mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBags.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java delete mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/AndroidCapabilityChangePacket.java delete mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/ClientAndroidCapabilityChangePacketHandler.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidBatteryPacket.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 27043315a..80bb7f70c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -53,11 +53,14 @@ public class OverdriveThatMatters { FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Blocks.class); FMLJavaModLoadingContext.get().getModEventBus().register(Registry.BlockEntities.class); FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Menus.class); + FMLJavaModLoadingContext.get().getModEventBus().register(Registry.AndroidFeatures.class); FMLJavaModLoadingContext.get().getModEventBus().addListener(AndroidCapability::registerEffects); // LOGGER.info("Registered event handlers"); + Registry.createRegistry(); + CREATIVE_TAB = new CreativeModeTab("otm") { @Override public ItemStack makeIcon() { diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index d067e4d3e..644a1c258 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -5,15 +5,19 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.RegistryBuilder; import ru.dbotthepony.mc.otm.block.*; import ru.dbotthepony.mc.otm.block.entity.*; +import ru.dbotthepony.mc.otm.capability.android.AndroidAirBags; +import ru.dbotthepony.mc.otm.capability.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.item.ItemBattery; import ru.dbotthepony.mc.otm.item.ItemMatterCapacitor; import ru.dbotthepony.mc.otm.item.ItemPatternStorage; @@ -32,7 +36,28 @@ public class Registry { DAMAGE_BECOME_HUMANE.bypassArmor().bypassInvul().bypassMagic(); } + private static ForgeRegistry> ANDROID_FEATURES; + + public static ForgeRegistry> ANDROID_FEATURES() { + return ANDROID_FEATURES; + } + + public static void createRegistry() { + if (ANDROID_FEATURES != null) + throw new IllegalStateException("Already has registry"); + + var builder = new RegistryBuilder>(); + builder.setName(new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_features")); + + // make it shut up + builder.setType(c(AndroidFeatureType.class)); + ANDROID_FEATURES = (ForgeRegistry>) builder.create(); + } + + private static Class c(Class cls) { return (Class) cls; } + public static class Names { + // blocks public static final ResourceLocation ANDROID_STATION = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_station"); public static final ResourceLocation BATTERY_BANK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "battery_bank"); public static final ResourceLocation MATTER_DECOMPOSER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_decomposer"); @@ -43,8 +68,10 @@ public class Registry { public static final ResourceLocation MATTER_PANEL = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_panel"); public static final ResourceLocation MATTER_REPLICATOR = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_replicator"); + // capabilities public static final ResourceLocation ANDROID_CAPABILITY = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_capability"); + // items public static final ResourceLocation PILL_ANDROID = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pill_android"); public static final ResourceLocation PILL_HUMANE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pill_humane"); @@ -60,6 +87,9 @@ public class Registry { public static final ResourceLocation PATTERN_DRIVE_NORMAL = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pattern_drive_normal"); public static final ResourceLocation PATTERN_DRIVE_CREATIVE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pattern_drive_creative"); + + // android features + public static final ResourceLocation AIR_BAGS = new ResourceLocation(OverdriveThatMatters.MOD_ID, "air_bags"); } public static class Blocks { @@ -225,6 +255,19 @@ public class Registry { } } + public static class AndroidFeatures { + public static final AndroidFeatureType AIR_BAGS = new AndroidFeatureType<>(AndroidAirBags::new); + + static { + AIR_BAGS.setRegistryName(Names.AIR_BAGS); + } + + @SubscribeEvent + public static void register(final RegistryEvent.Register> event) { + event.getRegistry().register(AIR_BAGS); + } + } + public static class Menus { public static final MenuType ANDROID_STATION = new MenuType<>(AndroidStationMenu::new); public static final MenuType BATTERY_BANK = new MenuType<>(BatteryBankMenu::new); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java index 1e12a6429..28e064627 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java @@ -13,12 +13,11 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.common.util.LazyOptional; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.shapes.BlockShapes; diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java index 8939d2392..045c187f0 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java deleted file mode 100644 index 782d291e6..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.dbotthepony.mc.otm.capability; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.common.util.INBTSerializable; -import ru.dbotthepony.mc.otm.network.AndroidCapabilityChangePacket; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public interface IAndroidCapability extends IMatteryEnergyStorage, INBTSerializable { - void tick(); - void tickClient(); - LivingEntity getEntity(); - - default boolean isAndroid() { - return true; - } - - @Nonnull - ItemStack getBatteryItemStack(); - void setBatteryItemStack(@Nonnull ItemStack stack); - - // networking - void invalidateNetworkState(); // tell capability that player forgot everything - AndroidCapabilityChangePacket writeChanges(); // write changes to network - void readChanges(AndroidCapabilityChangePacket packet); // read changes from network -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index 620ea8f73..bebe88a2a 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -4,6 +4,7 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.energy.IEnergyStorage; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import java.math.BigDecimal; import java.math.MathContext; diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBags.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBags.java new file mode 100644 index 000000000..b0bbfdca4 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBags.java @@ -0,0 +1,7 @@ +package ru.dbotthepony.mc.otm.capability.android; + +public class AndroidAirBags extends AndroidFeature { + public AndroidAirBags(AndroidFeatureType type, IAndroidCapability capability) { + super(type, capability); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java index 1759056b8..66b704cf3 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java @@ -1,13 +1,14 @@ package ru.dbotthepony.mc.otm.capability.android; -import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.food.FoodData; import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; @@ -18,19 +19,21 @@ import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fmllegacy.network.PacketDistributor; +import org.apache.logging.log4j.core.jmx.Server; import ru.dbotthepony.mc.otm.OverdriveThatMatters; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.network.AndroidCapabilityChangePacket; +import ru.dbotthepony.mc.otm.network.MatteryNetworking; +import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket; +import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket; +import ru.dbotthepony.mc.otm.network.android.AndroidFeaturePacket; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.math.BigDecimal; -import java.util.HashSet; -import java.util.Optional; -import java.util.Random; -import java.util.Set; +import java.util.*; public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable { protected final LivingEntity ent; @@ -42,6 +45,64 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit private BigDecimal network_energy_max = new BigDecimal(-1); private ItemStack network_battery = ItemStack.EMPTY; + protected final Map, AndroidFeature> features = new HashMap<>(); + protected final ArrayList network_queue = new ArrayList<>(); + + protected boolean network_first = false; + + protected boolean addFeature(@Nonnull AndroidFeature feature) { + if (features.containsKey(feature.type)) + return false; + + features.put(feature.type, feature); + + if (ent instanceof ServerPlayer ply) { + sendNetwork(new AndroidFeaturePacket(true, feature)); + } + + return true; + } + + @Override + public boolean addFeature(@Nonnull AndroidFeatureType feature) { + if (features.containsKey(feature)) + return false; + + var factory = feature.factory(this); + features.put(feature, factory); + + if (ent instanceof ServerPlayer ply) { + sendNetwork(new AndroidFeaturePacket(true, factory)); + } + + return true; + } + + @Override + public boolean removeFeature(@Nonnull AndroidFeatureType feature) { + var removed = features.remove(feature); + + if (removed != null) { + if (ent instanceof ServerPlayer ply) { + sendNetwork(new AndroidFeaturePacket(false, removed)); + } + + return true; + } + + return false; + } + + @Override + public boolean hasFeature(@Nullable AndroidFeatureType feature) { + return features.containsKey(feature); + } + + @Nullable + public AndroidFeature getFeature(AndroidFeatureType feature) { + return features.get(feature); + } + public static final Set UNAFFECTED_EFFECTS = new HashSet<>(); public static void registerEffects(final FMLCommonSetupEvent event) { @@ -64,6 +125,23 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit network_energy = new BigDecimal(-1); network_energy_max = new BigDecimal(-1); network_battery = ItemStack.EMPTY; + + if (ent instanceof ServerPlayer ply) { + for (var feature : features.values()) { + sendNetwork(new AndroidFeaturePacket(true, feature)); + feature.invalidateNetwork(); + } + } + } + + @Override + public void setEnergy(BigDecimal value) { + energy_stored = value; + } + + @Override + public void setMaxEnergy(BigDecimal value) { + energy_stored_max = value; } public AndroidCapability(LivingEntity ent) { @@ -83,6 +161,22 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit tag.putString("energy_stored", energy_stored.toString()); tag.putString("energy_stored_max", energy_stored_max.toString()); tag.put("battery", battery.serializeNBT()); + + var features_nbt = new ListTag(); + + for (var feature : features.values()) { + var compound = new CompoundTag(); + compound.putString("id", Objects.requireNonNull(feature.type.getRegistryName()).toString()); + + if (feature instanceof INBTSerializable serializable) { + compound.put("data", serializable.serializeNBT()); + } + + features_nbt.add(compound); + } + + tag.put("features", features_nbt); + return tag; } @@ -96,6 +190,27 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit if (compound.contains("battery")) battery = ItemStack.of(compound.getCompound("battery")); + + features.clear(); + + var features_nbt = compound.getList("features", Tag.TAG_COMPOUND); + + for (var _tag : features_nbt) { + if (_tag instanceof CompoundTag tag) { + var get_feature = Registry.ANDROID_FEATURES().getValue(new ResourceLocation(tag.getString("id"))); + + if (get_feature != null) { + var feature = get_feature.factory(this); + + if (feature instanceof INBTSerializable serializable) { + serializable.deserializeNBT(tag.getCompound("data")); + } + + addFeature(feature); + feature.attachFinish(); + } + } + } } public void dropBattery() { @@ -106,49 +221,43 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit battery = ItemStack.EMPTY; } + protected void sendNetwork(Object packet) { + if (ent instanceof ServerPlayer ply) { + if (network_first) { + MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> ply), packet); + } else { + network_queue.add(packet); + } + } + } + protected void tickNetwork() { + network_first = true; - } + if (ent instanceof ServerPlayer ply) { + if (!energy_stored.equals(network_energy)) { + network_energy = energy_stored; + sendNetwork(new AndroidEnergyPacket(false, energy_stored)); + } - @Override - @Nullable - public AndroidCapabilityChangePacket writeChanges() { - if (!isAndroid()) - return null; + if (!energy_stored_max.equals(network_energy_max)) { + network_energy_max = energy_stored_max; + sendNetwork(new AndroidEnergyPacket(true, energy_stored_max)); + } - AndroidCapabilityChangePacket packet = null; + if (!network_battery.equals(battery, false)) { + network_battery = battery.copy(); + sendNetwork(new AndroidBatteryPacket(battery)); + } - if (!energy_stored.equals(network_energy)) { - network_energy = energy_stored; - packet = new AndroidCapabilityChangePacket(); - packet.energyChanged(network_energy); + if (network_queue.size() != 0) { + for (var packet : network_queue) { + MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> ply), packet); + } + + network_queue.clear(); + } } - - if (!energy_stored_max.equals(network_energy_max)) { - network_energy_max = energy_stored_max; - if (packet == null) packet = new AndroidCapabilityChangePacket(); - packet.maxEnergyChanged(energy_stored_max); - } - - if (!network_battery.equals(battery, false)) { - network_battery = battery.copy(); - if (packet == null) packet = new AndroidCapabilityChangePacket(); - packet.batteryStackChanged(battery); - } - - return packet; - } - - @Override - public void readChanges(AndroidCapabilityChangePacket packet) { - if (packet.energy != null) - energy_stored = packet.energy; - - if (packet.max_energy != null) - energy_stored_max = packet.max_energy; - - if (packet.battery != null) - battery = packet.battery; } protected void tickInnerClient() { @@ -157,19 +266,29 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Override public void tickClient() { - if (isAndroid()) + if (isAndroid()) { tickInnerClient(); + + for (var feature : features.values()) { + feature.tickClient(); + } + } } @Override public void tick() { - if (isAndroid()) - tickInner(); + if (isAndroid()) { + tickServer(); + + for (var feature : features.values()) { + feature.tickServer(); + } + } tickNetwork(); } - protected void tickInner() { + protected void tickServer() { if (ent.getAirSupply() < ent.getMaxAirSupply()) ent.setAirSupply(ent.getMaxAirSupply()); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java index 9581b80f3..f581b866e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java @@ -1,7 +1,6 @@ package ru.dbotthepony.mc.otm.capability.android; import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.InputUpdateEvent; @@ -9,19 +8,15 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fmllegacy.network.PacketDistributor; import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.network.AndroidCapabilityChangePacket; -import ru.dbotthepony.mc.otm.network.MatteryNetworking; +import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.math.BigDecimal; public class AndroidCapabilityPlayer extends AndroidCapability { - private boolean is_android = false; + public boolean is_android = false; private boolean network_is_android = false; @Override @@ -30,29 +25,6 @@ public class AndroidCapabilityPlayer extends AndroidCapability { network_is_android = false; } - @Override - public void readChanges(AndroidCapabilityChangePacket packet) { - super.readChanges(packet); - - if (packet.is_android != null) { - is_android = packet.is_android; - } - } - - @Nullable - @Override - public AndroidCapabilityChangePacket writeChanges() { - AndroidCapabilityChangePacket packet = super.writeChanges(); - - if (is_android != network_is_android) { - network_is_android = is_android; - if (packet == null) packet = new AndroidCapabilityChangePacket(); - packet.isAndroid(is_android); - } - - return packet; - } - @Override public boolean isAndroid() { return is_android; @@ -70,6 +42,21 @@ public class AndroidCapabilityPlayer extends AndroidCapability { ply.die(Registry.DAMAGE_BECOME_ANDROID); } + public void becomeHumane() { + if (!is_android) + return; + + is_android = false; + + energy_stored = new BigDecimal(0); + energy_stored_max = new BigDecimal(32_000); + + dropBattery(); + + ply.setHealth(0.0F); + ply.die(Registry.DAMAGE_BECOME_HUMANE); + } + @Override public void deserializeNBT(CompoundTag compound) { super.deserializeNBT(compound); @@ -86,21 +73,6 @@ public class AndroidCapabilityPlayer extends AndroidCapability { return tag; } - public void becomeHumane() { - if (!is_android) - return; - - is_android = false; - - energy_stored = new BigDecimal(0); - energy_stored_max = new BigDecimal(32_000); - - dropBattery(); - - ply.setHealth(0.0F); - ply.die(Registry.DAMAGE_BECOME_HUMANE); - } - @SubscribeEvent public static void onAttachCapabilityEvent(AttachCapabilitiesEvent event) { if (event.getObject() instanceof Player ply) { @@ -134,7 +106,7 @@ public class AndroidCapabilityPlayer extends AndroidCapability { }); } - private int last_jump_ticks = 10; + private int last_jump_ticks = 14; @SubscribeEvent public static void inputEvent(InputUpdateEvent event) { @@ -145,12 +117,15 @@ public class AndroidCapabilityPlayer extends AndroidCapability { if (!(_cap instanceof AndroidCapabilityPlayer cap)) return; + if (cap.hasFeature(Registry.AndroidFeatures.AIR_BAGS)) + return; + if (ply.getAbilities().mayfly) { - cap.last_jump_ticks = 10; + cap.last_jump_ticks = 14; } else { if (ply.isInWater()) { if (ply.isOnGround()) { - cap.last_jump_ticks = 10; + cap.last_jump_ticks = 14; } if (ply.isSwimming()) { @@ -177,22 +152,24 @@ public class AndroidCapabilityPlayer extends AndroidCapability { @Override protected void tickNetwork() { - AndroidCapabilityChangePacket packet = writeChanges(); + super.tickNetwork(); - if (packet != null) - MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) ent), packet); + if (is_android != network_is_android) { + network_is_android = is_android; + sendNetwork(new AndroidStatusPacket(is_android)); + } } public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(1000); @Override - public void tickInner() { - super.tickInner(); + public void tickServer() { + super.tickServer(); // TODO: Maybe passive drain? // extractEnergyInner(BigDecimal.valueOf(new Random().nextDouble()), false); - if (ply.isSwimming()) { + if (ply.isSwimming() && !hasFeature(Registry.AndroidFeatures.AIR_BAGS)) { ply.setSwimming(false); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java new file mode 100644 index 000000000..52c84bfdb --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java @@ -0,0 +1,43 @@ +package ru.dbotthepony.mc.otm.capability.android; + +public class AndroidFeature { + public final AndroidFeatureType type; + public final IAndroidCapability capability; + + public AndroidFeature(AndroidFeatureType type, IAndroidCapability capability) { + this.type = type; + this.capability = capability; + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) + return true; + + if (obj instanceof AndroidFeature feature) + return feature.type.equals(type); + + return false; + } + + public void invalidateNetwork() { + // when player forgets everything + } + + public void attachFinish() { + // override + } + + @Override + public int hashCode() { + return type.hashCode(); + } + + public void tickClient() { + + } + + public void tickServer() { + + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java new file mode 100644 index 000000000..f93b70d25 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java @@ -0,0 +1,24 @@ +package ru.dbotthepony.mc.otm.capability.android; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.registries.*; + +public class AndroidFeatureType extends ForgeRegistryEntry> { + public interface AndroidFeatureFactory { + T factory(AndroidFeatureType entry, IAndroidCapability capability); + } + + protected final AndroidFeatureFactory factory; + + public AndroidFeatureType(AndroidFeatureFactory factory) { + this.factory = factory; + } + + public T factory(IAndroidCapability capability) { + return factory.factory(this, capability); + } + + public boolean isApplicable(IAndroidCapability capability) { + return true; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java new file mode 100644 index 000000000..759a56388 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java @@ -0,0 +1,43 @@ +package ru.dbotthepony.mc.otm.capability.android; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.INBTSerializable; +import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.util.Optional; + +public interface IAndroidCapability extends IMatteryEnergyStorage, INBTSerializable { + void tick(); + void tickClient(); + LivingEntity getEntity(); + + boolean addFeature(@Nonnull AndroidFeatureType feature); + boolean removeFeature(@Nonnull AndroidFeatureType feature); + boolean hasFeature(@Nullable AndroidFeatureType feature); + AndroidFeature getFeature(AndroidFeatureType feature); + + @Nonnull + default Optional getFeatureO(AndroidFeatureType feature) { + var get = getFeature(feature); + return get != null ? Optional.of(get) : Optional.empty(); + } + + default boolean isAndroid() { + return true; + } + + @Nonnull + ItemStack getBatteryItemStack(); + void setBatteryItemStack(@Nonnull ItemStack stack); + + void invalidateNetworkState(); // tell capability that player forgot everything, and everything needs to be re-networked + + void setEnergy(BigDecimal value); + void setMaxEnergy(BigDecimal value); +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java index 9ba4aa1e2..6d9227a09 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java @@ -3,9 +3,7 @@ package ru.dbotthepony.mc.otm.client; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.DeathScreen; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffects; @@ -16,7 +14,7 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.gui.ForgeIngameGui; import net.minecraftforge.eventbus.api.SubscribeEvent; import ru.dbotthepony.mc.otm.OverdriveThatMatters; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import java.math.BigDecimal; diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java index 7d5572211..91bf2c9b7 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.Level; import net.minecraftforge.common.util.FakePlayer; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import javax.annotation.Nullable; diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java index 517d850b6..0be1eca06 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java @@ -7,7 +7,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.util.LazyOptional; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.menu.slot.BatterySlot; diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/AndroidCapabilityChangePacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/AndroidCapabilityChangePacket.java deleted file mode 100644 index 77a9a75d6..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/network/AndroidCapabilityChangePacket.java +++ /dev/null @@ -1,105 +0,0 @@ -package ru.dbotthepony.mc.otm.network; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fmllegacy.network.NetworkEvent; -import net.minecraftforge.fmllegacy.network.PacketDistributor; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.function.Supplier; - -public class AndroidCapabilityChangePacket { - public enum ChangeType { - TERMINATION, - ENERGY_CHANGED, - MAX_ENERGY_CHANGED, - BATTERY_STACK_CHANGED, - IS_ANDROID, - } - - public BigDecimal energy; - public BigDecimal max_energy; - public ItemStack battery; - public Boolean is_android; - - public boolean isEmpty() { - return energy == null && max_energy == null && battery == null; - } - - // build state - public void energyChanged(BigDecimal energy) { - this.energy = energy; - } - - public void maxEnergyChanged(BigDecimal energy) { - this.max_energy = energy; - } - - public void isAndroid(boolean is_android) { - this.is_android = is_android; - } - - public void batteryStackChanged(ItemStack stack) { - this.battery = stack; - } - - // encode state - public void encodeNetwork(FriendlyByteBuf buffer) { - if (energy != null) { - buffer.writeByte(ChangeType.ENERGY_CHANGED.ordinal()); - NetworkHelper.writeDecimal(buffer, energy); - } - - if (max_energy != null) { - buffer.writeByte(ChangeType.MAX_ENERGY_CHANGED.ordinal()); - NetworkHelper.writeDecimal(buffer, max_energy); - } - - if (battery != null) { - buffer.writeByte(ChangeType.BATTERY_STACK_CHANGED.ordinal()); - buffer.writeItem(battery); - } - - if (is_android != null) { - buffer.writeByte(ChangeType.IS_ANDROID.ordinal()); - buffer.writeByte(is_android ? 1 : 0); - } - - buffer.writeByte(ChangeType.TERMINATION.ordinal()); - } - - // handle state - public void handleMessage(Supplier context) { - context.get().setPacketHandled(true); - - context.get().enqueueWork(() -> { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientAndroidCapabilityChangePacketHandler.handlePacket(this, context)); - }); - } - - // decode state - public static AndroidCapabilityChangePacket decodeNetwork(FriendlyByteBuf buffer) { - AndroidCapabilityChangePacket packet = new AndroidCapabilityChangePacket(); - - ChangeType read = ChangeType.values()[buffer.readByte()]; - - while (read != ChangeType.TERMINATION) { - switch (read) { - case ENERGY_CHANGED -> packet.energy = NetworkHelper.readDecimal(buffer); - case MAX_ENERGY_CHANGED -> packet.max_energy = NetworkHelper.readDecimal(buffer); - case BATTERY_STACK_CHANGED -> packet.battery = buffer.readItem(); - case IS_ANDROID -> packet.is_android = buffer.readByte() > 0; - } - - read = ChangeType.values()[buffer.readByte()]; - } - - return packet; - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/ClientAndroidCapabilityChangePacketHandler.java b/src/main/java/ru/dbotthepony/mc/otm/network/ClientAndroidCapabilityChangePacketHandler.java deleted file mode 100644 index 0b7ba1b07..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/network/ClientAndroidCapabilityChangePacketHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.dbotthepony.mc.otm.network; - -import net.minecraft.client.Minecraft; -import net.minecraftforge.fmllegacy.network.NetworkEvent; -import ru.dbotthepony.mc.otm.OverdriveThatMatters; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; - -import java.util.function.Supplier; - -public class ClientAndroidCapabilityChangePacketHandler { - public static void handlePacket(AndroidCapabilityChangePacket packet, Supplier ctx) { - if (Minecraft.getInstance().player != null) { - Minecraft.getInstance().player.getCapability(MatteryCapability.ANDROID) - .orElseThrow(() -> new IllegalStateException("Local player has no android capability yet")) - .readChanges(packet); - } - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java index e7758c12e..057de9639 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java @@ -5,11 +5,15 @@ import net.minecraftforge.fmllegacy.network.NetworkDirection; import net.minecraftforge.fmllegacy.network.NetworkRegistry; import net.minecraftforge.fmllegacy.network.simple.SimpleChannel; import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket; +import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket; +import ru.dbotthepony.mc.otm.network.android.AndroidFeaturePacket; +import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket; import java.util.Optional; public class MatteryNetworking { - private static final String PROTOCOL_VERSION = "1"; + private static final String PROTOCOL_VERSION = "2"; private static int next_network_id = 0; @@ -23,10 +27,37 @@ public class MatteryNetworking { public static void register() { CHANNEL.registerMessage( next_network_id++, - AndroidCapabilityChangePacket.class, - AndroidCapabilityChangePacket::encodeNetwork, - AndroidCapabilityChangePacket::decodeNetwork, - AndroidCapabilityChangePacket::handleMessage, + AndroidBatteryPacket.class, + AndroidBatteryPacket::write, + AndroidBatteryPacket::read, + AndroidBatteryPacket::play, + Optional.of(NetworkDirection.PLAY_TO_CLIENT) + ); + + CHANNEL.registerMessage( + next_network_id++, + AndroidEnergyPacket.class, + AndroidEnergyPacket::write, + AndroidEnergyPacket::read, + AndroidEnergyPacket::play, + Optional.of(NetworkDirection.PLAY_TO_CLIENT) + ); + + CHANNEL.registerMessage( + next_network_id++, + AndroidStatusPacket.class, + AndroidStatusPacket::write, + AndroidStatusPacket::read, + AndroidStatusPacket::play, + Optional.of(NetworkDirection.PLAY_TO_CLIENT) + ); + + CHANNEL.registerMessage( + next_network_id++, + AndroidFeaturePacket.class, + AndroidFeaturePacket::write, + AndroidFeaturePacket::read, + AndroidFeaturePacket::play, Optional.of(NetworkDirection.PLAY_TO_CLIENT) ); diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidBatteryPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidBatteryPacket.java new file mode 100644 index 000000000..0b0e7436b --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidBatteryPacket.java @@ -0,0 +1,38 @@ +package ru.dbotthepony.mc.otm.network.android; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fmllegacy.network.NetworkEvent; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.network.NetworkHelper; + +import java.math.BigDecimal; +import java.util.function.Supplier; + +public record AndroidBatteryPacket(ItemStack battery) { + public void write(FriendlyByteBuf buffer) { + buffer.writeItem(battery); + } + + public void play(Supplier context) { + context.get().setPacketHandled(true); + context.get().enqueueWork(() -> { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient); + }); + } + + public void playClient() { + var ply = Minecraft.getInstance().player; + + if (ply != null) { + ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> cap.setBatteryItemStack(battery)); + } + } + + public static AndroidBatteryPacket read(FriendlyByteBuf buffer) { + return new AndroidBatteryPacket(buffer.readItem()); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java new file mode 100644 index 000000000..f31ae050d --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java @@ -0,0 +1,45 @@ +package ru.dbotthepony.mc.otm.network.android; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fmllegacy.network.NetworkEvent; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.network.NetworkHelper; + +import java.math.BigDecimal; +import java.util.function.Supplier; + +public record AndroidEnergyPacket(boolean is_maximal, BigDecimal energy) { + public void write(FriendlyByteBuf buffer) { + buffer.writeBoolean(is_maximal); + NetworkHelper.writeDecimal(buffer, energy); + } + + public void play(Supplier context) { + context.get().setPacketHandled(true); + context.get().enqueueWork(() -> { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient); + }); + } + + public void playClient() { + var ply = Minecraft.getInstance().player; + + if (ply != null) { + ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { + if (is_maximal) { + cap.setMaxEnergy(energy); + } else { + cap.setEnergy(energy); + } + }); + } + } + + public static AndroidEnergyPacket read(FriendlyByteBuf buffer) { + return new AndroidEnergyPacket(buffer.readBoolean(), NetworkHelper.readDecimal(buffer)); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java new file mode 100644 index 000000000..2dab07af6 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java @@ -0,0 +1,58 @@ +package ru.dbotthepony.mc.otm.network.android; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fmllegacy.network.NetworkEvent; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.capability.android.AndroidFeature; +import ru.dbotthepony.mc.otm.capability.android.AndroidFeatureType; + +import java.util.Objects; +import java.util.function.Supplier; + +public record AndroidFeaturePacket(boolean is_added, AndroidFeatureType feature) { + public AndroidFeaturePacket(boolean is_added, AndroidFeatureType feature) { + this.is_added = is_added; + this.feature = feature; + } + + public AndroidFeaturePacket(boolean is_added, AndroidFeature feature) { + this(is_added, feature.type); + } + + public void write(FriendlyByteBuf buffer) { + buffer.writeBoolean(is_added); + buffer.writeInt(Registry.ANDROID_FEATURES().getID(feature)); + } + + public void play(Supplier context) { + context.get().setPacketHandled(true); + context.get().enqueueWork(() -> { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient); + }); + } + + public void playClient() { + var ply = Minecraft.getInstance().player; + + if (ply != null) { + ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { + if (cap instanceof AndroidCapabilityPlayer pcap) { + pcap.addFeature(feature); + } + }); + } + } + + public static AndroidFeaturePacket read(FriendlyByteBuf buffer) { + var is_added = buffer.readBoolean(); + var feature = Objects.requireNonNull(Registry.ANDROID_FEATURES().getValue(buffer.readInt())); + + return new AndroidFeaturePacket(is_added, feature); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java new file mode 100644 index 000000000..9418b9697 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java @@ -0,0 +1,41 @@ +package ru.dbotthepony.mc.otm.network.android; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fmllegacy.network.NetworkEvent; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; + +import java.util.function.Supplier; + +public record AndroidStatusPacket(boolean status) { + public void write(FriendlyByteBuf buffer) { + buffer.writeBoolean(status); + } + + public void play(Supplier context) { + context.get().setPacketHandled(true); + context.get().enqueueWork(() -> { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient); + }); + } + + public void playClient() { + var ply = Minecraft.getInstance().player; + + if (ply != null) { + ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { + if (cap instanceof AndroidCapabilityPlayer pcap) { + pcap.is_android = status; + } + }); + } + } + + public static AndroidStatusPacket read(FriendlyByteBuf buffer) { + return new AndroidStatusPacket(buffer.readBoolean()); + } +}