Resolving issue #18 and #19

This commit is contained in:
Song Minjae
2017-04-23 22:53:49 +09:00
parent e9c8f03000
commit 41b2b8a694
38 changed files with 2670 additions and 241 deletions

View File

@@ -8,11 +8,11 @@ import net.torvald.colourutil.CIEXYZUtil.toColor
import net.torvald.terrarum.ModMgr
/**
* RGB-modeled CCT calculator
* RGB- and CIE-Modeled CCT calculator
* Created by minjaesong on 16-07-26.
*/
object ColourTemp {
private var envOverlayColourmap = Image(ModMgr.getPath("basegame", "colourmap/black_body_col_1000_40000_K.tga"))
private var clut = Image(ModMgr.getPath("basegame", "colourmap/black_body_col_1000_40000_K.tga"))
private fun colTempToImagePos(K: Int): Int {
if (K < 1000 || K >= 40000) throw IllegalArgumentException("K: out of range. ($K)")
@@ -21,7 +21,7 @@ object ColourTemp {
/** returns sRGB-normalised colour */
operator fun invoke(temp: Int): Color =
envOverlayColourmap.getPixel(colTempToImagePos(temp), 0).toColor()
clut.getPixel(colTempToImagePos(temp), 0).toColor()
/** returns CIExyY-based colour converted to slick.color
* @param CIE_Y 0.0 - 1.0+ */

View File

@@ -1,4 +1,4 @@
package net.torvald.terrarum
package net.torvald.dataclass
/**

View File

@@ -75,6 +75,10 @@ object DefaultConfig {
jsonObject.addProperty("safetywarning", true)
jsonObject.addProperty("maxparticles", 768)
return jsonObject
}
}

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum
import net.torvald.random.HQRNG
import net.torvald.terrarum.Terrarum.UPDATE_DELTA
import net.torvald.terrarum.Terrarum.delta
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.virtualcomputer.computer.TerrarumComputer
import net.torvald.terrarum.virtualcomputer.peripheral.PeripheralVideoCard
@@ -90,7 +90,7 @@ class StateGraphicComputerTest : BasicGameState() {
var angle = 0.0
override fun update(container: GameContainer, game: StateBasedGame?, delta: Int) {
UPDATE_DELTA = delta
Terrarum.delta = delta
Terrarum.appgc.setTitle("VT — F: ${container.fps}" +
" — M: ${Terrarum.memInUse}M / ${Terrarum.memTotal}M / ${Terrarum.memXmx}M" +

View File

@@ -1,8 +1,9 @@
package net.torvald.terrarum
import net.torvald.dataclass.CircularArray
import net.torvald.imagefont.GameFontBase
import net.torvald.random.HQRNG
import net.torvald.terrarum.Terrarum.UPDATE_DELTA
import net.torvald.terrarum.Terrarum.delta
import net.torvald.terrarum.audio.AudioResourceLibrary
import net.torvald.terrarum.concurrent.ThreadParallel
import net.torvald.terrarum.console.*
@@ -40,6 +41,7 @@ import java.lang.management.ManagementFactory
import java.util.*
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import javax.swing.JOptionPane
import kotlin.collections.HashMap
/**
@@ -48,15 +50,13 @@ import kotlin.collections.HashMap
class StateInGame : BasicGameState() {
private val ACTOR_UPDATE_RANGE = 4096
internal var game_mode = 0
lateinit var world: GameWorld
/**
* list of Actors that is sorted by Actors' referenceID
*/
val ACTORCONTAINER_INITIAL_SIZE = 128
val PARTICLES_MAX = 768
val ACTORCONTAINER_INITIAL_SIZE = 64
val PARTICLES_MAX = Terrarum.getConfigInt("maxparticles")
val actorContainer = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
val actorContainerInactive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
val particlesContainer = CircularArray<ParticleBase>(PARTICLES_MAX)
@@ -67,11 +67,6 @@ class StateInGame : BasicGameState() {
private val actorsRenderMidTop = ArrayList<ActorVisible>(ACTORCONTAINER_INITIAL_SIZE)
private val actorsRenderFront = ArrayList<ActorVisible>(ACTORCONTAINER_INITIAL_SIZE)
lateinit var consoleHandler: UIHandler
lateinit var debugWindow: UIHandler
lateinit var notifier: UIHandler
var playableActorDelegate: PlayableActorDelegate? = null // DO NOT LATEINIT!
private set
internal val player: ActorHumanoid? // currently POSSESSED actor :)
@@ -95,7 +90,12 @@ class StateInGame : BasicGameState() {
val KEY_LIGHTMAP_RENDER = Key.F7
val KEY_LIGHTMAP_SMOOTH = Key.F8
// UI aliases (no pause)
lateinit var consoleHandler: UIHandler
lateinit var debugWindow: UIHandler
lateinit var notifier: UIHandler
lateinit var uiPieMenu: UIHandler
lateinit var uiQuickBar: UIHandler
lateinit var uiInventoryPlayer: UIHandler
@@ -103,10 +103,12 @@ class StateInGame : BasicGameState() {
lateinit var uiVitalPrimary: UIHandler
lateinit var uiVitalSecondary: UIHandler
lateinit var uiVitalItem: UIHandler // itemcount/durability of held block or active ammo of held gun. As for the block, max value is 500.
lateinit var uiAliases: Array<UIHandler>
// UI aliases (pause)
val uiAlasesPausing = ArrayList<UIHandler>()
// UI aliases
lateinit var uiAliases: ArrayList<UIHandler>
private set
lateinit var uiAlasesPausing: ArrayList<UIHandler>
private set
var paused: Boolean = false
get() = uiAlasesPausing.map { if (it.isOpened) 1 else 0 }.sum() > 0
@@ -212,7 +214,7 @@ class StateInGame : BasicGameState() {
// batch-process uiAliases
uiAliases = arrayOf(
uiAliases = arrayListOf(
uiPieMenu,
uiQuickBar,
uiInventoryPlayer,
@@ -221,6 +223,9 @@ class StateInGame : BasicGameState() {
uiVitalSecondary,
uiVitalItem
)
uiAlasesPausing = arrayListOf(
consoleHandler
)
uiAlasesPausing.forEach { uiContainer.add(it) } // put them all to the UIContainer
uiAliases.forEach { uiContainer.add(it) } // put them all to the UIContainer
@@ -238,7 +243,7 @@ class StateInGame : BasicGameState() {
override fun update(gc: GameContainer, sbg: StateBasedGame, delta: Int) {
particlesActive = 0
UPDATE_DELTA = delta
Terrarum.delta = delta
setAppTitle()
@@ -337,7 +342,7 @@ class StateInGame : BasicGameState() {
}
playableActorDelegate = newActor
WorldSimulator(player, UPDATE_DELTA)
WorldSimulator(player, delta)
}
private fun changePossession(refid: Int) {
@@ -352,7 +357,7 @@ class StateInGame : BasicGameState() {
// accept new delegate
playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid)
playableActorDelegate!!.actor.collisionType = ActorWithPhysics.COLLISION_KINEMATIC
WorldSimulator(player, UPDATE_DELTA)
WorldSimulator(player, delta)
}
private fun setAppTitle() {
@@ -525,75 +530,15 @@ class StateInGame : BasicGameState() {
}
GameController.keyPressed(key, c)
if (canPlayerControl) {
player?.keyPressed(key, c)
}
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) {
uiPieMenu.setAsOpen()
uiQuickBar.setAsClose()
}
uiContainer.forEach { it.keyPressed(key, c) } // for KeyboardControlled UIcanvases
}
override fun keyReleased(key: Int, c: Char) {
GameController.keyReleased(key, c)
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) {
uiPieMenu.setAsClose()
uiQuickBar.setAsOpen()
}
uiContainer.forEach { it.keyReleased(key, c) } // for KeyboardControlled UIcanvases
}
override fun mouseMoved(oldx: Int, oldy: Int, newx: Int, newy: Int) {
GameController.mouseMoved(oldx, oldy, newx, newy)
uiContainer.forEach { it.mouseMoved(oldx, oldy, newx, newy) } // for MouseControlled UIcanvases
}
override fun mouseDragged(oldx: Int, oldy: Int, newx: Int, newy: Int) {
GameController.mouseDragged(oldx, oldy, newx, newy)
uiContainer.forEach { it.mouseDragged(oldx, oldy, newx, newy) } // for MouseControlled UIcanvases
}
override fun mousePressed(button: Int, x: Int, y: Int) {
GameController.mousePressed(button, x, y)
uiContainer.forEach { it.mousePressed(button, x, y) } // for MouseControlled UIcanvases
}
override fun mouseReleased(button: Int, x: Int, y: Int) {
GameController.mouseReleased(button, x, y)
uiContainer.forEach { it.mouseReleased(button, x, y) } // for MouseControlled UIcanvases
}
override fun mouseWheelMoved(change: Int) {
GameController.mouseWheelMoved(change)
uiContainer.forEach { it.mouseWheelMoved(change) } // for MouseControlled UIcanvases
}
override fun controllerButtonPressed(controller: Int, button: Int) {
GameController.controllerButtonPressed(controller, button)
uiContainer.forEach { it.controllerButtonPressed(controller, button) } // for GamepadControlled UIcanvases
// TODO use item on Player
}
override fun controllerButtonReleased(controller: Int, button: Int) {
GameController.controllerButtonReleased(controller, button)
uiContainer.forEach { it.controllerButtonReleased(controller, button) } // for GamepadControlled UIcanvases
}
override fun keyReleased(key: Int, c: Char) { GameController.keyReleased(key, c) }
override fun mouseMoved(oldx: Int, oldy: Int, newx: Int, newy: Int) { GameController.mouseMoved(oldx, oldy, newx, newy) }
override fun mouseDragged(oldx: Int, oldy: Int, newx: Int, newy: Int) { GameController.mouseDragged(oldx, oldy, newx, newy) }
override fun mousePressed(button: Int, x: Int, y: Int) { GameController.mousePressed(button, x, y) }
override fun mouseReleased(button: Int, x: Int, y: Int) { GameController.mouseReleased(button, x, y) }
override fun mouseWheelMoved(change: Int) { GameController.mouseWheelMoved(change) }
override fun controllerButtonPressed(controller: Int, button: Int) { GameController.controllerButtonPressed(controller, button) }
override fun controllerButtonReleased(controller: Int, button: Int) { GameController.controllerButtonReleased(controller, button) }
override fun getID(): Int = Terrarum.STATE_ID_GAME
@@ -858,8 +803,10 @@ class StateInGame : BasicGameState() {
if (index < 0) {
index = actorContainerInactive.binarySearch(ID)
if (index < 0)
if (index < 0) {
JOptionPane.showMessageDialog(null, "Actor with ID $ID does not exist.", null, JOptionPane.ERROR_MESSAGE)
throw IllegalArgumentException("Actor with ID $ID does not exist.")
}
else
return actorContainerInactive[index]
}

View File

@@ -0,0 +1,65 @@
package net.torvald.terrarum
import net.torvald.terrarum.gamecontroller.Key
import org.newdawn.slick.Color
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
import org.newdawn.slick.Image
import org.newdawn.slick.state.BasicGameState
import org.newdawn.slick.state.StateBasedGame
/**
* Created by SKYHi14 on 2017-04-22.
*/
class StateStutterTest : BasicGameState() {
private val testImage = Image(4096, 1728)
private val testImageG = testImage.graphics
override fun init(container: GameContainer?, game: StateBasedGame?) {
}
override fun update(container: GameContainer, game: StateBasedGame, delta: Int) {
Terrarum.appgc.setTitle("${Terrarum.NAME} — F: ${Terrarum.appgc.fps}")
if (container.input.isKeyDown(Key.UP))
dy -= moveDelta
if (container.input.isKeyDown(Key.DOWN))
dy += moveDelta
if (container.input.isKeyDown(Key.LEFT))
dx -= moveDelta
if (container.input.isKeyDown(Key.RIGHT))
dx += moveDelta
}
override fun getID() = Terrarum.STATE_ID_TEST_REFRESHRATE
private var imageMade = false
private var moveDelta = 3
private var dx = 0
private var dy = 0
override fun render(container: GameContainer, game: StateBasedGame, g: Graphics) {
if (!imageMade) {
testImageG.font = Terrarum.fontGame
testImageG.color = Color.white
(0x3400..0x9FFF).forEach {
testImageG.drawString(
"${it.toChar()}",
(it - 0x3400) % 256 * 16f,
(it - 0x3400) / 256 * 16f
)
}
testImageG.flush()
imageMade = true
}
g.translate(-dx.toFloat(), -dy.toFloat())
g.drawImage(testImage, 0f, 0f)
}
}

View File

@@ -47,7 +47,7 @@ class StateUITest : BasicGameState() {
init {
itemProperties[IVKey.ITEMTYPE] = IVKey.ItemType.HAMMER
}
override val id: Int = 5656
override var id: Int = 5656
override val isUnique: Boolean = true
override var originalName: String = "Test tool"
override var baseMass: Double = 12.0
@@ -63,7 +63,7 @@ class StateUITest : BasicGameState() {
init {
itemProperties[IVKey.ITEMTYPE] = IVKey.ItemType.ARTEFACT
}
override val id: Int = 4633
override var id: Int = 4633
override val isUnique: Boolean = true
override var originalName: String = "CONTEXT_ITEM_QUEST_NOUN"
override var baseMass: Double = 1.4

View File

@@ -159,6 +159,7 @@ object Terrarum : StateBasedGame(GAME_NAME) {
val STATE_ID_TEST_TTY = 0x102
val STATE_ID_TEST_BLUR = 0x103
val STATE_ID_TEST_SHADER = 0x104
val STATE_ID_TEST_REFRESHRATE = 0x105
val STATE_ID_TEST_INPUT = 0x106
val STATE_ID_TEST_UI1 = 0x110
@@ -197,7 +198,7 @@ object Terrarum : StateBasedGame(GAME_NAME) {
"${VERSION_RAW.ushr(24)}.${VERSION_RAW.and(0xFF0000).ushr(16)}.${VERSION_RAW.and(0xFFFF)}"
const val NAME = "Terrarum"
var UPDATE_DELTA: Int = 0
var delta: Int = 0
// these properties goes into the GameContainer
@@ -332,6 +333,8 @@ object Terrarum : StateBasedGame(GAME_NAME) {
//addState(StateControllerRumbleTest())
//addState(StateMidiInputTest())
//addState(StateNewRunesTest())
//addState(StateStutterTest())
ingame = StateInGame(); addState(ingame)

View File

@@ -138,7 +138,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
private val nullItem = object : InventoryItem() {
override val id: Int = 0
override var id: Int = 0
override val isUnique: Boolean = false
override var baseMass: Double = 0.0
override var baseToolSize: Double? = null

View File

@@ -44,12 +44,18 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
// If we already have the item, increment the amount
// If not, add item with specified amount
val existingItem = getByID(item.id)
if (existingItem != null) { // if the item already exists
val newCount = getByID(item.id)!!.amount + count
itemList.remove(existingItem)
itemList.add(InventoryPair(existingItem.item, newCount))
}
else {
else { // new item
if (item.isDynamic) {
// assign new ID
item.originalID = item.id
item.id = InventoryItem.generateNewDynamicID(this)
}
itemList.add(InventoryPair(item, count))
}
insertionSortLastElem(itemList)
@@ -121,12 +127,18 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode
false
fun consumeItem(item: InventoryItem) {
fun consumeItem(actor: Actor, item: InventoryItem) {
if (item.consumable) {
remove(item, 1)
}
else {
item.durability -= 1f
val baseDamagePerSwing = if (actor is ActorHumanoid)
actor.avStrength / 1000.0
else
1.0 // TODO variable: scale, strength
val swingDmgToFrameDmg = Terrarum.delta.toDouble() / actor.actorValue.getAsDouble(AVKey.ACTION_INTERVAL)!!
item.durability -= (baseDamagePerSwing * swingDmgToFrameDmg).toFloat()
if (item.durability <= 0)
remove(item, 1)
}

View File

@@ -107,9 +107,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
}
@Transient val MASS_LOWEST = 0.1 // Kilograms
/** Apparent mass. Use "avBaseMass" for base mass */
var mass: Double
val mass: Double
get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT * Math.pow(scale, 3.0)
set(value) {
/*set(value) { // use "var avBaseMass: Double"
if (value <= 0)
throw IllegalArgumentException("mass cannot be less than or equal to zero.")
else if (value < MASS_LOWEST) {
@@ -118,7 +118,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
}
actorValue[AVKey.BASEMASS] = value / Math.pow(scale, 3.0)
}
}*/
@Transient private val MASS_DEFAULT: Double = 60.0
/** Valid range: [0, 1] */
var elasticity: Double = 0.0
@@ -232,7 +232,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
protected val gameContainer: GameContainer
get() = Terrarum.appgc
protected val updateDelta: Int
get() = Terrarum.UPDATE_DELTA
get() = Terrarum.delta
/**
* true: This actor had just made collision
@@ -1286,15 +1286,12 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
set(value) {
actorValue[AVKey.SCALE] = value
}
/** Apparent strength */
var avStrength: Double
get() = (actorValue.getAsDouble(AVKey.STRENGTH) ?: 0.0) *
(actorValue.getAsDouble(AVKey.STRENGTHBUFF) ?: 0.0) * scale
set(value) {
actorValue[AVKey.STRENGTH] =
value /
((actorValue.getAsDouble(AVKey.STRENGTHBUFF) ?: 1.0) * (avBaseStrength ?: 1.0))
}
/**
* Apparent strength. 1 000 is default value
*/
val avStrength: Double
get() = (actorValue.getAsDouble(AVKey.STRENGTH) ?: 1000.0) *
(actorValue.getAsDouble(AVKey.STRENGTHBUFF) ?: 1.0) * scale
var avBaseStrength: Double?
get() = actorValue.getAsDouble(AVKey.STRENGTH)
set(value) {

View File

@@ -17,7 +17,7 @@ class DroppedItem(private val item: InventoryItem) : ActorWithPhysics(Actor.Rend
isVisible = true
mass = if (item.id < TileCodex.TILE_UNIQUE_MAX)
avBaseMass = if (item.id < TileCodex.TILE_UNIQUE_MAX)
TileCodex[item.id].density / 1000.0
else
ItemCodex[item.id].mass

View File

@@ -20,7 +20,7 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Int? = null
/** Will NOT actually delete from the CircularArray */
@Volatile var flagDespawn = false
override fun run() = update(Terrarum.appgc, Terrarum.UPDATE_DELTA)
override fun run() = update(Terrarum.appgc, Terrarum.delta)
var isNoSubjectToGrav = false
var dragCoefficient = 3.0

View File

@@ -9,7 +9,7 @@ import org.newdawn.slick.Image
class ParticleTestRain(posX: Double, posY: Double) : ParticleBase(Actor.RenderOrder.BEHIND, 6000) {
init {
body = Image("./assets/graphics/weathers/raindrop.tga")
body = Image("./assets/modules/basegame/weathers/raindrop.tga")
val w = body.width.toDouble()
val h = body.height.toDouble()
hitbox.setFromWidthHeight(

View File

@@ -16,7 +16,7 @@ class PhysTestBall : ActorWithPhysics(Actor.RenderOrder.MIDDLE, immobileBody = t
init {
setHitboxDimension(16, 16, 0, 0)
mass = 10.0
avBaseMass = 10.0
density = 200.0
color = RoguelikeRandomiser.composeColourFrom(RoguelikeRandomiser.POTION_PRIMARY_COLSET)

View File

@@ -25,7 +25,7 @@ interface Pocketed {
}
inventory.itemEquipped[item.equipPosition] = null
item.effectOnUnequip(Terrarum.appgc, Terrarum.UPDATE_DELTA)
item.effectOnUnequip(Terrarum.appgc, Terrarum.delta)
}
/**
@@ -37,7 +37,7 @@ interface Pocketed {
if (item.equipPosition >= 0) {
inventory.itemEquipped[item.equipPosition] = item
item.effectWhenEquipped(Terrarum.appgc, Terrarum.UPDATE_DELTA)
item.effectWhenEquipped(Terrarum.appgc, Terrarum.delta)
}
}
@@ -55,12 +55,13 @@ interface Pocketed {
fun consumePrimary(item: InventoryItem) {
if (item.primaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA))
inventory.consumeItem(item) // consume on successful
if (item.primaryUse(Terrarum.appgc, Terrarum.delta)) {
inventory.consumeItem(this as Actor, item) // consume on successful
}
}
fun consumeSecondary(item: InventoryItem) {
if (item.secondaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA))
inventory.consumeItem(item) // consume on successful
if (item.secondaryUse(Terrarum.appgc, Terrarum.delta))
inventory.consumeItem(this as Actor, item) // consume on successful
}
}

View File

@@ -18,15 +18,17 @@ import org.newdawn.slick.Input
*/
object GameController {
private val ingame = Terrarum.ingame!!
// these four values can also be accessed with GameContainer.<varname>
// e.g. gc.mouseTileX
/** position of the mouse (pixelwise) relative to the world (also, currently pointing world-wise coordinate, if the world coordinate is pixel-wise) */
val mouseX: Float
get() = (MapCamera.x + Terrarum.appgc.input.mouseX / (Terrarum.ingame?.screenZoom ?: 1f))
get() = (MapCamera.x + Terrarum.appgc.input.mouseX / (ingame.screenZoom ?: 1f))
/** position of the mouse (pixelwise) relative to the world (also, currently pointing world-wise coordinate, if the world coordinate is pixel-wise)*/
val mouseY: Float
get() = (MapCamera.y + Terrarum.appgc.input.mouseY / (Terrarum.ingame?.screenZoom ?: 1f))
get() = (MapCamera.y + Terrarum.appgc.input.mouseY / (ingame.screenZoom ?: 1f))
/** currently pointing tile coordinate */
val mouseTileX: Int
get() = (mouseX / FeaturesDrawer.TILE_SIZE).floorInt()
@@ -35,81 +37,97 @@ object GameController {
get() = (mouseY / FeaturesDrawer.TILE_SIZE).floorInt()
fun processInput(gc: GameContainer, delta: Int, input: Input) {
if (Terrarum.ingame != null) {
val ingame = Terrarum.ingame!!
// actor process input
if (!ingame.consoleHandler.isTakingControl) {
if (ingame.canPlayerControl) {
ingame.actorContainer.forEach {
if (it is Controllable) {
// disable control of actor if the actor is riding something?
if ((it as ActorHumanoid).vehicleRiding != null) {
it.vehicleRiding!!.processInput(gc, delta, input)
}
else {
it.processInput(gc, delta, input)
}
// actor process input
if (!ingame.consoleHandler.isTakingControl) {
if (ingame.canPlayerControl) {
ingame.actorContainer.forEach {
if (it is Controllable) {
// disable control of actor if the actor is riding something?
if ((it as ActorHumanoid).vehicleRiding != null) {
it.vehicleRiding!!.processInput(gc, delta, input)
}
else {
it.processInput(gc, delta, input)
}
}
}
else {
ingame.uiContainer.forEach {
it.processInput(gc, delta, input)
}
}
}
else {
ingame.consoleHandler.processInput(gc, delta, input)
ingame.uiContainer.forEach {
it.processInput(gc, delta, input)
}
}
}
else {
ingame.consoleHandler.processInput(gc, delta, input)
}
///////////////////
// MOUSE CONTROL //
///////////////////
///////////////////
// MOUSE CONTROL //
///////////////////
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
if (ingame.player != null && ingame.canPlayerControl) {
if (input.isMouseButtonDown(Terrarum.getConfigInt("mouseprimary")) || input.isMouseButtonDown(Terrarum.getConfigInt("mousesecondary"))) {
val itemOnGrip = ingame.player!!.inventory.itemEquipped[InventoryItem.EquipPosition.HAND_GRIP]
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
if (ingame.player != null && ingame.canPlayerControl) {
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)
}
if (input.isMouseButtonDown(Terrarum.getConfigInt("mousesecondary"))) {
ingame.player!!.consumeSecondary(itemOnGrip)
}
if (itemOnGrip != null) {
if (input.isMouseButtonDown(Terrarum.getConfigInt("mouseprimary"))) {
ingame.player!!.consumePrimary(itemOnGrip)
}
if (input.isMouseButtonDown(Terrarum.getConfigInt("mousesecondary"))) {
ingame.player!!.consumeSecondary(itemOnGrip)
}
}
}
/////////////////////
// GAMEPAD CONTROL //
/////////////////////
}
/////////////////////
// GAMEPAD CONTROL //
/////////////////////
}
fun keyPressed(key: Int, c: Char) {
if (ingame.canPlayerControl) {
ingame.player?.keyPressed(key, c)
}
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) {
ingame.uiPieMenu.setAsOpen()
ingame.uiQuickBar.setAsClose()
}
ingame.uiContainer.forEach { it.keyPressed(key, c) } // for KeyboardControlled UIcanvases
}
fun keyReleased(key: Int, c: Char) {
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) {
ingame.uiPieMenu.setAsClose()
ingame.uiQuickBar.setAsOpen()
}
ingame.uiContainer.forEach { it.keyReleased(key, c) } // for KeyboardControlled UIcanvases
}
fun mouseMoved(oldx: Int, oldy: Int, newx: Int, newy: Int) {
ingame.uiContainer.forEach { it.mouseMoved(oldx, oldy, newx, newy) } // for MouseControlled UIcanvases
}
fun mouseDragged(oldx: Int, oldy: Int, newx: Int, newy: Int) {
ingame.uiContainer.forEach { it.mouseDragged(oldx, oldy, newx, newy) } // for MouseControlled UIcanvases
}
fun mousePressed(button: Int, x: Int, y: Int) {
ingame.uiContainer.forEach { it.mousePressed(button, x, y) } // for MouseControlled UIcanvases
}
fun mouseReleased(button: Int, x: Int, y: Int) {
@@ -121,26 +139,29 @@ object GameController {
if (itemOnGrip != null) {
if (button == Terrarum.getConfigInt("mousePrimary")) {
itemOnGrip.endPrimaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA)
itemOnGrip.endPrimaryUse(Terrarum.appgc, Terrarum.delta)
}
if (button == Terrarum.getConfigInt("mouseSecondary")) {
itemOnGrip.endSecondaryUse(Terrarum.appgc, Terrarum.UPDATE_DELTA)
itemOnGrip.endSecondaryUse(Terrarum.appgc, Terrarum.delta)
}
}
}
ingame.uiContainer.forEach { it.mouseReleased(button, x, y) } // for MouseControlled UIcanvases
}
}
fun mouseWheelMoved(change: Int) {
ingame.uiContainer.forEach { it.mouseWheelMoved(change) } // for MouseControlled UIcanvases
}
fun controllerButtonPressed(controller: Int, button: Int) {
ingame.uiContainer.forEach { it.controllerButtonPressed(controller, button) } // for GamepadControlled UIcanvases
}
fun controllerButtonReleased(controller: Int, button: Int) {
ingame.uiContainer.forEach { it.controllerButtonReleased(controller, button) } // for GamepadControlled UIcanvases
}
}

View File

@@ -225,6 +225,8 @@ class GameWorld(val width: Int, val height: Int) {
fun inflctTerrainDamage(x: Int, y: Int, damage: Float): Boolean {
val addr = LandUtil.getTileAddr(x, y)
//println("[GameWorld] ($x, $y) Damage: $damage")
if (terrainDamages[addr] == null) { // add new
terrainDamages[addr] = damage
}
@@ -238,7 +240,7 @@ class GameWorld(val width: Int, val height: Int) {
//println("[GameWorld] accumulated damage: ${terrainDamages[addr]}")
// remove tile from the world
if (terrainDamages[addr]!! >= TileCodex[getTileFromTerrain(x, y)].strength) {
if (terrainDamages[addr] ?: 0f >= TileCodex[getTileFromTerrain(x, y)].strength) {
setTileTerrain(x, y, 0)
return true
}

View File

@@ -1,7 +1,6 @@
package net.torvald.terrarum.itemproperties
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.gameactors.sqrt
import net.torvald.terrarum.gameactors.*
/**
* Created by SKYHi14 on 2017-04-17.
@@ -16,8 +15,8 @@ object Calculate {
*
* TODO Newtons as unit?
*/
fun pickaxePower(material: Material): Float {
return 4f * material.forceMod.toFloat().sqrt()
fun pickaxePower(actor: ActorHumanoid, material: Material): Float {
return (4.0 * material.forceMod.toDouble().sqrt() * (actor.avStrength / 1000.0)).toFloat()
}

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.itemproperties
import net.torvald.random.HQRNG
import net.torvald.terrarum.ItemValue
import net.torvald.terrarum.gameactors.ActorInventory
import net.torvald.terrarum.gameactors.Pocketed
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.langpack.Lang
@@ -12,7 +14,7 @@ import org.newdawn.slick.GameContainer
*/
abstract class InventoryItem : Comparable<InventoryItem>, Cloneable {
abstract val id: Int
abstract var id: Int
/**
*
@@ -49,12 +51,23 @@ abstract class InventoryItem : Comparable<InventoryItem>, Cloneable {
/** Single-use then destroyed (e.g. Tiles), aka negation of "stackable" */
abstract var consumable: Boolean
/**
* DYNAMIC means the item ID should be generated on the fly whenever the item is created.
* This is to be used with weapons/armours/etc where multiple instances can exist, and
* each of them should be treated as different item.
*
* ID Range: 32768..1048575 (ItemCodex.ITEM_DYNAMIC)
*
* The opposite of this is called STATIC and their example is a Block.
*/
open val isDynamic = false
/**
* Where to equip the item
*/
open var equipPosition: Int = EquipPosition.NULL
open val equipPosition: Int = EquipPosition.NULL
open var material: Material? = null
open val material: Material? = null
/**
* Apparent mass of the item. (basemass * scale^3)
@@ -77,6 +90,7 @@ abstract class InventoryItem : Comparable<InventoryItem>, Cloneable {
else
throw NullPointerException("null input; nullify baseToolSize instead :p")
}
var originalID = id
/**
* Scale of the item.
@@ -226,4 +240,14 @@ abstract class InventoryItem : Comparable<InventoryItem>, Cloneable {
return clonedItem
}
companion object {
fun generateNewDynamicID(inventory: ActorInventory): Int {
var ret: Int
do {
ret = HQRNG().nextInt(ItemCodex.ITEM_DYNAMIC.endInclusive + 1 - ItemCodex.ITEM_DYNAMIC.first) + ItemCodex.ITEM_DYNAMIC.first
} while (inventory.contains(ret))
return ret
}
}
}

View File

@@ -46,7 +46,7 @@ object ItemCodex {
// tile items (blocks and walls are the same thing basically)
for (i in ITEM_TILES + ITEM_WALLS) {
itemCodex[i] = object : InventoryItem() {
override val id: Int = i
override var id: Int = i
override val isUnique: Boolean = false
override var baseMass: Double = TileCodex[i].density / 1000.0
override var baseToolSize: Double? = null
@@ -54,6 +54,7 @@ object ItemCodex {
override val originalName = TileCodex[i % ITEM_WALLS.first].nameKey
override var consumable = true
override var inventoryCategory = Category.BLOCK
override var isDynamic = true
init {
itemProperties[IVKey.ITEMTYPE] = if (i in ITEM_TILES)
@@ -103,19 +104,19 @@ object ItemCodex {
// test copper pickaxe
itemCodex[ITEM_STATIC.first] = object : InventoryItem() {
override val id = ITEM_STATIC.first
override var id = ITEM_STATIC.first
override val isUnique = false
override val originalName = "Test Pick"
override var baseMass = 10.0
override var baseToolSize: Double? = 10.0
override var consumable = false
override var maxDurability = 147//606 // this much tiles before breaking
override var maxDurability = 64//606 // this much tiles before breaking
override var durability = maxDurability.toFloat()
override var equipPosition = EquipPosition.HAND_GRIP
override var inventoryCategory = Category.TOOL
private val testmaterial = Material(
0,0,0,0,0,0,0,0,14,0.0 // quick test material Steel
0,0,0,0,0,0,0,0,1,0.0 // quick test material Stone
)
init {
@@ -131,6 +132,7 @@ object ItemCodex {
using = true
// linear search filter (check for intersection with tilewise mouse point and tilewise hitbox)
// return false if hitting actors
Terrarum.ingame!!.actorContainer.forEach {
if (it is ActorWithPhysics && it.tilewiseHitbox.intersects(mousePoint))
return false
@@ -144,11 +146,12 @@ object ItemCodex {
// filter passed, do the job
val swingDmgToFrameDmg = delta.toDouble() / actorvalue.getAsDouble(AVKey.ACTION_INTERVAL)!!
return Terrarum.ingame!!.world.inflctTerrainDamage(
Terrarum.ingame!!.world.inflctTerrainDamage(
gc.mouseTileX,
gc.mouseTileY,
Calculate.pickaxePower(testmaterial) * swingDmgToFrameDmg.toFloat()
Calculate.pickaxePower(Terrarum.ingame!!.player!!, testmaterial) * swingDmgToFrameDmg.toFloat()
)
return true
}
override fun endPrimaryUse(gc: GameContainer, delta: Int): Boolean {
@@ -164,6 +167,9 @@ object ItemCodex {
// read from save (if applicable) and fill dynamicItemDescription
}
/**
* Returns clone of the item in the Codex
*/
operator fun get(code: Int): InventoryItem {
if (code <= ITEM_STATIC.endInclusive) // generic item
return itemCodex[code]!!.clone() // from CSV

View File

@@ -158,7 +158,7 @@ class PeripheralVideoCard(val host: TerrarumComputer, val termW: Int = 80, val t
private val spriteBuffer = ImageBuffer(VSprite.width * 2, VSprite.height)
fun render(g: Graphics) {
cursorBlinkTimer += Terrarum.UPDATE_DELTA
cursorBlinkTimer += Terrarum.delta
if (cursorBlinkTimer > cursorBlinkTime) {
cursorBlinkTimer -= cursorBlinkTime
cursorBlinkOn = !cursorBlinkOn

View File

@@ -151,7 +151,7 @@ object WeatherMixer {
// interpolate R, G and B
val scale = (timeInSec % dataPointDistance).toFloat() / dataPointDistance // [0.0, 1.0]
val newCol = CIELChabUtil.getGradient(scale, colourThis, colourNext)
val newCol = CIELabUtil.getGradient(scale, colourThis, colourNext)
/* // very nice monitor code
// 65 -> 66 | 300 | 19623 | RGB8(255, 0, 255) -[41%]-> RGB8(193, 97, 23) | * `230`40`160`