From c35ba8201a57eb420a00e2185951507fcda93618 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Mon, 24 Apr 2017 21:31:53 +0900 Subject: [PATCH] new ID for dynamic item work flawlessly with adding multiple at once --- REFERENCING.md | 10 +++--- src/net/torvald/terrarum/AmmoMeterProxy.kt | 8 ++--- .../torvald/terrarum/UIItemInventoryElem.kt | 6 ++-- src/net/torvald/terrarum/console/Inventory.kt | 2 +- src/net/torvald/terrarum/gameactors/Actor.kt | 26 +++++++------- .../terrarum/gameactors/ActorInventory.kt | 35 +++++++++++++------ .../terrarum/gameactors/DroppedItem.kt | 2 +- .../torvald/terrarum/gameworld/GameEconomy.kt | 5 ++- .../terrarum/itemproperties/InventoryItem.kt | 21 ++++++++--- .../terrarum/itemproperties/ItemCodex.kt | 6 ++-- 10 files changed, 77 insertions(+), 44 deletions(-) diff --git a/REFERENCING.md b/REFERENCING.md index 8a4369819..3c161b4d3 100644 --- a/REFERENCING.md +++ b/REFERENCING.md @@ -4,9 +4,9 @@ |4096..8191|Walls| |8192..8447|Wires| |8448..32767|Items (static)| -|32768..1048575|Items (dynamic\*)| -|1048576..0x7FFF_FFFF|Actors| -|0x8000_0000..0xFFFF_FFFF (all negative numbers)|Faction| +|32768..0x0FFF_FFFF|Items (dynamic\*)| +|0x1000_0000..0x7FFF_FFFF|Actors| +|-2147483648..-1 (all negative numbers)|Faction| * dynamic items can have their own properties that will persist through savegame. @@ -14,7 +14,7 @@ Actors range in-depth |Range|Description| |-----|-----------| -|1048576..0x0FFF_FFFF|Rendered behind (e.g. tapestries) -|0x1000_0000..0x5FFF_FFFF|Regular actors (e.g. almost all of them) +|0x1000_0000..0x1FFF_FFFF|Rendered behind (e.g. tapestries) +|0x2000_0000..0x5FFF_FFFF|Regular actors (e.g. almost all of them) |0x6000_0000..0x6FFF_FFFF|Special (e.g. weapon swung, bullets, dropped item, particles) |0x7000_0000..0x7FFF_FFFF|Rendered front (e.g. fake tile) \ No newline at end of file diff --git a/src/net/torvald/terrarum/AmmoMeterProxy.kt b/src/net/torvald/terrarum/AmmoMeterProxy.kt index ac121cefa..82e43dd3c 100644 --- a/src/net/torvald/terrarum/AmmoMeterProxy.kt +++ b/src/net/torvald/terrarum/AmmoMeterProxy.kt @@ -20,16 +20,16 @@ object AmmoMeterProxy { else { meter.vitalGetterVal = { if (ItemCodex[currentItem.originalID].consumable) - actor.inventory.getByDynamicID(currentItem.dynamicID)!!.amount.toFloat() - else - actor.inventory.getByDynamicID(currentItem.dynamicID)!!.item.durability + actor.inventory.getByDynamicID(currentItem.dynamicID)!!.amount.toFloat() + else + currentItem.durability } meter.vitalGetterMax = { if (ItemCodex[currentItem.originalID].consumable) 500f else - actor.inventory.getByDynamicID(currentItem.dynamicID)!!.item.maxDurability.toFloat() + currentItem.maxDurability.toFloat() } } } diff --git a/src/net/torvald/terrarum/UIItemInventoryElem.kt b/src/net/torvald/terrarum/UIItemInventoryElem.kt index d7b3216be..cd79221ee 100644 --- a/src/net/torvald/terrarum/UIItemInventoryElem.kt +++ b/src/net/torvald/terrarum/UIItemInventoryElem.kt @@ -62,6 +62,8 @@ class UIItemInventoryElem( } } + private val fwsp = 0x3000.toChar() + override fun render(gc: GameContainer, g: Graphics) { g.font = Terrarum.fontGame @@ -91,8 +93,8 @@ class UIItemInventoryElem( // this one-liner sets color g.color = item!!.nameColour mul if (mouseUp) mouseOverTextCol else inactiveTextCol g.drawString( - "${item!!.dynamicID}/${item!!.originalID}" + (if (amount > 0 && !item!!.isUnique) "${0x3000.toChar()}($amount)" else "") + - //item!!.name + (if (amount > 0 && !item!!.isUnique) "${0x3000.toChar()}($amount)" else "") + + "$item" + (if (amount > 0 && !item!!.isUnique) "$fwsp($amount)" else "") + + //item!!.name + (if (amount > 0 && !item!!.isUnique) "$fwsp($amount)" else "") + (if (equippedSlot != null) " ${0xE081.toChar()}\$$equippedSlot" else ""), posX + textOffsetX, posY + textOffsetY diff --git a/src/net/torvald/terrarum/console/Inventory.kt b/src/net/torvald/terrarum/console/Inventory.kt index 97b972ec6..3ab315906 100644 --- a/src/net/torvald/terrarum/console/Inventory.kt +++ b/src/net/torvald/terrarum/console/Inventory.kt @@ -39,7 +39,7 @@ internal object Inventory : ConsoleCommand { if (it.amount == 0) { EchoError("Unexpected zero-amounted item: ID ${it.item.dynamicID}") } - Echo("ID ${it.item.dynamicID}${if (it.amount > 1) " ($it.second)" else ""}") + Echo("ID ${it.item}${if (it.amount > 1) " (${it.amount})" else ""}") } } } diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index c2d0a3746..2d74d7f36 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -4,6 +4,7 @@ import net.torvald.random.HQRNG import net.torvald.terrarum.ActorValue import net.torvald.terrarum.Terrarum import net.torvald.terrarum.itemproperties.ItemCodex +import net.torvald.terrarum.itemproperties.ItemCodex.ACTORID_MIN import org.newdawn.slick.GameContainer typealias ActorID = Int @@ -22,6 +23,13 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable, Runnable FRONT // fake tiles } + companion object { + val RANGE_BEHIND = ACTORID_MIN..0x1FFF_FFFF + val RANGE_MIDDLE = 0x2000_0000..0x5FFF_FFFF + val RANGE_MIDTOP = 0x6000_0000..0x6FFF_FFFF + val RANGE_FRONT = 0x7000_0000..0x7FFF_FFFF + } + abstract fun update(gc: GameContainer, delta: Int) /** @@ -52,18 +60,12 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable, Runnable fun hasCollision(value: ActorID) = try { Terrarum.ingame!!.theGameHasActor(value) || - value < ItemCodex.ACTOR_ID_MIN || - value < when (renderOrder) { - RenderOrder.BEHIND -> ItemCodex.ACTOR_ID_MIN - RenderOrder.MIDDLE -> 0x10000000 - RenderOrder.MIDTOP -> 0x60000000 - RenderOrder.FRONT -> 0x70000000 - } || - value > when (renderOrder) { - RenderOrder.BEHIND -> 0x0FFFFFFF - RenderOrder.MIDDLE -> 0x5FFFFFFF - RenderOrder.MIDTOP -> 0x6FFFFFFF - RenderOrder.FRONT -> 0x7FFFFFFF + value < ItemCodex.ACTORID_MIN || + value !in when (renderOrder) { + RenderOrder.BEHIND -> RANGE_BEHIND + RenderOrder.MIDDLE -> RANGE_MIDDLE + RenderOrder.MIDTOP -> RANGE_MIDTOP + RenderOrder.FRONT -> RANGE_FRONT } } catch (gameNotInitialisedException: KotlinNullPointerException) { diff --git a/src/net/torvald/terrarum/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/gameactors/ActorInventory.kt index 3f45e5709..ee8e95729 100644 --- a/src/net/torvald/terrarum/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/gameactors/ActorInventory.kt @@ -57,18 +57,22 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode // new item else { if (item.isDynamic) { - // assign new ID - - println("[ActorInventory] new dynamic item detected: ${item.originalID}") - - item.dynamicID = InventoryItem.generateNewDynamicID(this) + // assign new ID for each + repeat(count) { + val newItem = item.clone().generateUniqueDynamicID(this) + itemList.add(InventoryPair(newItem, 1)) + } + } + else { + itemList.add(InventoryPair(item, count)) } - itemList.add(InventoryPair(item, count)) } insertionSortLastElem(itemList) } - fun remove(itemID: Int, count: Int = 1) = remove(ItemCodex[itemID], count) + fun remove(itemID: Int, count: Int) = remove(ItemCodex[itemID], count) + /** Will check existence of the item using its Dynamic ID; careful with command order! + * e.g. re-assign after this operation */ fun remove(item: InventoryItem, count: Int = 1) { val existingItem = getByDynamicID(item.dynamicID) if (existingItem != null) { // if the item already exists @@ -139,12 +143,23 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode remove(item, 1) } else { + // unpack newly-made dynamic item (e.g. any weapon, floppy disk) + /*if (item.isDynamic && item.originalID == item.dynamicID) { + remove(item.originalID, 1) + item.generateUniqueDynamicID(this) + add(item) + }*/ + + + + // calculate damage value val baseDamagePerSwing = if (actor is ActorHumanoid) actor.avStrength / 1000.0 else 1.0 // TODO variable: scale, strength val swingDmgToFrameDmg = Terrarum.delta.toDouble() / actor.actorValue.getAsDouble(AVKey.ACTION_INTERVAL)!! + // damage the item item.durability -= (baseDamagePerSwing * swingDmgToFrameDmg).toFloat() if (item.durability <= 0) remove(item, 1) @@ -194,11 +209,11 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode while (low <= high) { val mid = (low + high).ushr(1) // safe from overflows - val midVal = get(mid).item + val midVal = get(mid).item.dynamicID - if (ID > midVal.dynamicID) + if (ID > midVal) low = mid + 1 - else if (ID < midVal.dynamicID) + else if (ID < midVal) high = mid - 1 else return mid // key found diff --git a/src/net/torvald/terrarum/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/gameactors/DroppedItem.kt index c195692ae..117781446 100644 --- a/src/net/torvald/terrarum/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/gameactors/DroppedItem.kt @@ -12,7 +12,7 @@ import org.newdawn.slick.Graphics class DroppedItem(private val item: InventoryItem) : ActorWithPhysics(Actor.RenderOrder.MIDTOP) { init { - if (item.dynamicID >= ItemCodex.ACTOR_ID_MIN) + if (item.dynamicID >= ItemCodex.ACTORID_MIN) throw RuntimeException("Attempted to create DroppedItem actor of a real actor; the real actor must be dropped instead.") isVisible = true diff --git a/src/net/torvald/terrarum/gameworld/GameEconomy.kt b/src/net/torvald/terrarum/gameworld/GameEconomy.kt index a62af49f4..36f3e35d8 100644 --- a/src/net/torvald/terrarum/gameworld/GameEconomy.kt +++ b/src/net/torvald/terrarum/gameworld/GameEconomy.kt @@ -3,9 +3,12 @@ package net.torvald.terrarum.gameworld import net.torvald.terrarum.gameactors.ActorID /** - * This world is economically isolated system. Economy will be important to make player keep playing, + * The whole world is economically isolated system. Economy will be important to make player keep playing, * when all the necessary contents are set and implemented to the production. * + * Design goal: keep the inflation rate low, but not negative (Single market) + * OR, give each faction (establishment) its own economy and watch them prosper/doomed (DF style) + * * Created by SKYHi14 on 2017-04-23. */ class GameEconomy { diff --git a/src/net/torvald/terrarum/itemproperties/InventoryItem.kt b/src/net/torvald/terrarum/itemproperties/InventoryItem.kt index a50113afc..6254bc79f 100644 --- a/src/net/torvald/terrarum/itemproperties/InventoryItem.kt +++ b/src/net/torvald/terrarum/itemproperties/InventoryItem.kt @@ -4,6 +4,7 @@ import net.torvald.random.HQRNG import net.torvald.terrarum.ItemValue import net.torvald.terrarum.gameactors.ActorInventory import net.torvald.terrarum.gameactors.Pocketed +import net.torvald.terrarum.itemproperties.ItemCodex.ITEM_DYNAMIC import net.torvald.terrarum.itemproperties.Material import net.torvald.terrarum.langpack.Lang import org.newdawn.slick.Color @@ -111,7 +112,7 @@ abstract class InventoryItem : Comparable, Cloneable { */ open var durability: Float = 0f - var using = false + @Transient var using = false // Always false when loaded from savegame /** * Effects applied continuously while in pocket @@ -166,7 +167,7 @@ abstract class InventoryItem : Comparable, Cloneable { override fun toString(): String { - return dynamicID.toString() + return "$dynamicID/$originalID" } override fun hashCode(): Int { @@ -242,13 +243,23 @@ abstract class InventoryItem : Comparable, Cloneable { return clonedItem } + + fun generateUniqueDynamicID(inventory: ActorInventory): InventoryItem { + dynamicID = InventoryItem.generateUniqueDynamicID(inventory) + return this + } + companion object { - fun generateNewDynamicID(inventory: ActorInventory): Int { + fun generateUniqueDynamicID(inventory: ActorInventory): Int { var ret: Int do { - ret = HQRNG().nextInt(ItemCodex.ITEM_DYNAMIC.endInclusive + 1 - ItemCodex.ITEM_DYNAMIC.first) + ItemCodex.ITEM_DYNAMIC.first + ret = ITEM_DYNAMIC.pickRandom() } while (inventory.contains(ret)) return ret } } -} \ No newline at end of file +} + +fun IntRange.pickRandom() = HQRNG().nextInt(this.endInclusive - this.start + 1) + this.start // count() on 200 million entries? Se on vitun hyvää idea +fun IntArray.pickRandom(): Int = this[HQRNG().nextInt(this.size)] +fun DoubleArray.pickRandom(): Double = this[HQRNG().nextInt(this.size)] diff --git a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt index 905700a65..702990f0a 100644 --- a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt +++ b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt @@ -26,7 +26,7 @@ object ItemCodex { /** * - * Will return corresponding Actor if ID >= 16777216 + * Will return corresponding Actor if ID >= ACTORID_MIN */ private val itemCodex = HashMap() private val dynamicItemDescription = HashMap() @@ -35,8 +35,8 @@ object ItemCodex { val ITEM_WALLS = GameWorld.TILES_SUPPORTED..GameWorld.TILES_SUPPORTED * 2 - 1 val ITEM_WIRES = GameWorld.TILES_SUPPORTED * 2..GameWorld.TILES_SUPPORTED * 2 + 255 val ITEM_STATIC = ITEM_WIRES.endInclusive + 1..32767 - val ITEM_DYNAMIC = 32768..1048575 - val ACTOR_ID_MIN = ITEM_DYNAMIC.endInclusive + 1 + val ITEM_DYNAMIC = 32768..0x0FFF_FFFF + val ACTORID_MIN = ITEM_DYNAMIC.endInclusive + 1 private val itemImagePlaceholder = Image("./assets/item_kari_24.tga")