Move Android capability to kotlin and fix issues along the way
This commit is contained in:
parent
0acbdc8c69
commit
9efb4d6176
@ -126,8 +126,8 @@ public class OverdriveThatMatters {
|
||||
|
||||
// Register ourselves for server and other game events we are interested in
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.class);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.class);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.Companion);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.Companion);
|
||||
MinecraftForge.EVENT_BUS.register(MatterRegistry.class);
|
||||
MinecraftForge.EVENT_BUS.register(BlockEntityBlackHole.BlackHoleExplosionQueue.class);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,328 +1,285 @@
|
||||
package ru.dbotthepony.mc.otm.capability.android;
|
||||
package ru.dbotthepony.mc.otm.capability.android
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearch;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
||||
import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket;
|
||||
import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket;
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraftforge.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 ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket
|
||||
import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.*
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply) {
|
||||
@JvmField
|
||||
var is_android = false
|
||||
private var network_is_android = false
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class AndroidCapabilityPlayer extends AndroidCapability {
|
||||
public boolean is_android = false;
|
||||
private boolean network_is_android = false;
|
||||
@JvmField
|
||||
var will_become_android = false
|
||||
private var network_will_become_android = false
|
||||
private val research = ArrayList<AndroidResearch>()
|
||||
|
||||
public boolean will_become_android = false;
|
||||
private boolean network_will_become_android = false;
|
||||
override fun invalidateNetworkState() {
|
||||
super.invalidateNetworkState()
|
||||
|
||||
private final ArrayList<AndroidResearch> research_list = new ArrayList<>();
|
||||
network_is_android = false
|
||||
network_will_become_android = false
|
||||
|
||||
@Override
|
||||
public void invalidateNetworkState() {
|
||||
super.invalidateNetworkState();
|
||||
network_is_android = false;
|
||||
network_will_become_android = false;
|
||||
|
||||
for (var instance : research_list) {
|
||||
instance.dirty = true;
|
||||
for (instance in research) {
|
||||
instance.dirty = true
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAndroid() {
|
||||
return is_android;
|
||||
override fun isAndroid(): Boolean = is_android
|
||||
fun isEverAndroid(): Boolean = is_android || will_become_android
|
||||
|
||||
fun becomeAndroidSoft() {
|
||||
if (is_android || will_become_android) return
|
||||
will_become_android = true
|
||||
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message").withStyle(ChatFormatting.GRAY), false)
|
||||
}
|
||||
|
||||
public boolean isEverAndroid() {
|
||||
return is_android || will_become_android;
|
||||
fun becomeAndroid() {
|
||||
if (is_android) return
|
||||
|
||||
is_android = true
|
||||
will_become_android = false
|
||||
energy_stored = Fraction(60000)
|
||||
energy_stored_max = Fraction(60000)
|
||||
}
|
||||
|
||||
public void becomeAndroidSoft() {
|
||||
if (is_android || will_become_android)
|
||||
return;
|
||||
fun becomeAndroidAndKill() {
|
||||
if (is_android) return
|
||||
|
||||
will_become_android = true;
|
||||
|
||||
if (ent instanceof ServerPlayer ply) {
|
||||
ply.displayClientMessage(new TranslatableComponent("otm.pill.message").withStyle(ChatFormatting.GRAY), false);
|
||||
}
|
||||
becomeAndroid()
|
||||
ply.hurt(Registry.DAMAGE_BECOME_ANDROID, ply.maxHealth * 2)
|
||||
}
|
||||
|
||||
public void becomeAndroid() {
|
||||
if (is_android)
|
||||
return;
|
||||
fun becomeHumane() {
|
||||
if (will_become_android) will_become_android = false
|
||||
if (!is_android) return
|
||||
|
||||
is_android = true;
|
||||
will_become_android = false;
|
||||
energy_stored = new Fraction(60_000);
|
||||
energy_stored_max = new Fraction(60_000);
|
||||
is_android = false
|
||||
energy_stored = Fraction(0)
|
||||
energy_stored_max = Fraction(60000)
|
||||
dropBattery()
|
||||
}
|
||||
|
||||
public void becomeAndroidAndKill() {
|
||||
if (is_android)
|
||||
return;
|
||||
fun becomeHumaneAndKill() {
|
||||
if (will_become_android) will_become_android = false
|
||||
if (!is_android) return
|
||||
|
||||
becomeAndroid();
|
||||
ply.hurt(Registry.DAMAGE_BECOME_ANDROID, ply.getMaxHealth() * 2);
|
||||
becomeHumane()
|
||||
ply.hurt(Registry.DAMAGE_BECOME_HUMANE, ply.maxHealth * 2)
|
||||
}
|
||||
|
||||
public void becomeHumane() {
|
||||
if (will_become_android)
|
||||
will_become_android = false;
|
||||
override fun deserializeNBT(compound: CompoundTag?) {
|
||||
super.deserializeNBT(compound!!)
|
||||
|
||||
if (!is_android)
|
||||
return;
|
||||
is_android = compound.getBoolean("is_android")
|
||||
will_become_android = compound.getBoolean("will_become_android")
|
||||
research.clear()
|
||||
|
||||
is_android = false;
|
||||
val list = compound.getList("research", Tag.TAG_COMPOUND.toInt())
|
||||
|
||||
energy_stored = new Fraction(0);
|
||||
energy_stored_max = new Fraction(60_000);
|
||||
|
||||
dropBattery();
|
||||
}
|
||||
|
||||
public void becomeHumaneAndKill() {
|
||||
if (will_become_android)
|
||||
will_become_android = false;
|
||||
|
||||
if (!is_android)
|
||||
return;
|
||||
|
||||
becomeHumane();
|
||||
ply.hurt(Registry.DAMAGE_BECOME_HUMANE, ply.getMaxHealth() * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag compound) {
|
||||
super.deserializeNBT(compound);
|
||||
|
||||
is_android = compound.getBoolean("is_android");
|
||||
will_become_android = compound.getBoolean("will_become_android");
|
||||
|
||||
research_list.clear();
|
||||
|
||||
var list = compound.getList("research", Tag.TAG_COMPOUND);
|
||||
|
||||
for (var _tag : list) {
|
||||
if (_tag instanceof CompoundTag tag) {
|
||||
var research = Registry.ANDROID_RESEARCH.getValue(new ResourceLocation(tag.getString("id")));
|
||||
for (tag in list) {
|
||||
if (tag is CompoundTag) {
|
||||
val research = Registry.ANDROID_RESEARCH.getValue(ResourceLocation(tag.getString("id")))
|
||||
|
||||
if (research != null) {
|
||||
var instance = research.factory(this);
|
||||
instance.deserializeNBT(tag);
|
||||
research_list.add(instance);
|
||||
val instance = research.factory(this)
|
||||
instance.deserializeNBT(tag)
|
||||
this.research.add(instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
CompoundTag tag = super.serializeNBT();
|
||||
tag.putBoolean("is_android", is_android);
|
||||
tag.putBoolean("will_become_android", will_become_android);
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
val tag = super.serializeNBT()
|
||||
|
||||
var list = new ListTag();
|
||||
tag["is_android"] = is_android
|
||||
tag["will_become_android"] = will_become_android
|
||||
|
||||
for (var instance : research_list) {
|
||||
var _tag = new CompoundTag();
|
||||
instance.serializeNBT(_tag);
|
||||
_tag.putString("id", Objects.requireNonNull(instance.type.getRegistryName()).toString());
|
||||
list.add(_tag);
|
||||
val list = ListTag()
|
||||
|
||||
for (instance in research) {
|
||||
val researchTag = CompoundTag()
|
||||
instance.serializeNBT(researchTag)
|
||||
|
||||
researchTag["id"] = instance.type.registryName!!.toString()
|
||||
list.add(researchTag)
|
||||
}
|
||||
|
||||
tag.put("research", list);
|
||||
|
||||
return tag;
|
||||
tag["research"] = list
|
||||
return tag
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends AndroidResearch> T getResearch(AndroidResearchType<T> type) {
|
||||
for (var instance : research_list) {
|
||||
if (instance.type == type) {
|
||||
return (T) instance;
|
||||
fun <T : AndroidResearch> getResearch(type: AndroidResearchType<T>): T {
|
||||
for (instance in research) {
|
||||
if (instance.type === type) {
|
||||
return instance as T
|
||||
}
|
||||
}
|
||||
|
||||
var instance = type.factory(this);
|
||||
research_list.add(instance);
|
||||
return instance;
|
||||
val instance = type.factory(this)
|
||||
research.add(instance)
|
||||
return instance
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@SuppressWarnings("unused")
|
||||
public static void onAttachCapabilityEvent(AttachCapabilitiesEvent<Entity> event) {
|
||||
if (event.getObject() instanceof Player ply) {
|
||||
event.addCapability(Registry.Names.ANDROID_CAPABILITY, new AndroidCapabilityPlayer(ply));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@SuppressWarnings("unused")
|
||||
public static void onPlayerChangeDimensionEvent(PlayerEvent.PlayerChangedDimensionEvent event) {
|
||||
event.getPlayer().getCapability(MatteryCapability.ANDROID).ifPresent(IAndroidCapability::invalidateNetworkState);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@SuppressWarnings("unused")
|
||||
public static void onPlayerCloneEvent(PlayerEvent.Clone event) {
|
||||
event.getPlayer().getCapability(MatteryCapability.ANDROID).ifPresent((cap) -> {
|
||||
LazyOptional<IAndroidCapability> resolver = event.getOriginal().getCapability(MatteryCapability.ANDROID);
|
||||
|
||||
if (!resolver.isPresent() || resolver.resolve().isEmpty()) {
|
||||
event.getOriginal().reviveCaps();
|
||||
resolver = event.getOriginal().getCapability(MatteryCapability.ANDROID);
|
||||
}
|
||||
|
||||
if (!resolver.isPresent() || resolver.resolve().isEmpty()) {
|
||||
event.getOriginal().invalidateCaps();
|
||||
return;
|
||||
}
|
||||
|
||||
var original = (AndroidCapabilityPlayer) resolver.resolve().get();
|
||||
|
||||
if (original.will_become_android && event.isWasDeath()) {
|
||||
original.becomeAndroid();
|
||||
|
||||
if (event.getPlayer() instanceof ServerPlayer ply) {
|
||||
ply.displayClientMessage(new TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false);
|
||||
}
|
||||
}
|
||||
|
||||
cap.deserializeNBT(original.serializeNBT());
|
||||
cap.invalidateNetworkState();
|
||||
event.getOriginal().invalidateCaps();
|
||||
});
|
||||
}
|
||||
|
||||
public int last_jump_ticks = 14;
|
||||
public final Player ply;
|
||||
|
||||
public AndroidCapabilityPlayer(Player ent) {
|
||||
super(ent);
|
||||
ply = ent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickNetwork() {
|
||||
super.tickNetwork();
|
||||
@JvmField
|
||||
var last_jump_ticks = 14
|
||||
|
||||
override fun tickNetwork() {
|
||||
super.tickNetwork()
|
||||
if (is_android != network_is_android) {
|
||||
network_is_android = is_android;
|
||||
sendNetwork(new AndroidStatusPacket(AndroidStatusPacket.Type.IS_ANDROID, is_android));
|
||||
network_is_android = is_android
|
||||
sendNetwork(AndroidStatusPacket(AndroidStatusPacket.Type.IS_ANDROID, is_android))
|
||||
}
|
||||
|
||||
if (will_become_android != network_will_become_android) {
|
||||
network_will_become_android = will_become_android;
|
||||
sendNetwork(new AndroidStatusPacket(AndroidStatusPacket.Type.WILL_BECOME_ANDROID, will_become_android));
|
||||
network_will_become_android = will_become_android
|
||||
sendNetwork(AndroidStatusPacket(AndroidStatusPacket.Type.WILL_BECOME_ANDROID, will_become_android))
|
||||
}
|
||||
|
||||
for (var instance : research_list) {
|
||||
for (instance in research) {
|
||||
if (instance.dirty) {
|
||||
instance.dirty = false;
|
||||
sendNetwork(new AndroidResearchPacket(instance));
|
||||
instance.dirty = false
|
||||
sendNetwork(AndroidResearchPacket(instance))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final Fraction ENERGY_FOR_HUNGER_POINT = new Fraction(1000);
|
||||
@JvmField
|
||||
var sleep_ticks = 0
|
||||
|
||||
public int sleep_ticks = 0;
|
||||
public static final int SLEEP_TICKS_LIMIT = 80;
|
||||
|
||||
@Override
|
||||
protected void tickInnerClientAlways() {
|
||||
super.tickInnerClientAlways();
|
||||
override fun tickInnerClientAlways() {
|
||||
super.tickInnerClientAlways()
|
||||
|
||||
if (will_become_android) {
|
||||
if (ent.isSleeping()) {
|
||||
sleep_ticks++;
|
||||
if (ply.isSleeping) {
|
||||
sleep_ticks++
|
||||
} else {
|
||||
sleep_ticks = 0;
|
||||
sleep_ticks = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickServerAlways() {
|
||||
super.tickServerAlways();
|
||||
override fun tickServerAlways() {
|
||||
super.tickServerAlways()
|
||||
|
||||
if (will_become_android) {
|
||||
if (ent.isSleeping()) {
|
||||
sleep_ticks++;
|
||||
if (ply.isSleeping) {
|
||||
sleep_ticks++
|
||||
|
||||
if (sleep_ticks > SLEEP_TICKS_LIMIT) {
|
||||
becomeAndroid();
|
||||
sleep_ticks = 0;
|
||||
becomeAndroid()
|
||||
sleep_ticks = 0
|
||||
|
||||
if (ent instanceof ServerPlayer ply) {
|
||||
ply.displayClientMessage(new TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false);
|
||||
}
|
||||
(ply as? ServerPlayer)?.displayClientMessage(TranslatableComponent("otm.pill.message_finish").withStyle(ChatFormatting.DARK_RED), false)
|
||||
}
|
||||
} else {
|
||||
sleep_ticks = 0;
|
||||
sleep_ticks = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tickServer() {
|
||||
super.tickServer();
|
||||
public override fun tickServer() {
|
||||
super.tickServer()
|
||||
|
||||
// TODO: Maybe passive drain?
|
||||
// extractEnergyInner(BigDecimal.valueOf(new Random().nextDouble()), false);
|
||||
|
||||
if (ply.isSwimming() && !hasFeature(Registry.AndroidFeatures.AIR_BAGS)) {
|
||||
ply.setSwimming(false);
|
||||
if (ply.isSwimming && !hasFeature(Registry.AndroidFeatures.AIR_BAGS)) {
|
||||
ply.isSwimming = false
|
||||
}
|
||||
|
||||
var stats = ply.getFoodData();
|
||||
val stats = ply.foodData
|
||||
|
||||
while (stats.getFoodLevel() < 18 && this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true).compareTo(ENERGY_FOR_HUNGER_POINT) == 0) {
|
||||
this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false);
|
||||
stats.setFoodLevel(stats.getFoodLevel() + 1);
|
||||
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.getFoodLevel() > 18 && this.receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, true).compareTo(ENERGY_FOR_HUNGER_POINT) == 0) {
|
||||
this.receiveEnergyInner(ENERGY_FOR_HUNGER_POINT, false);
|
||||
stats.setFoodLevel(stats.getFoodLevel() - 1);
|
||||
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
|
||||
}
|
||||
|
||||
var food_level = (float) stats.getFoodLevel();
|
||||
val foodLevel = stats.foodLevel.toFloat()
|
||||
|
||||
if (stats.getSaturationLevel() < food_level) {
|
||||
Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(food_level - stats.getSaturationLevel()), false);
|
||||
stats.setSaturation(stats.getSaturationLevel() + extracted.div(ENERGY_FOR_HUNGER_POINT).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.getExhaustionLevel() > 0f) {
|
||||
Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(stats.getExhaustionLevel() / 4f), false);
|
||||
stats.setExhaustion(stats.getExhaustionLevel() - extracted.div(ENERGY_FOR_HUNGER_POINT).toFloat() * 4f);
|
||||
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(Registry.Names.ANDROID_CAPABILITY, AndroidCapabilityPlayer(ent))
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onPlayerChangeDimensionEvent(event: PlayerChangedDimensionEvent) {
|
||||
event.player.getCapability(MatteryCapability.ANDROID)
|
||||
.ifPresent { it.invalidateNetworkState() }
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onPlayerCloneEvent(event: Clone) {
|
||||
event.player.getCapability(MatteryCapability.ANDROID).ifPresent {
|
||||
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@ifPresent
|
||||
}
|
||||
|
||||
val original = resolver.resolve().get() as AndroidCapabilityPlayer
|
||||
|
||||
if (original.will_become_android && event.isWasDeath) {
|
||||
original.becomeAndroid()
|
||||
(event.player 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 = Fraction(1000)
|
||||
const val SLEEP_TICKS_LIMIT = 80
|
||||
}
|
||||
}
|
@ -1,51 +1,45 @@
|
||||
package ru.dbotthepony.mc.otm.capability.android;
|
||||
package ru.dbotthepony.mc.otm.capability.android
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
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.Fraction;
|
||||
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.Fraction
|
||||
import java.util.*
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundTag?> {
|
||||
fun tick()
|
||||
fun tickClient()
|
||||
fun getEntity(): 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
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface IAndroidCapability extends IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
||||
void tick();
|
||||
void tickClient();
|
||||
LivingEntity getEntity();
|
||||
fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T?
|
||||
|
||||
<T extends AndroidFeature> T addFeature(AndroidFeatureType<T> feature);
|
||||
boolean removeFeature(AndroidFeatureType<?> feature);
|
||||
boolean hasFeature(@Nullable AndroidFeatureType<?> feature);
|
||||
boolean hasFeatureLevel(@Nullable AndroidFeatureType<?> feature, int level);
|
||||
@Nullable
|
||||
<T extends AndroidFeature> T getFeature(AndroidFeatureType<T> feature);
|
||||
|
||||
default <T extends AndroidFeature> Optional<T> getFeatureO(AndroidFeatureType<T> feature) {
|
||||
var get = getFeature(feature);
|
||||
return get != null ? Optional.of(get) : Optional.empty();
|
||||
fun <T : AndroidFeature> getFeatureO(feature: AndroidFeatureType<T>): Optional<T> {
|
||||
val get = getFeature(feature)
|
||||
return if (get != null) Optional.of(get) else Optional.empty()
|
||||
}
|
||||
|
||||
default boolean isAndroid() {
|
||||
return true;
|
||||
fun <T : AndroidFeature> ifFeature(feature: AndroidFeatureType<T>, consumer: (T) -> Unit) {
|
||||
val get = getFeature(feature)
|
||||
|
||||
if (get != null) {
|
||||
consumer(get)
|
||||
}
|
||||
}
|
||||
default void onHurt(LivingHurtEvent event) {}
|
||||
|
||||
ItemStack getBatteryItemStack();
|
||||
void setBatteryItemStack(ItemStack stack);
|
||||
fun isAndroid(): Boolean = true
|
||||
|
||||
void invalidateNetworkState(); // tell capability that player forgot everything, and everything needs to be re-networked
|
||||
|
||||
void setEnergy(Fraction value);
|
||||
void setMaxEnergy(Fraction value);
|
||||
fun onHurt(event: LivingHurtEvent?) {}
|
||||
var batteryItemStack: ItemStack
|
||||
fun invalidateNetworkState() // tell capability that player forgot everything, and everything needs to be re-networked
|
||||
fun setEnergy(value: Fraction?)
|
||||
fun setMaxEnergy(value: Fraction?)
|
||||
}
|
@ -19,9 +19,7 @@ import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||
import java.util.*
|
||||
|
||||
|
||||
|
||||
class AndroidStationScreen(p_97741_: AndroidStationMenu, p_97742_: Inventory, p_97743_: Component) :
|
||||
class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: Inventory, p_97743_: Component) :
|
||||
MatteryScreen<AndroidStationMenu>(p_97741_, p_97742_, p_97743_) {
|
||||
|
||||
internal inner class AndroidResearchButton(parent: EditablePanel?, private val node: AndroidResearch) :
|
||||
|
@ -53,7 +53,7 @@ class ItemPill(val pillType: PillType) :
|
||||
|
||||
val cap = resolver.get() as AndroidCapabilityPlayer
|
||||
|
||||
if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid || pillType == PillType.BECOME_HUMANE && cap.isEverAndroid) {
|
||||
if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid() || pillType == PillType.BECOME_HUMANE && cap.isEverAndroid()) {
|
||||
ply.startUsingItem(hand)
|
||||
return InteractionResultHolder.consume(ply.getItemInHand(hand))
|
||||
}
|
||||
@ -73,7 +73,7 @@ class ItemPill(val pillType: PillType) :
|
||||
|
||||
val cap = resolver.get() as AndroidCapabilityPlayer
|
||||
|
||||
if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid) {
|
||||
if (pillType == PillType.BECOME_ANDROID && !cap.isEverAndroid()) {
|
||||
if (ent.abilities.instabuild) {
|
||||
if (ent is ServerPlayer) {
|
||||
cap.becomeAndroid()
|
||||
@ -85,7 +85,7 @@ class ItemPill(val pillType: PillType) :
|
||||
cap.becomeAndroidSoft()
|
||||
}
|
||||
}
|
||||
} else if (pillType == PillType.BECOME_HUMANE && cap.isEverAndroid) {
|
||||
} else if (pillType == PillType.BECOME_HUMANE && cap.isEverAndroid()) {
|
||||
if (ent.abilities.instabuild) {
|
||||
if (ent is ServerPlayer) {
|
||||
cap.becomeHumane()
|
||||
|
Loading…
Reference in New Issue
Block a user