mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
Register prototypes and recoverers
This commit is contained in:
parent
04f6e647d4
commit
da72759132
@ -2,9 +2,11 @@ package ocelot.desktop
|
||||
|
||||
import li.flor.nativejfilechooser.NativeJFileChooser
|
||||
import ocelot.desktop.audio.{Audio, SoundSource}
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.PersistableItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.ItemRegistry
|
||||
import ocelot.desktop.ui.widget.inventory.item._
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.PersistableItemPrototype
|
||||
import ocelot.desktop.ui.widget.{ExitConfirmationDialog, RootWidget, SettingsDialog}
|
||||
import ocelot.desktop.util.FileUtils.getOcelotConfigDirectory
|
||||
import ocelot.desktop.util._
|
||||
@ -15,6 +17,7 @@ import totoro.ocelot.brain.event.FileSystemActivityType.Floppy
|
||||
import totoro.ocelot.brain.event._
|
||||
import totoro.ocelot.brain.nbt.persistence.NBTPersistence
|
||||
import totoro.ocelot.brain.nbt.{CompressedStreamTools, NBTTagCompound}
|
||||
import totoro.ocelot.brain.util.{DyeColor, Tier}
|
||||
import totoro.ocelot.brain.workspace.Workspace
|
||||
|
||||
import java.io._
|
||||
@ -41,6 +44,7 @@ object OcelotDesktop extends Logging {
|
||||
|
||||
Ocelot.initialize(LogManager.getLogger(Ocelot))
|
||||
setupNbtConstructors()
|
||||
setupItemRegistry()
|
||||
|
||||
val settingsFile = getOcelotConfigDirectory.resolve("ocelot.conf")
|
||||
Settings.load(settingsFile)
|
||||
@ -257,7 +261,6 @@ object OcelotDesktop extends Logging {
|
||||
}
|
||||
|
||||
def setupNbtConstructors(): Unit = {
|
||||
// FIXME: must construct and load an item's prototype first and use it then to build the item itself
|
||||
val itemConstructor = new PersistableItemPrototype.ItemConstructor
|
||||
val tieredConstructor = new NBTPersistence.TieredConstructor
|
||||
NBTPersistence.registerConstructor(classOf[CPUItemPrototype.CPU#Item].getName, itemConstructor)
|
||||
@ -300,6 +303,125 @@ object OcelotDesktop extends Logging {
|
||||
NBTPersistence.registerConstructor(classOf[WirelessNetworkCardItemPrototype.Tier2#Item].getName, itemConstructor)
|
||||
}
|
||||
|
||||
private def setupItemRegistry(): Unit = {
|
||||
ItemRegistry.register(new ItemRegistry.Group("Processor", Some(IconDef("items/CPU2"))) {
|
||||
register(new ItemRegistry.Group("CPU", Some(IconDef("items/CPU2"))) {
|
||||
for (tier <- Tier.One to Tier.Three) {
|
||||
register(new CPUItemPrototype.CPU(tier))
|
||||
}
|
||||
})
|
||||
|
||||
register(new ItemRegistry.Group("APU", Some(IconDef("items/APU2"))) {
|
||||
for (tier <- Tier.One to Tier.Three) {
|
||||
register(new CPUItemPrototype.APU(tier))
|
||||
}
|
||||
})
|
||||
})
|
||||
ItemRegistry.register(new CPUItemPrototype.CPU.Recoverer)
|
||||
ItemRegistry.register(new CPUItemPrototype.APU.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("Memory", Some(IconDef("items/Memory5"))) {
|
||||
for (tier <- Tier.One to Tier.Six) {
|
||||
register(new MemoryItemPrototype(tier))
|
||||
}
|
||||
})
|
||||
ItemRegistry.register(new MemoryItemPrototype.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("GPU", Some(IconDef("items/GraphicsCard2"))) {
|
||||
for (tier <- Tier.One to Tier.Three) {
|
||||
register(new GraphicsCardItemPrototype(tier))
|
||||
}
|
||||
})
|
||||
ItemRegistry.register(new GraphicsCardItemPrototype.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("HDD", Some(IconDef("items/HardDiskDrive2"))) {
|
||||
register(new ItemRegistry.Group("Managed", None) {
|
||||
for (tier <- Tier.One to Tier.Three) {
|
||||
register(new HDDItemPrototype.Managed(tier))
|
||||
}
|
||||
})
|
||||
|
||||
register(new ItemRegistry.Group("Unmanaged", None) {
|
||||
for (tier <- Tier.One to Tier.Three) {
|
||||
register(new HDDItemPrototype.Unmanaged(tier))
|
||||
}
|
||||
})
|
||||
})
|
||||
ItemRegistry.register(new HDDItemPrototype.Managed.Recoverer)
|
||||
ItemRegistry.register(new HDDItemPrototype.Unmanaged.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("Data Card", Some(IconDef("items/DataCard1"))) {
|
||||
register(new DataCardItemPrototype.Tier1)
|
||||
register(new DataCardItemPrototype.Tier2)
|
||||
register(new DataCardItemPrototype.Tier3)
|
||||
})
|
||||
ItemRegistry.register(new DataCardItemPrototype.Tier1.Recoverer)
|
||||
ItemRegistry.register(new DataCardItemPrototype.Tier2.Recoverer)
|
||||
ItemRegistry.register(new DataCardItemPrototype.Tier3.Recoverer)
|
||||
|
||||
ItemRegistry.register(new InternetCardItemPrototype)
|
||||
ItemRegistry.register(new InternetCardItemPrototype.Recoverer)
|
||||
|
||||
ItemRegistry.register(new LinkedCardItemPrototype)
|
||||
ItemRegistry.register(new LinkedCardItemPrototype.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("Network Card", Some(IconDef("items/WirelessNetworkCard1"))) {
|
||||
register(new NetworkCardItemPrototype)
|
||||
|
||||
register(new ItemRegistry.Group("Wireless", Some(IconDef("items/WirelessNetworkCard1"))) {
|
||||
register(new WirelessNetworkCardItemPrototype.Tier1)
|
||||
register(new WirelessNetworkCardItemPrototype.Tier2)
|
||||
})
|
||||
})
|
||||
ItemRegistry.register(new NetworkCardItemPrototype.Recoverer)
|
||||
ItemRegistry.register(new WirelessNetworkCardItemPrototype.Tier1.Recoverer)
|
||||
ItemRegistry.register(new WirelessNetworkCardItemPrototype.Tier2.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("Redstone Card", Some(IconDef("items/RedstoneCard0"))) {
|
||||
register(new RedstoneCardItemPrototype.Tier1)
|
||||
register(new RedstoneCardItemPrototype.Tier2)
|
||||
})
|
||||
ItemRegistry.register(new RedstoneCardItemPrototype.Tier1.Recoverer)
|
||||
ItemRegistry.register(new RedstoneCardItemPrototype.Tier2.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("EEPROM", Some(IconDef("items/EEPROM"))) {
|
||||
register(new EEPROMItemPrototype)
|
||||
|
||||
register(new ItemRegistry.Group("Loot", None) {
|
||||
for (key <- EEPROMItemPrototype.LootFactories.keys) {
|
||||
register(new EEPROMItemPrototype(key))
|
||||
}
|
||||
})
|
||||
})
|
||||
ItemRegistry.register(new EEPROMItemPrototype.Recoverer)
|
||||
|
||||
ItemRegistry.register(new ItemRegistry.Group("Floppy Disk", Some(IconDef("items/FloppyDisk_dyeGray"))) {
|
||||
register(new FloppyItemPrototype.Managed)
|
||||
|
||||
register(new ItemRegistry.Group("Loot", Some(IconDef("items/FloppyDisk_dyeGreen"))) {
|
||||
for (key <- FloppyItemPrototype.Managed.LootFactories.keys) {
|
||||
register(new FloppyItemPrototype.Managed(key))
|
||||
}
|
||||
})
|
||||
|
||||
register(new ItemRegistry.Group("Managed (colored)", Some(IconDef("items/FloppyDisk_dyePink"))) {
|
||||
for (dye <- DyeColor.ALL if dye != DyeColor.GRAY) {
|
||||
register(new FloppyItemPrototype.Managed(dye, None))
|
||||
}
|
||||
})
|
||||
|
||||
register(new ItemRegistry.Group("Unmanaged", Some(IconDef("items/FloppyDisk_dyeBlack"))) {
|
||||
register(new FloppyItemPrototype.Unmanaged(DyeColor.GRAY))
|
||||
|
||||
for (dye <- DyeColor.ALL if dye != DyeColor.GRAY) {
|
||||
register(new FloppyItemPrototype.Unmanaged(dye))
|
||||
}
|
||||
})
|
||||
})
|
||||
ItemRegistry.register(new FloppyItemPrototype.Managed.Recoverer)
|
||||
ItemRegistry.register(new FloppyItemPrototype.Unmanaged.Recoverer)
|
||||
}
|
||||
|
||||
private def setupEventHandlers(): Unit = {
|
||||
EventBus.subscribe[BeepEvent] { event =>
|
||||
if (!UiHandler.audioDisabled)
|
||||
|
||||
@ -4,28 +4,31 @@ import ocelot.desktop.OcelotDesktop
|
||||
import ocelot.desktop.color.IntColor
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.node.EnvironmentNode
|
||||
import ocelot.desktop.ui.widget.inventory.{InventorySlotGroup, Item}
|
||||
import ocelot.desktop.ui.widget.inventory.InventorySlotGroup
|
||||
import ocelot.desktop.ui.widget.inventory.item.FloppyItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.slot.FloppySlot
|
||||
import totoro.ocelot.brain.entity.FloppyDiskDrive
|
||||
import totoro.ocelot.brain.entity.traits.{Environment, Floppy}
|
||||
import totoro.ocelot.brain.entity.traits.Environment
|
||||
import totoro.ocelot.brain.nbt.{NBT, NBTTagCompound}
|
||||
import totoro.ocelot.brain.util.{DyeColor, Persistable}
|
||||
import totoro.ocelot.brain.util.DyeColor
|
||||
|
||||
class DiskDriveNode(val diskDrive: FloppyDiskDrive) extends EnvironmentNode {
|
||||
class DiskDriveNode(val diskDrive: FloppyDiskDrive, initialize: Boolean = true) extends EnvironmentNode {
|
||||
var lastAccess = 0L
|
||||
|
||||
OcelotDesktop.workspace.add(diskDrive)
|
||||
|
||||
val slot = new FloppySlot(diskDrive.inventory(0), workspaceView)
|
||||
val slotGroup = new InventorySlotGroup(slot)
|
||||
|
||||
if (initialize) {
|
||||
slot.item = slot.item.orElse(Some(new FloppyItemPrototype.Managed("openos").build))
|
||||
}
|
||||
|
||||
def this(nbt: NBTTagCompound) {
|
||||
this({
|
||||
val address = nbt.getString("address")
|
||||
OcelotDesktop.workspace.entityByAddress(address).get.asInstanceOf[FloppyDiskDrive]
|
||||
})
|
||||
}, false)
|
||||
|
||||
load(nbt)
|
||||
}
|
||||
|
||||
@ -146,6 +146,8 @@ object InventorySlotGroup extends Logging {
|
||||
new Exception(s"Inventory ${slot.inventory.owner} stores an Entity $entity (slot index: ${slot.index}) " +
|
||||
s"that cannot be recovered to an Item")
|
||||
).log("Could not recover an item from an Inventory")
|
||||
} else {
|
||||
logger.debug(s"Recovered an Item from $entity (inventory ${slot.inventory.owner}, slot ${slot.index})")
|
||||
}
|
||||
|
||||
item
|
||||
|
||||
@ -8,7 +8,7 @@ import scala.reflect.ClassTag
|
||||
trait ItemRecoverer {
|
||||
type Element
|
||||
|
||||
implicit val elementTag: ClassTag[Element]
|
||||
val elementTag: ClassTag[Element]
|
||||
|
||||
def recover(element: Element): Item[Element]
|
||||
}
|
||||
|
||||
@ -25,8 +25,7 @@ object ItemRegistry {
|
||||
recovererRegistry(recoverer.elementTag.runtimeClass) = recoverer
|
||||
|
||||
def recover[E](element: E): Option[Item[E]] = {
|
||||
recovererRegistry
|
||||
.get(element.getClass)
|
||||
findSuperclass(Some(element.getClass))(recovererRegistry.get)
|
||||
.map(recoverer => {
|
||||
// wild type-casting ¯\_(ツ)_/¯
|
||||
// (should be safe though)
|
||||
@ -36,9 +35,30 @@ object ItemRegistry {
|
||||
|
||||
def children: Iterator[Node] = nodes.iterator
|
||||
|
||||
private def findSuperclass[T](classes: IterableOnce[Class[_]])(filter: Class[_] => Option[T]): Option[T] = {
|
||||
val visited = mutable.Set.empty[Class[_]]
|
||||
val queue = mutable.ArrayDeque.from(classes)
|
||||
|
||||
while (queue.nonEmpty) {
|
||||
val clazz = queue.removeHead()
|
||||
val filterResult = filter(clazz)
|
||||
|
||||
if (filterResult.nonEmpty) {
|
||||
return filterResult
|
||||
}
|
||||
|
||||
visited += clazz
|
||||
|
||||
val superclasses = Option(clazz.getSuperclass).iterator ++ clazz.getInterfaces
|
||||
queue ++= superclasses.filterNot(visited)
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
sealed trait Node
|
||||
|
||||
abstract case class Group(name: String, icon: Option[IconDef]) extends Node { self =>
|
||||
abstract case class Group(name: String, icon: Option[IconDef]) extends Node {
|
||||
private val _children: ArrayBuffer[Node] = ArrayBuffer.empty
|
||||
|
||||
final def children: Iterator[Node] = _children.iterator
|
||||
|
||||
@ -4,6 +4,7 @@ import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry, Cont
|
||||
import ocelot.desktop.ui.widget.inventory.ItemRegistry.{Group, Node}
|
||||
|
||||
trait LmbItemSelectionSlot[E] extends SlotWidget[E] {
|
||||
// FIXME: nested submenus exhibit weird behavior
|
||||
override def fillLmbMenu(menu: ContextMenu): Unit = {
|
||||
def traverse(node: Node): Option[ContextMenuEntry] = node match {
|
||||
case group@Group(name, icon) =>
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.ItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{EnvironmentItemPrototype, PersistableItemPrototype, SlotTieredItemPrototype}
|
||||
import totoro.ocelot.brain.entity
|
||||
import totoro.ocelot.brain.entity.traits.{GenericCPU, Tiered}
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class CPUItemPrototype[E <: GenericCPU](implicit override val elementTag: ClassTag[E])
|
||||
extends ItemPrototype.WithInstance
|
||||
@ -28,7 +28,7 @@ sealed abstract class CPUItemPrototype[E <: GenericCPU](implicit override val el
|
||||
}
|
||||
|
||||
object CPUItemPrototype {
|
||||
class CPU(override var tier: Int) extends CPUItemPrototype[entity.CPU] {
|
||||
final class CPU(override var tier: Int) extends CPUItemPrototype[entity.CPU] {
|
||||
override type Item = Instance
|
||||
|
||||
override def name: String = s"CPU ($tierString)"
|
||||
@ -38,7 +38,21 @@ object CPUItemPrototype {
|
||||
override def build: Item = new Instance(new entity.CPU(tier))
|
||||
}
|
||||
|
||||
class APU(override var tier: Int) extends CPUItemPrototype[entity.APU] {
|
||||
object CPU {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = entity.CPU
|
||||
|
||||
override val elementTag: ClassTag[entity.CPU] = classTag[entity.CPU]
|
||||
|
||||
override def recover(element: entity.CPU): Item[entity.CPU] = {
|
||||
val proto = new CPU(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class APU(override var tier: Int) extends CPUItemPrototype[entity.APU] {
|
||||
override type Item = Instance
|
||||
|
||||
override def name: String = s"APU ($tierString)"
|
||||
@ -55,5 +69,17 @@ object CPUItemPrototype {
|
||||
private val Animation = Some(Array(
|
||||
(0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f),
|
||||
(4, 3f), (3, 3f), (2, 3f), (1, 3f), (0, 3f)))
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = entity.APU
|
||||
|
||||
override val elementTag: ClassTag[entity.APU] = classTag[entity.APU]
|
||||
|
||||
override def recover(element: entity.APU): Item[entity.APU] = {
|
||||
val proto = new APU(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.ItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype, SlotTieredItemPrototype}
|
||||
import totoro.ocelot.brain.entity.DataCard
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class DataCardItemPrototype[E <: DataCard](implicit override val elementTag: ClassTag[E])
|
||||
extends ItemPrototype.WithInstance
|
||||
@ -30,7 +30,7 @@ sealed abstract class DataCardItemPrototype[E <: DataCard](implicit override val
|
||||
object DataCardItemPrototype {
|
||||
private final val Animation = Some(Array((0, 4f), (1, 4f), (2, 4f), (3, 4f), (4, 4f), (5, 4f), (6, 4f), (7, 4f)))
|
||||
|
||||
class Tier1 extends DataCardItemPrototype[DataCard.Tier1] {
|
||||
final class Tier1 extends DataCardItemPrototype[DataCard.Tier1] {
|
||||
override type Item = Instance
|
||||
|
||||
override val slotTier: Int = Tier.One
|
||||
@ -38,6 +38,20 @@ object DataCardItemPrototype {
|
||||
override def build: Item = new Instance(new DataCard.Tier1)
|
||||
}
|
||||
|
||||
object Tier1 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = DataCard.Tier1
|
||||
|
||||
override val elementTag: ClassTag[DataCard.Tier1] = classTag[DataCard.Tier1]
|
||||
|
||||
override def recover(element: DataCard.Tier1): Item[DataCard.Tier1] = {
|
||||
val proto = new Tier1
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Tier2 extends DataCardItemPrototype[DataCard.Tier2] {
|
||||
override type Item = Instance
|
||||
|
||||
@ -46,6 +60,20 @@ object DataCardItemPrototype {
|
||||
override def build: Item = new Instance(new DataCard.Tier2)
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = DataCard.Tier2
|
||||
|
||||
override val elementTag: ClassTag[DataCard.Tier2] = classTag[DataCard.Tier2]
|
||||
|
||||
override def recover(element: DataCard.Tier2): Item[DataCard.Tier2] = {
|
||||
val proto = new Tier2
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Tier3 extends DataCardItemPrototype[DataCard.Tier3] {
|
||||
override type Item = Instance
|
||||
|
||||
@ -53,4 +81,18 @@ object DataCardItemPrototype {
|
||||
|
||||
override def build: Item = new Instance(new DataCard.Tier3)
|
||||
}
|
||||
|
||||
object Tier3 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = DataCard.Tier3
|
||||
|
||||
override val elementTag: ClassTag[DataCard.Tier3] = classTag[DataCard.Tier3]
|
||||
|
||||
override def recover(element: DataCard.Tier3): Item[DataCard.Tier3] = {
|
||||
val proto = new Tier3
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.ItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.EEPROMItemPrototype.LootFactories
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.EEPROM
|
||||
@ -11,7 +11,7 @@ import totoro.ocelot.brain.workspace.Workspace
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class EEPROMItemPrototype(private var lootFactoryKey: Option[String])
|
||||
final class EEPROMItemPrototype(private var lootFactoryKey: Option[String])
|
||||
extends ItemPrototype.WithInstance
|
||||
with EnvironmentItemPrototype
|
||||
with PersistableItemPrototype {
|
||||
@ -23,6 +23,10 @@ class EEPROMItemPrototype(private var lootFactoryKey: Option[String])
|
||||
this(None)
|
||||
}
|
||||
|
||||
def this(lootFactoryKey: String) {
|
||||
this(Some(lootFactoryKey))
|
||||
}
|
||||
|
||||
override type Element = EEPROM
|
||||
override type Item = Instance
|
||||
|
||||
@ -67,4 +71,17 @@ object EEPROMItemPrototype {
|
||||
)
|
||||
|
||||
private final val LootTag = "loot"
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = EEPROM
|
||||
|
||||
override val elementTag: ClassTag[EEPROM] = classTag[EEPROM]
|
||||
|
||||
override def recover(element: EEPROM): Item[EEPROM] = {
|
||||
// TODO: try to recover loot factory info? (use hash codes)
|
||||
val proto = new EEPROMItemPrototype
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ package ocelot.desktop.ui.widget.inventory.item
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.item.FloppyItemPrototype.Managed.LootFactories
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import totoro.ocelot.brain.entity.traits.Floppy
|
||||
import totoro.ocelot.brain.entity.{FloppyManaged, FloppyUnmanaged}
|
||||
import totoro.ocelot.brain.loot.Loot
|
||||
@ -11,7 +11,7 @@ import totoro.ocelot.brain.nbt.NBTTagCompound
|
||||
import totoro.ocelot.brain.util.DyeColor
|
||||
import totoro.ocelot.brain.workspace.Workspace
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class FloppyItemPrototype[E <: Floppy](var color: DyeColor)
|
||||
(implicit override val elementTag: ClassTag[E])
|
||||
@ -42,7 +42,7 @@ sealed abstract class FloppyItemPrototype[E <: Floppy](var color: DyeColor)
|
||||
}
|
||||
|
||||
object FloppyItemPrototype {
|
||||
class Managed(initialColor: DyeColor,
|
||||
final class Managed(initialColor: DyeColor,
|
||||
private var lootFactoryKey: Option[String]) extends FloppyItemPrototype[FloppyManaged](initialColor) {
|
||||
def this() {
|
||||
this(DyeColor.GRAY, None)
|
||||
@ -94,9 +94,21 @@ object FloppyItemPrototype {
|
||||
)
|
||||
|
||||
private final val LootTag = "loot"
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = FloppyManaged
|
||||
|
||||
override val elementTag: ClassTag[FloppyManaged] = classTag[FloppyManaged]
|
||||
|
||||
override def recover(element: FloppyManaged): Item[FloppyManaged] = {
|
||||
val proto = new Managed(element.color, None)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Unmanaged(initialColor: DyeColor) extends FloppyItemPrototype[FloppyUnmanaged](initialColor) {
|
||||
final class Unmanaged(initialColor: DyeColor) extends FloppyItemPrototype[FloppyUnmanaged](initialColor) {
|
||||
def this() {
|
||||
this(DyeColor.GRAY)
|
||||
}
|
||||
@ -108,5 +120,19 @@ object FloppyItemPrototype {
|
||||
override def build: Item = new Instance(new FloppyUnmanaged(name, color))
|
||||
}
|
||||
|
||||
object Unmanaged {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = FloppyUnmanaged
|
||||
|
||||
override val elementTag: ClassTag[FloppyUnmanaged] = classTag[FloppyUnmanaged]
|
||||
|
||||
override def recover(element: FloppyUnmanaged): Item[FloppyUnmanaged] = {
|
||||
val proto = new Unmanaged(element.color)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final val ColorTag = "color"
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@ package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import totoro.ocelot.brain.entity.GraphicsCard
|
||||
import totoro.ocelot.brain.entity.traits.Tiered
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class GraphicsCardItemPrototype(override var tier: Int)
|
||||
final class GraphicsCardItemPrototype(override var tier: Int)
|
||||
extends ItemPrototype.WithInstance
|
||||
with CardItemPrototype
|
||||
with EnvironmentItemPrototype
|
||||
@ -35,3 +35,17 @@ class GraphicsCardItemPrototype(override var tier: Int)
|
||||
with super[EnvironmentItemPrototype].ExtendedInstance
|
||||
with super[PersistableItemPrototype].ExtendedInstance
|
||||
}
|
||||
|
||||
object GraphicsCardItemPrototype {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = GraphicsCard
|
||||
|
||||
override val elementTag: ClassTag[GraphicsCard] = classTag[GraphicsCard]
|
||||
|
||||
override def recover(element: GraphicsCard): Item[GraphicsCard] = {
|
||||
val proto = new GraphicsCardItemPrototype(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,12 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{EnvironmentItemPrototype, PersistableItemPrototype, SlotTieredItemPrototype}
|
||||
import totoro.ocelot.brain.entity.{HDDManaged, HDDUnmanaged}
|
||||
import totoro.ocelot.brain.entity.traits.{Disk, Tiered}
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class HDDItemPrototype[E <: Disk](implicit override val elementTag: ClassTag[E])
|
||||
extends ItemPrototype.WithInstance
|
||||
@ -28,7 +28,7 @@ sealed abstract class HDDItemPrototype[E <: Disk](implicit override val elementT
|
||||
}
|
||||
|
||||
object HDDItemPrototype {
|
||||
class Managed(override var tier: Int) extends HDDItemPrototype[HDDManaged] {
|
||||
final class Managed(override var tier: Int) extends HDDItemPrototype[HDDManaged] {
|
||||
override type Item = Instance
|
||||
|
||||
override def name: String = s"HDD ($tierString)"
|
||||
@ -36,7 +36,21 @@ object HDDItemPrototype {
|
||||
override def build: Item = new Instance(new HDDManaged(tier))
|
||||
}
|
||||
|
||||
class Unmanaged(override var tier: Int) extends HDDItemPrototype[HDDUnmanaged] {
|
||||
object Managed {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = HDDManaged
|
||||
|
||||
override val elementTag: ClassTag[HDDManaged] = classTag[HDDManaged]
|
||||
|
||||
override def recover(element: HDDManaged): Item[HDDManaged] = {
|
||||
val proto = new Managed(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class Unmanaged(override var tier: Int) extends HDDItemPrototype[HDDUnmanaged] {
|
||||
override type Item = Instance
|
||||
|
||||
override def name: String = s"HDD ($tierString, unmanaged)"
|
||||
@ -44,4 +58,18 @@ object HDDItemPrototype {
|
||||
// TODO: figure out what should be fed to name
|
||||
override def build: Item = new Instance(new HDDUnmanaged(tier, name = null))
|
||||
}
|
||||
|
||||
object Unmanaged {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = HDDUnmanaged
|
||||
|
||||
override val elementTag: ClassTag[HDDUnmanaged] = classTag[HDDUnmanaged]
|
||||
|
||||
override def recover(element: HDDUnmanaged): Item[HDDUnmanaged] = {
|
||||
val proto = new Unmanaged(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,14 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.InternetCard
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class InternetCardItemPrototype
|
||||
final class InternetCardItemPrototype
|
||||
extends ItemPrototype
|
||||
with CardItemPrototype
|
||||
with EnvironmentItemPrototype
|
||||
@ -36,4 +36,16 @@ class InternetCardItemPrototype
|
||||
object InternetCardItemPrototype {
|
||||
private final val Animation =
|
||||
Some(Array((0, 2f), (1, 7f), (0, 5f), (1, 4f), (0, 7f), (1, 2f), (0, 8f), (1, 9f), (0, 6f), (1, 4f)))
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = InternetCard
|
||||
|
||||
override val elementTag: ClassTag[InternetCard] = classTag[InternetCard]
|
||||
|
||||
override def recover(element: InternetCard): Item[InternetCard] = {
|
||||
val proto = new InternetCardItemPrototype
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.LinkedCard
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class LinkedCardItemPrototype
|
||||
final class LinkedCardItemPrototype
|
||||
extends ItemPrototype
|
||||
with CardItemPrototype
|
||||
with EnvironmentItemPrototype
|
||||
@ -35,4 +35,16 @@ class LinkedCardItemPrototype
|
||||
|
||||
object LinkedCardItemPrototype {
|
||||
private final val Animation = Some(Array((0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f)))
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = LinkedCard
|
||||
|
||||
override val elementTag: ClassTag[LinkedCard] = classTag[LinkedCard]
|
||||
|
||||
override def recover(element: LinkedCard): Item[LinkedCard] = {
|
||||
val proto = new LinkedCardItemPrototype
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{EnvironmentItemPrototype, PersistableItemPrototype, SlotTieredItemPrototype}
|
||||
import totoro.ocelot.brain.entity.Memory
|
||||
import totoro.ocelot.brain.entity.traits.Tiered
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class MemoryItemPrototype(var tier: Int)
|
||||
final class MemoryItemPrototype(var tier: Int)
|
||||
extends ItemPrototype
|
||||
with SlotTieredItemPrototype
|
||||
with EnvironmentItemPrototype
|
||||
with PersistableItemPrototype
|
||||
with Tiered {
|
||||
|
||||
require((1 to 6).contains(tier), s"Unsupported memory tier: $tier")
|
||||
require((Tier.One to Tier.Six).contains(tier), s"Unsupported memory tier: $tier")
|
||||
|
||||
override type Element = Memory
|
||||
override type Item = Instance
|
||||
@ -44,4 +45,16 @@ object MemoryItemPrototype {
|
||||
"Tier 2", "Tier 2.5",
|
||||
"Tier 3", "Tier 3.5",
|
||||
)
|
||||
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = Memory
|
||||
|
||||
override val elementTag: ClassTag[Memory] = classTag[Memory]
|
||||
|
||||
override def recover(element: Memory): Item[Memory] = {
|
||||
val proto = new MemoryItemPrototype(element.tier)
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.NetworkCard
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
class NetworkCardItemPrototype
|
||||
final class NetworkCardItemPrototype
|
||||
extends ItemPrototype
|
||||
with CardItemPrototype
|
||||
with EnvironmentItemPrototype
|
||||
@ -32,3 +32,17 @@ class NetworkCardItemPrototype
|
||||
with super[EnvironmentItemPrototype].ExtendedInstance
|
||||
with super[PersistableItemPrototype].ExtendedInstance
|
||||
}
|
||||
|
||||
object NetworkCardItemPrototype {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = NetworkCard
|
||||
|
||||
override val elementTag: ClassTag[NetworkCard] = classTag[NetworkCard]
|
||||
|
||||
override def recover(element: NetworkCard): Item[NetworkCard] = {
|
||||
val proto = new NetworkCardItemPrototype
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,13 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype}
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.Redstone
|
||||
import totoro.ocelot.brain.entity.traits.Environment
|
||||
import totoro.ocelot.brain.util.{Persistable, Tier}
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class RedstoneCardItemPrototype[E <: Environment with Persistable](implicit override val elementTag: ClassTag[E])
|
||||
extends ItemPrototype
|
||||
@ -30,7 +30,7 @@ sealed abstract class RedstoneCardItemPrototype[E <: Environment with Persistabl
|
||||
}
|
||||
|
||||
object RedstoneCardItemPrototype {
|
||||
class Tier1 extends RedstoneCardItemPrototype[Redstone.Tier1] {
|
||||
final class Tier1 extends RedstoneCardItemPrototype[Redstone.Tier1] {
|
||||
override type Item = Instance
|
||||
|
||||
override val slotTier: Int = Tier.One
|
||||
@ -38,11 +38,39 @@ object RedstoneCardItemPrototype {
|
||||
override def build: Item = new Instance(new Redstone.Tier1)
|
||||
}
|
||||
|
||||
class Tier2 extends RedstoneCardItemPrototype[Redstone.Tier2] {
|
||||
object Tier1 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = Redstone.Tier1
|
||||
|
||||
override val elementTag: ClassTag[Redstone.Tier1] = classTag[Redstone.Tier1]
|
||||
|
||||
override def recover(element: Redstone.Tier1): Item[Redstone.Tier1] = {
|
||||
val proto = new Tier1
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class Tier2 extends RedstoneCardItemPrototype[Redstone.Tier2] {
|
||||
override type Item = Instance
|
||||
|
||||
override val slotTier: Int = Tier.Two
|
||||
|
||||
override def build: Item = new Instance(new Redstone.Tier2)
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = Redstone.Tier2
|
||||
|
||||
override val elementTag: ClassTag[Redstone.Tier2] = classTag[Redstone.Tier2]
|
||||
|
||||
override def recover(element: Redstone.Tier2): Item[Redstone.Tier2] = {
|
||||
val proto = new Tier2
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
package ocelot.desktop.ui.widget.inventory.item
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.ui.widget.inventory.ItemPrototype
|
||||
import ocelot.desktop.ui.widget.inventory.{Item, ItemPrototype, ItemRecoverer}
|
||||
import ocelot.desktop.ui.widget.inventory.item.traits.{CardItemPrototype, EnvironmentItemPrototype, PersistableItemPrototype}
|
||||
import totoro.ocelot.brain.entity.WirelessNetworkCard
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
sealed abstract class WirelessNetworkCardItemPrototype[E <: WirelessNetworkCard](implicit override val elementTag: ClassTag[E])
|
||||
extends ItemPrototype
|
||||
@ -27,7 +27,7 @@ sealed abstract class WirelessNetworkCardItemPrototype[E <: WirelessNetworkCard]
|
||||
}
|
||||
|
||||
object WirelessNetworkCardItemPrototype {
|
||||
class Tier1 extends WirelessNetworkCardItemPrototype[WirelessNetworkCard.Tier1] {
|
||||
final class Tier1 extends WirelessNetworkCardItemPrototype[WirelessNetworkCard.Tier1] {
|
||||
override type Item = Instance
|
||||
|
||||
override val slotTier: Int = Tier.One
|
||||
@ -35,11 +35,39 @@ object WirelessNetworkCardItemPrototype {
|
||||
override def build: Item = new Instance(new WirelessNetworkCard.Tier1)
|
||||
}
|
||||
|
||||
class Tier2 extends WirelessNetworkCardItemPrototype[WirelessNetworkCard.Tier2] {
|
||||
object Tier1 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = WirelessNetworkCard.Tier1
|
||||
|
||||
override val elementTag: ClassTag[WirelessNetworkCard.Tier1] = classTag[WirelessNetworkCard.Tier1]
|
||||
|
||||
override def recover(element: WirelessNetworkCard.Tier1): Item[WirelessNetworkCard.Tier1] = {
|
||||
val proto = new Tier1
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class Tier2 extends WirelessNetworkCardItemPrototype[WirelessNetworkCard.Tier2] {
|
||||
override type Item = Instance
|
||||
|
||||
override val slotTier: Int = Tier.Two
|
||||
|
||||
override def build: Item = new Instance(new WirelessNetworkCard.Tier2)
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
class Recoverer extends ItemRecoverer {
|
||||
override type Element = WirelessNetworkCard.Tier2
|
||||
|
||||
override val elementTag: ClassTag[WirelessNetworkCard.Tier2] = classTag[WirelessNetworkCard.Tier2]
|
||||
|
||||
override def recover(element: WirelessNetworkCard.Tier2): Item[WirelessNetworkCard.Tier2] = {
|
||||
val proto = new Tier2
|
||||
|
||||
new proto.Instance(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ trait SlotTieredItemPrototype {
|
||||
|
||||
protected def tierString: String =
|
||||
if (slotTier == Tier.Four) "Creative"
|
||||
else s"Tier $slotTier"
|
||||
else s"Tier ${slotTier + 1}"
|
||||
}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package ocelot.desktop.ui.widget.inventory.slot
|
||||
|
||||
import ocelot.desktop.ui.widget.WorkspaceView
|
||||
import ocelot.desktop.ui.widget.inventory.{ItemPrototype, SlotWidget}
|
||||
import ocelot.desktop.ui.widget.inventory.{ItemPrototype, LmbItemSelectionSlot, SlotWidget}
|
||||
|
||||
class AnySlot(workspaceView: WorkspaceView)
|
||||
extends SlotWidget[AnyRef](workspaceView)
|
||||
with LmbItemSelectionSlot[AnyRef] {
|
||||
|
||||
class AnySlot(workspaceView: WorkspaceView) extends SlotWidget[AnyRef](workspaceView) {
|
||||
override def accepts(prototype: ItemPrototype): Boolean = true
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import ocelot.desktop.ui.widget.inventory.{DecoratedSlotWidget, InventorySlotWid
|
||||
import totoro.ocelot.brain.entity.HDDManaged
|
||||
import totoro.ocelot.brain.entity.traits.Inventory
|
||||
|
||||
// TODO: accept unmanaged HDDs!
|
||||
class DiskSlot(owner: Inventory#Slot, val tier: Int, workspaceView: WorkspaceView)
|
||||
extends InventorySlotWidget[HDDManaged](owner, workspaceView)
|
||||
with DecoratedSlotWidget[HDDManaged]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user