diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 80bb7f70c..8d06df395 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -12,8 +12,8 @@ import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import ru.dbotthepony.mc.otm.capability.android.AndroidCapability; -import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.capability.AndroidCapability; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.client.AndroidGui; import ru.dbotthepony.mc.otm.matter.MatterGrid; @@ -54,6 +54,7 @@ public class OverdriveThatMatters { FMLJavaModLoadingContext.get().getModEventBus().register(Registry.BlockEntities.class); FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Menus.class); FMLJavaModLoadingContext.get().getModEventBus().register(Registry.AndroidFeatures.class); + FMLJavaModLoadingContext.get().getModEventBus().register(Registry.AndroidResearch.class); FMLJavaModLoadingContext.get().getModEventBus().addListener(AndroidCapability::registerEffects); diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index f276f6915..f041061df 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -13,13 +13,13 @@ 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.android.AndroidFeature; +import ru.dbotthepony.mc.otm.android.AndroidResearch; +import ru.dbotthepony.mc.otm.android.AndroidResearchType; 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.AndroidAirBagsType; -import ru.dbotthepony.mc.otm.capability.android.AndroidFeatureType; +import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.item.ItemBattery; import ru.dbotthepony.mc.otm.item.ItemMatterCapacitor; import ru.dbotthepony.mc.otm.item.ItemPatternStorage; @@ -39,10 +39,14 @@ public class Registry { } private static ForgeRegistry> ANDROID_FEATURES; + private static ForgeRegistry> ANDROID_RESEARCH; public static ForgeRegistry> ANDROID_FEATURES() { return ANDROID_FEATURES; } + public static ForgeRegistry> ANDROID_RESEARCH() { + return ANDROID_RESEARCH; + } public static void createRegistry() { if (ANDROID_FEATURES != null) @@ -54,6 +58,13 @@ public class Registry { // make it shut up builder.setType(c(AndroidFeatureType.class)); ANDROID_FEATURES = (ForgeRegistry>) builder.create(); + + var builder2 = new RegistryBuilder>(); + builder2.setName(new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research")); + + // make it shut up + builder2.setType(c(AndroidResearchType.class)); + ANDROID_RESEARCH = (ForgeRegistry>) builder2.create(); } private static Class c(Class cls) { return (Class) cls; } @@ -266,7 +277,7 @@ public class Registry { } public static class AndroidFeatures { - public static final AndroidAirBagsType AIR_BAGS = new AndroidAirBagsType(); + public static final AndroidFeatureType AIR_BAGS = new AndroidFeatureType<>(AndroidFeature::new); static { AIR_BAGS.setRegistryName(Names.AIR_BAGS); @@ -278,6 +289,25 @@ public class Registry { } } + public static class AndroidResearch { + public static final AndroidResearchType AIR_BAGS = new AndroidResearchType<>( + new ru.dbotthepony.mc.otm.android.AndroidResearch.Builder() + .setExperienceCost(18) + .addFeatureResult(AndroidFeatures.AIR_BAGS) + .withDescription() + .build() + ); + + 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/capability/android/AndroidFeature.java b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeature.java similarity index 58% rename from src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java rename to src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeature.java index 52c84bfdb..dbedd63da 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeature.java +++ b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeature.java @@ -1,6 +1,10 @@ -package ru.dbotthepony.mc.otm.capability.android; +package ru.dbotthepony.mc.otm.android; -public class AndroidFeature { +import net.minecraft.nbt.CompoundTag; +import net.minecraftforge.common.util.INBTSerializable; +import ru.dbotthepony.mc.otm.capability.IAndroidCapability; + +public class AndroidFeature implements INBTSerializable { public final AndroidFeatureType type; public final IAndroidCapability capability; @@ -40,4 +44,20 @@ public class AndroidFeature { public void tickServer() { } + + public void serializeNBT(CompoundTag tag) { + + } + + @Override + public CompoundTag serializeNBT() { + var tag = new CompoundTag(); + serializeNBT(tag); + return tag; + } + + @Override + public void deserializeNBT(CompoundTag tag) { + + } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeatureType.java similarity index 70% rename from src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java rename to src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeatureType.java index c3bccabcc..127f6b715 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureType.java +++ b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidFeatureType.java @@ -1,9 +1,9 @@ -package ru.dbotthepony.mc.otm.capability.android; +package ru.dbotthepony.mc.otm.android; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraftforge.registries.*; +import ru.dbotthepony.mc.otm.capability.IAndroidCapability; import javax.annotation.Nullable; @@ -26,25 +26,6 @@ public class AndroidFeatureType extends ForgeRegistryE return true; } - public boolean isResearchable() { - return false; - } - - @Nullable - protected AndroidFeatureResearchNode getResearchNodeInner() { - return null; - } - - private AndroidFeatureResearchNode cache; - - @Nullable - public AndroidFeatureResearchNode getResearchNode() { - if (cache != null) - return cache; - - return cache = getResearchNodeInner(); - } - public Component getDisplayName() { if (getRegistryName() == null) return new TranslatableComponent("android_feature.null.null"); diff --git a/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearch.java b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearch.java new file mode 100644 index 000000000..a04ef1880 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearch.java @@ -0,0 +1,303 @@ +package ru.dbotthepony.mc.otm.android; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraftforge.common.util.INBTSerializable; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.RegistryManager; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.network.MatteryNetworking; +import ru.dbotthepony.mc.otm.network.android.AndroidResearchRequestPacket; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; + +public abstract class AndroidResearch implements INBTSerializable { + public final AndroidResearchType type; + public final AndroidCapabilityPlayer capability; + + protected boolean researched = false; + public boolean dirty = true; + + public void markDirty() { + dirty = true; + } + + public boolean isResearched() { + return researched; + } + + public AndroidResearch(AndroidResearchType type, AndroidCapabilityPlayer capability) { + this.capability = capability; + this.type = type; + } + + abstract public List> getPrerequisites(); + abstract public void onResearched(); + abstract public void consumeCost(); + abstract public boolean canAfford(); + + public List getTooltip() { + return List.of(type.getDisplayName()); + } + + public boolean research(boolean force) { + if (researched) + return false; + + if (!force && !canAfford()) + return false; + + consumeCost(); + researched = true; + onResearched(); + + markDirty(); + + return true; + } + + public boolean research() { + return research(false); + } + + public void researchClient() { + if (!researched && canAfford() && capability.isAndroid()) + MatteryNetworking.CHANNEL.sendToServer(new AndroidResearchRequestPacket(type)); + } + + @Override + public CompoundTag serializeNBT() { + var nbt = new CompoundTag(); + serializeNBT(nbt); + return nbt; + } + + public void serializeNBT(CompoundTag tag) { + tag.putByte("researched", researched ? (byte) 1 : 0); + } + + public void deserializeNBT(CompoundTag nbt) { + researched = nbt.getByte("researched") > 0; + } + + public static class Builder { + record DeferredItemStack(ResourceLocation id, int amount) {} + + public int experience = 0; + public boolean has_description = false; + public final ArrayList items = new ArrayList<>(); + public final ArrayList prerequisites = new ArrayList<>(); + public final ArrayList feature_results = new ArrayList<>(); + + public Builder addPrerequisite(ResourceLocation location) { + prerequisites.add(location); + return this; + } + + public Builder addFeatureResult(ResourceLocation location) { + feature_results.add(location); + return this; + } + + public Builder addFeatureResult(AndroidFeatureType location) { + feature_results.add(Objects.requireNonNull(location.getRegistryName())); + return this; + } + + public Builder addItem(ResourceLocation location) { + items.add(new DeferredItemStack(location, 1)); + return this; + } + + public Builder addItem(ResourceLocation location, int amount) { + items.add(new DeferredItemStack(location, amount)); + return this; + } + + public Builder setExperienceCost(int experience) { + this.experience = experience; + return this; + } + + public Builder withDescription() { + this.has_description = true; + return this; + } + + private final ArrayList resolved_stacks = new ArrayList<>(); + private final ArrayList> resolved_preq = new ArrayList<>(); + private final ArrayList> resolved_features = new ArrayList<>(); + + private boolean resolved = false; + + private void resolve() { + if (!resolved) { + resolved = true; + + for (var item : items) { + var get_item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(item.id); + + if (get_item != null && get_item != Items.AIR) { + resolved_stacks.add(new ItemStack(get_item, item.amount)); + } + } + + for (var entry : prerequisites) { + var get = Registry.ANDROID_RESEARCH().getValue(entry); + + if (get != null) { + resolved_preq.add(get); + } else { + throw new IllegalArgumentException("Can not find android research " + entry); + } + } + + for (var entry : feature_results) { + var get = Registry.ANDROID_FEATURES().getValue(entry); + + if (get != null) { + resolved_features.add(get); + } else { + throw new IllegalArgumentException("Can not find android feature " + entry); + } + } + } + } + + public AndroidResearchType.AndroidResearchFactory build() { + return (type, capability) -> { + resolve(); + + return new AndroidResearch(type, capability) { + @Override + public List getTooltip() { + var list = new ArrayList<>(super.getTooltip()); + + if (has_description) { + list.add(new TranslatableComponent("android_research." + type.getRegistryName().getNamespace() + "." + type.getRegistryName().getPath() + ".description")); + } + + if (!researched) { + if (experience > 0) { + if (capability.ply.experienceLevel >= experience) { + list.add(new TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(ChatFormatting.DARK_GREEN)); + } else { + list.add(new TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(ChatFormatting.DARK_RED)); + } + } + + for (var stack : resolved_stacks) { + boolean hit = false; + + if (stack.getTag() == null) { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { + hit = true; + break; + } + } + } else { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { + hit = true; + break; + } + } + } + + if (hit) { + list.add(new TranslatableComponent("otm.android_station.research.item", stack.getDisplayName(), stack.getCount()).withStyle(ChatFormatting.DARK_GREEN)); + } else { + list.add(new TranslatableComponent("otm.android_station.research.item", stack.getDisplayName(), stack.getCount()).withStyle(ChatFormatting.DARK_RED)); + } + } + } + + return list; + } + + @Override + public List> getPrerequisites() { + return List.copyOf(resolved_preq); + } + + @Override + public void onResearched() { + for (var feature : resolved_features) { + capability.addFeature(feature); + } + } + + @Override + public boolean canAfford() { + if (capability.ply.experienceLevel < experience) + return false; + + for (var stack : resolved_stacks) { + boolean hit = false; + + if (stack.getTag() == null) { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { + hit = true; + break; + } + } + } else { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { + hit = true; + break; + } + } + } + + if (!hit) + return false; + } + + return true; + } + + @Override + public void consumeCost() { + if (experience > 0) + capability.ply.giveExperienceLevels(-experience); + + for (var stack : resolved_stacks) { + if (stack.getTag() == null) { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { + inv_stack.shrink(stack.getCount()); + break; + } + } + } else { + for (var inv_stack : capability.ply.getInventory().items) { + if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { + inv_stack.shrink(stack.getCount()); + break; + } + } + } + } + + capability.ply.getInventory().setChanged(); + } + }; + }; + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java new file mode 100644 index 000000000..0df8d4aab --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/android/AndroidResearchType.java @@ -0,0 +1,29 @@ +package ru.dbotthepony.mc.otm.android; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraftforge.registries.ForgeRegistryEntry; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; + +public class AndroidResearchType extends ForgeRegistryEntry> { + public interface AndroidResearchFactory { + T factory(AndroidResearchType entry, AndroidCapabilityPlayer capability); + } + + protected final AndroidResearchFactory factory; + + public AndroidResearchType(AndroidResearchFactory factory) { + this.factory = factory; + } + + public T factory(AndroidCapabilityPlayer capability) { + return factory.factory(this, capability); + } + + public Component getDisplayName() { + if (getRegistryName() == null) + return new TranslatableComponent("android_research.null.null"); + + return new TranslatableComponent("android_research." + getRegistryName().getNamespace() + "." + getRegistryName().getPath()); + } +} 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 28e064627..96b84ac3f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java @@ -17,7 +17,7 @@ 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.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.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 045c187f0..8939d2392 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.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.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/android/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java similarity index 96% rename from src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java rename to src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java index e5ad50a96..76cbfc08f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java @@ -1,4 +1,4 @@ -package ru.dbotthepony.mc.otm.capability.android; +package ru.dbotthepony.mc.otm.capability; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -20,11 +20,9 @@ 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.Registry; -import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.android.AndroidFeature; +import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket; import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket; @@ -167,12 +165,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit for (var feature : features.values()) { var compound = new CompoundTag(); + feature.serializeNBT(compound); compound.putString("id", Objects.requireNonNull(feature.type.getRegistryName()).toString()); - - if (feature instanceof INBTSerializable serializable) { - compound.put("data", serializable.serializeNBT()); - } - features_nbt.add(compound); } @@ -202,10 +196,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit if (get_feature != null && get_feature.isApplicable(this)) { var feature = get_feature.factory(this); - - if (feature instanceof INBTSerializable serializable) { - serializable.deserializeNBT(tag.getCompound("data")); - } + feature.deserializeNBT(tag); addFeature(feature); feature.attachFinish(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java similarity index 76% rename from src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java rename to src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java index f581b866e..3794c9a94 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapabilityPlayer.java @@ -1,6 +1,9 @@ -package ru.dbotthepony.mc.otm.capability.android; +package ru.dbotthepony.mc.otm.capability; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.InputUpdateEvent; @@ -9,20 +12,30 @@ import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.android.AndroidResearch; +import ru.dbotthepony.mc.otm.android.AndroidResearchType; +import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket; import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket; import javax.annotation.Nonnull; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Objects; public class AndroidCapabilityPlayer extends AndroidCapability { public boolean is_android = false; private boolean network_is_android = false; + private final ArrayList research_list = new ArrayList<>(); + @Override public void invalidateNetworkState() { super.invalidateNetworkState(); network_is_android = false; + + for (var instance : research_list) { + instance.dirty = true; + } } @Override @@ -63,16 +76,56 @@ public class AndroidCapabilityPlayer extends AndroidCapability { if (compound.contains("is_android")) is_android = compound.getByte("is_android") > 0; + + research_list.clear(); + + var list = compound.getList("research", Tag.TAG_COMPOUND); + + for (var _tag : list) { + if (_tag instanceof CompoundTag tag) { + var research = Registry.ANDROID_RESEARCH().getValue(new ResourceLocation(tag.getString("id"))); + + if (research != null) { + var instance = research.factory(this); + instance.deserializeNBT(tag); + research_list.add(instance); + } + } + } } @Nonnull @Override public CompoundTag serializeNBT() { CompoundTag tag = super.serializeNBT(); - tag.putByte("is_android", is_android ? (byte) 1 : (byte) 0); + tag.putByte("is_android", is_android ? (byte) 1 : 0); + + var list = new ListTag(); + + for (var instance : research_list) { + var _tag = new CompoundTag(); + instance.serializeNBT(_tag); + _tag.putString("id", Objects.requireNonNull(instance.type.getRegistryName()).toString()); + list.add(_tag); + } + + tag.put("research", list); + return tag; } + public AndroidResearch getResearch(AndroidResearchType type) { + for (var instance : research_list) { + if (instance.type == type) { + return instance; + } + } + + var instance = type.factory(this); + research_list.add(instance); + return instance; + } + @SubscribeEvent public static void onAttachCapabilityEvent(AttachCapabilitiesEvent event) { if (event.getObject() instanceof Player ply) { @@ -143,7 +196,7 @@ public class AndroidCapabilityPlayer extends AndroidCapability { }); } - private final Player ply; + public final Player ply; public AndroidCapabilityPlayer(Player ent) { super(ent); @@ -158,6 +211,13 @@ public class AndroidCapabilityPlayer extends AndroidCapability { network_is_android = is_android; sendNetwork(new AndroidStatusPacket(is_android)); } + + for (var instance : research_list) { + if (instance.dirty) { + instance.dirty = false; + sendNetwork(new AndroidResearchPacket(instance)); + } + } } public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(1000); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java similarity index 89% rename from src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java rename to src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java index 759a56388..8b8e23f32 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java @@ -1,10 +1,11 @@ -package ru.dbotthepony.mc.otm.capability.android; +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.android.AndroidFeature; +import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import javax.annotation.Nonnull; 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 bebe88a2a..620ea8f73 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -4,7 +4,6 @@ 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 deleted file mode 100644 index b0bbfdca4..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBags.java +++ /dev/null @@ -1,7 +0,0 @@ -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/AndroidAirBagsType.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBagsType.java deleted file mode 100644 index 4870c6c06..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidAirBagsType.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.dbotthepony.mc.otm.capability.android; - -import javax.annotation.Nullable; - -public class AndroidAirBagsType extends AndroidFeatureType { - public AndroidAirBagsType() { - super(AndroidAirBags::new); - } - - @Nullable - @Override - public AndroidFeatureResearchNode getResearchNodeInner() { - return new AndroidFeatureResearchNode(this, new AndroidFeatureResearchCost(18)) - .withDescription(); - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchCost.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchCost.java deleted file mode 100644 index 56a77a627..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchCost.java +++ /dev/null @@ -1,124 +0,0 @@ -package ru.dbotthepony.mc.otm.capability.android; - -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; - -import java.util.ArrayList; -import java.util.List; - -public record AndroidFeatureResearchCost(int experience, ItemStack ...items) { - public boolean matches(Player ply) { - if (ply.experienceLevel < experience) - return false; - - for (var stack : items) { - boolean hit = false; - - if (stack.getTag() == null) { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { - hit = true; - break; - } - } - } else { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { - hit = true; - break; - } - } - } - - if (!hit) - return false; - } - - return true; - } - - public List getTooltip() { - var list = new ArrayList(); - - if (experience > 0) - list.add(new TranslatableComponent("otm.android_station.research.xp_cost", experience)); - - for (var itemstack : items) - list.add(new TranslatableComponent("otm.android_station.research.item", itemstack.getDisplayName(), itemstack.getCount())); - - return list; - } - - public List getTooltip(Player ply) { - var list = new ArrayList(); - - if (experience > 0) { - if (ply.experienceLevel >= experience) { - list.add(new TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(ChatFormatting.DARK_GREEN)); - } else { - list.add(new TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(ChatFormatting.DARK_RED)); - } - } - - for (var stack : items) { - boolean hit = false; - - if (stack.getTag() == null) { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { - hit = true; - break; - } - } - } else { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { - hit = true; - break; - } - } - } - - if (hit) { - list.add(new TranslatableComponent("otm.android_station.research.item", stack.getDisplayName(), stack.getCount()).withStyle(ChatFormatting.DARK_GREEN)); - } else { - list.add(new TranslatableComponent("otm.android_station.research.item", stack.getDisplayName(), stack.getCount()).withStyle(ChatFormatting.DARK_RED)); - } - } - - return list; - } - - public boolean research(Player ply) { - if (!matches(ply)) - return false; - - if (experience > 0) - ply.giveExperienceLevels(-experience); - - for (var stack : items) { - if (stack.getTag() == null) { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount()) { - inv_stack.shrink(stack.getCount()); - break; - } - } - } else { - for (var inv_stack : ply.getInventory().items) { - if (inv_stack.is(stack.getItem()) && inv_stack.getCount() >= stack.getCount() && inv_stack.getTag() != null && inv_stack.getTag().equals(stack.getTag())) { - inv_stack.shrink(stack.getCount()); - break; - } - } - } - } - - ply.getInventory().setChanged(); - - return true; - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchNode.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchNode.java deleted file mode 100644 index 7c09394e7..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidFeatureResearchNode.java +++ /dev/null @@ -1,120 +0,0 @@ -package ru.dbotthepony.mc.otm.capability.android; - -import net.minecraft.client.Minecraft; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.entity.player.Player; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.network.MatteryNetworking; -import ru.dbotthepony.mc.otm.network.android.AndroidResearchRequestPacket; -import ru.dbotthepony.mc.otm.screen.SkinElement; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class AndroidFeatureResearchNode { - public final AndroidFeatureType type; - public final AndroidFeatureResearchCost cost; - - public final Set> predecessors = new HashSet<>(); - - protected final Component description; - public boolean with_description = false; - - public SkinElement icon; - - public AndroidFeatureResearchNode(AndroidFeatureType type, AndroidFeatureResearchCost cost) { - this.type = type; - this.cost = cost; - description = new TranslatableComponent("android_feature." + type.getRegistryName().getNamespace() + "." + type.getRegistryName().getPath() + ".description"); - } - - public AndroidFeatureResearchNode(AndroidFeatureType type, AndroidFeatureResearchCost cost, SkinElement icon) { - this(type, cost); - this.icon = icon; - } - - public AndroidFeatureResearchNode addPredecessor(AndroidFeatureType value) { - predecessors.add(value); - return this; - } - - public AndroidFeatureResearchNode withDescription() { - with_description = true; - return this; - } - - public boolean canResearch(Player ply, AndroidCapabilityPlayer cap) { - for (var prec : predecessors) { - if (!cap.hasFeature(prec)) - return false; - } - - return cost.matches(ply); - } - - public void research(Player ply, AndroidCapabilityPlayer cap) { - if (cap.hasFeature(type)) - return; - - if (!canResearch(ply, cap)) - return; - - cost.research(ply); - cap.addFeature(type); - } - - public void researchClient() { - var ply = Minecraft.getInstance().player; - - ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { - if (cap.hasFeature(type)) - return; - - if (!canResearch(ply, (AndroidCapabilityPlayer) cap)) - return; - - MatteryNetworking.CHANNEL.sendToServer(new AndroidResearchRequestPacket(type)); - }); - } - - public Component getDescription() { - return description; - } - - public List getTooltip() { - var list = new ArrayList(); - list.add(type.getDisplayName()); - - if (with_description) { - list.add(getDescription()); - } - - list.addAll(cost.getTooltip()); - - return list; - } - - public List getTooltip(Player ply) { - var list = new ArrayList(); - list.add(type.getDisplayName()); - - if (with_description) { - list.add(getDescription()); - } - - list.addAll(cost.getTooltip(ply)); - - ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { - for (var prec : predecessors) { - if (!cap.hasFeature(prec)) { - list.add(new TranslatableComponent("otm.android_station.research.missing_predecessors", prec.getDisplayName())); - } - } - }); - - return list; - } -} 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 6d9227a09..22484b6a8 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java @@ -14,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.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.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 91bf2c9b7..d716f9d92 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java @@ -12,8 +12,8 @@ import net.minecraft.world.item.*; 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.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.capability.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 5761359ef..8f140c40b 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.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.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/MatteryNetworking.java b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java index 5e5c17899..0871ec2f4 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/MatteryNetworking.java @@ -111,5 +111,14 @@ public class MatteryNetworking { AndroidResearchRequestPacket::play, Optional.of(NetworkDirection.PLAY_TO_SERVER) ); + + CHANNEL.registerMessage( + next_network_id++, + AndroidResearchPacket.class, + AndroidResearchPacket::write, + AndroidResearchPacket::read, + AndroidResearchPacket::play, + Optional.of(NetworkDirection.PLAY_TO_CLIENT) + ); } } 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 index 2dab07af6..c586cd775 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidFeaturePacket.java @@ -2,15 +2,14 @@ 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 ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.android.AndroidFeature; +import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import java.util.Objects; import java.util.function.Supplier; diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchPacket.java new file mode 100644 index 000000000..d2cf51d94 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchPacket.java @@ -0,0 +1,49 @@ +package ru.dbotthepony.mc.otm.network.android; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +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.Registry; +import ru.dbotthepony.mc.otm.android.AndroidResearch; +import ru.dbotthepony.mc.otm.android.AndroidResearchType; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; + +import java.util.function.Supplier; + +public record AndroidResearchPacket(AndroidResearchType type, CompoundTag payload) { + public AndroidResearchPacket(AndroidResearch research) { + this(research.type, research.serializeNBT()); + } + + public void write(FriendlyByteBuf buffer) { + buffer.writeInt(Registry.ANDROID_RESEARCH().getID(type)); + buffer.writeNbt(payload); + } + + public static AndroidResearchPacket read(FriendlyByteBuf buffer) { + return new AndroidResearchPacket(Registry.ANDROID_RESEARCH().getValue(buffer.readInt()), buffer.readNbt()); + } + + 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.getResearch(type).deserializeNBT(payload); + } + }); + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchRequestPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchRequestPacket.java index 847cb8183..1fae6aa6a 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchRequestPacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidResearchRequestPacket.java @@ -1,52 +1,43 @@ package ru.dbotthepony.mc.otm.network.android; -import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; -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.android.AndroidResearch; +import ru.dbotthepony.mc.otm.android.AndroidResearchType; 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 ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import java.util.Objects; import java.util.function.Supplier; -public record AndroidResearchRequestPacket(AndroidFeatureType feature) { - public AndroidResearchRequestPacket(AndroidFeatureType feature) { - this.feature = feature; +public record AndroidResearchRequestPacket(AndroidResearchType research) { + public AndroidResearchRequestPacket(AndroidResearchType research) { + this.research = research; } - public AndroidResearchRequestPacket(AndroidFeature feature) { + public AndroidResearchRequestPacket(AndroidResearch feature) { this(feature.type); } public void write(FriendlyByteBuf buffer) { - buffer.writeInt(Registry.ANDROID_FEATURES().getID(feature)); + buffer.writeInt(Registry.ANDROID_RESEARCH().getID(research)); } public void play(Supplier context) { context.get().setPacketHandled(true); - context.get().enqueueWork(() -> context.get().getSender().getCapability(MatteryCapability.ANDROID).ifPresent(cap -> this.playServer((AndroidCapabilityPlayer) cap, (ServerPlayer) context.get().getSender()))); + context.get().enqueueWork(() -> context.get().getSender().getCapability(MatteryCapability.ANDROID).ifPresent(cap -> this.playServer((AndroidCapabilityPlayer) cap, context.get().getSender()))); } public void playServer(AndroidCapabilityPlayer cap, ServerPlayer ply) { - if (cap.hasFeature(feature)) + if (!cap.isAndroid()) return; - var node = feature.getResearchNode(); - - if (node == null) - return; - - node.research(ply, cap); + cap.getResearch(research).research(); } public static AndroidResearchRequestPacket read(FriendlyByteBuf buffer) { - return new AndroidResearchRequestPacket(Objects.requireNonNull(Registry.ANDROID_FEATURES().getValue(buffer.readInt()))); + return new AndroidResearchRequestPacket(Objects.requireNonNull(Registry.ANDROID_RESEARCH().getValue(buffer.readInt()))); } } 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 index 9418b9697..2c48edb8b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidStatusPacket.java @@ -2,12 +2,11 @@ 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 ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import java.util.function.Supplier; diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java index 16d82415f..d5ad9600d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java @@ -1,39 +1,31 @@ package ru.dbotthepony.mc.otm.screen; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; -import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.android.AndroidResearch; import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; -import ru.dbotthepony.mc.otm.capability.android.AndroidFeatureResearchNode; +import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; import ru.dbotthepony.mc.otm.screen.panels.*; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; public class AndroidStationScreen extends MatteryScreen { - class AndroidFeatureButton extends EditablePanel { + class AndroidResearchButton extends EditablePanel { public static final int BUTTON_SIZE = 16; - private final AndroidFeatureResearchNode node; + private final AndroidResearch node; public static final RGBAColor RESEARCHED = new RGBAColor(150, 150, 200); public static final RGBAColor CAN_BE_RESEARCHED = new RGBAColor(150, 200, 150); public static final RGBAColor CAN_NOT_BE_RESEARCHED = new RGBAColor(200, 150, 150); - public AndroidFeatureButton(@Nullable EditablePanel parent, AndroidFeatureResearchNode node) { + public AndroidResearchButton(@Nullable EditablePanel parent, AndroidResearch node) { super(AndroidStationScreen.this, parent, 0, 0, BUTTON_SIZE, BUTTON_SIZE); this.node = node; setDockMargin(2, 2, 0, 0); @@ -43,9 +35,9 @@ public class AndroidStationScreen extends MatteryScreen { protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) { Minecraft.getInstance().player.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> { if (_cap instanceof AndroidCapabilityPlayer cap) { - if (cap.hasFeature(node.type)) { + if (node.isResearched()) { RenderHelper.setDrawColor(RESEARCHED); - } else if (node.canResearch(Minecraft.getInstance().player, cap)) { + } else if (node.canAfford()) { RenderHelper.setDrawColor(CAN_BE_RESEARCHED); } else { RenderHelper.setDrawColor(CAN_NOT_BE_RESEARCHED); @@ -65,19 +57,15 @@ public class AndroidStationScreen extends MatteryScreen { @Override protected boolean innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) { if (is_hovered) { - var list = new ArrayList<>(node.getTooltip(Minecraft.getInstance().player)); + var list = new ArrayList<>(node.getTooltip()); - Minecraft.getInstance().player.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> { - if (_cap instanceof AndroidCapabilityPlayer cap) { - if (cap.hasFeature(node.type)) { - list.add(new TranslatableComponent("otm.android_station.research.researched").withStyle(ChatFormatting.DARK_AQUA)); - } else if (node.canResearch(Minecraft.getInstance().player, cap)) { - list.add(new TranslatableComponent("otm.android_station.research.can_be_researched").withStyle(ChatFormatting.DARK_GREEN)); - } else { - list.add(new TranslatableComponent("otm.android_station.research.can_not_be_researched").withStyle(ChatFormatting.DARK_RED)); - } - } - }); + if (node.isResearched()) { + list.add(new TranslatableComponent("otm.android_station.research.researched").withStyle(ChatFormatting.DARK_AQUA)); + } else if (node.canAfford()) { + list.add(new TranslatableComponent("otm.android_station.research.can_be_researched").withStyle(ChatFormatting.DARK_GREEN)); + } else { + list.add(new TranslatableComponent("otm.android_station.research.can_not_be_researched").withStyle(ChatFormatting.DARK_RED)); + } renderComponentTooltip(stack, list, (int) mouse_x, (int) mouse_y); } @@ -99,16 +87,19 @@ public class AndroidStationScreen extends MatteryScreen { @Override protected FramePanel makeMainFrame() { var frame = new FramePanel(this, null, 0, 0, FRAME_WIDTH, FRAME_HEIGHT, getTitle()); - var grid = new GridPanel(this, frame, 0, 0, GRID_WIDTH * 18, 0, GRID_WIDTH, GRID_HEIGHT); - for (var feature : Registry.ANDROID_FEATURES().getValues()) { - var node = feature.getResearchNode(); + minecraft.player.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> { + if (_cap instanceof AndroidCapabilityPlayer cap) { + for (var feature : Registry.ANDROID_RESEARCH().getValues()) { + var node = cap.getResearch(feature); - if (node != null) { - new AndroidFeatureButton(grid, node); + if (node != null) { + new AndroidResearchButton(grid, node); + } + } } - } + }); grid.setDocking(Dock.RIGHT); diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index 734b91266..dbf4d12aa 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -44,7 +44,8 @@ "otm.android_station.research.missing_predecessors": "%s needs to be researched first", "android_feature.overdrive_that_matters.air_bags": "Air bags", - "android_feature.overdrive_that_matters.air_bags.description": "Allows to swim in water", + "android_research.overdrive_that_matters.air_bags": "Air bags", + "android_research.overdrive_that_matters.air_bags.description": "Allows unit to swim in water", "otm.suffix.merge": "%s %s",