bedd093

Branches > main > bedd093 > files

Sync

Grahp, 2026-07-03

Commit: bedd0931c653d6721f5d864eba7ef4ba6b5d086c
Parent: be9c7ea

8 changed files:

src/main/kotlin/net/bowmap/handlers/Death.kt modified (view file)

@@ -5,7 +5,9 @@ import net.bowmap.stormbow.effect.*  import net.bowmap.server.adventure.headComponent-import net.bowmap.server.item.BUG+import net.bowmap.server.item.*+import net.bowmap.server.loot.tables.mobLootTable+import net.bowmap.server.loot.Loot import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor.* import org.bukkit.Material@@ -25,7 +27,7 @@   return headComponent(player)          .append(Component.text(" "))          .append(player.displayName())-         .append(Component.text(" Died (jk).", RED))+         .append(Component.text(" Died.", RED)) }  object Death {@@ -41,7 +43,12 @@      handler<PlayerKilledEntity> {       // TODO loot tables-      effects(Give(player, BUG))+      val lootTable = mobLootTable(entity)+      if (lootTable is Loot) {+        effects(Give(player, lootTable.getLoot()))+      } else {+        effects(Give(player, Item(CustomItemType.BUG)), Debug("lootTable", lootTable), Debug("class", entity::class))+      }     }   } }

src/main/kotlin/net/bowmap/handlers/Fishing.kt modified (view file)

@@ -13,6 +13,7 @@ import org.bukkit.util.Vector  import net.bowmap.server.loot.tables.fishingLootTable+import net.bowmap.server.item.toItemStacks  private fun calculateFishVelocity(e: PlayerCaughtFish): Vector {   val eye = e.player.eyeLocation@@ -33,7 +34,7 @@     handler<PlayerCaughtFish> {       val loot = fishingLootTable.getLoot() -      for (stack in loot) {+      for (stack in toItemStacks(loot)) {         val item = hook.world.dropItem(hook.location, stack)         item.setVelocity(calculateFishVelocity(this))       }

src/main/kotlin/net/bowmap/server/item/Item.kt modified (view file)

@@ -9,33 +9,25 @@  // Bowmap's Item type -// Either a material or a custommodeldata-data class Texture(val material: Material? = null, val customModelData: Int? = null) {-  init {-    require(material != null || customModelData != null) { "Texture requires either a material or custom model data" }-  }-}- enum class Rarity {-  COMMON, UNCOMMON, RARE+  COMMON, UNCOMMON, RARE, SPECIAL }  fun rarityLoreComponent(rarity: Rarity): Component = when (rarity) {   Rarity.COMMON -> Component.text("COMMON", NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false).decoration(TextDecoration.BOLD, true)   Rarity.UNCOMMON -> Component.text("UNCOMMON", NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false).decoration(TextDecoration.BOLD, true)   Rarity.RARE -> Component.text("RARE", NamedTextColor.BLUE).decoration(TextDecoration.ITALIC, false).decoration(TextDecoration.BOLD, true)+  Rarity.SPECIAL -> Component.text("SPECIAL", NamedTextColor.RED).decoration(TextDecoration.ITALIC, false).decoration(TextDecoration.BOLD, true) }  data class Item(-  val material: Material,+  val type: ItemType,   val amount: Int = 1,-  val texture: Texture = Texture(material = material),-  // Can have a custom name for its rarity-  val name: Component,-  val rarity: Rarity = Rarity.COMMON,-  // Lore is a function of multiple things about an item-  val description: String? = null,-)+) {+  val name: Component = name(type)+  val rarity: Rarity = rarity(type)+  val description: String? = description(type)+}  fun computeLore(item: Item): PersistentList<Component> {   var loreList = persistentListOf<Component>()@@ -44,6 +36,51 @@     // TODO split the lore by text size     loreList = loreList.adding(Component.text(item.description, NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false))   }-  loreList = loreList.adding(rarityLoreComponent(item.rarity))   return loreList }++/// The type of an item+/// Corrosponds to its Minecraft/Bukkit material and custommodeldata/texture+/// Properties like max stack size, name, description, etc., can be derived from this type as well+sealed interface ItemType++fun maxStackSize(type: ItemType) : Int = when (type) {+  is CustomItemType -> type.maxStackSize+  is MaterialItemType -> type.minecraftMaterial.maxStackSize+}++fun name(type: ItemType): Component = when (type) {+  is CustomItemType -> type.defaultName+  is MaterialItemType -> Component.translatable(type.material)+}++fun material(type: ItemType): Material = when (type) {+  is CustomItemType -> type.minecraftMaterial+  is MaterialItemType -> type.minecraftMaterial+}++fun description(type: ItemType): String? = when (type) {+  is CustomItemType -> type.description+  is MaterialItemType -> null // Can have descriptions later+}++fun rarity(type: ItemType): Rarity = when (type) {+  is CustomItemType -> type.rarity+  is MaterialItemType -> Rarity.COMMON+}++data class MaterialItemType(val material: Material) : ItemType {+  val minecraftMaterial = material+  val customModelData = null+}++enum class CustomItemType(+    val minecraftMaterial: Material,+    val defaultName: Component,+    val description: String?,+    val customModelData: Int? = null,+    val maxStackSize: Int = 64,+    val rarity: Rarity = Rarity.COMMON+) : ItemType {+  BUG(Material.STONE_BUTTON, Component.text("This is a bug yeag"), "You found a bug!", rarity = Rarity.SPECIAL)+}

src/main/kotlin/net/bowmap/server/item/ItemStacks.kt modified (view file)

@@ -1,4 +1,3 @@- /// Itemstack interop functions package net.bowmap.server.item @@ -6,7 +5,7 @@  fun toItemStack(item: Item): ItemStack {   // TODO custommodeldata-  val itemStack = ItemStack(item.material, item.amount)+  val itemStack = ItemStack(material(item.type), item.amount)   val meta = itemStack.getItemMeta()    // itemName is not editable via an anvil, which is the desired behavior@@ -18,15 +17,20 @@   return itemStack } +fun toItemStacks(items: List<Item>): List<ItemStack> {+  return items.map(::toItemStack)+}+ /// Turns a vanilla ItemStack into a Bowmap item. /// This function is the inverse of toItemStack, so that toItem(toItemStack(x)) == x fun toItem(itemStack: ItemStack): Item {   // TODO custommodeldata   // See the above itemName comment-  val meta = itemStack.getItemMeta()+  // val meta = itemStack.getItemMeta()   return Item(-    material = itemStack.type,+    // TODO right now this won't work with any custom materials+    // It'll have to be stored somwhere on the item :)+    type = MaterialItemType(itemStack.type),     amount = itemStack.amount,-    name = meta.itemName(),   ) }

src/main/kotlin/net/bowmap/server/item/Items.kt deleted (view file)

@@ -1,13 +0,0 @@-package net.bowmap.server.item--import kotlinx.collections.immutable.*-import org.bukkit.Material-import net.kyori.adventure.text.Component-import net.kyori.adventure.text.format.NamedTextColor-import net.kyori.adventure.text.format.TextDecoration--val BUG = Item(-  material = Material.STONE_BUTTON,-  name = Component.text("Bug"),-  description = "You encountered a very long lore line!"-)

src/main/kotlin/net/bowmap/server/loot/LootTables.kt modified (view file)

@@ -1,11 +1,11 @@ package net.bowmap.server.loot  import org.bukkit.Material-import org.bukkit.inventory.ItemStack import java.util.concurrent.ThreadLocalRandom+import net.bowmap.server.item.*  interface Loot {-  fun getLoot(): List<ItemStack>+  fun getLoot(): List<Item> }  data class LootList(val list: List<Loot>) : Loot {@@ -15,22 +15,23 @@    constructor(vararg loots: Loot) : this(loots.toList()) -  override fun getLoot(): List<ItemStack> {+  override fun getLoot(): List<Item> {     val i = ThreadLocalRandom.current().nextInt(list.size)     return list[i].getLoot()   } } -data class MaterialLoot(val material: Material, val min: Int = 1, val max: Int = min) : Loot {+data class MaterialLoot(val type: ItemType, val min: Int = 1, val max: Int = min) : Loot {+  constructor(material: Material, min: Int = 1, max: Int = min) : this(MaterialItemType(material), min, max)   init {-    require(min >= 1 && min <= max && max <= material.maxStackSize) {+    require(min >= 1 && min <= max && max <= maxStackSize(type)) {       "Invalid min/max stack sizes!"     }   } -  override fun getLoot(): List<ItemStack> {+  override fun getLoot(): List<Item> {     val amount = ThreadLocalRandom.current().nextInt(min, max + 1)-    return listOf(ItemStack(material, amount))+    return listOf(Item(type = type, amount = amount))   } } @@ -44,7 +45,7 @@     require(weight > 0) { "weight must be > 0" }   } -  override fun getLoot(): List<ItemStack> = loot.getLoot()+  override fun getLoot(): List<Item> = loot.getLoot() }  private fun buildLookup(categories: Array<out Category>): Array<Category> {@@ -78,7 +79,7 @@     return lookup[randomWeight]   } -  override fun getLoot(): List<ItemStack> {+  override fun getLoot(): List<Item> {     return pickRandomCategory().getLoot()   } }

src/main/kotlin/net/bowmap/server/loot/tables/Mobs.kt added (view file)

@@ -0,0 +1,27 @@+package net.bowmap.server.loot.tables++import org.bukkit.entity.Zombie+import org.bukkit.entity.Entity+import net.bowmap.server.item.*+import kotlin.reflect.KClass+import net.bowmap.server.loot.*+import org.bukkit.Material.*++// TODO need some kind of way to do armor?+val zombieLootTable = WeightedLoot(+  Category(+    "flesh",+    100,+    MaterialLoot(ROTTEN_FLESH)+  ),+  Category(+    "iron",+    8,+    MaterialLoot(IRON_NUGGET, 4), MaterialLoot(IRON_INGOT)+  )+)++fun mobLootTable(entity: Entity): Loot? = when (entity) {+  is Zombie -> zombieLootTable+  else -> null+}

src/main/kotlin/net/bowmap/stormbow/effect/Effects.kt modified (view file)

@@ -1,6 +1,7 @@ package net.bowmap.stormbow.effect  import net.kyori.adventure.text.Component+import net.kyori.adventure.text.format.NamedTextColor.* import net.kyori.adventure.audience.Audience import net.bowmap.stormbow.effect.* import org.bukkit.inventory.ItemStack@@ -26,10 +27,17 @@   } } -// Also make Player, mutable players are yucky-data class Give(val player: Player, val item: Item) : DefaultEffect {+data class Debug(val id: String, val x: Any?) : DefaultEffect {   override fun execute() {-    player.give(listOf(toItemStack(item)))+    Bukkit.broadcast(Component.text("Debug ($id): $x", GRAY))+  }+}++// Also make Player, mutable players are yucky+data class Give(val player: Player, val items: List<Item>) : DefaultEffect {+  constructor(player: Player, item: Item) : this(player, listOf(item))+  override fun execute() {+    player.give(items.map(::toItemStack))   } }