743d568

Branches > main > 743d568 > files

Dangit I was going to try and commit more often

Grahp, 2026-06-29

Commit: 743d56824391288af266ee50b057946c9876f1e0
Parent: a347d46

22 changed files:

build.gradle.kts modified (view file)

@@ -23,7 +23,7 @@ }  tasks.jar {-  archiveFileName.set("Bowmap.jar")+  archiveFileName.set("Bowmap2.jar")    from({     configurations.runtimeClasspath.get().map { zipTree(it) }

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

@@ -3,40 +3,35 @@ import org.bukkit.plugin.java.JavaPlugin import net.kyori.adventure.text.Component -import net.bowmap.events.* import net.bowmap.paper.* import net.bowmap.server.setup import net.bowmap.stormbow.Listeners-import net.bowmap.handlers.MiscHandlers+import net.bowmap.handlers.*  class Main : JavaPlugin() {   override fun onEnable() {     try {       setup()       server.sendMessage(Component.text("Loading Bowmap..."))-      // server.pluginManager.registerEvents(Chat(), this);-      server.pluginManager.registerEvents(Death(), this);-      server.pluginManager.registerEvents(Durability(), this);-      server.pluginManager.registerEvents(Fishing(), this);-      server.pluginManager.registerEvents(Welcome(), this);-      server.pluginManager.registerEvents(ZoneGuard(), this);-      server.pluginManager.registerEvents(Tutorial(), this); -      server.pluginManager.registerEvents(Listeners(), this);+      setupStormbow(this)       MiscHandlers.register()-+      ZoneGuard.register()+      Death.register()+      Welcome.register()+      Fishing.register()     } catch (t: Exception) {       logger.severe("Startup Failed!")       server.shutdown()     }   } -  override fun onDisable() {-    // logger.severe("Bowmap Failed!")-    // server.shutdown()-  }+  override fun onDisable() { } }  // TODO: // Mob spawning // Disable advancements, make achievements+// Disable the nether just in case, lol+// Remove all uses of ItemStack!+

src/main/kotlin/net/bowmap/events/Death.kt deleted (view file)

@@ -1,64 +0,0 @@-package net.bowmap.events--import net.bowmap.paper.*-import net.bowmap.server.items.BUG-import net.kyori.adventure.text.Component-import net.kyori.adventure.text.format.NamedTextColor.*-import org.bukkit.Material-import org.bukkit.entity.Entity-import org.bukkit.entity.Player-import org.bukkit.entity.Zombie-import org.bukkit.event.EventHandler-import org.bukkit.event.Listener-import org.bukkit.event.entity.EntityDeathEvent-import org.bukkit.inventory.ItemStack--class Death : Listener {-  // Doesn't use attacker but how the player died does contribute to the death event-  // This should probably be the damage source?-  private fun deathMessage(player: Player, attacker: Entity?): Component {-    return headComponent(player)-    .append(SPACE)-    .append(player.displayName())-    .append(Component.text(" Died.", RED))-  }--  // TODO stats-  private fun onPlayerDeath(e: EntityDeathEvent, player: Player, attacker: Entity?) {-    e.isCancelled = true-    broadcast(deathMessage(player, attacker))-  }--  // There is loot table stuff now :)-  private fun calculateDrops(p: Player, victim: Entity): Set<ItemStack> {-    return if (victim is Zombie) {-      setOf(ItemStack(Material.ROTTEN_FLESH))-    } else {-      setOf(BUG)-    }-  }--  private fun onPlayerKill(e: EntityDeathEvent, player: Player, victim: Entity) {-    debug("player KILLED")-    e.droppedExp = 0-    // TODO Based on loot table?-    player.giveExp(1)-    giveOrDrop(player, calculateDrops(player, victim))-  }--  @EventHandler-  fun onEntityDeath(e: EntityDeathEvent) {-    val victim = e.entity-    val attacker = e.damageSource.causingEntity--    if (victim is Player) {-      onPlayerDeath(e, victim, attacker)-    }--    if (attacker is Player) {-      onPlayerKill(e, attacker, victim)-    }--    e.drops.clear()-  }-}

src/main/kotlin/net/bowmap/events/Durability.kt deleted (view file)

@@ -1,12 +0,0 @@-package net.bowmap.events--import org.bukkit.event.Listener-import org.bukkit.event.EventHandler-import org.bukkit.event.player.PlayerItemDamageEvent--class Durability : Listener {-  @EventHandler-  fun onItemLoseDurability(e: PlayerItemDamageEvent) {-    e.isCancelled = true-  }-}

src/main/kotlin/net/bowmap/events/Tutorial.kt deleted (view file)

@@ -1,72 +0,0 @@-package net.bowmap.events--import net.bowmap.server.items.TUTORIAL_BOW--import net.bowmap.Main-import net.kyori.adventure.text.Component-import org.bukkit.Location-import org.bukkit.entity.Villager-import org.bukkit.entity.EntityType-import org.bukkit.entity.Entity-import org.bukkit.entity.Player-import org.bukkit.entity.Damageable-import org.bukkit.entity.Zombie-import org.bukkit.event.Listener-import org.bukkit.event.EventHandler-import org.bukkit.event.entity.EntityDamageByEntityEvent-import org.bukkit.event.entity.EntityDeathEvent-import org.bukkit.Bukkit-import org.bukkit.Material-import org.bukkit.inventory.ItemStack--// Give ID and kill :p-// TODO needs to be per-player-fun spawnTutorialNPC() {-  val server = Bukkit.getServer()-  val loc = Location(server.getWorld("world"), -1.5, 56.0, 3.5);-  val tutorial = loc.getWorld().spawn(loc, Zombie::class.java);-  tutorial.setAI(false)-  tutorial.setShouldBurnInDay(false)-  tutorial.setFireTicks(0)-  tutorial.setInvulnerable(true)-  tutorial.setSilent(true)-  tutorial.customName(Component.text("Tutorial"));-  tutorial.setCustomNameVisible(true)-  // Below name says "PUNCH TO INTERACT"-  // Set look at player-}--fun tutorial(e: Entity): Zombie? {-  // Find a better way!-  return if (e.customName() == Component.text("Tutorial")) e as? Zombie else null-}--class Tutorial : Listener {-  init {-    spawnTutorialNPC()-  }--  @EventHandler-  fun onTutorialDeath(event: EntityDeathEvent) {-    if(tutorial(event.entity) != null) {-      // TODO these items also need to only be pickup-able by the player?-      // If they ignore the bow and don't pick it up, it shouldn't despawn...-      event.drops.clear()-      event.drops.add(TUTORIAL_BOW) // Tutorial Bow!-      event.drops.add(ItemStack(Material.ARROW))-    }-  }--  // TODO can't seem to punch in survival?-  @EventHandler-  fun onPunchTutorial(event: EntityDamageByEntityEvent) {-    tutorial(event.entity)?.let { zombie ->-      // TODO remove the unsafe cast-      zombie.health = 0.0;-      // Give player bow!-      // Drop bow-      Bukkit.broadcast(Component.text("Tutorial NPC killed"))-    }-  }-}-

src/main/kotlin/net/bowmap/events/Welcome.kt deleted (view file)

@@ -1,31 +0,0 @@-package net.bowmap.events--import org.bukkit.event.*-import org.bukkit.event.player.*--import net.kyori.adventure.text.Component-import net.kyori.adventure.text.format.NamedTextColor-import net.bowmap.paper.*--class Welcome : Listener {-  @EventHandler-  // TODO give bow-  fun onPlayerJoin(e: PlayerJoinEvent) {-    e.joinMessage(null)-    if (false) {-      broadcast(headComponent(e.player).append(SPACE, e.player.displayName(), Component.text(" joined the server", NamedTextColor.GREEN)))-    } else {-      broadcast(Component.text("Welcome to Bowmap, ", NamedTextColor.GREEN)-      .append(headComponent(e.player).color(NamedTextColor.WHITE),-      Component.text(" "),-      e.player.displayName().colorIfAbsent(NamedTextColor.WHITE),-      Component.text("!", NamedTextColor.GREEN)))-    }-  }--  @EventHandler-  fun onPlayerQuit(e: PlayerQuitEvent) {-    e.quitMessage(null)-    broadcast(headComponent(e.player).append(SPACE, e.player.displayName(), Component.text(" left the server", NamedTextColor.RED)))-  }-}

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

@@ -0,0 +1,40 @@+package net.bowmap.handlers++import net.bowmap.stormbow.handler+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.*++import net.bowmap.paper.*+import net.bowmap.server.item.BUG+import net.kyori.adventure.text.Component+import net.kyori.adventure.text.format.NamedTextColor.*+import org.bukkit.Material+import org.bukkit.entity.Entity+import org.bukkit.entity.Player+import org.bukkit.entity.Zombie+import org.bukkit.event.EventHandler+import org.bukkit.event.Listener+import org.bukkit.event.entity.EntityDeathEvent+import org.bukkit.inventory.ItemStack+import org.bukkit.damage.DamageSource++// Doesn't use attacker but how the player died does contribute to the death event+// This should probably be the damage source?+private fun deathMessage(player: Player, attacker: DamageSource): Component {+  return headComponent(player)+         .append(SPACE)+         .append(player.displayName())+         .append(Component.text(" Died (jk).", RED))+}++object Death {+  fun register() {+    handler<PlayerDied> {+      effects(Cancel(), Broadcast(message = deathMessage(player, cause)))+    }++    handler<PlayerKilledEntity> {+      effects(Give(player, BUG))+    }+  }+}

src/main/kotlin/net/bowmap/handlers/Fishing.kt renamed from src/main/kotlin/net/bowmap/events/Fishing.kt (view file)

@@ -1,4 +1,8 @@-package net.bowmap.events+package net.bowmap.handlers++import net.bowmap.stormbow.handler+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.*  import net.bowmap.server.loot.* import org.bukkit.Material.*@@ -10,13 +14,11 @@  import net.bowmap.paper.* -private fun calculateFishVelocity(e: PlayerFishEvent): Vector {-  val hook = e.hook+private fun calculateFishVelocity(e: PlayerCaughtFish): Vector {   val eye = e.player.eyeLocation+  val distance = eye.distance(e.hook.location) -  val distance = eye.distance(hook.location)--  return eye.subtract(hook.location)+  return eye.subtract(e.hook.location)             .toVector()             .normalize()             .multiply(0.2 + distance * 0.1)@@ -80,32 +82,20 @@   ) ) -private fun setWaitTime(e: PlayerFishEvent) {-  e.hook.setWaitTime(20)-}+object Fishing {+  fun register() {+    handler<PlayerStartedFishing> {+      effects(SetFishTime(ticks = 20))+    } +    handler<PlayerCaughtFish> {+      val loot = fishingLootTable.getLoot() -class Fishing : Listener {-  @EventHandler-  fun onFish(e: PlayerFishEvent) {-    when (e.state) {-      State.FISHING -> {-        setWaitTime(e)+      for (stack in loot) {+        val item = hook.world.dropItem(hook.location, stack)+        item.setVelocity(calculateFishVelocity(this))       }--      State.CAUGHT_FISH -> {-        val hook = e.hook-        val loot = fishingLootTable.getLoot()--        for (stack in loot) {-          val item = hook.world.dropItem(hook.location, stack)-          item.setVelocity(calculateFishVelocity(e))-        }--        e.caught?.remove()-        e.expToDrop = 1-      }-      else -> {}+      effects()     }   } }

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

@@ -1,11 +1,8 @@ package net.bowmap.handlers -import net.bowmap.stormbow.register import net.bowmap.stormbow.handler-import net.bowmap.stormbow.fact.PlayerSentChatMessage-import net.bowmap.stormbow.fact.Fact-import net.bowmap.stormbow.effect.SendMessage-import net.bowmap.stormbow.effect.effects+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.* import net.kyori.adventure.text.Component  import net.bowmap.perms.prefix

src/main/kotlin/net/bowmap/handlers/Welcome.kt added (view file)

@@ -0,0 +1,26 @@+package net.bowmap.handlers++import net.bowmap.stormbow.handler+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.*++import net.kyori.adventure.text.Component+import net.kyori.adventure.text.format.NamedTextColor+import net.bowmap.paper.*++object Welcome {+  fun register() {+    handler<PlayerJoined> {+        // broadcast(headComponent(player).append(SPACE, player.displayName(), Component.text(" joined the server", NamedTextColor.GREEN)))+        effects(Broadcast(Component.text("Welcome to Bowmap, ", NamedTextColor.GREEN)+        .append(headComponent(player).color(NamedTextColor.WHITE),+                Component.text(" "),+                player.displayName().colorIfAbsent(NamedTextColor.WHITE),+                Component.text("!", NamedTextColor.GREEN))))+    }++    handler<PlayerQuit> {+      effects(Broadcast(headComponent(player).append(SPACE, player.displayName(), Component.text(" left the server", NamedTextColor.RED))))+    }+  }+}

src/main/kotlin/net/bowmap/handlers/ZoneGuard.kt renamed from src/main/kotlin/net/bowmap/events/ZoneGuard.kt (view file)

@@ -1,6 +1,8 @@+package net.bowmap.handlers --package net.bowmap.events+import net.bowmap.stormbow.handler+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.*  import org.bukkit.event.Listener import org.bukkit.event.block.BlockBreakEvent@@ -43,11 +45,14 @@   return isInsideRegion(spawn, b.location) } -class ZoneGuard : Listener {-  @EventHandler-  fun onBlockBreak(e: BlockBreakEvent) {-    if (isBlockInSpawn(e.block)) {-      e.setCancelled(true)+object ZoneGuard {+  fun register() {+    handler<PlayerBrokeBlock> {+      if (isBlockInSpawn(block)) {+        effects(Cancel())+      } else {+        effects()+      }     }   } }

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

@@ -5,7 +5,8 @@  /// Sets up the world state fun setup() {-  Bukkit.getWorlds().forEach { world -> +  // TODO can make these into effects+  Bukkit.getWorlds().forEach { world ->     world.setGameRule(GameRules.ADVANCE_TIME, false)     world.setTime(18000L)     world.setGameRule(GameRules.RESPAWN_RADIUS, 0)

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

@@ -0,0 +1,53 @@+package net.bowmap.server.item++import net.kyori.adventure.text.Component+import org.bukkit.inventory.ItemStack+import org.bukkit.Material+import kotlinx.collections.immutable.*++// 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" }+  }+}++data class Item(+  val material: Material,+  val amount: Int = 1,+  val texture: Texture = Texture(material = material),+  val name: Component,+  val lore: PersistentList<Component> = persistentListOf()+)++fun toItemStack(item: Item): ItemStack {+  // TODO custommodeldata+  val itemStack = ItemStack(item.material, item.amount)+  val meta = itemStack.getItemMeta()++  // itemName is not editable via an anvil, which is the desired behavior+  // TODO make sure its not italics!+  meta.itemName(item.name)+  if (item.lore.isNotEmpty()) {+    // TODO Make sure it's not purple and italics...+    meta.lore(item.lore)+  }++  itemStack.setItemMeta(meta)+  return itemStack+}++fun toItem(itemStack: ItemStack): Item {+  // TODO custommodeldata+  // See the above itemName comment+  val meta = itemStack.getItemMeta()+  val lore = meta.lore()?.toPersistentList() ?: persistentListOf()+  return Item(+    material = itemStack.type,+    amount = itemStack.amount,+    name = meta.itemName(),+    lore = lore+  )+}

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

@@ -0,0 +1,16 @@+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"),+  lore = persistentListOf(+    Component.text("You encountered something that hasn't been implemented yet,", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false),+    Component.text("so you get this instead.", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false)+  )+)

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

@@ -1,52 +0,0 @@-// TODO just make an item class-package net.bowmap.server.items--import net.kyori.adventure.text.Component-import net.kyori.adventure.text.format.NamedTextColor-import net.kyori.adventure.text.format.TextDecoration-import org.bukkit.Material-import org.bukkit.inventory.ItemStack-import org.bukkit.inventory.meta.ItemMeta--val BUG: ItemStack = updateMeta(ItemStack(Material.STONE_BUTTON)) {-  it.itemName(Component.text("Bug"))-  it.lore(-    listOf(-      Component.text("You encountered something that hasn't been implemented yet,", NamedTextColor.GRAY)-                .decoration(TextDecoration.ITALIC, false),-      Component.text("so you get this instead.", NamedTextColor.GRAY)-               .decoration(TextDecoration.ITALIC, false)-    )-  )-}--val TUTORIAL_BOW: ItemStack = updateMeta(ItemStack(Material.BOW)) {-  it.itemName(Component.text("Tutorial Bow"))-  // Rarity-  // Lore:-  // Less powerful than a skeleton's bow.-  // You'll want to find one.-}--// TODO just use a lambda lol-fun updateMeta(item: ItemStack, f: (ItemMeta) -> Unit): ItemStack {-  val newItem = item.clone()-  val meta = newItem.itemMeta-  f(meta)-  newItem.setItemMeta(meta)-  return newItem-}--// data class Texture(val material: Material, val customModelData: Int? = null)-//-// data class BowmapItem(-//   val material: Material,-//   val name: Component,-//   val amount: Int = 1,-//   val maxStackSize: Int = 1,-//   val texture: Texture = Texture(material = material)-// ) {-//   init {-//     require(material == texture.material)-//   }-// }

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

@@ -11,12 +11,6 @@  var registry: PersistentMap<KClass<out Fact>, PersistentList<Handler>> = persistentMapOf() -// Pretty please make these the same type :)-fun <F : Fact> register(factClass: KClass<F>, handler: Handler) {-  val list = registry[factClass] ?: persistentListOf()-  registry = registry.putting(factClass, list.adding(handler))-}- inline fun <reified T : Fact> handler(noinline handler: T.() -> PersistentList<Effect>) {   val adapted: (Fact) -> PersistentList<Effect> = { fact ->     handler(fact as T)

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

@@ -7,18 +7,22 @@ package net.bowmap.stormbow  import io.papermc.paper.event.player.AsyncChatEvent-import net.bowmap.paper.headComponent+import org.bukkit.event.*+import org.bukkit.event.entity.*+import org.bukkit.event.player.*+import org.bukkit.event.block.*+import org.bukkit.entity.* import net.kyori.adventure.text.Component import net.kyori.adventure.audience.Audience +import org.bukkit.event.player.PlayerFishEvent.State import net.bowmap.paper.*-import org.bukkit.event.Listener-import org.bukkit.event.EventHandler import net.bowmap.perms.prefix -import net.bowmap.stormbow.fact.PlayerSentChatMessage-import net.bowmap.stormbow.fact.handle-import net.bowmap.stormbow.effect.execute+import net.bowmap.stormbow.fact.*+import net.bowmap.stormbow.effect.*++import org.bukkit.event.player.PlayerItemDamageEvent  class Listeners : Listener {   @EventHandler@@ -28,4 +32,85 @@     // Here, SendMessage effects could replace the chat message, but there's no reason to     execute(handle(f))   }++  @EventHandler+  fun onItemDamage(e: PlayerItemDamageEvent) {+    // Logic leaking into this layer but oh well+    // Basically this should be controlled by a fact + effect but I can't be bothered+    e.setCancelled(true)+  }++  @EventHandler+  fun onBlockBreak(e: BlockBreakEvent) {+    // Logic leaking into this layer but oh well+    // Basically this should be controlled by a fact + effect but I can't be bothered+    val f = PlayerBrokeBlock(player = e.player, block = e.block)+    val effects = handle(f)+    if (effects.any {it is Cancel}) {+      e.setCancelled(true)+    }+    execute(effects)+  }++  @EventHandler+  fun onEntityDeath(e: EntityDeathEvent) {+    val victim = e.entity+    val attacker = e.damageSource.causingEntity++    if (victim is Player) {+      val effects = handle(PlayerDied(player = victim, cause = e.damageSource))+      if (effects.any {it is Cancel}) {+        e.setCancelled(true)+      }+      execute(effects)+    }++    if (attacker is Player) {+      val effects = handle(PlayerKilledEntity(player = attacker, entity = victim, cause = e.damageSource))+      if (effects.any {it is Cancel}) {+        e.setCancelled(true)+      }+      execute(effects)+    }++    e.drops.clear()+    e.setDroppedExp(0)+  }++  @EventHandler+  fun onPlayerJoin(e: PlayerJoinEvent) {+    e.joinMessage(null)+    execute(handle(PlayerJoined(player = e.player)))+  }++  @EventHandler+  fun onPlayerQuit(e: PlayerQuitEvent) {+    e.quitMessage(null)+    execute(handle(PlayerQuit(player = e.player)))+  }++  @EventHandler+  fun onFishEvent(e: PlayerFishEvent) {+    when (e.state) {+      State.FISHING -> {+        val effects = handle(PlayerStartedFishing(player = e.player, hook = e.hook))+        if (contains<Cancel>(effects)) {+          e.setCancelled(true)+        }++        find<SetFishTime>(effects)?.let {

Show all 115 lines

src/main/kotlin/net/bowmap/stormbow/Setup.kt added (view file)

@@ -0,0 +1,6 @@++package net.bowmap.stormbow++fun setupStormbow(plugin: JavaPlugin) {+  plugin.server.pluginManager.registerEvents(Listeners(), this);+}

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

@@ -3,13 +3,28 @@ import kotlinx.collections.immutable.*  interface Effect {+}++/// An effect that knows how to run itself.+/// Some effects are to be run by event listeners themselves+interface DefaultEffect : Effect {   fun execute() }  fun execute(effects: PersistentList<Effect>) {   effects.forEach { effect ->-    effect.execute()+    if (effect is DefaultEffect) {+      effect.execute()+    }   } }  fun effects(vararg e: Effect) = persistentListOf(*e)++inline fun <reified T : Effect> find(effects: PersistentList<Effect>): T? {+  return effects.filterIsInstance<T>().firstOrNull()+}++inline fun <reified T : Effect> contains(effects: PersistentList<Effect>): Boolean {+  return effects.any {it is T}+}

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

@@ -0,0 +1,37 @@+package net.bowmap.stormbow.effect++import net.kyori.adventure.text.Component+import net.kyori.adventure.audience.Audience+import net.bowmap.stormbow.effect.*+import org.bukkit.inventory.ItemStack+import org.bukkit.Bukkit+import org.bukkit.entity.Player+import net.bowmap.server.item.*++// TODO you can send a message to more than one audience+// I'd like audiences to just be able to be collections :/+data class SendMessage(val audience: Collection<Audience>, val message: Component) : DefaultEffect {+  override fun execute() {+    audience.forEach { a ->+      a.sendMessage(message)+    }+  }+}++data class Broadcast(val message: Component) : DefaultEffect {+  override fun execute() {+    Bukkit.broadcast(message)+  }+}++// Also make Player, mutable players are yucky+data class Give(val player: Player, val item: Item) : DefaultEffect {+  override fun execute() {+    player.give(listOf(toItemStack(item)))+  }+}++/// Cancels the current action.+/// Events will generally call .setCancelled(true), but this is a logical action, and they could do something else.+class Cancel() : Effect+data class SetFishTime(val ticks: Int) : Effect

src/main/kotlin/net/bowmap/stormbow/effect/SendMessage.kt deleted (view file)

@@ -1,15 +0,0 @@-package net.bowmap.stormbow.effect--import net.kyori.adventure.text.Component-import net.kyori.adventure.audience.Audience-import net.bowmap.stormbow.effect.Effect--// TODO you can send a message to more than one audience-// I'd like audiences to just be able to be collections :/-data class SendMessage(val audience: Collection<Audience>, val message: Component) : Effect {-  override fun execute() {-    audience.forEach { a ->-      a.sendMessage(message)-    }-  }-}

src/main/kotlin/net/bowmap/stormbow/fact/Facts.kt modified (view file)

@@ -1,9 +1,18 @@ package net.bowmap.stormbow.fact -import org.bukkit.entity.Player+import org.bukkit.entity.*+import org.bukkit.damage.DamageSource+import org.bukkit.block.Block import net.kyori.adventure.audience.Audience import net.kyori.adventure.text.Component  // TODO a player is a game entity... // Game entities should probably be referenced by their UUID data class PlayerSentChatMessage(val player: Player, val audience: Collection<Audience>, val message: Component) : Fact+data class PlayerBrokeBlock(val player: Player, val block: Block) : Fact+data class PlayerKilledEntity(val player: Player, val entity: Entity, val cause: DamageSource) : Fact+data class PlayerDied(val player: Player, val cause: DamageSource) : Fact+data class PlayerJoined(val player: Player) : Fact+data class PlayerQuit(val player: Player) : Fact+data class PlayerStartedFishing(val player: Player, val hook: FishHook) : Fact+data class PlayerCaughtFish(val player: Player, val hook: FishHook) : Fact