From f6b0b447a4e96285a64e87a9eab2b189b8322a68 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 2 Oct 2021 17:50:27 +0900 Subject: [PATCH] dropped item can be picked up (at a weird distance) --- src/net/torvald/terrarum/IngameInstance.kt | 8 ++--- src/net/torvald/terrarum/gameactors/Hitbox.kt | 7 ++++ .../torvald/terrarum/gameworld/GameWorld.kt | 1 + .../terrarum/gameworld/WorldSimulator.kt | 32 +++++++++++++++++-- .../modulebasegame/gameactors/DroppedItem.kt | 11 ++++++- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index 3f5626a3d..7aebd55f6 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -425,8 +425,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { /** Will use centre point of the actors * @return List of DistanceResult, list may be empty */ - fun findKNearestActors(from: ActorWithBody, maxHits: Int): List> { - return actorsRTree.nearestNeighbour(actorDistanceCalculator, null, maxHits, object : PointND { + fun findKNearestActors(from: ActorWithBody, maxHits: Int, nodeFilter: (ActorWithBody) -> Boolean): List> { + return actorsRTree.nearestNeighbour(actorDistanceCalculator, nodeFilter, maxHits, object : PointND { override fun getDimensions(): Int = 2 override fun getOrd(axis: Int): Double = when(axis) { 0 -> from.hitbox.centeredX @@ -437,8 +437,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { } /** Will use centre point of the actors * @return Pair of: the actor, distance from the actor; null if none found */ - fun findNearestActors(from: ActorWithBody): DistanceResult? { - val t = findKNearestActors(from, 1) + fun findNearestActor(from: ActorWithBody, nodeFilter: (ActorWithBody) -> Boolean): DistanceResult? { + val t = findKNearestActors(from, 1, nodeFilter) return if (t.isNotEmpty()) t[0] else diff --git a/src/net/torvald/terrarum/gameactors/Hitbox.kt b/src/net/torvald/terrarum/gameactors/Hitbox.kt index db99d8aee..c7f571de5 100644 --- a/src/net/torvald/terrarum/gameactors/Hitbox.kt +++ b/src/net/torvald/terrarum/gameactors/Hitbox.kt @@ -156,6 +156,13 @@ class Hitbox { infix fun intersects(position: Point2d) = (position.x >= startX && position.x <= startX + width) && (position.y >= startY && position.y <= startY + height) + infix fun intersects(other: Hitbox) = + (this.startX <= other.startX && other.startX <= this.endX) || + (this.startX <= other.endX && other.endX <= this.endX) && + + (this.startY <= other.startY && other.startY <= this.endY) || + (this.startY <= other.endY && other.endY <= this.endY) + fun toVector(): Vector2 = Vector2(startX, startY) diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index a72c9994c..4bb659f2f 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -114,6 +114,7 @@ open class GameWorld() : Disposable { internal var genver = -1 internal var comp = -1 + @Deprecated("This value is only used for savegames; DO NOT USE THIS", ReplaceWith("INGAME.actorContainerActive", "net.torvald.terrarum.INGAME")) internal val actors = ArrayList() // only filled up on save and load; DO NOT USE THIS /** diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 714436907..2e3bdef16 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -5,11 +5,11 @@ import net.torvald.terrarum.* import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Fluid +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.Controllable import net.torvald.terrarum.gameitem.ItemID import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange -import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid -import net.torvald.terrarum.modulebasegame.gameactors.Electric -import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase +import net.torvald.terrarum.modulebasegame.gameactors.* import org.dyn4j.geometry.Vector2 import kotlin.math.roundToInt @@ -88,6 +88,9 @@ object WorldSimulator { App.measureDebugTime("WorldSimulator.wires") { simulateWires(delta) } + App.measureDebugTime("WorldSimulator.collisionDroppedItem") { + collideDroppedItems() + } //printdbg(this, "============================") } @@ -140,6 +143,29 @@ object WorldSimulator { } } } + fun collideDroppedItems() { + ingame.actorContainerActive.filter { it is DroppedItem }.forEach { droppedItem0 -> + val droppedItem = droppedItem0 as DroppedItem + if (droppedItem.canBePickedUp()) { + val actors = ingame.findKNearestActors(droppedItem0 as ActorWithBody, 64) { it is Controllable && it is Pocketed } + for (result in actors) { + val actor = result.get() + // if hitbox overlaps, pick up + val s = actor.scale + val w = actor.baseHitboxW * s + val h = actor.baseHitboxH * s + val pickupDistance = w*w + h*h// TODO refer to the actorValue +// println("${result.distance}\t$pickupDistance") + if (result.distance < pickupDistance) { + droppedItem.flagDespawn = true + (actor as Pocketed).inventory.add(droppedItem.itemID, droppedItem.itemCount) + break + } + } + } + } + } + /** * displace fluids. Note that the code assumes the gravity pulls things downward ONLY, * which means you'll need to modify the code A LOT if you're going to implement zero- or diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt index 79cb80d2c..33e2adca0 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt @@ -17,7 +17,11 @@ import net.torvald.terrarum.worlddrawer.WorldCamera */ open class DroppedItem : ActorWithBody { - private var itemID: ItemID = "" + companion object { + const val NO_PICKUP_TIME = 1f + } + + var itemID: ItemID = ""; private set @Transient private var textureRegion: TextureRegion? = null // deserialiser won't call setter of the fields @@ -25,6 +29,10 @@ open class DroppedItem : ActorWithBody { protected constructor() + private var timeSinceSpawned = 0f + + fun canBePickedUp() = timeSinceSpawned > NO_PICKUP_TIME + constructor(itemID: ItemID, topLeftX: Int, topLeftY: Int) : super(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) { this.itemID = itemID @@ -97,6 +105,7 @@ open class DroppedItem : ActorWithBody { override fun update(delta: Float) { super.update(delta) + timeSinceSpawned += delta // TODO merge into the already existing droppeditem with isStationary==true if one is detected } } \ No newline at end of file