mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
fixed a long bug where item would be used twice but discounted by only one on single click
This commit is contained in:
@@ -205,9 +205,9 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
|
|
||||||
try { processor = GetCpuName.getModelName(); }
|
try { processor = GetCpuName.getModelName(); }
|
||||||
catch (IOException e1) { processor = "Unknown"; }
|
catch (IOException e1) { processor = "Unknown CPU"; }
|
||||||
try { processorVendor = GetCpuName.getCPUID(); }
|
try { processorVendor = GetCpuName.getCPUID(); }
|
||||||
catch (IOException e2) { processorVendor = "Unknown"; }
|
catch (IOException e2) { processorVendor = "Unknown CPU"; }
|
||||||
|
|
||||||
|
|
||||||
ShaderProgram.pedantic = false;
|
ShaderProgram.pedantic = false;
|
||||||
|
|||||||
@@ -126,6 +126,9 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wire version of terrainChanged() event
|
* Wire version of terrainChanged() event
|
||||||
|
*
|
||||||
|
* @param old previous settings of conduits in bit set format.
|
||||||
|
* @param new current settings of conduits in bit set format.
|
||||||
*/
|
*/
|
||||||
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
||||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||||
|
|||||||
@@ -6,24 +6,25 @@ package net.torvald.terrarum.blockproperties
|
|||||||
object Wire {
|
object Wire {
|
||||||
|
|
||||||
/* A mapping for World's conduitTypes bits */
|
/* A mapping for World's conduitTypes bits */
|
||||||
|
/* Must be aligned with the sprite sheet */
|
||||||
const val BIT_NONE = 0
|
const val BIT_NONE = 0
|
||||||
const val BIT_SIGNAL_RED = 1
|
const val BIT_SIGNAL_RED = 1
|
||||||
const val BIT_UTILITY_PROTOTYPE = 2 // logic gates/PCLs/Diodes/Caps/etc.
|
const val BIT_UTILITY_PROTOTYPE = 2 // logic gates/PCLs/Diodes/Caps/etc.
|
||||||
const val BIT_POWER_LOW = 4
|
const val BIT_POWER_LOW = 4
|
||||||
const val BIT_POWER_HIGHT = 8
|
const val BIT_POWER_HIGHT = 8
|
||||||
const val BIT_PARALLEL_8B = 16 // uses bit-to-mantissa encoding
|
const val BIT_THICKNET = 16 // the actual datagramme should be represented by another means than the ConduitFills
|
||||||
const val BIT_PARALLEL_16B = 32 // uses bit-to-mantissa encoding. 16 bit half duplex OR 8 bit full duplex
|
const val BIT_PARALLEL_8B = 32 // uses bit-to-mantissa encoding
|
||||||
const val BIT_ETHERNET = 64 // the actual datagramme should be represented by another means than the ConduitFills
|
const val BIT_PARALLEL_16B = 64 // uses bit-to-mantissa encoding. 16 bit half duplex OR 8 bit full duplex
|
||||||
|
|
||||||
/* A mapping for World's WiringNode.fills[] index */
|
/* A mapping for World's WiringNode.fills[] index */
|
||||||
const val FILL_ID_SIGNAL_RED = 0
|
/*const val FILL_ID_SIGNAL_RED = 0
|
||||||
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
||||||
|
|
||||||
fun bitToConduitFillID(bit: Int) = when(bit) {
|
fun bitToConduitFillID(bit: Int) = when(bit) {
|
||||||
BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED
|
BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED
|
||||||
BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE
|
BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,8 +36,8 @@ object Wire {
|
|||||||
* s eeeeeeee bbbbbbbb cccccccc xxxxxxx
|
* s eeeeeeee bbbbbbbb cccccccc xxxxxxx
|
||||||
* s: sign (ignored)
|
* s: sign (ignored)
|
||||||
* e: binary32 exponent (non-zero and non-255)
|
* e: binary32 exponent (non-zero and non-255)
|
||||||
* b: upper byte
|
* b: upper octet
|
||||||
* c: lower byte (zero for Byte representation)
|
* c: lower octet (zero for Byte representation)
|
||||||
* x: not used, all zero
|
* x: not used, all zero
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,16 +6,12 @@ import com.badlogic.gdx.InputAdapter
|
|||||||
import com.badlogic.gdx.controllers.Controllers
|
import com.badlogic.gdx.controllers.Controllers
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.controller.TerrarumController
|
import net.torvald.terrarum.controller.TerrarumController
|
||||||
import net.torvald.terrarum.floorInt
|
import net.torvald.terrarum.floorInt
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,22 +53,16 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
|
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
|
||||||
|
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
||||||
if (ingame.canPlayerControl) {
|
if (ingame.canPlayerControl) {
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) ||
|
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
||||||
Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
||||||
|
|
||||||
val player = (Terrarum.ingame!! as Ingame).actorNowPlaying
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
||||||
if (player == null) return
|
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
|
}
|
||||||
val itemOnGrip = player.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||||
|
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
itemOnGrip?.let {
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
|
||||||
player.consumePrimary(ItemCodex[it]!!)
|
|
||||||
}
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
|
||||||
player.consumeSecondary(ItemCodex[it]!!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,21 +182,6 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
|
||||||
if (ingame.canPlayerControl) {
|
|
||||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
|
||||||
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
|
||||||
|
|
||||||
if (button == AppLoader.getConfigInt("mouseprimary")) {
|
|
||||||
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
|
||||||
}
|
|
||||||
if (button == AppLoader.getConfigInt("mousesecondary")) {
|
|
||||||
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ingame.uiContainer.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
ingame.uiContainer.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import net.torvald.terrarum.blockproperties.Fluid
|
|||||||
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
||||||
import net.torvald.terrarum.toInt
|
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
@@ -75,20 +74,16 @@ open class GameWorld {
|
|||||||
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||||
val fluidFills: HashMap<BlockAddress, Float>
|
val fluidFills: HashMap<BlockAddress, Float>
|
||||||
|
|
||||||
// Actually stores the wiring data; used by renderers //
|
/**
|
||||||
|
* Single block can have multiple conduits, different types of conduits are stored separately.
|
||||||
|
*/
|
||||||
|
@TEMzPayload("WiNt", TEMzPayload.EXTERNAL_JSON)
|
||||||
|
private val wirings: HashMap<BlockAddress, SortedArrayList<WiringNode>>
|
||||||
|
|
||||||
@TEMzPayload("CtYP", TEMzPayload.INT48_INT_PAIR)
|
/**
|
||||||
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
|
* Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised.
|
||||||
@TEMzPayload("CfL", TEMzPayload.INT48_FLOAT_PAIR)
|
*/
|
||||||
val conduitFills: Array<HashMap<BlockAddress, Float>>
|
private val wiringBlocks: HashMap<BlockAddress, Int>
|
||||||
val conduitFills0: HashMap<BlockAddress, Float> // size of liquid packet on the block
|
|
||||||
get() = conduitFills[0]
|
|
||||||
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
|
|
||||||
get() = conduitFills[1]
|
|
||||||
|
|
||||||
// Built from the above data; used by hypothetical updater //
|
|
||||||
|
|
||||||
private val wiringNodes = SortedArrayList<WiringNode>()
|
|
||||||
|
|
||||||
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
||||||
//physics
|
//physics
|
||||||
@@ -119,13 +114,13 @@ open class GameWorld {
|
|||||||
layerTerrainLowBits = PairedMapLayer(width, height)
|
layerTerrainLowBits = PairedMapLayer(width, height)
|
||||||
layerWallLowBits = PairedMapLayer(width, height)
|
layerWallLowBits = PairedMapLayer(width, height)
|
||||||
|
|
||||||
wallDamages = HashMap<BlockAddress, Float>()
|
wallDamages = HashMap()
|
||||||
terrainDamages = HashMap<BlockAddress, Float>()
|
terrainDamages = HashMap()
|
||||||
fluidTypes = HashMap<BlockAddress, FluidType>()
|
fluidTypes = HashMap()
|
||||||
fluidFills = HashMap<BlockAddress, Float>()
|
fluidFills = HashMap()
|
||||||
|
|
||||||
conduitTypes = HashMap<BlockAddress, Int>()
|
wiringBlocks = HashMap()
|
||||||
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
wirings = HashMap()
|
||||||
|
|
||||||
// temperature layer: 2x2 is one cell
|
// temperature layer: 2x2 is one cell
|
||||||
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
||||||
@@ -153,8 +148,8 @@ open class GameWorld {
|
|||||||
fluidTypes = layerData.fluidTypes
|
fluidTypes = layerData.fluidTypes
|
||||||
fluidFills = layerData.fluidFills
|
fluidFills = layerData.fluidFills
|
||||||
|
|
||||||
conduitTypes = HashMap<BlockAddress, Int>()
|
wiringBlocks = HashMap()
|
||||||
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
wirings = HashMap()
|
||||||
|
|
||||||
spawnX = layerData.spawnX
|
spawnX = layerData.spawnX
|
||||||
spawnY = layerData.spawnY
|
spawnY = layerData.spawnY
|
||||||
@@ -215,8 +210,8 @@ open class GameWorld {
|
|||||||
terrain * PairedMapLayer.RANGE + terrainDamage
|
terrain * PairedMapLayer.RANGE + terrainDamage
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWires(x: Int, y: Int): Int {
|
fun getWiringBlocks(x: Int, y: Int): Int {
|
||||||
return conduitTypes.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWallLowBits(x: Int, y: Int): Int? {
|
fun getWallLowBits(x: Int, y: Int): Int? {
|
||||||
@@ -296,25 +291,31 @@ open class GameWorld {
|
|||||||
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/**
|
fun getAllConduitsFrom(x: Int, y: Int): SortedArrayList<WiringNode>? {
|
||||||
* Overrides entire bits with given value. DO NOT USE THIS if you don't know what this means, you'll want to use setWire().
|
return wirings.get(LandUtil.getBlockAddr(this, x, y))
|
||||||
* Besides, this function won't fire WireChangedEvent
|
|
||||||
*/
|
|
||||||
fun setWires(x: Int, y: Int, wireBits: Int) {
|
|
||||||
val (x, y) = coerceXY(x, y)
|
|
||||||
conduitTypes[LandUtil.getBlockAddr(this, x, y)] = wireBits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets single bit for given tile. YOU'LL WANT TO USE THIS instead of setWires()
|
* @param conduitTypeBit defined in net.torvald.terrarum.blockproperties.Wire, always power-of-two
|
||||||
* @param selectedWire wire-bit to modify, must be power of two
|
|
||||||
*/
|
*/
|
||||||
fun setWire(x: Int, y: Int, selectedWire: Int, bitToSet: Boolean) {
|
fun getConduitByTypeFrom(x: Int, y: Int, conduitTypeBit: Int): WiringNode? {
|
||||||
val oldWireBits = getWires(x, y)
|
val conduits = getAllConduitsFrom(x, y)
|
||||||
val oldStatus = getWires(x, y) or selectedWire != 0
|
return conduits?.searchFor(conduitTypeBit) { it.typeBitMask }
|
||||||
if (oldStatus != bitToSet) {
|
}
|
||||||
setWires(x, y, (oldWireBits and selectedWire.inv()) or (selectedWire * oldStatus.toInt()))
|
|
||||||
Terrarum.ingame?.queueWireChangedEvent(selectedWire * oldStatus.toInt(), selectedWire * bitToSet.toInt(), LandUtil.getBlockAddr(this, x, y))
|
fun addNewConduitTo(x: Int, y: Int, node: WiringNode) {
|
||||||
|
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||||
|
|
||||||
|
// check for existing type of conduit
|
||||||
|
// if there's no duplicate...
|
||||||
|
if (getWiringBlocks(x, y) and node.typeBitMask == 0) {
|
||||||
|
// store as-is
|
||||||
|
wirings.getOrPut(blockAddr) { SortedArrayList() }.add(node)
|
||||||
|
// synchronise wiringBlocks
|
||||||
|
wiringBlocks[blockAddr] = (wiringBlocks[blockAddr] ?: 0) or node.typeBitMask
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TODO("need overwriting policy for existing conduit node")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +327,7 @@ open class GameWorld {
|
|||||||
return getTileFromWall(x, y)
|
return getTileFromWall(x, y)
|
||||||
}
|
}
|
||||||
else if (mode == WIRE) {
|
else if (mode == WIRE) {
|
||||||
return getWires(x, y)
|
return getWiringBlocks(x, y)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
||||||
@@ -487,7 +488,7 @@ open class GameWorld {
|
|||||||
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
|
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class WiringNode(
|
data class WiringNode(
|
||||||
val position: BlockAddress,
|
val position: BlockAddress,
|
||||||
/** One defined in WireCodex, always power of two */
|
/** One defined in WireCodex, always power of two */
|
||||||
val typeBitMask: Int,
|
val typeBitMask: Int,
|
||||||
@@ -540,6 +541,9 @@ inline class FluidType(val value: Int) {
|
|||||||
*/
|
*/
|
||||||
annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
||||||
companion object {
|
companion object {
|
||||||
|
const val EXTERNAL_JAVAPROPERTIES = -3
|
||||||
|
const val EXTERNAL_CSV = -2
|
||||||
|
const val EXTERNAL_JSON = -1
|
||||||
const val EIGHT_MSB = 0
|
const val EIGHT_MSB = 0
|
||||||
const val FOUR_LSB = 1
|
const val FOUR_LSB = 1
|
||||||
const val INT48_FLOAT_PAIR = 2
|
const val INT48_FLOAT_PAIR = 2
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class EntryPoint : ModuleEntryPoint() {
|
|||||||
this.inventoryCategory == Category.WALL &&
|
this.inventoryCategory == Category.WALL &&
|
||||||
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
|
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
|
||||||
this.inventoryCategory == Category.WIRE &&
|
this.inventoryCategory == Category.WIRE &&
|
||||||
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWires(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
|
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWiringBlocks(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|||||||
@@ -394,7 +394,9 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
override fun worldPrimaryClickStart(delta: Float) {
|
override fun worldPrimaryClickStart(delta: Float) {
|
||||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||||
ItemCodex[itemOnGrip]?.startPrimaryUse(delta)
|
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startPrimaryUse(delta) ?: false
|
||||||
|
if (consumptionSuccessful)
|
||||||
|
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun worldPrimaryClickEnd(delta: Float) {
|
override fun worldPrimaryClickEnd(delta: Float) {
|
||||||
@@ -404,7 +406,9 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
override fun worldSecondaryClickStart(delta: Float) {
|
override fun worldSecondaryClickStart(delta: Float) {
|
||||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||||
ItemCodex[itemOnGrip]?.startSecondaryUse(delta)
|
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startSecondaryUse(delta) ?: false
|
||||||
|
if (consumptionSuccessful)
|
||||||
|
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun worldSecondaryClickEnd(delta: Float) {
|
override fun worldSecondaryClickEnd(delta: Float) {
|
||||||
|
|||||||
@@ -177,7 +177,9 @@ class ActorInventory(@Transient val actor: Pocketed, var maxCapacity: Int, var c
|
|||||||
false
|
false
|
||||||
|
|
||||||
|
|
||||||
fun consumeItem(actor: Actor, item: GameItem) {
|
fun consumeItem(item: GameItem) {
|
||||||
|
val actor = this.actor as Actor
|
||||||
|
|
||||||
if (item.stackable && !item.isDynamic) {
|
if (item.stackable && !item.isDynamic) {
|
||||||
remove(item, 1)
|
remove(item, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.itemproperties.ItemID
|
import net.torvald.terrarum.itemproperties.ItemID
|
||||||
@@ -79,15 +78,4 @@ interface Pocketed {
|
|||||||
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
|
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
|
||||||
fun hasItem(id: Int) = inventory.contains(id)
|
fun hasItem(id: Int) = inventory.contains(id)
|
||||||
|
|
||||||
|
|
||||||
fun consumePrimary(item: GameItem) {
|
|
||||||
if (item.startPrimaryUse(AppLoader.UPDATE_RATE.toFloat())) {
|
|
||||||
inventory.consumeItem(this as Actor, item) // consume on successful
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun consumeSecondary(item: GameItem) {
|
|
||||||
if (item.startSecondaryUse(AppLoader.UPDATE_RATE.toFloat()))
|
|
||||||
inventory.consumeItem(this as Actor, item) // consume on successful
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,9 @@ class WirePieceSignalWire(override val originalID: ItemID) : GameItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun startPrimaryUse(delta: Float): Boolean {
|
override fun startPrimaryUse(delta: Float): Boolean {
|
||||||
return super.startPrimaryUse(delta)
|
println("Wire!")
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun effectWhenEquipped(delta: Float) {
|
override fun effectWhenEquipped(delta: Float) {
|
||||||
|
|||||||
@@ -263,12 +263,13 @@ internal object BlocksDrawer {
|
|||||||
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
||||||
* @return 0 -> null, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
* @return 0 -> null, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
||||||
*/
|
*/
|
||||||
private fun Int.toBitOrd(): Int? =
|
private fun Int.toBitOrd(): Int? {
|
||||||
if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this")
|
//if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this")
|
||||||
else {
|
//else {
|
||||||
val k = FastMath.intLog2(this, -1)
|
val k = FastMath.intLog2(this, -1)
|
||||||
if (k == -1) null else k
|
return if (k == -1) null else k
|
||||||
}
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes to buffer. Actual draw code must be called after this operation.
|
* Writes to buffer. Actual draw code must be called after this operation.
|
||||||
@@ -305,7 +306,7 @@ internal object BlocksDrawer {
|
|||||||
val thisTile = when (mode) {
|
val thisTile = when (mode) {
|
||||||
WALL -> world.getTileFromWall(x, y)
|
WALL -> world.getTileFromWall(x, y)
|
||||||
TERRAIN -> world.getTileFromTerrain(x, y)
|
TERRAIN -> world.getTileFromTerrain(x, y)
|
||||||
WIRE -> world.getWires(x, y).and(wireBit).toBitOrd()
|
WIRE -> world.getWiringBlocks(x, y).and(wireBit).toBitOrd()
|
||||||
FLUID -> world.getFluid(x, y).type.abs()
|
FLUID -> world.getFluid(x, y).type.abs()
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,21 +66,25 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
|||||||
return false // key not found
|
return false // key not found
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired
|
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired, null when there is no such element.
|
||||||
* element is stored.
|
* element is stored.
|
||||||
* (e.g. search the Actor by its ID rather than the actor instance) */
|
* (e.g. search the Actor by its ID rather than the actor instance)
|
||||||
fun <R: Comparable<R>> searchForIndex(key: R, predicate: (T) -> R): Int? {
|
*
|
||||||
|
* @param searchQuery what exactly are we looking for?
|
||||||
|
* @param searchHow and where or how can it be found?
|
||||||
|
*/
|
||||||
|
fun <R: Comparable<R>> searchForIndex(searchQuery: R, searchHow: (T) -> R): Int? {
|
||||||
var low = 0
|
var low = 0
|
||||||
var high = this.size - 1
|
var high = this.size - 1
|
||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
val mid = (low + high).ushr(1) // safe from overflows
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
|
||||||
val midVal = predicate(get(mid))
|
val midVal = searchHow(get(mid))
|
||||||
|
|
||||||
if (key > midVal)
|
if (searchQuery > midVal)
|
||||||
low = mid + 1
|
low = mid + 1
|
||||||
else if (key < midVal)
|
else if (searchQuery < midVal)
|
||||||
high = mid - 1
|
high = mid - 1
|
||||||
else
|
else
|
||||||
return mid // key found
|
return mid // key found
|
||||||
@@ -88,9 +92,13 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
|||||||
return null // key not found
|
return null // key not found
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches the element using given predicate instead of the element itself. Returns the element desired.
|
/** Searches the element using given predicate instead of the element itself. Returns the element desired, null when there is no such element.
|
||||||
* (e.g. search the Actor by its ID rather than the actor instance) */
|
* (e.g. search the Actor by its ID rather than the actor instance)
|
||||||
fun <R: Comparable<R>> searchFor(key: R, predicate: (T) -> R): T? = getOrNull(searchForIndex(key, predicate))
|
*
|
||||||
|
* @param searchQuery what exactly are we looking for?
|
||||||
|
* @param searchHow and where or how can it be found?
|
||||||
|
*/
|
||||||
|
fun <R: Comparable<R>> searchFor(searchQuery: R, searchHow: (T) -> R): T? = getOrNull(searchForIndex(searchQuery, searchHow))
|
||||||
|
|
||||||
fun iterator() = arrayList.iterator()
|
fun iterator() = arrayList.iterator()
|
||||||
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
||||||
|
|||||||
Reference in New Issue
Block a user