Android networking reworked
This commit is contained in:
parent
20425015ea
commit
2f6f40d5f4
@ -21,7 +21,7 @@ import ru.dbotthepony.mc.otm.capability.android.AndroidCapability;
|
|||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.DrivePool;
|
import ru.dbotthepony.mc.otm.capability.drive.DrivePool;
|
||||||
import ru.dbotthepony.mc.otm.client.AndroidGui;
|
import ru.dbotthepony.mc.otm.client.AndroidGui;
|
||||||
import ru.dbotthepony.mc.otm.client.EventHandler;
|
import ru.dbotthepony.mc.otm.client.EventHandlerKt;
|
||||||
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
|
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
|
||||||
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
||||||
@ -31,6 +31,7 @@ import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
|
|||||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistryKt;
|
import ru.dbotthepony.mc.otm.matter.MatterRegistryKt;
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidNetworkChannel;
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
||||||
import ru.dbotthepony.mc.otm.registry.*;
|
import ru.dbotthepony.mc.otm.registry.*;
|
||||||
import ru.dbotthepony.mc.otm.storage.*;
|
import ru.dbotthepony.mc.otm.storage.*;
|
||||||
@ -108,6 +109,8 @@ public final class OverdriveThatMatters {
|
|||||||
AndroidFeatureType.Companion.markRegistryLoaded();
|
AndroidFeatureType.Companion.markRegistryLoaded();
|
||||||
|
|
||||||
MatteryNetworking.register();
|
MatteryNetworking.register();
|
||||||
|
AndroidNetworkChannel.INSTANCE.register();
|
||||||
|
|
||||||
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
||||||
|
|
||||||
if (ModList.get().isLoaded("mekanism")) {
|
if (ModList.get().isLoaded("mekanism")) {
|
||||||
@ -120,7 +123,7 @@ public final class OverdriveThatMatters {
|
|||||||
ANDROID_GUI = new AndroidGui();
|
ANDROID_GUI = new AndroidGui();
|
||||||
MinecraftForge.EVENT_BUS.register(ANDROID_GUI);
|
MinecraftForge.EVENT_BUS.register(ANDROID_GUI);
|
||||||
MinecraftForge.EVENT_BUS.register(AndroidGui.class);
|
MinecraftForge.EVENT_BUS.register(AndroidGui.class);
|
||||||
MinecraftForge.EVENT_BUS.register(EventHandler.class);
|
MinecraftForge.EVENT_BUS.register(EventHandlerKt.class);
|
||||||
|
|
||||||
TritaniumArmorModel.register();
|
TritaniumArmorModel.register();
|
||||||
GravitationStabilizerModel.register();
|
GravitationStabilizerModel.register();
|
||||||
|
@ -71,7 +71,7 @@ public class AndroidGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mc.player.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> {
|
mc.player.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> {
|
||||||
if (!((AndroidCapabilityPlayer) cap).willBecomeAndroid) {
|
if (!((AndroidCapabilityPlayer) cap).getWillBecomeAndroid()) {
|
||||||
known_button.x = known_button_x;
|
known_button.x = known_button_x;
|
||||||
known_button.y = known_button_y;
|
known_button.y = known_button_y;
|
||||||
known_button_x = -1;
|
known_button_x = -1;
|
||||||
@ -81,7 +81,7 @@ public class AndroidGui {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dispersion = (int) ((10.0 * Math.max(0, ((AndroidCapabilityPlayer) cap).sleep_ticks - 20)) / (AndroidCapabilityPlayer.SLEEP_TICKS_LIMIT - 20));
|
int dispersion = (int) ((10.0 * Math.max(0, ((AndroidCapabilityPlayer) cap).getSleepTicks() - 20)) / (AndroidCapabilityPlayer.SLEEP_TICKS_LIMIT - 20));
|
||||||
|
|
||||||
known_button.x = known_button_x - dispersion / 2 + (int) (button_shaker.nextDouble() * dispersion);
|
known_button.x = known_button_x - dispersion / 2 + (int) (button_shaker.nextDouble() * dispersion);
|
||||||
known_button.y = known_button_y - dispersion / 2 + (int) (button_shaker.nextDouble() * dispersion);
|
known_button.y = known_button_y - dispersion / 2 + (int) (button_shaker.nextDouble() * dispersion);
|
||||||
@ -110,7 +110,7 @@ public class AndroidGui {
|
|||||||
known_button_screen = screen;
|
known_button_screen = screen;
|
||||||
|
|
||||||
mc.player.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> {
|
mc.player.getCapability(MatteryCapability.ANDROID).ifPresent(cap -> {
|
||||||
if (((AndroidCapabilityPlayer) cap).willBecomeAndroid) {
|
if (((AndroidCapabilityPlayer) cap).getWillBecomeAndroid()) {
|
||||||
known_button_screen = screen;
|
known_button_screen = screen;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client;
|
|
||||||
|
|
||||||
import net.minecraftforge.client.event.MovementInputUpdateEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures;
|
|
||||||
|
|
||||||
public class EventHandler {
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void inputEvent(MovementInputUpdateEvent event) {
|
|
||||||
var ply = event.getPlayer();
|
|
||||||
var input = event.getInput();
|
|
||||||
|
|
||||||
ply.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> {
|
|
||||||
if (!(_cap instanceof AndroidCapabilityPlayer cap))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cap.hasFeature(AndroidFeatures.INSTANCE.getAIR_BAGS()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ply.getAbilities().mayfly) {
|
|
||||||
cap.last_jump_ticks = 14;
|
|
||||||
} else {
|
|
||||||
if (ply.isInWater()) {
|
|
||||||
if (ply.isOnGround()) {
|
|
||||||
cap.last_jump_ticks = 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ply.isSwimming()) {
|
|
||||||
ply.setSwimming(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cap.last_jump_ticks <= 0) {
|
|
||||||
event.getInput().jumping = false;
|
|
||||||
event.getInput().up = false;
|
|
||||||
} else {
|
|
||||||
cap.last_jump_ticks--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,12 +16,10 @@ import ru.dbotthepony.mc.otm.matter.RegistryPacketClear;
|
|||||||
import ru.dbotthepony.mc.otm.matter.RegistryPacketFullUpdate;
|
import ru.dbotthepony.mc.otm.matter.RegistryPacketFullUpdate;
|
||||||
import ru.dbotthepony.mc.otm.matter.RegistryPacketRemove;
|
import ru.dbotthepony.mc.otm.matter.RegistryPacketRemove;
|
||||||
import ru.dbotthepony.mc.otm.matter.RegistryPacketUpdate;
|
import ru.dbotthepony.mc.otm.matter.RegistryPacketUpdate;
|
||||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu;
|
|
||||||
import ru.dbotthepony.mc.otm.menu.data.*;
|
import ru.dbotthepony.mc.otm.menu.data.*;
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket;
|
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket;
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket;
|
import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket;
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket;
|
import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket;
|
||||||
import ru.dbotthepony.mc.otm.network.android.*;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -54,42 +52,6 @@ public class MatteryNetworking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
CHANNEL.registerMessage(
|
|
||||||
next_network_id++,
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
|
|
||||||
CHANNEL.registerMessage(
|
CHANNEL.registerMessage(
|
||||||
next_network_id++,
|
next_network_id++,
|
||||||
PatternGridPacket.class,
|
PatternGridPacket.class,
|
||||||
@ -162,24 +124,6 @@ public class MatteryNetworking {
|
|||||||
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
|
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
|
||||||
);
|
);
|
||||||
|
|
||||||
CHANNEL.registerMessage(
|
|
||||||
next_network_id++,
|
|
||||||
AndroidResearchRequestPacket.class,
|
|
||||||
AndroidResearchRequestPacket::write,
|
|
||||||
AndroidResearchRequestPacket::read,
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
|
|
||||||
CHANNEL.registerMessage(
|
CHANNEL.registerMessage(
|
||||||
next_network_id++,
|
next_network_id++,
|
||||||
ClearPacket.class,
|
ClearPacket.class,
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
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.network.NetworkEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidBatteryPacket(ItemStack battery) {
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeItem(battery);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> 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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
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.network.NetworkEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidEnergyPacket(boolean is_maximal, ImpreciseFraction energy) {
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeBoolean(is_maximal);
|
|
||||||
energy.write(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> 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(), ImpreciseFraction.read(buffer));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
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.network.NetworkEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature;
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidFeaturePacket(boolean is_added, AndroidFeatureType<?> feature) {
|
|
||||||
public AndroidFeaturePacket(boolean is_added, AndroidFeature feature) {
|
|
||||||
this(is_added, feature.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeBoolean(is_added);
|
|
||||||
buffer.writeInt(MRegistry.INSTANCE.getANDROID_FEATURES().getID(feature));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> 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(MRegistry.INSTANCE.getANDROID_FEATURES().getValue(buffer.readInt()));
|
|
||||||
|
|
||||||
return new AndroidFeaturePacket(is_added, feature);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
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.network.NetworkEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearch;
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidResearchPacket(AndroidResearchType<?> type, CompoundTag payload) {
|
|
||||||
public AndroidResearchPacket(AndroidResearch research) {
|
|
||||||
this(research.getType(), research.serializeNBT());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeInt(MRegistry.INSTANCE.getANDROID_RESEARCH().getID(type));
|
|
||||||
buffer.writeNbt(payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AndroidResearchPacket read(FriendlyByteBuf buffer) {
|
|
||||||
return new AndroidResearchPacket(MRegistry.INSTANCE.getANDROID_RESEARCH().getValue(buffer.readInt()), buffer.readNbt());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.network.android;
|
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
|
||||||
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.menu.AndroidStationMenu;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidResearchRequestPacket(AndroidResearchType<?> research) {
|
|
||||||
public AndroidResearchRequestPacket(AndroidResearchType<?> research) {
|
|
||||||
this.research = research;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidResearchRequestPacket(AndroidResearch feature) {
|
|
||||||
this(feature.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeInt(MRegistry.INSTANCE.getANDROID_RESEARCH().getID(research));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> context) {
|
|
||||||
context.get().setPacketHandled(true);
|
|
||||||
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.isAndroid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ply.containerMenu instanceof AndroidStationMenu)
|
|
||||||
cap.getResearch(research).research(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AndroidResearchRequestPacket read(FriendlyByteBuf buffer) {
|
|
||||||
return new AndroidResearchRequestPacket(Objects.requireNonNull(MRegistry.INSTANCE.getANDROID_RESEARCH().getValue(buffer.readInt())));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.network.android;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.sounds.SoundSource;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public record AndroidStatusPacket(Type type, boolean status, boolean playSound) {
|
|
||||||
public enum Type {
|
|
||||||
IS_ANDROID,
|
|
||||||
WILL_BECOME_ANDROID,
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeByte(type.ordinal());
|
|
||||||
buffer.writeBoolean(status);
|
|
||||||
buffer.writeBoolean(playSound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play(Supplier<NetworkEvent.Context> 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) {
|
|
||||||
if (type == Type.IS_ANDROID)
|
|
||||||
pcap.isAndroid = status;
|
|
||||||
else if (type == Type.WILL_BECOME_ANDROID)
|
|
||||||
pcap.willBecomeAndroid = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playSound) {
|
|
||||||
ply.level.playSound(ply, ply, MSoundEvents.INSTANCE.getPLAYER_BECOME_ANDROID(), SoundSource.PLAYERS, 1f, 1f);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AndroidStatusPacket read(FriendlyByteBuf buffer) {
|
|
||||||
return new AndroidStatusPacket(Type.values()[buffer.readByte()], buffer.readBoolean(), buffer.readBoolean());
|
|
||||||
}
|
|
||||||
}
|
|
37
src/main/kotlin/ru/dbotthepony/mc/otm/FriendlyStreams.kt
Normal file
37
src/main/kotlin/ru/dbotthepony/mc/otm/FriendlyStreams.kt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package ru.dbotthepony.mc.otm
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufInputStream
|
||||||
|
import io.netty.handler.codec.EncoderException
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.NbtAccounter
|
||||||
|
import net.minecraft.nbt.NbtIo
|
||||||
|
import java.io.DataInputStream
|
||||||
|
import java.io.DataOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
// But seriously, Mojang, why would you need to derive from ByteBuf directly, when you can implement
|
||||||
|
// your own InputStream and OutputStream, since ByteBuf is meant to be operated on most time like a stream anyway?
|
||||||
|
|
||||||
|
// netty ByteBuf -> netty ByteBufInputStream -> Minecraft FriendlyInputStream
|
||||||
|
|
||||||
|
fun <T : OutputStream> T.writeNbt(value: CompoundTag): T {
|
||||||
|
try {
|
||||||
|
NbtIo.write(value, if (this is DataOutputStream) this else DataOutputStream(this))
|
||||||
|
} catch (ioexception: IOException) {
|
||||||
|
throw EncoderException(ioexception)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : InputStream> T.readNbt(accounter: NbtAccounter = NbtAccounter.UNLIMITED): CompoundTag {
|
||||||
|
return try {
|
||||||
|
NbtIo.read(if (this is DataInputStream) this else DataInputStream(this), accounter)
|
||||||
|
} catch (ioexception: IOException) {
|
||||||
|
throw EncoderException(ioexception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,11 +4,20 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||||
|
import ru.dbotthepony.mc.otm.readNbt
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
import ru.dbotthepony.mc.otm.writeNbt
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: AndroidCapability) : INBTSerializable<CompoundTag> {
|
abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: AndroidCapability) : INBTSerializable<CompoundTag> {
|
||||||
val entity get() = android.entity
|
val entity get() = android.entity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whenever there are changes to network
|
||||||
|
*/
|
||||||
|
var isDirty = false
|
||||||
|
|
||||||
open var level = 0
|
open var level = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value != field) {
|
if (value != field) {
|
||||||
@ -30,6 +39,14 @@ abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: Andr
|
|||||||
|
|
||||||
open fun onHurt(event: LivingHurtEvent) {}
|
open fun onHurt(event: LivingHurtEvent) {}
|
||||||
|
|
||||||
|
open fun writeNetwork(stream: OutputStream) {
|
||||||
|
stream.writeNbt(serializeNBT())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun readNetwork(stream: InputStream) {
|
||||||
|
deserializeNBT(stream.readNbt())
|
||||||
|
}
|
||||||
|
|
||||||
override fun serializeNBT(): CompoundTag {
|
override fun serializeNBT(): CompoundTag {
|
||||||
return CompoundTag().also {
|
return CompoundTag().also {
|
||||||
it["level"] = level
|
it["level"] = level
|
||||||
|
@ -3,20 +3,33 @@ package ru.dbotthepony.mc.otm.android
|
|||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
||||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.readNbt
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
import ru.dbotthepony.mc.otm.writeNbt
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability: AndroidCapabilityPlayer) : INBTSerializable<CompoundTag> {
|
abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability: AndroidCapabilityPlayer) : INBTSerializable<CompoundTag> {
|
||||||
var isResearched = false
|
var isResearched = false
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whenever there are changes to network
|
||||||
|
*/
|
||||||
var isDirty = false
|
var isDirty = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when it is required to network everything again
|
||||||
|
*/
|
||||||
|
abstract fun invalidateNetwork()
|
||||||
|
|
||||||
fun unResearch() {
|
fun unResearch() {
|
||||||
if (!isResearched) {
|
if (!isResearched) {
|
||||||
return
|
return
|
||||||
@ -46,6 +59,14 @@ abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability:
|
|||||||
*/
|
*/
|
||||||
abstract fun refund(simulate: Boolean): Boolean
|
abstract fun refund(simulate: Boolean): Boolean
|
||||||
|
|
||||||
|
open fun writeNetwork(buff: OutputStream) {
|
||||||
|
buff.writeNbt(serializeNBT())
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun readNetwork(buff: InputStream) {
|
||||||
|
deserializeNBT(buff.readNbt())
|
||||||
|
}
|
||||||
|
|
||||||
open val canResearch: Boolean get() {
|
open val canResearch: Boolean get() {
|
||||||
if (!consumeResearchCost(simulate = true)) {
|
if (!consumeResearchCost(simulate = true)) {
|
||||||
return false
|
return false
|
||||||
|
@ -174,6 +174,10 @@ class AndroidResearchBuilder(
|
|||||||
|
|
||||||
return object : AndroidResearchType<AndroidResearch>(factory@{ it, capability ->
|
return object : AndroidResearchType<AndroidResearch>(factory@{ it, capability ->
|
||||||
return@factory object : AndroidResearch(it, capability) {
|
return@factory object : AndroidResearch(it, capability) {
|
||||||
|
override fun invalidateNetwork() {
|
||||||
|
// NO-OP
|
||||||
|
}
|
||||||
|
|
||||||
override fun onUnResearch() {
|
override fun onUnResearch() {
|
||||||
for (feature in features) {
|
for (feature in features) {
|
||||||
val level = oldResearchLevel[feature.feature]
|
val level = oldResearchLevel[feature.feature]
|
||||||
|
@ -31,7 +31,7 @@ class AndroidStationBlock : MatteryBlock(), EntityBlock {
|
|||||||
): InteractionResult {
|
): InteractionResult {
|
||||||
val cap = ply.getCapability(MatteryCapability.ANDROID).orNull() ?: return InteractionResult.FAIL
|
val cap = ply.getCapability(MatteryCapability.ANDROID).orNull() ?: return InteractionResult.FAIL
|
||||||
|
|
||||||
if (!cap.isAndroid())
|
if (!cap.isAndroid)
|
||||||
return InteractionResult.FAIL
|
return InteractionResult.FAIL
|
||||||
|
|
||||||
return super.use(blockState, level, blockPos, ply, hand, blockHitResult)
|
return super.use(blockState, level, blockPos, ply, hand, blockHitResult)
|
||||||
|
@ -39,7 +39,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
for (ent in level.getEntitiesOfClass(LivingEntity::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0))) {
|
for (ent in level.getEntitiesOfClass(LivingEntity::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0))) {
|
||||||
ent.getCapability(MatteryCapability.ANDROID).ifPresent {
|
ent.getCapability(MatteryCapability.ANDROID).ifPresent {
|
||||||
if (!it.isAndroid())
|
if (!it.isAndroid)
|
||||||
return@ifPresent
|
return@ifPresent
|
||||||
|
|
||||||
val missing = it.missingPower
|
val missing = it.missingPower
|
||||||
|
@ -12,15 +12,12 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
|||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import java.lang.Runnable
|
import java.lang.Runnable
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidFeaturePacket
|
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import net.minecraftforge.network.PacketDistributor
|
import net.minecraftforge.network.PacketDistributor
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket
|
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket
|
|
||||||
import net.minecraft.world.effect.MobEffect
|
import net.minecraft.world.effect.MobEffect
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import net.minecraftforge.energy.CapabilityEnergy
|
import net.minecraftforge.energy.CapabilityEnergy
|
||||||
@ -37,6 +34,10 @@ import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
|||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
import ru.dbotthepony.mc.otm.ifPresentK
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidFeatureRemovePacket
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidFeatureSyncPacket
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidNetworkChannel
|
||||||
|
import ru.dbotthepony.mc.otm.orNull
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
@ -48,14 +49,10 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
override var batteryItemStack: ItemStack = ItemStack.EMPTY
|
override var batteryItemStack: ItemStack = ItemStack.EMPTY
|
||||||
|
|
||||||
private var remoteBattery = ImpreciseFraction(-1)
|
|
||||||
private var remoteMaxBattery = ImpreciseFraction(-1)
|
|
||||||
private var remoteBatteryStack = ItemStack.EMPTY
|
|
||||||
|
|
||||||
protected val features = Object2ObjectArrayMap<AndroidFeatureType<*>, AndroidFeature>()
|
protected val features = Object2ObjectArrayMap<AndroidFeatureType<*>, AndroidFeature>()
|
||||||
protected val networkQueue = ArrayList<Any>()
|
protected val networkQueue = ArrayList<Any>()
|
||||||
protected val queuedTicks = ArrayList<Runnable>()
|
protected val queuedTicks = ArrayList<Runnable>()
|
||||||
protected var networkTickedOnce = false
|
protected var tickedOnce = false
|
||||||
|
|
||||||
protected fun addFeature(feature: AndroidFeature): Boolean {
|
protected fun addFeature(feature: AndroidFeature): Boolean {
|
||||||
if (features.containsKey(feature.type)) return false
|
if (features.containsKey(feature.type)) return false
|
||||||
@ -66,7 +63,7 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
if (entity is ServerPlayer) {
|
||||||
sendNetwork(AndroidFeaturePacket(true, feature))
|
sendNetwork(AndroidFeatureSyncPacket(feature))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -86,7 +83,7 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
if (entity is ServerPlayer) {
|
||||||
sendNetwork(AndroidFeaturePacket(true, factory))
|
sendNetwork(AndroidFeatureSyncPacket(factory))
|
||||||
}
|
}
|
||||||
|
|
||||||
return factory
|
return factory
|
||||||
@ -103,7 +100,7 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
if (entity is ServerPlayer) {
|
||||||
sendNetwork(AndroidFeaturePacket(false, removed))
|
sendNetwork(AndroidFeatureRemovePacket(removed.type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,27 +121,6 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
return features[feature] as T?
|
return features[feature] as T?
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidateNetworkState() {
|
|
||||||
remoteBattery = ImpreciseFraction.MINUS_ONE
|
|
||||||
remoteMaxBattery = ImpreciseFraction.MINUS_ONE
|
|
||||||
remoteBatteryStack = ItemStack.EMPTY
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
for (feature in features.values) {
|
|
||||||
sendNetwork(AndroidFeaturePacket(true, feature))
|
|
||||||
feature.invalidateNetwork()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setEnergy(value: ImpreciseFraction) {
|
|
||||||
battery = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setMaxEnergy(value: ImpreciseFraction) {
|
|
||||||
maxBattery = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onHurt(event: LivingHurtEvent) {
|
override fun onHurt(event: LivingHurtEvent) {
|
||||||
for (feature in features.values) {
|
for (feature in features.values) {
|
||||||
feature.onHurt(event)
|
feature.onHurt(event)
|
||||||
@ -216,43 +192,14 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
protected fun sendNetwork(packet: Any) {
|
protected fun sendNetwork(packet: Any) {
|
||||||
if (entity is ServerPlayer) {
|
if (entity is ServerPlayer) {
|
||||||
if (networkTickedOnce) {
|
if (tickedOnce) {
|
||||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { entity }, packet)
|
AndroidNetworkChannel.send(entity, packet)
|
||||||
} else {
|
} else {
|
||||||
networkQueue.add(packet)
|
networkQueue.add(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun tickNetwork() {
|
|
||||||
networkTickedOnce = true
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
if (battery != remoteBattery) {
|
|
||||||
remoteBattery = battery
|
|
||||||
sendNetwork(AndroidEnergyPacket(false, battery))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxBattery != remoteMaxBattery) {
|
|
||||||
remoteMaxBattery = maxBattery
|
|
||||||
sendNetwork(AndroidEnergyPacket(true, maxBattery))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!remoteBatteryStack.equals(batteryItemStack, false)) {
|
|
||||||
remoteBatteryStack = batteryItemStack.copy()
|
|
||||||
sendNetwork(AndroidBatteryPacket(batteryItemStack))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (networkQueue.size != 0) {
|
|
||||||
for (packet in networkQueue) {
|
|
||||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { entity }, packet)
|
|
||||||
}
|
|
||||||
|
|
||||||
networkQueue.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun tickInnerClient() {}
|
protected open fun tickInnerClient() {}
|
||||||
protected open fun tickInnerClientAlways() {}
|
protected open fun tickInnerClientAlways() {}
|
||||||
|
|
||||||
@ -264,7 +211,7 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
tickInnerClientAlways()
|
tickInnerClientAlways()
|
||||||
|
|
||||||
if (isAndroid()) {
|
if (isAndroid) {
|
||||||
tickInnerClient()
|
tickInnerClient()
|
||||||
|
|
||||||
for (feature in features.values) {
|
for (feature in features.values) {
|
||||||
@ -278,7 +225,7 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
tickServerAlways()
|
tickServerAlways()
|
||||||
|
|
||||||
if (isAndroid()) {
|
if (isAndroid) {
|
||||||
tickServer()
|
tickServer()
|
||||||
|
|
||||||
for (feature in features.values) {
|
for (feature in features.values) {
|
||||||
@ -291,7 +238,6 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
}
|
}
|
||||||
|
|
||||||
queuedTicks.clear()
|
queuedTicks.clear()
|
||||||
tickNetwork()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun tickServerAlways() {}
|
protected open fun tickServerAlways() {}
|
||||||
@ -396,7 +342,8 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
return receiveEnergyOuter(howMuch, simulate)
|
return receiveEnergyOuter(howMuch, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val batteryLevel: ImpreciseFraction get() {
|
override var batteryLevel: ImpreciseFraction
|
||||||
|
get() {
|
||||||
if (!batteryItemStack.isEmpty) {
|
if (!batteryItemStack.isEmpty) {
|
||||||
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
||||||
|
|
||||||
@ -413,8 +360,12 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
return battery
|
return battery
|
||||||
}
|
}
|
||||||
|
set(value) {
|
||||||
|
maxBattery = value
|
||||||
|
}
|
||||||
|
|
||||||
override val maxBatteryLevel: ImpreciseFraction get() {
|
override var maxBatteryLevel: ImpreciseFraction
|
||||||
|
get() {
|
||||||
if (batteryItemStack != ItemStack.EMPTY) {
|
if (batteryItemStack != ItemStack.EMPTY) {
|
||||||
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
||||||
|
|
||||||
@ -431,6 +382,9 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
|
|
||||||
return maxBattery
|
return maxBattery
|
||||||
}
|
}
|
||||||
|
set(value) {
|
||||||
|
maxBattery = value
|
||||||
|
}
|
||||||
|
|
||||||
private val resolver = LazyOptional.of { this }
|
private val resolver = LazyOptional.of { this }
|
||||||
|
|
||||||
@ -485,3 +439,5 @@ open class AndroidCapability(final override val entity: LivingEntity) : ICapabil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ICapabilityProvider.android get() = getCapability(MatteryCapability.ANDROID).orNull()
|
||||||
|
@ -9,45 +9,43 @@ import net.minecraft.resources.ResourceLocation
|
|||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.event.AttachCapabilitiesEvent
|
import net.minecraftforge.event.AttachCapabilitiesEvent
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent.Clone
|
import net.minecraftforge.event.entity.player.PlayerEvent.Clone
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent
|
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
|
import net.minecraftforge.network.PacketDistributor
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket
|
import ru.dbotthepony.mc.otm.ifPresentK
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply) {
|
class AndroidCapabilityPlayer(val ply: Player) : AndroidCapability(ply) {
|
||||||
@JvmField
|
override var isAndroid = false
|
||||||
var isAndroid = false
|
private var remoteIsAndroid = false
|
||||||
private var isAndroidNetwork = false
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var willBecomeAndroid = false
|
var willBecomeAndroid = false
|
||||||
private var willBecomeAndroidNetwork = false
|
private var willBecomeAndroidNetwork = false
|
||||||
private var shouldPlaySound = false
|
private var shouldPlaySound = false
|
||||||
private val research = ArrayList<AndroidResearch>()
|
private val research = ArrayList<AndroidResearch>()
|
||||||
|
|
||||||
override fun invalidateNetworkState() {
|
private var remoteBattery = ImpreciseFraction(-1)
|
||||||
super.invalidateNetworkState()
|
private var remoteMaxBattery = ImpreciseFraction(-1)
|
||||||
|
private var remoteBatteryStack = ItemStack.EMPTY
|
||||||
|
|
||||||
isAndroidNetwork = false
|
private var invalidateNetworkIn = 10
|
||||||
willBecomeAndroidNetwork = false
|
|
||||||
|
|
||||||
for (instance in research) {
|
fun invalidateNetworkState() {
|
||||||
instance.isDirty = true
|
invalidateNetworkIn = 10
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAndroid(): Boolean = isAndroid
|
|
||||||
fun isEverAndroid(): Boolean = isAndroid || willBecomeAndroid
|
fun isEverAndroid(): Boolean = isAndroid || willBecomeAndroid
|
||||||
|
|
||||||
fun becomeAndroidSoft() {
|
fun becomeAndroidSoft() {
|
||||||
@ -162,41 +160,91 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
|
|||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmField
|
var lastJumpTicks = 14
|
||||||
var last_jump_ticks = 14
|
|
||||||
|
|
||||||
override fun tickNetwork() {
|
override fun tick() {
|
||||||
super.tickNetwork()
|
super.tick()
|
||||||
if (isAndroid != isAndroidNetwork) {
|
|
||||||
isAndroidNetwork = isAndroid
|
if (invalidateNetworkIn > 0 && --invalidateNetworkIn == 0) {
|
||||||
sendNetwork(AndroidStatusPacket(AndroidStatusPacket.Type.IS_ANDROID, isAndroid, shouldPlaySound))
|
remoteBattery = ImpreciseFraction.MINUS_ONE
|
||||||
|
remoteMaxBattery = ImpreciseFraction.MINUS_ONE
|
||||||
|
remoteBatteryStack = ItemStack.EMPTY
|
||||||
|
|
||||||
|
remoteIsAndroid = false
|
||||||
|
willBecomeAndroidNetwork = false
|
||||||
|
|
||||||
|
for (instance in research) {
|
||||||
|
instance.isDirty = true
|
||||||
|
instance.invalidateNetwork()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (feature in features.values) {
|
||||||
|
feature.isDirty = true
|
||||||
|
feature.invalidateNetwork()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tickedOnce = true
|
||||||
|
|
||||||
|
if (battery != remoteBattery) {
|
||||||
|
remoteBattery = battery
|
||||||
|
sendNetwork(AndroidEnergyLevelPacket(level = battery, isMaxEnergy = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxBattery != remoteMaxBattery) {
|
||||||
|
remoteMaxBattery = maxBattery
|
||||||
|
sendNetwork(AndroidEnergyLevelPacket(level = maxBattery, isMaxEnergy = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remoteBatteryStack.equals(batteryItemStack, false)) {
|
||||||
|
remoteBatteryStack = batteryItemStack.copy()
|
||||||
|
sendNetwork(AndroidBatteryItemPacket(batteryItemStack))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (networkQueue.size != 0) {
|
||||||
|
for (packet in networkQueue) {
|
||||||
|
AndroidNetworkChannel.send(ply, packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
networkQueue.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAndroid != remoteIsAndroid) {
|
||||||
|
remoteIsAndroid = isAndroid
|
||||||
|
sendNetwork(IsAndroidPacket(isAndroid))
|
||||||
shouldPlaySound = false
|
shouldPlaySound = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (willBecomeAndroid != willBecomeAndroidNetwork) {
|
if (willBecomeAndroid != willBecomeAndroidNetwork) {
|
||||||
willBecomeAndroidNetwork = willBecomeAndroid
|
willBecomeAndroidNetwork = willBecomeAndroid
|
||||||
sendNetwork(AndroidStatusPacket(AndroidStatusPacket.Type.WILL_BECOME_ANDROID, willBecomeAndroid, false))
|
sendNetwork(WillBecomeAndroidPacket(willBecomeAndroid))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (instance in research) {
|
for (instance in research) {
|
||||||
if (instance.isDirty) {
|
if (instance.isDirty) {
|
||||||
instance.isDirty = false
|
instance.isDirty = false
|
||||||
sendNetwork(AndroidResearchPacket(instance))
|
sendNetwork(AndroidResearchSyncPacket(instance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (instance in features.values) {
|
||||||
|
if (instance.isDirty) {
|
||||||
|
instance.isDirty = false
|
||||||
|
sendNetwork(AndroidFeatureSyncPacket(instance))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmField
|
var sleepTicks = 0
|
||||||
var sleep_ticks = 0
|
|
||||||
|
|
||||||
override fun tickInnerClientAlways() {
|
override fun tickInnerClientAlways() {
|
||||||
super.tickInnerClientAlways()
|
super.tickInnerClientAlways()
|
||||||
|
|
||||||
if (willBecomeAndroid) {
|
if (willBecomeAndroid) {
|
||||||
if (ply.isSleeping) {
|
if (ply.isSleeping) {
|
||||||
sleep_ticks++
|
sleepTicks++
|
||||||
} else {
|
} else {
|
||||||
sleep_ticks = 0
|
sleepTicks = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,17 +254,17 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
|
|||||||
|
|
||||||
if (willBecomeAndroid) {
|
if (willBecomeAndroid) {
|
||||||
if (ply.isSleeping) {
|
if (ply.isSleeping) {
|
||||||
sleep_ticks++
|
sleepTicks++
|
||||||
|
|
||||||
if (sleep_ticks > SLEEP_TICKS_LIMIT) {
|
if (sleepTicks > SLEEP_TICKS_LIMIT) {
|
||||||
becomeAndroid()
|
becomeAndroid()
|
||||||
shouldPlaySound = true
|
shouldPlaySound = true
|
||||||
sleep_ticks = 0
|
sleepTicks = 0
|
||||||
|
|
||||||
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sleep_ticks = 0
|
sleepTicks = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,12 +319,13 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onPlayerChangeDimensionEvent(event: PlayerChangedDimensionEvent) {
|
fun onPlayerChangeDimensionEvent(event: PlayerChangedDimensionEvent) {
|
||||||
event.player.getCapability(MatteryCapability.ANDROID)
|
event.player.getCapability(MatteryCapability.ANDROID)
|
||||||
.ifPresent { it.invalidateNetworkState() }
|
.ifPresentK { (it as AndroidCapabilityPlayer).invalidateNetworkState() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onPlayerCloneEvent(event: Clone) {
|
fun onPlayerCloneEvent(event: Clone) {
|
||||||
event.player.getCapability(MatteryCapability.ANDROID).ifPresent {
|
val it = event.player.android as AndroidCapabilityPlayer? ?: return
|
||||||
|
|
||||||
var resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
var resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
||||||
|
|
||||||
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
||||||
@ -286,7 +335,7 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
|
|||||||
|
|
||||||
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
||||||
event.original.invalidateCaps()
|
event.original.invalidateCaps()
|
||||||
return@ifPresent
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val original = resolver.resolve().get() as AndroidCapabilityPlayer
|
val original = resolver.resolve().get() as AndroidCapabilityPlayer
|
||||||
@ -300,7 +349,6 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
|
|||||||
it.invalidateNetworkState()
|
it.invalidateNetworkState()
|
||||||
event.original.invalidateCaps()
|
event.original.invalidateCaps()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val ENERGY_FOR_HUNGER_POINT = ImpreciseFraction(1000)
|
val ENERGY_FOR_HUNGER_POINT = ImpreciseFraction(1000)
|
||||||
const val SLEEP_TICKS_LIMIT = 80
|
const val SLEEP_TICKS_LIMIT = 80
|
||||||
|
@ -22,6 +22,10 @@ interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundT
|
|||||||
|
|
||||||
fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T?
|
fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T?
|
||||||
|
|
||||||
|
fun <T : AndroidFeature> computeIfAbsent(feature: AndroidFeatureType<T>): T {
|
||||||
|
return getFeature(feature) ?: addFeature(feature)
|
||||||
|
}
|
||||||
|
|
||||||
fun <T : AndroidFeature> getFeatureO(feature: AndroidFeatureType<T>): Optional<T> {
|
fun <T : AndroidFeature> getFeatureO(feature: AndroidFeatureType<T>): Optional<T> {
|
||||||
val get = getFeature(feature)
|
val get = getFeature(feature)
|
||||||
return if (get != null) Optional.of(get) else Optional.empty()
|
return if (get != null) Optional.of(get) else Optional.empty()
|
||||||
@ -35,11 +39,11 @@ interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAndroid(): Boolean = true
|
val isAndroid: Boolean get() = true
|
||||||
|
|
||||||
fun onHurt(event: LivingHurtEvent) {}
|
fun onHurt(event: LivingHurtEvent) {}
|
||||||
var batteryItemStack: ItemStack
|
var batteryItemStack: ItemStack
|
||||||
fun invalidateNetworkState() // tell capability that player forgot everything, and everything needs to be re-networked
|
|
||||||
fun setEnergy(value: ImpreciseFraction)
|
override var batteryLevel: ImpreciseFraction
|
||||||
fun setMaxEnergy(value: ImpreciseFraction)
|
override var maxBatteryLevel: ImpreciseFraction
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ import org.lwjgl.opengl.GL30
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.android.android
|
||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
@ -144,10 +145,8 @@ class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context
|
|||||||
if (!Minecraft.getInstance().options.hideGui && (
|
if (!Minecraft.getInstance().options.hideGui && (
|
||||||
(ply.mainHandItem.item == MItems.BLACK_HOLE_SCANNER || ply.offhandItem.item == MItems.BLACK_HOLE_SCANNER) &&
|
(ply.mainHandItem.item == MItems.BLACK_HOLE_SCANNER || ply.offhandItem.item == MItems.BLACK_HOLE_SCANNER) &&
|
||||||
poseStack.translation().length() < tile.gravitationStrength * 64.0 ||
|
poseStack.translation().length() < tile.gravitationStrength * 64.0 ||
|
||||||
(ply.abilities.instabuild || ply.abilities.invulnerable ||
|
(ply.abilities.instabuild || ply.android?.isAndroid == true) &&
|
||||||
ply.getCapability(MatteryCapability.ANDROID).isPresent &&
|
poseStack.translation().length() < tile.gravitationStrength * 28.0
|
||||||
ply.getCapability(MatteryCapability.ANDROID).resolve().get().isAndroid()) &&
|
|
||||||
poseStack.translation().length() < tile.gravitationStrength * 32.0
|
|
||||||
)) {
|
)) {
|
||||||
val facing = tile.blockPos.asVector() - Minecraft.getInstance().gameRenderer.mainCamera.position
|
val facing = tile.blockPos.asVector() - Minecraft.getInstance().gameRenderer.mainCamera.position
|
||||||
val distance = facing.length()
|
val distance = facing.length()
|
||||||
|
@ -19,8 +19,9 @@ import ru.dbotthepony.mc.otm.client.screen.panels.*
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidNetworkChannel
|
||||||
|
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import ru.dbotthepony.mc.otm.network.android.AndroidResearchRequestPacket
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
||||||
if (mouse_click_type == InputConstants.MOUSE_BUTTON_LEFT) {
|
if (mouse_click_type == InputConstants.MOUSE_BUTTON_LEFT) {
|
||||||
if (node.canResearch && !node.isResearched) {
|
if (node.canResearch && !node.isResearched) {
|
||||||
MatteryNetworking.CHANNEL.sendToServer(AndroidResearchRequestPacket(node.type))
|
AndroidNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
|
||||||
}
|
}
|
||||||
|
|
||||||
ru.dbotthepony.mc.otm.client.minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
ru.dbotthepony.mc.otm.client.minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
||||||
|
@ -41,7 +41,7 @@ class HealPillItem : Item(Properties().stacksTo(64).rarity(Rarity.UNCOMMON).tab(
|
|||||||
override fun use(level: Level, ply: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
override fun use(level: Level, ply: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||||
val resolver = ply.getCapability(MatteryCapability.ANDROID).resolve()
|
val resolver = ply.getCapability(MatteryCapability.ANDROID).resolve()
|
||||||
|
|
||||||
if (!resolver.isEmpty && resolver.get().isAndroid())
|
if (!resolver.isEmpty && resolver.get().isAndroid)
|
||||||
return super.use(level, ply, hand)
|
return super.use(level, ply, hand)
|
||||||
|
|
||||||
ply.startUsingItem(hand)
|
ply.startUsingItem(hand)
|
||||||
@ -51,7 +51,7 @@ class HealPillItem : Item(Properties().stacksTo(64).rarity(Rarity.UNCOMMON).tab(
|
|||||||
override fun finishUsingItem(stack: ItemStack, level: Level, ent: LivingEntity): ItemStack {
|
override fun finishUsingItem(stack: ItemStack, level: Level, ent: LivingEntity): ItemStack {
|
||||||
val resolver = ent.getCapability(MatteryCapability.ANDROID).resolve()
|
val resolver = ent.getCapability(MatteryCapability.ANDROID).resolve()
|
||||||
|
|
||||||
if (!resolver.isEmpty && resolver.get().isAndroid())
|
if (!resolver.isEmpty && resolver.get().isAndroid)
|
||||||
return super.finishUsingItem(stack, level, ent)
|
return super.finishUsingItem(stack, level, ent)
|
||||||
|
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
@ -106,7 +106,7 @@ class PillItem(val pillType: PillType) :
|
|||||||
if (
|
if (
|
||||||
pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid() ||
|
pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid() ||
|
||||||
pillType == PillType.BECOME_HUMANE && cap.isEverAndroid() ||
|
pillType == PillType.BECOME_HUMANE && cap.isEverAndroid() ||
|
||||||
pillType == PillType.OBLIVION && cap.isAndroid()
|
pillType == PillType.OBLIVION && cap.isAndroid
|
||||||
) {
|
) {
|
||||||
ply.startUsingItem(hand)
|
ply.startUsingItem(hand)
|
||||||
return InteractionResultHolder.consume(ply.getItemInHand(hand))
|
return InteractionResultHolder.consume(ply.getItemInHand(hand))
|
||||||
@ -127,7 +127,7 @@ class PillItem(val pillType: PillType) :
|
|||||||
|
|
||||||
val cap = resolver.get() as AndroidCapabilityPlayer
|
val cap = resolver.get() as AndroidCapabilityPlayer
|
||||||
|
|
||||||
if (pillType == PillType.OBLIVION && cap.isAndroid()) {
|
if (pillType == PillType.OBLIVION && cap.isAndroid) {
|
||||||
if (!ent.abilities.instabuild) {
|
if (!ent.abilities.instabuild) {
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,241 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.network
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
|
||||||
|
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
|
||||||
|
import net.minecraftforge.network.NetworkEvent
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||||
|
import ru.dbotthepony.mc.otm.capability.android.*
|
||||||
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
|
import ru.dbotthepony.mc.otm.core.readImpreciseFraction
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeImpreciseFraction
|
||||||
|
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
sealed class AndroidStatusPacket : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {}
|
||||||
|
|
||||||
|
protected abstract fun play(capability: AndroidCapabilityPlayer)
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
play(minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object IsAndroidPacket : AndroidStatusPacket() {
|
||||||
|
override fun play(capability: AndroidCapabilityPlayer) {
|
||||||
|
capability.isAndroid = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object IsNotAndroidPacket : AndroidStatusPacket() {
|
||||||
|
override fun play(capability: AndroidCapabilityPlayer) {
|
||||||
|
capability.isAndroid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IsAndroidPacket(status: Boolean) = if (status) IsAndroidPacket else IsNotAndroidPacket
|
||||||
|
|
||||||
|
object WillBecomeAndroidPacket : AndroidStatusPacket() {
|
||||||
|
override fun play(capability: AndroidCapabilityPlayer) {
|
||||||
|
capability.willBecomeAndroid = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object WillNotBecomeAndroidPacket : AndroidStatusPacket() {
|
||||||
|
override fun play(capability: AndroidCapabilityPlayer) {
|
||||||
|
capability.willBecomeAndroid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun WillBecomeAndroidPacket(status: Boolean) = if (status) WillBecomeAndroidPacket else WillNotBecomeAndroidPacket
|
||||||
|
|
||||||
|
class AndroidResearchRequestPacket(val type: AndroidResearchType<*>) : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeInt(MRegistry.ANDROID_RESEARCH.getID(type))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val ply = context.get().sender ?: return@enqueueWork
|
||||||
|
val android = ply.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
if (!android.isAndroid || ply.containerMenu !is AndroidStationMenu)
|
||||||
|
return@enqueueWork
|
||||||
|
|
||||||
|
android.getResearch(type).research()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidResearchRequestPacket {
|
||||||
|
return AndroidResearchRequestPacket(MRegistry.ANDROID_RESEARCH.getValue(buff.readInt()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getData(invoke: (stream: OutputStream) -> Unit): FastByteArrayOutputStream {
|
||||||
|
val stream = FastByteArrayOutputStream()
|
||||||
|
invoke(stream)
|
||||||
|
return stream
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidResearchSyncPacket(val type: AndroidResearchType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket {
|
||||||
|
constructor(feature: AndroidResearch) : this(feature.type, getData(feature::writeNetwork), null)
|
||||||
|
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
dataList ?: throw NullPointerException("No byte list is present")
|
||||||
|
buff.writeInt(MRegistry.ANDROID_RESEARCH.getID(type))
|
||||||
|
buff.writeBytes(dataList.array, 0, dataList.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
dataBytes ?: throw NullPointerException("No data bytes array is present")
|
||||||
|
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
android.getResearch(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidResearchSyncPacket {
|
||||||
|
return AndroidResearchSyncPacket(
|
||||||
|
MRegistry.ANDROID_RESEARCH.getValue(buff.readInt()),
|
||||||
|
null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket {
|
||||||
|
constructor(feature: AndroidFeature) : this(feature.type, getData(feature::writeNetwork), null)
|
||||||
|
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
dataList ?: throw NullPointerException("No byte list is present")
|
||||||
|
buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type))
|
||||||
|
buff.writeBytes(dataList.array, 0, dataList.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
dataBytes ?: throw NullPointerException("No data bytes array is present")
|
||||||
|
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
android.computeIfAbsent(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidFeatureSyncPacket {
|
||||||
|
return AndroidFeatureSyncPacket(
|
||||||
|
MRegistry.ANDROID_FEATURES.getValue(buff.readInt()),
|
||||||
|
null, ByteArray(buff.readableBytes()).also { buff.readBytes(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
android.removeFeature(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket {
|
||||||
|
return AndroidFeatureRemovePacket(MRegistry.ANDROID_FEATURES.getValue(buff.readInt()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidBatteryItemPacket(val item: ItemStack) : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeItem(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
android.batteryItemStack = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidBatteryItemPacket {
|
||||||
|
return AndroidBatteryItemPacket(buff.readItem())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidEnergyLevelPacket(val level: ImpreciseFraction, val isMaxEnergy: Boolean) : MatteryPacket {
|
||||||
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeBoolean(isMaxEnergy)
|
||||||
|
buff.writeImpreciseFraction(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
|
context.get().packetHandled = true
|
||||||
|
context.get().enqueueWork {
|
||||||
|
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
||||||
|
|
||||||
|
if (isMaxEnergy) {
|
||||||
|
android.maxBatteryLevel = level
|
||||||
|
} else {
|
||||||
|
android.batteryLevel = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun read(buff: FriendlyByteBuf): AndroidEnergyLevelPacket {
|
||||||
|
return AndroidEnergyLevelPacket(buff.readImpreciseFraction(), buff.readBoolean())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AndroidNetworkChannel : MatteryNetworkChannel(
|
||||||
|
version = "1",
|
||||||
|
name = "android"
|
||||||
|
) {
|
||||||
|
fun register() {
|
||||||
|
add(IsAndroidPacket::class.java, { IsAndroidPacket }, PLAY_TO_CLIENT)
|
||||||
|
add(IsNotAndroidPacket::class.java, { IsNotAndroidPacket }, PLAY_TO_CLIENT)
|
||||||
|
add(WillBecomeAndroidPacket::class.java, { WillBecomeAndroidPacket }, PLAY_TO_CLIENT)
|
||||||
|
add(WillNotBecomeAndroidPacket::class.java, { WillNotBecomeAndroidPacket }, PLAY_TO_CLIENT)
|
||||||
|
|
||||||
|
add(AndroidResearchRequestPacket::class.java, AndroidResearchRequestPacket.Companion::read, PLAY_TO_SERVER)
|
||||||
|
add(AndroidResearchSyncPacket::class.java, AndroidResearchSyncPacket.Companion::read, PLAY_TO_CLIENT)
|
||||||
|
add(AndroidFeatureSyncPacket::class.java, AndroidFeatureSyncPacket.Companion::read, PLAY_TO_CLIENT)
|
||||||
|
add(AndroidFeatureRemovePacket::class.java, AndroidFeatureRemovePacket.Companion::read, PLAY_TO_CLIENT)
|
||||||
|
add(AndroidBatteryItemPacket::class.java, AndroidBatteryItemPacket.Companion::read, PLAY_TO_CLIENT)
|
||||||
|
add(AndroidEnergyLevelPacket::class.java, AndroidEnergyLevelPacket.Companion::read, PLAY_TO_CLIENT)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.network
|
||||||
|
|
||||||
|
import java.util.function.Function
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraftforge.network.NetworkDirection
|
||||||
|
import net.minecraftforge.network.NetworkEvent
|
||||||
|
import net.minecraftforge.network.NetworkRegistry
|
||||||
|
import net.minecraftforge.network.PacketDistributor
|
||||||
|
import net.minecraftforge.network.simple.SimpleChannel
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.function.BiConsumer
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
interface MatteryPacket {
|
||||||
|
fun write(buff: FriendlyByteBuf)
|
||||||
|
fun play(context: Supplier<NetworkEvent.Context>)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||||
|
val channel: SimpleChannel = NetworkRegistry.newSimpleChannel(
|
||||||
|
ResourceLocation(OverdriveThatMatters.MOD_ID, name),
|
||||||
|
{ version },
|
||||||
|
{ it == version },
|
||||||
|
{ it == version },
|
||||||
|
)
|
||||||
|
|
||||||
|
fun sendToServer(packet: Any) = channel.sendToServer(packet)
|
||||||
|
|
||||||
|
fun send(ply: Player, packet: Any) {
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
channel.send(PacketDistributor.PLAYER.with { ply }, packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun send(distributor: PacketDistributor.PacketTarget, packet: Any) = channel.send(distributor, packet)
|
||||||
|
|
||||||
|
private var nextNetworkPacketID = 0
|
||||||
|
|
||||||
|
fun <T> add(
|
||||||
|
packetClass: Class<T>,
|
||||||
|
writer: BiConsumer<T, FriendlyByteBuf>,
|
||||||
|
reader: Function<FriendlyByteBuf, T>,
|
||||||
|
handler: BiConsumer<T, Supplier<NetworkEvent.Context>>,
|
||||||
|
direction: NetworkDirection? = null
|
||||||
|
) {
|
||||||
|
@Suppress("INACCESSIBLE_TYPE")
|
||||||
|
channel.registerMessage(nextNetworkPacketID++, packetClass, writer, reader, handler, if (direction == null) Optional.empty() else Optional.of(direction))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : MatteryPacket> add(
|
||||||
|
packetClass: Class<T>,
|
||||||
|
reader: Function<FriendlyByteBuf, T>,
|
||||||
|
direction: NetworkDirection? = null
|
||||||
|
) {
|
||||||
|
add(packetClass, MatteryPacket::write, reader, MatteryPacket::play, direction)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user