mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-09 21:31:51 +09:00
actors can now block light
This commit is contained in:
@@ -58,6 +58,10 @@ object AVKey {
|
||||
const val LUMG = "luminositygreen"
|
||||
const val LUMB = "luminosityblue"
|
||||
const val LUMA = "luminosityuv"
|
||||
const val OPAR = "opacityred"
|
||||
const val OPAG = "opacitygreen"
|
||||
const val OPAB = "opacityblue"
|
||||
const val OPAA = "opacityuv"
|
||||
const val DRAGCOEFF = "dragcoeff"
|
||||
const val FALLDAMPENMULT = "falldampenmult"
|
||||
|
||||
|
||||
@@ -2,37 +2,28 @@ package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
|
||||
data class Lightbox(val hitbox: Hitbox, val getLight: () -> Cvec)
|
||||
|
||||
/**
|
||||
* For actors that either emits or blocks lights
|
||||
*
|
||||
* Created by minjaesong on 2016-02-19.
|
||||
*/
|
||||
interface Luminous {
|
||||
|
||||
/**
|
||||
* Range of 0.0 - 4.0 for each channel
|
||||
*
|
||||
* Recommended implementation:
|
||||
*
|
||||
override var color: Color
|
||||
get() = Color(
|
||||
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
(actorValue.getAsFloat(AVKey.LUMB) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
(actorValue.getAsFloat(AVKey.LUMA) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||
)
|
||||
set(value) {
|
||||
actorValue[AVKey.LUMR] = value.r * LightmapRenderer.MUL_FLOAT
|
||||
actorValue[AVKey.LUMG] = value.g * LightmapRenderer.MUL_FLOAT
|
||||
actorValue[AVKey.LUMB] = value.b * LightmapRenderer.MUL_FLOAT
|
||||
actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
|
||||
}
|
||||
*/
|
||||
var color: Cvec
|
||||
|
||||
/**
|
||||
* Arguments:
|
||||
*
|
||||
* Hitbox(x-offset, y-offset, width, height)
|
||||
* (Use ArrayList for normal circumstances)
|
||||
*/
|
||||
val lightBoxList: List<Hitbox>
|
||||
val lightBoxList: List<Lightbox>
|
||||
|
||||
/**
|
||||
* Arguments:
|
||||
*
|
||||
* Hitbox(x-offset, y-offset, width, height)
|
||||
* (Use ArrayList for normal circumstances)
|
||||
*/
|
||||
val shadeBoxList: List<Lightbox>
|
||||
}
|
||||
@@ -64,7 +64,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
if (houseDesignation != null) houseDesignation!!.clear()
|
||||
}
|
||||
|
||||
override var color: Cvec
|
||||
var actorValueColour: Cvec
|
||||
get() = Cvec(
|
||||
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f),
|
||||
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f),
|
||||
@@ -78,14 +78,32 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
actorValue[AVKey.LUMA] = value.a
|
||||
}
|
||||
|
||||
var actorValueShade: Cvec
|
||||
get() = Cvec(
|
||||
(actorValue.getAsFloat(AVKey.OPAR) ?: 0f),
|
||||
(actorValue.getAsFloat(AVKey.OPAG) ?: 0f),
|
||||
(actorValue.getAsFloat(AVKey.OPAB) ?: 0f),
|
||||
(actorValue.getAsFloat(AVKey.OPAA) ?: 0f)
|
||||
)
|
||||
set(value) {
|
||||
actorValue[AVKey.OPAR] = value.r
|
||||
actorValue[AVKey.OPAG] = value.g
|
||||
actorValue[AVKey.OPAB] = value.b
|
||||
actorValue[AVKey.OPAA] = value.a
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments:
|
||||
*
|
||||
* Hitbox(x-offset, y-offset, width, height)
|
||||
* (Use ArrayList for normal circumstances)
|
||||
*/
|
||||
override val lightBoxList: List<Hitbox>
|
||||
get() = arrayOf(Hitbox(2.0, 2.0, hitbox.width - 3, hitbox.height - 3)).toList() // things are asymmetric!!
|
||||
override val lightBoxList: List<Lightbox>
|
||||
get() = arrayOf(Lightbox(Hitbox(2.0, 2.0, hitbox.width - 3, hitbox.height - 3)) { actorValueColour }).toList() // things are asymmetric!!
|
||||
// use getter; dimension of the player may change by time.
|
||||
|
||||
override val shadeBoxList: List<Lightbox>
|
||||
get() = arrayOf(Lightbox(Hitbox(2.0, 2.0, hitbox.width - 3, hitbox.height - 3)) { actorValueShade }).toList() // things are asymmetric!!
|
||||
// use getter; dimension of the player may change by time.
|
||||
|
||||
@Transient val BASE_DENSITY = 980.0
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameactors.Hitbox
|
||||
import net.torvald.terrarum.gameactors.Lightbox
|
||||
import net.torvald.terrarum.gameactors.Luminous
|
||||
import net.torvald.terrarum.gameparticles.ParticleVanishingSprite
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
@@ -25,13 +26,14 @@ internal class FixtureTikiTorch : FixtureBase, Luminous {
|
||||
private val rndHash1 = rng.nextInt()
|
||||
private val rndHash2 = rng.nextInt()
|
||||
|
||||
override var color: Cvec
|
||||
private var color: Cvec
|
||||
get() = BlockCodex[Block.TORCH].getLumCol(rndHash1, rndHash2)
|
||||
set(value) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override val lightBoxList: ArrayList<Hitbox> = ArrayList(1)
|
||||
override val lightBoxList: ArrayList<Lightbox> = ArrayList(1)
|
||||
override val shadeBoxList: ArrayList<Lightbox> = ArrayList(1)
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 2),
|
||||
@@ -51,7 +53,7 @@ internal class FixtureTikiTorch : FixtureBase, Luminous {
|
||||
|
||||
setHitboxDimension(16, 32, 0, 0)
|
||||
|
||||
lightBoxList.add(Hitbox(6.0, 5.0, 4.0, 3.0))
|
||||
lightBoxList.add(Lightbox(Hitbox(6.0, 5.0, 4.0, 3.0)) { color })
|
||||
|
||||
makeNewSprite(CommonResourcePool.getAsTextureRegionPack("sprites-fixtures-tiki_torch.tga"))
|
||||
sprite!!.setRowsAndFrames(1, 2)
|
||||
|
||||
@@ -7,13 +7,10 @@ import net.torvald.terrarum.Point2d
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.Hitbox
|
||||
import net.torvald.terrarum.gameactors.Luminous
|
||||
import net.torvald.terrarum.gameactors.PhysProperties
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import java.util.*
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.*
|
||||
|
||||
/**
|
||||
* Simplest projectile.
|
||||
@@ -31,7 +28,7 @@ open class ProjectileSimple : ActorWithBody, Luminous, Projectile {
|
||||
var speed: Int = 0
|
||||
|
||||
|
||||
override var color: Cvec
|
||||
private var color: Cvec
|
||||
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec).cpy()
|
||||
set(value) {
|
||||
}
|
||||
@@ -41,7 +38,8 @@ open class ProjectileSimple : ActorWithBody, Luminous, Projectile {
|
||||
* Hitbox(x-offset, y-offset, width, height)
|
||||
* (Use ArrayList for normal circumstances)
|
||||
*/
|
||||
override val lightBoxList = ArrayList<Hitbox>()
|
||||
override val lightBoxList = ArrayList<Lightbox>()
|
||||
override val shadeBoxList = ArrayList<Lightbox>()
|
||||
|
||||
private val lifetimeMax = 2500
|
||||
private var lifetimeCounter = 0f
|
||||
@@ -60,7 +58,7 @@ open class ProjectileSimple : ActorWithBody, Luminous, Projectile {
|
||||
setPosition(fromPoint.x, fromPoint.y)
|
||||
posPre = Point2d(fromPoint.x, fromPoint.y)
|
||||
// lightbox sized 8x8 centered to the bullet
|
||||
lightBoxList.add(Hitbox(-4.0, -4.0, 8.0, 8.0))
|
||||
lightBoxList.add(Lightbox(Hitbox(-4.0, -4.0, 8.0, 8.0)) { color })
|
||||
//this.externalV.set(velocity)
|
||||
|
||||
damage = bulletDatabase[type][OFFSET_DAMAGE] as Int
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.Hitbox
|
||||
import net.torvald.terrarum.gameactors.Luminous
|
||||
import net.torvald.terrarum.gameactors.PhysProperties
|
||||
import net.torvald.terrarum.gameactors.*
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
@@ -32,7 +29,7 @@ class WeaponSwung : ActorWithBody, Luminous {
|
||||
actorValue[AVKey.LUMINOSITY] = value
|
||||
}
|
||||
*/
|
||||
override var color: Cvec
|
||||
private var color: Cvec
|
||||
get() = throw UnsupportedOperationException()
|
||||
set(value) {
|
||||
}
|
||||
@@ -42,7 +39,9 @@ class WeaponSwung : ActorWithBody, Luminous {
|
||||
* Hitbox(x-offset, y-offset, width, height)
|
||||
* (Use ArrayList for normal circumstances)
|
||||
*/
|
||||
override val lightBoxList: List<Hitbox>
|
||||
override val lightBoxList: List<Lightbox>
|
||||
get() = throw UnsupportedOperationException()
|
||||
override val shadeBoxList: List<Lightbox>
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
init {
|
||||
|
||||
@@ -20,7 +20,6 @@ import net.torvald.terrarum.modulebasegame.ui.abs
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import java.util.*
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* Sub-portion of IngameRenderer. You are not supposed to directly deal with this.
|
||||
@@ -73,6 +72,7 @@ object LightmapRenderer {
|
||||
//private val noopMask = HashSet<Point2i>((LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT) * 2)
|
||||
|
||||
private val lanternMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
||||
private val shadowMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
||||
private val giMap = HashMap<BlockAddress, Cvec>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
||||
/**
|
||||
* Float value, 1.0 for 1023
|
||||
@@ -340,12 +340,14 @@ object LightmapRenderer {
|
||||
|
||||
private fun buildLanternmap(actorContainer: List<ActorWithBody>) {
|
||||
lanternMap.clear()
|
||||
shadowMap.clear()
|
||||
actorContainer.forEach {
|
||||
if (it is Luminous) {
|
||||
val lightBoxCopy = it.lightBoxList.subList(0, it.lightBoxList.size) // make copy to prevent ConcurrentModificationException
|
||||
val shadeBoxCopy = it.shadeBoxList.subList(0, it.shadeBoxList.size) // make copy to prevent ConcurrentModificationException
|
||||
|
||||
// put lanterns to the area the luminantBox is occupying
|
||||
for (lightBox in lightBoxCopy) {
|
||||
lightBoxCopy.forEach { (lightBox, colour) ->
|
||||
val lightBoxX = it.hitbox.startX + lightBox.startX
|
||||
val lightBoxY = it.hitbox.startY + lightBox.startY
|
||||
val lightBoxW = lightBox.width
|
||||
@@ -356,12 +358,31 @@ object LightmapRenderer {
|
||||
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
|
||||
|
||||
val oldLight = lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: Cvec(0) // if two or more luminous actors share the same block, mix the light
|
||||
val actorLight = it.color
|
||||
val actorLight = colour()
|
||||
|
||||
lanternMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.maxAndAssign(actorLight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// put shades to the area the luminantBox is occupying
|
||||
shadeBoxCopy.forEach { (shadeBox, colour) ->
|
||||
val lightBoxX = it.hitbox.startX + shadeBox.startX
|
||||
val lightBoxY = it.hitbox.startY + shadeBox.startY
|
||||
val lightBoxW = shadeBox.width
|
||||
val lightBoxH = shadeBox.height
|
||||
for (y in lightBoxY.div(TILE_SIZE).floorInt()
|
||||
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
|
||||
for (x in lightBoxX.div(TILE_SIZE).floorInt()
|
||||
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
|
||||
|
||||
val oldLight = shadowMap[LandUtil.getBlockAddr(world, x, y)] ?: Cvec(0) // if two or more luminous actors share the same block, mix the light
|
||||
val actorLight = colour()
|
||||
|
||||
shadowMap[LandUtil.getBlockAddr(world, x, y)] = oldLight.maxAndAssign(actorLight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -464,15 +485,18 @@ object LightmapRenderer {
|
||||
_fluidAmountToCol.set(_thisFluid.amount, _thisFluid.amount, _thisFluid.amount, _thisFluid.amount)
|
||||
|
||||
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY))
|
||||
_thisTileLuminosity.maxAndAssign(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol)) // already been div by four
|
||||
_thisTileLuminosity.maxAndAssign(_thisFluidProp.getLumCol(worldX, worldY).mul(_fluidAmountToCol))
|
||||
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
|
||||
_mapThisTileOpacity.max(lx, ly, _thisFluidProp.opacity.mul(_fluidAmountToCol))// already been div by four
|
||||
_mapThisTileOpacity.max(lx, ly, _thisFluidProp.opacity.mul(_fluidAmountToCol))
|
||||
}
|
||||
else {
|
||||
_thisTileLuminosity.set(_thisTerrainProp.getLumCol(worldX, worldY))
|
||||
_mapThisTileOpacity.setVec(lx, ly, _thisTerrainProp.opacity)
|
||||
}
|
||||
|
||||
// blend shade
|
||||
_mapThisTileOpacity.max(lx, ly, shadowMap[LandUtil.getBlockAddr(world, worldX, worldY)] ?: colourNull)
|
||||
|
||||
_mapThisTileOpacity2.setR(lx, ly, _mapThisTileOpacity.getR(lx, ly) * 1.41421356f)
|
||||
_mapThisTileOpacity2.setG(lx, ly, _mapThisTileOpacity.getG(lx, ly) * 1.41421356f)
|
||||
_mapThisTileOpacity2.setB(lx, ly, _mapThisTileOpacity.getB(lx, ly) * 1.41421356f)
|
||||
|
||||
Reference in New Issue
Block a user