mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
35 Commits
v0.3.2-hot
...
v0.3.3-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97a7a36030 | ||
|
|
662069466a | ||
|
|
52cff00338 | ||
|
|
1a40334f8e | ||
|
|
763f512419 | ||
|
|
620a1c6956 | ||
|
|
5f4fcdba69 | ||
|
|
7a79f444b2 | ||
|
|
e4b947ce69 | ||
|
|
fdfec960ca | ||
|
|
75021ecfa2 | ||
|
|
c90ef21bfa | ||
|
|
3fce5d7e95 | ||
|
|
8db1228e70 | ||
|
|
5f7f724058 | ||
|
|
fab4179068 | ||
|
|
32803b6f18 | ||
|
|
f8f75fb7b6 | ||
|
|
9919a99032 | ||
|
|
6a43d1a5bd | ||
|
|
24c971e4b8 | ||
|
|
62f0fd7c68 | ||
|
|
3dec312989 | ||
|
|
77b51a45dd | ||
|
|
d1b4ce3404 | ||
|
|
fd7b88307c | ||
|
|
579b6b5b29 | ||
|
|
cef58f6a73 | ||
|
|
c0c98c3b80 | ||
|
|
88d844cc09 | ||
|
|
2411db17a7 | ||
|
|
53d372be38 | ||
|
|
88831051c8 | ||
|
|
87d92ecb74 | ||
|
|
6672dffdbc |
@@ -1,26 +1,17 @@
|
||||
package net.torvald.terrarum.modulecomputers.gameactors
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import kotlin.coroutines.*
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.BlockBox
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.modulecomputers.ui.UIHomeComputer
|
||||
import net.torvald.tsvm.*
|
||||
import net.torvald.tsvm.peripheral.AdapterConfig
|
||||
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||
import net.torvald.tsvm.peripheral.VMProgramRom
|
||||
import net.torvald.unicode.*
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2021-12-04.
|
||||
@@ -131,77 +122,3 @@ class FixtureHomeComputer : FixtureBase {
|
||||
}
|
||||
}
|
||||
|
||||
internal class UIHomeComputer : UICanvas(
|
||||
toggleKeyLiteral = Input.Keys.ESCAPE, // FIXME why do I have specify ESC for it to function? ESC should be work as the default key
|
||||
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
||||
) {
|
||||
override var width = 640
|
||||
override var height = 480
|
||||
override var openCloseTime = 0f
|
||||
|
||||
private val drawOffX = (width - 560).div(2).toFloat()
|
||||
private val drawOffY = (height - 448).div(2).toFloat()
|
||||
|
||||
private var batch: FlippingSpriteBatch
|
||||
private var camera: OrthographicCamera
|
||||
|
||||
internal lateinit var vm: VM
|
||||
internal lateinit var fixture: FixtureHomeComputer
|
||||
|
||||
init {
|
||||
batch = FlippingSpriteBatch()
|
||||
camera = OrthographicCamera(width.toFloat(), height.toFloat())
|
||||
//val m = Matrix4()
|
||||
//m.setToOrtho2D(0f, 0f, width.toFloat(), height.toFloat())
|
||||
batch.projectionMatrix = camera.combined
|
||||
}
|
||||
|
||||
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
||||
|
||||
private val controlHelp =
|
||||
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_T$KEYCAP_R Terminate\u3000" +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_S Reset\u3000" +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_Q SysRq"
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
}
|
||||
|
||||
override fun renderUI(otherBatch: SpriteBatch, otherCamera: Camera) {
|
||||
otherBatch.end()
|
||||
|
||||
fbo.inAction(camera, batch) {
|
||||
Gdx.gl.glClearColor(0f,0f,0f,1f)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) // to hide the crap might be there
|
||||
|
||||
(vm.peripheralTable[1].peripheral as? GraphicsAdapter)?.let { gpu ->
|
||||
val clearCol = gpu.getBackgroundColour()
|
||||
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
|
||||
gpu.render(Gdx.graphics.deltaTime, batch, drawOffX, drawOffY, true, fbo) // gpu.render will internally end() the fbo then begin() again before using the batch I've fed in
|
||||
}
|
||||
}
|
||||
|
||||
otherBatch.begin()
|
||||
otherBatch.shader = null
|
||||
blendNormalStraightAlpha(otherBatch)
|
||||
otherBatch.color = Color.WHITE
|
||||
otherBatch.draw(fbo.colorBufferTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
|
||||
otherBatch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(otherBatch, posX - 1, posY - 1, width + 2, height + 2)
|
||||
|
||||
App.fontGame.draw(otherBatch, controlHelp, posX, posY + height + 4)
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
fixture.startVM()
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package net.torvald.terrarum.modulecomputers.ui
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.FlippingSpriteBatch
|
||||
import net.torvald.terrarum.blendNormalStraightAlpha
|
||||
import net.torvald.terrarum.inAction
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulecomputers.gameactors.FixtureHomeComputer
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.tsvm.VM
|
||||
import net.torvald.tsvm.peripheral.GraphicsAdapter
|
||||
import net.torvald.unicode.*
|
||||
|
||||
internal class UIHomeComputer : UICanvas(
|
||||
toggleKeyLiteral = Input.Keys.ESCAPE, // FIXME why do I have specify ESC for it to function? ESC should be work as the default key
|
||||
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
||||
) {
|
||||
override var width = 640
|
||||
override var height = 480
|
||||
override var openCloseTime = 0f
|
||||
|
||||
private val drawOffX = (width - 560).div(2).toFloat()
|
||||
private val drawOffY = (height - 448).div(2).toFloat()
|
||||
|
||||
private var batch: FlippingSpriteBatch
|
||||
private var camera: OrthographicCamera
|
||||
|
||||
internal lateinit var vm: VM
|
||||
internal lateinit var fixture: FixtureHomeComputer
|
||||
|
||||
init {
|
||||
batch = FlippingSpriteBatch()
|
||||
camera = OrthographicCamera(width.toFloat(), height.toFloat())
|
||||
//val m = Matrix4()
|
||||
//m.setToOrtho2D(0f, 0f, width.toFloat(), height.toFloat())
|
||||
batch.projectionMatrix = camera.combined
|
||||
}
|
||||
|
||||
private val fbo = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
|
||||
|
||||
private val controlHelp =
|
||||
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_T$KEYCAP_R Terminate\u3000" +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_S Reset\u3000" +
|
||||
"$KEYCAP_CTRL$KEYCAP_SHIFT$KEYCAP_R$KEYCAP_Q SysRq"
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
}
|
||||
|
||||
override fun renderUI(otherBatch: SpriteBatch, otherCamera: Camera) {
|
||||
otherBatch.end()
|
||||
|
||||
fbo.inAction(camera, batch) {
|
||||
Gdx.gl.glClearColor(0f,0f,0f,1f)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) // to hide the crap might be there
|
||||
|
||||
(vm.peripheralTable[1].peripheral as? GraphicsAdapter)?.let { gpu ->
|
||||
val clearCol = gpu.getBackgroundColour()
|
||||
Gdx.gl.glClearColor(clearCol.r, clearCol.g, clearCol.b, clearCol.a)
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
|
||||
gpu.render(Gdx.graphics.deltaTime, batch, drawOffX, drawOffY, true, fbo) // gpu.render will internally end() the fbo then begin() again before using the batch I've fed in
|
||||
}
|
||||
}
|
||||
|
||||
otherBatch.begin()
|
||||
otherBatch.shader = null
|
||||
blendNormalStraightAlpha(otherBatch)
|
||||
otherBatch.color = Color.WHITE
|
||||
otherBatch.draw(fbo.colorBufferTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat())
|
||||
otherBatch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(otherBatch, posX - 1, posY - 1, width + 2, height + 2)
|
||||
|
||||
App.fontGame.draw(otherBatch, controlHelp, posX, posY + height + 4)
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
fixture.startVM()
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
fbo.dispose()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
"MENU_LABEL_STREAMING": "Livestreaming",
|
||||
"MENU_LABEL_SYSTEM_INFO": "System Info",
|
||||
"MENU_MODULES" : "Modules",
|
||||
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "Atlas Texture Size",
|
||||
"MENU_OPTIONS_AUTOSAVE": "Autosave",
|
||||
"MENU_OPTIONS_BLUR": "Blur",
|
||||
"MENU_OPTIONS_DEBUG_CONSOLE": "Debug Console",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"MENU_LABEL_STREAMING": "실시간 방송",
|
||||
"MENU_LABEL_SYSTEM_INFO": "시스템 정보",
|
||||
"MENU_MODULES" : "모듈",
|
||||
"MENU_OPTIONS_ATLAS_TEXTURE_SIZE": "아틀라스 텍스처 크기",
|
||||
"MENU_OPTIONS_AUTOSAVE": "자동 저장",
|
||||
"MENU_OPTIONS_BLUR": "흐림",
|
||||
"MENU_OPTIONS_DEBUG_CONSOLE": "디버그 콘솔",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"id";"drop";"spawn";"name";"shdr";"shdg";"shdb";"shduv";"str";"dsty";"mate";"solid";"wall";"grav";"dlfn";"fv";"fr";"lumr";"lumg";"lumb";"lumuv";"colour";"vscs";"refl";"tags"
|
||||
"0";"0";"0";"BLOCK_AIR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1";"NULL";"0";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";""
|
||||
"0";"0";"0";"BLOCK_AIR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1";"NULL";"0";"1";"N/A";"0";"0";"4";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"INCONSEQUENTIAL"
|
||||
"16";"17";"17";"BLOCK_STONE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL"
|
||||
"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK"
|
||||
"18";"18";"18";"BLOCK_STONE_TILE_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.18";"STONE"
|
||||
@@ -188,6 +188,7 @@
|
||||
## Some tags are reserved for internal use, which are:
|
||||
## - INTERNAL: denotes that the tile is internal-use. Will not be rendered unless debug window is on.
|
||||
## - DORENDER: this internal tile must go through the standard-issue tile drawing routine.
|
||||
## - INCONSEQUENTIAL: denotes that this tile can be overwritten without dropping it. Usually used with flower tiles.
|
||||
#
|
||||
#
|
||||
## References ##
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 179 and column 37.
|
@@ -8,6 +8,7 @@ id;classname
|
||||
8;net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter
|
||||
9;net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
|
||||
10;net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter
|
||||
11;net.torvald.terrarum.modulebasegame.gameitems.ItemWallCalendar
|
||||
|
||||
256;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorOak
|
||||
257;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorEbony
|
||||
|
||||
|
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"GAME_ITEM_CALENDAR": "Calendar",
|
||||
"MENU_CALENDAR_CALENDAR": "Calendar",
|
||||
"MENU_CALENDAR_EVENTS": "Events",
|
||||
"MENU_CALENDAR_ADD_NEW_EVENT": "Add New Event…",
|
||||
"MENU_CALENDAR_ADD_NEW_EVENT": "Add New Event",
|
||||
"CONTEXT_CALENDAR_SEASON_SPRING": "Spring",
|
||||
"CONTEXT_CALENDAR_SEASON_SUMMER": "Summer",
|
||||
"CONTEXT_CALENDAR_SEASON_AUTUMN": "Autumn",
|
||||
@@ -11,6 +10,9 @@
|
||||
"CONTEXT_CALENDAR_SEASON_SUMM": "Summ",
|
||||
"CONTEXT_CALENDAR_SEASON_AUTM": "Autm",
|
||||
"CONTEXT_CALENDAR_SEASON_WINT": "Wint",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_Y": "Year {0}",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_YMD": "Year {0} {1} {2}",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_DDD": "Year {0} {1} {2} {3}",
|
||||
|
||||
"CONTEXT_CALENDAR_DAY_MONDAG_DNT": "Mondag",
|
||||
"CONTEXT_CALENDAR_DAY_TYSDAG_DNT": "Tysdag",
|
||||
@@ -27,5 +29,6 @@
|
||||
"CONTEXT_CALENDAR_DAY_FRE_DNT": "Fre",
|
||||
"CONTEXT_CALENDAR_DAY_LAU_DNT": "Lau",
|
||||
"CONTEXT_CALENDAR_DAY_SUN_DNT": "Sun",
|
||||
"CONTEXT_CALENDAR_DAY_VER_DNT": "Ver"
|
||||
"CONTEXT_CALENDAR_DAY_VER_DNT": "Ver",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_SHORT_DNT": "ɣ{0}-{1}-{2}"
|
||||
}
|
||||
@@ -1,23 +1,24 @@
|
||||
{
|
||||
"CONTEXT_GENERATOR_SEED": "Seed",
|
||||
"CONTEXT_ITEM_MAP": "Map",
|
||||
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
|
||||
"CONTEXT_PLACE_COORDINATE": "Coordinate",
|
||||
"CONTEXT_WORLD_COUNT": "Worlds: ",
|
||||
"CONTEXT_WORLD_NEW": "New World",
|
||||
"MENU_LABEL_DELETE_WORLD": "Delete World",
|
||||
"CONTEXT_WORLD_COUNT": "Worlds: ",
|
||||
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
|
||||
"GAME_INVENTORY_POTIONS": "Potions",
|
||||
"GAME_INVENTORY_BLOCKS": "Blocks",
|
||||
"GAME_INVENTORY_WALLS": "Walls",
|
||||
"CONTEXT_ITEM_TOOL_PLURAL": "Tools",
|
||||
"GAME_INVENTORY_FAVORITES": "Favorites",
|
||||
"GAME_INVENTORY_REGISTER": "Register",
|
||||
"CONTEXT_ITEM_MAP": "Map",
|
||||
"MENU_LABEL_MENU": "Menu",
|
||||
"CONTEXT_GENERATOR_SEED": "Seed",
|
||||
"MENU_LABEL_PREV_SAVES": "Previous Saves",
|
||||
"MENU_LABEL_RENAME": "Rename",
|
||||
"GAME_ACTION_CRAFT": "Craft",
|
||||
"GAME_ACTION_GRAPPLE": "Grapple",
|
||||
"GAME_ACTION_QUICKSEL": "Quick Select",
|
||||
"GAME_ACTION_CRAFT": "Craft",
|
||||
"GAME_CRAFTING": "Crafting",
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"MENU_LABEL_RENAME": "Rename",
|
||||
"GAME_ACTION_TELEPORT": "Teleport",
|
||||
"CONTEXT_PLACE_COORDINATE": "Coordinate"
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"GAME_CRAFTING": "Crafting",
|
||||
"GAME_INVENTORY_BLOCKS": "Blocks",
|
||||
"GAME_INVENTORY_FAVORITES": "Favorites",
|
||||
"GAME_INVENTORY_INGREDIENTS": "Ingredients",
|
||||
"GAME_INVENTORY_POTIONS": "Potions",
|
||||
"GAME_INVENTORY_REGISTER": "Register",
|
||||
"GAME_INVENTORY_WALLS": "Walls"
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
{
|
||||
"BLOCK_STONE_DEEP": "Deepstone",
|
||||
"BLOCK_SCAFFOLDING_NORMAL": "Scaffolding",
|
||||
"BLOCK_STONE_MARBLE": "Marble",
|
||||
|
||||
"ITEM_CALENDAR": "Calendar",
|
||||
"ITEM_LOGIC_SIGNAL_EMITTER": "Logic Signal Emitter",
|
||||
"ITEM_STORAGE_CHEST": "Storage Chest",
|
||||
"ITEM_TIKI_TORCH": "Tiki Torch",
|
||||
"ITEM_TYPEWRITER": "Typewriter",
|
||||
"ITEM_WIRE": "Wire",
|
||||
"ITEM_WIRE_CUTTER": "Wire Cutter",
|
||||
|
||||
"ACTORBLOCK_ALLOW_MOVE_DOWN": "Urist Arôlcustith",
|
||||
"ACTORBLOCK_FULL_COLLISION": "Urist Berdanrifot",
|
||||
"ACTORBLOCK_NO_COLLISION": "Urist Zafal",
|
||||
"ACTORBLOCK_NO_PASS_RIGHT": "Urist McPassLeft",
|
||||
"ACTORBLOCK_NO_PASS_LEFT": "Urist McPassRight",
|
||||
"ACTORBLOCK_TILING_PLACEHOLDER": "Urist Berdanurdim",
|
||||
|
||||
"BLOCK_STONE_DEEP": "Deepstone",
|
||||
"BLOCK_SCAFFOLDING_NORMAL": "Scaffolding",
|
||||
"BLOCK_STONE_MARBLE": "Marble",
|
||||
|
||||
"ITEM_STORAGE_CHEST": "Storage Chest",
|
||||
"ITEM_WIRE": "Wire",
|
||||
"ITEM_WIRE_CUTTER": "Wire Cutter",
|
||||
"ITEM_LOGIC_SIGNAL_EMITTER": "Logic Signal Emitter",
|
||||
"ITEM_TIKI_TORCH": "Tiki Torch"
|
||||
"ACTORBLOCK_TILING_PLACEHOLDER": "Urist Berdanurdim"
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"GAME_ITEM_CALENDAR": "달력",
|
||||
"MENU_CALENDAR_CALENDAR": "달력",
|
||||
"MENU_CALENDAR_EVENTS": "일정",
|
||||
"MENU_CALENDAR_ADD_NEW_EVENT": "새 일정 추가…",
|
||||
"MENU_CALENDAR_ADD_NEW_EVENT": "새 일정 추가",
|
||||
"CONTEXT_CALENDAR_SEASON_SPRING": "봄",
|
||||
"CONTEXT_CALENDAR_SEASON_SUMMER": "여름",
|
||||
"CONTEXT_CALENDAR_SEASON_AUTUMN": "가을",
|
||||
@@ -10,5 +9,8 @@
|
||||
"CONTEXT_CALENDAR_SEASON_SPRI": "봄",
|
||||
"CONTEXT_CALENDAR_SEASON_SUMM": "여름",
|
||||
"CONTEXT_CALENDAR_SEASON_AUTM": "가을",
|
||||
"CONTEXT_CALENDAR_SEASON_WINT": "겨울"
|
||||
"CONTEXT_CALENDAR_SEASON_WINT": "겨울",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_Y": "{0}년",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_YMD": "{0}년 {1} {2}일",
|
||||
"CONTEXT_CALENDAR_DATE_FORMAT_YMD_DDD": "{0}년 {1} {2}일 {3}"
|
||||
}
|
||||
@@ -1,24 +1,25 @@
|
||||
{
|
||||
"CONTEXT_GENERATOR_SEED": "시드",
|
||||
"CONTEXT_ITEM_MAP": "지도",
|
||||
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
|
||||
"CONTEXT_PLACE_COORDINATE": "좌표",
|
||||
"CONTEXT_WORLD_COUNT": "새계: ",
|
||||
"CONTEXT_WORLD_NEW": "새 세계",
|
||||
"MENU_LABEL_DELETE_WORLD": "새계 삭제",
|
||||
"CONTEXT_WORLD_COUNT": "새계: ",
|
||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||
"GAME_INVENTORY_INGREDIENTS": "재료",
|
||||
"GAME_INVENTORY_POTIONS": "물약",
|
||||
"GAME_INVENTORY_BLOCKS": "블록",
|
||||
"GAME_INVENTORY_WALLS": "벽지",
|
||||
"CONTEXT_ITEM_TOOL_PLURAL": "도구",
|
||||
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
|
||||
"GAME_INVENTORY_REGISTER": "등록하기",
|
||||
"MENU_LABEL_MENU": "메뉴",
|
||||
"CONTEXT_ITEM_MAP": "지도",
|
||||
"CONTEXT_GENERATOR_SEED": "시드",
|
||||
"MENU_LABEL_PREV_SAVES": "이전 세이브",
|
||||
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||
"GAME_ACTION_CRAFT": "제작하기",
|
||||
"GAME_ACTION_GRAPPLE": "매달리기",
|
||||
"GAME_ACTION_QUICKSEL": "빠른 선택",
|
||||
"GAME_ACTION_CRAFT": "제작하기",
|
||||
"GAME_CRAFTING": "제작",
|
||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||
"GAME_ACTION_TELEPORT": "텔레포트하기",
|
||||
"CONTEXT_PLACE_COORDINATE": "좌표"
|
||||
"GAME_CRAFTABLE_ITEMS": "제작 가능한 아이템",
|
||||
"GAME_CRAFTING": "제작",
|
||||
"GAME_INVENTORY_BLOCKS": "블록",
|
||||
"GAME_INVENTORY_FAVORITES": "즐겨찾기",
|
||||
"GAME_INVENTORY_INGREDIENTS": "재료",
|
||||
"GAME_INVENTORY_POTIONS": "물약",
|
||||
"GAME_INVENTORY_REGISTER": "등록하기",
|
||||
"GAME_INVENTORY_WALLS": "벽지"
|
||||
}
|
||||
@@ -3,9 +3,11 @@
|
||||
"BLOCK_SCAFFOLDING_NORMAL": "발판",
|
||||
"BLOCK_STONE_MARBLE": "대리석",
|
||||
|
||||
"ITEM_STORAGE_CHEST": "보관상자",
|
||||
"ITEM_WIRE": "전선",
|
||||
"ITEM_WIRE_CUTTER": "전선 절단기",
|
||||
"ITEM_CALENDAR": "달력",
|
||||
"ITEM_LOGIC_SIGNAL_EMITTER": "신호발생기",
|
||||
"ITEM_TIKI_TORCH": "티키 토치"
|
||||
"ITEM_STORAGE_CHEST": "보관상자",
|
||||
"ITEM_TIKI_TORCH": "티키 토치",
|
||||
"ITEM_TYPEWRITER": "타자기",
|
||||
"ITEM_WIRE": "전선",
|
||||
"ITEM_WIRE_CUTTER": "전선 절단기"
|
||||
}
|
||||
BIN
assets/mods/basegame/sprites/fixtures/calendar.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/calendar.tga
LFS
Normal file
Binary file not shown.
@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
|
||||
|
||||
cd "${0%/*}"
|
||||
SRCFILES="terrarummac_arm"
|
||||
DESTDIR="out/TerrarumMac.arm.app"
|
||||
APPDIR="./TerrarumMac.arm.app"
|
||||
DESTDIR="out/$APPDIR"
|
||||
RUNTIME="runtime-osx-arm"
|
||||
|
||||
if [ ! -d "../assets_release" ]; then
|
||||
@@ -34,4 +35,8 @@ cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
|
||||
|
||||
cd "out"
|
||||
rm $APPDIR.zip
|
||||
7z a -tzip $APPDIR.zip $APPDIR
|
||||
|
||||
echo "Build successful: $DESTDIR"
|
||||
|
||||
@@ -3,7 +3,8 @@ if (( $EUID == 0 )); then echo "The build process is not meant to be run with ro
|
||||
|
||||
cd "${0%/*}"
|
||||
SRCFILES="terrarummac_x86"
|
||||
DESTDIR="out/TerrarumMac.x86.app"
|
||||
APPDIR="./TerrarumMac.x86.app"
|
||||
DESTDIR="out/$APPDIR"
|
||||
RUNTIME="runtime-osx-x86"
|
||||
|
||||
if [ ! -d "../assets_release" ]; then
|
||||
@@ -34,4 +35,8 @@ cp -r "../assets_release" $DESTDIR/Contents/MacOS/
|
||||
mv $DESTDIR/Contents/MacOS/assets_release $DESTDIR/Contents/MacOS/assets
|
||||
cp "../out/TerrarumBuild.jar" $DESTDIR/Contents/MacOS/out/
|
||||
|
||||
cd "out"
|
||||
rm $APPDIR.zip
|
||||
7z a -tzip $APPDIR.zip $APPDIR
|
||||
|
||||
echo "Build successful: $DESTDIR"
|
||||
|
||||
25
buildapp/make_assets_release.sh
Executable file
25
buildapp/make_assets_release.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
if (( $EUID == 0 )); then echo "The build process is not meant to be run with root privilege, exiting now." >&2; exit 1; fi
|
||||
|
||||
cd "${0%/*}"
|
||||
DESTDIR="../assets_release"
|
||||
|
||||
rm -r $DESTDIR
|
||||
cp -r "../assets" $DESTDIR
|
||||
|
||||
rm $DESTDIR/loopey.wav
|
||||
rm $DESTDIR/ktGrepExample.kts
|
||||
rm $DESTDIR/batchtest.txt
|
||||
rm $DESTDIR/test_texture.tga
|
||||
rm $DESTDIR/worldbacktest.tga
|
||||
rm -r $DESTDIR/books
|
||||
rm $DESTDIR/clut/skybox.tga
|
||||
rm $DESTDIR/graphics/*.bat
|
||||
rm $DESTDIR/keylayout/*.not_ime
|
||||
rm $DESTDIR/mods/basegame/blocks/*.gz
|
||||
rm $DESTDIR/mods/basegame/blocks/*.txt
|
||||
rm -r $DESTDIR/mods/basegame/sounds
|
||||
rm -r $DESTDIR/mods/dwarventech
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.badlogic.gdx.graphics.glutils;
|
||||
|
||||
import com.badlogic.gdx.Application;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.GL30;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import net.torvald.terrarum.App;
|
||||
|
||||
// typealias Float16FrameBuffer = FloatFrameBuffer
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-08-16.
|
||||
*/
|
||||
public class Float16FrameBuffer extends FrameBuffer {
|
||||
|
||||
Float16FrameBuffer () {
|
||||
}
|
||||
|
||||
/** Creates a GLFrameBuffer from the specifications provided by bufferBuilder
|
||||
*
|
||||
* @param bufferBuilder **/
|
||||
protected Float16FrameBuffer (GLFrameBufferBuilder<? extends GLFrameBuffer<Texture>> bufferBuilder) {
|
||||
super(bufferBuilder);
|
||||
}
|
||||
|
||||
/** Creates a new FrameBuffer with a float backing texture, having the given dimensions and potentially a depth buffer
|
||||
* attached.
|
||||
*
|
||||
* @param width the width of the framebuffer in pixels
|
||||
* @param height the height of the framebuffer in pixels
|
||||
* @param hasDepth whether to attach a depth buffer
|
||||
* @throws GdxRuntimeException in case the FrameBuffer could not be created */
|
||||
public Float16FrameBuffer (int width, int height, boolean hasDepth) {
|
||||
if (App.isAppleM) { // disable float framebuffer for Apple M chips
|
||||
FrameBufferBuilder bufferBuilder = new FrameBufferBuilder(width, height);
|
||||
bufferBuilder.addColorTextureAttachment(GL20.GL_RGBA, GL20.GL_RGBA, GL20.GL_UNSIGNED_SHORT); // but 16bpp int works perfectly?!
|
||||
if (hasDepth) bufferBuilder.addBasicDepthRenderBuffer();
|
||||
this.bufferBuilder = bufferBuilder;
|
||||
}
|
||||
else {
|
||||
FloatFrameBufferBuilder bufferBuilder = new FloatFrameBufferBuilder(width, height);
|
||||
bufferBuilder.addFloatAttachment(GL30.GL_RGBA16F, GL30.GL_RGBA, GL30.GL_FLOAT, false); // FIXME sporadic black screen on GL_RGBA16F? or maybe it was Plasma bugging out?
|
||||
if (hasDepth) bufferBuilder.addBasicDepthRenderBuffer();
|
||||
this.bufferBuilder = bufferBuilder;
|
||||
}
|
||||
|
||||
build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Texture createTexture (FrameBufferTextureAttachmentSpec attachmentSpec) {
|
||||
if (App.isAppleM) {
|
||||
GLOnlyTextureData data = new GLOnlyTextureData(bufferBuilder.width, bufferBuilder.height, 0, attachmentSpec.internalFormat,
|
||||
attachmentSpec.format, attachmentSpec.type);
|
||||
Texture result = new Texture(data);
|
||||
result.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||
result.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
FloatTextureData data = new FloatTextureData(bufferBuilder.width, bufferBuilder.height, attachmentSpec.internalFormat,
|
||||
attachmentSpec.format, attachmentSpec.type, attachmentSpec.isGpuOnly);
|
||||
Texture result = new Texture(data);
|
||||
result.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
|
||||
result.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,9 +62,11 @@ public class App implements ApplicationListener {
|
||||
|
||||
public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME;
|
||||
public static final long VERSION_RAW = TerrarumAppConfiguration.VERSION_RAW;
|
||||
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
|
||||
|
||||
public static final String getVERSION_STRING() {
|
||||
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL);
|
||||
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL) +
|
||||
(VERSION_TAG.isBlank() ? "" : "-"+VERSION_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,12 +269,13 @@ public class App implements ApplicationListener {
|
||||
Gdx.gl20.glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
public static final float UPDATE_RATE = 1f / 64f; // apparent framerate will be limited by update rate
|
||||
public static final int TICKS = 64;
|
||||
public static final float UPDATE_RATE = 1f / TICKS; // apparent framerate will be limited by update rate
|
||||
|
||||
private static float loadTimer = 0f;
|
||||
private static final float showupTime = 100f / 1000f;
|
||||
|
||||
private static FloatFrameBuffer renderFBO;
|
||||
private static Float16FrameBuffer renderFBO;
|
||||
|
||||
public static HashSet<File> tempFilePool = new HashSet<>();
|
||||
|
||||
@@ -609,19 +612,21 @@ public class App implements ApplicationListener {
|
||||
|
||||
private static void processScreenshotRequest(FrameBuffer fb) {
|
||||
if (screenshotRequested) {
|
||||
String msg = "Screenshot taken";
|
||||
FrameBufferManager.begin(fb);
|
||||
try {
|
||||
Pixmap p = Pixmap.createFromFrameBuffer(0, 0, fb.getWidth(), fb.getHeight());
|
||||
PixmapIO.writePNG(Gdx.files.absolute(defaultDir+"/Screenshot-"+String.valueOf(System.currentTimeMillis())+".png"), p, 9, true);
|
||||
p.dispose();
|
||||
Terrarum.INSTANCE.getIngame().sendNotification("Screenshot taken");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Terrarum.INSTANCE.getIngame().sendNotification("Failed to take screenshot: "+e.getMessage());
|
||||
msg = ("Failed to take screenshot: "+e.getMessage());
|
||||
}
|
||||
FrameBufferManager.end();
|
||||
screenshotRequested = false;
|
||||
|
||||
Terrarum.INSTANCE.getIngame().sendNotification(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,12 +755,12 @@ public class App implements ApplicationListener {
|
||||
(renderFBO.getWidth() != scr.getWidth() ||
|
||||
renderFBO.getHeight() != scr.getHeight())
|
||||
) {
|
||||
renderFBO = new FloatFrameBuffer(
|
||||
renderFBO = new Float16FrameBuffer(
|
||||
scr.getWidth(),
|
||||
scr.getHeight(),
|
||||
false
|
||||
);
|
||||
postProcessorOutFBO2 = new FloatFrameBuffer(
|
||||
postProcessorOutFBO2 = new Float16FrameBuffer(
|
||||
scr.getWidth() * 2,
|
||||
scr.getHeight() * 2,
|
||||
false
|
||||
|
||||
@@ -67,6 +67,8 @@ basegame
|
||||
// Commit counts up to the Release 0.3.1: 2278
|
||||
// Commit counts up to the Release 0.3.2: 2732
|
||||
|
||||
const val VERSION_TAG: String = "test001"
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// CONFIGURATION FOR TILE MAKER //
|
||||
// MAKE SURE THESE VALUES ARE UNIQUE IN THE SOURCE CODE //
|
||||
|
||||
@@ -209,8 +209,8 @@ class BlockCodex {
|
||||
prop.isSolid = record.boolVal("solid")
|
||||
//prop.isClear = record.boolVal("clear")
|
||||
|
||||
prop.isPlatform = prop.tags.contains("PLATFORM")
|
||||
prop.isActorBlock = prop.tags.contains("ACTORBLOCK")
|
||||
prop.isPlatform = prop.hasTag("PLATFORM")
|
||||
prop.isActorBlock = prop.hasTag("ACTORBLOCK")
|
||||
|
||||
prop.isWallable = record.boolVal("wall")
|
||||
prop.maxSupport = record.intVal("grav")
|
||||
|
||||
@@ -75,6 +75,8 @@ class BlockProp {
|
||||
BlockCodex[BlockCodex.tileToVirtual[id]!![offset]]._lumCol.lane(channel)
|
||||
}
|
||||
|
||||
fun hasTag(s: String) = tags.contains(s)
|
||||
|
||||
/**
|
||||
* @param luminosity
|
||||
*/
|
||||
|
||||
@@ -214,6 +214,11 @@ object Skybox : Disposable {
|
||||
|
||||
/**
|
||||
* To get the idea what the fuck is going on here, please refer to https://www.desmos.com/calculator/snqglcu2wl
|
||||
*
|
||||
* Sidenote: the original model involved two cosine curves, but since its Taylor series begins with x^2, I figured
|
||||
* quadratic curve ought to be good enough, and the error against the original model was below 1/255 for
|
||||
* reasonable range of p, and that's the reason I stopped at x^2 rather than also taking x^4 into the approximated
|
||||
* model that is the code below.
|
||||
*/
|
||||
internal fun smoothLinear(p: Double, x0: Double): Double {
|
||||
val x = x0 - 0.5
|
||||
|
||||
@@ -36,7 +36,7 @@ internal object Authenticator : ConsoleCommand {
|
||||
println("auth passwd: '$pwd'")
|
||||
println("hash: $hashedPwd")
|
||||
|
||||
if ("09ccf5067db6f58265b004829e33e715e819ba0984f1e1fcef49c36fcd5f745f".equals(hashedPwd, ignoreCase = true)) {
|
||||
if ("2d962f949f55906ac47f16095ded190c9e44d95920259b8f36c2e54bd75df173".equals(hashedPwd, ignoreCase = true)) {
|
||||
// beedle
|
||||
val msg = if (a) "Locked" else "Authenticated"
|
||||
Echo(msg)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -145,6 +145,9 @@ class Hitbox {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the hitbox centred around the "canonical" point.
|
||||
*/
|
||||
fun canonicalResize(w: Double, h: Double): Hitbox {
|
||||
// sx_1 + 0.5w_1 = sx_2 + 0.5w_2 // equals because the final point must not move. sx_1: old start-x, sx_2: new start-x which is what we want
|
||||
// sx_2 = sx_1 + 0.5w_1 - 0.5w_2 // move variables to right-hand side to derive final value sx_2
|
||||
|
||||
@@ -359,6 +359,8 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
||||
return this
|
||||
}
|
||||
|
||||
fun hasTag(s: String) = tags.contains(s)
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package net.torvald.terrarum.gameworld
|
||||
|
||||
import net.torvald.terrarum.modulebasegame.worldgenerator.TWO_PI
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
|
||||
/**
|
||||
@@ -57,8 +56,10 @@ import kotlin.math.sin
|
||||
*/
|
||||
class WorldTime(initTime: Long = 0L) {
|
||||
|
||||
@Transient private val TWO_PI = Math.PI * 2.0
|
||||
|
||||
/** It is not recommended to directly modify the TIME_T. Use provided methods instead. */
|
||||
var TIME_T = 0L // Epoch: Year 125 Spring 1st, 0h00:00 (Mondag) // 125-01-01
|
||||
var TIME_T = 0L // Epoch: Year 1 Spring 1st, 0h00:00 (Mondag) // 0001-01-01
|
||||
|
||||
init {
|
||||
TIME_T = initTime
|
||||
@@ -151,21 +152,7 @@ class WorldTime(initTime: Long = 0L) {
|
||||
@Transient private val REAL_SEC_TO_GAME_SECS = 1.0 / GAME_MIN_TO_REAL_SEC // how slow is real-life clock (second-wise) relative to the ingame one
|
||||
|
||||
// NOTE: ingame calendars (the fixture with GUI) should use symbols AND fullnames; the watch already uses shot daynames
|
||||
val DAY_NAMES = arrayOf(//daynames are taken from Nynorsk (å -> o)
|
||||
"Mondag", "Tysdag", "Midtveke" //middle-week
|
||||
, "Torsdag", "Fredag", "Laurdag", "Sundag", "Verddag" //From Norsk word 'verd'
|
||||
)
|
||||
val DAY_NAMES_SHORT = arrayOf("Mon", "Tys", "Mid", "Tor", "Fre", "Lau", "Sun", "Ver")
|
||||
|
||||
// dwarven calendar of 12 monthes
|
||||
/*val MONTH_NAMES = arrayOf(
|
||||
"Opal", "Obsidian", "Granite", "Slate", "Felsite", "Hematite",
|
||||
"Malachite", "Galena", "Limestone", "Sandstone", "Timber", "Moonstone"
|
||||
)
|
||||
val MONTH_NAMES_SHORT = arrayOf("Opal", "Obsi", "Gran", "Slat", "Fels", "Hema",
|
||||
"Mala", "Gale", "Lime", "Sand", "Timb", "Moon")*/
|
||||
val MONTH_NAMES = arrayOf("Spring", "Summer", "Autumn", "Winter")
|
||||
val MONTH_NAMES_SHORT = arrayOf("Spri", "Summ", "Autm", "Wint")
|
||||
|
||||
companion object {
|
||||
/** Each day is displayed as 24 hours, but in real-life clock it's 22 mins long */
|
||||
@@ -181,7 +168,7 @@ class WorldTime(initTime: Long = 0L) {
|
||||
|
||||
const val MONTH_LENGTH = 30 // ingame calendar specific
|
||||
|
||||
const val EPOCH_YEAR = 125
|
||||
const val EPOCH_YEAR = 1
|
||||
|
||||
val YEAR_SECONDS = DAY_LENGTH * YEAR_DAYS
|
||||
|
||||
@@ -203,6 +190,31 @@ class WorldTime(initTime: Long = 0L) {
|
||||
|
||||
val LUNAR_CYCLE: Int = 29 * DAY_LENGTH + 12 * HOUR_SEC + 44 * MINUTE_SEC + 3 // 29 days, 12 hours, 44 minutes, and 3 seconds in-game calendar
|
||||
const val DIURNAL_MOTION_LENGTH = 86636f
|
||||
|
||||
val DAY_NAMES = arrayOf(//daynames are taken from Nynorsk (å -> o)
|
||||
"MONDAG", "TYSDAG", "MIDTVEKE" //middle-week
|
||||
, "TORSDAG", "FREDAG", "LAURDAG", "SUNDAG", "VERDDAG" //From Norsk word 'verd'
|
||||
)
|
||||
val DAY_NAMES_SHORT = arrayOf("MON", "TYS", "MID", "TOR", "FRE", "LAU", "SUN", "VER")
|
||||
// dwarven calendar of 12 monthes
|
||||
/*val MONTH_NAMES = arrayOf(
|
||||
"Opal", "Obsidian", "Granite", "Slate", "Felsite", "Hematite",
|
||||
"Malachite", "Galena", "Limestone", "Sandstone", "Timber", "Moonstone"
|
||||
)
|
||||
val MONTH_NAMES_SHORT = arrayOf("Opal", "Obsi", "Gran", "Slat", "Fels", "Hema",
|
||||
"Mala", "Gale", "Lime", "Sand", "Timb", "Moon")*/
|
||||
val MONTH_NAMES = arrayOf("SPRING", "SUMMER", "AUTUMN", "WINTER")
|
||||
val MONTH_NAMES_SHORT = arrayOf("SPRI", "SUMM", "AUTM", "WINT")
|
||||
|
||||
val DAY_NAMES_LANG_KEYS = DAY_NAMES.map { "CONTEXT_CALENDAR_DAY_${it}_DNT" }
|
||||
val DAY_NAMES_SHORT_LANG_KEYS = DAY_NAMES_SHORT.map { "CONTEXT_CALENDAR_DAY_${it}_DNT" }
|
||||
val MONTH_NAMES_LANG_KEYS = MONTH_NAMES.map { "CONTEXT_CALENDAR_SEASON_${it}" }
|
||||
val MONTH_NAMES_SHORT_LANG_KEYS = MONTH_NAMES_SHORT.map { "CONTEXT_CALENDAR_SEASON_${it}" }
|
||||
|
||||
fun getDayName(index: Int) = Lang[DAY_NAMES_LANG_KEYS[index]]
|
||||
fun getDayNameShort(index: Int) = Lang[DAY_NAMES_SHORT_LANG_KEYS[index]]
|
||||
fun getMonthName(index: Int) = Lang[MONTH_NAMES_LANG_KEYS[index - 1]]
|
||||
fun getMonthNameShort(index: Int) = Lang[MONTH_NAMES_SHORT_LANG_KEYS[index - 1]]
|
||||
}
|
||||
|
||||
fun update(delta: Float) {
|
||||
@@ -228,27 +240,30 @@ class WorldTime(initTime: Long = 0L) {
|
||||
TIME_T += t
|
||||
}
|
||||
|
||||
val dayName: String
|
||||
get() = DAY_NAMES[dayOfWeek]
|
||||
|
||||
fun Long.toPositiveInt() = this.and(0x7FFFFFFF).toInt()
|
||||
fun Long.abs() = Math.abs(this)
|
||||
|
||||
/** Format: "%A, %Y %B %d %X" */
|
||||
fun getFormattedTime() = "${getDayNameShort()}, " +
|
||||
"$years " +
|
||||
"${getMonthNameFull()} " +
|
||||
"$calendarDay " +
|
||||
"${String.format("%02d", hours)}:" +
|
||||
"${String.format("%02d", minutes)}:" +
|
||||
"${String.format("%02d", seconds)}"
|
||||
/** Format: "ɣ%Y %B %d %A, %X" */
|
||||
fun getFormattedTime() =
|
||||
"ɣ$years " +
|
||||
"${getMonthNameFull()} " +
|
||||
"$calendarDay " +
|
||||
"${getDayNameFull()}, " +
|
||||
"${String.format("%02d", hours)}:" +
|
||||
"${String.format("%02d", minutes)}:" +
|
||||
"${String.format("%02d", seconds)}"
|
||||
fun getFormattedCalendarDay() =
|
||||
"ɣ$years " +
|
||||
"${getMonthNameFull()} " +
|
||||
"$calendarDay " +
|
||||
"${getDayNameFull()}"
|
||||
fun getShortTime() = "${years.toString().padStart(4, '0')}-${getMonthNameShort()}-${calendarDay.toString().padStart(2, '0')}"
|
||||
fun getFilenameTime() = "${years.toString().padStart(4, '0')}${calendarMonth.toString().padStart(2, '0')}${calendarDay.toString().padStart(2, '0')}"
|
||||
|
||||
fun getDayNameFull() = DAY_NAMES[dayOfWeek]
|
||||
fun getDayNameShort() = DAY_NAMES_SHORT[dayOfWeek]
|
||||
fun getMonthNameFull() = MONTH_NAMES[calendarMonth - 1]
|
||||
fun getMonthNameShort() = MONTH_NAMES_SHORT[calendarMonth - 1]
|
||||
fun getDayNameFull() = getDayName(dayOfWeek)
|
||||
fun getDayNameShort() = getDayNameShort(dayOfWeek)
|
||||
fun getMonthNameFull() = getMonthName(calendarMonth)
|
||||
fun getMonthNameShort() = getMonthNameShort(calendarMonth)
|
||||
|
||||
override fun toString() = getFormattedTime()
|
||||
}
|
||||
@@ -152,6 +152,15 @@ object Lang {
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun getAndUseTemplate(key: String, capitalise: Boolean = true, vararg arguments: Any?): String {
|
||||
var raw = get(key, capitalise)
|
||||
arguments.forEachIndexed { index, it0 ->
|
||||
val it = if (capitalise) it0.toString().capitalize() else it0.toString()
|
||||
raw = raw.replace("{${index}}", it)
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
/**
|
||||
* Does NOT parse the operators
|
||||
*/
|
||||
|
||||
@@ -4,11 +4,10 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.graphics.glutils.FloatFrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
@@ -53,20 +52,20 @@ object IngameRenderer : Disposable {
|
||||
private lateinit var blurWriteQuad2: Mesh
|
||||
// private lateinit var blurWriteQuad4: Mesh
|
||||
|
||||
private lateinit var lightmapFbo: FloatFrameBuffer
|
||||
private lateinit var fboRGB: FloatFrameBuffer
|
||||
private lateinit var fboRGB_lightMixed: FloatFrameBuffer
|
||||
private lateinit var fboA: FloatFrameBuffer
|
||||
private lateinit var fboA_lightMixed: FloatFrameBuffer
|
||||
private lateinit var fboMixedOut: FloatFrameBuffer
|
||||
private lateinit var lightmapFbo: Float16FrameBuffer
|
||||
private lateinit var fboRGB: Float16FrameBuffer
|
||||
private lateinit var fboRGB_lightMixed: Float16FrameBuffer
|
||||
private lateinit var fboA: Float16FrameBuffer
|
||||
private lateinit var fboA_lightMixed: Float16FrameBuffer
|
||||
private lateinit var fboMixedOut: Float16FrameBuffer
|
||||
private lateinit var rgbTex: TextureRegion
|
||||
private lateinit var aTex: TextureRegion
|
||||
private lateinit var mixedOutTex: TextureRegion
|
||||
private lateinit var lightTex: TextureRegion
|
||||
private lateinit var blurTex: TextureRegion
|
||||
|
||||
private lateinit var fboBlurHalf: FloatFrameBuffer
|
||||
// private lateinit var fboBlurQuarter: FloatFrameBuffer
|
||||
private lateinit var fboBlurHalf: Float16FrameBuffer
|
||||
// private lateinit var fboBlurQuarter: Float16FrameBuffer
|
||||
|
||||
// you must have lightMixed FBO; otherwise you'll be reading from unbaked FBO and it freaks out GPU
|
||||
|
||||
@@ -694,7 +693,7 @@ object IngameRenderer : Disposable {
|
||||
|
||||
private const val KAWASE_POWER = 1.5f
|
||||
|
||||
fun processNoBlur(outFbo: FloatFrameBuffer) {
|
||||
fun processNoBlur(outFbo: Float16FrameBuffer) {
|
||||
|
||||
blurtex0.dispose()
|
||||
|
||||
@@ -710,7 +709,7 @@ object IngameRenderer : Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
fun processKawaseBlur(outFbo: FloatFrameBuffer) {
|
||||
fun processKawaseBlur(outFbo: Float16FrameBuffer) {
|
||||
|
||||
blurtex0.dispose()
|
||||
|
||||
@@ -807,12 +806,12 @@ object IngameRenderer : Disposable {
|
||||
//fboBlurQuarter.dispose()
|
||||
}
|
||||
|
||||
fboRGB = FloatFrameBuffer(width, height, false)
|
||||
fboRGB_lightMixed = FloatFrameBuffer(width, height, false)
|
||||
fboA = FloatFrameBuffer(width, height, false)
|
||||
fboA_lightMixed = FloatFrameBuffer(width, height, false)
|
||||
fboMixedOut = FloatFrameBuffer(width, height, false)
|
||||
lightmapFbo = FloatFrameBuffer(
|
||||
fboRGB = Float16FrameBuffer(width, height, false)
|
||||
fboRGB_lightMixed = Float16FrameBuffer(width, height, false)
|
||||
fboA = Float16FrameBuffer(width, height, false)
|
||||
fboA_lightMixed = Float16FrameBuffer(width, height, false)
|
||||
fboMixedOut = Float16FrameBuffer(width, height, false)
|
||||
lightmapFbo = Float16FrameBuffer(
|
||||
LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(),
|
||||
LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(),
|
||||
false
|
||||
@@ -823,13 +822,13 @@ object IngameRenderer : Disposable {
|
||||
blurTex = TextureRegion()
|
||||
mixedOutTex = TextureRegion(fboMixedOut.colorBufferTexture)
|
||||
|
||||
fboBlurHalf = FloatFrameBuffer(
|
||||
fboBlurHalf = Float16FrameBuffer(
|
||||
LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 2,
|
||||
LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 2,
|
||||
false
|
||||
)
|
||||
|
||||
/*fboBlurQuarter = FloatFrameBuffer(
|
||||
/*fboBlurQuarter = Float16FrameBuffer(
|
||||
LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 4,
|
||||
LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 4,
|
||||
false
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.badlogic.gdx.graphics.OrthographicCamera
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.graphics.glutils.FloatFrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
@@ -147,7 +147,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
internal lateinit var uiRemoCon: UIRemoCon
|
||||
internal lateinit var uiFakeBlurOverlay: UICanvas
|
||||
|
||||
private lateinit var worldFBO: FloatFrameBuffer
|
||||
private lateinit var worldFBO: Float16FrameBuffer
|
||||
|
||||
private val warning32bitJavaIcon = TextureRegion(Texture(Gdx.files.internal("assets/graphics/gui/32_bit_warning.tga")))
|
||||
private val warningAppleRosettaIcon = TextureRegion(Texture(Gdx.files.internal("assets/graphics/gui/apple_rosetta_warning.tga")))
|
||||
@@ -262,7 +262,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
Gdx.input.inputProcessor = TitleScreenController(this)
|
||||
|
||||
|
||||
worldFBO = FloatFrameBuffer(App.scr.width, App.scr.height, false)
|
||||
worldFBO = Float16FrameBuffer(App.scr.width, App.scr.height, false)
|
||||
|
||||
// load list of savegames
|
||||
printdbg(this, "update list of savegames")
|
||||
|
||||
@@ -14,16 +14,21 @@ import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
*/
|
||||
internal object Inventory : ConsoleCommand {
|
||||
|
||||
private var targetID: ActorID = INGAME.actorNowPlaying?.referenceID ?: PLAYER_REF_ID
|
||||
private var targetID: ActorID = 0
|
||||
|
||||
private fun tryTargetActivePlayer() {
|
||||
targetID = INGAME.actorNowPlaying?.referenceID ?: 0
|
||||
}
|
||||
|
||||
override fun execute(args: Array<String>) {
|
||||
if (args.size == 1) {
|
||||
printUsage()
|
||||
}
|
||||
else if (args[1] == "target") {
|
||||
targetID = if (args[2].lowercase() == "player") (INGAME.actorNowPlaying?.referenceID ?: PLAYER_REF_ID) else args[2].toInt()
|
||||
if (args[2].lowercase() == "player") tryTargetActivePlayer() else targetID = args[2].toInt()
|
||||
}
|
||||
else {
|
||||
if (targetID == 0) tryTargetActivePlayer()
|
||||
val actor = getActor()
|
||||
if (actor != null) {
|
||||
when (args[1]) {
|
||||
@@ -36,7 +41,7 @@ internal object Inventory : ConsoleCommand {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Echo("Actor $targetID is not Pocketed or does not exists")
|
||||
Echo("Actor $targetID is not Pocketed or does not exist")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.gameactors.*
|
||||
import net.torvald.terrarum.gameactors.faction.Faction
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.itemproperties.Material
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
@@ -116,6 +115,8 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
|
||||
@Transient const val SPRITE_ROW_IDLE = 0
|
||||
@Transient const val SPRITE_ROW_WALK = 1
|
||||
|
||||
@Transient const val downDownMinLengthBase = 12
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -173,7 +174,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
|
||||
var isUpDown = false; protected set
|
||||
var isDownDown = false; protected set
|
||||
var downDownVirtually = false; internal set
|
||||
var downButtonHeld = 0; internal set
|
||||
var isLeftDown = false; protected set
|
||||
var isRightDown = false; protected set
|
||||
var isJumpDown = false; protected set
|
||||
@@ -221,7 +222,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
if (isNoClip) {
|
||||
//grounded = true
|
||||
// platformToIgnore = null
|
||||
downDownVirtually = false
|
||||
downButtonHeld = 0
|
||||
}
|
||||
|
||||
// reset control box of AI
|
||||
@@ -248,6 +249,9 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
}
|
||||
}
|
||||
|
||||
private val downDownMinLength: Int
|
||||
get() = (downDownMinLengthBase * (gravitation.y.abs() / 9.8).sqrt()).ceilToInt()
|
||||
|
||||
private fun updateGamerControlBox() {
|
||||
if (isGamer) {
|
||||
isUpDown = Gdx.input.isKeyPressed(App.getConfigInt("control_key_up"))
|
||||
@@ -288,17 +292,14 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
}
|
||||
|
||||
// platform-related hacks
|
||||
// allow latching down downDownVirtually only when standing on a platform AND not jumping upwards
|
||||
val occupyingTileHasPlatform = bodyTiles.filterNotNull().any { it.isPlatform }
|
||||
val feetTileHasPlatform = feetTiles.filterNotNull().any { it.isPlatform }
|
||||
val feetTileIsAllPlatform = feetTiles.filterNotNull().all { it.isPlatform }
|
||||
if (isDownDown && feetTileIsAllPlatform && (controllerV?.y ?: 0.0) >= 0.0) {// ||
|
||||
// occupyingTileHasPlatform && !feetTileHasPlatform) { // FIXME commenting this out enables platform-ladder but falldown gets slowed down if the body passes thru the platform but I think this behav might be beneficial for player?
|
||||
downDownVirtually = true
|
||||
if (isDownDown || downButtonHeld in 1 until downDownMinLength) {
|
||||
downButtonHeld += 1
|
||||
}
|
||||
if (downDownVirtually && !occupyingTileHasPlatform && !feetTileIsAllPlatform) {
|
||||
downDownVirtually = false
|
||||
else {
|
||||
downButtonHeld = 0
|
||||
}
|
||||
// TODO just disable "snap to ground" on collision solver if {player's body overlaps with the platform/downDownVirtually}?
|
||||
// the point is: disable snap (or don't consider offending tiles as solid) for certain Y-pos only, tiles on Y+1 are still solid
|
||||
}
|
||||
|
||||
private inline val hasController: Boolean
|
||||
|
||||
@@ -248,7 +248,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
forEachBlockbox { x, y, _, _ ->
|
||||
if (!hasCollision) {
|
||||
val tile = world!!.getTileFromTerrain(x, y)
|
||||
if (BlockCodex[tile].isSolid || BlockCodex[tile].isActorBlock) {
|
||||
if (!BlockCodex[tile].hasTag("INCONSEQUENTIAL")) {
|
||||
hasCollision = true
|
||||
}
|
||||
}
|
||||
@@ -311,7 +311,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
forEachBlockbox { x, y, _, _ ->
|
||||
if (!hasCollision) {
|
||||
val tile = world!!.getTileFromTerrain(x, y)
|
||||
if (BlockCodex[tile].isSolid || BlockCodex[tile].isActorBlock) {
|
||||
if (!BlockCodex[tile].hasTag("INCONSEQUENTIAL")) {
|
||||
hasCollision = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIWallCalendar
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-08-08.
|
||||
*/
|
||||
class FixtureWallCalendar : FixtureBase {
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 1),
|
||||
nameFun = { Lang["ITEM_CALENDAR"] },
|
||||
mainUI = UIWallCalendar()
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/calendar.tga")
|
||||
|
||||
density = 600.0
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, 1)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 1.0
|
||||
}
|
||||
|
||||
override var tooltipText: String?
|
||||
get() = Lang.getAndUseTemplate("CONTEXT_CALENDAR_DATE_FORMAT_YMD_DDD", false,
|
||||
world!!.worldTime.years,
|
||||
world!!.worldTime.getMonthNameFull(),
|
||||
world!!.worldTime.calendarDay,
|
||||
world!!.worldTime.getDayNameFull()
|
||||
)//INGAME.world.worldTime.getFormattedCalendarDay()
|
||||
set(value) {}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ object BlockBase {
|
||||
|
||||
// return false if there is a "solid" tile already
|
||||
if (isWall && BlockCodex[wallUnderCursor].isSolid ||
|
||||
!isWall && (BlockCodex[terrainUnderCursor].isSolid || BlockCodex[terrainUnderCursor].isActorBlock))
|
||||
!isWall && !BlockCodex[terrainUnderCursor].hasTag("INCONSEQUENTIAL"))
|
||||
return@mouseInInteractableRange -1L
|
||||
|
||||
// filter passed, do the job
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-08-08.
|
||||
*/
|
||||
class ItemWallCalendar(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureWallCalendar") {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override val originalName = "ITEM_CALENDAR"
|
||||
override var baseMass = 1.0
|
||||
override var stackable = true
|
||||
override var inventoryCategory = Category.MISC
|
||||
override val isUnique = false
|
||||
override val isDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/calendar.tga")
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
|
||||
init {
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class QuickSingleplayerWorldSavingThread(
|
||||
|
||||
// Write Actors //
|
||||
actorsList.forEachIndexed { count, it ->
|
||||
printdbg(this, "Writing actors... ${count+1}/${actorsList.size}")
|
||||
printdbg(this, "Writing actors... ${count+1}/${actorsList.size} (${it.javaClass.canonicalName})")
|
||||
|
||||
val actorContent = EntryFile(WriteActor.encodeToByteArray64(it))
|
||||
val actor = DiskEntry(it.referenceID.toLong(), ROOT, creation_t, time_t, actorContent)
|
||||
|
||||
@@ -56,10 +56,10 @@ object ControlPanelCommon {
|
||||
|
||||
val initialSel = optionsList.indexOf(App.getConfigString(optionName))
|
||||
|
||||
println("labelFuns = ${labelFuns.map { it.invoke() }}")
|
||||
println("optionsList = $optionsList")
|
||||
println("optionName = $optionName; value = ${App.getConfigString(optionName)}")
|
||||
println("initialSel = $initialSel")
|
||||
// println("labelFuns = ${labelFuns.map { it.invoke() }}")
|
||||
// println("optionsList = $optionsList")
|
||||
// println("optionName = $optionName; value = ${App.getConfigString(optionName)}")
|
||||
// println("initialSel = $initialSel")
|
||||
|
||||
if (initialSel < 0) throw IllegalArgumentException("config value '${App.getConfigString(optionName)}' for option '$optionName' is not found on the options list")
|
||||
|
||||
@@ -69,6 +69,19 @@ object ControlPanelCommon {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("spinnersel,")) {
|
||||
val labelFuns = arg.subList(1, arg.size).map { { it } }
|
||||
val optionsList = arg.subList(1, arg.size).map { it.toInt() }
|
||||
|
||||
val initialSel = optionsList.indexOf(App.getConfigInt(optionName))
|
||||
if (initialSel < 0) throw IllegalArgumentException("config value '${App.getConfigInt(optionName)}' for option '$optionName' is not found on the options list")
|
||||
|
||||
UIItemTextSelector(parent, x, y, labelFuns, initialSel, CONFIG_SPINNER_WIDTH, clickToShowPalette = false, useSpinnerButtons = true) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemTextSelector).selectionChangeListener = {
|
||||
App.setConfig(optionStr, optionsList[it])
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.startsWith("spinner,")) {
|
||||
UIItemSpinner(parent, x, y, App.getConfigInt(optionName), arg[1].toInt(), arg[2].toInt(), arg[3].toInt(), CONFIG_SPINNER_WIDTH, numberToTextFunction = { "${it.toLong()}" }) to { it: UIItem, optionStr: String ->
|
||||
(it as UIItemSpinner).selectionChangeListener = {
|
||||
|
||||
@@ -17,6 +17,10 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
*/
|
||||
class UIBasicInfo() : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
val player: ActorHumanoid?
|
||||
get() = Terrarum.ingame?.actorNowPlaying
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ import net.torvald.terrarum.ui.UICanvas
|
||||
*/
|
||||
class UICheatDetected : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
override var width: Int
|
||||
get() = App.scr.width
|
||||
set(value) { throw UnsupportedOperationException() }
|
||||
|
||||
@@ -125,7 +125,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
// If the player has the required item, use it; otherwise, will take an item from the ItemCodex
|
||||
player.itemList.filter { (itm, qty) ->
|
||||
ItemCodex[itm]?.tags?.contains(ingredient.key) == true && qty >= ingredient.qty
|
||||
}.maxByOrNull { it.qty }?.itm ?: ((ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.tags.contains(ingredient.key)) it.key else null }) ?: throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed"))
|
||||
}.maxByOrNull { it.qty }?.itm ?: ((ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.hasTag(ingredient.key)) it.key else null }) ?: throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed"))
|
||||
}
|
||||
else {
|
||||
ingredient.key
|
||||
@@ -234,7 +234,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
// don't rely on highlightedness of the button to determine the item on the button is the selected
|
||||
// ingredient (because I don't fully trust my code lol)
|
||||
val targetItemToAlter = recipe.ingredients.filter { // altering recipe doesn't make sense if player selected a recipe that requires no tag-ingredients
|
||||
(it.keyMode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.tags.contains(it.key))
|
||||
(it.keyMode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.hasTag(it.key))
|
||||
}.let {
|
||||
if (it.size > 1)
|
||||
println("[UICrafting] Your recipe seems to have two similar ingredients defined\n" +
|
||||
@@ -245,7 +245,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
|
||||
targetItemToAlter?.let {
|
||||
val oldItem = _getItemListIngredients().getInventory().itemList.first { itemPair ->
|
||||
(it.keyMode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itemPair.itm]!!.tags.contains(it.key))
|
||||
(it.keyMode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itemPair.itm]!!.hasTag(it.key))
|
||||
}
|
||||
changeIngredient(oldItem, itemID)
|
||||
refreshCraftButtonStatus()
|
||||
@@ -279,7 +279,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
// If the player has the required item, use it; otherwise, will take an item from the ItemCodex
|
||||
val selectedItem = playerInventory.itemList.filter { (itm, qty) ->
|
||||
ItemCodex[itm]?.tags?.contains(ingredient.key) == true && qty >= ingredient.qty
|
||||
}.maxByOrNull { it.qty }?.itm ?: ((ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.tags.contains(ingredient.key)) it.key else null }) ?: throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed"))
|
||||
}.maxByOrNull { it.qty }?.itm ?: ((ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.hasTag(ingredient.key)) it.key else null }) ?: throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed"))
|
||||
|
||||
// printdbg(this, "Adding ingredients by tag ${selectedItem} (${ingredient.qty})")
|
||||
selectedItem
|
||||
|
||||
@@ -24,18 +24,18 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
init {
|
||||
ControlPanelCommon.register(this, width, "basegame.graphicscontrolpanel", arrayOf(
|
||||
arrayOf("", { Lang["CREDITS_VFX"] }, "h1"),
|
||||
arrayOf("fx_dither", { Lang["MENU_OPTIONS_DITHER"] }, "toggle"),
|
||||
arrayOf("fx_backgroundblur", { Lang["MENU_OPTIONS_BLUR"] }, "toggle"),
|
||||
arrayOf("maxparticles", { Lang["MENU_OPTIONS_PARTICLES"] }, "spinner,256,1024,256"),
|
||||
arrayOf("fx_dither", { Lang["MENU_OPTIONS_DITHER"] }, "toggle"),
|
||||
arrayOf("fx_backgroundblur", { Lang["MENU_OPTIONS_BLUR"] }, "toggle"),
|
||||
arrayOf("maxparticles", { Lang["MENU_OPTIONS_PARTICLES"] }, "spinner,256,1024,256"),
|
||||
arrayOf("", { Lang["MENU_OPTIONS_DISPLAY"] }, "h1"),
|
||||
arrayOf("screenwidth,screenheight", { Lang["MENU_OPTIONS_RESOLUTION"] }, "typeinres"),
|
||||
arrayOf("screenmagnifying", { Lang["GAME_ACTION_ZOOM"] }, "spinnerd,1.0,2.0,0.05"),
|
||||
arrayOf("screenmagnifyingfilter", { Lang["MENU_OPTIONS_FILTERING_MODE"] }, "textsel,none=MENU_OPTIONS_NONE,bilinear=MENU_OPTIONS_FILTERING_BILINEAR,hq2x=MENU_OPTIONS_FILTERING_HQ2X_DNT"),
|
||||
arrayOf("displayfps", { Lang["MENU_LABEL_FRAMESPERSEC"] }, "spinner,0,300,2"),
|
||||
arrayOf("usevsync", { Lang["MENU_OPTIONS_VSYNC"] }, "toggle"),
|
||||
arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"),
|
||||
arrayOf("screenwidth,screenheight", { Lang["MENU_OPTIONS_RESOLUTION"] }, "typeinres"),
|
||||
arrayOf("screenmagnifying", { Lang["GAME_ACTION_ZOOM"] }, "spinnerd,1.0,2.0,0.05"),
|
||||
arrayOf("screenmagnifyingfilter", { Lang["MENU_OPTIONS_FILTERING_MODE"] }, "textsel,none=MENU_OPTIONS_NONE,bilinear=MENU_OPTIONS_FILTERING_BILINEAR,hq2x=MENU_OPTIONS_FILTERING_HQ2X_DNT"),
|
||||
arrayOf("displayfps", { Lang["MENU_LABEL_FRAMESPERSEC"] }, "spinner,0,300,2"),
|
||||
arrayOf("usevsync", { Lang["MENU_OPTIONS_VSYNC"] }, "toggle"),
|
||||
arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"),
|
||||
arrayOf("", { Lang["MENU_LABEL_STREAMING"] }, "h1"),
|
||||
arrayOf("fx_streamerslayout", { Lang["MENU_OPTIONS_STREAMERS_LAYOUT"] }, "toggle"),
|
||||
arrayOf("fx_streamerslayout", { Lang["MENU_OPTIONS_STREAMERS_LAYOUT"] }, "toggle"),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,6 @@ class UIInventoryFull(
|
||||
//val INVENTORY_CELLS_OFFSET_Y: Int = 107 + (AppLoader.terrarumAppConfig.screenH - internalHeight) / 2
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = true
|
||||
}
|
||||
|
||||
private val SP = "\u3000 "
|
||||
|
||||
@@ -235,7 +235,7 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
||||
if (showSpinner) {
|
||||
val spin = spinner.get(spinnerFrame % 8, spinnerFrame / 8)
|
||||
val offX = UIRemoCon.menubarOffX - UIRemoCon.UIRemoConElement.paddingLeft + 72 + 1
|
||||
val offY = UIRemoCon.menubarOffY - UIRemoCon.UIRemoConElement.lineHeight * 3 + 16
|
||||
val offY = UIRemoCon.menubarOffY - UIRemoCon.UIRemoConElement.lineHeight * 4 + 16
|
||||
batch.draw(spin, offX.toFloat(), offY.toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,17 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
||||
listOf(NullUI/*, transitionalAutosave*/)
|
||||
)
|
||||
|
||||
internal fun queueUpManageScr() { transitionPanel.setCentreUIto(0) }
|
||||
internal fun queueUpNewCharScr() { transitionPanel.setCentreUIto(1) }
|
||||
private val nodesForListing = Yaml(UITitleRemoConYaml.injectedMenuSingleCharSel).parse()
|
||||
private val nodesForManage = Yaml(UITitleRemoConYaml.injectedMenuSingleSaveManage).parse()
|
||||
|
||||
internal fun queueUpManageScr() {
|
||||
transitionPanel.setCentreUIto(0)
|
||||
remoCon.setNewRemoConContents(nodesForManage)
|
||||
}
|
||||
internal fun queueUpNewCharScr() {
|
||||
transitionPanel.setCentreUIto(1)
|
||||
remoCon.setNewRemoConContents(nodesForListing)
|
||||
}
|
||||
|
||||
// internal fun bringAutosaveSelectorUp() { transitionPanel.setRightUIto(1) }
|
||||
// internal fun takeAutosaveSelectorDown() { transitionPanel.setRightUIto(0) }
|
||||
@@ -102,6 +111,10 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
||||
|
||||
internal fun changePanelTo(index: Int) {
|
||||
transitionPanel.requestTransition(index)
|
||||
if (index == 1)
|
||||
remoCon.setNewRemoConContents(nodesForManage)
|
||||
else
|
||||
remoCon.setNewRemoConContents(nodesForListing)
|
||||
}
|
||||
|
||||
override fun advanceMode(button: UIItem) {
|
||||
@@ -118,6 +131,9 @@ class UILoadSavegame(val remoCon: UIRemoCon) : Advanceable() {
|
||||
// takeAutosaveSelectorDown()
|
||||
transitionPanel.show()
|
||||
|
||||
nodesForListing.parent = remoCon.treeRoot
|
||||
nodesForManage.parent = remoCon.treeRoot
|
||||
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
|
||||
@@ -26,11 +26,14 @@ class UIPerformanceControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
arrayOf("", { Lang["MENU_OPTIONS_GAMEPLAY"] }, "h1"),
|
||||
arrayOf("autosaveinterval", { Lang["MENU_OPTIONS_AUTOSAVE"] + " (${Lang["CONTEXT_TIME_MINUTE_PLURAL"]})" }, "spinnerimul,1,120,1,60000"),
|
||||
arrayOf("notificationshowuptime", { Lang["MENU_OPTIONS_NOTIFICATION_DISPLAY_DURATION"] + " (${Lang["CONTEXT_TIME_SECOND_PLURAL"]})" }, "spinnerimul,2,10,1,1000"),
|
||||
arrayOf("", { Lang["MENU_LABEL_GRAPHICS"] }, "h1"),
|
||||
arrayOf("atlastexsize", { Lang["MENU_OPTIONS_ATLAS_TEXTURE_SIZE"] }, "spinnersel,1024,2048,4096,8192"),
|
||||
arrayOf("", { Lang["MENU_LABEL_JVM_DNT"] }, "h1"),
|
||||
arrayOf("jvm_xmx", { Lang["MENU_OPTIONS_JVM_HEAP_MAX"] + " (GB)" }, "spinner,2,32,1"),
|
||||
arrayOf("jvm_extra_cmd", { Lang["MENU_LABEL_EXTRA_JVM_ARGUMENTS"] }, "typein"),
|
||||
arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"),
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override var height = ControlPanelCommon.getMenuHeight("basegame.performancecontrolpanel")
|
||||
|
||||
@@ -18,6 +18,11 @@ import kotlin.math.roundToInt
|
||||
* Created by minjaesong on 2016-07-20.
|
||||
*/
|
||||
class UIQuickslotBar : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
private val cellSize = ItemSlotImageFactory.slotImage.tileW // 38
|
||||
|
||||
private val gutter = 10 - 6 // do -6 to get a gutter size of not-enlarged cells
|
||||
|
||||
@@ -21,6 +21,11 @@ import kotlin.math.roundToInt
|
||||
* Created by minjaesong on 2016-07-20.
|
||||
*/
|
||||
class UIQuickslotPie : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
private val cellSize = ItemSlotImageFactory.slotImage.tileW
|
||||
|
||||
private val slotCount = UIQuickslotBar.SLOT_COUNT
|
||||
|
||||
@@ -21,6 +21,10 @@ class UIScreenZoom : UICanvas(
|
||||
App.getConfigInt("control_key_zoom")
|
||||
) {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
val zoomText = "${getKeycapPC(handler.toggleKeyLiteral!!)} $EMDASH Zoom Out"
|
||||
|
||||
override var width = App.fontGame.getWidth(zoomText)
|
||||
|
||||
@@ -41,6 +41,7 @@ object UITitleRemoConYaml {
|
||||
|
||||
// todo add MENU_IO_IMPORT
|
||||
val injectedMenuSingleCharSel = """
|
||||
- MENU_IO_IMPORT
|
||||
- CONTEXT_CHARACTER_NEW : net.torvald.terrarum.modulebasegame.ui.UINewCharacter
|
||||
- MENU_LABEL_RETURN
|
||||
"""
|
||||
@@ -48,6 +49,12 @@ object UITitleRemoConYaml {
|
||||
val injectedMenuSingleWorldSel = """
|
||||
- CONTEXT_WORLD_NEW : net.torvald.terrarum.modulebasegame.ui.UINewWorld
|
||||
- MENU_LABEL_RETURN
|
||||
"""
|
||||
|
||||
val injectedMenuSingleSaveManage = """
|
||||
- MENU_MODULES
|
||||
- MENU_LABEL_PREV_SAVES
|
||||
- MENU_LABEL_RETURN
|
||||
"""
|
||||
|
||||
operator fun invoke(hasSave: Boolean) =
|
||||
|
||||
@@ -14,6 +14,10 @@ import net.torvald.terrarum.ui.UICanvas
|
||||
*/
|
||||
class UITooltip : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
override var openCloseTime: Second = 0f
|
||||
|
||||
private val tooltipBackCol = Color.WHITE
|
||||
|
||||
@@ -21,6 +21,10 @@ class UIVitalMetre(
|
||||
val order: Int
|
||||
) : UICanvas() {
|
||||
|
||||
init {
|
||||
handler.allowESCtoClose = false
|
||||
}
|
||||
|
||||
init {
|
||||
// semitransparent
|
||||
color?.a = 0.91f
|
||||
|
||||
385
src/net/torvald/terrarum/modulebasegame/ui/UIWallCalendar.kt
Normal file
385
src/net/torvald/terrarum/modulebasegame/ui/UIWallCalendar.kt
Normal file
@@ -0,0 +1,385 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.RunningEnvironment
|
||||
import net.torvald.terrarum.floorToInt
|
||||
import net.torvald.terrarum.gameworld.WorldTime
|
||||
import net.torvald.terrarum.gameworld.WorldTime.Companion.MONTH_LENGTH
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.unicode.getKeycapPC
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-08-15.
|
||||
*/
|
||||
class UIWallCalendar : UICanvas(
|
||||
toggleKeyLiteral = App.getConfigInt("control_key_inventory"),
|
||||
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
||||
) {
|
||||
private val yearCellWidth = 200
|
||||
private val cellWidth = 80
|
||||
private val cellHeight = 24
|
||||
|
||||
override var width: Int = Toolkit.drawWidth
|
||||
override var height: Int = App.scr.height
|
||||
|
||||
private val y = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y() + 1 - 34
|
||||
|
||||
private val drawStartX = (Toolkit.drawWidth - cellWidth * 8) / 2 - 4
|
||||
private val cellsStartY = y + 34
|
||||
|
||||
private val SP = "\u3000 "
|
||||
val controlHelp: String
|
||||
get() = if (App.environment == RunningEnvironment.PC)
|
||||
"${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
|
||||
else
|
||||
"${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]}"
|
||||
|
||||
|
||||
private var todayCell = -1
|
||||
|
||||
private val cellBackCols = listOf(
|
||||
Color(0x3f1e22_C8), // OKLCh 14, 5, 18
|
||||
Color(0x022f3a_C8), // OKLCh 218, 5, 18
|
||||
Color(0x2d2b09_C8), // OKLCh 105, 5, 18
|
||||
Color(0x252934_C8) // OKLCh 265, 2, 18
|
||||
)
|
||||
private val seasonMarkers = listOf(
|
||||
7 to "CONTEXT_CALENDAR_SEASON_SPRING",
|
||||
39 to "CONTEXT_CALENDAR_SEASON_SUMMER",
|
||||
71 to "CONTEXT_CALENDAR_SEASON_AUTUMN",
|
||||
103 to "CONTEXT_CALENDAR_SEASON_WINTER"
|
||||
)
|
||||
|
||||
private var mouseOverCell = -1
|
||||
private var mouseOverSeason = -1
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
mouseOverCell = if (relativeMouseX in drawStartX until drawStartX + 8 * (cellWidth + 1) &&
|
||||
relativeMouseY in cellsStartY - 1 until cellsStartY - 1 + 17 * (cellHeight + 3)) {
|
||||
|
||||
val x = (relativeMouseX - drawStartX) / (cellWidth + 1)
|
||||
val y = (relativeMouseY - cellsStartY + 1) / (cellHeight + 3)
|
||||
|
||||
// disable highlighting on invalid date (verddag and not winter 30)
|
||||
if (x == 7 && y < 16) -1
|
||||
else y * 8 + x
|
||||
}
|
||||
else -1
|
||||
|
||||
mouseOverSeason = when (mouseOverCell) {
|
||||
-1 -> -1
|
||||
in 0 until 34 -> 0
|
||||
in 34 until 68 -> 1
|
||||
in 68 until 102 -> 2
|
||||
else -> 3
|
||||
}
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
UIInventoryFull.drawBackground(batch, 1f)
|
||||
|
||||
val thisYear = INGAME.world.worldTime.years
|
||||
val today = INGAME.world.worldTime.ordinalDay + 1
|
||||
val todayOfWeek = INGAME.world.worldTime.dayOfWeek
|
||||
|
||||
// cell background
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, (width - yearCellWidth) / 2, y - 34, yearCellWidth, 24)
|
||||
for (week in 0..7) {
|
||||
Toolkit.fillArea(batch, drawStartX + (cellWidth + 1) * week + 1, y, cellWidth - 2, 24)
|
||||
}
|
||||
for (cellNum in 0 until 17 * 8) {
|
||||
batch.color = when (cellNum) {
|
||||
in 0 until 34 -> cellBackCols[0]
|
||||
in 34 until 68 -> cellBackCols[1]
|
||||
in 68 until 102 -> cellBackCols[2]
|
||||
else -> cellBackCols[3]
|
||||
}
|
||||
if (cellNum % 8 != 7 || cellNum == 17 * 8 - 1) {
|
||||
Toolkit.fillArea(batch, drawStartX + (cellWidth + 1) * (cellNum % 8) + 1, cellsStartY + (cellHeight + 3) * (cellNum / 8), cellWidth - 2, cellHeight)
|
||||
}
|
||||
}
|
||||
// season name cell background
|
||||
for (k in 0..3) {
|
||||
batch.color = cellBackCols[k]
|
||||
Toolkit.fillArea(batch, drawStartX + (cellWidth + 1) * 7 + 1, cellsStartY + (cellHeight + 3) * (k * 4), cellWidth - 2, (cellHeight + 3) * 4 - 3)
|
||||
}
|
||||
|
||||
|
||||
// cell border
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, (width - yearCellWidth) / 2 - 1, y - 35, yearCellWidth + 2, 26)
|
||||
Toolkit.drawBoxBorder(batch, drawStartX, y - 1, 8 * (cellWidth + 1) - 1, 26)
|
||||
for (week in 0..7) {
|
||||
Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * week, y - 1, cellWidth, 26)
|
||||
}
|
||||
// highlight a day name of mouse-up
|
||||
batch.color = Toolkit.Theme.COL_MOUSE_UP
|
||||
if (mouseOverCell >= 0) Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * (mouseOverCell % 8), y - 1, cellWidth, 26)
|
||||
// highlight today's week name
|
||||
batch.color = Toolkit.Theme.COL_SELECTED
|
||||
Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * todayOfWeek, y - 1, cellWidth, 26)
|
||||
|
||||
|
||||
// draw days grid
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, drawStartX, cellsStartY - 1, 8 * (cellWidth + 1) - 1, 17 * (cellHeight + 3) - 1)
|
||||
// non-season-name-cells
|
||||
for (cellNum in 0 until 17 * 8) {
|
||||
if (cellNum % 8 != 7 || cellNum == 17 * 8 - 1) {
|
||||
Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * (cellNum % 8), cellsStartY + (cellHeight + 3) * (cellNum / 8) - 1, cellWidth, cellHeight + 2)
|
||||
}
|
||||
}
|
||||
// season-name-cells
|
||||
for (k in 0..3) {
|
||||
Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * 7, cellsStartY + (cellHeight + 3) * (k * 4) - 1, cellWidth, (cellHeight + 3) * 4 - 1)
|
||||
}
|
||||
// highlight a day of mouse-up
|
||||
batch.color = Toolkit.Theme.COL_MOUSE_UP
|
||||
if (mouseOverCell >= 0) Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * (mouseOverCell % 8), cellsStartY + (cellHeight + 3) * (mouseOverCell / 8) - 1, cellWidth, cellHeight + 2)
|
||||
|
||||
|
||||
// season border
|
||||
batch.color = Toolkit.Theme.COL_MOUSE_UP
|
||||
if (mouseOverSeason == 0) {
|
||||
Toolkit.drawStraightLine(batch,
|
||||
drawStartX,
|
||||
cellsStartY - 2,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX - 1,
|
||||
cellsStartY - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 5 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
cellsStartY - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 4 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason in 0..1) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 5 - 3,
|
||||
drawStartX + (cellWidth + 1) * 2 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 2 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 4 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 5 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 4 - 3,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason == 1) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 5 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 9 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 4 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 8 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason in 1..2) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 9 - 3,
|
||||
drawStartX + (cellWidth + 1) * 4 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 4 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 8 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 9 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 4,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 8 - 3,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason == 2) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 9 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 13 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 8 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 12 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason in 2..3) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 13 - 3,
|
||||
drawStartX + (cellWidth + 1) * 6 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 6 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 12 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 13 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 6,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 12 - 3,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
}
|
||||
if (mouseOverSeason == 3) {
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 13 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 17 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(
|
||||
batch,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 12 - 2,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 17 - 3,
|
||||
1,
|
||||
true
|
||||
)
|
||||
Toolkit.drawStraightLine(batch,
|
||||
drawStartX,
|
||||
cellsStartY + 1 + (cellHeight + 3) * 17 - 3,
|
||||
drawStartX + (cellWidth + 1) * 8 - 1,
|
||||
1,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
// cell texts
|
||||
batch.color = Toolkit.Theme.COL_LIST_DEFAULT
|
||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang.getAndUseTemplate("CONTEXT_CALENDAR_DATE_FORMAT_Y", false, thisYear), yearCellWidth, (width - yearCellWidth) / 2, y - 34)
|
||||
for (week in 0..7) {
|
||||
// highlight this week and the mouse-up
|
||||
batch.color = if (week == todayOfWeek) Toolkit.Theme.COL_SELECTED else if (week == mouseOverCell % 8) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
|
||||
|
||||
val t = WorldTime.getDayName(week)
|
||||
val tlen = App.fontGame.getWidth(t)
|
||||
App.fontGame.draw(batch, t, drawStartX + (cellWidth + 1) * week + (cellWidth - tlen) / 2, y)
|
||||
}
|
||||
var dayAkku = 1
|
||||
for (cellNum in 0 until 17 * 8) {
|
||||
val day = if (cellNum == 17*8-1) 120 else if (cellNum % 8 == 7) 0 else dayAkku
|
||||
|
||||
if (day > 0) {
|
||||
// highlight today and the mouse-up
|
||||
batch.color = if (day == today) Toolkit.Theme.COL_SELECTED else if (cellNum == mouseOverCell) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
|
||||
|
||||
val t = "${(day % MONTH_LENGTH).let { if (it == 0) MONTH_LENGTH else it }}".padStart(2, '\u2007')
|
||||
App.fontGame.draw(batch, t, drawStartX + (cellWidth + 1) * (cellNum % 8) - 20 + cellWidth - 4, cellsStartY + (cellHeight + 3) * (cellNum / 8))
|
||||
|
||||
if (day == today) todayCell = cellNum
|
||||
|
||||
dayAkku += 1
|
||||
}
|
||||
}
|
||||
// draw seasonal names
|
||||
seasonMarkers.forEachIndexed { index, (cellNum, key) ->
|
||||
batch.color = if (index == mouseOverSeason) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawTextCentered(batch, App.fontGame, Lang[key], cellWidth, drawStartX + (cellWidth + 1) * (cellNum % 8), cellsStartY + (cellHeight + 3) * (cellNum / 8) + ((cellHeight + 3) * 1.5f).floorToInt())
|
||||
}
|
||||
|
||||
// highlight today cell
|
||||
if (todayCell >= 0) {
|
||||
batch.color = Toolkit.Theme.COL_SELECTED
|
||||
Toolkit.drawBoxBorder(batch, drawStartX + (cellWidth + 1) * (todayCell % 8), cellsStartY + (cellHeight + 3) * (todayCell / 8) - 1, cellWidth, cellHeight + 2)
|
||||
}
|
||||
|
||||
// control hints
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, controlHelp, drawStartX + 2, cellsStartY+ 17 * (cellHeight + 3) + 6)
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
INGAME.pause()
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun doClosing(delta: Float) {
|
||||
super.doClosing(delta)
|
||||
INGAME.resume()
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
super.endOpening(delta)
|
||||
UIItemInventoryItemGrid.tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
super.endClosing(delta)
|
||||
UIItemInventoryItemGrid.tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
App.fontSmallNumbers.draw(batch, "${if (player.jumping) "$ccG" else "$ccK"}JM", gap + 7f*(jX + 8), line(jY))
|
||||
App.fontSmallNumbers.draw(batch, "${if (player.isJumpDown) "$ccG" else "$ccK"}KY", gap + 7f*(jX + 8), line(jY+1))
|
||||
|
||||
App.fontSmallNumbers.draw(batch, "${if (player.downDownVirtually) "$ccG" else "$ccK"}$ARROW_DOWN", gap + 7f*(jX + 11), line(jY+1))
|
||||
App.fontSmallNumbers.draw(batch, "${if (player.downButtonHeld > 0) "$ccG" else "$ccK"}$ARROW_DOWN", gap + 7f*(jX + 11), line(jY+1))
|
||||
|
||||
App.fontSmallNumbers.draw(batch, "$WIDTH$ccG${player.hitbox.width.toString().padEnd(5).substring(0,5).trim()}$ccY$HEIGHT$ccG${player.hitbox.height.toString().padEnd(5).substring(0,5)}", gap + 7f*(jX + 13), line(jY))
|
||||
App.fontSmallNumbers.draw(batch, "$MASS$ccG${player.mass.toString().padEnd(8).substring(0,8)}", gap + 7f*(jX + 13), line(jY+1))
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.badlogic.gdx.graphics.*
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.graphics.glutils.FloatFrameBuffer
|
||||
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.random.HQRNG
|
||||
@@ -48,9 +48,9 @@ object Toolkit : Disposable {
|
||||
private val shaderBoxDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxdown.frag")
|
||||
private val shaderBoxUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxup.frag")
|
||||
|
||||
private lateinit var fboBlur: FloatFrameBuffer
|
||||
private lateinit var fboBlurHalf: FloatFrameBuffer
|
||||
private lateinit var fboBlurQuarter: FloatFrameBuffer
|
||||
private lateinit var fboBlur: Float16FrameBuffer
|
||||
private lateinit var fboBlurHalf: Float16FrameBuffer
|
||||
private lateinit var fboBlurQuarter: Float16FrameBuffer
|
||||
private lateinit var blurWriteQuad: Mesh
|
||||
private lateinit var blurWriteQuad2: Mesh
|
||||
private lateinit var blurWriteQuad4: Mesh
|
||||
@@ -326,17 +326,17 @@ object Toolkit : Disposable {
|
||||
val fw = App.scr.width//MathUtils.nextPowerOfTwo(App.scr.width)
|
||||
val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height)
|
||||
|
||||
fboBlur = FloatFrameBuffer(
|
||||
fboBlur = Float16FrameBuffer(
|
||||
fw,
|
||||
fh,
|
||||
false
|
||||
)
|
||||
fboBlurHalf = FloatFrameBuffer(
|
||||
fboBlurHalf = Float16FrameBuffer(
|
||||
fw / 2,
|
||||
fh / 2,
|
||||
false
|
||||
)
|
||||
fboBlurQuarter = FloatFrameBuffer(
|
||||
fboBlurQuarter = Float16FrameBuffer(
|
||||
fw / 4,
|
||||
fh / 4,
|
||||
false
|
||||
|
||||
@@ -30,7 +30,7 @@ class UIHandler(//var UI: UICanvas,
|
||||
// UI positions itself? (you must g.flush() yourself after the g.translate(Int, Int))
|
||||
var customPositioning: Boolean = false, // mainly used by vital meter
|
||||
var doNotWarnConstant: Boolean = false,
|
||||
internal var allowESCtoClose: Boolean = false,
|
||||
internal var allowESCtoClose: Boolean = true,
|
||||
var uiTogglerFunctionDefault: ((UIHandler) -> Unit)? = null
|
||||
): Disposable {
|
||||
|
||||
@@ -214,7 +214,7 @@ void main() {
|
||||
}
|
||||
|
||||
// ESC is a master key for closing
|
||||
if (allowESCtoClose && Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE) && isOpened) {
|
||||
if (!alwaysVisible && allowESCtoClose && Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE) && isOpened) {
|
||||
setAsClose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ import kotlin.math.roundToInt
|
||||
*/
|
||||
|
||||
class UIItemSpinner(
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
private var initialValue: Number,
|
||||
val min: Number,
|
||||
val max: Number,
|
||||
val step: Number,
|
||||
override val width: Int,
|
||||
private val drawBorder: Boolean = true,
|
||||
private val numberToTextFunction: (Number) -> String = { "$it" }
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
private var initialValue: Number,
|
||||
val min: Number,
|
||||
val max: Number,
|
||||
val step: Number,
|
||||
override val width: Int,
|
||||
private val drawBorder: Boolean = true,
|
||||
private val numberToTextFunction: (Number) -> String = { "$it" }
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
// to alleviate floating point errors adding up as the spinner is being used
|
||||
|
||||
@@ -17,13 +17,14 @@ import net.torvald.terrarum.gameworld.fmod
|
||||
* Created by minjaesong on 2021-10-21.
|
||||
*/
|
||||
class UIItemTextSelector(
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
val labelfuns: List<() -> String>,
|
||||
initialSelection: Int,
|
||||
override val width: Int,
|
||||
private val drawBorder: Boolean = true,
|
||||
private val clickToShowPalette: Boolean = true
|
||||
parentUI: UICanvas,
|
||||
initialX: Int, initialY: Int,
|
||||
val labelfuns: List<() -> String>,
|
||||
initialSelection: Int,
|
||||
override val width: Int,
|
||||
private val drawBorder: Boolean = true,
|
||||
private val clickToShowPalette: Boolean = true,
|
||||
private val useSpinnerButtons: Boolean = false,
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
init {
|
||||
@@ -127,6 +128,9 @@ class UIItemTextSelector(
|
||||
else if (!Terrarum.mouseDown) mouseLatched = false
|
||||
}
|
||||
|
||||
private val leftIcon = if (useSpinnerButtons) labels.get(9,2) else labels.get(16,0)
|
||||
private val rightIcon = if (useSpinnerButtons) labels.get(10,2) else labels.get(17,0)
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
labelCache = labelfuns.map { it() }
|
||||
|
||||
@@ -184,12 +188,12 @@ class UIItemTextSelector(
|
||||
// left button icon
|
||||
batch.color = if (mouseOnButton == 1 && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseOnButton == 1) Toolkit.Theme.COL_MOUSE_UP else UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
batch.draw(labels.get(16,0), posX + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
batch.draw(leftIcon, posX + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
|
||||
// right button icon
|
||||
batch.color = if (mouseOnButton == 2 && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseOnButton == 2) Toolkit.Theme.COL_MOUSE_UP else UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
batch.draw(labels.get(17,0), posX + width - buttonW + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
batch.draw(rightIcon, posX + width - buttonW + (buttonW - labels.tileW) / 2f, posY + (height - labels.tileH) / 2f)
|
||||
|
||||
// draw text
|
||||
if (!paletteShowing) {
|
||||
|
||||
@@ -155,7 +155,7 @@ internal object WeatherMixer : RNGConsumer {
|
||||
}
|
||||
|
||||
var turbidity = 1.0; private set
|
||||
private var gH = 1.4f * App.scr.height
|
||||
private var gH = 1.8f * App.scr.height
|
||||
// private var gH = 0.8f * App.scr.height
|
||||
|
||||
internal var parallaxPos = 0f; private set
|
||||
|
||||
@@ -349,7 +349,7 @@ internal object BlocksDrawer {
|
||||
val tileNumber = if (thisTile == Block.AIR) 0
|
||||
// special case: actorblocks and F3 key
|
||||
else if (BlockCodex.hasProp(thisTile) && BlockCodex[thisTile].isActorBlock &&
|
||||
!BlockCodex[thisTile].tags.contains("DORENDER") && !KeyToggler.isOn(Keys.F3))
|
||||
!BlockCodex[thisTile].hasTag("DORENDER") && !KeyToggler.isOn(Keys.F3))
|
||||
0
|
||||
// special case: fluids
|
||||
else if (mode == FLUID)
|
||||
|
||||
@@ -6,7 +6,9 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.gdx.graphics.PixmapIO2
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
@@ -15,6 +17,7 @@ import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.AtlasSource.*
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/**
|
||||
* This class implements work_files/dynamic_shape_2_0.psd
|
||||
@@ -28,13 +31,12 @@ import kotlin.math.roundToInt
|
||||
*/
|
||||
class CreateTileAtlas {
|
||||
|
||||
// min size 1024 = tile_size 16 * atlasCursor 64
|
||||
val MAX_TEX_SIZE = App.getConfigInt("atlastexsize").coerceIn(1024, App.glInfo.GL_MAX_TEXTURE_SIZE)
|
||||
val TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE
|
||||
var MAX_TEX_SIZE = App.getConfigInt("atlastexsize").coerceIn(1024, App.glInfo.GL_MAX_TEXTURE_SIZE); private set
|
||||
var TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE; private set
|
||||
|
||||
val SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat())
|
||||
var SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat()); private set
|
||||
|
||||
private val TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
private var TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
|
||||
val wallOverlayColour = Color(.65f, .65f, .65f, 1f)
|
||||
|
||||
@@ -66,12 +68,54 @@ class CreateTileAtlas {
|
||||
private val atlasInit = "./assets/graphics/blocks/init.tga"
|
||||
private var itemSheetCursor = 16
|
||||
|
||||
internal val itemTerrainPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemTerrainPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemWallPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemWallPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal lateinit var itemTerrainPixmap: Pixmap
|
||||
internal lateinit var itemTerrainPixmapGlow: Pixmap
|
||||
internal lateinit var itemWallPixmap: Pixmap
|
||||
internal lateinit var itemWallPixmapGlow: Pixmap
|
||||
|
||||
|
||||
private fun drawInitPixmap() {
|
||||
val initPixmap = Pixmap(Gdx.files.internal(atlasInit))
|
||||
|
||||
val tilesInInitPixmap = (initPixmap.width * initPixmap.height) / (TILE_SIZE * TILE_SIZE)
|
||||
val tilesPossibleInCurrentPixmap = (atlas.width * atlas.height) / (TILE_SIZE * TILE_SIZE)
|
||||
|
||||
if (tilesInInitPixmap > tilesPossibleInCurrentPixmap) throw Error("Atlas size too small -- can't even fit the init.tga (MAX_TEX_SIZE must be at least ${FastMath.nextPowerOfTwo((sqrt(tilesInInitPixmap.toFloat()) * TILE_SIZE).ceilToInt())})")
|
||||
|
||||
if (MAX_TEX_SIZE >= initPixmap.width) {
|
||||
atlas.drawPixmap(initPixmap, 0, 0)
|
||||
atlasAutumn.drawPixmap(initPixmap, 0, 0)
|
||||
atlasWinter.drawPixmap(initPixmap, 0, 0)
|
||||
atlasSpring.drawPixmap(initPixmap, 0, 0)
|
||||
}
|
||||
else {
|
||||
/*
|
||||
What's happening:
|
||||
|
||||
src: dest:
|
||||
AAAABBBBCCCCDDDD AAAA
|
||||
BBBB
|
||||
CCCC
|
||||
DDDD
|
||||
*/
|
||||
val destX = 0
|
||||
val srcY = 0
|
||||
val scanW = MAX_TEX_SIZE
|
||||
val scanH = TILE_SIZE
|
||||
for (scantile in 0 until (initPixmap.width.toFloat() / MAX_TEX_SIZE).ceilToInt()) {
|
||||
val srcX = scantile * scanW
|
||||
val destY = scantile * TILE_SIZE
|
||||
|
||||
atlas.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasAutumn.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasWinter.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasSpring.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
}
|
||||
}
|
||||
|
||||
initPixmap.dispose()
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called AFTER mods' loading so that all the block props are loaded
|
||||
*/
|
||||
@@ -80,27 +124,17 @@ class CreateTileAtlas {
|
||||
tags = HashMap<ItemID, RenderTag>()
|
||||
itemSheetNumbers = HashMap<ItemID, Int>()
|
||||
|
||||
atlas = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasAutumn = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasWinter = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasSpring = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasFluid = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
|
||||
atlas.blending = Pixmap.Blending.None
|
||||
atlasAutumn.blending = Pixmap.Blending.None
|
||||
atlasWinter.blending = Pixmap.Blending.None
|
||||
atlasSpring.blending = Pixmap.Blending.None
|
||||
atlasFluid.blending = Pixmap.Blending.None
|
||||
atlasGlow.blending = Pixmap.Blending.None
|
||||
atlas = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasAutumn = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasWinter = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasSpring = 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 }
|
||||
|
||||
// populate the atlantes with atlasInit
|
||||
// this just directly copies the image to the atlantes :p
|
||||
val initPixmap = Pixmap(Gdx.files.internal(atlasInit))
|
||||
atlas.drawPixmap(initPixmap, 0, 0)
|
||||
atlasAutumn.drawPixmap(initPixmap, 0, 0)
|
||||
atlasWinter.drawPixmap(initPixmap, 0, 0)
|
||||
atlasSpring.drawPixmap(initPixmap, 0, 0)
|
||||
drawInitPixmap()
|
||||
|
||||
|
||||
// get all the files applicable
|
||||
// first, get all the '/blocks' directory, and add all the files, regardless of their extension, to the list
|
||||
@@ -135,8 +169,8 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
// test print
|
||||
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlas.tga"), atlas, false)
|
||||
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlasGlow.tga"), atlasGlow, false)
|
||||
// PixmapIO2.writeTGA(Gdx.files.absolute("${App.defaultDir}/atlas.tga"), atlas, false)
|
||||
// PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlasGlow.tga"), atlasGlow, false)
|
||||
|
||||
|
||||
|
||||
@@ -161,6 +195,11 @@ class CreateTileAtlas {
|
||||
// val itemTerrainPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
// val itemWallPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
tags.toMap().forEach { id, tag ->
|
||||
val tilePosFromAtlas = tag.tileNumber + maskTypetoTileIDForItemImage(tag.maskType)
|
||||
val srcX = (tilePosFromAtlas % TILES_IN_X) * TILE_SIZE
|
||||
@@ -217,7 +256,6 @@ class CreateTileAtlas {
|
||||
itemWallTextureGlow = Texture(itemWallPixmapGlow)
|
||||
// itemTerrainPixmap.dispose()
|
||||
// itemWallPixmap.dispose()
|
||||
initPixmap.dispose()
|
||||
|
||||
initialised = true
|
||||
} }
|
||||
@@ -242,6 +280,7 @@ class CreateTileAtlas {
|
||||
val blockName = matte.nameWithoutExtension().split('-').last().toInt() // basically a filename
|
||||
val blockID = "$modname:$blockName"
|
||||
|
||||
|
||||
// determine the type of the block (populate tags list)
|
||||
// predefined by the image dimension: 16x16 for (1,0)
|
||||
if (tilesPixmap.width == TILE_SIZE && tilesPixmap.height == TILE_SIZE) {
|
||||
@@ -307,8 +346,10 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
private fun drawToAtlantes(matte: Pixmap, glow: Pixmap, tilesCount: Int) {
|
||||
if (atlasCursor >= TOTAL_TILES) {
|
||||
throw Error("Too much tiles for $MAX_TEX_SIZE texture size: $atlasCursor")
|
||||
if (atlasCursor + tilesCount >= TOTAL_TILES) {
|
||||
// throw Error("Too much tiles for $MAX_TEX_SIZE texture size: $atlasCursor")
|
||||
println("[CreateTileAtlas] Too much tiles for atlas of ${MAX_TEX_SIZE}x$MAX_TEX_SIZE (tiles so far: $atlasCursor/${(MAX_TEX_SIZE*MAX_TEX_SIZE)/(TILE_SIZE* TILE_SIZE)}, tiles to be added: $tilesCount), trying to expand the atlas...")
|
||||
expandAtlantes()
|
||||
}
|
||||
|
||||
val seasonal = matte.width == matte.height && matte.width == 14 * TILE_SIZE
|
||||
@@ -413,4 +454,60 @@ class CreateTileAtlas {
|
||||
private enum class AtlasSource {
|
||||
FOUR_SEASONS, SUMMER, AUTUMN, WINTER, SPRING, FLUID, GLOW
|
||||
}
|
||||
|
||||
private fun expandAtlantes() {
|
||||
if (MAX_TEX_SIZE >= App.glInfo.GL_MAX_TEXTURE_SIZE) {
|
||||
throw RuntimeException("Cannot expand atlas: texture size is already at its maximum possible size allowed by the graphics processor (${MAX_TEX_SIZE}x${MAX_TEX_SIZE})")
|
||||
}
|
||||
|
||||
val oldTexSize = MAX_TEX_SIZE
|
||||
val newTexSize = oldTexSize * 2
|
||||
|
||||
|
||||
MAX_TEX_SIZE = newTexSize
|
||||
TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE
|
||||
SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat())
|
||||
TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
|
||||
|
||||
val newAtlantes = Array<Pixmap>(5) {
|
||||
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(atlas, atlasAutumn, atlasWinter, atlasSpring, atlasGlow).forEachIndexed { index, pixmap ->
|
||||
/*
|
||||
How it works:
|
||||
|
||||
old: new:
|
||||
AAAAAAAA AAAAAAAABBBBBBBB
|
||||
BBBBBBBB CCCCCCCCDDDDDDDD
|
||||
CCCCCCCC ...
|
||||
DDDDDDDD
|
||||
...
|
||||
|
||||
*/
|
||||
for (scantile in 0 until pixmap.height / TILE_SIZE) {
|
||||
val srcX = 0
|
||||
val srcY = scantile * TILE_SIZE
|
||||
val destX = (scantile % 2) * oldTexSize
|
||||
val destY = (scantile / 2) * TILE_SIZE
|
||||
val scanW = pixmap.width
|
||||
val scanH = TILE_SIZE
|
||||
|
||||
newAtlantes[index].drawPixmap(pixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
}
|
||||
pixmap.dispose()
|
||||
}
|
||||
|
||||
atlas = newAtlantes[0]
|
||||
atlasAutumn = newAtlantes[1]
|
||||
atlasWinter = newAtlantes[2]
|
||||
atlasSpring = newAtlantes[3]
|
||||
atlasGlow = newAtlantes[4]
|
||||
|
||||
|
||||
App.setConfig("atlastexsize", newTexSize)
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,12 @@ object FeaturesDrawer {
|
||||
TileSurvey.submitProposal(
|
||||
TileSurvey.SurveyProposal(
|
||||
"basegame.FeaturesDrawer.coldTiles", 72, 48, 2, 2
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].tags.contains("COLD") }
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].hasTag("COLD") }
|
||||
)
|
||||
TileSurvey.submitProposal(
|
||||
TileSurvey.SurveyProposal(
|
||||
"basegame.FeaturesDrawer.warmTiles", 72, 48, 2, 2
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].tags.contains("WARM") }
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].hasTag("WARM") }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
package org.dyn4j.geometry
|
||||
|
||||
import org.dyn4j.Epsilon
|
||||
import kotlin.math.sign
|
||||
|
||||
/**
|
||||
* This class represents a vector or point in 2D space.
|
||||
@@ -699,6 +700,9 @@ class Vector2 {
|
||||
return a
|
||||
}
|
||||
|
||||
val signum: Vector2
|
||||
get() = Vector2(this.x.sign, this.y.sign)
|
||||
|
||||
companion object {
|
||||
/** A vector representing the x-axis; this vector should not be changed at runtime; used internally */
|
||||
internal val X_AXIS = Vector2(1.0, 0.0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#version 150
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ PlainText = ? regular string but does not contain { c U r L y } brackets ? ;
|
||||
function ShowMsg(string: String, vararg args: String) { ... } // pre-defined
|
||||
|
||||
val m = "Give {0} {P.0 1} to {2.ACC}"
|
||||
ShowMsg(m, 42, "GAME_ITEM_COAL", conversationTarget.actorValue.name)
|
||||
ShowMsg(m, 42, "ITEM_COAL", conversationTarget.actorValue.name)
|
||||
|
||||
val m2 = "{0}{G.0 을 를} 찾을 수 없습니다"
|
||||
ShowMsg(m2, something)
|
||||
|
||||
BIN
work_files/graphics/sprites/fixtures/electronics_workbench.kra
LFS
Normal file
BIN
work_files/graphics/sprites/fixtures/electronics_workbench.kra
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user