mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-09-15 23:32:08 +02:00
Compare commits
2 Commits
5564fc4a24
...
components
Author | SHA1 | Date | |
---|---|---|---|
b64005357e | |||
3279dde625 |
@@ -76,8 +76,8 @@ class EntityMobAngryEnderman(type: EntityType<EntityMobAngryEnderman>, world: Wo
|
||||
}
|
||||
|
||||
override fun updateAITasks() {
|
||||
teleportHandler.update()
|
||||
waterHandler.update()
|
||||
teleportHandler.tickServer()
|
||||
waterHandler.tickServer()
|
||||
|
||||
val currentTarget = attackTarget
|
||||
|
||||
|
@@ -26,6 +26,10 @@ import chylex.hee.game.mechanics.causatum.events.CausatumEventEndermanKill
|
||||
import chylex.hee.game.world.playServer
|
||||
import chylex.hee.init.ModEntities
|
||||
import chylex.hee.init.ModSounds
|
||||
import chylex.hee.system.component.EntityComponents
|
||||
import chylex.hee.system.component.general.deserializeFrom
|
||||
import chylex.hee.system.component.general.serializeTo
|
||||
import chylex.hee.system.component.general.tick
|
||||
import chylex.hee.system.facades.Resource
|
||||
import chylex.hee.system.forge.SubscribeAllEvents
|
||||
import chylex.hee.system.forge.SubscribeEvent
|
||||
@@ -76,8 +80,6 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
|
||||
@SubscribeAllEvents(modid = HEE.ID)
|
||||
companion object {
|
||||
private const val TELEPORT_HANDLER_TAG = "Teleport"
|
||||
private const val WATER_HANDLER_TAG = "Water"
|
||||
private const val CAN_PICK_UP_BLOCKS_TAG = "CanPickUpBlocks"
|
||||
private const val HELD_BLOCK_TIMER_TAG = "HeldBlockTimer"
|
||||
private const val HELD_BLOCK_DESPAWNS_TAG = "HeldBlockDespawns"
|
||||
@@ -202,8 +204,9 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
|
||||
// Instance
|
||||
|
||||
private lateinit var components: EntityComponents
|
||||
|
||||
private lateinit var teleportHandler: EndermanTeleportHandler
|
||||
private lateinit var waterHandler: EndermanWaterHandler
|
||||
private lateinit var blockHandler: EndermanBlockHandler
|
||||
|
||||
private lateinit var aiAttackTarget: AIToggle
|
||||
@@ -227,6 +230,13 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
|
||||
// Initialization
|
||||
|
||||
override fun registerData() {
|
||||
super.registerData()
|
||||
|
||||
components = EntityComponents()
|
||||
components.attach(EndermanWaterHandler(this, takeDamageAfterWetTicks = 80))
|
||||
}
|
||||
|
||||
override fun registerAttributes() {
|
||||
super.registerAttributes()
|
||||
|
||||
@@ -238,8 +248,7 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
}
|
||||
|
||||
override fun registerGoals() {
|
||||
teleportHandler = EndermanTeleportHandler(this)
|
||||
waterHandler = EndermanWaterHandler(this, takeDamageAfterWetTicks = 80)
|
||||
teleportHandler = EndermanTeleportHandler(this).also(components::attach)
|
||||
blockHandler = EndermanBlockHandler(this)
|
||||
|
||||
aiWatchTargetInShock = AIWatchTargetInShock(this, maxDistance = 72.0)
|
||||
@@ -265,10 +274,9 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
override fun livingTick() {
|
||||
super.livingTick()
|
||||
|
||||
if (!world.isRemote) {
|
||||
teleportHandler.update()
|
||||
waterHandler.update()
|
||||
components.tick(this)
|
||||
|
||||
if (!world.isRemote) {
|
||||
if (heldBlockTimer > 0 && --heldBlockTimer == 0.toShort()) {
|
||||
if (heldBlockDespawns || !blockHandler.tryPlaceBlock(allowPlayerProximity = false)) {
|
||||
teleportHandler.teleportOutOfWorld(force = rand.nextBoolean())
|
||||
@@ -536,8 +544,7 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
override fun writeAdditional(nbt: TagCompound) = nbt.heeTag.use {
|
||||
super.writeAdditional(nbt)
|
||||
|
||||
put(TELEPORT_HANDLER_TAG, teleportHandler.serializeNBT())
|
||||
put(WATER_HANDLER_TAG, waterHandler.serializeNBT())
|
||||
components.serializeTo(this)
|
||||
|
||||
putBoolean(CAN_PICK_UP_BLOCKS_TAG, aiPickUpBlocks.enabled)
|
||||
putShort(HELD_BLOCK_TIMER_TAG, heldBlockTimer)
|
||||
@@ -547,8 +554,7 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
|
||||
override fun readAdditional(nbt: TagCompound) = nbt.heeTag.use {
|
||||
super.readAdditional(nbt)
|
||||
|
||||
teleportHandler.deserializeNBT(getCompound(TELEPORT_HANDLER_TAG))
|
||||
waterHandler.deserializeNBT(getCompound(WATER_HANDLER_TAG))
|
||||
components.deserializeFrom(this)
|
||||
|
||||
aiPickUpBlocks.enabled = getBoolean(CAN_PICK_UP_BLOCKS_TAG)
|
||||
heldBlockTimer = getShort(HELD_BLOCK_TIMER_TAG)
|
||||
|
@@ -29,6 +29,8 @@ import chylex.hee.network.client.PacketClientFX
|
||||
import chylex.hee.network.fx.FxEntityData
|
||||
import chylex.hee.network.fx.FxEntityHandler
|
||||
import chylex.hee.system.color.IntColor.Companion.RGB
|
||||
import chylex.hee.system.component.general.SerializableComponent
|
||||
import chylex.hee.system.component.general.TickableComponent
|
||||
import chylex.hee.system.math.Vec
|
||||
import chylex.hee.system.math.Vec3
|
||||
import chylex.hee.system.math.addY
|
||||
@@ -53,13 +55,12 @@ import net.minecraft.util.SoundCategory
|
||||
import net.minecraft.util.math.AxisAlignedBB
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import java.util.Random
|
||||
import java.util.UUID
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) : INBTSerializable<TagCompound> {
|
||||
class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) : TickableComponent, SerializableComponent {
|
||||
companion object {
|
||||
private const val DEFAULT_RESTORE_Y = -256.0
|
||||
|
||||
@@ -117,6 +118,9 @@ class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) :
|
||||
}
|
||||
}
|
||||
|
||||
override val serializationKey
|
||||
get() = "Teleport"
|
||||
|
||||
val preventDespawn
|
||||
get() = tpDelayTicks > 0
|
||||
|
||||
@@ -133,7 +137,7 @@ class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) :
|
||||
|
||||
private var lastDodged: UUID? = null
|
||||
|
||||
fun update() {
|
||||
override fun tickServer() {
|
||||
if (tpCooldown > 0) {
|
||||
--tpCooldown
|
||||
}
|
||||
|
@@ -4,15 +4,16 @@ import chylex.hee.game.entity.OPERATION_MUL_INCR_INDIVIDUAL
|
||||
import chylex.hee.game.entity.living.EntityMobAbstractEnderman
|
||||
import chylex.hee.game.entity.tryApplyModifier
|
||||
import chylex.hee.game.entity.tryRemoveModifier
|
||||
import chylex.hee.system.component.general.SerializableComponent
|
||||
import chylex.hee.system.component.general.TickableComponent
|
||||
import chylex.hee.system.random.nextInt
|
||||
import chylex.hee.system.serialization.TagCompound
|
||||
import chylex.hee.system.serialization.use
|
||||
import net.minecraft.entity.SharedMonsterAttributes.ATTACK_DAMAGE
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier
|
||||
import net.minecraft.util.DamageSource
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
|
||||
class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, private val takeDamageAfterWetTicks: Int) : INBTSerializable<TagCompound> {
|
||||
class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, private val takeDamageAfterWetTicks: Int) : TickableComponent, SerializableComponent {
|
||||
private companion object {
|
||||
private val DEBUFF_WEAKNESS = AttributeModifier("Water weakness", -0.5, OPERATION_MUL_INCR_INDIVIDUAL)
|
||||
|
||||
@@ -20,10 +21,13 @@ class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, priv
|
||||
private const val DEBUFF_TICKS_TAG = "DebuffTicks"
|
||||
}
|
||||
|
||||
override val serializationKey
|
||||
get() = "Water"
|
||||
|
||||
private var wetCounter = 0
|
||||
private var debuffTicks = 0
|
||||
|
||||
fun update() {
|
||||
override fun tickServer() {
|
||||
val isWet = enderman.isWet
|
||||
|
||||
if (isWet) {
|
||||
|
@@ -3,6 +3,7 @@ package chylex.hee.game.item
|
||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||
import chylex.hee.game.inventory.heeTag
|
||||
import chylex.hee.game.inventory.heeTagOrNull
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity.Units
|
||||
import chylex.hee.game.particle.ParticleEnergyTransferToPlayer
|
||||
@@ -36,11 +37,11 @@ import chylex.hee.system.serialization.use
|
||||
import chylex.hee.system.serialization.writePos
|
||||
import net.minecraft.client.util.ITooltipFlag
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.network.PacketBuffer
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.util.text.ITextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
@@ -50,7 +51,7 @@ import java.util.Random
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
|
||||
abstract class ItemAbstractEnergyUser(properties: Properties) : Item(properties) {
|
||||
abstract class ItemAbstractEnergyUser(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
companion object {
|
||||
private const val ENERGY_LEVEL_TAG = "EnergyLevel"
|
||||
|
||||
@@ -100,6 +101,8 @@ abstract class ItemAbstractEnergyUser(properties: Properties) : Item(properties)
|
||||
init {
|
||||
@Suppress("DEPRECATION")
|
||||
require(maxStackSize == 1) { "energy item must have a maximum stack size of 1" }
|
||||
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
protected abstract fun getEnergyCapacity(stack: ItemStack): Units
|
||||
@@ -163,15 +166,11 @@ abstract class ItemAbstractEnergyUser(properties: Properties) : Item(properties)
|
||||
|
||||
// Energy charging
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
val tile = pos.getTile<TileEntityEnergyCluster>(world)
|
||||
val stack = player.getHeldItem(context.hand)
|
||||
val stack = player.getHeldItem(ctx.hand)
|
||||
|
||||
if (tile == null || !player.canPlayerEdit(pos, context.face, stack)) {
|
||||
if (tile == null || !player.canPlayerEdit(pos, ctx.face, stack)) {
|
||||
return FAIL
|
||||
}
|
||||
else if (world.isRemote) {
|
||||
|
@@ -13,7 +13,7 @@ import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
|
||||
abstract class ItemAbstractInfusable(properties: Properties) : Item(properties), IInfusableItem {
|
||||
abstract class ItemAbstractInfusable(properties: Properties) : ItemWithComponents(properties), IInfusableItem {
|
||||
companion object {
|
||||
fun onCanApplyInfusion(item: Item, infusion: Infusion): Boolean {
|
||||
return infusion.targetItems.contains(item)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package chylex.hee.game.item
|
||||
|
||||
import chylex.hee.game.inventory.size
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
import chylex.hee.init.ModItems
|
||||
import chylex.hee.network.client.PacketClientFX
|
||||
@@ -15,7 +16,6 @@ import chylex.hee.system.migration.ItemBoneMeal
|
||||
import net.minecraft.block.DispenserBlock.FACING
|
||||
import net.minecraft.dispenser.IBlockSource
|
||||
import net.minecraft.dispenser.OptionalDispenseBehavior
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
@@ -25,7 +25,7 @@ import net.minecraft.world.server.ServerWorld
|
||||
import net.minecraftforge.common.util.FakePlayerFactory
|
||||
import java.util.Random
|
||||
|
||||
class ItemCompost(properties: Properties) : Item(properties) {
|
||||
class ItemCompost(properties: Properties) : ItemWithComponents(properties) {
|
||||
companion object {
|
||||
private const val BONE_MEAL_EQUIVALENT = 2
|
||||
|
||||
@@ -61,6 +61,24 @@ class ItemCompost(properties: Properties) : Item(properties) {
|
||||
}
|
||||
|
||||
init {
|
||||
components.attach(object : UseOnBlockComponent {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
|
||||
if (!BlockEditor.canEdit(pos, player, item)) {
|
||||
return FAIL
|
||||
}
|
||||
else if (world.isRemote) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
if (applyCompost(world, pos, player)) {
|
||||
item.shrink(1)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
return PASS
|
||||
}
|
||||
})
|
||||
|
||||
BlockDispenser.registerDispenseBehavior(this, object : OptionalDispenseBehavior() {
|
||||
override fun dispenseStack(source: IBlockSource, stack: ItemStack): ItemStack {
|
||||
val world = source.world
|
||||
@@ -77,26 +95,4 @@ class ItemCompost(properties: Properties) : Item(properties) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
|
||||
if (!BlockEditor.canEdit(pos, player, heldItem)) {
|
||||
return FAIL
|
||||
}
|
||||
else if (world.isRemote) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
if (applyCompost(world, pos, player)) {
|
||||
heldItem.shrink(1)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
return PASS
|
||||
}
|
||||
}
|
||||
|
@@ -2,27 +2,27 @@ package chylex.hee.game.item
|
||||
|
||||
import chylex.hee.game.block.IBlockDeathFlowerDecaying
|
||||
import chylex.hee.game.entity.item.EntityItemCauldronTrigger
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
import chylex.hee.game.world.getBlock
|
||||
import chylex.hee.system.migration.ActionResult.FAIL
|
||||
import chylex.hee.system.migration.ActionResult.PASS
|
||||
import chylex.hee.system.migration.ActionResult.SUCCESS
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
class ItemEndPowder(properties: Properties) : Item(properties) {
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
class ItemEndPowder(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
init {
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
|
||||
if (!BlockEditor.canEdit(pos, player, heldItem)) {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
if (!BlockEditor.canEdit(pos, player, item)) {
|
||||
return FAIL
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class ItemEndPowder(properties: Properties) : Item(properties) {
|
||||
block.healDeathFlower(world, pos)
|
||||
}
|
||||
|
||||
heldItem.shrink(1)
|
||||
item.shrink(1)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
|
@@ -28,7 +28,6 @@ import chylex.hee.system.math.angleBetween
|
||||
import chylex.hee.system.math.floorToInt
|
||||
import chylex.hee.system.math.over
|
||||
import chylex.hee.system.math.toDegrees
|
||||
import chylex.hee.system.migration.ActionResult.FAIL
|
||||
import chylex.hee.system.migration.ActionResult.SUCCESS
|
||||
import chylex.hee.system.migration.EntityLivingBase
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
@@ -150,17 +149,13 @@ class ItemEnergyOracle(properties: Properties) : ItemAbstractEnergyUser(properti
|
||||
return ItemAbstractInfusable.onCanApplyInfusion(this, infusion)
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
if (player.isSneaking && pos.getTile<TileEntityEnergyCluster>(world) != null) {
|
||||
if (world.isRemote) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
val heldItem = player.getHeldItem(ctx.hand)
|
||||
val entry = pos.toLong()
|
||||
|
||||
with(heldItem.heeTag) {
|
||||
@@ -176,7 +171,7 @@ class ItemEnergyOracle(properties: Properties) : ItemAbstractEnergyUser(properti
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
return super.onItemUse(context)
|
||||
return super.useOnBlock(world, pos, player, item, ctx)
|
||||
}
|
||||
|
||||
override fun inventoryTick(stack: ItemStack, world: World, entity: Entity, itemSlot: Int, isSelected: Boolean) {
|
||||
|
@@ -4,6 +4,7 @@ import chylex.hee.client.color.NO_TINT
|
||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||
import chylex.hee.game.inventory.heeTag
|
||||
import chylex.hee.game.inventory.heeTagOrNull
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.item.infusion.Infusion.SAFETY
|
||||
import chylex.hee.game.item.infusion.Infusion.STABILITY
|
||||
import chylex.hee.game.item.infusion.InfusionList
|
||||
@@ -27,10 +28,10 @@ import chylex.hee.system.forge.Side
|
||||
import chylex.hee.system.forge.Sided
|
||||
import chylex.hee.system.migration.ActionResult.FAIL
|
||||
import chylex.hee.system.migration.ActionResult.SUCCESS
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import chylex.hee.system.serialization.TagCompound
|
||||
import chylex.hee.system.serialization.getIntegerOrNull
|
||||
import chylex.hee.system.serialization.hasKey
|
||||
import chylex.hee.system.serialization.use
|
||||
import net.minecraft.client.renderer.color.IItemColor
|
||||
import net.minecraft.client.util.ITooltipFlag
|
||||
import net.minecraft.entity.Entity
|
||||
@@ -43,7 +44,7 @@ import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
import kotlin.math.pow
|
||||
|
||||
class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(properties) {
|
||||
class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(properties), UseOnBlockComponent {
|
||||
private companion object {
|
||||
private const val CLUSTER_SNAPSHOT_TAG = "Cluster"
|
||||
private const val UPDATE_TIME_TAG = "UpdateTime"
|
||||
@@ -105,18 +106,14 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
|
||||
}
|
||||
|
||||
// POLISH tweak animation
|
||||
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
val stack = player.getHeldItem(context.hand)
|
||||
|
||||
stack.heeTag.use {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
with(item.heeTag) {
|
||||
if (hasKey(CLUSTER_SNAPSHOT_TAG)) {
|
||||
val finalPos = BlockEditor.place(ModBlocks.ENERGY_CLUSTER, player, stack, context)
|
||||
val finalPos = BlockEditor.place(ModBlocks.ENERGY_CLUSTER, player, item, ctx)
|
||||
|
||||
if (world.isRemote) {
|
||||
return SUCCESS
|
||||
@@ -126,7 +123,7 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
|
||||
finalPos.getTile<TileEntityEnergyCluster>(world)?.let {
|
||||
it.loadClusterSnapshot(ClusterSnapshot(getCompound(CLUSTER_SNAPSHOT_TAG)), inactive = false)
|
||||
|
||||
if (shouldLoseHealth(it, this, InfusionTag.getList(stack))) {
|
||||
if (shouldLoseHealth(it, this, InfusionTag.getList(item))) {
|
||||
it.deteriorateHealth()
|
||||
}
|
||||
}
|
||||
@@ -141,7 +138,7 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
|
||||
return SUCCESS
|
||||
}
|
||||
}
|
||||
else if (BlockEditor.canEdit(pos, player, stack)) {
|
||||
else if (BlockEditor.canEdit(pos, player, item)) {
|
||||
if (world.isRemote) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import chylex.hee.game.entity.heeTag
|
||||
import chylex.hee.game.entity.heeTagOrNull
|
||||
import chylex.hee.game.entity.posVec
|
||||
import chylex.hee.game.inventory.doDamage
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
import chylex.hee.game.world.FLAG_NONE
|
||||
import chylex.hee.game.world.getBlock
|
||||
@@ -14,7 +15,6 @@ import chylex.hee.game.world.playServer
|
||||
import chylex.hee.game.world.removeBlock
|
||||
import chylex.hee.game.world.setBlock
|
||||
import chylex.hee.init.ModBlocks
|
||||
import chylex.hee.system.compatibility.MinecraftForgeEventBus
|
||||
import chylex.hee.system.forge.EventPriority
|
||||
import chylex.hee.system.forge.SubscribeAllEvents
|
||||
import chylex.hee.system.forge.SubscribeEvent
|
||||
@@ -26,7 +26,6 @@ import chylex.hee.system.migration.EntityPlayer
|
||||
import chylex.hee.system.migration.Sounds
|
||||
import chylex.hee.system.random.nextFloat
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
@@ -36,7 +35,7 @@ import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.event.world.ExplosionEvent
|
||||
|
||||
class ItemFlintAndInfernium(properties: Properties) : Item(properties) {
|
||||
class ItemFlintAndInfernium(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
@SubscribeAllEvents(modid = HEE.ID)
|
||||
companion object {
|
||||
private const val CREEPER_INFERNIUM_TAG = "Infernium"
|
||||
@@ -55,7 +54,7 @@ class ItemFlintAndInfernium(properties: Properties) : Item(properties) {
|
||||
}
|
||||
|
||||
init {
|
||||
MinecraftForgeEventBus.register(this)
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
fun igniteTNT(world: World, pos: BlockPos, player: EntityPlayer?, ignoreTrap: Boolean) {
|
||||
@@ -67,14 +66,8 @@ class ItemFlintAndInfernium(properties: Properties) : Item(properties) {
|
||||
pos.removeBlock(world)
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
|
||||
if (!BlockEditor.canEdit(pos, player, heldItem)) {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
if (!BlockEditor.canEdit(pos, player, item)) {
|
||||
return FAIL
|
||||
}
|
||||
|
||||
@@ -85,11 +78,11 @@ class ItemFlintAndInfernium(properties: Properties) : Item(properties) {
|
||||
igniteTNT(world, pos, player, ignoreTrap = false)
|
||||
}
|
||||
else {
|
||||
BlockEditor.place(ModBlocks.ETERNAL_FIRE, player, heldItem, context) ?: return FAIL
|
||||
BlockEditor.place(ModBlocks.ETERNAL_FIRE, player, item, ctx) ?: return FAIL
|
||||
}
|
||||
|
||||
Sounds.ITEM_FLINTANDSTEEL_USE.playServer(world, pos, SoundCategory.BLOCKS, volume = 1.1F, pitch = world.rand.nextFloat(0.4F, 0.5F))
|
||||
heldItem.doDamage(1, player, context.hand)
|
||||
item.doDamage(1, player, ctx.hand)
|
||||
}
|
||||
|
||||
return SUCCESS
|
||||
|
@@ -9,6 +9,7 @@ import chylex.hee.game.entity.item.EntityTokenHolder
|
||||
import chylex.hee.game.entity.selectExistingEntities
|
||||
import chylex.hee.game.inventory.heeTag
|
||||
import chylex.hee.game.inventory.heeTagOrNull
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.mechanics.portal.DimensionTeleporter
|
||||
import chylex.hee.game.mechanics.portal.EntityPortalContact
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
@@ -34,7 +35,6 @@ import chylex.hee.system.serialization.putEnum
|
||||
import net.minecraft.client.renderer.color.IItemColor
|
||||
import net.minecraft.client.util.ITooltipFlag
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemGroup
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
@@ -43,13 +43,14 @@ import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.NonNullList
|
||||
import net.minecraft.util.math.AxisAlignedBB
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.text.ITextComponent
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.dimension.DimensionType
|
||||
|
||||
class ItemPortalToken(properties: Properties) : Item(properties) {
|
||||
class ItemPortalToken(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
companion object {
|
||||
private const val TYPE_TAG = "Type"
|
||||
private const val TERRITORY_TYPE_TAG = "Territory"
|
||||
@@ -72,6 +73,8 @@ class ItemPortalToken(properties: Properties) : Item(properties) {
|
||||
}
|
||||
|
||||
init {
|
||||
components.attach(this)
|
||||
|
||||
addPropertyOverride(Resource.Custom("token_type")) { stack, _, _ ->
|
||||
getTokenType(stack).propertyValue + (if (stack.heeTagOrNull.hasKey(IS_CORRUPTED_TAG)) 0.5F else 0F)
|
||||
}
|
||||
@@ -178,10 +181,7 @@ class ItemPortalToken(properties: Properties) : Item(properties) {
|
||||
return ActionResult(SUCCESS, heldItem)
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
|
||||
if (!player.isCreative || player.isSneaking) {
|
||||
return PASS
|
||||
}
|
||||
@@ -190,16 +190,14 @@ class ItemPortalToken(properties: Properties) : Item(properties) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
val targetPos = context.pos.up()
|
||||
val targetPos = pos.up()
|
||||
val territoryType = getTerritoryType(item)
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
val territoryType = getTerritoryType(heldItem)
|
||||
|
||||
if (territoryType == null || context.face != UP || !BlockEditor.canEdit(targetPos, player, heldItem) || world.selectExistingEntities.inBox<EntityTokenHolder>(AxisAlignedBB(targetPos)).any()) {
|
||||
if (territoryType == null || ctx.face != UP || !BlockEditor.canEdit(targetPos, player, item) || world.selectExistingEntities.inBox<EntityTokenHolder>(AxisAlignedBB(targetPos)).any()) {
|
||||
return FAIL
|
||||
}
|
||||
|
||||
world.addEntity(EntityTokenHolder(world, targetPos, getTokenType(heldItem), territoryType))
|
||||
world.addEntity(EntityTokenHolder(world, targetPos, getTokenType(item), territoryType))
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package chylex.hee.game.item
|
||||
|
||||
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
import chylex.hee.game.world.getTile
|
||||
import chylex.hee.game.world.playUniversal
|
||||
@@ -8,20 +9,19 @@ import chylex.hee.init.ModSounds
|
||||
import chylex.hee.system.migration.ActionResult.FAIL
|
||||
import chylex.hee.system.migration.ActionResult.PASS
|
||||
import chylex.hee.system.migration.ActionResult.SUCCESS
|
||||
import net.minecraft.item.Item
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.SoundCategory
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
class ItemPuzzleMedallion(properties: Properties) : Item(properties) {
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
|
||||
if (!BlockEditor.canEdit(pos, player, heldItem)) {
|
||||
class ItemPuzzleMedallion(properties: Properties) : ItemWithComponents(properties) {
|
||||
init {
|
||||
components.attach(object : UseOnBlockComponent {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
|
||||
if (!BlockEditor.canEdit(pos, player, item)) {
|
||||
return FAIL
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class ItemPuzzleMedallion(properties: Properties) : Item(properties) {
|
||||
|
||||
if (tile != null && !tile.hasMedallion) {
|
||||
tile.hasMedallion = true
|
||||
heldItem.shrink(1)
|
||||
item.shrink(1)
|
||||
|
||||
ModSounds.ITEM_PUZZLE_MEDALLION_INSERT.playUniversal(player, pos, SoundCategory.BLOCKS, volume = 2F, pitch = 0.8F)
|
||||
return SUCCESS
|
||||
@@ -37,4 +37,6 @@ class ItemPuzzleMedallion(properties: Properties) : Item(properties) {
|
||||
|
||||
return PASS
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package chylex.hee.game.item
|
||||
import chylex.hee.client.model.ModelHelper
|
||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||
import chylex.hee.game.entity.item.EntityItemRevitalizationSubstance
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.mechanics.energy.IClusterHealth.HealthOverride.REVITALIZING
|
||||
import chylex.hee.game.particle.ParticleSmokeCustom
|
||||
import chylex.hee.game.particle.spawner.ParticleSpawnerCustom
|
||||
@@ -26,7 +27,6 @@ import chylex.hee.system.serialization.readPos
|
||||
import chylex.hee.system.serialization.use
|
||||
import chylex.hee.system.serialization.writePos
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.network.PacketBuffer
|
||||
@@ -37,7 +37,7 @@ import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import java.util.Random
|
||||
|
||||
class ItemRevitalizationSubstance(properties: Properties) : Item(properties) {
|
||||
class ItemRevitalizationSubstance(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
companion object {
|
||||
private val PARTICLE_FAIL = ParticleSpawnerCustom(
|
||||
type = ParticleSmokeCustom,
|
||||
@@ -70,11 +70,11 @@ class ItemRevitalizationSubstance(properties: Properties) : Item(properties) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
init {
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
if (world.isRemote) {
|
||||
return FAIL // disable animation
|
||||
}
|
||||
@@ -83,11 +83,11 @@ class ItemRevitalizationSubstance(properties: Properties) : Item(properties) {
|
||||
|
||||
if (cluster.currentHealth != REVITALIZING) {
|
||||
if (cluster.addRevitalizationSubstance()) {
|
||||
player.getHeldItem(context.hand).shrink(1)
|
||||
player.getHeldItem(ctx.hand).shrink(1)
|
||||
ModSounds.ITEM_REVITALIZATION_SUBSTANCE_USE_SUCCESS.playServer(world, pos, SoundCategory.BLOCKS, volume = 0.5F)
|
||||
}
|
||||
else {
|
||||
PacketClientFX(FX_FAIL, FxUseData(pos, player, context.hand)).sendToAllAround(player, 24.0)
|
||||
PacketClientFX(FX_FAIL, FxUseData(pos, player, ctx.hand)).sendToAllAround(player, 24.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,33 +2,33 @@ package chylex.hee.game.item
|
||||
|
||||
import chylex.hee.game.block.BlockAbstractTableTile
|
||||
import chylex.hee.game.block.BlockTableBase
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.BlockEditor
|
||||
import chylex.hee.game.world.breakBlock
|
||||
import chylex.hee.game.world.getBlock
|
||||
import chylex.hee.game.world.setBlock
|
||||
import chylex.hee.system.forge.Side
|
||||
import chylex.hee.system.forge.Sided
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import net.minecraft.client.util.ITooltipFlag
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.ActionResultType.FAIL
|
||||
import net.minecraft.util.ActionResultType.PASS
|
||||
import net.minecraft.util.ActionResultType.SUCCESS
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.text.ITextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
|
||||
class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, properties: Properties) : Item(properties) {
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
init {
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
|
||||
if (!BlockEditor.canEdit(pos, player, heldItem)) {
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
|
||||
if (!BlockEditor.canEdit(pos, player, item)) {
|
||||
return FAIL
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, p
|
||||
pos.setBlock(world, table)
|
||||
}
|
||||
|
||||
heldItem.shrink(1)
|
||||
item.shrink(1)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_FAIL
|
||||
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_OUTPUT
|
||||
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_RESTART
|
||||
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_SUCCESS
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.game.world.getBlock
|
||||
import chylex.hee.game.world.getTile
|
||||
import chylex.hee.game.world.playClient
|
||||
@@ -26,6 +27,7 @@ import chylex.hee.system.forge.Sided
|
||||
import chylex.hee.system.migration.ActionResult.FAIL
|
||||
import chylex.hee.system.migration.ActionResult.SUCCESS
|
||||
import chylex.hee.system.migration.EntityItem
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import chylex.hee.system.random.nextFloat
|
||||
import chylex.hee.system.serialization.getPos
|
||||
import chylex.hee.system.serialization.hasKey
|
||||
@@ -34,7 +36,6 @@ import chylex.hee.system.serialization.readPos
|
||||
import chylex.hee.system.serialization.use
|
||||
import chylex.hee.system.serialization.writePos
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.network.PacketBuffer
|
||||
@@ -44,7 +45,7 @@ import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import java.util.Random
|
||||
|
||||
class ItemTableLink(properties: Properties) : Item(properties) {
|
||||
class ItemTableLink(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
|
||||
companion object {
|
||||
private const val POS_TAG = "StoredPos"
|
||||
private const val TIME_TAG = "StoredTime"
|
||||
@@ -106,11 +107,11 @@ class ItemTableLink(properties: Properties) : Item(properties) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
val world = context.world
|
||||
val pos = context.pos
|
||||
init {
|
||||
components.attach(this)
|
||||
}
|
||||
|
||||
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
|
||||
if (!player.isSneaking || !isValidTarget(world, pos)) {
|
||||
val pedestal = pos.getTile<TileEntityTablePedestal>(world)
|
||||
|
||||
@@ -131,7 +132,7 @@ class ItemTableLink(properties: Properties) : Item(properties) {
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
val heldItem = player.getHeldItem(context.hand)
|
||||
val heldItem = player.getHeldItem(ctx.hand)
|
||||
var newStoredPos = pos
|
||||
var soundType = LINK_RESTART
|
||||
|
||||
|
@@ -0,0 +1,18 @@
|
||||
package chylex.hee.game.item
|
||||
|
||||
import chylex.hee.game.item.components.UseOnBlockComponent
|
||||
import chylex.hee.system.component.EntityComponents
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.ActionResultType.FAIL
|
||||
import net.minecraft.util.ActionResultType.PASS
|
||||
|
||||
open class ItemWithComponents(properties: Properties) : Item(properties) {
|
||||
val components = EntityComponents()
|
||||
|
||||
final override fun onItemUse(context: ItemUseContext): ActionResultType {
|
||||
val player = context.player ?: return FAIL
|
||||
return components.handle<UseOnBlockComponent, ActionResultType> { useOnBlock(context.world, context.pos, player, context.item, context) } ?: PASS
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package chylex.hee.game.item.components
|
||||
|
||||
import chylex.hee.system.migration.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ItemUseContext
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
interface UseOnBlockComponent { // TODO use as objects instead of inheriting the interface on Item
|
||||
fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType?
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package chylex.hee.system.component
|
||||
|
||||
abstract class AbstractAwareComponent {
|
||||
var entityComponents: EntityComponents? = null
|
||||
|
||||
open fun onComponentAttached() {}
|
||||
open fun onComponentDetached() {}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package chylex.hee.system.component
|
||||
|
||||
class EntityComponents {
|
||||
private val mutableComponents = mutableListOf<Any>()
|
||||
|
||||
val components: List<Any>
|
||||
get() = mutableComponents
|
||||
|
||||
fun attach(component: Any) {
|
||||
require(!mutableComponents.contains(component)) { "[EntityComponents] component must not be registered twice" }
|
||||
mutableComponents.add(component)
|
||||
|
||||
if (component is AbstractAwareComponent) {
|
||||
require(component.entityComponents === null) { "[EntityComponents] component must not be registered in two entities" }
|
||||
component.entityComponents = this
|
||||
component.onComponentAttached()
|
||||
}
|
||||
}
|
||||
|
||||
fun detach(component: Any) {
|
||||
if (!mutableComponents.remove(component)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (component is AbstractAwareComponent) {
|
||||
require(component.entityComponents === this) { "[EntityComponents] component was not registered correctly" }
|
||||
component.onComponentDetached()
|
||||
component.entityComponents = null
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> on(f: T.() -> Unit) {
|
||||
for(component in components) {
|
||||
if (component is T) {
|
||||
f(component)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T, U> handle(f: T.() -> U?): U? {
|
||||
for(component in components) {
|
||||
if (component is T) {
|
||||
val result = f(component)
|
||||
if (result != null) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <reified T> list(): List<T> {
|
||||
return components.filterIsInstance<T>()
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package chylex.hee.system.component.general
|
||||
|
||||
import chylex.hee.system.component.EntityComponents
|
||||
import chylex.hee.system.serialization.TagCompound
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
|
||||
interface SerializableComponent : INBTSerializable<TagCompound> {
|
||||
val serializationKey: String
|
||||
}
|
||||
|
||||
fun EntityComponents.serializeTo(tag: TagCompound) {
|
||||
this.on<SerializableComponent> {
|
||||
require(!tag.contains(serializationKey)) { "[SerializableComponent] cannot serialize duplicate key: $serializationKey" }
|
||||
tag.put(serializationKey, serializeNBT())
|
||||
}
|
||||
}
|
||||
|
||||
fun EntityComponents.deserializeFrom(tag: TagCompound) {
|
||||
this.on<SerializableComponent> { deserializeNBT(tag.getCompound(serializationKey)) }
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package chylex.hee.system.component.general
|
||||
|
||||
import chylex.hee.system.component.EntityComponents
|
||||
import net.minecraft.entity.Entity
|
||||
|
||||
interface TickableComponent {
|
||||
@JvmDefault fun tickClient() {}
|
||||
@JvmDefault fun tickServer() {}
|
||||
}
|
||||
|
||||
@JvmName("tickEntity")
|
||||
fun <T : Entity> EntityComponents.tick(entity: T) {
|
||||
if (entity.world.isRemote) {
|
||||
this.on(TickableComponent::tickClient)
|
||||
}
|
||||
else {
|
||||
this.on(TickableComponent::tickServer)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user