selecting and consuming item in inventory

This commit is contained in:
Song Minjae
2017-04-11 19:21:32 +09:00
parent c20524836d
commit 8d565a36ba
15 changed files with 223 additions and 138 deletions

View File

@@ -12,6 +12,7 @@ import net.torvald.terrarum.gameactors.physicssolver.CollisionSolver
import net.torvald.terrarum.gamecontroller.GameController import net.torvald.terrarum.gamecontroller.GameController
import net.torvald.terrarum.gamecontroller.Key import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldSimulator import net.torvald.terrarum.gameworld.WorldSimulator
import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.gameworld.WorldTime
@@ -578,6 +579,8 @@ class StateInGame : BasicGameState() {
GameController.controllerButtonPressed(controller, button) GameController.controllerButtonPressed(controller, button)
uiContainer.forEach { it.controllerButtonPressed(controller, button) } // for GamepadControlled UIcanvases uiContainer.forEach { it.controllerButtonPressed(controller, button) } // for GamepadControlled UIcanvases
// TODO use item on Player
} }
override fun controllerButtonReleased(controller: Int, button: Int) { override fun controllerButtonReleased(controller: Int, button: Int) {
@@ -663,7 +666,18 @@ class StateInGame : BasicGameState() {
ThreadParallel.startAll() ThreadParallel.startAll()
} }
else { else {
actorContainer.forEach { it.update(gc, delta) } actorContainer.forEach {
it.update(gc, delta)
if (it is Pocketed) {
it.inventory.forEach { inventoryEntry ->
inventoryEntry.item.effectWhileInPocket(gc, delta)
if (it.isEquipped(inventoryEntry.item)) {
inventoryEntry.item.effectWhenEquipped(gc, delta)
}
}
}
}
} }
} }

View File

@@ -26,8 +26,7 @@ class StateUITest : BasicGameState() {
TODO("not implemented") TODO("not implemented")
} }
override var inventory: ActorInventory = ActorInventory() override var inventory: ActorInventory = ActorInventory(this, 100, ActorInventory.CAPACITY_MODE_WEIGHT)
override val itemEquipped = Array<InventoryItem?>(InventoryItem.EquipPosition.INDEX_MAX + 1, { null })
} }
init { init {
@@ -56,6 +55,7 @@ class StateUITest : BasicGameState() {
override var category: String = InventoryItem.Category.TOOL override var category: String = InventoryItem.Category.TOOL
override var maxDurability: Double = 10.0 override var maxDurability: Double = 10.0
override var durability: Double = 6.43 override var durability: Double = 6.43
override var consumable = false
}) })
actor.inventory.getByID(5656)!!.item.name = "Test tool" actor.inventory.getByID(5656)!!.item.name = "Test tool"
@@ -69,6 +69,7 @@ class StateUITest : BasicGameState() {
override var baseMass: Double = 1.4 override var baseMass: Double = 1.4
override var baseToolSize: Double? = null override var baseToolSize: Double? = null
override var category: String = InventoryItem.Category.MISC override var category: String = InventoryItem.Category.MISC
override var consumable = false
}) })
actor.inventory.add(ItemCodex[16], 543) actor.inventory.add(ItemCodex[16], 543)

View File

