working proof-of-concept inventory system

Former-commit-id: 1be5d6d10d0a5c93bceaf12f15d2ee50602cb602
Former-commit-id: 44f25a27c3b5d196210f4efcc3fef4dec8e30ff7
This commit is contained in:
Song Minjae
2016-12-14 15:41:20 +09:00
parent 7078ecfed4
commit 1d1769a2c3
7 changed files with 153 additions and 80 deletions

View File

@@ -60,9 +60,9 @@ constructor() : BasicGameState() {
lateinit var debugWindow: UIHandler lateinit var debugWindow: UIHandler
lateinit var notifier: UIHandler lateinit var notifier: UIHandler
lateinit internal var playableActorDelegate: PlayableActorDelegate internal var playableActorDelegate: PlayableActorDelegate? = null
internal val player: ActorHumanoid // currently POSSESSED actor :) internal val player: ActorHumanoid // currently POSSESSED actor :)
get() = playableActorDelegate.actor get() = playableActorDelegate!!.actor
//private var GRADIENT_IMAGE: Image? = null //private var GRADIENT_IMAGE: Image? = null
//private var skyBox: Rectangle? = null //private var skyBox: Rectangle? = null

View File

@@ -11,27 +11,29 @@ import net.torvald.terrarum.itemproperties.ItemPropCodex
*/ */
internal object Inventory : ConsoleCommand { internal object Inventory : ConsoleCommand {
private var target: ActorInventory = Terrarum.ingame.player.inventory private var target: Pocketed = Terrarum.ingame.player
override fun execute(args: Array<String>) { override fun execute(args: Array<String>) {
if (args.size == 1) { if (args.size == 1) {
printUsage() printUsage()
} else { }
else {
when (args[1]) { when (args[1]) {
"list" -> listInventory() "list" -> listInventory()
"add" -> addItem(args[2].toInt(), args[3].toInt()) "add" -> addItem(args[2].toInt(), args[3].toInt())
"target" -> setTarget(args[2].toInt()) "target" -> setTarget(args[2].toInt())
"assign" -> assignQuickBar(args[2].toInt(), args[3].toInt()) "hold" -> holdItem(args[2].toInt())
else -> printUsage() else -> printUsage()
} }
} }
} }
private fun listInventory() { private fun listInventory() {
if (target.getTotalUniqueCount() == 0) { if (target.inventory.getTotalUniqueCount() == 0) {
Echo("(inventory empty)") Echo("(inventory empty)")
} else { }
target.forEach { refId, amount -> else {
target.inventory.forEach { refId, amount ->
if (amount == 0) { if (amount == 0) {
EchoError("Unexpected zero-amounted item: ID $refId") EchoError("Unexpected zero-amounted item: ID $refId")
} }
@@ -44,22 +46,29 @@ internal object Inventory : ConsoleCommand {
val actor = Terrarum.ingame.getActorByID(actorRefId) val actor = Terrarum.ingame.getActorByID(actorRefId)
if (actor !is Pocketed) { if (actor !is Pocketed) {
EchoError("Cannot edit inventory of incompatible actor: $actor") EchoError("Cannot edit inventory of incompatible actor: $actor")
} else { }
target = actor.inventory else {
target = actor
} }
} }
private fun addItem(refId: Int, amount: Int = 1) { private fun addItem(refId: Int, amount: Int = 1) {
target.add(ItemPropCodex.getProp(refId), amount) target.inventory.add(ItemPropCodex.getProp(refId), amount)
} }
private fun assignQuickBar(refId: Int, index: Int) { private fun holdItem(refId: Int) {
// if the item does not exist, add it first
if (!target.inventory.contains(refId)) {
target.inventory.add(refId)
}
target.itemHolding = ItemPropCodex.getProp(refId)
} }
override fun printUsage() { override fun printUsage() {
Echo("Usage: inventory command arguments") Echo("Usage: inventory command arguments")
Echo("Available commands:") Echo("Available commands:")
Echo("list | assign slot | add itemid [amount] | target [actorid]") Echo("list | assign slot | add itemid [amount] | target [actorid] | hold itemid")
Echo("equip itemid")
} }
} }

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gamecontroller.EnumKeyFunc import net.torvald.terrarum.gamecontroller.EnumKeyFunc
import net.torvald.terrarum.gamecontroller.KeyMap import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.gameitem.InventoryItemAdapter
import net.torvald.terrarum.realestate.RealEstateUtility import net.torvald.terrarum.realestate.RealEstateUtility
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
import org.lwjgl.input.Controller import org.lwjgl.input.Controller
@@ -26,11 +27,8 @@ 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()
override var itemHolding: InventoryItem override var itemHolding: InventoryItem? = null
get() = throw TODO("itemHolding") override val itemEquipped = ArrayList<InventoryItem>()
set(value) {
throw TODO("itemHolding")
}
/** Must be set by PlayerFactory */ /** Must be set by PlayerFactory */
override var faction: HashSet<Faction> = HashSet() override var faction: HashSet<Faction> = HashSet()
@@ -136,6 +134,13 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
get() = this is Player // FIXME true iff composed by PlayableActorDelegate get() = this is Player // FIXME true iff composed by PlayableActorDelegate
private val nullItem = object : InventoryItemAdapter() {
override val itemID: Int = 0
override var mass: Double = 0.0
override var scale: Double = 1.0
}
override fun update(gc: GameContainer, delta: Int) { override fun update(gc: GameContainer, delta: Int) {
super.update(gc, delta) super.update(gc, delta)
@@ -206,12 +211,12 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
*/ */
// Left mouse // Left mouse
if (isGamer && input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) { if (isGamer && input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) {
itemHolding.primaryUse(gc, delta) (itemHolding ?: nullItem).primaryUse(gc, delta)
} }
// Right mouse // Right mouse
if (isGamer && input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON)) { if (isGamer && input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON)) {
itemHolding.secondaryUse(gc, delta) (itemHolding ?: nullItem).secondaryUse(gc, delta)
} }
/** /**

View File

@@ -51,6 +51,43 @@ class ActorInventory() {
} }
} }
fun add(item: InventoryItem, count: Int = 1) = add(item.itemID, count)
fun add(itemID: Int, count: Int = 1) {
if (itemID == Player.PLAYER_REF_ID)
throw IllegalArgumentException("Attempted to put human player into the inventory.")
if (Terrarum.ingame.playableActorDelegate != null &&
itemID == Terrarum.ingame.player.referenceID)
throw IllegalArgumentException("Attempted to put active player into the inventory.")
// If we already have the item, increment the amount
// If not, add item with specified amount
itemList.put(itemID, itemList[itemID] ?: 0 + count)
}
fun remove(item: InventoryItem, count: Int = 1) = remove(item.itemID, count)
fun remove(itemID: Int, count: Int = 1) {
// check if the item does NOT exist
if (itemList[itemID] == null) {
return
}
else {
// remove the existence of the item if count <= 0
if (itemList[itemID]!! - count <= 0) {
itemList.remove(itemID)
}
// else, decrement the item count
else {
itemList.put(itemID, itemList[itemID]!! - count)
}
}
}
fun contains(item: InventoryItem) = itemList.containsKey(item.itemID)
fun contains(itemID: Int) = itemList.containsKey(itemID)
fun forEach(consumer: (Int, Int) -> Unit) = itemList.forEach(consumer)
/** /**
* Get capacity of inventory * Get capacity of inventory
* @return * @return
@@ -79,8 +116,6 @@ class ActorInventory() {
return itemList return itemList
} }
fun forEach(consumer: (Int, Int) -> Unit) = itemList.forEach(consumer)
/** /**
* Get clone of the itemList * Get clone of the itemList
* @return * @return
@@ -120,21 +155,6 @@ class ActorInventory() {
return itemList.entries.size return itemList.entries.size
} }
fun add(item: InventoryItem) {
add(item, 1)
}
fun add(item: InventoryItem, count: Int) {
val key = item.itemID
if (key == Player.PLAYER_REF_ID || key == Terrarum.ingame.player.referenceID)
throw IllegalArgumentException("Attempted to put active player or human player into the inventory.")
// If we already have the item, increment the amount
// If not, add item with specified amount
itemList.put(key, itemList[key] ?: 0 + count)
}
/** /**
* Check whether the itemList contains too many items * Check whether the itemList contains too many items
* @return * @return

View File

@@ -53,10 +53,14 @@ open class ActorWithBody : Actor() {
internal val velocity = Vector2(0.0, 0.0) internal val velocity = Vector2(0.0, 0.0)
var veloX: Double var veloX: Double
get() = velocity.x get() = velocity.x
protected set(value) { velocity.x = value } protected set(value) {
velocity.x = value
}
var veloY: Double var veloY: Double
get() = velocity.y get() = velocity.y
protected set(value) { velocity.y = value } protected set(value) {
velocity.y = value
}
val moveDelta = Vector2(0.0, 0.0) val moveDelta = Vector2(0.0, 0.0)
@Transient private val VELO_HARD_LIMIT = 100.0 @Transient private val VELO_HARD_LIMIT = 100.0
@@ -67,10 +71,14 @@ open class ActorWithBody : Actor() {
var controllerVel: Vector2? = if (this is Controllable) Vector2() else null var controllerVel: Vector2? = if (this is Controllable) Vector2() else null
var walkX: Double var walkX: Double
get() = controllerVel!!.x get() = controllerVel!!.x
protected set(value) { controllerVel!!.x = value } protected set(value) {
controllerVel!!.x = value
}
var walkY: Double var walkY: Double
get() = controllerVel!!.y get() = controllerVel!!.y
protected set(value) { controllerVel!!.y = value } protected set(value) {
controllerVel!!.y = value
}
/** /**
* Physical properties. * Physical properties.
@@ -114,7 +122,9 @@ open class ActorWithBody : Actor() {
* Formula: restitution = 1.0 - elasticity * Formula: restitution = 1.0 - elasticity
*/ */
var restitution: Double var restitution: Double
set(value) { elasticity = 1.0 - value } set(value) {
elasticity = 1.0 - value
}
get() = 1.0 - elasticity get() = 1.0 - elasticity
@Transient private val CEILING_HIT_ELASTICITY = 0.3 @Transient private val CEILING_HIT_ELASTICITY = 0.3
@@ -475,7 +485,7 @@ open class ActorWithBody : Actor() {
private fun displaceByCCD() { private fun displaceByCCD() {
ccdCollided = false ccdCollided = false
if (!isNoCollideWorld){ if (!isNoCollideWorld) {
if (!isColliding(nextHitbox, COLLIDING_ALLSIDE)) if (!isColliding(nextHitbox, COLLIDING_ALLSIDE))
return return
@@ -534,7 +544,10 @@ open class ActorWithBody : Actor() {
if (isNoCollideWorld) return false if (isNoCollideWorld) return false
// offsets will stretch and shrink detection box according to the argument // offsets will stretch and shrink detection box according to the argument
val x1: Double; val x2: Double; val y1: Double; val y2: Double val x1: Double;
val x2: Double;
val y1: Double;
val y2: Double
if (option == COLLIDING_LR || option == COLLIDING_UD) { if (option == COLLIDING_LR || option == COLLIDING_UD) {
val offsetX = if (option == COLLIDING_LR) A_PIXEL else 0.0 val offsetX = if (option == COLLIDING_LR) A_PIXEL else 0.0
val offsetY = if (option == COLLIDING_UD) A_PIXEL else 0.0 val offsetY = if (option == COLLIDING_UD) A_PIXEL else 0.0
@@ -586,7 +599,10 @@ open class ActorWithBody : Actor() {
} }
private fun isTouchingSide(hitbox: Hitbox, option: Int): Boolean { private fun isTouchingSide(hitbox: Hitbox, option: Int): Boolean {
val x1: Double; val x2: Double; val y1: Double; val y2: Double val x1: Double;
val x2: Double;
val y1: Double;
val y2: Double
if (option == COLLIDING_TOP) { if (option == COLLIDING_TOP) {
x1 = hitbox.posX x1 = hitbox.posX
x2 = hitbox.endPointX x2 = hitbox.endPointX
@@ -623,7 +639,10 @@ open class ActorWithBody : Actor() {
private fun isCollidingSide(hitbox: Hitbox, option: Int): Boolean { private fun isCollidingSide(hitbox: Hitbox, option: Int): Boolean {
val x1: Double; val x2: Double; val y1: Double; val y2: Double val x1: Double;
val x2: Double;
val y1: Double;
val y2: Double
if (option == COLLIDING_TOP) { if (option == COLLIDING_TOP) {
x1 = hitbox.posX x1 = hitbox.posX
x2 = hitbox.endPointX x2 = hitbox.endPointX
@@ -823,6 +842,7 @@ open class ActorWithBody : Actor() {
return friction return friction
} }
fun Int.tileFrictionToMult(): Double = this / 16.0 fun Int.tileFrictionToMult(): Double = this / 16.0
/** /**
@@ -908,7 +928,8 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat() (scale).toFloat()
) )
} else { }
else {
spriteGlow!!.render(g, spriteGlow!!.render(g,
(hitbox.posX - scale).toFloat(), (hitbox.posX - scale).toFloat(),
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
@@ -932,7 +953,8 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat() (scale).toFloat()
) )
} else { }
else {
sprite!!.render(g, sprite!!.render(g,
(hitbox.posX - scale).toFloat(), (hitbox.posX - scale).toFloat(),
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
@@ -953,18 +975,22 @@ open class ActorWithBody : Actor() {
private fun clampW(x: Double): Double = private fun clampW(x: Double): Double =
if (x < TSIZE + nextHitbox.width / 2) { if (x < TSIZE + nextHitbox.width / 2) {
TSIZE + nextHitbox.width / 2 TSIZE + nextHitbox.width / 2
} else if (x >= (world.width * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.width / 2) { }
else if (x >= (world.width * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.width / 2) {
(world.width * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.width / 2 (world.width * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.width / 2
} else { }
else {
x x
} }
private fun clampH(y: Double): Double = private fun clampH(y: Double): Double =
if (y < TSIZE + nextHitbox.height) { if (y < TSIZE + nextHitbox.height) {
TSIZE + nextHitbox.height TSIZE + nextHitbox.height
} else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) { }
else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) {
(world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height (world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height
} else { }
else {
y y
} }
@@ -995,7 +1021,9 @@ open class ActorWithBody : Actor() {
assertPrinted = true assertPrinted = true
} }
internal fun flagDespawn() { flagDespawn = true } internal fun flagDespawn() {
flagDespawn = true
}
companion object { companion object {
@@ -1040,6 +1068,7 @@ fun Double.bipolarClamp(limit: Double) =
if (this > 0 && this > limit) limit if (this > 0 && this > limit) limit
else if (this < 0 && this < -limit) -limit else if (this < 0 && this < -limit) -limit
else this else this
fun absMax(left: Double, right: Double): Double { fun absMax(left: Double, right: Double): Double {
if (left > 0 && right > 0) if (left > 0 && right > 0)
if (left > right) return left if (left > right) return left
@@ -1054,6 +1083,7 @@ fun absMax(left: Double, right: Double): Double {
else return right else return right
} }
} }
fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr() fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr()
fun Double.sign() = if (this > 0.0) 1.0 else if (this < 0.0) -1.0 else 0.0 fun Double.sign() = if (this > 0.0) 1.0 else if (this < 0.0) -1.0 else 0.0

View File

@@ -6,6 +6,7 @@ import net.torvald.spriteanimation.SpriteAnimation
import com.google.gson.JsonObject import com.google.gson.JsonObject
import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.gameactors.faction.FactionFactory import net.torvald.terrarum.gameactors.faction.FactionFactory
import net.torvald.terrarum.itemproperties.ItemPropCodex
import net.torvald.terrarum.mapdrawer.MapDrawer import net.torvald.terrarum.mapdrawer.MapDrawer
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import java.io.IOException import java.io.IOException
@@ -74,7 +75,8 @@ object PlayerBuilderSigrid {
// Test fill up inventory // Test fill up inventory
p.inventory.add(16)
p.itemHolding = ItemPropCodex.getProp(16)

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.gameitem.InventoryItem
import java.util.*
/** /**
* Created by minjaesong on 16-01-15. * Created by minjaesong on 16-01-15.
@@ -9,7 +10,13 @@ interface Pocketed {
var inventory: ActorInventory var inventory: ActorInventory
/** Item currentry holding, like tools/weapons/scrolls/magic/etc. */ /** Item currentry holding, like tools/weapons/scrolls/magic/etc.
var itemHolding: InventoryItem * Null if not holding anything
*/
var itemHolding: InventoryItem?
/**
* List of all equipped items (tools, armours, rings, necklaces, etc.)
*/
val itemEquipped: ArrayList<InventoryItem>
} }