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 b84063074..068e5d20b 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 @@ -311,8 +311,19 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } + protected void tickInnerClientAlways() { + + } + @Override public void tickClient() { + delayed_tick_server.clear(); + + if (!ent.isAlive()) + return; + + tickInnerClientAlways(); + if (isAndroid()) { tickInnerClient(); @@ -320,12 +331,15 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit feature.tickClient(); } } - - delayed_tick_server.clear(); } @Override public void tick() { + if (!ent.isAlive()) + return; + + tickServerAlways(); + if (isAndroid()) { tickServer(); @@ -339,10 +353,13 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } delayed_tick_server.clear(); - tickNetwork(); } + protected void tickServerAlways() { + + } + 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 8beab9c31..bf1ba8065 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,10 +1,13 @@ package ru.dbotthepony.mc.otm.capability.android; +import net.minecraft.ChatFormatting; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.common.util.LazyOptional; @@ -30,12 +33,16 @@ public class AndroidCapabilityPlayer extends AndroidCapability { public boolean is_android = false; private boolean network_is_android = false; + public boolean will_become_android = false; + private boolean network_will_become_android = false; + private final ArrayList research_list = new ArrayList<>(); @Override public void invalidateNetworkState() { super.invalidateNetworkState(); network_is_android = false; + network_will_become_android = false; for (var instance : research_list) { instance.dirty = true; @@ -47,28 +54,62 @@ public class AndroidCapabilityPlayer extends AndroidCapability { return is_android; } + public boolean isEverAndroid() { + return is_android || will_become_android; + } + + public void becomeAndroidSoft() { + if (is_android || will_become_android) + return; + + will_become_android = true; + + if (ent instanceof ServerPlayer ply) { + ply.displayClientMessage(new TranslatableComponent("otm.pill.message").withStyle(ChatFormatting.GRAY), false); + } + } + public void becomeAndroid() { if (is_android) return; is_android = true; + will_become_android = false; energy_stored = new BigDecimal(60_000); energy_stored_max = new BigDecimal(60_000); + } + public void becomeAndroidAndKill() { + if (is_android) + return; + + becomeAndroid(); ply.hurt(Registry.DAMAGE_BECOME_ANDROID, ply.getMaxHealth() * 2); } public void becomeHumane() { + if (will_become_android) + will_become_android = false; + if (!is_android) return; is_android = false; energy_stored = new BigDecimal(0); - energy_stored_max = new BigDecimal(32_000); + energy_stored_max = new BigDecimal(60_000); dropBattery(); + } + public void becomeHumaneAndKill() { + if (will_become_android) + will_become_android = false; + + if (!is_android) + return; + + becomeHumane(); ply.hurt(Registry.DAMAGE_BECOME_HUMANE, ply.getMaxHealth() * 2); } @@ -76,8 +117,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability { public void deserializeNBT(CompoundTag compound) { super.deserializeNBT(compound); - if (compound.contains("is_android")) - is_android = compound.getByte("is_android") > 0; + is_android = compound.getBoolean("is_android"); + will_become_android = compound.getBoolean("will_become_android"); research_list.clear(); @@ -100,7 +141,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability { @Override public CompoundTag serializeNBT() { CompoundTag tag = super.serializeNBT(); - tag.putByte("is_android", is_android ? (byte) 1 : 0); + tag.putBoolean("is_android", is_android); + tag.putBoolean("will_become_android", will_become_android); var list = new ListTag(); @@ -130,6 +172,7 @@ public class AndroidCapabilityPlayer extends AndroidCapability { } @SubscribeEvent + @SuppressWarnings("unused") public static void onAttachCapabilityEvent(AttachCapabilitiesEvent event) { if (event.getObject() instanceof Player ply) { event.addCapability(Registry.Names.ANDROID_CAPABILITY, new AndroidCapabilityPlayer(ply)); @@ -137,11 +180,13 @@ public class AndroidCapabilityPlayer extends AndroidCapability { } @SubscribeEvent + @SuppressWarnings("unused") public static void onPlayerChangeDimensionEvent(PlayerEvent.PlayerChangedDimensionEvent event) { event.getPlayer().getCapability(MatteryCapability.ANDROID).ifPresent(IAndroidCapability::invalidateNetworkState); } @SubscribeEvent + @SuppressWarnings("unused") public static void onPlayerCloneEvent(PlayerEvent.Clone event) { event.getPlayer().getCapability(MatteryCapability.ANDROID).ifPresent((cap) -> { LazyOptional resolver = event.getOriginal().getCapability(MatteryCapability.ANDROID); @@ -156,7 +201,17 @@ public class AndroidCapabilityPlayer extends AndroidCapability { return; } - cap.deserializeNBT(resolver.resolve().get().serializeNBT()); + var original = (AndroidCapabilityPlayer) resolver.resolve().get(); + + if (original.will_become_android && event.isWasDeath()) { + original.becomeAndroid(); + + if (event.getPlayer() instanceof ServerPlayer ply) { + ply.displayClientMessage(new TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false); + } + } + + cap.deserializeNBT(original.serializeNBT()); cap.invalidateNetworkState(); event.getOriginal().invalidateCaps(); }); @@ -176,7 +231,12 @@ public class AndroidCapabilityPlayer extends AndroidCapability { if (is_android != network_is_android) { network_is_android = is_android; - sendNetwork(new AndroidStatusPacket(is_android)); + sendNetwork(new AndroidStatusPacket(AndroidStatusPacket.Type.IS_ANDROID, is_android)); + } + + if (will_become_android != network_will_become_android) { + network_will_become_android = will_become_android; + sendNetwork(new AndroidStatusPacket(AndroidStatusPacket.Type.WILL_BECOME_ANDROID, will_become_android)); } for (var instance : research_list) { @@ -189,6 +249,30 @@ public class AndroidCapabilityPlayer extends AndroidCapability { public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(1000); + private int sleep_ticks = 0; + + @Override + protected void tickServerAlways() { + super.tickServerAlways(); + + if (will_become_android) { + if (ent.isSleeping()) { + sleep_ticks++; + + if (sleep_ticks > 40) { + becomeAndroid(); + sleep_ticks = 0; + + if (ent instanceof ServerPlayer ply) { + ply.displayClientMessage(new TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false); + } + } + } else { + sleep_ticks = 0; + } + } + } + @Override public void tickServer() { super.tickServer(); 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..fc80b631e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPill.java @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.item; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.server.level.ServerPlayer; @@ -17,9 +18,12 @@ import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; import java.util.Optional; +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class ItemPill extends Item { public enum PillType { BECOME_ANDROID, @@ -42,12 +46,12 @@ public class ItemPill extends Item { public void appendHoverText(ItemStack p_41421_, @Nullable Level p_41422_, List p_41423_, TooltipFlag p_41424_) { super.appendHoverText(p_41421_, p_41422_, p_41423_, p_41424_); - if (this.pill_type == PillType.BECOME_ANDROID) + if (this.pill_type == PillType.BECOME_ANDROID) { p_41423_.add(new TranslatableComponent("otm.pill.android").withStyle(ChatFormatting.GRAY)); - else + } else { p_41423_.add(new TranslatableComponent("otm.pill.humane").withStyle(ChatFormatting.GRAY)); - - p_41423_.add(new TranslatableComponent("otm.pill.warning").withStyle(ChatFormatting.RED)); + p_41423_.add(new TranslatableComponent("otm.pill.warning").withStyle(ChatFormatting.RED)); + } } @Override @@ -60,7 +64,7 @@ public class ItemPill extends Item { if (resolver.isEmpty() || !(resolver.get() instanceof AndroidCapabilityPlayer)) return super.use(level, ply, hand); - if (this.pill_type == PillType.BECOME_ANDROID && !resolver.get().isAndroid() || this.pill_type == PillType.BECOME_HUMANE && resolver.get().isAndroid()) { + if (this.pill_type == PillType.BECOME_ANDROID && !((AndroidCapabilityPlayer) resolver.get()).isEverAndroid() || this.pill_type == PillType.BECOME_HUMANE && ((AndroidCapabilityPlayer) resolver.get()).isEverAndroid()) { ply.startUsingItem(hand); return InteractionResultHolder.consume(ply.getItemInHand(hand)); } @@ -79,16 +83,16 @@ public class ItemPill extends Item { if (resolver.isEmpty() || !(resolver.get() instanceof AndroidCapabilityPlayer)) return super.finishUsingItem(stack, level, ply); - if (this.pill_type == PillType.BECOME_ANDROID && !resolver.get().isAndroid()) { + if (this.pill_type == PillType.BECOME_ANDROID && !((AndroidCapabilityPlayer) resolver.get()).isEverAndroid()) { stack.shrink(1); if (ply instanceof ServerPlayer) - ((AndroidCapabilityPlayer) resolver.get()).becomeAndroid(); + ((AndroidCapabilityPlayer) resolver.get()).becomeAndroidSoft(); } else if (this.pill_type == PillType.BECOME_HUMANE && resolver.get().isAndroid()) { stack.shrink(1); if (ply instanceof ServerPlayer) - ((AndroidCapabilityPlayer) resolver.get()).becomeHumane(); + ((AndroidCapabilityPlayer) resolver.get()).becomeHumaneAndKill(); } return stack; 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 ce714ddd5..15ba5eb12 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 @@ -10,8 +10,14 @@ import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; import java.util.function.Supplier; -public record AndroidStatusPacket(boolean status) { +public record AndroidStatusPacket(Type type, boolean status) { + public enum Type { + IS_ANDROID, + WILL_BECOME_ANDROID, + } + public void write(FriendlyByteBuf buffer) { + buffer.writeByte(type.ordinal()); buffer.writeBoolean(status); } @@ -28,13 +34,16 @@ public record AndroidStatusPacket(boolean status) { if (ply != null) { ply.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> { if (cap instanceof AndroidCapabilityPlayer pcap) { - pcap.is_android = status; + if (type == Type.IS_ANDROID) + pcap.is_android = status; + else if (type == Type.WILL_BECOME_ANDROID) + pcap.will_become_android = status; } }); } } public static AndroidStatusPacket read(FriendlyByteBuf buffer) { - return new AndroidStatusPacket(buffer.readBoolean()); + return new AndroidStatusPacket(Type.values()[buffer.readByte()], buffer.readBoolean()); } } 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 dd7f51f32..ce8ed0db4 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 @@ -1,9 +1,12 @@ { "itemGroup.otm": "Overdrive That Matters", - "otm.pill.warning": "WARNING: This will INSTANTLY kill you upon ingestion!", + "otm.pill.warning": "WARNING: This will INSTANTLY decommission you upon ingestion!", "otm.pill.android": "Take this pill and lose what is holding you back.", "otm.pill.humane": "Take this pill and wake up in bed none the wiser.", + "otm.pill.message": "You feel exhausted, but nothing happens?.. Maybe get a bed rest.", + "otm.pill.message_finish": "§kONE OF US ONE OF US ONE OF US ONE OF US ONE OF US", + "otm.gui.power.percentage_level": "Energy level: %s%%", "otm.gui.level": "%s / %s", "otm.gui.power.name": "MtE", @@ -126,7 +129,7 @@ "otm.suffix.yocto": "%s y%s", "death.attack.otm_become_android": "%1$s lost their humanity", - "death.attack.otm_become_humane": "%1$s gained their humanity", + "death.attack.otm_become_humane": "%1$s regained their humanity", "death.attack.otm_event_horizon": "%1$s never crossed event horizon", "death.attack.otm_hawking_radiation": "%1$s discovered Hawking radiation",