@@ -66,10 +66,12 @@ class UIItemInventoryElem(
// mouseover background // mouseover background
if (item != null || drawBackOnNull) { if (item != null || drawBackOnNull) {
if (mouseUp) { // do not highlight even if drawBackOnNull is true
if (mouseUp && item != null) {
BlendMode.resolve(mouseoverBackBlendMode) BlendMode.resolve(mouseoverBackBlendMode)
g.color = mouseoverBackCol g.color = mouseoverBackCol
} }
// if drawBackOnNull, just draw background
else { else {
BlendMode.resolve(backBlendMode) BlendMode.resolve(backBlendMode)
g.color = backCol g.color = backCol
@@ -136,11 +138,11 @@ class UIItemInventoryElem(
val itemEquipSlot = item!!.equipPosition val itemEquipSlot = item!!.equipPosition
val player = Terrarum.ingame!!.player val player = Terrarum.ingame!!.player
if (item != player.itemEquipped[itemEquipSlot]) { // if this item is unequipped, equip it if (item != player.inventory.itemEquipped[itemEquipSlot]) { // if this item is unequipped, equip it
player.itemEquipped[itemEquipSlot] = item player.equipItem(item!!)
} }
else { // if not, unequip it else { // if not, unequip it
player.itemEquipped[itemEquipSlot] = null player.unequipItem(item!!)
} }
} }

View File

@@ -65,7 +65,7 @@ internal object Inventory : ConsoleCommand {
target.inventory.add(item) target.inventory.add(item)
} }
target.itemEquipped[item.equipPosition] = item target.inventory.itemEquipped[item.equipPosition] = item
} }
override fun printUsage() { override fun printUsage() {

View File

@@ -23,8 +23,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
/** Must be set by PlayerFactory */ /** Must be set by PlayerFactory */
override var inventory: ActorInventory = ActorInventory() override var inventory: ActorInventory = ActorInventory(this, 2000, ActorInventory.CAPACITY_MODE_WEIGHT) // default constructor
override val itemEquipped = Array<InventoryItem?>(InventoryItem.EquipPosition.INDEX_MAX + 1, { null })
/** Must be set by PlayerFactory */ /** Must be set by PlayerFactory */
@@ -141,6 +140,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
override var baseToolSize: Double? = null override var baseToolSize: Double? = null
override var category = "should_not_be_seen" override var category = "should_not_be_seen"
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "(no name)" override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "(no name)"
override var consumable = false
} }
override fun update(gc: GameContainer, delta: Int) { override fun update(gc: GameContainer, delta: Int) {
@@ -177,7 +177,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
// update inventory items // update inventory items
inventory.forEach { inventory.forEach {
if (!itemEquipped.contains(it.item)) { // unequipped if (!inventory.itemEquipped.contains(it.item)) { // unequipped
it.item.effectWhileInPocket(gc, delta) it.item.effectWhileInPocket(gc, delta)
} }
else { // equipped else { // equipped
@@ -186,23 +186,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
} }
} }
fun unequipItem(item: InventoryItem) {
for (i in 0..itemEquipped.size - 1) {
val it = itemEquipped[i]
if (item == it) {
it.effectWhenUnEquipped(gameContainer, updateDelta)
itemEquipped[i] = null // remove from the array by nulling it
break
}
}
}
fun equipItem(item: InventoryItem) {
if (item.equipPosition >= 0) {
itemEquipped[item.equipPosition] = item
}
}
private fun updateGamerControlBox(input: Input) { private fun updateGamerControlBox(input: Input) {
if (isGamer) { if (isGamer) {
isUpDown = input.isKeyDown(Terrarum.getConfigInt("keyup")) isUpDown = input.isKeyDown(Terrarum.getConfigInt("keyup"))
@@ -234,22 +217,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
else true else true
override fun processInput(gc: GameContainer, delta: Int, input: Input) { override fun processInput(gc: GameContainer, delta: Int, input: Input) {
///////////////////
// MOUSE CONTROL //
///////////////////
/**
* Primary Use
*/
// Left mouse
if (isGamer && input.isKeyDown(Terrarum.getConfigInt("mouseprimary"))) {
(itemEquipped[InventoryItem.EquipPosition.HAND_GRIP] ?: nullItem).primaryUse(gc, delta)
}
// Right mouse
if (isGamer && input.isKeyDown(Terrarum.getConfigInt("mouseprimary"))) {
(itemEquipped[InventoryItem.EquipPosition.HAND_GRIP] ?: nullItem).secondaryUse(gc, delta)
}
/** /**
* L-R stop * L-R stop
@@ -511,7 +478,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (sprite != null) sprite!!.update(delta) if (sprite != null) sprite!!.update(delta)
if (spriteGlow != null) spriteGlow!!.update(delta) if (spriteGlow != null) spriteGlow!!.update(delta)
println("$this\tsprite current frame: ${sprite!!.currentFrame}") //println("$this\tsprite current frame: ${sprite!!.currentFrame}")
if (grounded) { if (grounded) {
// set anim row // set anim row

View File

@@ -12,46 +12,24 @@ import java.util.concurrent.locks.ReentrantLock
* Created by minjaesong on 16-03-15. * Created by minjaesong on 16-03-15.
*/ */
class ActorInventory() { class ActorInventory(val actor: Pocketed, var maxCapacity: Int, private var capacityMode: Int) {
@Transient val CAPACITY_MAX = 0x7FFFFFFF companion object {
@Transient val CAPACITY_MODE_NO_ENCUMBER = 0 @Transient val CAPACITY_MODE_NO_ENCUMBER = 0
@Transient val CAPACITY_MODE_COUNT = 1 @Transient val CAPACITY_MODE_COUNT = 1
@Transient val CAPACITY_MODE_WEIGHT = 2 @Transient val CAPACITY_MODE_WEIGHT = 2
}
/**
private var capacityByCount: Int * List of all equipped items (tools, armours, rings, necklaces, etc.)
private var capacityByWeight: Int */
private var capacityMode: Int val itemEquipped = Array<InventoryItem?>(InventoryItem.EquipPosition.INDEX_MAX, { null })
/** /**
* Sorted by referenceID. * Sorted by referenceID.
*/ */
private val itemList = ArrayList<InventoryPair>() private val itemList = ArrayList<InventoryPair>()
/**
* Default constructor with no encumbrance.
*/
init { init {
capacityMode = CAPACITY_MODE_NO_ENCUMBER
capacityByCount = 0
capacityByWeight = 0
}
/**
* Construct new inventory with specified capacity.
* @param capacity if is_weight is true, killogramme value is required, counts of items otherwise.
* *
* @param is_weight whether encumbrance should be calculated upon the weight of the inventory. False to use item counts.
*/
constructor(capacity: Int, is_weight: Boolean) : this() {
if (is_weight) {
capacityByWeight = capacity
capacityMode = CAPACITY_MODE_WEIGHT
} else {
capacityByCount = capacity
capacityMode = CAPACITY_MODE_COUNT
}
} }
fun add(itemID: Int, count: Int = 1) = add(ItemCodex[itemID], count) fun add(itemID: Int, count: Int = 1) = add(ItemCodex[itemID], count)
@@ -85,10 +63,14 @@ class ActorInventory() {
throw Error("Tried to remove $count of $item, but the inventory only contains ${getByID(item.id)!!.amount} of them.") throw Error("Tried to remove $count of $item, but the inventory only contains ${getByID(item.id)!!.amount} of them.")
} }
else if (newCount > 0) { else if (newCount > 0) {
// decrement count
add(item, -count) add(item, -count)
} }
else { else {
// depleted item; remove entry from inventory
itemList.remove(existingItem) itemList.remove(existingItem)
// unequip, if applicable
actor.unequipItem(existingItem.item)
} }
} }
else { else {
@@ -105,21 +87,13 @@ class ActorInventory() {
* Get capacity of inventory * Get capacity of inventory
* @return * @return
*/ */
fun getCapacity(): Int { val capacity: Double
if (capacityMode == CAPACITY_MODE_NO_ENCUMBER) { get() = if (capacityMode == CAPACITY_MODE_NO_ENCUMBER)
return CAPACITY_MAX maxCapacity.toDouble()
} else if (capacityMode == CAPACITY_MODE_WEIGHT)
else if (capacityMode == CAPACITY_MODE_WEIGHT) { getTotalWeight()
return capacityByWeight else
} getTotalCount().toDouble()
else {
return capacityByCount
}
}
fun getCapacityMode(): Int {
return capacityMode
}
fun getTotalWeight(): Double = itemList.map { it.item.mass * it.amount }.sum() fun getTotalWeight(): Double = itemList.map { it.item.mass * it.amount }.sum()
@@ -137,13 +111,21 @@ class ActorInventory() {
* Check whether the itemList contains too many items * Check whether the itemList contains too many items
* @return * @return
*/ */
fun isEncumbered(): Boolean { val isEncumbered: Boolean
if (getCapacityMode() == CAPACITY_MODE_WEIGHT) { get() = if (capacityMode == CAPACITY_MODE_NO_ENCUMBER)
return capacityByWeight < getTotalWeight() false
} else if (getCapacityMode() == CAPACITY_MODE_COUNT) { else if (capacityMode == CAPACITY_MODE_WEIGHT)
return capacityByCount < getTotalCount() maxCapacity < capacity
} else { else
return false false
fun consumeItem(item: InventoryItem) {
if (item.consumable) {
remove(item, 1)
}
else {
// TODO decrement durability
} }
} }
@@ -152,6 +134,7 @@ class ActorInventory() {
fun hasItem(item: InventoryItem) = hasItem(item.id) fun hasItem(item: InventoryItem) = hasItem(item.id)
fun hasItem(id: Int) = fun hasItem(id: Int) =
if (itemList.size == 0) if (itemList.size == 0)

View File

@@ -41,7 +41,7 @@ open class HumanoidNPC(
// we're having InventoryItem data so that this class could be somewhat universal // we're having InventoryItem data so that this class could be somewhat universal
override var itemData: InventoryItem = object : InventoryItem() { override var itemData: InventoryItem = object : InventoryItem() {
override var id = referenceID override var id = referenceID
override val isUnique: Boolean = true override val isUnique = true
override var baseMass: Double override var baseMass: Double
get() = actorValue.getAsDouble(AVKey.BASEMASS)!! get() = actorValue.getAsDouble(AVKey.BASEMASS)!!
set(value) { actorValue[AVKey.BASEMASS] = value } set(value) { actorValue[AVKey.BASEMASS] = value }
@@ -53,8 +53,10 @@ open class HumanoidNPC(
} }
override var category = "npc" override var category = "npc"
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "NPC" override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "NPC"
override var consumable = false
override fun secondaryUse(gc: GameContainer, delta: Int) { override fun secondaryUse(gc: GameContainer, delta: Int): Boolean {
return false
// TODO place this Actor to the world // TODO place this Actor to the world
} }
} }

View File

@@ -66,7 +66,7 @@ object PlayerBuilderSigrid {
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 11, 0) // FIXME offsetY of -2: Have no idea about the error; it's just supposed to be zero p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 11, 0) // FIXME offsetY of -2: Have no idea about the error; it's just supposed to be zero
p.inventory = ActorInventory(0x7FFFFFFF, true) p.inventory = ActorInventory(p, 0, ActorInventory.CAPACITY_MODE_NO_ENCUMBER)
p.setPosition((4096 * FeaturesDrawer.TILE_SIZE).toDouble(), (300 * 16).toDouble()) p.setPosition((4096 * FeaturesDrawer.TILE_SIZE).toDouble(), (300 * 16).toDouble())

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.gameitem.InventoryItem
import java.util.* import java.util.*
@@ -10,9 +11,38 @@ interface Pocketed {
var inventory: ActorInventory var inventory: ActorInventory
/**
* List of all equipped items (tools, armours, rings, necklaces, etc.)
*/
val itemEquipped: Array<InventoryItem?>
fun unequipItem(item: InventoryItem) {
if (item.equipPosition == InventoryItem.EquipPosition.NULL)
throw Error("Unequipping the item that cannot be equipped")
if (!inventory.hasItem(item))
throw Error("Unequipping the item that does not exist in inventory")
inventory.itemEquipped[item.equipPosition] = null
item.effectOnUnequip(Terrarum.appgc, Terrarum.UPDATE_DELTA)
}
fun equipItem(item: InventoryItem) {
if (item.equipPosition >= 0) {
inventory.itemEquipped[item.equipPosition] = item
item.effectWhenEquipped(Terrarum.appgc, Terrarum.UPDATE_DELTA)
}
}
fun isEquipped(item: InventoryItem): Boolean {
return inventory.itemEquipped[item.equipPosition] == item
}
fun consumePrimary(item: InventoryItem) {
if (item.primaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA))
inventory.consumeItem(item) // consume on successful
}
fun consumeSecondary(item: InventoryItem) {
if (item.secondaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA))
inventory.consumeItem(item) // consume on successful
}
} }

View File

@@ -9,7 +9,18 @@ import org.newdawn.slick.GameContainer
class ThreadActorUpdate(val startIndex: Int, val endIndex: Int, class ThreadActorUpdate(val startIndex: Int, val endIndex: Int,
val gc: GameContainer, val delta: Int) : Runnable { val gc: GameContainer, val delta: Int) : Runnable {
override fun run() { override fun run() {
for (i in startIndex..endIndex) for (i in startIndex..endIndex) {
Terrarum.ingame!!.actorContainer[i].update(gc, delta) val it = Terrarum.ingame!!.actorContainer[i]
it.update(gc, delta)
if (it is Pocketed) {
it.inventory.forEach { inventoryEntry ->
inventoryEntry.item.effectWhileInPocket(gc, delta)
if (it.isEquipped(inventoryEntry.item)) {
inventoryEntry.item.effectWhenEquipped(gc, delta)
}
}
}
}
} }
} }

View File

@@ -4,6 +4,7 @@ import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.mapdrawer.FeaturesDrawer import net.torvald.terrarum.mapdrawer.FeaturesDrawer
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.mapdrawer.MapCamera import net.torvald.terrarum.mapdrawer.MapCamera
import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.tileproperties.TileCodex import net.torvald.terrarum.tileproperties.TileCodex
@@ -34,11 +35,11 @@ object GameController {
get() = (mouseY / FeaturesDrawer.TILE_SIZE).floorInt() get() = (mouseY / FeaturesDrawer.TILE_SIZE).floorInt()
fun processInput(gc: GameContainer, delta: Int, input: Input) { fun processInput(gc: GameContainer, delta: Int, input: Input) {
if (Terrarum.ingame != null) { if (Terrarum.ingame != null) {
val ingame = Terrarum.ingame!! val ingame = Terrarum.ingame!!
// actor process input
if (!ingame.consoleHandler.isTakingControl) { if (!ingame.consoleHandler.isTakingControl) {
if (ingame.canPlayerMove) { if (ingame.canPlayerMove) {
ingame.actorContainer.forEach { ingame.actorContainer.forEach {
@@ -67,7 +68,20 @@ object GameController {
/////////////////// ///////////////////
// MOUSE CONTROL // // MOUSE CONTROL //
/////////////////// ///////////////////
// PRIMARY/SECONDARY IS FIXED TO LEFT/RIGHT BUTTON //
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
if (input.isMouseButtonDown(Terrarum.getConfigInt("mouseprimary")) || input.isMouseButtonDown(Terrarum.getConfigInt("mousesecondary"))) {
val itemOnGrip = ingame.player.inventory.itemEquipped[InventoryItem.EquipPosition.HAND_GRIP]
if (itemOnGrip != null) {
if (input.isMouseButtonDown(Terrarum.getConfigInt("mouseprimary"))) {
ingame.player.consumePrimary(itemOnGrip)
}
else if (input.isMouseButtonDown(Terrarum.getConfigInt("mousesecondary"))) {
ingame.player.consumeSecondary(itemOnGrip)
}
}
}
///////////////////// /////////////////////

View File

@@ -51,6 +51,9 @@ abstract class InventoryItem : Comparable<InventoryItem> {
var itemProperties = ItemValue() var itemProperties = ItemValue()
/** Single-use then destroyed (e.g. Tiles) */
abstract var consumable: Boolean
/** /**
* Where to equip the item * Where to equip the item
*/ */
@@ -107,13 +110,17 @@ abstract class InventoryItem : Comparable<InventoryItem> {
/** /**
* Effects applied (continuously or not) while primary button (usually left mouse button) is down * Effects applied (continuously or not) while primary button (usually left mouse button) is down
*
* @return true when use successfully, false otherwise
*/ */
open fun primaryUse(gc: GameContainer, delta: Int) { } open fun primaryUse(gc: GameContainer, delta: Int): Boolean = false
/** /**
* Effects applied (continuously or not) while secondary button (usually right mouse button) is down * Effects applied (continuously or not) while secondary button (usually right mouse button) is down
*
* @return true when use successfully, false otherwise
*/ */
open fun secondaryUse(gc: GameContainer, delta: Int) { } open fun secondaryUse(gc: GameContainer, delta: Int): Boolean = false
/** /**
* Effects applied immediately only once if thrown from pocket * Effects applied immediately only once if thrown from pocket
@@ -128,7 +135,7 @@ abstract class InventoryItem : Comparable<InventoryItem> {
/** /**
* Effects applied only once when unequipped * Effects applied only once when unequipped
*/ */
open fun effectWhenUnEquipped(gc: GameContainer, delta: Int) { } open fun effectOnUnequip(gc: GameContainer, delta: Int) { }
override fun toString(): String { override fun toString(): String {
@@ -158,11 +165,7 @@ abstract class InventoryItem : Comparable<InventoryItem> {
if (equipPosition == EquipPosition.NULL) if (equipPosition == EquipPosition.NULL)
throw IllegalArgumentException("Item is not supposed to be equipped (equipPosition is NULL") throw IllegalArgumentException("Item is not supposed to be equipped (equipPosition is NULL")
if (!actor.inventory.hasItem(this.id)) { actor.equipItem(this)
actor.inventory.add(this)
}
actor.itemEquipped[this.equipPosition] = this
} }
object EquipPosition { object EquipPosition {

View File

@@ -10,8 +10,10 @@ import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY import net.torvald.terrarum.gamecontroller.mouseTileY
import net.torvald.terrarum.gameitem.IVKey import net.torvald.terrarum.gameitem.IVKey
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.tileproperties.TileCodex import net.torvald.terrarum.tileproperties.TileCodex
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
import org.newdawn.slick.Image
import java.util.* import java.util.*
/** /**
@@ -33,6 +35,9 @@ object ItemCodex {
val ITEM_DYNAMIC_MIN = ITEM_STATIC_MAX + 1 val ITEM_DYNAMIC_MIN = ITEM_STATIC_MAX + 1
val ITEM_STATIC_MIN = ITEM_TILE_MAX + 1 // 4096 val ITEM_STATIC_MIN = ITEM_TILE_MAX + 1 // 4096
private val itemImagePlaceholder = Image("./assets/item_kari_24.tga")
init { init {
// tile items (blocks and walls are the same thing basically) // tile items (blocks and walls are the same thing basically)
for (i in 0..ITEM_TILE_MAX) { for (i in 0..ITEM_TILE_MAX) {
@@ -44,28 +49,38 @@ object ItemCodex {
override var equipPosition = EquipPosition.HAND_GRIP override var equipPosition = EquipPosition.HAND_GRIP
override var category = "block" override var category = "block"
override val originalName = TileCodex[i].nameKey override val originalName = TileCodex[i].nameKey
override var consumable = true
init { init {
itemProperties[IVKey.ITEMTYPE] = IVKey.ItemType.BLOCK itemProperties[IVKey.ITEMTYPE] = IVKey.ItemType.BLOCK
} }
override fun primaryUse(gc: GameContainer, delta: Int) { override fun primaryUse(gc: GameContainer, delta: Int): Boolean {
return false
// TODO base punch attack // TODO base punch attack
} }
override fun secondaryUse(gc: GameContainer, delta: Int) { override fun secondaryUse(gc: GameContainer, delta: Int): Boolean {
val mousePoint = Point2d(gc.mouseTileX.toDouble(), gc.mouseTileY.toDouble()) val mousePoint = Point2d(gc.mouseTileX.toDouble(), gc.mouseTileY.toDouble())
// linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox)
Terrarum.ingame!!.actorContainer.forEach { Terrarum.ingame!!.actorContainer.forEach {
if (it is ActorWithSprite && it.tilewiseHitbox.intersects(mousePoint)) if (it is ActorWithSprite && it.tilewiseHitbox.intersects(mousePoint))
return return false
} }
// return false if the tile is already there
if (this.id == Terrarum.ingame!!.world.getTileFromTerrain(gc.mouseTileX, gc.mouseTileY))
return false
// filter passed, do the job // filter passed, do the job
// FIXME this is only useful for Player
Terrarum.ingame!!.world.setTileTerrain( Terrarum.ingame!!.world.setTileTerrain(
gc.mouseTileX, gc.mouseTileX,
gc.mouseTileY, gc.mouseTileY,
i i
) )
return true
} }
} }
} }
@@ -89,5 +104,12 @@ object ItemCodex {
} }
} }
fun getItemImage(code: Int): Image {
if (code <= ITEM_TILE_MAX)
return TilesDrawer.tilesTerrain.getSubImage((code % 16) * 16, code / 16)
else
return itemImagePlaceholder
}
fun hasItem(itemID: Int): Boolean = dynamicItemDescription.containsKey(itemID) fun hasItem(itemID: Int): Boolean = dynamicItemDescription.containsKey(itemID)
} }

View File

@@ -6,6 +6,7 @@ import net.torvald.terrarum.Terrarum.joypadLabelNinA
import net.torvald.terrarum.Terrarum.joypadLabelNinY import net.torvald.terrarum.Terrarum.joypadLabelNinY
import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import org.newdawn.slick.* import org.newdawn.slick.*
import java.util.* import java.util.*
@@ -28,11 +29,9 @@ class UIInventory(
override var handler: UIHandler? = null override var handler: UIHandler? = null
override var openCloseTime: Int = 120 override var openCloseTime: Int = 120
val itemImagePlaceholder = Image("./assets/item_kari_24.tga")
val catButtonsToCatIdent = HashMap<String, String>() val catButtonsToCatIdent = HashMap<String, String>()
val backgroundColour = Color(0xA0242424.toInt()) val backgroundColour = Color(0x80242424.toInt())
init { init {
catButtonsToCatIdent.put("GAME_INVENTORY_WEAPONS", InventoryItem.Category.WEAPON) catButtonsToCatIdent.put("GAME_INVENTORY_WEAPONS", InventoryItem.Category.WEAPON)
@@ -88,7 +87,7 @@ class UIInventory(
val itemsStripWidth = ((width - catButtons.width) - (2 * itemStripGutterH + itemInterColGutter)) / 2 val itemsStripWidth = ((width - catButtons.width) - (2 * itemStripGutterH + itemInterColGutter)) / 2
val items = Array( val items = Array(
2 + height / (UIItemInventoryElem.height + itemStripGutterV - controlHelpHeight) * 2, { ((height - controlHelpHeight) / (UIItemInventoryElem.height + itemStripGutterV)) * 2, {
UIItemInventoryElem( UIItemInventoryElem(
parentUI = this, parentUI = this,
posX = catButtons.width + if (it % 2 == 0) itemStripGutterH else (itemStripGutterH + itemsStripWidth + itemInterColGutter), posX = catButtons.width + if (it % 2 == 0) itemStripGutterH else (itemStripGutterH + itemsStripWidth + itemInterColGutter),
@@ -99,7 +98,9 @@ class UIInventory(
itemImage = null, itemImage = null,
mouseoverBackCol = Color(0x282828), mouseoverBackCol = Color(0x282828),
mouseoverBackBlendMode = BlendMode.SCREEN, mouseoverBackBlendMode = BlendMode.SCREEN,
drawBackOnNull = false backCol = Color(0xd4d4d4),
backBlendMode = BlendMode.MULTIPLY,
drawBackOnNull = true
) }) ) })
val itemsScrollOffset = 0 val itemsScrollOffset = 0
@@ -160,7 +161,7 @@ class UIInventory(
val sortListItem = inventorySortList[k + itemsScrollOffset] val sortListItem = inventorySortList[k + itemsScrollOffset]
items[k].item = sortListItem.item items[k].item = sortListItem.item
items[k].amount = sortListItem.amount items[k].amount = sortListItem.amount
items[k].itemImage = itemImagePlaceholder items[k].itemImage = ItemCodex.getItemImage(sortListItem.item.id)
// set quickslot number // set quickslot number
for (qs in 1..QUICKSLOT_MAX) { for (qs in 1..QUICKSLOT_MAX) {
@@ -173,9 +174,9 @@ class UIInventory(
} }
// set equippedslot number // set equippedslot number
for (eq in 0..actor!!.itemEquipped.size - 1) { for (eq in 0..actor!!.inventory.itemEquipped.size - 1) {
if (eq < actor!!.itemEquipped.size) { if (eq < actor!!.inventory.itemEquipped.size) {
if (actor!!.itemEquipped[eq] == items[k].item) { if (actor!!.inventory.itemEquipped[eq] == items[k].item) {
items[k].equippedSlot = eq items[k].equippedSlot = eq
break break
} }
@@ -199,6 +200,8 @@ class UIInventory(
oldCatSelect = catButtons.selectedIndex oldCatSelect = catButtons.selectedIndex
} }
private val weightBarWidth = 60f
override fun render(gc: GameContainer, g: Graphics) { override fun render(gc: GameContainer, g: Graphics) {
// background // background
blendNormal() blendNormal()
@@ -221,9 +224,42 @@ class UIInventory(
// texts // texts
blendNormal() blendNormal()
g.color = Color(0xdddddd) g.color = Color(0xe8e8e8)
Typography.printCentered(g, listControlHelp, catButtons.width, height - controlHelpHeight, width - catButtons.width) // W - close
Typography.printCentered(g, listControlClose, 0, height - controlHelpHeight, catButtons.width) g.drawString(listControlClose, 4f, height - controlHelpHeight.toFloat())
// MouseL - Use ; 1.9 - Register ; T - Drop
g.drawString(listControlHelp, catButtons.width + 4f, height - controlHelpHeight.toFloat())
// encumbrance
if (inventory != null) {
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
g.drawString(
encumbranceText,
width - 9 - g.font.getWidth(encumbranceText) - weightBarWidth,
height - controlHelpHeight.toFloat()
)
// encumbrance bar background
blendMul()
g.color = Color(0xa0a0a0)
g.fillRect(
width - 3 - weightBarWidth,
height - controlHelpHeight + 3f,
weightBarWidth,
controlHelpHeight - 6f
)
// encumbrance bar
blendNormal()
val encumbPerc = inventory!!.capacity.toFloat() / inventory!!.maxCapacity
g.color = if (inventory!!.isEncumbered) Color(0xccff0000.toInt()) else Color(0xcc00ff00.toInt())
g.fillRect(
width - 3 - weightBarWidth,
height - controlHelpHeight + 3f,
minOf(weightBarWidth, maxOf(1f, weightBarWidth * encumbPerc)), // make sure 1px is always be seen
controlHelpHeight - 5f
)
}
} }

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.ui package net.torvald.terrarum.ui
import com.jme3.math.FastMath
import net.torvald.colourutil.CIELabUtil.darkerLab import net.torvald.colourutil.CIELabUtil.darkerLab
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.ActorHumanoid
@@ -59,12 +60,9 @@ class UIVitalMetre(
*/ */
override fun render(gc: GameContainer, g: Graphics) { override fun render(gc: GameContainer, g: Graphics) {
if (vitalGetterVal() != null && vitalGetterMax() != null && player != null) { if (vitalGetterVal() != null && vitalGetterMax() != null && player != null) {
// FIXME does not work well with screen zoom, because of my custom g.translate
g.translate( g.translate(
-MapCamera.x + player!!.centrePosPoint.x.toFloat(), Terrarum.ingame!!.screenZoom * (player!!.centrePosPoint.x.toFloat() - (MapCamera.x)),
-MapCamera.y + player!!.centrePosPoint.y.toFloat() Terrarum.ingame!!.screenZoom * (player!!.centrePosPoint.y.toFloat() - (MapCamera.y))
) )
@@ -118,6 +116,8 @@ class UIVitalMetre(
} }
} }
fun Float.abs() = FastMath.abs(this)
/* /*
+-------------+ (84) +-------------+ (84)