Merge android capability into rigid single class
since it is relevant only for player anyway
This commit is contained in:
parent
589d3a5499
commit
c24176374c
@ -13,12 +13,9 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
|||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
|
||||||
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability;
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability;
|
|
||||||
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.EventHandlerKt;
|
import ru.dbotthepony.mc.otm.client.EventHandlerKt;
|
||||||
@ -86,7 +83,6 @@ public final class OverdriveThatMatters {
|
|||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
MinecraftForge.EVENT_BUS.register(TickerKt.class);
|
MinecraftForge.EVENT_BUS.register(TickerKt.class);
|
||||||
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.Companion);
|
|
||||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.Companion);
|
MinecraftForge.EVENT_BUS.register(AndroidCapability.Companion);
|
||||||
MinecraftForge.EVENT_BUS.register(MatterRegistryKt.class);
|
MinecraftForge.EVENT_BUS.register(MatterRegistryKt.class);
|
||||||
MinecraftForge.EVENT_BUS.register(MatterDataKt.class);
|
MinecraftForge.EVENT_BUS.register(MatterDataKt.class);
|
||||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.capability;
|
|||||||
|
|
||||||
import mekanism.api.energy.IStrictEnergyHandler;
|
import mekanism.api.energy.IStrictEnergyHandler;
|
||||||
import net.minecraftforge.common.capabilities.*;
|
import net.minecraftforge.common.capabilities.*;
|
||||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
|
||||||
@ -13,7 +12,7 @@ import ru.dbotthepony.mc.otm.storage.IStorageStack;
|
|||||||
|
|
||||||
public class MatteryCapability {
|
public class MatteryCapability {
|
||||||
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IAndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<AndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatterGraphNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatterGraphNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
@ -26,7 +25,7 @@ public class MatteryCapability {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static void register(final RegisterCapabilitiesEvent event) {
|
public static void register(final RegisterCapabilitiesEvent event) {
|
||||||
event.register(IMatteryEnergyStorage.class);
|
event.register(IMatteryEnergyStorage.class);
|
||||||
event.register(IAndroidCapability.class);
|
event.register(AndroidCapability.class);
|
||||||
event.register(IMatterHandler.class);
|
event.register(IMatterHandler.class);
|
||||||
event.register(IPatternStorage.class);
|
event.register(IPatternStorage.class);
|
||||||
event.register(IMatterTaskProvider.class);
|
event.register(IMatterTaskProvider.class);
|
||||||
|
@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.android
|
|||||||
import net.minecraft.nbt.CompoundTag
|
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.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.readNbt
|
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 ru.dbotthepony.mc.otm.writeNbt
|
||||||
@ -11,7 +11,7 @@ import java.io.InputStream
|
|||||||
import java.io.OutputStream
|
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.ply
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever there are changes to network
|
* Whenever there are changes to network
|
||||||
|
@ -4,7 +4,7 @@ import net.minecraft.network.chat.Component
|
|||||||
import net.minecraft.network.chat.ComponentContents
|
import net.minecraft.network.chat.ComponentContents
|
||||||
import net.minecraft.network.chat.MutableComponent
|
import net.minecraft.network.chat.MutableComponent
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents
|
import net.minecraft.network.chat.contents.TranslatableContents
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.getKeyNullable
|
import ru.dbotthepony.mc.otm.getKeyNullable
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
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.AndroidCapability
|
||||||
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.readNbt
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.writeNbt
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability: AndroidCapabilityPlayer) : INBTSerializable<CompoundTag> {
|
abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability: AndroidCapability) : INBTSerializable<CompoundTag> {
|
||||||
var isResearched = false
|
var isResearched = false
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
|
@ -7,12 +7,12 @@ import net.minecraft.network.chat.ComponentContents
|
|||||||
import net.minecraft.network.chat.MutableComponent
|
import net.minecraft.network.chat.MutableComponent
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents
|
import net.minecraft.network.chat.contents.TranslatableContents
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.getKeyNullable
|
import ru.dbotthepony.mc.otm.getKeyNullable
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
|
|
||||||
fun interface AndroidResearchFactory<R : AndroidResearch> {
|
fun interface AndroidResearchFactory<R : AndroidResearch> {
|
||||||
fun factory(type: AndroidResearchType<*>, capability: AndroidCapabilityPlayer): R
|
fun factory(type: AndroidResearchType<*>, capability: AndroidCapability): R
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findPrerequisites(
|
private fun findPrerequisites(
|
||||||
@ -173,7 +173,7 @@ open class AndroidResearchType<R : AndroidResearch>(
|
|||||||
ImmutableList.copyOf(findAllChildren(flatUnlocks))
|
ImmutableList.copyOf(findAllChildren(flatUnlocks))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun factory(capability: AndroidCapabilityPlayer) = factory.factory(this, capability)
|
fun factory(capability: AndroidCapability) = factory.factory(this, capability)
|
||||||
|
|
||||||
val registryName by lazy {
|
val registryName by lazy {
|
||||||
MRegistry.ANDROID_RESEARCH.getKeyNullable(this)
|
MRegistry.ANDROID_RESEARCH.getKeyNullable(this)
|
||||||
|
@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.android.feature
|
|||||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.android.feature
|
|||||||
|
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||||
import net.minecraftforge.common.ForgeMod
|
import net.minecraftforge.common.ForgeMod
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.android.feature
|
|||||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
|
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
|
@ -4,7 +4,7 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||||
|
@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.android.feature
|
|||||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||||
import net.minecraftforge.common.ForgeMod
|
import net.minecraftforge.common.ForgeMod
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -0,0 +1,737 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.capability
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||||
|
import java.lang.Runnable
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
|
import net.minecraft.nbt.ListTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.effect.MobEffect
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
|
||||||
|
import net.minecraft.world.effect.MobEffects
|
||||||
|
import net.minecraft.world.entity.Entity
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import net.minecraftforge.event.AttachCapabilitiesEvent
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
|
import net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerEvent
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority
|
||||||
|
import ru.dbotthepony.mc.otm.*
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||||
|
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
||||||
|
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||||
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
|
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
class AndroidCapability(val ply: Player) : ICapabilityProvider, IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
||||||
|
private var battery = ImpreciseFraction.ZERO
|
||||||
|
private var maxBattery = ImpreciseFraction(60000)
|
||||||
|
|
||||||
|
var batteryItemStack: ItemStack = ItemStack.EMPTY
|
||||||
|
|
||||||
|
private val features = Object2ObjectArrayMap<AndroidFeatureType<*>, AndroidFeature>()
|
||||||
|
private val networkQueue = ArrayList<Any>()
|
||||||
|
private val queuedTicks = ArrayList<Runnable>()
|
||||||
|
private var tickedOnce = false
|
||||||
|
|
||||||
|
private var willBecomeAndroidNetwork = false
|
||||||
|
private var shouldPlaySound = false
|
||||||
|
private val research = ArrayList<AndroidResearch>()
|
||||||
|
|
||||||
|
private var remoteBattery = ImpreciseFraction(-1)
|
||||||
|
private var remoteMaxBattery = ImpreciseFraction(-1)
|
||||||
|
private var remoteBatteryStack = ItemStack.EMPTY
|
||||||
|
|
||||||
|
private var invalidateNetworkIn = 10
|
||||||
|
private var remoteIsAndroid = false
|
||||||
|
|
||||||
|
var willBecomeAndroid = false
|
||||||
|
var isAndroid = false
|
||||||
|
|
||||||
|
var sleepTicks = 0
|
||||||
|
|
||||||
|
fun invalidateNetworkState() {
|
||||||
|
invalidateNetworkIn = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
val isEverAndroid: Boolean get() = isAndroid || willBecomeAndroid
|
||||||
|
|
||||||
|
fun becomeAndroidSoft() {
|
||||||
|
if (isAndroid || willBecomeAndroid) return
|
||||||
|
willBecomeAndroid = true
|
||||||
|
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message").withStyle(ChatFormatting.GRAY), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun becomeAndroid() {
|
||||||
|
if (isAndroid) return
|
||||||
|
|
||||||
|
isAndroid = true
|
||||||
|
willBecomeAndroid = false
|
||||||
|
shouldPlaySound = false
|
||||||
|
battery = ImpreciseFraction(60000)
|
||||||
|
maxBattery = ImpreciseFraction(60000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun becomeAndroidAndKill() {
|
||||||
|
if (isAndroid) return
|
||||||
|
|
||||||
|
becomeAndroid()
|
||||||
|
ply.hurt(MRegistry.DAMAGE_BECOME_ANDROID, ply.maxHealth * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun becomeHumane() {
|
||||||
|
if (willBecomeAndroid) willBecomeAndroid = false
|
||||||
|
if (!isAndroid) return
|
||||||
|
|
||||||
|
isAndroid = false
|
||||||
|
shouldPlaySound = false
|
||||||
|
battery = ImpreciseFraction(0)
|
||||||
|
maxBattery = ImpreciseFraction(60000)
|
||||||
|
dropBattery()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun becomeHumaneAndKill() {
|
||||||
|
if (willBecomeAndroid) willBecomeAndroid = false
|
||||||
|
if (!isAndroid) return
|
||||||
|
|
||||||
|
becomeHumane()
|
||||||
|
ply.hurt(MRegistry.DAMAGE_BECOME_HUMANE, ply.maxHealth * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun obliviate(refund: Boolean = true) {
|
||||||
|
if (refund) {
|
||||||
|
for (instance in research) {
|
||||||
|
if (instance.isResearched) {
|
||||||
|
instance.unResearch()
|
||||||
|
instance.refund(simulate = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val copy = java.util.List.copyOf(features.values)
|
||||||
|
|
||||||
|
for (feature in copy) {
|
||||||
|
removeFeature(feature.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : AndroidResearch> getResearch(type: AndroidResearchType<T>): T {
|
||||||
|
for (instance in research) {
|
||||||
|
if (instance.type === type) {
|
||||||
|
return instance as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val instance = type.factory(this)
|
||||||
|
research.add(instance)
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastJumpTicks = 14
|
||||||
|
|
||||||
|
private fun addFeature(feature: AndroidFeature): Boolean {
|
||||||
|
if (features.containsKey(feature.type)) return false
|
||||||
|
features[feature.type] = feature
|
||||||
|
|
||||||
|
if (!ply.level.isClientSide) {
|
||||||
|
queuedTicks.add(feature::applyModifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
sendNetwork(AndroidFeatureSyncPacket(feature))
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unchecked_cast")
|
||||||
|
fun <T : AndroidFeature> addFeature(feature: AndroidFeatureType<T>): T {
|
||||||
|
val get = features[feature]
|
||||||
|
if (get != null) return get as T
|
||||||
|
|
||||||
|
val factory = feature.create(this)
|
||||||
|
|
||||||
|
features[feature] = factory
|
||||||
|
|
||||||
|
if (!ply.level.isClientSide) {
|
||||||
|
queuedTicks.add(factory::applyModifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
sendNetwork(AndroidFeatureSyncPacket(factory))
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeFeature(feature: AndroidFeatureType<*>): Boolean {
|
||||||
|
val removed = features.remove(feature)
|
||||||
|
|
||||||
|
if (removed != null) {
|
||||||
|
if (!ply.level.isClientSide) {
|
||||||
|
queuedTicks.add {
|
||||||
|
removed.removeModifiers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
sendNetwork(AndroidFeatureRemovePacket(removed.type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasFeature(feature: AndroidFeatureType<*>): Boolean {
|
||||||
|
return features.containsKey(feature)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasFeatureLevel(feature: AndroidFeatureType<*>, level: Int): Boolean {
|
||||||
|
val get = features[feature] ?: return false
|
||||||
|
return get.level >= level
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unchecked_cast")
|
||||||
|
fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T? {
|
||||||
|
return features[feature] as T?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onHurt(event: LivingHurtEvent) {
|
||||||
|
for (feature in features.values) {
|
||||||
|
feature.onHurt(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : AndroidFeature> computeIfAbsent(feature: AndroidFeatureType<T>): T {
|
||||||
|
return getFeature(feature) ?: addFeature(feature)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : AndroidFeature> getFeatureO(feature: AndroidFeatureType<T>): Optional<T> {
|
||||||
|
val get = getFeature(feature)
|
||||||
|
return if (get != null) Optional.of(get) else Optional.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : AndroidFeature> ifFeature(feature: AndroidFeatureType<T>, consumer: (T) -> Unit) {
|
||||||
|
val get = getFeature(feature)
|
||||||
|
|
||||||
|
if (get != null) {
|
||||||
|
consumer(get)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serializeNBT(): CompoundTag {
|
||||||
|
val tag = CompoundTag()
|
||||||
|
|
||||||
|
tag["energy_stored"] = battery.serializeNBT()
|
||||||
|
tag["energy_stored_max"] = maxBattery.serializeNBT()
|
||||||
|
tag["battery"] = batteryItemStack.serializeNBT()
|
||||||
|
|
||||||
|
val featureList = ListTag()
|
||||||
|
|
||||||
|
for (feature in features.values) {
|
||||||
|
val featureNbt = feature.serializeNBT()
|
||||||
|
|
||||||
|
featureNbt["id"] = feature.type.registryName!!.toString()
|
||||||
|
featureList.add(featureNbt)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag["features"] = featureList
|
||||||
|
|
||||||
|
tag["is_android"] = isAndroid
|
||||||
|
tag["will_become_android"] = willBecomeAndroid
|
||||||
|
|
||||||
|
val list = ListTag()
|
||||||
|
|
||||||
|
for (instance in research) {
|
||||||
|
val researchTag = instance.serializeNBT()
|
||||||
|
|
||||||
|
researchTag["id"] = instance.type.registryName!!.toString()
|
||||||
|
list.add(researchTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag["research"] = list
|
||||||
|
|
||||||
|
return tag
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializeNBT(compound: CompoundTag) {
|
||||||
|
compound.ifHas("energy_stored") {
|
||||||
|
battery = ImpreciseFraction.deserializeNBT(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
compound.ifHas("energy_stored_max") {
|
||||||
|
maxBattery = ImpreciseFraction.deserializeNBT(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
compound.ifHas("battery", CompoundTag::class.java) {
|
||||||
|
batteryItemStack = ItemStack.of(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
features.clear()
|
||||||
|
|
||||||
|
val featuresNbt = compound.getList("features", Tag.TAG_COMPOUND.toInt())
|
||||||
|
|
||||||
|
for (tag in featuresNbt) {
|
||||||
|
if (tag is CompoundTag) {
|
||||||
|
val feature = MRegistry.ANDROID_FEATURES.getValue(ResourceLocation(tag.getString("id")))
|
||||||
|
|
||||||
|
if (feature?.isApplicable(this) == true) {
|
||||||
|
val instance = feature.create(this)
|
||||||
|
|
||||||
|
instance.deserializeNBT(tag)
|
||||||
|
addFeature(instance)
|
||||||
|
|
||||||
|
if (!ply.level.isClientSide) {
|
||||||
|
queuedTicks.add(instance::applyModifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isAndroid = compound.getBoolean("is_android")
|
||||||
|
willBecomeAndroid = compound.getBoolean("will_become_android")
|
||||||
|
research.clear()
|
||||||
|
|
||||||
|
val list = compound.getList("research", Tag.TAG_COMPOUND.toInt())
|
||||||
|
|
||||||
|
for (tag in list) {
|
||||||
|
if (tag is CompoundTag) {
|
||||||
|
val research = MRegistry.ANDROID_RESEARCH.getValue(ResourceLocation(tag.getString("id")))
|
||||||
|
|
||||||
|
if (research != null) {
|
||||||
|
val instance = research.factory(this)
|
||||||
|
instance.deserializeNBT(tag)
|
||||||
|
this.research.add(instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dropBattery() {
|
||||||
|
if (batteryItemStack.isEmpty) return
|
||||||
|
ply.spawnAtLocation(batteryItemStack)
|
||||||
|
batteryItemStack = ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendNetwork(packet: Any) {
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
if (tickedOnce) {
|
||||||
|
AndroidNetworkChannel.send(ply, packet)
|
||||||
|
} else {
|
||||||
|
networkQueue.add(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tickClient() {
|
||||||
|
queuedTicks.clear()
|
||||||
|
|
||||||
|
if (!ply.isAlive) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (willBecomeAndroid) {
|
||||||
|
if (ply.isSleeping) {
|
||||||
|
sleepTicks++
|
||||||
|
} else {
|
||||||
|
sleepTicks = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAndroid) {
|
||||||
|
for (feature in features.values) {
|
||||||
|
feature.tickClient()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
if (!ply.isAlive) return
|
||||||
|
|
||||||
|
if (willBecomeAndroid) {
|
||||||
|
if (ply.isSleeping) {
|
||||||
|
sleepTicks++
|
||||||
|
|
||||||
|
if (sleepTicks > SLEEP_TICKS_LIMIT) {
|
||||||
|
becomeAndroid()
|
||||||
|
shouldPlaySound = true
|
||||||
|
sleepTicks = 0
|
||||||
|
|
||||||
|
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sleepTicks = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAndroid) {
|
||||||
|
if (ply.airSupply < ply.maxAirSupply)
|
||||||
|
ply.airSupply = ply.maxAirSupply
|
||||||
|
|
||||||
|
for (effect in UNAFFECTED_EFFECTS)
|
||||||
|
if (ply.hasEffect(effect))
|
||||||
|
ply.removeEffect(effect)
|
||||||
|
|
||||||
|
if (!batteryItemStack.isEmpty && battery < maxBattery) {
|
||||||
|
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresent {
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
battery += it.extractEnergyInner(maxBattery - battery, false)
|
||||||
|
} else {
|
||||||
|
battery += it.extractEnergy(maxBattery - battery, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Maybe passive drain?
|
||||||
|
// extractEnergyInner(BigDecimal.valueOf(new Random().nextDouble()), false);
|
||||||
|
if (ply.isSwimming && !hasFeature(AndroidFeatures.AIR_BAGS)) {
|
||||||
|
ply.isSwimming = false
|
||||||
|
}
|
||||||
|
|
||||||
|
val stats = ply.foodData
|
||||||
|
|
||||||
|
while (stats.foodLevel < 18 && extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true) >= ENERGY_FOR_HUNGER_POINT) {
|
||||||
|
extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false)
|
||||||
|
stats.foodLevel = stats.foodLevel + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// "block" quick regeneration
|
||||||
|
// also cause power to generate while in peaceful
|
||||||
|
while (stats.foodLevel > 18 && receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, true) >= ENERGY_FOR_HUNGER_POINT) {
|
||||||
|
receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, false)
|
||||||
|
stats.foodLevel = stats.foodLevel - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val foodLevel = stats.foodLevel.toFloat()
|
||||||
|
|
||||||
|
if (stats.saturationLevel < foodLevel) {
|
||||||
|
val extracted = extractEnergyInner(ENERGY_FOR_HUNGER_POINT * (foodLevel - stats.saturationLevel), false)
|
||||||
|
stats.setSaturation(stats.saturationLevel + (extracted / ENERGY_FOR_HUNGER_POINT).toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.exhaustionLevel > 0f) {
|
||||||
|
val extracted = extractEnergyInner(ENERGY_FOR_HUNGER_POINT * (stats.exhaustionLevel / 4f), false)
|
||||||
|
stats.setExhaustion(stats.exhaustionLevel - (extracted / ENERGY_FOR_HUNGER_POINT).toFloat() * 4f)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (feature in features.values) {
|
||||||
|
feature.tickServer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (runnable in queuedTicks) {
|
||||||
|
runnable.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
queuedTicks.clear()
|
||||||
|
|
||||||
|
if (invalidateNetworkIn > 0 && --invalidateNetworkIn == 0) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if (willBecomeAndroid != willBecomeAndroidNetwork) {
|
||||||
|
willBecomeAndroidNetwork = willBecomeAndroid
|
||||||
|
sendNetwork(WillBecomeAndroidPacket(willBecomeAndroid))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (instance in research) {
|
||||||
|
if (instance.isDirty) {
|
||||||
|
instance.isDirty = false
|
||||||
|
sendNetwork(AndroidResearchSyncPacket(instance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (instance in features.values) {
|
||||||
|
if (instance.isDirty) {
|
||||||
|
instance.isDirty = false
|
||||||
|
sendNetwork(AndroidFeatureSyncPacket(instance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
return ImpreciseFraction.ZERO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
@Suppress("name_shadowing")
|
||||||
|
var howMuch = howMuch
|
||||||
|
var drained = ImpreciseFraction.ZERO
|
||||||
|
|
||||||
|
if (!batteryItemStack.isEmpty) {
|
||||||
|
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
val extracted = it.extractEnergyOuter(howMuch, simulate)
|
||||||
|
drained += extracted
|
||||||
|
howMuch -= extracted
|
||||||
|
} else {
|
||||||
|
val extracted = it.extractEnergy(howMuch, simulate)
|
||||||
|
drained += extracted
|
||||||
|
howMuch -= extracted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (howMuch.isZero) {
|
||||||
|
if (!simulate && ply is ServerPlayer) {
|
||||||
|
ply.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
return drained
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val new = (battery - howMuch).moreThanZero()
|
||||||
|
drained += battery - new
|
||||||
|
|
||||||
|
if (!simulate) {
|
||||||
|
battery = new
|
||||||
|
|
||||||
|
if (ply is ServerPlayer) {
|
||||||
|
ply.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return drained
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
@Suppress("name_shadowing")
|
||||||
|
var howMuch = howMuch
|
||||||
|
var received = ImpreciseFraction.ZERO
|
||||||
|
|
||||||
|
if (!batteryItemStack.isEmpty) {
|
||||||
|
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
val extracted = it.receiveEnergyOuter(howMuch, simulate)
|
||||||
|
received += extracted
|
||||||
|
howMuch -= extracted
|
||||||
|
} else {
|
||||||
|
val extracted = it.receiveEnergy(howMuch, simulate)
|
||||||
|
received += extracted
|
||||||
|
howMuch -= extracted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (howMuch.isZero) {
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val new = (battery + howMuch).coerceAtMost(maxBattery)
|
||||||
|
received += new - battery
|
||||||
|
|
||||||
|
if (!simulate) {
|
||||||
|
battery = new
|
||||||
|
}
|
||||||
|
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
|
return receiveEnergyOuter(howMuch, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
override var batteryLevel: ImpreciseFraction
|
||||||
|
get() {
|
||||||
|
if (!batteryItemStack.isEmpty) {
|
||||||
|
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return battery + it.batteryLevel
|
||||||
|
} else {
|
||||||
|
return battery + it.energyStored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return battery
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
battery = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override var maxBatteryLevel: ImpreciseFraction
|
||||||
|
get() {
|
||||||
|
if (batteryItemStack != ItemStack.EMPTY) {
|
||||||
|
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return maxBattery + it.maxBatteryLevel
|
||||||
|
} else {
|
||||||
|
return maxBattery + it.maxEnergyStored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxBattery
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
maxBattery = value
|
||||||
|
}
|
||||||
|
|
||||||
|
private val resolver = LazyOptional.of { this }
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
return if (cap == MatteryCapability.ANDROID) {
|
||||||
|
resolver.cast()
|
||||||
|
} else LazyOptional.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun registerEffects(event: FMLCommonSetupEvent) {
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
||||||
|
// maybe it makes things go haywire idk
|
||||||
|
// UNAFFECTED_EFFECTS.add(MobEffects.HARM);
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.REGENERATION)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.WATER_BREATHING)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.POISON)
|
||||||
|
// even skeletons can be withered
|
||||||
|
// UNAFFECTED_EFFECTS.add(MobEffects.WITHER);
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.HEALTH_BOOST)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.ABSORPTION)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.SATURATION)
|
||||||
|
UNAFFECTED_EFFECTS.add(MobEffects.DOLPHINS_GRACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onLivingTick(event: LivingTickEvent) {
|
||||||
|
val ent = event.entity
|
||||||
|
|
||||||
|
if (ent.level.isClientSide) {
|
||||||
|
ent.getCapability(MatteryCapability.ANDROID).ifPresentK {
|
||||||
|
it.tickClient()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ent.getCapability(MatteryCapability.ANDROID).ifPresentK {
|
||||||
|
it.tick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||||
|
fun onHurtEvent(event: LivingHurtEvent) {
|
||||||
|
if (event.isCanceled) return
|
||||||
|
|
||||||
|
event.entity.getCapability(MatteryCapability.ANDROID).ifPresentK { it.onHurt(event) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity?>) {
|
||||||
|
val ent = event.`object`
|
||||||
|
|
||||||
|
if (ent is Player) {
|
||||||
|
event.addCapability(MNames.ANDROID_CAPABILITY_RS, AndroidCapability(ent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onPlayerChangeDimensionEvent(event: PlayerEvent.PlayerChangedDimensionEvent) {
|
||||||
|
event.entity.getCapability(MatteryCapability.ANDROID)
|
||||||
|
.ifPresentK { it.invalidateNetworkState() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onPlayerCloneEvent(event: PlayerEvent.Clone) {
|
||||||
|
val it = event.entity.android ?: return
|
||||||
|
|
||||||
|
var resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
||||||
|
|
||||||
|
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
||||||
|
event.original.reviveCaps()
|
||||||
|
resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
||||||
|
event.original.invalidateCaps()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val original = resolver.resolve().get()
|
||||||
|
|
||||||
|
if (original.willBecomeAndroid && event.isWasDeath) {
|
||||||
|
original.becomeAndroid()
|
||||||
|
(event.entity as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
it.deserializeNBT(original.serializeNBT())
|
||||||
|
it.invalidateNetworkState()
|
||||||
|
event.original.invalidateCaps()
|
||||||
|
}
|
||||||
|
|
||||||
|
val ENERGY_FOR_HUNGER_POINT = ImpreciseFraction(1000)
|
||||||
|
const val SLEEP_TICKS_LIMIT = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val ICapabilityProvider.android get() = getCapability(MatteryCapability.ANDROID).orNull()
|
@ -5,7 +5,6 @@ import net.minecraft.world.entity.LivingEntity
|
|||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.CapabilityEnergy
|
|
||||||
import net.minecraftforge.energy.IEnergyStorage
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import net.minecraftforge.fml.ModList
|
import net.minecraftforge.fml.ModList
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
||||||
|
@ -1,436 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.android
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
|
||||||
import net.minecraft.core.Direction
|
|
||||||
import net.minecraft.world.entity.LivingEntity
|
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
|
||||||
import java.lang.Runnable
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
|
||||||
import net.minecraft.nbt.ListTag
|
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
|
||||||
import net.minecraftforge.network.PacketDistributor
|
|
||||||
import net.minecraft.world.effect.MobEffect
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
|
||||||
import net.minecraftforge.energy.CapabilityEnergy
|
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
|
|
||||||
import net.minecraft.world.effect.MobEffects
|
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
|
||||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent
|
|
||||||
import net.minecraftforge.eventbus.api.EventPriority
|
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
|
||||||
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
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.StatNames
|
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
open class AndroidCapability(final override val entity: LivingEntity) : ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag> {
|
|
||||||
protected var battery = ImpreciseFraction.ZERO
|
|
||||||
protected var maxBattery = ImpreciseFraction(60000)
|
|
||||||
|
|
||||||
override var batteryItemStack: ItemStack = ItemStack.EMPTY
|
|
||||||
|
|
||||||
protected val features = Object2ObjectArrayMap<AndroidFeatureType<*>, AndroidFeature>()
|
|
||||||
protected val networkQueue = ArrayList<Any>()
|
|
||||||
protected val queuedTicks = ArrayList<Runnable>()
|
|
||||||
protected var tickedOnce = false
|
|
||||||
|
|
||||||
protected fun addFeature(feature: AndroidFeature): Boolean {
|
|
||||||
if (features.containsKey(feature.type)) return false
|
|
||||||
features[feature.type] = feature
|
|
||||||
|
|
||||||
if (!entity.level.isClientSide) {
|
|
||||||
queuedTicks.add(feature::applyModifiers)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
sendNetwork(AndroidFeatureSyncPacket(feature))
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
|
||||||
override fun <T : AndroidFeature> addFeature(feature: AndroidFeatureType<T>): T {
|
|
||||||
val get = features[feature]
|
|
||||||
if (get != null) return get as T
|
|
||||||
|
|
||||||
val factory = feature.create(this)
|
|
||||||
|
|
||||||
features[feature] = factory
|
|
||||||
|
|
||||||
if (!entity.level.isClientSide) {
|
|
||||||
queuedTicks.add(factory::applyModifiers)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
sendNetwork(AndroidFeatureSyncPacket(factory))
|
|
||||||
}
|
|
||||||
|
|
||||||
return factory
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeFeature(feature: AndroidFeatureType<*>): Boolean {
|
|
||||||
val removed = features.remove(feature)
|
|
||||||
|
|
||||||
if (removed != null) {
|
|
||||||
if (!entity.level.isClientSide) {
|
|
||||||
queuedTicks.add {
|
|
||||||
removed.removeModifiers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
sendNetwork(AndroidFeatureRemovePacket(removed.type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return removed != null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasFeature(feature: AndroidFeatureType<*>): Boolean {
|
|
||||||
return features.containsKey(feature)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasFeatureLevel(feature: AndroidFeatureType<*>, level: Int): Boolean {
|
|
||||||
val get = features[feature] ?: return false
|
|
||||||
return get.level >= level
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
|
||||||
override fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T? {
|
|
||||||
return features[feature] as T?
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onHurt(event: LivingHurtEvent) {
|
|
||||||
for (feature in features.values) {
|
|
||||||
feature.onHurt(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun serializeNBT(): CompoundTag {
|
|
||||||
val tag = CompoundTag()
|
|
||||||
|
|
||||||
tag["energy_stored"] = battery.serializeNBT()
|
|
||||||
tag["energy_stored_max"] = maxBattery.serializeNBT()
|
|
||||||
tag["battery"] = batteryItemStack.serializeNBT()
|
|
||||||
|
|
||||||
val featureList = ListTag()
|
|
||||||
|
|
||||||
for (feature in features.values) {
|
|
||||||
val featureNbt = feature.serializeNBT()
|
|
||||||
|
|
||||||
featureNbt["id"] = feature.type.registryName!!.toString()
|
|
||||||
featureList.add(featureNbt)
|
|
||||||
}
|
|
||||||
|
|
||||||
tag["features"] = featureList
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun deserializeNBT(compound: CompoundTag?) {
|
|
||||||
compound!!
|
|
||||||
|
|
||||||
compound.ifHas("energy_stored") {
|
|
||||||
battery = ImpreciseFraction.deserializeNBT(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
compound.ifHas("energy_stored_max") {
|
|
||||||
maxBattery = ImpreciseFraction.deserializeNBT(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
compound.ifHas("battery", CompoundTag::class.java) {
|
|
||||||
batteryItemStack = ItemStack.of(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
features.clear()
|
|
||||||
|
|
||||||
val featuresNbt = compound.getList("features", Tag.TAG_COMPOUND.toInt())
|
|
||||||
|
|
||||||
for (tag in featuresNbt) {
|
|
||||||
if (tag is CompoundTag) {
|
|
||||||
val feature = MRegistry.ANDROID_FEATURES.getValue(ResourceLocation(tag.getString("id")))
|
|
||||||
|
|
||||||
if (feature?.isApplicable(this) == true) {
|
|
||||||
val instance = feature.create(this)
|
|
||||||
|
|
||||||
instance.deserializeNBT(tag)
|
|
||||||
addFeature(instance)
|
|
||||||
|
|
||||||
if (!entity.level.isClientSide) {
|
|
||||||
queuedTicks.add(instance::applyModifiers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dropBattery() {
|
|
||||||
if (batteryItemStack.isEmpty) return
|
|
||||||
entity.spawnAtLocation(batteryItemStack)
|
|
||||||
batteryItemStack = ItemStack.EMPTY
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun sendNetwork(packet: Any) {
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
if (tickedOnce) {
|
|
||||||
AndroidNetworkChannel.send(entity, packet)
|
|
||||||
} else {
|
|
||||||
networkQueue.add(packet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun tickInnerClient() {}
|
|
||||||
protected open fun tickInnerClientAlways() {}
|
|
||||||
|
|
||||||
override fun tickClient() {
|
|
||||||
queuedTicks.clear()
|
|
||||||
|
|
||||||
if (!entity.isAlive)
|
|
||||||
return
|
|
||||||
|
|
||||||
tickInnerClientAlways()
|
|
||||||
|
|
||||||
if (isAndroid) {
|
|
||||||
tickInnerClient()
|
|
||||||
|
|
||||||
for (feature in features.values) {
|
|
||||||
feature.tickClient()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
if (!entity.isAlive) return
|
|
||||||
|
|
||||||
tickServerAlways()
|
|
||||||
|
|
||||||
if (isAndroid) {
|
|
||||||
tickServer()
|
|
||||||
|
|
||||||
for (feature in features.values) {
|
|
||||||
feature.tickServer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (runnable in queuedTicks) {
|
|
||||||
runnable.run()
|
|
||||||
}
|
|
||||||
|
|
||||||
queuedTicks.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun tickServerAlways() {}
|
|
||||||
|
|
||||||
protected open fun tickServer() {
|
|
||||||
if (entity.airSupply < entity.maxAirSupply)
|
|
||||||
entity.airSupply = entity.maxAirSupply
|
|
||||||
|
|
||||||
for (effect in UNAFFECTED_EFFECTS)
|
|
||||||
if (entity.hasEffect(effect))
|
|
||||||
entity.removeEffect(effect)
|
|
||||||
|
|
||||||
if (!batteryItemStack.isEmpty && battery < maxBattery) {
|
|
||||||
batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
|
||||||
if (it is IMatteryEnergyStorage) {
|
|
||||||
battery += it.extractEnergyInner(maxBattery - battery, false)
|
|
||||||
} else {
|
|
||||||
battery += it.extractEnergy(maxBattery - battery, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
|
||||||
return ImpreciseFraction.ZERO
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
|
||||||
@Suppress("name_shadowing")
|
|
||||||
var howMuch = howMuch
|
|
||||||
var drained = ImpreciseFraction.ZERO
|
|
||||||
|
|
||||||
if (!batteryItemStack.isEmpty) {
|
|
||||||
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
|
||||||
if (it is IMatteryEnergyStorage) {
|
|
||||||
val extracted = it.extractEnergyOuter(howMuch, simulate)
|
|
||||||
drained += extracted
|
|
||||||
howMuch -= extracted
|
|
||||||
} else {
|
|
||||||
val extracted = it.extractEnergy(howMuch, simulate)
|
|
||||||
drained += extracted
|
|
||||||
howMuch -= extracted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (howMuch.isZero) {
|
|
||||||
if (!simulate && entity is ServerPlayer) {
|
|
||||||
entity.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
return drained
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val new = (battery - howMuch).moreThanZero()
|
|
||||||
drained += battery - new
|
|
||||||
|
|
||||||
if (!simulate) {
|
|
||||||
battery = new
|
|
||||||
|
|
||||||
if (entity is ServerPlayer) {
|
|
||||||
entity.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return drained
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
|
||||||
var howMuch = howMuch
|
|
||||||
var received = ImpreciseFraction.ZERO
|
|
||||||
|
|
||||||
if (!batteryItemStack.isEmpty) {
|
|
||||||
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
|
||||||
if (it is IMatteryEnergyStorage) {
|
|
||||||
val extracted = it.receiveEnergyOuter(howMuch, simulate)
|
|
||||||
received += extracted
|
|
||||||
howMuch -= extracted
|
|
||||||
} else {
|
|
||||||
val extracted = it.receiveEnergy(howMuch, simulate)
|
|
||||||
received += extracted
|
|
||||||
howMuch -= extracted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (howMuch.isZero) {
|
|
||||||
return received
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val new = (battery + howMuch).coerceAtMost(maxBattery)
|
|
||||||
received += new - battery
|
|
||||||
|
|
||||||
if (!simulate) {
|
|
||||||
battery = new
|
|
||||||
}
|
|
||||||
|
|
||||||
return received
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
|
||||||
return receiveEnergyOuter(howMuch, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
override var batteryLevel: ImpreciseFraction
|
|
||||||
get() {
|
|
||||||
if (!batteryItemStack.isEmpty) {
|
|
||||||
batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
|
||||||
if (it is IMatteryEnergyStorage) {
|
|
||||||
return battery + it.batteryLevel
|
|
||||||
} else {
|
|
||||||
return battery + it.energyStored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return battery
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
battery = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override var maxBatteryLevel: ImpreciseFraction
|
|
||||||
get() {
|
|
||||||
if (batteryItemStack != ItemStack.EMPTY) {
|
|
||||||
val resolver = batteryItemStack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
|
||||||
if (it is IMatteryEnergyStorage) {
|
|
||||||
return maxBattery + it.maxBatteryLevel
|
|
||||||
} else {
|
|
||||||
return maxBattery + it.maxEnergyStored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxBattery
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
maxBattery = value
|
|
||||||
}
|
|
||||||
|
|
||||||
private val resolver = LazyOptional.of { this }
|
|
||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
|
||||||
return if (cap === MatteryCapability.ANDROID) {
|
|
||||||
resolver.cast()
|
|
||||||
} else LazyOptional.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun registerEffects(event: FMLCommonSetupEvent) {
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
|
||||||
// maybe it makes things go haywire idk
|
|
||||||
// UNAFFECTED_EFFECTS.add(MobEffects.HARM);
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.REGENERATION)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.WATER_BREATHING)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.POISON)
|
|
||||||
// even skeletons can be withered
|
|
||||||
// UNAFFECTED_EFFECTS.add(MobEffects.WITHER);
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.HEALTH_BOOST)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.ABSORPTION)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.SATURATION)
|
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.DOLPHINS_GRACE)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onLivingTick(event: LivingTickEvent) {
|
|
||||||
val ent = event.entity
|
|
||||||
|
|
||||||
if (ent.level.isClientSide) {
|
|
||||||
ent.getCapability(MatteryCapability.ANDROID).ifPresentK {
|
|
||||||
it.tickClient()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ent.getCapability(MatteryCapability.ANDROID).ifPresentK {
|
|
||||||
it.tick()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onHurtEvent(event: LivingHurtEvent) {
|
|
||||||
if (event.isCanceled) return
|
|
||||||
|
|
||||||
event.entity.getCapability(MatteryCapability.ANDROID).ifPresentK { cap: IAndroidCapability -> cap.onHurt(event) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val ICapabilityProvider.android get() = getCapability(MatteryCapability.ANDROID).orNull()
|
|
@ -1,356 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.android
|
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.nbt.ListTag
|
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
|
||||||
import net.minecraft.world.entity.Entity
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraftforge.event.AttachCapabilitiesEvent
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent.Clone
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
|
||||||
import net.minecraftforge.network.PacketDistributor
|
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
|
||||||
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.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
|
||||||
import ru.dbotthepony.mc.otm.network.*
|
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class AndroidCapabilityPlayer(val ply: Player) : AndroidCapability(ply) {
|
|
||||||
override var isAndroid = false
|
|
||||||
private var remoteIsAndroid = false
|
|
||||||
|
|
||||||
var willBecomeAndroid = false
|
|
||||||
private var willBecomeAndroidNetwork = false
|
|
||||||
private var shouldPlaySound = false
|
|
||||||
private val research = ArrayList<AndroidResearch>()
|
|
||||||
|
|
||||||
private var remoteBattery = ImpreciseFraction(-1)
|
|
||||||
private var remoteMaxBattery = ImpreciseFraction(-1)
|
|
||||||
private var remoteBatteryStack = ItemStack.EMPTY
|
|
||||||
|
|
||||||
private var invalidateNetworkIn = 10
|
|
||||||
|
|
||||||
fun invalidateNetworkState() {
|
|
||||||
invalidateNetworkIn = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isEverAndroid(): Boolean = isAndroid || willBecomeAndroid
|
|
||||||
|
|
||||||
fun becomeAndroidSoft() {
|
|
||||||
if (isAndroid || willBecomeAndroid) return
|
|
||||||
willBecomeAndroid = true
|
|
||||||
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message").withStyle(ChatFormatting.GRAY), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun becomeAndroid() {
|
|
||||||
if (isAndroid) return
|
|
||||||
|
|
||||||
isAndroid = true
|
|
||||||
willBecomeAndroid = false
|
|
||||||
shouldPlaySound = false
|
|
||||||
battery = ImpreciseFraction(60000)
|
|
||||||
maxBattery = ImpreciseFraction(60000)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun becomeAndroidAndKill() {
|
|
||||||
if (isAndroid) return
|
|
||||||
|
|
||||||
becomeAndroid()
|
|
||||||
ply.hurt(MRegistry.DAMAGE_BECOME_ANDROID, ply.maxHealth * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun becomeHumane() {
|
|
||||||
if (willBecomeAndroid) willBecomeAndroid = false
|
|
||||||
if (!isAndroid) return
|
|
||||||
|
|
||||||
isAndroid = false
|
|
||||||
shouldPlaySound = false
|
|
||||||
battery = ImpreciseFraction(0)
|
|
||||||
maxBattery = ImpreciseFraction(60000)
|
|
||||||
dropBattery()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun becomeHumaneAndKill() {
|
|
||||||
if (willBecomeAndroid) willBecomeAndroid = false
|
|
||||||
if (!isAndroid) return
|
|
||||||
|
|
||||||
becomeHumane()
|
|
||||||
ply.hurt(MRegistry.DAMAGE_BECOME_HUMANE, ply.maxHealth * 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun deserializeNBT(compound: CompoundTag?) {
|
|
||||||
super.deserializeNBT(compound!!)
|
|
||||||
|
|
||||||
isAndroid = compound.getBoolean("is_android")
|
|
||||||
willBecomeAndroid = compound.getBoolean("will_become_android")
|
|
||||||
research.clear()
|
|
||||||
|
|
||||||
val list = compound.getList("research", Tag.TAG_COMPOUND.toInt())
|
|
||||||
|
|
||||||
for (tag in list) {
|
|
||||||
if (tag is CompoundTag) {
|
|
||||||
val research = MRegistry.ANDROID_RESEARCH.getValue(ResourceLocation(tag.getString("id")))
|
|
||||||
|
|
||||||
if (research != null) {
|
|
||||||
val instance = research.factory(this)
|
|
||||||
instance.deserializeNBT(tag)
|
|
||||||
this.research.add(instance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun obliviate(refund: Boolean = true) {
|
|
||||||
if (refund) {
|
|
||||||
for (instance in research) {
|
|
||||||
if (instance.isResearched) {
|
|
||||||
instance.unResearch()
|
|
||||||
instance.refund(simulate = false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val copy = java.util.List.copyOf(features.values)
|
|
||||||
|
|
||||||
for (feature in copy) {
|
|
||||||
removeFeature(feature.type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun serializeNBT(): CompoundTag {
|
|
||||||
val tag = super.serializeNBT()
|
|
||||||
|
|
||||||
tag["is_android"] = isAndroid
|
|
||||||
tag["will_become_android"] = willBecomeAndroid
|
|
||||||
|
|
||||||
val list = ListTag()
|
|
||||||
|
|
||||||
for (instance in research) {
|
|
||||||
val researchTag = instance.serializeNBT()
|
|
||||||
|
|
||||||
researchTag["id"] = instance.type.registryName!!.toString()
|
|
||||||
list.add(researchTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
tag["research"] = list
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : AndroidResearch> getResearch(type: AndroidResearchType<T>): T {
|
|
||||||
for (instance in research) {
|
|
||||||
if (instance.type === type) {
|
|
||||||
return instance as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val instance = type.factory(this)
|
|
||||||
research.add(instance)
|
|
||||||
return instance
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastJumpTicks = 14
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
super.tick()
|
|
||||||
|
|
||||||
if (invalidateNetworkIn > 0 && --invalidateNetworkIn == 0) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if (willBecomeAndroid != willBecomeAndroidNetwork) {
|
|
||||||
willBecomeAndroidNetwork = willBecomeAndroid
|
|
||||||
sendNetwork(WillBecomeAndroidPacket(willBecomeAndroid))
|
|
||||||
}
|
|
||||||
|
|
||||||
for (instance in research) {
|
|
||||||
if (instance.isDirty) {
|
|
||||||
instance.isDirty = false
|
|
||||||
sendNetwork(AndroidResearchSyncPacket(instance))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (instance in features.values) {
|
|
||||||
if (instance.isDirty) {
|
|
||||||
instance.isDirty = false
|
|
||||||
sendNetwork(AndroidFeatureSyncPacket(instance))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sleepTicks = 0
|
|
||||||
|
|
||||||
override fun tickInnerClientAlways() {
|
|
||||||
super.tickInnerClientAlways()
|
|
||||||
|
|
||||||
if (willBecomeAndroid) {
|
|
||||||
if (ply.isSleeping) {
|
|
||||||
sleepTicks++
|
|
||||||
} else {
|
|
||||||
sleepTicks = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tickServerAlways() {
|
|
||||||
super.tickServerAlways()
|
|
||||||
|
|
||||||
if (willBecomeAndroid) {
|
|
||||||
if (ply.isSleeping) {
|
|
||||||
sleepTicks++
|
|
||||||
|
|
||||||
if (sleepTicks > SLEEP_TICKS_LIMIT) {
|
|
||||||
becomeAndroid()
|
|
||||||
shouldPlaySound = true
|
|
||||||
sleepTicks = 0
|
|
||||||
|
|
||||||
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sleepTicks = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun tickServer() {
|
|
||||||
super.tickServer()
|
|
||||||
|
|
||||||
// TODO: Maybe passive drain?
|
|
||||||
// extractEnergyInner(BigDecimal.valueOf(new Random().nextDouble()), false);
|
|
||||||
if (ply.isSwimming && !hasFeature(AndroidFeatures.AIR_BAGS)) {
|
|
||||||
ply.isSwimming = false
|
|
||||||
}
|
|
||||||
|
|
||||||
val stats = ply.foodData
|
|
||||||
|
|
||||||
while (stats.foodLevel < 18 && extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true) >= ENERGY_FOR_HUNGER_POINT) {
|
|
||||||
extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false)
|
|
||||||
stats.foodLevel = stats.foodLevel + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// "block" quick regeneration
|
|
||||||
// also cause power to generate while in peaceful
|
|
||||||
while (stats.foodLevel > 18 && receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, true) >= ENERGY_FOR_HUNGER_POINT) {
|
|
||||||
receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, false)
|
|
||||||
stats.foodLevel = stats.foodLevel - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
val foodLevel = stats.foodLevel.toFloat()
|
|
||||||
|
|
||||||
if (stats.saturationLevel < foodLevel) {
|
|
||||||
val extracted = extractEnergyInner(ENERGY_FOR_HUNGER_POINT * (foodLevel - stats.saturationLevel), false)
|
|
||||||
stats.setSaturation(stats.saturationLevel + (extracted / ENERGY_FOR_HUNGER_POINT).toFloat())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stats.exhaustionLevel > 0f) {
|
|
||||||
val extracted = extractEnergyInner(ENERGY_FOR_HUNGER_POINT * (stats.exhaustionLevel / 4f), false)
|
|
||||||
stats.setExhaustion(stats.exhaustionLevel - (extracted / ENERGY_FOR_HUNGER_POINT).toFloat() * 4f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
companion object {
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity?>) {
|
|
||||||
val ent = event.`object`
|
|
||||||
|
|
||||||
if (ent is Player) {
|
|
||||||
event.addCapability(MNames.ANDROID_CAPABILITY_RS, AndroidCapabilityPlayer(ent))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onPlayerChangeDimensionEvent(event: PlayerChangedDimensionEvent) {
|
|
||||||
event.entity.getCapability(MatteryCapability.ANDROID)
|
|
||||||
.ifPresentK { (it as AndroidCapabilityPlayer).invalidateNetworkState() }
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onPlayerCloneEvent(event: Clone) {
|
|
||||||
val it = event.entity.android as AndroidCapabilityPlayer? ?: return
|
|
||||||
|
|
||||||
var resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
|
||||||
|
|
||||||
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
|
||||||
event.original.reviveCaps()
|
|
||||||
resolver = event.original.getCapability(MatteryCapability.ANDROID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolver.isPresent || resolver.resolve().isEmpty) {
|
|
||||||
event.original.invalidateCaps()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val original = resolver.resolve().get() as AndroidCapabilityPlayer
|
|
||||||
|
|
||||||
if (original.willBecomeAndroid && event.isWasDeath) {
|
|
||||||
original.becomeAndroid()
|
|
||||||
(event.entity as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.deserializeNBT(original.serializeNBT())
|
|
||||||
it.invalidateNetworkState()
|
|
||||||
event.original.invalidateCaps()
|
|
||||||
}
|
|
||||||
|
|
||||||
val ENERGY_FOR_HUNGER_POINT = ImpreciseFraction(1000)
|
|
||||||
const val SLEEP_TICKS_LIMIT = 80
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.android
|
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.world.entity.LivingEntity
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
|
||||||
fun tick()
|
|
||||||
fun tickClient()
|
|
||||||
val entity: LivingEntity
|
|
||||||
fun <T : AndroidFeature> addFeature(feature: AndroidFeatureType<T>): T
|
|
||||||
fun removeFeature(feature: AndroidFeatureType<*>): Boolean
|
|
||||||
fun hasFeature(feature: AndroidFeatureType<*>): Boolean
|
|
||||||
fun hasFeatureLevel(feature: AndroidFeatureType<*>, level: Int): Boolean
|
|
||||||
|
|
||||||
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> {
|
|
||||||
val get = getFeature(feature)
|
|
||||||
return if (get != null) Optional.of(get) else Optional.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : AndroidFeature> ifFeature(feature: AndroidFeatureType<T>, consumer: (T) -> Unit) {
|
|
||||||
val get = getFeature(feature)
|
|
||||||
|
|
||||||
if (get != null) {
|
|
||||||
consumer(get)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isAndroid: Boolean get() = true
|
|
||||||
|
|
||||||
fun onHurt(event: LivingHurtEvent) {}
|
|
||||||
var batteryItemStack: ItemStack
|
|
||||||
|
|
||||||
override var batteryLevel: ImpreciseFraction
|
|
||||||
override var maxBatteryLevel: ImpreciseFraction
|
|
||||||
}
|
|
@ -19,7 +19,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
|||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.android
|
import ru.dbotthepony.mc.otm.capability.android
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
import ru.dbotthepony.mc.otm.ifPresentK
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ object AndroidGui {
|
|||||||
private var knownButton: Button? = null
|
private var knownButton: Button? = null
|
||||||
private var knownButtonScreen: InBedChatScreen? = null
|
private var knownButtonScreen: InBedChatScreen? = null
|
||||||
|
|
||||||
private var lastState: AndroidCapabilityPlayer? = null
|
private var lastState: AndroidCapability? = null
|
||||||
|
|
||||||
private val button_shaker = Random()
|
private val button_shaker = Random()
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ object AndroidGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
||||||
if (!(it as AndroidCapabilityPlayer).willBecomeAndroid) {
|
if (!it.willBecomeAndroid) {
|
||||||
knownButton!!.x = knownButtonX
|
knownButton!!.x = knownButtonX
|
||||||
knownButton!!.y = knownButtonY
|
knownButton!!.y = knownButtonY
|
||||||
knownButtonX = -1
|
knownButtonX = -1
|
||||||
@ -73,7 +73,7 @@ object AndroidGui {
|
|||||||
return@ifPresentK
|
return@ifPresentK
|
||||||
}
|
}
|
||||||
|
|
||||||
val dispersion = (10.0 * Math.max(0, it.sleepTicks - 20) / (AndroidCapabilityPlayer.SLEEP_TICKS_LIMIT - 20)).toInt()
|
val dispersion = (10.0 * Math.max(0, it.sleepTicks - 20) / (AndroidCapability.SLEEP_TICKS_LIMIT - 20)).toInt()
|
||||||
|
|
||||||
knownButton!!.x =
|
knownButton!!.x =
|
||||||
knownButtonX - dispersion / 2 + (button_shaker.nextDouble() * dispersion).toInt()
|
knownButtonX - dispersion / 2 + (button_shaker.nextDouble() * dispersion).toInt()
|
||||||
@ -103,7 +103,7 @@ object AndroidGui {
|
|||||||
knownButtonScreen = screen
|
knownButtonScreen = screen
|
||||||
|
|
||||||
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
minecraft.player?.getCapability(MatteryCapability.ANDROID)?.ifPresentK {
|
||||||
if ((it as AndroidCapabilityPlayer).willBecomeAndroid) {
|
if (it.willBecomeAndroid) {
|
||||||
knownButtonScreen = screen
|
knownButtonScreen = screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,12 +134,9 @@ object AndroidGui {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val lazy = ply.android
|
var android = ply.android
|
||||||
var android: AndroidCapabilityPlayer? = null
|
|
||||||
|
|
||||||
if (lazy != null) {
|
if (!ply.isAlive && android == null) {
|
||||||
android = lazy as AndroidCapabilityPlayer
|
|
||||||
} else if (!ply.isAlive) {
|
|
||||||
android = lastState
|
android = lastState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.client
|
|||||||
import net.minecraftforge.client.event.MovementInputUpdateEvent
|
import net.minecraftforge.client.event.MovementInputUpdateEvent
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import ru.dbotthepony.mc.otm.capability.android
|
import ru.dbotthepony.mc.otm.capability.android
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@ -12,7 +11,7 @@ fun inputEvent(event: MovementInputUpdateEvent) {
|
|||||||
val ply = event.entity
|
val ply = event.entity
|
||||||
val input = event.input
|
val input = event.input
|
||||||
|
|
||||||
val cap = ply.android as? AndroidCapabilityPlayer ?: return
|
val cap = ply.android ?: return
|
||||||
|
|
||||||
if (cap.hasFeature(AndroidFeatures.AIR_BAGS))
|
if (cap.hasFeature(AndroidFeatures.AIR_BAGS))
|
||||||
return
|
return
|
||||||
|
@ -14,8 +14,7 @@ import org.lwjgl.opengl.GL30
|
|||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||||
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.android
|
||||||
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
|
||||||
|
@ -11,13 +11,13 @@ import net.minecraft.world.entity.player.Inventory
|
|||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||||
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.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
|
||||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability
|
|
||||||
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
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.ifPresentK
|
||||||
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.AndroidNetworkChannel
|
||||||
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||||
@ -43,8 +43,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
||||||
ru.dbotthepony.mc.otm.client.minecraft.player!!.getCapability(MatteryCapability.ANDROID)
|
ru.dbotthepony.mc.otm.client.minecraft.player!!.getCapability(MatteryCapability.ANDROID)
|
||||||
.ifPresent { _cap: IAndroidCapability? ->
|
.ifPresentK {
|
||||||
if (_cap is AndroidCapabilityPlayer) {
|
|
||||||
if (node.isResearched) {
|
if (node.isResearched) {
|
||||||
RESEARCHED.setSystemColor()
|
RESEARCHED.setSystemColor()
|
||||||
} else if (node.canResearch) {
|
} else if (node.canResearch) {
|
||||||
@ -68,7 +67,6 @@ 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) {
|
||||||
@ -108,7 +106,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
private val createdButtons = Array(100) { arrayOfNulls<AndroidResearchButton>(1000) }
|
private val createdButtons = Array(100) { arrayOfNulls<AndroidResearchButton>(1000) }
|
||||||
private val createdButtonsIdx = IntArray(100)
|
private val createdButtonsIdx = IntArray(100)
|
||||||
|
|
||||||
private fun dive(cap: AndroidCapabilityPlayer, research: AndroidResearchType<*>, level: Int) {
|
private fun dive(cap: AndroidCapability, research: AndroidResearchType<*>, level: Int) {
|
||||||
if (seen.contains(research)) return
|
if (seen.contains(research)) return
|
||||||
seen.add(research)
|
seen.add(research)
|
||||||
|
|
||||||
@ -156,14 +154,11 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
}
|
}
|
||||||
|
|
||||||
minecraft?.player?.getCapability(MatteryCapability.ANDROID)?.ifPresent {
|
minecraft?.player?.getCapability(MatteryCapability.ANDROID)?.ifPresent {
|
||||||
if (it !is AndroidCapabilityPlayer)
|
|
||||||
return@ifPresent
|
|
||||||
|
|
||||||
Arrays.fill(rows, null)
|
Arrays.fill(rows, null)
|
||||||
nextX = 0f
|
nextX = 0f
|
||||||
|
|
||||||
for (research in MRegistry.ANDROID_RESEARCH.values) {
|
for (research in MRegistry.ANDROID_RESEARCH.values) {
|
||||||
if (research.definedPrerequisites.size == 0) {
|
if (research.definedPrerequisites.isEmpty()) {
|
||||||
dive(it, research, 0)
|
dive(it, research, 0)
|
||||||
|
|
||||||
var max = 0f
|
var max = 0f
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraftforge.common.util.FakePlayer
|
|||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
|
|
||||||
enum class PillType {
|
enum class PillType {
|
||||||
BECOME_ANDROID, BECOME_HUMANE, OBLIVION
|
BECOME_ANDROID, BECOME_HUMANE, OBLIVION
|
||||||
@ -98,14 +98,14 @@ class PillItem(val pillType: PillType) :
|
|||||||
|
|
||||||
val resolver = ply.getCapability(MatteryCapability.ANDROID).resolve()
|
val resolver = ply.getCapability(MatteryCapability.ANDROID).resolve()
|
||||||
|
|
||||||
if (resolver.isEmpty || resolver.get() !is AndroidCapabilityPlayer)
|
if (resolver.isEmpty)
|
||||||
return super.use(level, ply, hand)
|
return super.use(level, ply, hand)
|
||||||
|
|
||||||
val cap = resolver.get() as AndroidCapabilityPlayer
|
val cap = resolver.get()
|
||||||
|
|
||||||
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)
|
||||||
@ -122,10 +122,10 @@ class PillItem(val pillType: PillType) :
|
|||||||
if (ent is Player) {
|
if (ent is Player) {
|
||||||
val resolver = ent.getCapability(MatteryCapability.ANDROID).resolve()
|
val resolver = ent.getCapability(MatteryCapability.ANDROID).resolve()
|
||||||
|
|
||||||
if (resolver.isEmpty || resolver.get() !is AndroidCapabilityPlayer)
|
if (resolver.isEmpty)
|
||||||
return super.finishUsingItem(stack, level, ent)
|
return super.finishUsingItem(stack, level, ent)
|
||||||
|
|
||||||
val cap = resolver.get() as AndroidCapabilityPlayer
|
val cap = resolver.get()
|
||||||
|
|
||||||
if (pillType == PillType.OBLIVION && cap.isAndroid) {
|
if (pillType == PillType.OBLIVION && cap.isAndroid) {
|
||||||
if (!ent.abilities.instabuild) {
|
if (!ent.abilities.instabuild) {
|
||||||
@ -136,7 +136,7 @@ class PillItem(val pillType: PillType) :
|
|||||||
cap.obliviate()
|
cap.obliviate()
|
||||||
ent.displayClientMessage(TranslatableComponent("otm.pill.message_oblivion").withStyle(ChatFormatting.GRAY), false)
|
ent.displayClientMessage(TranslatableComponent("otm.pill.message_oblivion").withStyle(ChatFormatting.GRAY), false)
|
||||||
}
|
}
|
||||||
} else if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid()) {
|
} else if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid) {
|
||||||
if (ent.abilities.instabuild) {
|
if (ent.abilities.instabuild) {
|
||||||
if (ent is ServerPlayer) {
|
if (ent is ServerPlayer) {
|
||||||
cap.becomeAndroid()
|
cap.becomeAndroid()
|
||||||
@ -148,7 +148,7 @@ class PillItem(val pillType: PillType) :
|
|||||||
cap.becomeAndroidSoft()
|
cap.becomeAndroidSoft()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pillType == PillType.BECOME_HUMANE && cap.isEverAndroid()) {
|
} else if (pillType == PillType.BECOME_HUMANE && cap.isEverAndroid) {
|
||||||
if (ent.abilities.instabuild) {
|
if (ent.abilities.instabuild) {
|
||||||
if (ent is ServerPlayer) {
|
if (ent is ServerPlayer) {
|
||||||
cap.becomeHumane()
|
cap.becomeHumane()
|
||||||
|
@ -6,12 +6,12 @@ import net.minecraft.world.entity.player.Player
|
|||||||
import net.minecraft.world.inventory.Slot
|
import net.minecraft.world.inventory.Slot
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.capability.AndroidCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
|
|
||||||
private class AndroidStationContainer(val player: Player) : SimpleContainer(1) {
|
private class AndroidStationContainer(player: Player) : SimpleContainer(1) {
|
||||||
var android: IAndroidCapability? = null
|
var android: AndroidCapability? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
player.getCapability(MatteryCapability.ANDROID).ifPresent {
|
player.getCapability(MatteryCapability.ANDROID).ifPresent {
|
||||||
@ -22,7 +22,7 @@ private class AndroidStationContainer(val player: Player) : SimpleContainer(1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class AndroidBatterySlot(container: AndroidStationContainer, index: Int) : BatterySlot(container, index) {
|
private class AndroidBatterySlot(container: AndroidStationContainer, index: Int) : BatterySlot(container, index) {
|
||||||
val android: IAndroidCapability? = container.android
|
val android: AndroidCapability? = container.android
|
||||||
|
|
||||||
override fun set(stack: ItemStack) {
|
override fun set(stack: ItemStack) {
|
||||||
super.set(stack)
|
super.set(stack)
|
||||||
|
@ -10,6 +10,8 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature
|
|||||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||||
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.AndroidCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.android
|
||||||
import ru.dbotthepony.mc.otm.capability.android.*
|
import ru.dbotthepony.mc.otm.capability.android.*
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
@ -24,24 +26,24 @@ import java.util.function.Supplier
|
|||||||
sealed class AndroidStatusPacket : MatteryPacket {
|
sealed class AndroidStatusPacket : MatteryPacket {
|
||||||
override fun write(buff: FriendlyByteBuf) {}
|
override fun write(buff: FriendlyByteBuf) {}
|
||||||
|
|
||||||
protected abstract fun play(capability: AndroidCapabilityPlayer)
|
protected abstract fun play(capability: AndroidCapability)
|
||||||
|
|
||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
play(minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork)
|
play(minecraft.player?.android ?: return@enqueueWork)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object IsAndroidPacket : AndroidStatusPacket() {
|
object IsAndroidPacket : AndroidStatusPacket() {
|
||||||
override fun play(capability: AndroidCapabilityPlayer) {
|
override fun play(capability: AndroidCapability) {
|
||||||
capability.isAndroid = true
|
capability.isAndroid = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object IsNotAndroidPacket : AndroidStatusPacket() {
|
object IsNotAndroidPacket : AndroidStatusPacket() {
|
||||||
override fun play(capability: AndroidCapabilityPlayer) {
|
override fun play(capability: AndroidCapability) {
|
||||||
capability.isAndroid = false
|
capability.isAndroid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,13 +51,13 @@ object IsNotAndroidPacket : AndroidStatusPacket() {
|
|||||||
fun IsAndroidPacket(status: Boolean) = if (status) IsAndroidPacket else IsNotAndroidPacket
|
fun IsAndroidPacket(status: Boolean) = if (status) IsAndroidPacket else IsNotAndroidPacket
|
||||||
|
|
||||||
object WillBecomeAndroidPacket : AndroidStatusPacket() {
|
object WillBecomeAndroidPacket : AndroidStatusPacket() {
|
||||||
override fun play(capability: AndroidCapabilityPlayer) {
|
override fun play(capability: AndroidCapability) {
|
||||||
capability.willBecomeAndroid = true
|
capability.willBecomeAndroid = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object WillNotBecomeAndroidPacket : AndroidStatusPacket() {
|
object WillNotBecomeAndroidPacket : AndroidStatusPacket() {
|
||||||
override fun play(capability: AndroidCapabilityPlayer) {
|
override fun play(capability: AndroidCapability) {
|
||||||
capability.willBecomeAndroid = false
|
capability.willBecomeAndroid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +73,7 @@ class AndroidResearchRequestPacket(val type: AndroidResearchType<*>) : MatteryPa
|
|||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val ply = context.get().sender ?: return@enqueueWork
|
val ply = context.get().sender ?: return@enqueueWork
|
||||||
val android = ply.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = ply.android ?: return@enqueueWork
|
||||||
|
|
||||||
if (!android.isAndroid || ply.containerMenu !is AndroidStationMenu)
|
if (!android.isAndroid || ply.containerMenu !is AndroidStationMenu)
|
||||||
return@enqueueWork
|
return@enqueueWork
|
||||||
@ -107,7 +109,7 @@ class AndroidResearchSyncPacket(val type: AndroidResearchType<*>, val dataList:
|
|||||||
|
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = minecraft.player?.android ?: return@enqueueWork
|
||||||
|
|
||||||
android.getResearch(type).readNetwork(ByteArrayInputStream(dataBytes))
|
android.getResearch(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||||
}
|
}
|
||||||
@ -137,7 +139,7 @@ class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: Fa
|
|||||||
|
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = minecraft.player?.android ?: return@enqueueWork
|
||||||
|
|
||||||
android.computeIfAbsent(type).readNetwork(ByteArrayInputStream(dataBytes))
|
android.computeIfAbsent(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||||
}
|
}
|
||||||
@ -161,7 +163,7 @@ class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : MatteryPacke
|
|||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = minecraft.player?.android ?: return@enqueueWork
|
||||||
|
|
||||||
android.removeFeature(type)
|
android.removeFeature(type)
|
||||||
}
|
}
|
||||||
@ -182,7 +184,7 @@ class AndroidBatteryItemPacket(val item: ItemStack) : MatteryPacket {
|
|||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = minecraft.player?.android ?: return@enqueueWork
|
||||||
|
|
||||||
android.batteryItemStack = item
|
android.batteryItemStack = item
|
||||||
}
|
}
|
||||||
@ -204,7 +206,7 @@ class AndroidEnergyLevelPacket(val level: ImpreciseFraction, val isMaxEnergy: Bo
|
|||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
context.get().packetHandled = true
|
context.get().packetHandled = true
|
||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val android = minecraft.player?.android as? AndroidCapabilityPlayer ?: return@enqueueWork
|
val android = minecraft.player?.android ?: return@enqueueWork
|
||||||
|
|
||||||
if (isMaxEnergy) {
|
if (isMaxEnergy) {
|
||||||
android.maxBatteryLevel = level
|
android.maxBatteryLevel = level
|
||||||
|
Loading…
Reference in New Issue
Block a user