All Downloads are FREE. Search and download functionalities are using the official Maven repository.

walkmc.hologram.AbstractItemLine.kt Maven / Gradle / Ivy

package walkmc.hologram

import net.minecraft.server.*
import org.bukkit.*
import org.bukkit.World
import org.bukkit.craftbukkit.inventory.*
import org.bukkit.entity.*
import org.bukkit.entity.Item
import org.bukkit.inventory.ItemStack
import walkmc.*
import walkmc.block.*
import walkmc.collections.*
import walkmc.extensions.*
import walkmc.hologram.api.*
import walkmc.hologram.entity.*
import walkmc.serializer.tag.impl.*

/**
 * An abstract implementation of a hologram item line.
 *
 * This works like a skeletal model for any hologram item line.
 */
abstract class AbstractItemLine(world: MinecraftWorld) : EntityHologramItem(world), ItemLine {
	
	constructor() : this(worlds[0].handler)
	constructor(hologram: Hologram) : this(hologram.handler.world) {
		this.hologram = hologram
	}
	
	/**
	 * The carrier of this hologram item line.
	 *
	 * Hologram item lines have a carrier to make the item moves smooth.
	 */
	private lateinit var carrier: EntityItemCarrier
	
	/**
	 * Returns if the carrier item of this hologram item line is already initialized.
	 */
	private val isCarrierInitialized: Boolean
		get() = this::carrier.isInitialized
	
	/**
	 * Returns if the hologram of this item line is already initialized
	 */
	val isHologramInitialized: Boolean
		get() = this::hologram.isInitialized
	
	override val world: World
		get() = world.world
	
	override val location: Location
		get() = Location(world.world, locX, locY, locZ)
	
	override val holder: EntityHologramItem
		get() = this
	
	override val holderEntity: Item
		get() = entityBukkit
	
	override lateinit var hologram: Hologram
	override var options: IndexList = newIndexList()
	override var height: Double = 1.05
	override var allowRefresh: Boolean = false
	override var refreshInterval: Int = 20
	
	override var allowPickup: Boolean = false
		set(value) {
			pickupDelay = if (value) 0 else 32767
			field = value
		}
	
	override fun display(location: Location) {
		if (hasOptions)
			setItem(options[0])
		
		carrier = EntityItemCarrier(location)
		carrier.spawnInWorld(true)
		spawnInWorld(location, true)
		mount(carrier)
	}
	
	override fun move(location: Location, broadcast: Boolean) {
		if (!isValid || !isCarrierInitialized)
			return
		
		carrier.setPosition(location)
		if (broadcast)
			carrier.broadcastTeleportPacket()
	}
	
	override fun onVisibilityChange(player: Player, visible: Boolean) {
		if (isCarrierInitialized) {
			val packet = if (visible) PacketPlayOutSpawnEntityLiving(carrier) else PacketPlayOutEntityDestroy(carrier.id)
			player.sendPacket(packet)
		}
		
		if (isValid) {
			val packet = if (visible) PacketPlayOutSpawnEntity(this, 0, 0) else PacketPlayOutEntityDestroy(id)
			player.sendPacket(packet)
		}
	}
	
	override fun onInteract(player: Player, click: Click, distance: Double): Boolean {
		return true
	}
	
	override fun onPickup(player: Player) {
	}
	
	override fun canRefresh(): Boolean {
		if (!allowRefresh || !isHologramInitialized || !isCarrierInitialized)
			return false
		
		if (!isValid || !carrier.isValid || !hasOptions)
			return false
		
		if (ticksLived % refreshInterval != 0)
			return false
		
		return true
	}
	
	override fun refresh() {
		changeDisplay(options.toNextOrFirst())
	}
	
	override fun onCollideWithPlayer(entityhuman: EntityHuman?) {
		if (entityhuman !is EntityPlayer)
			return
		
		if (allowPickup) {
			entityhuman.entityBukkit.giveItem(currentOption())
			delete()
		}
		
		onPickup(entityhuman.entityBukkit)
	}
	
	override fun onTick() {
		if (!canRefresh())
			return
		
		refresh()
	}
	
	override fun onEntityInteract(player: Player, click: Click, distance: Double): Boolean {
		if (isHologramInitialized)
			hologram.onInteract(player, click, this)
			
		return onInteract(player, click, distance)
	}
	
	override fun saveEntityData(tag: NBTTagCompound) {
		super.saveEntityData(tag)
		
		try {
			tag.setBoolean("AllowRefresh", allowRefresh)
			tag.setInt("RefreshInterval", refreshInterval)
			tag.setDouble("LineHeight", height)
			
			if (hasOptions) {
				val list = NBTTagList()
				for (line in options) {
					val handler = line.handlerCopy() ?: continue
					list.add(handler.writeToNBT(NBTTagCompound()))
				}
				tag.set("Lines", list)
			}
		} catch (ex: Exception) {
			delete()
		}
	}
	
	override fun loadEntityData(tag: NBTTagCompound) {
		super.loadEntityData(tag)
		
		try {
			allowRefresh = tag.getBoolean("AllowRefresh")
			refreshInterval = tag.getInt("RefreshInterval")
			height = tag.getDouble("LineHeight")
			
			if (tag.hasKey("Lines")) {
				val list = tag.getList("Lines", NBTBase.COMPOUND)
				for (line in list) {
					if (line !is NBTTagCompound)
						continue
					
					val item = net.minecraft.server.ItemStack.createStack(line)
					options.add(CraftItemStack.asBukkitCopy(item))
				}
			}
		} catch (ex: Exception) {
			delete()
		}
	}
	
	override fun saveEntityData(tag: CompoundTag) {
		try {
			if (isCarrierInitialized)
				tag["Carrier"] = carrier.uniqueID
		} catch (ex: Exception) {
			delete()
		}
	}
	
	override fun loadEntityDataLater(tag: CompoundTag) {
		try {
			if ("Carrier" in tag) {
				val entity = worldServer.getEntity(tag.getUuid("Carrier"))
				if (entity is EntityItemCarrier)
					carrier = entity
			}
		} catch (ex: Exception) {
			delete()
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy