WIP inventory implementation

Former-commit-id: ce7d2125209c2c4f49b7d755b068ce72387f5e8f
Former-commit-id: f413b2699ee7448f3d3b70775ca7b679ade66475
This commit is contained in:
Song Minjae
2016-12-12 23:29:13 +09:00
parent 870c9b36ff
commit e1642c799c
10 changed files with 157 additions and 52 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -18,7 +18,7 @@ class CodexEdictis : ConsoleCommand {
}
else {
try {
val commandObj = CommandDict.get(args[1].toLowerCase())
val commandObj = CommandDict[args[1].toLowerCase()]
commandObj.printUsage()
}
catch (e: NullPointerException) {

View File

@@ -40,6 +40,7 @@ object CommandDict {
Pair("seed", Seed()),
Pair("testgetlight", TestGetLight()),
Pair("println", EchoConsole()),
Pair("inventory", Inventory()),
// Test codes
Pair("bulletintest", SetBulletin()),

View File

@@ -0,0 +1,65 @@
package net.torvald.terrarum.console
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorInventory
import net.torvald.terrarum.gameactors.Player
import net.torvald.terrarum.gameactors.Pocketed
import net.torvald.terrarum.itemproperties.ItemPropCodex
/**
* Created by SKYHi14 on 2016-12-12.
*/
class Inventory : ConsoleCommand {
private var target: ActorInventory = Terrarum.ingame.player.inventory
override fun execute(args: Array<String>) {
if (args.size == 1) {
printUsage()
} else {
when (args[1]) {
"list" -> listInventory()
"add" -> addItem(args[2].toInt(), args[3].toInt())
"target" -> setTarget(args[2].toInt())
"assign" -> assignQuickBar(args[2].toInt(), args[3].toInt())
else -> printUsage()
}
}
}
private fun listInventory() {
if (target.getTotalUniqueCount() == 0) {
Echo().execute("(inventory empty)")
} else {
target.forEach { refId, amount ->
if (amount == 0) {
Error().execute("Unexpected zero-amounted item: ID $refId")
}
Echo().execute("ID $refId${if (amount > 1) " ($amount)" else ""}")
}
}
}
private fun setTarget(actorRefId: Int = Player.PLAYER_REF_ID) {
val actor = Terrarum.ingame.getActorByID(actorRefId)
if (actor !is Pocketed) {
Error().execute("Cannot edit inventory of incompatible actor: $actor")
} else {
target = actor.inventory
}
}
private fun addItem(refId: Int, amount: Int = 1) {
target.add(ItemPropCodex.getProp(refId), amount)
}
private fun assignQuickBar(refId: Int, index: Int) {
}
override fun printUsage() {
Echo().execute("Usage: inventory command arguments")
Echo().execute("Available commands:")
Echo().execute("list | assign slot | add itemid [amount] | target [actorid]")
}
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.gameactors
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.itemproperties.ItemPropCodex
import java.util.*
@@ -21,7 +22,7 @@ class ActorInventory() {
private var capacityMode: Int
/**
* HashMap&lt;ReferenceID, Amounts&gt;
* HashMap<ReferenceID, Amounts>
*/
private val itemList: HashMap<Int, Int> = HashMap()
@@ -78,6 +79,8 @@ class ActorInventory() {
return itemList
}
fun forEach(consumer: (Int, Int) -> Unit) = itemList.forEach(consumer)
/**
* Get clone of the itemList
* @return
@@ -97,6 +100,9 @@ class ActorInventory() {
return weight
}
/**
* Real amount
*/
fun getTotalCount(): Int {
var count = 0
@@ -107,26 +113,26 @@ class ActorInventory() {
return count
}
/**
* Unique amount, multiple items are calculated as one
*/
fun getTotalUniqueCount(): Int {
return itemList.entries.size
}
fun appendToPocket(item: InventoryItem) {
appendToPocket(item, 1)
fun add(item: InventoryItem) {
add(item, 1)
}
fun appendToPocket(item: InventoryItem, count: Int) {
fun add(item: InventoryItem, count: Int) {
val key = item.itemID
// if (key == Player.PLAYER_REF_ID)
// throw new IllegalArgumentException("Attempted to put player into the inventory.");
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 (itemList.containsKey(key))
// increment amount if it already has specified item
itemList.put(key, itemList[key]!! + count)
else
// add new entry if it does not have specified item
itemList.put(key, count)
// If we already have the item, increment the amount
// If not, add item with specified amount
itemList.put(key, itemList[key] ?: 0 + count)
}
/**

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.gameitem.InventoryItemAdapter
import org.luaj.vm2.Globals
import org.luaj.vm2.LoadState
import org.luaj.vm2.LuaError
@@ -39,7 +40,7 @@ open class HumanoidNPC(aiFile: String, born: GameDate) : ActorHumanoid(born), AI
}
// we're having InventoryItem data so that this class could be somewhat universal
override var itemData: InventoryItem = object : InventoryItem {
override var itemData: InventoryItem = object : InventoryItemAdapter() {
override var itemID = referenceID
override var mass: Double
@@ -54,30 +55,9 @@ open class HumanoidNPC(aiFile: String, born: GameDate) : ActorHumanoid(born), AI
actorValue[AVKey.SCALE] = value
}
override fun effectWhileInPocket(gc: GameContainer, delta: Int) {
}
override fun effectWhenPickedUp(gc: GameContainer, delta: Int) {
}
override fun primaryUse(gc: GameContainer, delta: Int) {
// TODO do not allow primary_use
}
override fun secondaryUse(gc: GameContainer, delta: Int) {
// TODO place this Actor to the world
}
override fun effectWhenThrown(gc: GameContainer, delta: Int) {
}
override fun effectWhenTakenOut(gc: GameContainer, delta: Int) {
}
override fun worldActorEffect(gc: GameContainer, delta: Int) {
}
}
override fun getItemWeight(): Double {

View File

@@ -55,7 +55,7 @@ object PlayerBuilderSigrid {
p.actorValue[AVKey.INTELLIGENT] = true
p.actorValue[AVKey.LUMINOSITY] = 0//95487100
p.actorValue[AVKey.LUMINOSITY] = 95487100
p.actorValue[AVKey.BASEDEFENCE] = 141
@@ -71,6 +71,14 @@ object PlayerBuilderSigrid {
p.faction.add(FactionFactory.create("FactionSigrid.json"))
// Test fill up inventory
return p
}
}

View File

@@ -8,20 +8,21 @@ import org.newdawn.slick.GameContainer
interface InventoryItem {
/**
* Internal ID of an Item, Long
* 0-4096: Tiles
* 4097-32767: Static items
* 0-4095: Tiles
* 4096-32767: Static items
* 32768-16777215: Dynamic items
* >= 16777216: Actor RefID
*/
val itemID: Int
/**
* Weight of the item
* Base mass of the item. Real mass must be calculated from
* mass * scale^3
*/
var mass: Double
/**
* Scale of the item. Real mass: mass * (scale^3)
* Scale of the item.
*
* For static item, it must be 1.0. If you tinkered the item to be bigger,
* it must be re-assigned as Dynamic Item
@@ -57,10 +58,4 @@ interface InventoryItem {
* Effects applied (continuously or not) while thrown to the world
*/
fun effectWhenTakenOut(gc: GameContainer, delta: Int)
/**
* Effects applied (continuously or not) while thrown to the world,
* called by the proxy Actor
*/
fun worldActorEffect(gc: GameContainer, delta: Int)
}

View File

@@ -0,0 +1,30 @@
package net.torvald.terrarum.gameitem
import org.newdawn.slick.GameContainer
/**
* Created by SKYHi14 on 2016-12-12.
*/
abstract class InventoryItemAdapter : InventoryItem {
override abstract val itemID: Int
override abstract var mass: Double
override abstract var scale: Double
override fun effectWhileInPocket(gc: GameContainer, delta: Int) {
}
override fun effectWhenPickedUp(gc: GameContainer, delta: Int) {
}
override fun primaryUse(gc: GameContainer, delta: Int) {
}
override fun secondaryUse(gc: GameContainer, delta: Int) {
}
override fun effectWhenThrown(gc: GameContainer, delta: Int) {
}
override fun effectWhenTakenOut(gc: GameContainer, delta: Int) {
}
}

View File

@@ -5,7 +5,11 @@ import net.torvald.terrarum.KVHashMap
import net.torvald.terrarum.gameactors.CanBeAnItem
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameitem.InventoryItemAdapter
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.tileproperties.TileProp
import net.torvald.terrarum.tileproperties.TilePropCodex
import org.apache.commons.csv.CSVRecord
import org.newdawn.slick.GameContainer
import java.util.*
@@ -14,23 +18,39 @@ import java.util.*
*/
object ItemPropCodex {
val CSV_PATH = "./src/com/torvald/terrarum/itemproperties/itemprop.csv"
/**
* <ItemID or RefID for Actor, TheItem>
* Will return corresponding Actor if ID >= 16777216
*/
private val itemCodex = ArrayList<InventoryItem>()
private val itemCodex = HashMap<Int, InventoryItem>()
private val dynamicItemDescription = HashMap<Int, KVHashMap>()
val ITEM_TILE_MAX = GameWorld.TILES_SUPPORTED
val ITEM_TILE_MAX = GameWorld.TILES_SUPPORTED - 1 // 4095
val ITEM_COUNT_MAX = 16777216
val ITEM_DYNAMIC_MAX = ITEM_COUNT_MAX - 1
val ITEM_STATIC_MAX = 32767
val ITEM_DYNAMIC_MIN = ITEM_STATIC_MAX + 1
val ITEM_STATIC_MIN = ITEM_TILE_MAX
val ITEM_STATIC_MIN = ITEM_TILE_MAX + 1 // 4096
init {
// tile items
for (i in 0..ITEM_TILE_MAX) {
itemCodex[i] = object : InventoryItemAdapter() {
override val itemID: Int = i
override var mass: Double = TilePropCodex.getProp(i).density / 1000.0
// no need to set setter as scale would not change
override var scale: Double = 1.0
override fun primaryUse(gc: GameContainer, delta: Int) {
// TODO base punch attack
}
override fun secondaryUse(gc: GameContainer, delta: Int) {
// TODO place block to the world
}
}
}
// read prop in csv and fill itemCodex
// read from save (if applicable) and fill dynamicItemDescription
@@ -38,7 +58,7 @@ object ItemPropCodex {
fun getProp(code: Int): InventoryItem {
if (code < ITEM_STATIC_MAX) // generic item
return itemCodex[code] // from CSV
return itemCodex[code]!! // from CSV
else if (code < ITEM_DYNAMIC_MAX) {
TODO("read from dynamicitem description (JSON)")
}