diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index 8adeffeb9..2137ee0d7 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -60,9 +60,9 @@ constructor() : BasicGameState() { lateinit var debugWindow: UIHandler lateinit var notifier: UIHandler - lateinit internal var playableActorDelegate: PlayableActorDelegate + internal var playableActorDelegate: PlayableActorDelegate? = null internal val player: ActorHumanoid // currently POSSESSED actor :) - get() = playableActorDelegate.actor + get() = playableActorDelegate!!.actor //private var GRADIENT_IMAGE: Image? = null //private var skyBox: Rectangle? = null diff --git a/src/net/torvald/terrarum/console/Inventory.kt b/src/net/torvald/terrarum/console/Inventory.kt index fd54cddef..44bae1796 100644 --- a/src/net/torvald/terrarum/console/Inventory.kt +++ b/src/net/torvald/terrarum/console/Inventory.kt @@ -11,27 +11,29 @@ import net.torvald.terrarum.itemproperties.ItemPropCodex */ internal object Inventory : ConsoleCommand { - private var target: ActorInventory = Terrarum.ingame.player.inventory + private var target: Pocketed = Terrarum.ingame.player override fun execute(args: Array) { if (args.size == 1) { printUsage() - } else { + } + 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()) + "hold" -> holdItem(args[2].toInt()) else -> printUsage() } } } private fun listInventory() { - if (target.getTotalUniqueCount() == 0) { + if (target.inventory.getTotalUniqueCount() == 0) { Echo("(inventory empty)") - } else { - target.forEach { refId, amount -> + } + else { + target.inventory.forEach { refId, amount -> if (amount == 0) { EchoError("Unexpected zero-amounted item: ID $refId") } @@ -44,22 +46,29 @@ internal object Inventory : ConsoleCommand { val actor = Terrarum.ingame.getActorByID(actorRefId) if (actor !is Pocketed) { EchoError("Cannot edit inventory of incompatible actor: $actor") - } else { - target = actor.inventory + } + else { + target = actor } } 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() { Echo("Usage: inventory command arguments") 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") } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index 497886a67..78d6f9980 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.gameactors.faction.Faction import net.torvald.terrarum.gamecontroller.EnumKeyFunc import net.torvald.terrarum.gamecontroller.KeyMap import net.torvald.terrarum.gameitem.InventoryItem +import net.torvald.terrarum.gameitem.InventoryItemAdapter import net.torvald.terrarum.realestate.RealEstateUtility import org.dyn4j.geometry.Vector2 import org.lwjgl.input.Controller @@ -26,11 +27,8 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) /** Must be set by PlayerFactory */ override var inventory: ActorInventory = ActorInventory() - override var itemHolding: InventoryItem - get() = throw TODO("itemHolding") - set(value) { - throw TODO("itemHolding") - } + override var itemHolding: InventoryItem? = null + override val itemEquipped = ArrayList() /** Must be set by PlayerFactory */ override var faction: HashSet = HashSet() @@ -136,6 +134,13 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) 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) { super.update(gc, delta) @@ -206,12 +211,12 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) */ // Left mouse if (isGamer && input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) { - itemHolding.primaryUse(gc, delta) + (itemHolding ?: nullItem).primaryUse(gc, delta) } // Right mouse if (isGamer && input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON)) { - itemHolding.secondaryUse(gc, delta) + (itemHolding ?: nullItem).secondaryUse(gc, delta) } /** diff --git a/src/net/torvald/terrarum/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/gameactors/ActorInventory.kt index 67314b890..1f9d39655 100644 --- a/src/net/torvald/terrarum/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/gameactors/ActorInventory.kt @@ -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 * @return @@ -79,8 +116,6 @@ class ActorInventory() { return itemList } - fun forEach(consumer: (Int, Int) -> Unit) = itemList.forEach(consumer) - /** * Get clone of the itemList * @return @@ -120,21 +155,6 @@ class ActorInventory() { 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 * @return diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index f901352f8..fb102a943 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -53,10 +53,14 @@ open class ActorWithBody : Actor() { internal val velocity = Vector2(0.0, 0.0) var veloX: Double get() = velocity.x - protected set(value) { velocity.x = value } + protected set(value) { + velocity.x = value + } var veloY: Double get() = velocity.y - protected set(value) { velocity.y = value } + protected set(value) { + velocity.y = value + } val moveDelta = Vector2(0.0, 0.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 walkX: Double get() = controllerVel!!.x - protected set(value) { controllerVel!!.x = value } + protected set(value) { + controllerVel!!.x = value + } var walkY: Double get() = controllerVel!!.y - protected set(value) { controllerVel!!.y = value } + protected set(value) { + controllerVel!!.y = value + } /** * Physical properties. @@ -114,7 +122,9 @@ open class ActorWithBody : Actor() { * Formula: restitution = 1.0 - elasticity */ var restitution: Double - set(value) { elasticity = 1.0 - value } + set(value) { + elasticity = 1.0 - value + } get() = 1.0 - elasticity @Transient private val CEILING_HIT_ELASTICITY = 0.3 @@ -363,7 +373,7 @@ open class ActorWithBody : Actor() { } // cheap solution for sticking into the wall while Left or Right is held - walledLeft = isTouchingSide(nextHitbox, COLLIDING_LEFT) + walledLeft = isTouchingSide(nextHitbox, COLLIDING_LEFT) walledRight = isTouchingSide(nextHitbox, COLLIDING_RIGHT) if (isPlayerNoClip) { walledLeft = false @@ -462,7 +472,7 @@ open class ActorWithBody : Actor() { } // axis X if (isTouchingSide(nextHitbox, COLLIDING_LEFT) || isTouchingSide(nextHitbox, COLLIDING_RIGHT) - && moveDelta.x != 0.0) { // check right and left + && moveDelta.x != 0.0) { // check right and left // the actor is hitting the wall hitAndReflectX() } @@ -475,7 +485,7 @@ open class ActorWithBody : Actor() { private fun displaceByCCD() { ccdCollided = false - if (!isNoCollideWorld){ + if (!isNoCollideWorld) { if (!isColliding(nextHitbox, COLLIDING_ALLSIDE)) return @@ -534,7 +544,10 @@ open class ActorWithBody : Actor() { if (isNoCollideWorld) return false // 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) { val offsetX = if (option == COLLIDING_LR) A_PIXEL else 0.0 val offsetY = if (option == COLLIDING_UD) A_PIXEL else 0.0 @@ -578,15 +591,18 @@ open class ActorWithBody : Actor() { } val txStart = x1.div(TSIZE).floorInt() - val txEnd = x2.div(TSIZE).floorInt() + val txEnd = x2.div(TSIZE).floorInt() val tyStart = y1.div(TSIZE).floorInt() - val tyEnd = y2.div(TSIZE).floorInt() + val tyEnd = y2.div(TSIZE).floorInt() return isCollidingInternal(txStart, tyStart, txEnd, tyEnd) } 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) { x1 = hitbox.posX x2 = hitbox.endPointX @@ -614,16 +630,19 @@ open class ActorWithBody : Actor() { else throw IllegalArgumentException() val txStart = x1.div(TSIZE).floorInt() - val txEnd = x2.div(TSIZE).floorInt() + val txEnd = x2.div(TSIZE).floorInt() val tyStart = y1.div(TSIZE).floorInt() - val tyEnd = y2.div(TSIZE).floorInt() + val tyEnd = y2.div(TSIZE).floorInt() return isCollidingInternal(txStart, tyStart, txEnd, tyEnd) } 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) { x1 = hitbox.posX x2 = hitbox.endPointX @@ -804,8 +823,8 @@ open class ActorWithBody : Actor() { if (!isWalkingH) Hitbox(nextHitbox.posX, nextHitbox.posY, nextHitbox.width + 2.0, nextHitbox.height + 2.0) - // when not walking, enlarge the hitbox for calculation so that - // feet tiles are also counted + // when not walking, enlarge the hitbox for calculation so that + // feet tiles are also counted else nextHitbox.clone() @@ -823,6 +842,7 @@ open class ActorWithBody : Actor() { return friction } + fun Int.tileFrictionToMult(): Double = this / 16.0 /** @@ -908,7 +928,8 @@ open class ActorWithBody : Actor() { (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (scale).toFloat() ) - } else { + } + else { spriteGlow!!.render(g, (hitbox.posX - scale).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), @@ -921,9 +942,9 @@ open class ActorWithBody : Actor() { open fun drawBody(gc: GameContainer, g: Graphics) { if (isVisible && sprite != null) { when (drawMode) { - DrawMode.NORMAL -> blendNormal() + DrawMode.NORMAL -> blendNormal() DrawMode.MULTIPLY -> blendMul() - DrawMode.SCREEN -> blendScreen() + DrawMode.SCREEN -> blendScreen() } if (!sprite!!.flippedHorizontal()) { @@ -932,7 +953,8 @@ open class ActorWithBody : Actor() { (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), (scale).toFloat() ) - } else { + } + else { sprite!!.render(g, (hitbox.posX - scale).toFloat(), (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), @@ -951,22 +973,26 @@ open class ActorWithBody : Actor() { } private fun clampW(x: Double): Double = - if (x < TSIZE + nextHitbox.width / 2) { - TSIZE + 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 - } else { - x - } + if (x < TSIZE + nextHitbox.width / 2) { + TSIZE + 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 + } + else { + x + } private fun clampH(y: Double): Double = - if (y < TSIZE + nextHitbox.height) { - TSIZE + nextHitbox.height - } else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) { - (world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height - } else { - y - } + if (y < TSIZE + nextHitbox.height) { + TSIZE + nextHitbox.height + } + else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) { + (world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height + } + else { + y + } private fun clampWtile(x: Int): Int = if (x < 0) 0 else if (x >= world.width) world.width - 1 else x @@ -995,7 +1021,9 @@ open class ActorWithBody : Actor() { assertPrinted = true } - internal fun flagDespawn() { flagDespawn = true } + internal fun flagDespawn() { + flagDespawn = true + } companion object { @@ -1037,23 +1065,25 @@ fun Double.sqr() = this * this fun Double.sqrt() = Math.sqrt(this) fun Int.abs() = if (this < 0) -this else this 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 this + fun absMax(left: Double, right: Double): Double { if (left > 0 && right > 0) if (left > right) return left - else return right + else return right else if (left < 0 && right < 0) if (left < right) return left - else return right + else return right else { val absL = left.abs() val absR = right.abs() if (absL > absR) return left - else return right + else return right } } + 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 diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt index f9f55d0c1..2bce11228 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt @@ -6,6 +6,7 @@ import net.torvald.spriteanimation.SpriteAnimation import com.google.gson.JsonObject import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.faction.FactionFactory +import net.torvald.terrarum.itemproperties.ItemPropCodex import net.torvald.terrarum.mapdrawer.MapDrawer import org.newdawn.slick.SlickException import java.io.IOException @@ -74,7 +75,8 @@ object PlayerBuilderSigrid { // Test fill up inventory - + p.inventory.add(16) + p.itemHolding = ItemPropCodex.getProp(16) diff --git a/src/net/torvald/terrarum/gameactors/Pocketed.kt b/src/net/torvald/terrarum/gameactors/Pocketed.kt index ca3e421ab..b9b5709dc 100644 --- a/src/net/torvald/terrarum/gameactors/Pocketed.kt +++ b/src/net/torvald/terrarum/gameactors/Pocketed.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.gameactors import net.torvald.terrarum.gameitem.InventoryItem +import java.util.* /** * Created by minjaesong on 16-01-15. @@ -9,7 +10,13 @@ interface Pocketed { var inventory: ActorInventory - /** Item currentry holding, like tools/weapons/scrolls/magic/etc. */ - var itemHolding: InventoryItem + /** Item currentry holding, like tools/weapons/scrolls/magic/etc. + * Null if not holding anything + */ + var itemHolding: InventoryItem? + /** + * List of all equipped items (tools, armours, rings, necklaces, etc.) + */ + val itemEquipped: ArrayList } \ No newline at end of file