From 60e8aa45cdbd696b135600dc049e57399b13d434 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 13 Nov 2023 13:55:32 +0900 Subject: [PATCH] axe wip --- assets/mods/basegame/blocks/blocks.csv | 16 +- .../terrarum/modulebasegame/TerrarumIngame.kt | 9 +- .../modulebasegame/gameitems/AxeCore.kt | 154 ++++++++++++++++++ .../gameitems/PickaxeGeneric.kt | 7 +- 4 files changed, 176 insertions(+), 10 deletions(-) create mode 100644 src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt diff --git a/assets/mods/basegame/blocks/blocks.csv b/assets/mods/basegame/blocks/blocks.csv index a5e2fed0d..8bce08425 100644 --- a/assets/mods/basegame/blocks/blocks.csv +++ b/assets/mods/basegame/blocks/blocks.csv @@ -28,10 +28,10 @@ "51";"51";"51";"BLOCK_PLANK_ROSEWOOD";"0.1252";"0.1252";"0.1252";"0.1252";"17";"900";"WOOD";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"WOOD,NORANDTILE" # small punchable trees -"64";"64";"64";"BLOCK_TRUNK_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"16";"740";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" -"65";"65";"65";"BLOCK_TRUNK_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" -"66";"66";"66";"BLOCK_TRUNK_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" -"67";"67";"67";"BLOCK_TRUNK_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" +"64";"72";"64";"BLOCK_TRUNK_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"16";"740";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" +"65";"73";"65";"BLOCK_TRUNK_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" +"66";"74";"66";"BLOCK_TRUNK_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" +"67";"75";"67";"BLOCK_TRUNK_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREESMALL,NATURAL" # large non-punchable trees "72";"72";"72";"BLOCK_TRUNK_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"16";"740";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,TREETRUNK,TREELARGE,NATURAL" @@ -50,10 +50,10 @@ "97";"97";"97";"BLOCK_GRAVEL_GREY";"0.1252";"0.1252";"0.1252";"0.1252";"24";"2400";"GRVL";"1";"0";"0";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GRAVEL,NATURAL" # tree leaves -"112";"112";"112";"BLOCK_FOLIAGE_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"16";"740";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" -"113";"113";"113";"BLOCK_FOLIAGE_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" -"114";"114";"114";"BLOCK_FOLIAGE_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" -"115";"115";"115";"BLOCK_FOLIAGE_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" +"112";"N/A";"112";"BLOCK_FOLIAGE_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"16";"740";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" +"113";"N/A";"113";"BLOCK_FOLIAGE_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"19";"1200";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" +"114";"N/A";"114";"BLOCK_FOLIAGE_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"15";"670";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" +"115";"N/A";"115";"BLOCK_FOLIAGE_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"17";"900";"GRSS";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"TREE,LEAVES,NATURAL" # to be removed #"112";"112";"112";"BLOCK_ORE_MALACHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"OORE";"1";"0";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ORE,NATURAL" diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index eebfc300e..7ee37e3c5 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -31,6 +31,7 @@ import net.torvald.terrarum.gameworld.WorldSimulator import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.gameactors.* import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver +import net.torvald.terrarum.modulebasegame.gameitems.AxeCore import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore import net.torvald.terrarum.modulebasegame.gameworld.GameEconomy import net.torvald.terrarum.modulebasegame.serialise.LoadSavegame @@ -1405,6 +1406,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { val punchSize = actor.scale * actor.actorValue.getAsDouble(AVKey.BAREHAND_BASE_DIGSIZE)!! + val punchBlockSize = punchSize.div(TILE_SIZED).floorToInt() + + val mouseUnderPunchableTreeTrunk = BlockCodex[world.getTileFromTerrain(mtx, mty)].hasAllTagOf("TREETRUNK", "TREESMALL") // if there are attackable actor or fixtures val actorsUnderMouse: List = getActorsAtVicinity(mwx, mwy, punchSize / 2.0).sortedBy { @@ -1444,12 +1448,15 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { } } } + // TODO punch a small tree/shrub + else if (mouseUnderPunchableTreeTrunk) { + AxeCore.startPrimaryUse(actor, delta, null, mtx, mty, punchBlockSize.coerceAtLeast(1), punchBlockSize.coerceAtLeast(1), listOf("TREESMALL")) + } // TODO attack a mob // else if (mobsUnderHand.size > 0 && canAttackOrDig) { // } // else, punch a block else if (canAttackOrDig) { - val punchBlockSize = punchSize.div(TILE_SIZED).floorToInt() if (punchBlockSize > 0) { PickaxeCore.startPrimaryUse(actor, delta, null, mtx, mty, 1.0 / punchBlockSize, punchBlockSize, punchBlockSize) } diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt new file mode 100644 index 000000000..8d6fee3b8 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/AxeCore.kt @@ -0,0 +1,154 @@ +package net.torvald.terrarum.modulebasegame.gameitems + +import com.badlogic.gdx.graphics.Color +import net.torvald.terrarum.* +import net.torvald.terrarum.blockproperties.Block +import net.torvald.terrarum.gameactors.AVKey +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameitems.GameItem +import net.torvald.terrarum.gameitems.ItemID +import net.torvald.terrarum.gameitems.mouseInInteractableRangeTools +import net.torvald.terrarum.gameparticles.createRandomBlockParticle +import net.torvald.terrarum.itemproperties.Calculate +import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.modulebasegame.gameactors.DroppedItem +import net.torvald.terrarum.worlddrawer.CreateTileAtlas +import org.dyn4j.geometry.Vector2 + +/** + * Created by minjaesong on 2023-11-13. + */ +object AxeCore { + + fun startPrimaryUse( + actor: ActorWithBody, delta: Float, item: GameItem?, mx: Int, my: Int, + mw: Int = 1, mh: Int = 1, additionalCheckTags: List = listOf() + ) = mouseInInteractableRangeTools(actor, item) { + // un-round the mx + val ww = INGAME.world.width + val hpww = ww * TerrarumAppConfiguration.TILE_SIZE / 2 + val apos = actor.centrePosPoint + val mx = if (apos.x - mx * TerrarumAppConfiguration.TILE_SIZE < -hpww) mx - ww + else if (apos.x - mx * TerrarumAppConfiguration.TILE_SIZE >= hpww) mx + ww + else mx + + var xoff = -(mw / 2) // implicit flooring + var yoff = -(mh / 2) // implicit flooring + // if mw or mh is even number, make it closer toward the actor + if (mw % 2 == 0 && apos.x > mx * TerrarumAppConfiguration.TILE_SIZE) xoff += 1 + if (mh % 2 == 0 && apos.y > my * TerrarumAppConfiguration.TILE_SIZE) yoff += 1 + + var usageStatus = false + + for (oy in 0 until mh) for (ox in 0 until mw) { + val x = mx + xoff + ox + val y = my + yoff + oy + + val actorvalue = actor.actorValue + val tile = INGAME.world.getTileFromTerrain(x, y) + + item?.using = true + + // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) + // return false if hitting actors + // ** below is commented out -- don't make actors obstruct the way of digging ** + /*var ret1 = true + INGAME.actorContainerActive.forEach { + if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint)) + ret1 = false // return is not allowed here + } + if (!ret1) return ret1*/ + + + // check if tile under mouse is a tree + if (BlockCodex[tile].hasAllTag(listOf("TREE", "TREETRUNK") + additionalCheckTags)) { + val actionInterval = actorvalue.getAsDouble(AVKey.ACTION_INTERVAL)!! + val swingDmgToFrameDmg = delta.toDouble() / actionInterval + + INGAME.world.inflictTerrainDamage( + x, y, + Calculate.pickaxePower(actor, item?.material) * swingDmgToFrameDmg + ).let { tileBroken -> + // tile busted + if (tileBroken != null) { + // make tree fell by scanning upwards + TODO() + var drop = "" + if (drop.isNotBlank()) { + INGAME.queueActorAddition( + DroppedItem( + drop, + (x + 0.5) * TerrarumAppConfiguration.TILE_SIZED, + (y + 1.0) * TerrarumAppConfiguration.TILE_SIZED + ) + ) + } + PickaxeCore.makeDust(tile, x, y, 9) + } + // tile not busted + if (Math.random() < actionInterval) { + PickaxeCore.makeDust(tile, x, y, 1) + } + } + + usageStatus = usageStatus or true + } + // return false if here's no tile + else { + usageStatus = usageStatus or false + continue + } + } + + + usageStatus + } + + private val pixelOffs = intArrayOf(2, 7, 12) // hard-coded assuming TILE_SIZE=16 + fun makeDust(tile: ItemID, x: Int, y: Int, density: Int = 9, drawCol: Color = Color.WHITE) { + val pw = 3 + val ph = 3 + val xo = App.GLOBAL_RENDER_TIMER and 1 + val yo = App.GLOBAL_RENDER_TIMER.ushr(1) and 1 + + val renderTag = App.tileMaker.getRenderTag(tile) + val baseTilenum = renderTag.tileNumber + val representativeTilenum = when (renderTag.maskType) { + CreateTileAtlas.RenderTag.MASK_47 -> 17 + CreateTileAtlas.RenderTag.MASK_PLATFORM -> 7 + else -> 0 + } + val tileNum = baseTilenum + representativeTilenum // the particle won't match the visible tile anyway because of the seasons stuff + + val indices = (0..8).toList().shuffled().subList(0, density) + for (it in indices) { + val u = pixelOffs[it % 3] + val v = pixelOffs[it / 3] + val pos = Vector2( + TerrarumAppConfiguration.TILE_SIZED * x + u + xo + 0.5, + TerrarumAppConfiguration.TILE_SIZED * y + v + yo + 2, + ) + val veloMult = Vector2( + 1.0 * (if (Math.random() < 0.5) -1 else 1), + (2.0 - (it / 3)) / 2.0 // 1, 0.5, 0 + ) + createRandomBlockParticle(tileNum, pos, veloMult, u, v, pw, ph).let { + it.despawnUponCollision = true + it.drawColour.set(drawCol) + (Terrarum.ingame as TerrarumIngame).addParticle(it) + } + } + } + + fun endPrimaryUse(actor: ActorWithBody, delta: Float, item: GameItem): Boolean { + + item.using = false + // reset action timer to zero + actor.actorValue.set(AVKey.__ACTION_TIMER, 0.0) + return true + } + + const val BASE_MASS_AND_SIZE = 10.0 // of iron pick + const val TOOL_DURABILITY_BASE = 350 // of iron pick + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt index f519da90a..77faeb226 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt @@ -57,7 +57,6 @@ object PickaxeCore { val x = mx + xoff + ox val y = my + yoff + oy - val mousePoint = Point2d(x.toDouble(), y.toDouble()) val actorvalue = actor.actorValue val tile = INGAME.world.getTileFromTerrain(x, y) @@ -78,6 +77,12 @@ object PickaxeCore { usageStatus = usageStatus or false continue } + // return false for punchable trees + // non-punchable trees (= "log" tile placed by log item) must be mineable in order to make them useful as decor tiles + if (BlockCodex[tile].hasAllTagOf("TREE", "TREETRUNK", "TREESMALL")) { + usageStatus = usageStatus or false + continue + } // filter passed, do the job val actionInterval = actorvalue.getAsDouble(AVKey.ACTION_INTERVAL)!!