Resolving issues #16 and #20

This commit is contained in:
Song Minjae
2017-04-24 02:23:13 +09:00
parent 6399c2d66b
commit 5cd5ebbea3
21 changed files with 158 additions and 76 deletions

View File

@@ -6,6 +6,8 @@ import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.itemproperties.ItemCodex
import org.newdawn.slick.GameContainer
typealias ActorID = Int
/**
* @param renderOrder invisible/technical must use "Actor.RenderOrder.MIDDLE"
*
@@ -26,7 +28,7 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable<Actor>, Runnable
* Valid RefID is equal to or greater than 16777216.
* @return Reference ID. (16777216-0x7FFF_FFFF)
*/
open var referenceID: Int = generateUniqueReferenceID()
open var referenceID: ActorID = generateUniqueReferenceID()
var actorValue = ActorValue()
@Volatile var flagDespawn = false
@@ -46,8 +48,8 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable<Actor>, Runnable
*
* override var referenceID: Int = generateUniqueReferenceID()
*/
fun generateUniqueReferenceID(): Int {
fun hasCollision(value: Int) =
fun generateUniqueReferenceID(): ActorID {
fun hasCollision(value: ActorID) =
try {
Terrarum.ingame!!.theGameHasActor(value) ||
value < ItemCodex.ACTOR_ID_MIN ||

View File

@@ -138,13 +138,15 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
private val nullItem = object : InventoryItem() {
override var id: Int = 0
override var dynamicID: Int = 0
override val originalID = dynamicID
override val isUnique: Boolean = false
override var baseMass: Double = 0.0
override var baseToolSize: Double? = null
override var inventoryCategory = "should_not_be_seen"
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "(no name)"
override var consumable = false
override val isDynamic = false
}
override fun update(gc: GameContainer, delta: Int) {

View File

@@ -35,26 +35,33 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
fun add(itemID: Int, count: Int = 1) = add(ItemCodex[itemID], count)
fun add(item: InventoryItem, count: Int = 1) {
if (item.id == Player.PLAYER_REF_ID || item.id == 0x51621D) // do not delete this magic
if (item.dynamicID == Player.PLAYER_REF_ID || item.dynamicID == 0x51621D) // do not delete this magic
throw IllegalArgumentException("Attempted to put human player into the inventory.")
if (Terrarum.ingame != null &&
(item.id == Terrarum.ingame?.player?.referenceID))
(item.dynamicID == 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
val existingItem = getByID(item.id)
val existingItem = getByDynamicID(item.dynamicID)
if (existingItem != null) { // if the item already exists
val newCount = getByID(item.id)!!.amount + count
// if the item already exists
if (existingItem != null) {
val newCount = getByDynamicID(item.dynamicID)!!.amount + count
itemList.remove(existingItem)
itemList.add(InventoryPair(existingItem.item, newCount))
}
else { // new item
// new item
else {
if (item.isDynamic) {
// assign new ID
item.originalID = item.id
item.id = InventoryItem.generateNewDynamicID(this)
println("[ActorInventory] new dynamic item detected: ${item.originalID}")
item.dynamicID = InventoryItem.generateNewDynamicID(this)
}
itemList.add(InventoryPair(item, count))
}
@@ -63,11 +70,11 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
fun remove(itemID: Int, count: Int = 1) = remove(ItemCodex[itemID], count)
fun remove(item: InventoryItem, count: Int = 1) {
val existingItem = getByID(item.id)
val existingItem = getByDynamicID(item.dynamicID)
if (existingItem != null) { // if the item already exists
val newCount = getByID(item.id)!!.amount - count
val newCount = getByDynamicID(item.dynamicID)!!.amount - count
if (newCount < 0) {
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 ${getByDynamicID(item.dynamicID)!!.amount} of them.")
}
else if (newCount > 0) {
// decrement count
@@ -141,6 +148,8 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
item.durability -= (baseDamagePerSwing * swingDmgToFrameDmg).toFloat()
if (item.durability <= 0)
remove(item, 1)
println("[ActorInventory] consumed; ${item.durability}")
}
}
@@ -150,13 +159,13 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
fun contains(item: InventoryItem) = contains(item.id)
fun contains(item: InventoryItem) = contains(item.dynamicID)
fun contains(id: Int) =
if (itemList.size == 0)
false
else
itemList.binarySearch(id) >= 0
fun getByID(id: Int): InventoryPair? {
fun getByDynamicID(id: Int): InventoryPair? {
if (itemList.size == 0)
return null
@@ -187,9 +196,9 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
val midVal = get(mid).item
if (ID > midVal.id)
if (ID > midVal.dynamicID)
low = mid + 1
else if (ID < midVal.id)
else if (ID < midVal.dynamicID)
high = mid - 1
else
return mid // key found

View File

@@ -12,17 +12,17 @@ import org.newdawn.slick.Graphics
class DroppedItem(private val item: InventoryItem) : ActorWithPhysics(Actor.RenderOrder.MIDTOP) {
init {
if (item.id >= ItemCodex.ACTOR_ID_MIN)
if (item.dynamicID >= ItemCodex.ACTOR_ID_MIN)
throw RuntimeException("Attempted to create DroppedItem actor of a real actor; the real actor must be dropped instead.")
isVisible = true
avBaseMass = if (item.id < TileCodex.TILE_UNIQUE_MAX)
TileCodex[item.id].density / 1000.0
avBaseMass = if (item.dynamicID < TileCodex.TILE_UNIQUE_MAX)
TileCodex[item.dynamicID].density / 1000.0
else
ItemCodex[item.id].mass
ItemCodex[item.dynamicID].mass
scale = ItemCodex[item.id].scale
scale = ItemCodex[item.dynamicID].scale
}
override fun update(gc: GameContainer, delta: Int) {

View File

@@ -43,7 +43,8 @@ open class HumanoidNPC(
// we're having InventoryItem data so that this class could be somewhat universal
override var itemData: InventoryItem = object : InventoryItem() {
override var id = referenceID
override var dynamicID = referenceID
override val originalID = dynamicID
override val isUnique = true
override var baseMass: Double
get() = actorValue.getAsDouble(AVKey.BASEMASS)!!
@@ -57,6 +58,7 @@ open class HumanoidNPC(
override var inventoryCategory = "npc"
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "NPC"
override var consumable = true
override val isDynamic = false
override fun secondaryUse(gc: GameContainer, delta: Int): Boolean {
try {

View File

@@ -87,7 +87,7 @@ object PlayerBuilderSigrid {
Tile.SANDSTONE_RED, Tile.STONE, Tile.STONE_BRICKS,
Tile.STONE_QUARRIED, Tile.STONE_TILE_WHITE, Tile.TORCH
)
tiles.forEach { p.inventory.add(it, 999) }
tiles.forEach { p.addItem(it, 999) }
p.inventory.add(ItemCodex.ITEM_STATIC.first)

View File

@@ -50,7 +50,7 @@ interface Pocketed {
fun removeItem(itemID: Int, count: Int = 1) = inventory.remove(ItemCodex[itemID], count)
fun removeItem(item: InventoryItem, count: Int = 1) = inventory.remove(item, count)
fun hasItem(item: InventoryItem) = inventory.contains(item.id)
fun hasItem(item: InventoryItem) = inventory.contains(item.dynamicID)
fun hasItem(id: Int) = inventory.contains(id)

View File

@@ -7,6 +7,9 @@ import java.util.HashSet
/**
* Created by minjaesong on 16-02-15.
*/
typealias FactionID = Int
class Faction(name: String) : Comparable<Faction> {
var factionName: String = name
@@ -14,7 +17,7 @@ class Faction(name: String) : Comparable<Faction> {
lateinit var factionNeutral: HashSet<String>
lateinit var factionHostile: HashSet<String>
lateinit var factionFearful: HashSet<String>
var referenceID: Long = generateUniqueID()
var referenceID: FactionID = generateUniqueID()
init {
factionAmicable = HashSet<String>()
@@ -59,10 +62,11 @@ class Faction(name: String) : Comparable<Faction> {
factionFearful.remove(faction)
}
private fun generateUniqueID(): Long {
var ret: Long
/** Valid range: -2147483648..-1 (all the negative number) */
private fun generateUniqueID(): Int {
var ret: Int
do {
ret = HQRNG().nextLong().or(0x80000000L).and(0xFFFFFFFFL) // guaranteed to be 2147483648..4294967295
ret = HQRNG().nextInt(2147483647).plus(1).unaryMinus()
} while (FactionCodex.hasFaction(ret)) // check for collision
return ret
}

View File

@@ -9,7 +9,7 @@ import java.util.*
object FactionCodex {
val factionContainer = ArrayList<Faction>()
fun hasFaction(ID: Long): Boolean =
fun hasFaction(ID: FactionID): Boolean =
if (factionContainer.size == 0)
false
else
@@ -22,7 +22,7 @@ object FactionCodex {
insertionSortLastElem(factionContainer) // we can do this as we are only adding single actor
}
fun getFactionByID(ID: Long): Faction {
fun getFactionByID(ID: FactionID): Faction {
if (factionContainer.size == 0) throw IllegalArgumentException("Faction with ID $ID does not exist.")
val index = factionContainer.binarySearch(ID)
@@ -45,7 +45,7 @@ object FactionCodex {
arr[j + 1] = x
}
private fun ArrayList<Faction>.binarySearch(ID: Long): Int {
private fun ArrayList<Faction>.binarySearch(ID: FactionID): Int {
// code from collections/Collections.kt
var low = 0
var high = factionContainer.size - 1