Revisit android features structure
This commit is contained in:
parent
5ba79f20e5
commit
ddf2c178e6
@ -1,80 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
|
||||
public class AndroidFeature implements INBTSerializable<CompoundTag> {
|
||||
public final AndroidFeatureType<? extends AndroidFeature> type;
|
||||
public final IAndroidCapability capability;
|
||||
|
||||
protected int level = 0;
|
||||
|
||||
public AndroidFeature(AndroidFeatureType<?> type, IAndroidCapability capability) {
|
||||
this.type = type;
|
||||
this.capability = capability;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
if (this.level != level) {
|
||||
this.level = level;
|
||||
applyModifiers();
|
||||
}
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (super.equals(obj))
|
||||
return true;
|
||||
|
||||
if (obj instanceof AndroidFeature feature)
|
||||
return feature.type.equals(type);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void invalidateNetwork() {
|
||||
// when player forgets everything
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return type.hashCode();
|
||||
}
|
||||
|
||||
public void tickClient() {
|
||||
// override
|
||||
}
|
||||
|
||||
public void tickServer() {
|
||||
// override
|
||||
}
|
||||
|
||||
public void applyModifiers() {}
|
||||
public void removeModifiers() {}
|
||||
|
||||
public void serializeNBT(CompoundTag tag) {
|
||||
tag.putInt("level", level);
|
||||
}
|
||||
|
||||
public void onHurt(LivingHurtEvent event) {
|
||||
// override
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
var tag = new CompoundTag();
|
||||
serializeNBT(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag tag) {
|
||||
level = tag.getInt("level");
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraftforge.registries.*;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
|
||||
public class AndroidFeatureType<T extends AndroidFeature> extends ForgeRegistryEntry<AndroidFeatureType<?>> {
|
||||
public interface AndroidFeatureFactory<T extends AndroidFeature> {
|
||||
T factory(IAndroidCapability capability);
|
||||
}
|
||||
|
||||
public interface AndroidFullFeatureFactory<T extends AndroidFeature> {
|
||||
T factory(AndroidFeatureType<T> type, IAndroidCapability capability);
|
||||
}
|
||||
|
||||
protected final AndroidFeatureFactory<T> factory;
|
||||
|
||||
public AndroidFeatureType(AndroidFeatureFactory<T> factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public AndroidFeatureType(AndroidFullFeatureFactory<T> factory) {
|
||||
this.factory = (c) -> factory.factory(this, c);
|
||||
}
|
||||
|
||||
public T factory(IAndroidCapability capability) {
|
||||
return factory.factory(capability);
|
||||
}
|
||||
|
||||
public boolean isApplicable(IAndroidCapability capability) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Component getDisplayName() {
|
||||
if (getRegistryName() == null)
|
||||
return new TranslatableComponent("android_feature.null.null");
|
||||
|
||||
return new TranslatableComponent("android_feature." + getRegistryName().getNamespace() + "." + getRegistryName().getPath());
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature;
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AndroidExtendedReach extends AndroidFeature {
|
||||
public static final UUID MODIFIER_ID = UUID.fromString("4a3fae46-47a8-a03f-857d-f5c2b2c8f2f2");
|
||||
|
||||
public AndroidExtendedReach(IAndroidCapability capability) {
|
||||
super(AndroidFeatures.INSTANCE.getEXTENDED_REACH(), capability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyModifiers() {
|
||||
var reach = capability.getEntity().getAttribute(ForgeMod.REACH_DISTANCE.get());
|
||||
|
||||
if (reach != null) {
|
||||
reach.removePermanentModifier(MODIFIER_ID);
|
||||
reach.addPermanentModifier(new AttributeModifier(MODIFIER_ID, type.getDisplayName().toString(), level + 1, AttributeModifier.Operation.ADDITION));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModifiers() {
|
||||
var reach = capability.getEntity().getAttribute(ForgeMod.REACH_DISTANCE.get());
|
||||
|
||||
if (reach != null) {
|
||||
reach.removePermanentModifier(MODIFIER_ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature;
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AndroidLimbOverclocking extends AndroidFeature {
|
||||
public static final UUID MODIFIER_ID = UUID.fromString("4a3fae46-e57b-4e20-857d-f5c2b2c8f2f2");
|
||||
|
||||
public AndroidLimbOverclocking(IAndroidCapability capability) {
|
||||
super(AndroidFeatures.INSTANCE.getLIMB_OVERCLOCKING(), capability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyModifiers() {
|
||||
var speed = capability.getEntity().getAttribute(Attributes.MOVEMENT_SPEED);
|
||||
|
||||
if (speed != null) {
|
||||
speed.removePermanentModifier(MODIFIER_ID);
|
||||
speed.addPermanentModifier(new AttributeModifier(MODIFIER_ID, type.getDisplayName().toString(), 0.08d * (level + 1), AttributeModifier.Operation.MULTIPLY_TOTAL));
|
||||
}
|
||||
|
||||
var attack_speed = capability.getEntity().getAttribute(Attributes.ATTACK_SPEED);
|
||||
|
||||
if (attack_speed != null) {
|
||||
attack_speed.removePermanentModifier(MODIFIER_ID);
|
||||
attack_speed.addPermanentModifier(new AttributeModifier(MODIFIER_ID, type.getDisplayName().toString(), 0.06d * (level + 1), AttributeModifier.Operation.MULTIPLY_TOTAL));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModifiers() {
|
||||
var speed = capability.getEntity().getAttribute(Attributes.MOVEMENT_SPEED);
|
||||
|
||||
if (speed != null) {
|
||||
speed.removePermanentModifier(MODIFIER_ID);
|
||||
}
|
||||
|
||||
var attack_speed = capability.getEntity().getAttribute(Attributes.ATTACK_SPEED);
|
||||
|
||||
if (attack_speed != null) {
|
||||
attack_speed.removePermanentModifier(MODIFIER_ID);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures;
|
||||
import ru.dbotthepony.mc.otm.registry.MNames;
|
||||
import ru.dbotthepony.mc.otm.registry.StatNames;
|
||||
|
||||
public class AndroidNanobotsArmor extends AndroidFeature {
|
||||
public AndroidNanobotsArmor(IAndroidCapability capability) {
|
||||
super(AndroidFeatures.INSTANCE.getNANOBOTS_ARMOR(), capability);
|
||||
}
|
||||
|
||||
public int getStrength() {
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void setStrength(int strength) {
|
||||
this.strength = Math.max(0, Math.min(2, strength));
|
||||
}
|
||||
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public void setSpeed(int speed) {
|
||||
this.speed = Math.max(0, Math.min(2, speed));
|
||||
}
|
||||
|
||||
protected int strength = 0;
|
||||
protected int speed = 0;
|
||||
|
||||
protected int ticks_passed = 0;
|
||||
protected int layers = 0;
|
||||
|
||||
protected static final ImpreciseFraction ENERGY_PER_BUILT = new ImpreciseFraction(200);
|
||||
protected static final ImpreciseFraction ENERGY_PER_HITPOINT = new ImpreciseFraction(500);
|
||||
|
||||
public static final int[] TICKS = new int[] {
|
||||
80, // 4 seconds to build a layer
|
||||
70, // 3.5 seconds to build a layer
|
||||
60, // 3 seconds to build a layer
|
||||
50, // 2.5 seconds to build a layer
|
||||
};
|
||||
|
||||
public static final float[] SHIELD_STRENGTH = new float[] {
|
||||
0.1f,
|
||||
0.2f,
|
||||
0.3f,
|
||||
0.4f,
|
||||
};
|
||||
|
||||
@Override
|
||||
public void tickServer() {
|
||||
if (layers < strength + 1 && capability.extractEnergyInner(ENERGY_PER_BUILT, true).compareTo(ENERGY_PER_BUILT) == 0) {
|
||||
ticks_passed++;
|
||||
|
||||
if (ticks_passed >= TICKS[speed]) {
|
||||
layers++;
|
||||
capability.extractEnergyInner(ENERGY_PER_BUILT, false);
|
||||
}
|
||||
} else {
|
||||
ticks_passed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHurt(LivingHurtEvent event) {
|
||||
ticks_passed = 0;
|
||||
|
||||
if (!event.getSource().isBypassArmor() && layers > 0) {
|
||||
var absorbed = event.getAmount() * SHIELD_STRENGTH[layers];
|
||||
|
||||
if (absorbed > 0.1f) {
|
||||
var required = ENERGY_PER_HITPOINT.times(absorbed);
|
||||
var extracted = capability.extractEnergyInner(required, false);
|
||||
var real_absorbed = absorbed * extracted.div(required).toFloat();
|
||||
event.setAmount(event.getAmount() - real_absorbed);
|
||||
|
||||
if (capability.getEntity() instanceof ServerPlayer ply) {
|
||||
ply.awardStat(StatNames.INSTANCE.getDAMAGE_ABSORBED(), Math.round(real_absorbed * 10f));
|
||||
}
|
||||
|
||||
layers--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeNBT(CompoundTag tag) {
|
||||
super.serializeNBT(tag);
|
||||
tag.putInt("ticks_passed", ticks_passed);
|
||||
tag.putInt("layers", layers);
|
||||
tag.putInt("strength", strength);
|
||||
tag.putInt("speed", speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag tag) {
|
||||
super.deserializeNBT(tag);
|
||||
|
||||
ticks_passed = tag.getInt("ticks_passed");
|
||||
layers = tag.getInt("layers");
|
||||
strength = tag.getInt("strength");
|
||||
speed = tag.getInt("speed");
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures;
|
||||
import ru.dbotthepony.mc.otm.registry.MNames;
|
||||
import ru.dbotthepony.mc.otm.registry.StatNames;
|
||||
|
||||
public class AndroidNanobotsRegeneration extends AndroidFeature {
|
||||
public AndroidNanobotsRegeneration(IAndroidCapability capability) {
|
||||
super(AndroidFeatures.INSTANCE.getNANOBOTS_REGENERATION(), capability);
|
||||
}
|
||||
|
||||
protected int ticks_passed = 0;
|
||||
protected int heal_ticks = 0;
|
||||
|
||||
protected static final ImpreciseFraction ENERGY_PER_HITPOINT = new ImpreciseFraction(800);
|
||||
|
||||
protected static final int[] TICKS_BETWEEN_HEAL = new int[] {
|
||||
100, // 5 seconds
|
||||
80, // 4 seconds
|
||||
60, // 3 seconds
|
||||
40, // 2 seconds
|
||||
};
|
||||
|
||||
@Override
|
||||
public void tickServer() {
|
||||
var ent = capability.getEntity();
|
||||
|
||||
if (ent.getHealth() > 0 && ent.getHealth() < ent.getMaxHealth()) {
|
||||
ticks_passed++;
|
||||
|
||||
var wait_time = heal_ticks >= TICKS_BETWEEN_HEAL.length ? TICKS_BETWEEN_HEAL[TICKS_BETWEEN_HEAL.length - 1] : TICKS_BETWEEN_HEAL[heal_ticks];
|
||||
|
||||
if (ticks_passed > wait_time) {
|
||||
var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth());
|
||||
var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.times(missing), false);
|
||||
|
||||
if (extract.compareTo(ImpreciseFraction.ZERO) > 0) {
|
||||
heal_ticks = Math.min(heal_ticks + 1, level);
|
||||
var heal = missing * extract.div(ENERGY_PER_HITPOINT).toFloat();
|
||||
ent.heal(heal);
|
||||
|
||||
if (capability.getEntity() instanceof ServerPlayer ply) {
|
||||
ply.awardStat(StatNames.INSTANCE.getHEALTH_REGENERATED(), Math.round(heal * 10f));
|
||||
}
|
||||
|
||||
ticks_passed = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
heal_ticks = 0;
|
||||
ticks_passed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHurt(LivingHurtEvent event) {
|
||||
heal_ticks = 0;
|
||||
ticks_passed = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeNBT(CompoundTag tag) {
|
||||
super.serializeNBT(tag);
|
||||
tag.putInt("heal_ticks", heal_ticks);
|
||||
tag.putInt("ticks_passed", ticks_passed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag tag) {
|
||||
super.deserializeNBT(tag);
|
||||
heal_ticks = tag.getInt("heal_ticks");
|
||||
ticks_passed = tag.getInt("ticks_passed");
|
||||
}
|
||||
}
|
@ -15,13 +15,8 @@ import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public record AndroidFeaturePacket(boolean is_added, AndroidFeatureType<?> feature) {
|
||||
public AndroidFeaturePacket(boolean is_added, AndroidFeatureType<?> feature) {
|
||||
this.is_added = is_added;
|
||||
this.feature = feature;
|
||||
}
|
||||
|
||||
public AndroidFeaturePacket(boolean is_added, AndroidFeature feature) {
|
||||
this(is_added, feature.type);
|
||||
this(is_added, feature.getType());
|
||||
}
|
||||
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
|
@ -0,0 +1,76 @@
|
||||
package ru.dbotthepony.mc.otm.android
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry
|
||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
|
||||
open class AndroidFeatureType<T : AndroidFeature> : ForgeRegistryEntry<AndroidFeatureType<*>> {
|
||||
private val factory: (AndroidFeatureType<T>, AndroidCapability) -> T
|
||||
|
||||
constructor(factory: (AndroidCapability) -> T) : super() {
|
||||
this.factory = { _, capability -> factory.invoke(capability) }
|
||||
}
|
||||
|
||||
constructor(factory: (AndroidFeatureType<T>, AndroidCapability) -> T) : super() {
|
||||
this.factory = factory
|
||||
}
|
||||
|
||||
fun create(android: AndroidCapability): T {
|
||||
return factory.invoke(this, android)
|
||||
}
|
||||
|
||||
open fun isApplicable(android: AndroidCapability) = true
|
||||
|
||||
open val displayName: Component get() = registryName?.let { TranslatableComponent("android_feature.${it.namespace}.${it.path}") } ?: TranslatableComponent("android_feature.null.null")
|
||||
}
|
||||
|
||||
abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: AndroidCapability) : INBTSerializable<CompoundTag> {
|
||||
val entity get() = android.entity
|
||||
|
||||
open var level = 0
|
||||
set(value) {
|
||||
if (value != field) {
|
||||
field = value
|
||||
applyModifiers()
|
||||
}
|
||||
}
|
||||
|
||||
open fun tickClient() {}
|
||||
open fun tickServer() {}
|
||||
|
||||
/**
|
||||
* Called when it is required to network everything again
|
||||
*/
|
||||
open fun invalidateNetwork() {}
|
||||
|
||||
open fun applyModifiers() {}
|
||||
open fun removeModifiers() {}
|
||||
|
||||
open fun onHurt(event: LivingHurtEvent) {}
|
||||
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
return CompoundTag().also {
|
||||
it["level"] = level
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserializeNBT(nbt: CompoundTag) {
|
||||
level = nbt.getInt("level")
|
||||
}
|
||||
}
|
||||
|
||||
class DummyAndroidFeature(type: AndroidFeatureType<*>, android: AndroidCapability) : AndroidFeature(type, android) {
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
return CompoundTag()
|
||||
}
|
||||
|
||||
override fun deserializeNBT(nbt: CompoundTag) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||
import net.minecraftforge.common.ForgeMod
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import java.util.*
|
||||
|
||||
class ExtendedReach(android: AndroidCapability) : AndroidFeature(AndroidFeatures.EXTENDED_REACH, android) {
|
||||
override fun applyModifiers() {
|
||||
if (!ForgeMod.REACH_DISTANCE.isPresent)
|
||||
return
|
||||
|
||||
val reach = entity.getAttribute(ForgeMod.REACH_DISTANCE.get()) ?: return
|
||||
|
||||
reach.removePermanentModifier(MODIFIER_ID)
|
||||
reach.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), level + 1.0, AttributeModifier.Operation.ADDITION))
|
||||
}
|
||||
|
||||
override fun removeModifiers() {
|
||||
if (!ForgeMod.REACH_DISTANCE.isPresent)
|
||||
return
|
||||
|
||||
entity.getAttribute(ForgeMod.REACH_DISTANCE.get())?.removePermanentModifier(MODIFIER_ID)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val MODIFIER_ID = UUID.fromString("4a3fae46-47a8-a03f-857d-f5c2b2c8f2f2")
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import java.util.*
|
||||
|
||||
class LimbOverclocking(android: AndroidCapability) : AndroidFeature(AndroidFeatures.LIMB_OVERCLOCKING, android) {
|
||||
override fun applyModifiers() {
|
||||
val speed = entity.getAttribute(Attributes.MOVEMENT_SPEED)
|
||||
|
||||
if (speed != null) {
|
||||
speed.removePermanentModifier(MODIFIER_ID)
|
||||
speed.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * 0.08, AttributeModifier.Operation.MULTIPLY_TOTAL))
|
||||
}
|
||||
|
||||
val attackSpeed = entity.getAttribute(Attributes.ATTACK_SPEED)
|
||||
|
||||
if (attackSpeed != null) {
|
||||
attackSpeed.removePermanentModifier(MODIFIER_ID)
|
||||
attackSpeed.addPermanentModifier(AttributeModifier(MODIFIER_ID, type.displayName.toString(), (level + 1) * 0.06, AttributeModifier.Operation.MULTIPLY_TOTAL))
|
||||
}
|
||||
}
|
||||
|
||||
override fun removeModifiers() {
|
||||
entity.getAttribute(Attributes.MOVEMENT_SPEED)?.removePermanentModifier(MODIFIER_ID)
|
||||
entity.getAttribute(Attributes.ATTACK_SPEED)?.removePermanentModifier(MODIFIER_ID)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val MODIFIER_ID = UUID.fromString("4a3fae46-e57b-4e20-857d-f5c2b2c8f2f2")
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class NanobotsArmor(android: AndroidCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {
|
||||
var strength: Int = 0
|
||||
set(value) { field = value.coerceIn(0 .. 2) }
|
||||
|
||||
var speed: Int = 0
|
||||
set(value) { field = value.coerceIn(0 .. 2) }
|
||||
|
||||
private var ticksPassed = 0
|
||||
private var layers = 0
|
||||
|
||||
override fun tickServer() {
|
||||
if (layers < strength + 1 && android.extractEnergyInnerExact(ENERGY_PER_LAYER, true).isPositive) {
|
||||
ticksPassed++
|
||||
|
||||
if (ticksPassed >= TICKS[speed]) {
|
||||
layers++
|
||||
android.extractEnergyInner(ENERGY_PER_LAYER, false)
|
||||
}
|
||||
} else {
|
||||
ticksPassed = 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHurt(event: LivingHurtEvent) {
|
||||
ticksPassed = 0
|
||||
|
||||
if (!event.source.isBypassArmor && layers > 0) {
|
||||
val absorbed = event.amount * STRENGTH[layers]
|
||||
|
||||
if (absorbed > 0.1f) {
|
||||
val powerRequired = ENERGY_PER_HITPOINT * absorbed
|
||||
val powerExtracted = android.extractEnergyInner(powerRequired, false)
|
||||
val realAbsorbed = (powerExtracted / ENERGY_PER_HITPOINT).toFloat()
|
||||
event.amount = event.amount - realAbsorbed
|
||||
(entity as ServerPlayer?)?.awardStat(StatNames.DAMAGE_ABSORBED, (realAbsorbed * 10f).roundToInt())
|
||||
layers--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
return super.serializeNBT().also {
|
||||
it["ticksPassed"] = ticksPassed
|
||||
it["layers"] = layers
|
||||
it["strength"] = strength
|
||||
it["speed"] = speed
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserializeNBT(nbt: CompoundTag) {
|
||||
super.deserializeNBT(nbt)
|
||||
ticksPassed = nbt.getInt("ticksPassed")
|
||||
layers = nbt.getInt("layers")
|
||||
strength = nbt.getInt("strength")
|
||||
speed = nbt.getInt("speed")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ENERGY_PER_LAYER = ImpreciseFraction(200)
|
||||
private val ENERGY_PER_HITPOINT = ImpreciseFraction(500)
|
||||
|
||||
private val TICKS = listOf(
|
||||
80, // 4 seconds to build a layer
|
||||
70, // 3.5 seconds to build a layer
|
||||
60, // 3 seconds to build a layer
|
||||
50, // 2.5 seconds to build a layer
|
||||
)
|
||||
|
||||
private val STRENGTH = listOf(
|
||||
0.1f,
|
||||
0.2f,
|
||||
0.3f,
|
||||
0.4f,
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.capability.android.AndroidCapability
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class NanobotsRegeneration(android: AndroidCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) {
|
||||
private var ticksPassed = 0
|
||||
private var healTicks = 0
|
||||
|
||||
override fun tickServer() {
|
||||
if (entity.health > 0f && entity.health < entity.maxHealth) {
|
||||
ticksPassed++
|
||||
|
||||
val waitTime = TICKS_BETWEEN_HEAL.getOrElse(healTicks) { TICKS_BETWEEN_HEAL.last() }
|
||||
|
||||
if (ticksPassed > waitTime) {
|
||||
val missingHealth = entity.maxHealth - entity.health
|
||||
val power = ENERGY_PER_HITPOINT * missingHealth
|
||||
val extracted = android.extractEnergyInner(power, false)
|
||||
|
||||
if (extracted.isPositive) {
|
||||
healTicks = (healTicks + 1).coerceAtMost(level)
|
||||
val healed = (extracted / ENERGY_PER_HITPOINT).toFloat()
|
||||
entity.heal(healed)
|
||||
(entity as ServerPlayer?)?.awardStat(StatNames.HEALTH_REGENERATED, (healed * 10f).roundToInt())
|
||||
ticksPassed = 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ticksPassed = 0
|
||||
healTicks = 0
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHurt(event: LivingHurtEvent) {
|
||||
ticksPassed = 0
|
||||
healTicks = 0
|
||||
}
|
||||
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
return super.serializeNBT().also {
|
||||
it["ticksPassed"] = ticksPassed
|
||||
it["healTicks"] = healTicks
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserializeNBT(nbt: CompoundTag) {
|
||||
super.deserializeNBT(nbt)
|
||||
ticksPassed = nbt.getInt("ticksPassed")
|
||||
healTicks = nbt.getInt("healTicks")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ENERGY_PER_HITPOINT = ImpreciseFraction(800)
|
||||
|
||||
private val TICKS_BETWEEN_HEAL = listOf(
|
||||
100, // 5 seconds
|
||||
80, // 4 seconds
|
||||
60, // 3 seconds
|
||||
40, // 2 seconds
|
||||
)
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package ru.dbotthepony.mc.otm.capability.android
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||
import net.minecraft.core.Direction
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
@ -36,55 +36,55 @@ 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.registry.MNames
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.*
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag> {
|
||||
@JvmField protected var battery = ImpreciseFraction.ZERO
|
||||
@JvmField protected var maxBattery = ImpreciseFraction(60000)
|
||||
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.EMPTY
|
||||
override var batteryItemStack: ItemStack = ItemStack.EMPTY
|
||||
|
||||
private var remoteBattery = ImpreciseFraction(-1)
|
||||
private var remoteMaxBattery = ImpreciseFraction(-1)
|
||||
private var remoteBatteryStack = ItemStack.EMPTY
|
||||
|
||||
@JvmField protected val features: MutableMap<AndroidFeatureType<*>, AndroidFeature> = HashMap()
|
||||
@JvmField protected val networkQueue = ArrayList<Any>()
|
||||
@JvmField protected val queuedTicks = ArrayList<Runnable>()
|
||||
@JvmField protected var networkFirst = false
|
||||
protected val features = Object2ObjectArrayMap<AndroidFeatureType<*>, AndroidFeature>()
|
||||
protected val networkQueue = ArrayList<Any>()
|
||||
protected val queuedTicks = ArrayList<Runnable>()
|
||||
protected var networkTickedOnce = false
|
||||
|
||||
protected fun addFeature(feature: AndroidFeature): Boolean {
|
||||
if (features.containsKey(feature.type)) return false
|
||||
features[feature.type] = feature
|
||||
|
||||
if (!ent.level.isClientSide) {
|
||||
queuedTicks.add(Runnable { feature.applyModifiers() })
|
||||
if (!entity.level.isClientSide) {
|
||||
queuedTicks.add(feature::applyModifiers)
|
||||
}
|
||||
if (ent is ServerPlayer) {
|
||||
|
||||
if (entity is ServerPlayer) {
|
||||
sendNetwork(AndroidFeaturePacket(true, 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.factory(this)
|
||||
val factory = feature.create(this)
|
||||
|
||||
features[feature] = factory
|
||||
|
||||
if (!ent.level.isClientSide) {
|
||||
queuedTicks.add(Runnable { factory.applyModifiers() })
|
||||
if (!entity.level.isClientSide) {
|
||||
queuedTicks.add(factory::applyModifiers)
|
||||
}
|
||||
|
||||
if (ent is ServerPlayer) {
|
||||
if (entity is ServerPlayer) {
|
||||
sendNetwork(AndroidFeaturePacket(true, factory))
|
||||
}
|
||||
|
||||
@ -95,11 +95,13 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
val removed = features.remove(feature)
|
||||
|
||||
if (removed != null) {
|
||||
if (!ent.level.isClientSide) {
|
||||
queuedTicks.add { removed.removeModifiers() }
|
||||
if (!entity.level.isClientSide) {
|
||||
queuedTicks.add {
|
||||
removed.removeModifiers()
|
||||
}
|
||||
}
|
||||
|
||||
if (ent is ServerPlayer) {
|
||||
if (entity is ServerPlayer) {
|
||||
sendNetwork(AndroidFeaturePacket(false, removed))
|
||||
}
|
||||
}
|
||||
@ -116,6 +118,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
return get.level >= level
|
||||
}
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
override fun <T : AndroidFeature> getFeature(feature: AndroidFeatureType<T>): T? {
|
||||
return features[feature] as T?
|
||||
}
|
||||
@ -125,7 +128,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
remoteMaxBattery = ImpreciseFraction.MINUS_ONE
|
||||
remoteBatteryStack = ItemStack.EMPTY
|
||||
|
||||
if (ent is ServerPlayer) {
|
||||
if (entity is ServerPlayer) {
|
||||
for (feature in features.values) {
|
||||
sendNetwork(AndroidFeaturePacket(true, feature))
|
||||
feature.invalidateNetwork()
|
||||
@ -157,8 +160,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
val featureList = ListTag()
|
||||
|
||||
for (feature in features.values) {
|
||||
val featureNbt = CompoundTag()
|
||||
feature.serializeNBT(featureNbt)
|
||||
val featureNbt = feature.serializeNBT()
|
||||
|
||||
featureNbt["id"] = feature.type.registryName!!.toString()
|
||||
featureList.add(featureNbt)
|
||||
@ -191,14 +193,14 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
if (tag is CompoundTag) {
|
||||
val feature = MRegistry.ANDROID_FEATURES.getValue(ResourceLocation(tag.getString("id")))
|
||||
|
||||
if (feature != null && feature.isApplicable(this)) {
|
||||
val feature = feature.factory(this)
|
||||
if (feature?.isApplicable(this) == true) {
|
||||
val instance = feature.create(this)
|
||||
|
||||
feature.deserializeNBT(tag)
|
||||
addFeature(feature)
|
||||
instance.deserializeNBT(tag)
|
||||
addFeature(instance)
|
||||
|
||||
if (!ent.level.isClientSide) {
|
||||
queuedTicks.add(Runnable { feature.applyModifiers() })
|
||||
if (!entity.level.isClientSide) {
|
||||
queuedTicks.add(instance::applyModifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -207,14 +209,14 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
|
||||
fun dropBattery() {
|
||||
if (batteryItemStack.isEmpty) return
|
||||
ent.spawnAtLocation(batteryItemStack)
|
||||
entity.spawnAtLocation(batteryItemStack)
|
||||
batteryItemStack = ItemStack.EMPTY
|
||||
}
|
||||
|
||||
protected fun sendNetwork(packet: Any) {
|
||||
if (ent is ServerPlayer) {
|
||||
if (networkFirst) {
|
||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { ent }, packet)
|
||||
if (entity is ServerPlayer) {
|
||||
if (networkTickedOnce) {
|
||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { entity }, packet)
|
||||
} else {
|
||||
networkQueue.add(packet)
|
||||
}
|
||||
@ -222,9 +224,9 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
}
|
||||
|
||||
protected open fun tickNetwork() {
|
||||
networkFirst = true
|
||||
networkTickedOnce = true
|
||||
|
||||
if (ent is ServerPlayer) {
|
||||
if (entity is ServerPlayer) {
|
||||
if (battery != remoteBattery) {
|
||||
remoteBattery = battery
|
||||
sendNetwork(AndroidEnergyPacket(false, battery))
|
||||
@ -242,7 +244,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
|
||||
if (networkQueue.size != 0) {
|
||||
for (packet in networkQueue) {
|
||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with {ent}, packet)
|
||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { entity }, packet)
|
||||
}
|
||||
|
||||
networkQueue.clear()
|
||||
@ -255,10 +257,15 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
|
||||
override fun tickClient() {
|
||||
queuedTicks.clear()
|
||||
if (!ent.isAlive) return
|
||||
|
||||
if (!entity.isAlive)
|
||||
return
|
||||
|
||||
tickInnerClientAlways()
|
||||
|
||||
if (isAndroid()) {
|
||||
tickInnerClient()
|
||||
|
||||
for (feature in features.values) {
|
||||
feature.tickClient()
|
||||
}
|
||||
@ -266,17 +273,22 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
if (!ent.isAlive) return
|
||||
if (!entity.isAlive) return
|
||||
|
||||
tickServerAlways()
|
||||
|
||||
if (isAndroid()) {
|
||||
tickServer()
|
||||
|
||||
for (feature in features.values) {
|
||||
feature.tickServer()
|
||||
}
|
||||
}
|
||||
|
||||
for (runnable in queuedTicks) {
|
||||
runnable.run()
|
||||
}
|
||||
|
||||
queuedTicks.clear()
|
||||
tickNetwork()
|
||||
}
|
||||
@ -284,12 +296,12 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
protected open fun tickServerAlways() {}
|
||||
|
||||
protected open fun tickServer() {
|
||||
if (ent.airSupply < ent.maxAirSupply)
|
||||
ent.airSupply = ent.maxAirSupply
|
||||
if (entity.airSupply < entity.maxAirSupply)
|
||||
entity.airSupply = entity.maxAirSupply
|
||||
|
||||
for (effect in UNAFFECTED_EFFECTS)
|
||||
if (ent.hasEffect(effect))
|
||||
ent.removeEffect(effect)
|
||||
if (entity.hasEffect(effect))
|
||||
entity.removeEffect(effect)
|
||||
|
||||
if (!batteryItemStack.isEmpty && battery < maxBattery) {
|
||||
batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||
@ -325,8 +337,8 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
}
|
||||
|
||||
if (howMuch.isZero) {
|
||||
if (!simulate && ent is ServerPlayer) {
|
||||
ent.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||
if (!simulate && entity is ServerPlayer) {
|
||||
entity.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||
}
|
||||
|
||||
return drained
|
||||
@ -339,8 +351,8 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
if (!simulate) {
|
||||
battery = new
|
||||
|
||||
if (ent is ServerPlayer) {
|
||||
ent.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||
if (entity is ServerPlayer) {
|
||||
entity.awardStat(StatNames.POWER_CONSUMED, drained.toInt() * 10)
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,10 +395,6 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
return receiveEnergyOuter(howMuch, simulate)
|
||||
}
|
||||
|
||||
override fun getEntity(): LivingEntity {
|
||||
return ent
|
||||
}
|
||||
|
||||
override val batteryLevel: ImpreciseFraction get() {
|
||||
if (!batteryItemStack.isEmpty) {
|
||||
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
||||
@ -434,10 +442,10 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
||||
@Suppress("unused")
|
||||
companion object {
|
||||
@JvmField
|
||||
val UNAFFECTED_EFFECTS: MutableSet<MobEffect> = HashSet()
|
||||
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
||||
|
||||
@JvmStatic
|
||||
fun registerEffects(event: FMLCommonSetupEvent?) {
|
||||
fun registerEffects(event: FMLCommonSetupEvent) {
|
||||
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
||||
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
||||
// maybe it makes things go haywire idk
|
||||
|
@ -14,7 +14,7 @@ import java.util.*
|
||||
interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
||||
fun tick()
|
||||
fun tickClient()
|
||||
fun getEntity(): LivingEntity
|
||||
val entity: LivingEntity
|
||||
fun <T : AndroidFeature> addFeature(feature: AndroidFeatureType<T>): T
|
||||
fun removeFeature(feature: AndroidFeatureType<*>): Boolean
|
||||
fun hasFeature(feature: AndroidFeatureType<*>): Boolean
|
||||
|
@ -4,20 +4,20 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
|
||||
import net.minecraftforge.registries.DeferredRegister
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.android.feature.AndroidExtendedReach
|
||||
import ru.dbotthepony.mc.otm.android.feature.AndroidLimbOverclocking
|
||||
import ru.dbotthepony.mc.otm.android.feature.AndroidNanobotsArmor
|
||||
import ru.dbotthepony.mc.otm.android.feature.AndroidNanobotsRegeneration
|
||||
import ru.dbotthepony.mc.otm.android.DummyAndroidFeature
|
||||
import ru.dbotthepony.mc.otm.android.feature.ExtendedReach
|
||||
import ru.dbotthepony.mc.otm.android.feature.LimbOverclocking
|
||||
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmor
|
||||
import ru.dbotthepony.mc.otm.android.feature.NanobotsRegeneration
|
||||
|
||||
object AndroidFeatures {
|
||||
private val registry = DeferredRegister.create(AndroidFeatureType::class.java, OverdriveThatMatters.MOD_ID)
|
||||
|
||||
val AIR_BAGS: AndroidFeatureType<*> by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::AndroidFeature) }
|
||||
val LIMB_OVERCLOCKING: AndroidFeatureType<*> by registry.register(MNames.LIMB_OVERCLOCKING) { AndroidFeatureType(::AndroidLimbOverclocking) }
|
||||
val NANOBOTS_REGENERATION: AndroidFeatureType<*> by registry.register(MNames.NANOBOTS_REGENERATION) { AndroidFeatureType(::AndroidNanobotsRegeneration) }
|
||||
val NANOBOTS_ARMOR: AndroidFeatureType<*> by registry.register(MNames.NANOBOTS_ARMOR) { AndroidFeatureType(::AndroidNanobotsArmor) }
|
||||
val EXTENDED_REACH: AndroidFeatureType<*> by registry.register(MNames.EXTENDED_REACH) { AndroidFeatureType(::AndroidExtendedReach) }
|
||||
val AIR_BAGS: AndroidFeatureType<*> by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::DummyAndroidFeature) }
|
||||
val LIMB_OVERCLOCKING: AndroidFeatureType<*> by registry.register(MNames.LIMB_OVERCLOCKING) { AndroidFeatureType(::LimbOverclocking) }
|
||||
val NANOBOTS_REGENERATION: AndroidFeatureType<*> by registry.register(MNames.NANOBOTS_REGENERATION) { AndroidFeatureType(::NanobotsRegeneration) }
|
||||
val NANOBOTS_ARMOR: AndroidFeatureType<*> by registry.register(MNames.NANOBOTS_ARMOR) { AndroidFeatureType(::NanobotsArmor) }
|
||||
val EXTENDED_REACH: AndroidFeatureType<*> by registry.register(MNames.EXTENDED_REACH) { AndroidFeatureType(::ExtendedReach) }
|
||||
|
||||
internal fun register() {
|
||||
registry.register(FMLJavaModLoadingContext.get().modEventBus)
|
||||
|
@ -1,3 +1,6 @@
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package ru.dbotthepony.mc.otm.registry
|
||||
|
||||
import net.minecraft.network.chat.TextComponent
|
||||
@ -9,7 +12,7 @@ import net.minecraftforge.registries.RegistryObject
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchBuilder
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.android.feature.AndroidNanobotsArmor
|
||||
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmor
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||
|
||||
object AndroidResearch {
|
||||
@ -105,7 +108,7 @@ object AndroidResearch {
|
||||
registry.register(FMLJavaModLoadingContext.get().modEventBus)
|
||||
}
|
||||
|
||||
val AIR_BAGS by registry.register(MNames.AIR_BAGS) {
|
||||
val AIR_BAGS: AndroidResearchType<*> by registry.register(MNames.AIR_BAGS) {
|
||||
AndroidResearchBuilder()
|
||||
.setExperienceCost(18)
|
||||
.addFeatureResult(AndroidFeatures.AIR_BAGS)
|
||||
@ -114,7 +117,7 @@ object AndroidResearch {
|
||||
.build()
|
||||
}
|
||||
|
||||
val EXTENDED_REACH by registry.register(MNames.EXTENDED_REACH) {
|
||||
val EXTENDED_REACH: AndroidResearchType<*> by registry.register(MNames.EXTENDED_REACH) {
|
||||
AndroidResearchBuilder()
|
||||
.setExperienceCost(40)
|
||||
.addFeatureResult(AndroidFeatures.EXTENDED_REACH)
|
||||
@ -123,7 +126,7 @@ object AndroidResearch {
|
||||
.build()
|
||||
}
|
||||
|
||||
val NANOBOTS by registry.register(MNames.NANOBOTS) {
|
||||
val NANOBOTS: AndroidResearchType<*> by registry.register(MNames.NANOBOTS) {
|
||||
AndroidResearchBuilder()
|
||||
.setExperienceCost(15)
|
||||
.withDescription()
|
||||
@ -131,7 +134,7 @@ object AndroidResearch {
|
||||
.build()
|
||||
}
|
||||
|
||||
val NANOBOTS_ARMOR by registry.register(MNames.NANOBOTS_ARMOR) {
|
||||
val NANOBOTS_ARMOR: AndroidResearchType<*> by registry.register(MNames.NANOBOTS_ARMOR) {
|
||||
AndroidResearchBuilder()
|
||||
.setExperienceCost(25)
|
||||
.withDescription()
|
||||
@ -222,7 +225,7 @@ object AndroidResearch {
|
||||
)
|
||||
)
|
||||
.addFeatureResult(OverdriveThatMatters.loc(MNames.NANOBOTS_ARMOR), 0) { feature ->
|
||||
if ((feature as AndroidNanobotsArmor).strength < level) feature.strength = level
|
||||
if ((feature as NanobotsArmor).strength < level) feature.strength = level
|
||||
}
|
||||
.build()
|
||||
})
|
||||
@ -247,7 +250,7 @@ object AndroidResearch {
|
||||
)
|
||||
)
|
||||
.addFeatureResult(OverdriveThatMatters.loc(MNames.NANOBOTS_ARMOR), 0) { feature ->
|
||||
if ((feature as AndroidNanobotsArmor).speed < level) feature.speed = level
|
||||
if ((feature as NanobotsArmor).speed < level) feature.speed = level
|
||||
}
|
||||
.build()
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user