mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
glow/emissive for held items, even if the actor has no glow/emissive sprites
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/tiki_torch_emsv.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/tiki_torch_emsv.tga
LFS
Normal file
Binary file not shown.
48
assets/mods/basegame/sprites/taimu2_emsv.properties
Normal file
48
assets/mods/basegame/sprites/taimu2_emsv.properties
Normal file
@@ -0,0 +1,48 @@
|
||||
# complete file name is: SPRITESHEET + bodypart name + EXTENSION
|
||||
SPRITESHEET=mods/basegame/sprites/test_werebeastf2/taimuemsv_
|
||||
EXTENSION=.tga
|
||||
# defines frame size and origin point. Origin point is given as: (originx, 0)
|
||||
CONFIG=SIZE 64,98;ORIGINX 40
|
||||
|
||||
! A skeleton also defines what body parts (images) be used.
|
||||
! You can also write multiline text using reverse solidus; this is a feature of .properties
|
||||
! skeleton joints are ordered: foremost-drawn object comes first, which means lowermost object IN THIS LIST
|
||||
! are painted first, and any object that comes before it will paint over it. In other words, this list is
|
||||
! first reversed then being iterated.
|
||||
! Some keywords are considered special within the game, they are:
|
||||
! HEADGEAR, HELD_ITEM, BOOT_L, BOOT_R, GAUNTLET_L, GAUNTLET_R and ARMOUR_* (star means any number starting from zero)
|
||||
BODYPARTS=HEADGEAR 13,14;\
|
||||
HEAD 13,14;\
|
||||
ARM_REST_RIGHT 10,4;\
|
||||
ARM_REST_LEFT 9,3;\
|
||||
LEG_REST_RIGHT 15,6;\
|
||||
LEG_REST_LEFT 8,6;\
|
||||
TORSO_0 18,19;\
|
||||
TORSO_1 18,19;\
|
||||
TAIL_0 30,2;\
|
||||
BUST_0 11,2;\
|
||||
HELD_ITEM 0,0
|
||||
SKELETON_STAND=HEADGEAR 0,78;\
|
||||
ARM_REST_RIGHT -16,66;\
|
||||
HELD_ITEM -11,33;\
|
||||
HEAD 0,78;\
|
||||
BUST_0 0,63;\
|
||||
LEG_REST_RIGHT -5,41;\
|
||||
TORSO_0 0,54;\
|
||||
TORSO_1 0,54;\
|
||||
LEG_REST_LEFT 3,41;\
|
||||
ARM_REST_LEFT 8,66;\
|
||||
TAIL_0 2,40
|
||||
|
||||
! When you move the arms/hands, make sure you move the HELD_ITEM as well
|
||||
|
||||
# RUNNING might need its own skeleton...
|
||||
ANIM_RUN=DELAY 0.18;ROW 2;SKELETON SKELETON_STAND
|
||||
ANIM_RUN_1=LEG_REST_RIGHT 2,2;LEG_REST_LEFT -2,0;TAIL_0 1,0;TORSO_1 0,-999
|
||||
ANIM_RUN_2=ALL 0,2;LEG_REST_RIGHT 0,-2;LEG_REST_LEFT 0,2;TAIL_0 -1,0;TORSO_1 0,-999
|
||||
ANIM_RUN_3=LEG_REST_RIGHT -2,0;LEG_REST_LEFT 2,2;TAIL_0 -1,0;TORSO_1 0,-999
|
||||
ANIM_RUN_4=ALL 0,2;LEG_REST_RIGHT 0,2;LEG_REST_LEFT 0,-2;TAIL_0 1,0;TORSO_1 0,-999
|
||||
|
||||
ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND
|
||||
ANIM_IDLE_1=TORSO_1 0,-999
|
||||
ANIM_IDLE_2=TORSO_0 0,-999;ARM_REST_LEFT 0,1;ARM_REST_RIGHT 0,1;HELD_ITEM 0,1;BUST_0 0,1;HEAD 0,1
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
package net.torvald.spriteanimation
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
@@ -31,10 +32,11 @@ class AssembledSpriteAnimation(
|
||||
parentActor: ActorWithBody,
|
||||
@Transient val disk: SimpleFileSystem?, // specify if the resources for the animation is contained in the disk archive
|
||||
@Transient val bodypartToFileMap: EntryID?, // which file in the disk contains bodypart-to-fileid mapping for this particular instance of sprite animation
|
||||
@Transient val isGlow: Boolean
|
||||
@Transient val isGlow: Boolean,
|
||||
@Transient val isEmissive: Boolean
|
||||
) : SpriteAnimation(parentActor) {
|
||||
|
||||
constructor(adp: ADProperties, parentActor: ActorWithBody, isGlow: Boolean) : this(adp, parentActor, null, null, isGlow)
|
||||
constructor(adp: ADProperties, parentActor: ActorWithBody, isGlow: Boolean, isEmissive: Boolean) : this(adp, parentActor, null, null, isGlow, isEmissive)
|
||||
|
||||
var currentFrame = 0 // while this number is zero-based, the frame number on the ADP is one-based
|
||||
private set
|
||||
@@ -112,9 +114,23 @@ class AssembledSpriteAnimation(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchItemImage(item: GameItem) = if (isGlow) ItemCodex.getItemImageGlow(item) else ItemCodex.getItemImage(item)
|
||||
private fun fetchItemImage(item: GameItem) = if (isEmissive)
|
||||
ItemCodex.getItemImageEmissive(item)
|
||||
else if (isGlow)
|
||||
ItemCodex.getItemImageGlow(item)
|
||||
else
|
||||
ItemCodex.getItemImage(item)
|
||||
|
||||
private fun fetchItemImage(mode: Int, item: GameItem) = when (mode) {
|
||||
0 -> ItemCodex.getItemImage(item)
|
||||
1 -> ItemCodex.getItemImageGlow(item)
|
||||
2 -> ItemCodex.getItemImageEmissive(item)
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
fun renderThisAnimation(batch: SpriteBatch, posX: Float, posY: Float, scale: Float, animName: String, mode: Int = 0) {
|
||||
val oldBatchColour = batch.color.cpy()
|
||||
|
||||
fun renderThisAnimation(batch: SpriteBatch, posX: Float, posY: Float, scale: Float, animName: String) {
|
||||
val animNameRoot = animName.substring(0, animName.indexOfLast { it == '_' }).ifBlank { return@renderThisAnimation }
|
||||
// quick fix for the temporary de-sync bug in which when the update-rate per frame is much greater than once, it attempts to load animation with blank name
|
||||
|
||||
@@ -138,8 +154,9 @@ class AssembledSpriteAnimation(
|
||||
|
||||
// draw held items/armours?
|
||||
if (name in jointNameToEquipPos) {
|
||||
batch.color = if (mode > 0) Color.WHITE else oldBatchColour
|
||||
ItemCodex[(parentActor as? Pocketed)?.inventory?.itemEquipped?.get(jointNameToEquipPos[name]!!)]?.let { item ->
|
||||
fetchItemImage(item)?.let { image ->
|
||||
fetchItemImage(mode, item)?.let { image ->
|
||||
val drawPos = adp.origin + bodypartPos // imgCentre for held items are (0,0)
|
||||
val w = image.regionWidth * scale
|
||||
val h = image.regionHeight * scale
|
||||
@@ -159,6 +176,7 @@ class AssembledSpriteAnimation(
|
||||
}
|
||||
}
|
||||
else {
|
||||
batch.color = oldBatchColour
|
||||
res[name]?.let { image ->
|
||||
var imgCentre = bodypartOrigins[name]!!
|
||||
if (flipVertical) imgCentre = imgCentre.invertY()
|
||||
@@ -185,10 +203,15 @@ class AssembledSpriteAnimation(
|
||||
} ?: throw NullPointerException("Animation with name '$animNameRoot' is not found")
|
||||
}
|
||||
|
||||
override fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float) {
|
||||
/**
|
||||
* Held items will ignore forcedColourFilter if mode > 0
|
||||
*
|
||||
* @param mode specifies the mode for drawing the held item. 0=diffuse, 1=glow, 2=emissive
|
||||
*/
|
||||
override fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float, mode: Int, forcedColourFilter: Color?) {
|
||||
if (parentActor.isVisible) {
|
||||
batch.color = colourFilter
|
||||
renderThisAnimation(batch, posX, posY, scale, "${currentAnimation}_${1+currentFrame}")
|
||||
batch.color = forcedColourFilter ?: colourFilter
|
||||
renderThisAnimation(batch, posX, posY, scale, "${currentAnimation}_${1+currentFrame}", mode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
abstract class SpriteAnimation(@Transient val parentActor: ActorWithBody) : Disposable {
|
||||
protected abstract val currentDelay: Second
|
||||
abstract fun update(delta: Float)
|
||||
abstract fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f)
|
||||
abstract fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float = 1f, mode: Int = 0, forcedColourFilter: Color? = null)
|
||||
|
||||
var flipHorizontal = false
|
||||
var flipVertical = false
|
||||
@@ -143,14 +143,14 @@ class SheetSpriteAnimation(parentActor: ActorWithBody) : SpriteAnimation(parentA
|
||||
* *
|
||||
* @param scale
|
||||
*/
|
||||
override fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float) {
|
||||
override fun render(frameDelta: Float, batch: SpriteBatch, posX: Float, posY: Float, scale: Float, mode: Int, forcedColourFilter: Color?) {
|
||||
assert(cellWidth > 0 || cellHeight > 0) {
|
||||
"Sprite width or height is set to zero! ($cellWidth, $cellHeight); master: $parentActor"
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
val region = textureRegion.get(currentFrame, currentRow)
|
||||
batch.color = colourFilter
|
||||
batch.color = forcedColourFilter ?: colourFilter
|
||||
|
||||
val tx = (parentActor.hitboxTranslateX) * scale
|
||||
val txF = (parentActor.hitboxTranslateX + parentActor.baseHitboxW) * scale
|
||||
|
||||
@@ -1793,16 +1793,22 @@ open class ActorWithBody : Actor {
|
||||
}
|
||||
|
||||
open fun drawGlow(frameDelta: Float, batch: SpriteBatch) {
|
||||
if (isVisible && spriteGlow != null) {
|
||||
if (isVisible) {
|
||||
blendNormalStraightAlpha(batch)
|
||||
drawSpriteInGoodPosition(frameDelta, spriteGlow!!, batch)
|
||||
if (spriteGlow != null)
|
||||
drawSpriteInGoodPosition(frameDelta, spriteGlow!!, batch, 2)
|
||||
else
|
||||
drawSpriteInGoodPosition(frameDelta, sprite!!, batch, 1, Color.BLACK)
|
||||
}
|
||||
}
|
||||
|
||||
open fun drawEmissive(frameDelta: Float, batch: SpriteBatch) {
|
||||
if (isVisible && spriteEmissive != null) {
|
||||
if (isVisible) {
|
||||
blendNormalStraightAlpha(batch)
|
||||
drawSpriteInGoodPosition(frameDelta, spriteEmissive!!, batch)
|
||||
if (spriteEmissive != null)
|
||||
drawSpriteInGoodPosition(frameDelta, spriteEmissive!!, batch, 1)
|
||||
else
|
||||
drawSpriteInGoodPosition(frameDelta, sprite!!, batch, 2, Color.BLACK)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1830,7 +1836,7 @@ open class ActorWithBody : Actor {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun drawSpriteInGoodPosition(frameDelta: Float, sprite: SpriteAnimation, batch: SpriteBatch) {
|
||||
protected fun drawSpriteInGoodPosition(frameDelta: Float, sprite: SpriteAnimation, batch: SpriteBatch, mode: Int = 0, forcedColourFilter: Color? = null) {
|
||||
if (world == null) return
|
||||
|
||||
val offsetX = 0f
|
||||
@@ -1840,7 +1846,7 @@ open class ActorWithBody : Actor {
|
||||
val posY = hitbox.startY.plus(PHYS_EPSILON_DIST).toFloat()
|
||||
|
||||
drawBodyInGoodPosition(posX, posY) { x, y ->
|
||||
sprite.render(frameDelta, batch, x + offsetX, y + offsetY, scale.toFloat())
|
||||
sprite.render(frameDelta, batch, x + offsetX, y + offsetY, scale.toFloat(), mode, forcedColourFilter)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
||||
*/
|
||||
@Transient open val itemImage: TextureRegion? = null
|
||||
@Transient open val itemImageGlow: TextureRegion? = null
|
||||
@Transient open val itemImageEmissive: TextureRegion? = null
|
||||
|
||||
/**
|
||||
* Apparent mass of the item. (basemass * scale^3)
|
||||
|
||||
@@ -135,6 +135,11 @@ class ItemCodex {
|
||||
return getItemImageGlow(item.originalID)
|
||||
}
|
||||
|
||||
fun getItemImageEmissive(item: GameItem?): TextureRegion? {
|
||||
if (item == null) return null
|
||||
return getItemImageEmissive(item.originalID)
|
||||
}
|
||||
|
||||
fun getItemImage(itemID: ItemID?): TextureRegion? {
|
||||
if (itemID == null) return null
|
||||
|
||||
@@ -193,6 +198,35 @@ class ItemCodex {
|
||||
}
|
||||
}
|
||||
|
||||
fun getItemImageEmissive(itemID: ItemID?): TextureRegion? {
|
||||
if (itemID == null) return null
|
||||
|
||||
if (itemID.isDynamic()) {
|
||||
return getItemImageEmissive(dynamicToStaticID(itemID))
|
||||
}
|
||||
else if (itemID.isItem()) {
|
||||
return itemCodex[itemID]?.itemImageEmissive
|
||||
}
|
||||
else if (itemID.isWire()) {
|
||||
return itemCodex[itemID]?.itemImageEmissive
|
||||
}
|
||||
else if (itemID.isWall()) {
|
||||
val itemSheetNumber = App.tileMaker.tileIDtoItemSheetNumber(itemID.substring(5))
|
||||
return BlocksDrawer.tileItemWallEmissive.get(
|
||||
itemSheetNumber % App.tileMaker.TILES_IN_X,
|
||||
itemSheetNumber / App.tileMaker.TILES_IN_X
|
||||
)
|
||||
}
|
||||
// else: terrain
|
||||
else {
|
||||
val itemSheetNumber = App.tileMaker.tileIDtoItemSheetNumber(itemID)
|
||||
return BlocksDrawer.tileItemTerrainEmissive.get(
|
||||
itemSheetNumber % App.tileMaker.TILES_IN_X,
|
||||
itemSheetNumber / App.tileMaker.TILES_IN_X
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hasItem(itemID: ItemID): Boolean = dynamicItemInventory.containsKey(itemID)
|
||||
fun isEmpty(): Boolean = itemCodex.isEmpty()
|
||||
}
|
||||
@@ -53,6 +53,7 @@ class FixtureJukebox : Electric, PlaysMusic {
|
||||
(mainUI as UIJukebox).parent = this
|
||||
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/jukebox.tga")
|
||||
val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/jukebox_emsv.tga")
|
||||
|
||||
density = 1400.0
|
||||
setHitboxDimension(TILE_SIZE * 2, TILE_SIZE * 3, 0, 0)
|
||||
@@ -60,6 +61,9 @@ class FixtureJukebox : Electric, PlaysMusic {
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE * 2, TILE_SIZE * 3)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, TILE_SIZE * 2, TILE_SIZE * 3)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 200.0
|
||||
|
||||
@@ -130,6 +134,7 @@ class FixtureJukebox : Electric, PlaysMusic {
|
||||
}
|
||||
|
||||
@Transient private var lampDecay = 0f
|
||||
@Transient private var lampIntensity = 0f
|
||||
|
||||
/**
|
||||
* Try to stop the disc being played, and reset the background music cue
|
||||
@@ -146,15 +151,27 @@ class FixtureJukebox : Electric, PlaysMusic {
|
||||
if (isVisible && musicNowPlaying != null) {
|
||||
val vol0 = (musicTracks[musicNowPlaying]?.processor?.maxSigLevel?.average() ?: 0.0).toFloat()
|
||||
val vol = FastMath.interpolateLinear(0.8f, vol0, lampDecay)
|
||||
lampIntensity = vol.coerceIn(0f, 1f)
|
||||
|
||||
blendScreen(batch)
|
||||
backLamp.colourFilter = Color(0f, vol.coerceIn(0f, 1f), 0f, 1f)
|
||||
backLamp.colourFilter = Color(0f, lampIntensity, 0f, 1f)
|
||||
drawSpriteInGoodPosition(frameDelta, backLamp, batch)
|
||||
|
||||
lampDecay = vol
|
||||
}
|
||||
}
|
||||
|
||||
override fun drawEmissive(frameDelta: Float, batch: SpriteBatch) {
|
||||
blendNormalStraightAlpha(batch)
|
||||
super.drawEmissive(frameDelta, batch)
|
||||
|
||||
if (isVisible && musicNowPlaying != null) {
|
||||
blendScreen(batch)
|
||||
backLamp.colourFilter = Color(0f, lampIntensity / 2f, 0f, 1f)
|
||||
drawSpriteInGoodPosition(frameDelta, backLamp, batch)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopDiscPlayback() {
|
||||
musicNowPlaying?.let {
|
||||
stopAudio(it)
|
||||
|
||||
@@ -45,9 +45,10 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite, NoSerialise {
|
||||
|
||||
private constructor()
|
||||
|
||||
constructor(animDescPath: String, animDescPathGlow: String?, born: Long) : super(born) {
|
||||
constructor(animDescPath: String, animDescPathGlow: String?, animDescPathEmissive: String?, born: Long) : super(born) {
|
||||
animDesc = ADProperties(Gdx.files.internal(animDescPath))
|
||||
if (animDescPathGlow != null) animDescGlow = ADProperties(Gdx.files.internal(animDescPathGlow))
|
||||
if (animDescPathEmissive != null) animDescEmissive = ADProperties(Gdx.files.internal(animDescPathEmissive))
|
||||
actorValue[AVKey.__HISTORICAL_BORNTIME] = born
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ object PlayerBuilder {
|
||||
operator fun invoke(): Actor {
|
||||
val world = (Terrarum.ingame!! as TerrarumIngame).world
|
||||
|
||||
val p: Actor = IngamePlayer("lol", "lol_glow", world.worldTime.TIME_T)
|
||||
val p: Actor = IngamePlayer("lol", "lol_glow", "lol_emsv", world.worldTime.TIME_T)
|
||||
InjectCreatureRaw(p.actorValue, "basegame", "CreaturePlayer.json")
|
||||
|
||||
// attach sprite
|
||||
|
||||
@@ -10,9 +10,10 @@ import net.torvald.terrarum.gameactors.AVKey
|
||||
object PlayerBuilderTestSubject1 {
|
||||
operator fun invoke(): IngamePlayer {
|
||||
val p: IngamePlayer = IngamePlayer(
|
||||
ModMgr.getGdxFile("basegame", "sprites/test_sprite.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/test_sprite_glow.properties").path(),
|
||||
-589141658L // random value thrown
|
||||
ModMgr.getGdxFile("basegame", "sprites/test_sprite.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/test_sprite_glow.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/test_sprite_emsv.properties").path(),
|
||||
0L // random value thrown
|
||||
)
|
||||
InjectCreatureRaw(p.actorValue, "basegame", "CreaturePlayer.json")
|
||||
|
||||
@@ -23,13 +24,11 @@ object PlayerBuilderTestSubject1 {
|
||||
p.actorValue[AVKey.NAME] = "Test Subject 1"
|
||||
|
||||
|
||||
/*p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/npc_template_anim_prototype.tga"), 48, 52))
|
||||
p.sprite!!.delays = floatArrayOf(2f, 1f/12f) // second value does nothing -- overridden by ActorHumanoid.updateSprite(float)
|
||||
p.sprite!!.setRowsAndFrames(2, 4)*/
|
||||
// TODO make null animation if animDesc is null
|
||||
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p, false, false) }
|
||||
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p, true, false) }
|
||||
p.animDescEmissive?.let { p.spriteEmissive = AssembledSpriteAnimation(it, p, true, true) }
|
||||
|
||||
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p, false) }
|
||||
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p, true) }
|
||||
//p.reassembleSprite(p.sprite, p.spriteGlow, null)
|
||||
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0)
|
||||
|
||||
// ingame must teleport the player to the spawn point
|
||||
|
||||
@@ -12,9 +12,10 @@ import net.torvald.terrarum.gameactors.AVKey
|
||||
object PlayerBuilderWerebeastTest {
|
||||
operator fun invoke(): IngamePlayer {
|
||||
val p: IngamePlayer = IngamePlayer(
|
||||
ModMgr.getGdxFile("basegame", "sprites/taimu2.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/taimu2_glow.properties").path(),
|
||||
-589141658L // random value thrown
|
||||
ModMgr.getGdxFile("basegame", "sprites/taimu2.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/taimu2_glow.properties").path(),
|
||||
ModMgr.getGdxFile("basegame", "sprites/taimu2_emsv.properties").path(),
|
||||
-589141658L // random value thrown
|
||||
)
|
||||
InjectCreatureRaw(p.actorValue, "basegame", "CreatureWerebeastBossBase.json")
|
||||
|
||||
@@ -24,9 +25,9 @@ object PlayerBuilderWerebeastTest {
|
||||
p.actorValue[AVKey.ACTION_INTERVAL] = ActorHumanoid.BASE_ACTION_INTERVAL
|
||||
p.actorValue[AVKey.NAME] = "Taimu"
|
||||
|
||||
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p, false) }
|
||||
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p, true) }
|
||||
p.animDescEmissive?.let { p.spriteEmissive = AssembledSpriteAnimation(it, p, true) }
|
||||
p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p, false, false) }
|
||||
p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p, true, false) }
|
||||
p.animDescEmissive?.let { p.spriteEmissive = AssembledSpriteAnimation(it, p, false, true) }
|
||||
p.setHitboxDimension(22, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 30, 0)
|
||||
|
||||
p.setPosition(3.0 * TILE_SIZE, 3.0 * TILE_SIZE)
|
||||
|
||||
@@ -14,6 +14,8 @@ class ItemFurnaceAndAnvil(originalID: ItemID) : FixtureItemBase(originalID, "net
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/metalworking_furnace_and_anvil.tga")
|
||||
override val itemImageEmissive: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/metalworking_furnace_and_anvil_emsv.tga")
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_FURNACE_AND_ANVIL"
|
||||
|
||||
@@ -14,6 +14,8 @@ class ItemJukebox(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/jukebox.tga")
|
||||
override val itemImageEmissive: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/jukebox_emsv.tga")
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_JUKEBOX"
|
||||
|
||||
@@ -14,6 +14,8 @@ class ItemSmelterBasic(originalID: ItemID) : FixtureItemBase(originalID, "net.to
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/smelter_tall.tga")
|
||||
override val itemImageEmissive: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/smelter_tall_emsv.tga")
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_SMELTER_SMALL"
|
||||
|
||||
@@ -180,8 +180,9 @@ object ReadActor {
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPART_TO_ENTRY_MAP else null,
|
||||
false
|
||||
false, false
|
||||
)
|
||||
|
||||
if (animFileGlow != null) {
|
||||
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
|
||||
actor.spriteGlow = AssembledSpriteAnimation(
|
||||
@@ -189,9 +190,10 @@ object ReadActor {
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPARTGLOW_TO_ENTRY_MAP else null,
|
||||
true
|
||||
true, false
|
||||
)
|
||||
}
|
||||
|
||||
if (animFileEmissive != null) {
|
||||
actor.animDescEmissive = ADProperties(ByteArray64Reader(animFileEmissive.bytes, Common.CHARSET))
|
||||
actor.spriteEmissive = AssembledSpriteAnimation(
|
||||
@@ -199,7 +201,7 @@ object ReadActor {
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPARTEMISSIVE_TO_ENTRY_MAP else null,
|
||||
true
|
||||
false, true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -213,12 +215,58 @@ object ReadActor {
|
||||
actor.reassembleSprite(actor.sprite!!, actor.spriteGlow, heldItem)*/
|
||||
}
|
||||
else if (actor is ActorWithBody && actor is HasAssembledSprite) {
|
||||
if (actor.animDesc != null) actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor, false)
|
||||
if (actor.animDescGlow != null) actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor, true)
|
||||
if (actor.animDescEmissive != null) actor.spriteEmissive = AssembledSpriteAnimation(actor.animDescEmissive!!, actor, true)
|
||||
if (actor.animDesc != null) actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor, false, false)
|
||||
if (actor.animDescGlow != null) actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor, true, false)
|
||||
if (actor.animDescEmissive != null) actor.spriteEmissive = AssembledSpriteAnimation(actor.animDescEmissive!!, actor, false, true)
|
||||
|
||||
//actor.reassembleSprite(actor.sprite, actor.spriteGlow, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeSprite(mode: Int, actor: IngamePlayer, disk: SimpleFileSystem, file: EntryFile?, bodypartsFile: EntryFile?) {
|
||||
val animDesc = when (mode) {
|
||||
0 -> actor.animDesc
|
||||
1 -> actor.animDescGlow
|
||||
2 -> actor.animDescEmissive
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
when (mode) {
|
||||
0 -> { actor.animDesc = ADProperties(ByteArray64Reader(file.bytes, Common.CHARSET)) }
|
||||
1 -> { actor.animDescGlow = ADProperties(ByteArray64Reader(file.bytes, Common.CHARSET)) }
|
||||
2 -> { actor.animDescEmissive = ADProperties(ByteArray64Reader(file.bytes, Common.CHARSET)) }
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
when (mode) {
|
||||
0 -> { actor.sprite = AssembledSpriteAnimation(
|
||||
actor.animDesc!!,
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPART_TO_ENTRY_MAP else null,
|
||||
false, false
|
||||
) }
|
||||
1 -> { actor.spriteGlow = AssembledSpriteAnimation(
|
||||
actor.animDescGlow!!,
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPARTGLOW_TO_ENTRY_MAP else null,
|
||||
true, false
|
||||
) }
|
||||
2 -> { actor.spriteEmissive = AssembledSpriteAnimation(
|
||||
actor.animDescEmissive!!,
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPARTEMISSIVE_TO_ENTRY_MAP else null,
|
||||
false, true
|
||||
) }
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,25 +51,26 @@ object AssembleSheetPixmap {
|
||||
}
|
||||
|
||||
|
||||
private fun drawAndGetCanvas(properties: ADProperties, fileGetter: (String) -> InputStream?, injectedItem: GameItem?): Pixmap {
|
||||
private fun drawAndGetCanvas(properties: ADProperties, fileGetter: (String) -> InputStream?, injectedItem: GameItem?, layerMode: Int): Pixmap {
|
||||
val canvas = Pixmap(properties.cols * (properties.frameWidth), properties.rows * (properties.frameHeight), Pixmap.Format.RGBA8888)
|
||||
canvas.blending = Pixmap.Blending.SourceOver
|
||||
|
||||
// actually draw
|
||||
properties.transforms.forEach { (t, _) ->
|
||||
drawThisFrame(t, canvas, properties, fileGetter, injectedItem)
|
||||
drawThisFrame(t, canvas, properties, fileGetter, injectedItem, layerMode)
|
||||
}
|
||||
|
||||
return canvas
|
||||
}
|
||||
|
||||
fun fromAssetsDir(properties: ADProperties, injectedItem: GameItem?) = drawAndGetCanvas(properties, getAssetsDirFileGetter(properties), injectedItem)
|
||||
fun fromAssetsDir(properties: ADProperties, injectedItem: GameItem?, layerMode: Int) =
|
||||
drawAndGetCanvas(properties, getAssetsDirFileGetter(properties), injectedItem, layerMode)
|
||||
|
||||
fun fromVirtualDisk(disk: SimpleFileSystem, entrynum: Long, properties: ADProperties, injectedItem: GameItem?): Pixmap {
|
||||
fun fromVirtualDisk(disk: SimpleFileSystem, entrynum: Long, properties: ADProperties, injectedItem: GameItem?, layerMode: Int): Pixmap {
|
||||
val bodypartMapping = Properties()
|
||||
bodypartMapping.load(ByteArray64Reader(disk.getFile(entrynum)!!.bytes, Common.CHARSET))
|
||||
|
||||
return drawAndGetCanvas(properties, getVirtualDiskFileGetter(bodypartMapping, disk), injectedItem)
|
||||
return drawAndGetCanvas(properties, getVirtualDiskFileGetter(bodypartMapping, disk), injectedItem, layerMode)
|
||||
}
|
||||
|
||||
fun getPartPixmap(getFile: (String) -> InputStream?, partName: String): Pixmap? {
|
||||
@@ -133,10 +134,11 @@ object AssembleSheetPixmap {
|
||||
}
|
||||
|
||||
fun drawThisFrame(frameName: String,
|
||||
canvas: Pixmap,
|
||||
properties: ADProperties,
|
||||
fileGetter: (String) -> InputStream?,
|
||||
injectedItem: GameItem?
|
||||
canvas: Pixmap,
|
||||
properties: ADProperties,
|
||||
fileGetter: (String) -> InputStream?,
|
||||
injectedItem: GameItem?,
|
||||
layerMode: Int
|
||||
) {
|
||||
val theAnim = properties.getAnimByFrameName(frameName)
|
||||
val skeleton = theAnim.skeleton.joints.reversed()
|
||||
@@ -163,18 +165,29 @@ object AssembleSheetPixmap {
|
||||
|
||||
// AppLoader.printdbg(this, "Frame to draw: $frameName (R$animRow C$animFrame)")
|
||||
|
||||
drawFrame(animRow, animFrame, canvas, properties, bodypartOrigins, bodypartImages, transformList, injectedItem)
|
||||
drawFrame(animRow, animFrame, canvas, properties, bodypartOrigins, bodypartImages, transformList, injectedItem, layerMode)
|
||||
|
||||
bodypartImages.values.forEach { it?.dispose() }
|
||||
}
|
||||
|
||||
private fun getItemImage(layerMode: Int, injectedItem: GameItem?): TextureRegion? {
|
||||
return when (layerMode) {
|
||||
0 -> ItemCodex.getItemImage(injectedItem)
|
||||
1 -> ItemCodex.getItemImageGlow(injectedItem)
|
||||
2 -> ItemCodex.getItemImageEmissive(injectedItem)
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun drawFrame(row: Int, column: Int,
|
||||
canvas: Pixmap,
|
||||
props: ADProperties,
|
||||
bodypartOrigins: HashMap<String, ADPropertyObject.Vector2i>,
|
||||
bodypartImages: Map<String, Pixmap?>,
|
||||
transformList: List<Pair<String, ADPropertyObject.Vector2i>>,
|
||||
injectedItem: GameItem?
|
||||
canvas: Pixmap,
|
||||
props: ADProperties,
|
||||
bodypartOrigins: HashMap<String, ADPropertyObject.Vector2i>,
|
||||
bodypartImages: Map<String, Pixmap?>,
|
||||
transformList: List<Pair<String, ADPropertyObject.Vector2i>>,
|
||||
injectedItem: GameItem?,
|
||||
layerMode: Int
|
||||
) {
|
||||
val tmpFrame = Pixmap(props.frameWidth, props.frameHeight, Pixmap.Format.RGBA8888)
|
||||
|
||||
@@ -182,7 +195,7 @@ object AssembleSheetPixmap {
|
||||
if (name == "HELD_ITEM" && injectedItem != null) {
|
||||
// printdbg(this, "ID of the held item: ${injectedItem.originalID}")
|
||||
|
||||
ItemCodex.getItemImage(injectedItem)?.let { textureRegion ->
|
||||
getItemImage(layerMode, injectedItem)?.let { textureRegion ->
|
||||
// printdbg(this, "and it did have a textureregion")
|
||||
|
||||
val texdata = textureRegion.texture.textureData
|
||||
|
||||
@@ -299,7 +299,7 @@ class SpriteAssemblerPreview: Game() {
|
||||
}
|
||||
|
||||
private fun assembleImage(prop: ADProperties) {
|
||||
image = AssembleSheetPixmap.fromAssetsDir(prop, null)
|
||||
image = AssembleSheetPixmap.fromAssetsDir(prop, null, 0)
|
||||
}
|
||||
|
||||
// TODO rename to requestAssembly
|
||||
|
||||
@@ -11,7 +11,7 @@ class SpriteAssemblerTest {
|
||||
|
||||
operator fun invoke() {
|
||||
val properties = ADProperties(StringReader(ADLParsingTest().TEST_STR))
|
||||
AssembleSheetPixmap.fromAssetsDir(properties, null)
|
||||
AssembleSheetPixmap.fromAssetsDir(properties, null, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,10 +53,13 @@ internal object BlocksDrawer {
|
||||
//val tilesWire: TextureRegionPack
|
||||
val tileItemTerrain: TextureRegionPack
|
||||
val tileItemTerrainGlow: TextureRegionPack
|
||||
val tileItemTerrainEmissive: TextureRegionPack
|
||||
val tileItemWall: TextureRegionPack
|
||||
val tileItemWallGlow: TextureRegionPack
|
||||
val tileItemWallEmissive: TextureRegionPack
|
||||
val tilesFluid: TextureRegionPack
|
||||
val tilesGlow: TextureRegionPack
|
||||
val tilesEmissive: TextureRegionPack
|
||||
|
||||
//val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
|
||||
|
||||
@@ -119,6 +122,7 @@ internal object BlocksDrawer {
|
||||
//tilesWire = TextureRegionPack(ModMgr.getGdxFile("basegame", "wires/wire.tga"), TILE_SIZE, TILE_SIZE)
|
||||
tilesFluid = TextureRegionPack(Texture(App.tileMaker.atlasFluid), TILE_SIZE, TILE_SIZE)
|
||||
tilesGlow = TextureRegionPack(Texture(App.tileMaker.atlasGlow), TILE_SIZE, TILE_SIZE)
|
||||
tilesEmissive = TextureRegionPack(Texture(App.tileMaker.atlasEmissive), TILE_SIZE, TILE_SIZE)
|
||||
|
||||
|
||||
printdbg(this, "Making terrain and wall item textures...")
|
||||
@@ -129,8 +133,10 @@ internal object BlocksDrawer {
|
||||
|
||||
tileItemTerrain = TextureRegionPack(App.tileMaker.itemTerrainTexture, TILE_SIZE, TILE_SIZE)
|
||||
tileItemTerrainGlow = TextureRegionPack(App.tileMaker.itemTerrainTextureGlow, TILE_SIZE, TILE_SIZE)
|
||||
tileItemTerrainEmissive = TextureRegionPack(App.tileMaker.itemTerrainTextureEmissive, TILE_SIZE, TILE_SIZE)
|
||||
tileItemWall = TextureRegionPack(App.tileMaker.itemWallTexture, TILE_SIZE, TILE_SIZE)
|
||||
tileItemWallGlow = TextureRegionPack(App.tileMaker.itemWallTextureGlow, TILE_SIZE, TILE_SIZE)
|
||||
tileItemWallEmissive = TextureRegionPack(App.tileMaker.itemWallTextureEmissive, TILE_SIZE, TILE_SIZE)
|
||||
|
||||
|
||||
// val texdata = tileItemTerrain.texture.textureData
|
||||
@@ -217,28 +223,28 @@ internal object BlocksDrawer {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun drawWall(projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean = false) {
|
||||
internal fun drawWall(projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean = false) {
|
||||
gdxBlendNormalStraightAlpha()
|
||||
renderUsingBuffer(WALL, projectionMatrix, drawGlow, drawBlack)
|
||||
renderUsingBuffer(WALL, projectionMatrix, drawGlow, drawEmissive)
|
||||
|
||||
gdxBlendMul()
|
||||
renderUsingBuffer(OCCLUSION, projectionMatrix, false, drawBlack)
|
||||
renderUsingBuffer(OCCLUSION, projectionMatrix, false, drawEmissive)
|
||||
}
|
||||
|
||||
internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean = false) {
|
||||
internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean = false) {
|
||||
gdxBlendNormalStraightAlpha()
|
||||
|
||||
renderUsingBuffer(TERRAIN, projectionMatrix, drawGlow, drawBlack)
|
||||
renderUsingBuffer(ORES, projectionMatrix, drawGlow, drawBlack)
|
||||
renderUsingBuffer(FLUID, projectionMatrix, drawGlow, drawBlack)
|
||||
renderUsingBuffer(TERRAIN, projectionMatrix, drawGlow, drawEmissive)
|
||||
renderUsingBuffer(ORES, projectionMatrix, drawGlow, drawEmissive)
|
||||
renderUsingBuffer(FLUID, projectionMatrix, drawGlow, drawEmissive)
|
||||
}
|
||||
|
||||
|
||||
internal fun drawFront(projectionMatrix: Matrix4, drawBlack: Boolean = false) {
|
||||
internal fun drawFront(projectionMatrix: Matrix4, drawEmissive: Boolean = false) {
|
||||
gdxBlendMul()
|
||||
|
||||
// let's just not MUL on terrain, make it FLUID only...
|
||||
renderUsingBuffer(FLUID, projectionMatrix, false, drawBlack)
|
||||
renderUsingBuffer(FLUID, projectionMatrix, false, drawEmissive)
|
||||
|
||||
|
||||
|
||||
@@ -708,7 +714,7 @@ internal object BlocksDrawer {
|
||||
private var _tilesBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
||||
private val occlusionIntensity = 0.22222222f // too low value and dark-coloured walls won't darken enough
|
||||
|
||||
private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean) {
|
||||
private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean) {
|
||||
//Gdx.gl.glClearColor(.094f, .094f, .094f, 0f)
|
||||
//Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
|
||||
@@ -732,7 +738,7 @@ internal object BlocksDrawer {
|
||||
OCCLUSION -> occlusionBuffer
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
val vertexColour = if (drawBlack) Color.BLACK else when (mode) {
|
||||
val vertexColour = when (mode) {
|
||||
TERRAIN, /*WIRE,*/ ORES, FLUID, OCCLUSION -> Color.WHITE
|
||||
WALL -> WALL_OVERLAY_COLOUR
|
||||
else -> throw IllegalArgumentException()
|
||||
@@ -754,7 +760,12 @@ internal object BlocksDrawer {
|
||||
_tilesBufferAsTex = Texture(tilesBuffer)
|
||||
_tilesBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||
|
||||
if (drawGlow) {
|
||||
if (drawEmissive) {
|
||||
tilesEmissive.texture.bind(2)
|
||||
_tilesBufferAsTex.bind(1) // trying 1 and 0...
|
||||
tilesEmissive.texture.bind(0) // for some fuck reason, it must be bound as last
|
||||
}
|
||||
else if (drawGlow) {
|
||||
tilesGlow.texture.bind(2)
|
||||
_tilesBufferAsTex.bind(1) // trying 1 and 0...
|
||||
tilesGlow.texture.bind(0) // for some fuck reason, it must be bound as last
|
||||
@@ -880,11 +891,13 @@ internal object BlocksDrawer {
|
||||
|
||||
weatherTerrains.forEach { it.dispose() }
|
||||
tilesGlow.dispose()
|
||||
//tilesWire.dispose()
|
||||
tilesEmissive.dispose()
|
||||
tileItemTerrain.dispose()
|
||||
tileItemTerrainGlow.dispose()
|
||||
tileItemTerrainEmissive.dispose()
|
||||
tileItemWall.dispose()
|
||||
tileItemWallGlow.dispose()
|
||||
tileItemWallEmissive.dispose()
|
||||
tilesFluid.dispose()
|
||||
tilesBuffer.dispose()
|
||||
_tilesBufferAsTex.dispose()
|
||||
|
||||
@@ -11,13 +11,10 @@ import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.utils.HashArray
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.AtlasSource.*
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.RenderTag.Companion.MASK_47
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/**
|
||||
@@ -51,10 +48,13 @@ class CreateTileAtlas {
|
||||
lateinit var atlasHibernal: Pixmap
|
||||
lateinit var atlasFluid: Pixmap
|
||||
lateinit var atlasGlow: Pixmap // glowing won't be affected by the season... for now
|
||||
lateinit var atlasEmissive: Pixmap // glowing won't be affected by the season... for now
|
||||
lateinit var itemTerrainTexture: Texture
|
||||
lateinit var itemTerrainTextureGlow: Texture
|
||||
lateinit var itemTerrainTextureEmissive: Texture
|
||||
lateinit var itemWallTexture: Texture
|
||||
lateinit var itemWallTextureGlow: Texture
|
||||
lateinit var itemWallTextureEmissive: Texture
|
||||
lateinit var terrainTileColourMap: HashMap<ItemID, Cvec>
|
||||
lateinit var tags: HashMap<ItemID, RenderTag> // TileID, RenderTag
|
||||
private set
|
||||
@@ -76,8 +76,10 @@ class CreateTileAtlas {
|
||||
|
||||
internal lateinit var itemTerrainPixmap: Pixmap
|
||||
internal lateinit var itemTerrainPixmapGlow: Pixmap
|
||||
internal lateinit var itemTerrainPixmapEmissive: Pixmap
|
||||
internal lateinit var itemWallPixmap: Pixmap
|
||||
internal lateinit var itemWallPixmapGlow: Pixmap
|
||||
internal lateinit var itemWallPixmapEmissive: Pixmap
|
||||
|
||||
val atlas: Pixmap
|
||||
get() = atlasVernal
|
||||
@@ -145,6 +147,7 @@ class CreateTileAtlas {
|
||||
atlasHibernal = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasFluid = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasEmissive = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
|
||||
// populate the atlantes with atlasInit
|
||||
// this just directly copies the image to the atlantes :p
|
||||
@@ -203,7 +206,15 @@ class CreateTileAtlas {
|
||||
val glowFile = Gdx.files.internal(
|
||||
filehandle.path().dropLast(4) + "_glow.tga"
|
||||
) // assuming strict ".tga" file for now...
|
||||
fileToAtlantes(modname, filehandle, if (glowFile.exists()) glowFile else null, if (dirName == "blocks") null else dirName)
|
||||
val emissiveFile = Gdx.files.internal(
|
||||
filehandle.path().dropLast(4) + "_emsv.tga"
|
||||
) // assuming strict ".tga" file for now...
|
||||
fileToAtlantes(
|
||||
modname, filehandle,
|
||||
if (glowFile.exists()) glowFile else null,
|
||||
if (emissiveFile.exists()) emissiveFile else null,
|
||||
if (dirName == "blocks") null else dirName
|
||||
)
|
||||
}
|
||||
catch (e: GdxRuntimeException) {
|
||||
System.err.println("Couldn't load file $filehandle from $modname, skipping...")
|
||||
@@ -240,8 +251,10 @@ class CreateTileAtlas {
|
||||
|
||||
itemTerrainPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemTerrainPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemTerrainPixmapEmissive = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemWallPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemWallPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemWallPixmapEmissive = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
|
||||
tags.toMap().forEach { id, tag ->
|
||||
val tilePosFromAtlas = tag.tileNumber + maskTypetoTileIDForItemImage(tag.maskType)
|
||||
@@ -252,8 +265,10 @@ class CreateTileAtlas {
|
||||
val destY = (t / TILES_IN_X) * TILE_SIZE
|
||||
itemTerrainPixmap.drawPixmap(atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
itemTerrainPixmapGlow.drawPixmap(atlasGlow, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
itemTerrainPixmapEmissive.drawPixmap(atlasEmissive, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
itemWallPixmap.drawPixmap(atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
itemWallPixmapGlow.drawPixmap(atlasGlow, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
itemWallPixmapEmissive.drawPixmap(atlasEmissive, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
|
||||
}
|
||||
// darken things for the wall
|
||||
for (y in 0 until itemWallPixmap.height) {
|
||||
@@ -262,6 +277,8 @@ class CreateTileAtlas {
|
||||
itemWallPixmap.drawPixel(x, y, c1)
|
||||
val c2 = Color(itemWallPixmapGlow.getPixel(x, y)).mulAndAssign(WALL_OVERLAY_COLOUR).toRGBA()
|
||||
itemWallPixmapGlow.drawPixel(x, y, c2)
|
||||
val c3 = Color(itemWallPixmapEmissive.getPixel(x, y)).mulAndAssign(WALL_OVERLAY_COLOUR).toRGBA()
|
||||
itemWallPixmapEmissive.drawPixel(x, y, c3)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,8 +312,10 @@ class CreateTileAtlas {
|
||||
|
||||
itemTerrainTexture = Texture(itemTerrainPixmap)
|
||||
itemTerrainTextureGlow = Texture(itemTerrainPixmapGlow)
|
||||
itemTerrainTextureEmissive = Texture(itemTerrainPixmapEmissive)
|
||||
itemWallTexture = Texture(itemWallPixmap)
|
||||
itemWallTextureGlow = Texture(itemWallPixmapGlow)
|
||||
itemWallTextureEmissive = Texture(itemWallPixmapEmissive)
|
||||
// itemTerrainPixmap.dispose()
|
||||
// itemWallPixmap.dispose()
|
||||
|
||||
@@ -314,10 +333,11 @@ class CreateTileAtlas {
|
||||
|
||||
val nullTile = Pixmap(TILE_SIZE * 16, TILE_SIZE * 16, Pixmap.Format.RGBA8888)
|
||||
|
||||
private fun fileToAtlantes(modname: String, matte: FileHandle, glow: FileHandle?, mode: String?) {
|
||||
val tilesPixmap = Pixmap(matte)
|
||||
private fun fileToAtlantes(modname: String, diffuse: FileHandle, glow: FileHandle?, emissive: FileHandle?, mode: String?) {
|
||||
val tilesPixmap = Pixmap(diffuse)
|
||||
val tilesGlowPixmap = if (glow != null) Pixmap(glow) else nullTile
|
||||
val blockName = matte.nameWithoutExtension().split('-').last().toInt() // basically a filename
|
||||
val tilesEmissivePixmap = if (emissive != null) Pixmap(emissive) else nullTile
|
||||
val blockName = diffuse.nameWithoutExtension().split('-').last().toInt() // basically a filename
|
||||
val blockID = if (mode != null) "$mode@$modname:$blockName" else "$modname:$blockName"
|
||||
|
||||
|
||||
@@ -325,37 +345,37 @@ class CreateTileAtlas {
|
||||
// predefined by the image dimension: 16x16 for (1,0)
|
||||
if (tilesPixmap.width == TILE_SIZE && tilesPixmap.height == TILE_SIZE) {
|
||||
addTag(blockID, RenderTag.CONNECT_SELF, RenderTag.MASK_NA)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_NA)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_NA)
|
||||
}
|
||||
// predefined by the image dimension: 64x16 for (2,3)
|
||||
else if (tilesPixmap.width == TILE_SIZE * 4 && tilesPixmap.height == TILE_SIZE) {
|
||||
addTag(blockID, RenderTag.CONNECT_WALL_STICKER, RenderTag.MASK_TORCH)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_TORCH)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_TORCH)
|
||||
}
|
||||
// predefined by the image dimension: 128x16 for (3,4)
|
||||
else if (tilesPixmap.width == TILE_SIZE * 8 && tilesPixmap.height == TILE_SIZE) {
|
||||
addTag(blockID, RenderTag.CONNECT_WALL_STICKER_CONNECT_SELF, RenderTag.MASK_PLATFORM)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_PLATFORM)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_PLATFORM)
|
||||
}
|
||||
// predefined by the image dimension: 256x16
|
||||
else if (tilesPixmap.width == TILE_SIZE * 16 && tilesPixmap.height == TILE_SIZE) {
|
||||
addTag(blockID, RenderTag.CONNECT_SELF, RenderTag.MASK_16)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_16)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_16)
|
||||
}
|
||||
// predefined by the image dimension: 256x64
|
||||
else if (tilesPixmap.width == TILE_SIZE * 16 && tilesPixmap.height == TILE_SIZE * 4) {
|
||||
addTag(blockID, RenderTag.CONNECT_SELF, RenderTag.MASK_16X4)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_16X4)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_16X4)
|
||||
}
|
||||
// predefined by the image dimension: 256x256
|
||||
else if (tilesPixmap.width == TILE_SIZE * 16 && tilesPixmap.height == TILE_SIZE * 16) {
|
||||
addTag(blockID, RenderTag.CONNECT_SELF, RenderTag.MASK_16X16)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, RenderTag.MASK_16X16)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, RenderTag.MASK_16X16)
|
||||
}
|
||||
// 112x112 or 224x224
|
||||
else {
|
||||
if (tilesPixmap.width != tilesPixmap.height && tilesPixmap.width % (7 * TILE_SIZE) >= 2) {
|
||||
throw IllegalArgumentException("Unrecognized image dimension ${tilesPixmap.width}x${tilesPixmap.height} from $modname:${matte.name()}")
|
||||
throw IllegalArgumentException("Unrecognized image dimension ${tilesPixmap.width}x${tilesPixmap.height} from $modname:${diffuse.name()}")
|
||||
}
|
||||
// figure out the tags
|
||||
var connectionType = 0
|
||||
@@ -371,7 +391,7 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
addTag(blockID, connectionType, maskType)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, maskType)
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, maskType)
|
||||
}
|
||||
|
||||
itemSheetNumbers[blockID] = itemSheetCursor
|
||||
@@ -400,7 +420,7 @@ class CreateTileAtlas {
|
||||
printdbg(this, "tileName ${id} ->> tileNumber ${atlasCursor}")
|
||||
}
|
||||
|
||||
private fun drawToAtlantes(matte: Pixmap, glow: Pixmap, renderMask: Int) {
|
||||
private fun drawToAtlantes(diffuse: Pixmap, glow: Pixmap, emissive: Pixmap, renderMask: Int) {
|
||||
val tilesCount = RenderTag.maskTypeToTileCount(renderMask)
|
||||
if (atlasCursor + tilesCount >= TOTAL_TILES) {
|
||||
// throw Error("Too much tiles for $MAX_TEX_SIZE texture size: $atlasCursor")
|
||||
@@ -408,30 +428,33 @@ class CreateTileAtlas {
|
||||
expandAtlantes()
|
||||
}
|
||||
|
||||
val sixSeasonal = matte.width == 21 * TILE_SIZE && matte.height == 14 * TILE_SIZE
|
||||
val txOfPixmap = matte.width / TILE_SIZE
|
||||
val sixSeasonal = diffuse.width == 21 * TILE_SIZE && diffuse.height == 14 * TILE_SIZE
|
||||
val txOfPixmap = diffuse.width / TILE_SIZE
|
||||
val txOfPixmapGlow = glow.width / TILE_SIZE
|
||||
val txOfPixmapEmissive = emissive.width / TILE_SIZE
|
||||
for (i in 0 until tilesCount) {
|
||||
//printdbg(this, "Rendering to atlas, tile# $atlasCursor, tilesCount = $tilesCount, seasonal = $seasonal")
|
||||
|
||||
// different texture for different seasons (224x224)
|
||||
if (sixSeasonal) {
|
||||
val i = if (renderMask == MASK_47) (if (i < 41) i else i + 1) else i // to compensate the discontinuity between 40th and 41st tile
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 , i / 7, PREVERNAL)
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 + 7 , i / 7, VERNAL)
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 + 14, i / 7, AESTIVAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 , i / 7, PREVERNAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 + 7 , i / 7, VERNAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 + 14, i / 7, AESTIVAL)
|
||||
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 + 14, i / 7 + 7, SEROTINAL)
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 + 7 , i / 7 + 7, AUTUMNAL)
|
||||
_drawToAtlantes(matte, atlasCursor, i % 7 , i / 7 + 7, HIBERNAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 + 14, i / 7 + 7, SEROTINAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 + 7 , i / 7 + 7, AUTUMNAL)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % 7 , i / 7 + 7, HIBERNAL)
|
||||
|
||||
_drawToAtlantes(glow, atlasCursor, i % 7, i / 7, GLOW)
|
||||
_drawToAtlantes(emissive, atlasCursor, i % 7, i / 7, EMISSIVE)
|
||||
atlasCursor += 1
|
||||
}
|
||||
else {
|
||||
val i = if (renderMask == MASK_47) (if (i < 41) i else i + 1) else i // to compensate the discontinuity between 40th and 41st tile
|
||||
_drawToAtlantes(matte, atlasCursor, i % txOfPixmap, i / txOfPixmap, SIX_SEASONS)
|
||||
_drawToAtlantes(diffuse, atlasCursor, i % txOfPixmap, i / txOfPixmap, SIX_SEASONS)
|
||||
_drawToAtlantes(glow, atlasCursor, i % txOfPixmapGlow, i / txOfPixmapGlow, GLOW)
|
||||
_drawToAtlantes(emissive, atlasCursor, i % txOfPixmapGlow, i / txOfPixmapGlow, EMISSIVE)
|
||||
atlasCursor += 1
|
||||
}
|
||||
}
|
||||
@@ -466,6 +489,7 @@ class CreateTileAtlas {
|
||||
HIBERNAL -> atlasHibernal.drawPixmap(pixmap, sourceX, sourceY, TILE_SIZE, TILE_SIZE, atlasX, atlasY, TILE_SIZE, TILE_SIZE)
|
||||
FLUID -> atlasFluid.drawPixmap(pixmap, sourceX, sourceY, TILE_SIZE, TILE_SIZE, atlasX, atlasY, TILE_SIZE, TILE_SIZE)
|
||||
GLOW -> atlasGlow.drawPixmap(pixmap, sourceX, sourceY, TILE_SIZE, TILE_SIZE, atlasX, atlasY, TILE_SIZE, TILE_SIZE)
|
||||
EMISSIVE -> atlasEmissive.drawPixmap(pixmap, sourceX, sourceY, TILE_SIZE, TILE_SIZE, atlasX, atlasY, TILE_SIZE, TILE_SIZE)
|
||||
else -> throw IllegalArgumentException("Unknown draw source $source")
|
||||
}
|
||||
}
|
||||
@@ -511,6 +535,7 @@ class CreateTileAtlas {
|
||||
atlasHibernal.dispose()
|
||||
atlasFluid.dispose()
|
||||
atlasGlow.dispose()
|
||||
atlasEmissive.dispose()
|
||||
//itemTerrainTexture.dispose() //BlocksDrawer will dispose of it as it disposes of 'tileItemTerrain (TextureRegionPack)'
|
||||
//itemTerrainTextureGlow.dispose() //BlocksDrawer will dispose of it as it disposes of 'tileItemTerrain (TextureRegionPack)'
|
||||
//itemWallTexture.dispose() //BlocksDrawer will dispose of it as it disposes of 'tileItemWall (TextureRegionPack)'
|
||||
@@ -522,7 +547,7 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
private enum class AtlasSource {
|
||||
/*FOUR_SEASONS, SUMMER, AUTUMN, WINTER, SPRING,*/ FLUID, GLOW,
|
||||
/*FOUR_SEASONS, SUMMER, AUTUMN, WINTER, SPRING,*/ FLUID, GLOW, EMISSIVE,
|
||||
SIX_SEASONS, PREVERNAL, VERNAL, AESTIVAL, SEROTINAL, AUTUMNAL, HIBERNAL,
|
||||
}
|
||||
|
||||
@@ -541,13 +566,13 @@ class CreateTileAtlas {
|
||||
TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
|
||||
|
||||
val newAtlantes = Array(7) {
|
||||
val newAtlantes = Array(8) {
|
||||
Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also {
|
||||
it.blending = Pixmap.Blending.None
|
||||
it.filter = Pixmap.Filter.NearestNeighbour
|
||||
}
|
||||
}
|
||||
listOf(atlasPrevernal, atlasVernal, atlasAestival, atlasSerotinal, atlasAutumnal, atlasHibernal, atlasGlow).forEachIndexed { index, pixmap ->
|
||||
listOf(atlasPrevernal, atlasVernal, atlasAestival, atlasSerotinal, atlasAutumnal, atlasHibernal, atlasGlow, atlasEmissive).forEachIndexed { index, pixmap ->
|
||||
/*
|
||||
How it works:
|
||||
|
||||
@@ -579,6 +604,7 @@ class CreateTileAtlas {
|
||||
atlasAutumnal = newAtlantes[4]
|
||||
atlasHibernal = newAtlantes[5]
|
||||
atlasGlow = newAtlantes[6]
|
||||
atlasEmissive = newAtlantes[7]
|
||||
|
||||
|
||||
App.setConfig("atlastexsize", newTexSize)
|
||||
|
||||
Reference in New Issue
Block a user