Compare commits

...

22 Commits

Author SHA1 Message Date
minjaesong
3d5fd984d7 another text pos change 2023-06-06 18:23:28 +09:00
minjaesong
8d0d84fbf8 font update/ime fix 2023-06-06 18:16:34 +09:00
minjaesong
eb2c716691 code for new itemsheet format 2023-06-06 14:37:54 +09:00
minjaesong
ac53f821e2 new format for item sprites; code upcoming ;) 2023-06-05 23:38:47 +09:00
minjaesong
cd6df71347 world portal listing: back tray for texts 2023-06-04 21:21:48 +09:00
minjaesong
ac553ed156 serialiser filters Companion objs 2023-06-01 17:50:39 +09:00
minjaesong
8c5c986cbf wider inventory cells 2023-05-31 21:07:57 +09:00
minjaesong
a0f597865e using Delete instead of Delete World 2023-05-30 01:07:07 +09:00
minjaesong
bafd0d9f7c ui theme updates 2023-05-30 00:51:32 +09:00
minjaesong
e259fc2f3b world size classification is now Tiny-Small-Big-Huge 2023-05-29 20:43:17 +09:00
minjaesong
ebbb121b8c fix: fixture pickup avail check is now done properly 2023-05-29 20:10:39 +09:00
minjaesong
331e89b4df world portal listing gui 2023-05-29 17:51:15 +09:00
minjaesong
98a6c9ae70 world portal gui wip 2023-05-29 02:41:59 +09:00
minjaesong
1646871ddf removing 'small' world size for new worlds: gamedesign choice 2023-05-28 21:31:14 +09:00
minjaesong
76bfc0fde4 world portal gui wip 2023-05-28 20:55:47 +09:00
minjaesong
ef6f39632d world portal wip 2023-05-28 18:41:21 +09:00
minjaesong
a3ecd4a4f4 some adjustments for the quickslot and pie 2023-05-28 01:47:17 +09:00
minjaesong
065f80224f fix: light/shadebox would get tilewise size of 2 when their hitbox size is set to 16 2023-05-28 00:31:29 +09:00
minjaesong
34fb046968 minor changes to the graphics control panel 2023-05-27 23:31:21 +09:00
minjaesong
43da6cc5d8 adding Char to QuickDirtyLint 2023-05-23 20:50:19 +09:00
minjaesong
fccc2162f6 quick and dirty but working linter 2023-05-23 00:09:11 +09:00
minjaesong
c554df9b98 trying the android linter for code inspection 2023-05-22 21:33:39 +09:00
125 changed files with 1385 additions and 254 deletions

14
.idea/libraries/io_github_classgraph.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="io.github.classgraph" type="repository">
<properties maven-id="io.github.classgraph:classgraph:4.8.157" />
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/classgraph-4.8.157.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/lib/classgraph-4.8.157-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/classgraph-4.8.157-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -16,5 +16,6 @@
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
<orderEntry type="library" name="io.github.classgraph" level="project" />
</component>
</module>

View File

@@ -24,5 +24,6 @@
<orderEntry type="library" name="badlogicgames.gdx.backend.lwjgl3" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
<orderEntry type="library" name="io.github.classgraph" level="project" />
</component>
</module>

BIN
assets/graphics/gui/hrule.tga LFS Normal file

Binary file not shown.

View File

@@ -26,5 +26,6 @@
"MENU_LABEL_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Cliboard",
"MENU_OPTIONS_PERFORMANCE": "Performance"
"MENU_OPTIONS_PERFORMANCE": "Performance",
"MENU_LABEL_DELETE": "Delete"
}

View File

@@ -14,4 +14,6 @@ id;classname
258;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorBirch
259;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorRosewood
320;net.torvald.terrarum.modulebasegame.gameitems.ItemWorldPortal
999999;net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry
1 id classname
14 259 net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorRosewood
15 999999 320 net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry net.torvald.terrarum.modulebasegame.gameitems.ItemWorldPortal
16 999999 net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry
17
18
19

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -16,5 +16,8 @@
"GAME_ACTION_QUICKSEL": "Quick Select",
"GAME_ACTION_CRAFT": "Craft",
"GAME_CRAFTING": "Crafting",
"GAME_CRAFTABLE_ITEMS": "Craftable Items"
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
"CONTEXT_WORLD_SEARCH": "World Search",
"CONTEXT_WORLD_LIST": "Worlds List",
"MENU_LABEL_RENAME": "Rename"
}

Binary file not shown.

View File

@@ -1,11 +1,11 @@
id;drop;name;renderclass;accept;inputcount;inputtype;outputtype;javaclass;inventoryimg;branching
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,9;1
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,10;1
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,11;1
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,2;1
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,2,9;1
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,3,9;1
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,4,9;1
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,4;1
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,1,4;1
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,2,4;1
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,0;1
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,3,4;1
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,4,4;1
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,5,4;1
# accept: which wiretype (defined elsewhere) the wires acceps. Use comma to separate multiple. N/A for electronic components (aka not wires)
1 id drop name renderclass accept inputcount inputtype outputtype javaclass inventoryimg branching
2 8192 8192 WIRE_RED signal digital_bit 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,1,9 basegame.items,0,4 1
3 8193 8193 WIRE_GREEN signal digital_bit 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,1,10 basegame.items,1,4 1
4 8194 8194 WIRE_BLUE signal digital_bit 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,1,11 basegame.items,2,4 1
5 #8195 8195 WIRE_BUNDLE signal digital_3bits 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,1,2 basegame.items,0,0 1
6 8196 8196 WIRE_POWER_LOW power power_low 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,2,9 basegame.items,3,4 1
7 8197 8197 WIRE_POWER_HIGH power power_high 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,3,9 basegame.items,4,4 1
8 8198 8198 WIRE_ETHERNET network 10base2 3 N/A N/A net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire basegame.items16,4,9 basegame.items,5,4 1
9 # accept: which wiretype (defined elsewhere) the wires acceps. Use comma to separate multiple. N/A for electronic components (aka not wires)
10 # inputcount: how many sides are input (outputcount is deduced from the inputcount). N/A for wires
11 # inputtype: which wiretype it accepts. N/A for wires

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/android-lint/kxml2-2.3.0.jar LFS Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.android.tools.lint</groupId>
<artifactId>lint</artifactId>
<version>31.0.1</version>
<name>com.android.tools.lint.lint</name>
<description>Lint tools. Both a Command line tool and a library to add lint features to other tools</description>
<url>http://tools.android.com/</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>The Android Open Source Project</name>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>com.android.tools.lint</groupId>
<artifactId>lint-api</artifactId>
<version>31.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.android.tools.lint</groupId>
<artifactId>lint-checks</artifactId>
<version>31.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.android.tools.external.com-intellij</groupId>
<artifactId>intellij-core</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.external.com-intellij</groupId>
<artifactId>kotlin-compiler</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.external.org-jetbrains</groupId>
<artifactId>uast</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.analytics-library</groupId>
<artifactId>protos</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.analytics-library</groupId>
<artifactId>shared</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.analytics-library</groupId>
<artifactId>tracker</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.build</groupId>
<artifactId>manifest-merger</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools</groupId>
<artifactId>common</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools.layoutlib</groupId>
<artifactId>layoutlib-api</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools</groupId>
<artifactId>sdk-common</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.android.tools</groupId>
<artifactId>sdklib</artifactId>
<version>31.0.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>1.7.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.7.10</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/android-lint/uast-31.0.1.jar LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/classgraph-4.8.157.jar LFS Normal file

Binary file not shown.

View File

@@ -118,6 +118,7 @@ object CommonResourcePool {
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)
fun getAsTexture(identifier: String) = getAs<Texture>(identifier)
fun getAsItemSheet(identifier: String) = getAs<ItemSheet>(identifier)
fun dispose() {
pool.forEach { (name, u) ->

View File

@@ -0,0 +1,49 @@
package net.torvald.terrarum
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2023-06-06.
*/
class ItemSheet(ref: FileHandle, tileW: Int = 48, tileH: Int = 48) : Disposable {
private val textureRegionPack = TextureRegionPack(ref, tileW, tileH + 1)
init {
val pixmap = Pixmap(ref)
for (y in 0 until textureRegionPack.verticalCount) {
for (x in 0 until textureRegionPack.horizontalCount) {
var w = 0
var h = 0
for (i in 0..7) {
// width
w = w or (pixmap.getPixel(x * tileW + i, y * (tileH + 1)).and(255) > 127).toInt(7 - i)
// height
h = h or (pixmap.getPixel(x * tileW + i + 8, y * (tileH + 1)).and(255) > 127).toInt(7 - i)
}
textureRegionPack.get(x, y).apply {
this.setRegion(x * tileW, y * (tileH + 1) + 1, w, h)
}
// println("[ItemSheet] ${ref.path()} ($x,$y) dim ($w,$h)")
}
}
pixmap.dispose()
}
val horizontalCount = textureRegionPack.horizontalCount
val verticalCount = textureRegionPack.verticalCount
fun get(x: Int, y: Int) = textureRegionPack.get(x, y)
fun forEach(action: (TextureRegion) -> Unit) = textureRegionPack.regions.forEach(action)
override fun dispose() {
textureRegionPack.dispose()
}
}

View File

@@ -0,0 +1,113 @@
package net.torvald.terrarum
import io.github.classgraph.ClassGraph
import io.github.classgraph.ClassInfo
import net.torvald.random.HQRNG
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameitems.GameItem
import java.util.*
/**
* Created by minjaesong on 2023-05-22.
*/
fun main() {
val superClasses = listOf(
Actor::class.java,
GameItem::class.java
)
val serialisablePrimitives = listOf(
// comparison: exact match
"Z",
"B",
"C",
"S",
"I",
"J",
"F",
"D",
).flatMap { listOf(it, "[$it") }
val serialisableTypes = listOf(
// arrays: has '[' prepended
// comparison: startsWith
// primitives
"Ljava/lang/String", // includes ZipCodedStr
"Ljava/lang/Boolean",
"Ljava/lang/Byte",
"Ljava/lang/Character",
"Ljava/lang/Short",
"Ljava/lang/Integer",
"Ljava/lang/Long",
"Ljava/lang/Float",
"Ljava/lang/Double",
// has serialiser on net.torvald.terrarum.serialise.Common
"Ljava/math/BigInteger",
"Ljava/util/UUID",
"Ljava/util/HashMap",
"Ljava/util/HashSet",
"Ljava/util/ArrayList",
"Lnet/torvald/terrarum/gameworld/BlockLayer",
"Lnet/torvald/terrarum/gameworld/WorldTime",
// complex types
"Lnet/torvald/gdx/graphics/Cvec",
"Lnet/torvald/random/HQRNG",
"Lnet/torvald/spriteanimation/SpriteAnimation",
"Lnet/torvald/terrarum/Codex",
"Lnet/torvald/terrarum/Point2d",
"Lnet/torvald/terrarum/Point2i",
"Lnet/torvald/terrarum/KVHashMap",
"Lnet/torvald/terrarum/gameactors/Actor\$RenderOrder",
"Lnet/torvald/terrarum/gameactors/ActorValue",
"Lnet/torvald/terrarum/gameactors/Hitbox",
"Lnet/torvald/terrarum/gameactors/Lightbox",
"Lnet/torvald/terrarum/gameactors/PhysProperties",
"Lnet/torvald/terrarum/gameitems/GameItem",
"Lnet/torvald/terrarum/utils/HashArray",
"Lnet/torvald/terrarum/utils/HashedWirings",
"Lnet/torvald/terrarum/utils/HashedWiringGraph",
"Lnet/torvald/terrarum/utils/WiringGraphMap",
"Lnet/torvald/terrarum/savegame/ByteArray64",
"Lnet/torvald/terrarum/modulebasegame/gameactors/ActorInventory",
"Lnet/torvald/terrarum/modulebasegame/gameactors/BlockBox",
"Lnet/torvald/terrarum/modulebasegame/gameactors/FixtureInventory",
"Lkotlin/ranges/IntRange",
"Lorg/dyn4j/geometry/Vector2",
"Lcom/badlogic/gdx/graphics/Color",
// subclasses
"Lnet/torvald/terrarum/gameactors/BlockMarkerActor",
"Lnet/torvald/terrarum/gameactors/Actor",
"Lnet/torvald/terrarum/gameactors/ActorWithBody",
"Lnet/torvald/terrarum/gameactors/ActorHumanoid",
// composite types
"Lkotlin/Pair<Ljava/lang/Integer;Ljava/lang/Integer;>"
).flatMap { listOf(it, "[$it") }
val classaNonGrata = listOf(
"net.torvald.terrarum.modulebasegame.MovableWorldCamera"
)
ClassGraph().acceptPackages("net.torvald.terrarum")/*.verbose()*/.enableAllInfo().scan().let { scan ->
val offendingFields = scan.allClasses.filter { classinfo ->
superClasses.any { classinfo.extendsSuperclass(it) || classinfo.name == it.canonicalName } &&
!classaNonGrata.contains(classinfo.name)
}.flatMap { clazz ->
clazz.declaredFieldInfo.filter { field ->
!field.isTransient &&
!field.isEnum &&
!serialisablePrimitives.contains(field.typeSignatureOrTypeDescriptorStr) &&
serialisableTypes.none { field.typeSignatureOrTypeDescriptorStr.startsWith(it) }
}
}
// println(offendingFields)
offendingFields.forEach {
println("\u001B[1m${it.name}\u001B[m\n\t\u001B[32mfrom: \u001B[m${it.className}\n\t\u001B[32mtype: \u001B[m${it.typeSignatureOrTypeDescriptorStr}")
}
}
}

View File

@@ -627,7 +627,7 @@ fun Double.sqrt() = Math.sqrt(this)
fun Float.sqrt() = FastMath.sqrt(this)
fun Int.abs() = this.absoluteValue
fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
fun Boolean.toInt() = if (this) 1 else 0
fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
fun Int.bitCount() = java.lang.Integer.bitCount(this)
fun Long.bitCount() = java.lang.Long.bitCount(this)

View File

@@ -136,11 +136,11 @@ class UIItemInventoryCatBar(
private val underlineColour = Color(0xeaeaea_40.toInt())
private val underlineHighlightColour = mainButtons[0].highlightCol
private var highlighterXPos = mainButtons[selectedIndex].posX.toFloat()
private var highlighterXPos = mainButtons[selectedIndex].posX
private var highlighterXStart = highlighterXPos
private var highlighterXEnd = highlighterXPos
private val highlighterYPos = catIcons.tileH + 4f
private val highlighterYPos = catIcons.tileH + 4
private var highlighterMoving = false
private val highlighterMoveDuration: Second = 0.15f
private var highlighterMoveTimer: Second = 0f
@@ -196,11 +196,11 @@ class UIItemInventoryCatBar(
highlighterMoveTimer += delta
highlighterXPos = Movement.moveQuick(
highlighterXStart,
highlighterXEnd,
highlighterXStart.toFloat(),
highlighterXEnd.toFloat(),
highlighterMoveTimer,
highlighterMoveDuration
)
).roundToInt()
if (highlighterMoveTimer > highlighterMoveDuration) {
highlighterMoveTimer = 0f
@@ -224,10 +224,10 @@ class UIItemInventoryCatBar(
// normal stuffs
val oldIndex = selectedIndex
highlighterXStart = mainButtons[selectedIndex].posX.toFloat() // using old selectedIndex
highlighterXStart = mainButtons[selectedIndex].posX // using old selectedIndex
selectedIndex = index
highlighterMoving = true
highlighterXEnd = mainButtons[selectedIndex].posX.toFloat() // using new selectedIndex
highlighterXEnd = mainButtons[selectedIndex].posX // using new selectedIndex
selectionChangeListener?.invoke(oldIndex, index)
}
@@ -290,12 +290,12 @@ class UIItemInventoryCatBar(
if (selectedPanel == 1) {
// indicator
batch.color = underlineHighlightColour
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2).round(), posY + highlighterYPos)
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2), posY + highlighterYPos.toFloat())
// label
batch.color = Color.WHITE
catIconsLabels[selectedIcon]().let {
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2).toFloat(), posY + highlighterYPos + 4)
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2), posY + highlighterYPos + 4)
}
}

View File

@@ -0,0 +1,97 @@
package net.torvald.terrarum
/*import com.android.tools.lint.client.api.IssueRegistry
import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.*
import net.torvald.random.HQRNG
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameitems.GameItem
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.savegame.ByteArray64
import net.torvald.terrarum.utils.*
import org.jetbrains.uast.UClass
import org.jetbrains.uast.UField
import org.jetbrains.uast.util.classSetOf
import org.jetbrains.uast.util.isInstanceOf
import java.math.BigInteger
import java.util.*
/**
* https://medium.com/@vanniktech/writing-your-first-lint-check-39ad0e90b9e6
* https://medium.com/mobile-app-development-publication/making-custom-lint-for-kotlin-code-8a6c203bf474
* https://github.com/googlesamples/android-custom-lint-rules
* https://googlesamples.github.io/android-custom-lint-rules/api-guide.html
*
* Created by minjaesong on 2023-05-22.
*/
class UnserialisableTypeIssueRegistry : IssueRegistry() {
override val issues = listOf(ISSUE_SAVEGAME_UNSERIALISABLE_TYPE_USED_WITHOUT_TRANSIENT)
}
val ISSUE_SAVEGAME_UNSERIALISABLE_TYPE_USED_WITHOUT_TRANSIENT = Issue.create("TerrarumNonTransientUnserialisableType",
"Unserialisable Type Used Without Care",
"Unserialisable type is used on the potentially serialised class without @Transient annotation",
Category.CORRECTNESS,
9,
Severity.ERROR,
Implementation(TerrarumNonTransientUnserialisableType::class.java, EnumSet.of(Scope.JAVA_FILE))
)
class TerrarumNonTransientUnserialisableType : Detector(), Detector.UastScanner {
override fun getApplicablePsiTypes() = listOf(UClass::class.java)
override fun createUastHandler(context: JavaContext) = TerrarumNonTransientUnserialisableTypeHandler(context)
class TerrarumNonTransientUnserialisableTypeHandler(private val context: JavaContext) : UElementHandler() {
override fun visitClass(clazz: UClass) {
/*if (clazz.name?.isDefinedCamelCase() == false) {
context.report(ISSUE_SAVEGAME_UNSERIALISABLE_TYPE_USED_WITHOUT_TRANSIENT, clazz,
context.getNameLocation(clazz),
"Not named in defined camel case.")
}*/
}
override fun visitField(node: UField) {
if (node.uastParent.isInstanceOf(classSetOf(Actor::class.java, GameItem::class.java)) &&
!node.hasAnnotation("Transient") &&
!node.isInstanceOf(classSetOf(
// primitives
String::class.java,
Array<String>::class.java,
Boolean::class.java,
Byte::class.java,
ByteArray::class.java,
ByteArray64::class.java,
Short::class.java,
ShortArray::class.java,
Int::class.java,
IntArray::class.java,
Long::class.java,
LongArray::class.java,
Float::class.java,
FloatArray::class.java,
Double::class.java,
DoubleArray::class.java,
// has serialiser on net.torvald.terrarum.serialise.Common
BigInteger::class.java,
ZipCodedStr::class.java,
BlockLayer::class.java,
WorldTime::class.java,
HashArray::class.java,
HashedWirings::class.java,
HashedWiringGraph::class.java,
WiringGraphMap::class.java,
UUID::class.java,
HQRNG::class.java,
))) {
context.report(
ISSUE_SAVEGAME_UNSERIALISABLE_TYPE_USED_WITHOUT_TRANSIENT,
node,
context.getNameLocation(node),
"Unserialisable type is used on the potentially serialised class without @Transient annotation"
)
}
}
}
}*/

View File

@@ -148,5 +148,5 @@ object AVKey {
*
* example value: `"SIxM+kGlrjZgLx5Zeqz7,;:UIZ5Q=2WT35SgKpOp.,vvf'fNW3G<ROimy(Y;E<,-mdtr5|^RGOqr0x*T*lC,YABr1oQwErKG)pGC'gUG"`
*/
const val WORLD_PORTAL_DICT = ""
const val WORLD_PORTAL_DICT = "worldportaldict"
}

View File

@@ -1,8 +1,10 @@
package net.torvald.terrarum.gameactors
import net.torvald.random.HQRNG
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ReferencingRanges
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.savegame.toBigEndian
import net.torvald.terrarum.utils.PasswordBase32
@@ -82,6 +84,9 @@ abstract class Actor : Comparable<Actor>, Runnable {
if (this is Pocketed)
inventory.actor = this
if (this is ActorHumanoid && vehicleRidingActorID != null) {
vehicleRiding = INGAME.getActorByID(vehicleRidingActorID!!) as Controllable
}
}
/**

View File

@@ -241,6 +241,7 @@ object IME {
TerrarumIMEConf(name, copying, lang, candidatesCount, if (keysymtable == null) keysyms else null, if (keysymtable == null) null else keysymtable, mode),
{ headkey, shifted, alted, lowLayerKeysym ->
val a = jsval.invokeMember("accept", headkey, shifted, alted, lowLayerKeysym)
// println(a.getArrayElement(0).asString().map { it.code.toString(16) })
a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString()
}, {
jsval.invokeMember("backspace").asString().toCanditates()

View File

@@ -29,7 +29,7 @@ class IMEDictionary(private val filename: String) {
private var dictLoaded = false
private fun loadDict() {
val reader = FileReader(File("assets/keylayout/", filename))
val reader = FileReader(File("assets/keylayout/", filename), Charsets.UTF_8)
reader.forEachLine {
if (it.contains(',')) {
val (key, value) = it.split(',')

View File

@@ -13,6 +13,9 @@ import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.savegame.ByteArray64
import net.torvald.terrarum.utils.HashArray
import net.torvald.terrarum.utils.ZipCodedStr
import org.dyn4j.geometry.Vector2
typealias ItemID = String

View File

@@ -123,6 +123,9 @@ object Lang {
private val bindOp = ">>="
fun getOrNull(key: String?, capitalise: Boolean = true) =
if (key == null) null else get(key, capitalise)
/**
* Syntax example:
*

View File

@@ -28,14 +28,8 @@ class EntryPoint : ModuleEntryPoint() {
printdbg(this, "Hello, world!")
// load common resources to the AssetsManager
CommonResourcePool.addToLoadingList("$moduleName.items16") {
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items.tga"), 16, 16)
}
CommonResourcePool.addToLoadingList("$moduleName.items24") {
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items24.tga"), 24, 24)
}
CommonResourcePool.addToLoadingList("$moduleName.items48") {
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items48.tga"), 48, 48)
CommonResourcePool.addToLoadingList("$moduleName.items") {
ItemSheet(ModMgr.getGdxFile(moduleName, "items/items.tga"))
}
CommonResourcePool.loadAll()

View File

@@ -144,10 +144,11 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
val SIZE_NORMAL = Point2i(9000, 2250)
val SIZE_LARGE = Point2i(13500, 2970)
val SIZE_HUGE = Point2i(22500, 4500)
val WORLDSIZE = if (App.IS_DEVELOPMENT_BUILD)
arrayOf(Point2i(2880, 1350), SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
val NEW_WORLD_SIZE = if (App.IS_DEVELOPMENT_BUILD)
arrayOf(Point2i(2880, 1350), /*SIZE_SMALL, */SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
else
arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
arrayOf(/*SIZE_SMALL, */SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
val WORLDPORTAL_NEW_WORLD_SIZE = arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
val worldgenThreadExecutor = ThreadExecutor()
}
@@ -654,21 +655,21 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
// what if there's multiple of such fixtures? whatever, you are supposed to DISALLOW such situation.
for (kk in actorsUnderMouse.indices) {
if (mouseInInteractableRange(actor) {
actorsUnderMouse[kk].mainUI?.let {
uiOpened = true
actorsUnderMouse[kk].mainUI?.let {
uiOpened = true
// property 'uiFixture' is a dedicated property that the TerrarumIngame recognises.
// when it's not null, the UI will be updated and rendered
// when the UI is closed, it'll be replaced with a null value
uiFixture = it
it.setPosition(
(Toolkit.drawWidth - it.width) / 4,
(App.scr.height - it.height) / 4 // what the fuck?
)
it.setAsOpen()
}
0L
} == 0L) break
// property 'uiFixture' is a dedicated property that the TerrarumIngame recognises.
// when it's not null, the UI will be updated and rendered
// when the UI is closed, it'll be replaced with a null value
uiFixture = it
it.setPosition(
(Toolkit.drawWidth - it.width) / 4,
(App.scr.height - it.height) / 4 // what the fuck?
)
it.setAsOpen()
}
0L
} == 0L) break
}
if (!uiOpened) {
@@ -1263,9 +1264,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
val fixturesUnderHand = ArrayList<FixtureBase>()
val mobsUnderHand = ArrayList<ActorWithBody>()
actorsUnderMouse.forEach {
if (it is FixtureBase && it.mainUI == null)
if (it is FixtureBase) // && it.mainUI == null) // pickup avail check must be done against fixture.canBeDespawned
fixturesUnderHand.add(it)
else
else if (it !is FixtureBase)
mobsUnderHand.add(it)
}

View File

@@ -65,7 +65,6 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
private lateinit var demoWorld: GameWorld
private lateinit var cameraNodes: FloatArray // camera Y-pos
private val cameraAI = object : ActorAI {
private var firstTime = true
private val lookaheadDist = 100.0

View File

@@ -37,8 +37,8 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
this.physProp = physProp
}
var vehicleRiding: Controllable? = null // usually player only
@Transient internal var vehicleRiding: Controllable? = null // usually player only
var vehicleRidingActorID: ActorID? = null
/** Must be set by PlayerFactory */

View File

@@ -244,7 +244,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
if (canBeDespawned) {
printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
printStackTrace(this)
// printStackTrace(this)
// remove filler block
forEachBlockbox { x, y, _, _ ->
@@ -312,7 +312,13 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
override fun flagDespawn() {
if (canBeDespawned) flagDespawn = true
if (canBeDespawned) {
printdbg(this, "Fixture at (${this.intTilewiseHitbox}) flagging despawn: ${this.javaClass.canonicalName}")
flagDespawn = true
}
else {
printdbg(this, "Fixture at (${this.intTilewiseHitbox}) CANNOT be despawned: ${this.javaClass.canonicalName}")
}
}
/**

View File

@@ -27,7 +27,7 @@ class FixtureLogicSignalEmitter : FixtureBase, Electric {
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_source.tga")
density = 1400.0
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, 1)
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE)).let {
it.setRowsAndFrames(1,1)

View File

@@ -23,7 +23,7 @@ internal class FixtureStorageChest : FixtureBase {
(mainUI as UIStorageChest).chestInventory = this.inventory!!
(mainUI as UIStorageChest).chestNameFun = this.nameFun
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, 1)
makeNewSprite(TextureRegionPack(CommonResourcePool.getAsTextureRegion("itemplaceholder_16").texture, 16, 16)).let {
it.setRowsAndFrames(1,1)

View File

@@ -126,7 +126,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity
// define physical size
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0)
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 1)
blockBox = BlockBox(BlockBox.FULL_COLLISION, tilewiseHitboxWidth, tilewiseHitboxHeight)
doorHoldLength = hashMapOf(

View File

@@ -0,0 +1,40 @@
package net.torvald.terrarum.modulebasegame.gameactors
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.UIWorldPortal
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2023-05-28.
*/
class FixtureWorldPortal : FixtureBase {
constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 5, 2),
nameFun = { Lang["ITEM_WORLD_PORTAL"] },
mainUI = UIWorldPortal()
) {
// TODO do something with (mainUI as UIWorldPortal).***
}
init {
val itemImage = FixtureItemBase.getItemImageFromSheet("basegame", "sprites/fixtures/portal_device.tga", 80, 32)
density = 2900.0
setHitboxDimension(80, 32, 0, 0)
makeNewSprite(TextureRegionPack(itemImage.texture, 80, 32)).let {
it.setRowsAndFrames(1,1)
}
actorValue[AVKey.BASEMASS] = FixtureLogicSignalEmitter.MASS
}
override fun reload() {
super.reload()
// TODO do something with (mainUI as UIWorldPortal).***
}
}

View File

@@ -16,7 +16,8 @@ import net.torvald.terrarum.itemproperties.Material
*/
open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
override lateinit var ai: ActorAI
var aiName: String = ""
@Transient override lateinit var ai: ActorAI
companion object {
val DEFAULT_COLLISION_TYPE = COLLISION_DYNAMIC
@@ -26,6 +27,7 @@ open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
constructor(ai: ActorAI, born: Long) : super(born) {
this.ai = ai
this.aiName = ai::class.java.canonicalName
}
init {

View File

@@ -13,7 +13,7 @@ import net.torvald.terrarum.gameactors.*
*/
class PhysTestLuarLander : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT), Controllable {
private val texture = Texture(ModMgr.getGdxFile("basegame", "sprites/phystest_lunarlander.tga"))
@Transient private val texture = Texture(ModMgr.getGdxFile("basegame", "sprites/phystest_lunarlander.tga"))
override val hitbox: Hitbox

View File

@@ -98,6 +98,8 @@ object PlayerBuilderSigrid {
inventory.add("item@basegame:258", 995) // doors
inventory.add("item@basegame:259", 995) // doors
inventory.add("item@basegame:320", 1) // portal
WireCodex.getAll().forEach {
try {
inventory.add(it.id, 9995)

View File

@@ -28,7 +28,7 @@ class ItemSwingingDoorOak(originalID: ItemID) :
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
@Transient override val makeFixture: () -> FixtureBase = {
FixtureSwingingDoorOak()
}
@@ -53,7 +53,7 @@ class ItemSwingingDoorEbony(originalID: ItemID) :
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
@Transient override val makeFixture: () -> FixtureBase = {
FixtureSwingingDoorEbony()
}
@@ -78,7 +78,7 @@ class ItemSwingingDoorBirch(originalID: ItemID) :
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
@Transient override val makeFixture: () -> FixtureBase = {
FixtureSwingingDoorBirch()
}
@@ -103,7 +103,7 @@ class ItemSwingingDoorRosewood(originalID: ItemID) :
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
@Transient override val makeFixture: () -> FixtureBase = {
FixtureSwingingDoorRosewood()
}

View File

@@ -30,7 +30,7 @@ class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torval
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
@Transient override val makeFixture: () -> FixtureBase = {
FixtureTapestry(
Gdx.files.internal("assets/monkey_island").readBytes(),
Block.PLANK_NORMAL

View File

@@ -0,0 +1,29 @@
package net.torvald.terrarum.modulebasegame.gameitems
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.modulebasegame.gameactors.FixtureTikiTorch
/**
* Created by minjaesong on 2023-05-28.
*/
class ItemWorldPortal(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureWorldPortal") {
override var dynamicID: ItemID = originalID
override val originalName = "ITEM_WORLD_PORTAL"
override var baseMass = 6000.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() = getItemImageFromSheet("basegame", "sprites/fixtures/portal_device.tga", 80, 32)
override var baseToolSize: Double? = baseMass
init {
equipPosition = EquipPosition.HAND_GRIP
}
}

View File

@@ -121,7 +121,7 @@ class PickaxeCopper(originalID: ItemID) : GameItem(originalID) {
override val materialId = "CUPR"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(0,0)
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(0,0)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
@@ -151,7 +151,7 @@ class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
override val materialId = "IRON"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(1,0)
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1,0)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
@@ -181,7 +181,7 @@ class PickaxeSteel(originalID: ItemID) : GameItem(originalID) {
override val materialId = "STAL"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(2,0)
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(2,0)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP

View File

@@ -94,7 +94,7 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID) {
override val isDynamic = false
override val materialId = ""
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items16").get(0, 9)
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1, 3)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP

View File

@@ -24,7 +24,7 @@ class WirePieceSignalWire(originalID: ItemID, private val atlasID: String, priva
override val isDynamic = false
override val materialId = ""
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack(atlasID).get(sheetX, sheetY)
get() = CommonResourcePool.getAsItemSheet(atlasID).get(sheetX, sheetY)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP

View File

@@ -33,8 +33,9 @@ object ItemSlotImageFactory {
return ItemSlotImage(slotImage.get(number, 0 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item))
}
fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?): ItemSlotImage {
return ItemSlotImage(slotImage.get(number, 1 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item))
fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?, hasGauge: Boolean): ItemSlotImage {
val y = if (hasGauge && isBlack) 9 else if (hasGauge && !isBlack) 8 else if (!hasGauge && isBlack) 3 else 1
return ItemSlotImage(slotImage.get(number, y), ItemCodex.getItemImage(item))
}

View File

@@ -74,7 +74,7 @@ class Notification : UICanvas() {
message.forEachIndexed { index, s ->
val xoff = 6 + (displayedTextWidth - realTextWidth) / 2
val y = -textHeight + App.fontGame.lineHeight * index
App.fontGame.draw(batch, s, LRmargin + xoff, y)
App.fontGame.draw(batch, s, LRmargin + xoff, y )
}

View File

@@ -465,7 +465,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
// control hints
val controlHintXPos = thisOffsetX.toFloat()
val controlHintXPos = thisOffsetX + 2f
blendNormalStraightAlpha(batch)
App.fontGame.draw(batch, controlHelp, controlHintXPos, full.yEnd - 20)
@@ -475,7 +475,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
// encumbrance meter
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
// encumbrance bar will go one row down if control help message is too long
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth + 36
val encumbBarTextXPos = encumbBarXPos - 6 - App.fontGame.getWidth(encumbranceText)
val encumbBarYPos = full.yEnd-20 + 3f +
if (App.fontGame.getWidth(full.listControlHelp) + 2 + controlHintXPos >= encumbBarTextXPos)

View File

@@ -1,14 +1,17 @@
package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
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.CommonResourcePool
import net.torvald.terrarum.ceilInt
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.TIMES
/**
@@ -43,6 +46,13 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
private val optionsYpos = IntArray(options.size + 1)
init {
CommonResourcePool.addToLoadingList("gui_hrule") {
TextureRegionPack(Gdx.files.internal("assets/graphics/gui/hrule.tga"), 216, 20)
}
CommonResourcePool.loadAll()
var akku = 0
options.forEachIndexed { index, row ->
val option = row[2]
@@ -60,10 +70,10 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
}
optionsYpos[optionsYpos.lastIndex] = akku
}
override var width = 420
override var width = 560
override var height = optionsYpos.last()
private val hrule = CommonResourcePool.getAsTextureRegionPack("gui_hrule")
private val spinnerWidth = 140
private val drawX = (Toolkit.drawWidth - width) / 2
@@ -170,7 +180,14 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
else
drawX + width/2 - panelgap - labelWidth // right aligned at the middle of the panel, offsetted by panelgap
App.fontGame.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index].toFloat())
App.fontGame.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index] - 2f)
// draw hrule
if (mode == "h1") {
val ruleWidth = ((width - 24 - labelWidth) / 2).toFloat()
batch.draw(hrule.get(0,0), xpos - 24f - ruleWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
batch.draw(hrule.get(0,1), xpos + 24f + labelWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
}
}
uiItems.forEach { it.render(batch, camera) }

View File

@@ -350,7 +350,7 @@ private class UIItemInputKeycap(
batch.draw(labels.get(21,2), (posX + (width - 20) / 2).toFloat(), posY + 4f)
else {
val keysymw = App.fontGame.getWidth(keysym)
App.fontGame.draw(batch, keysym, posX + (width - keysymw) / 2, posY + 4)
App.fontGame.draw(batch, keysym, posX + (width - keysymw) / 2, posY + 2)
}
}

View File

@@ -90,7 +90,7 @@ internal class UIInventoryCells(
// control hints
val controlHintXPos = full.offsetX
val controlHintXPos = full.offsetX - 34
blendNormalStraightAlpha(batch)
batch.color = Color.WHITE
App.fontGame.draw(batch, full.listControlHelp, controlHintXPos, full.yEnd - 20)

View File

@@ -39,9 +39,13 @@ class UIInventoryFull(
const val YPOS_CORRECTION = 16 // another hard-coding. X_X
const val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
const val CELLS_HOR = 10
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
(UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap)
const val CELLS_HOR = 12
fun getCellCountVertically(cellHeight: Int, gapHeight: Int = UIItemInventoryItemGrid.listGap): Int {
return (App.scr.height - REQUIRED_MARGIN - 134 + gapHeight) / // 134 is another magic number
(cellHeight + gapHeight)
}
val CELLS_VRT: Int; get() = getCellCountVertically(UIItemInventoryElemSimple.height, UIItemInventoryItemGrid.listGap)
const val itemListToEquipViewGap = UIItemInventoryItemGrid.listGap // used to be 24; figured out that the extra gap does nothig

View File

@@ -67,7 +67,7 @@ abstract class UIItemInventoryCellBase(
object UIItemInventoryCellCommonRes {
val meterColourMap = GdxColorMap(Gdx.files.internal("./assets/clut/health_bar_colouring_4096.tga"))
val meterBackDarkening = Color(0x828282ff.toInt())
val meterBackDarkening = Color(0x666666ff.toInt())
fun getHealthMeterColour(value: Float, start: Float, end: Float): Color {
if (start > end) throw IllegalArgumentException("Start value is greater than end value: $start..$end")

View File

@@ -48,7 +48,7 @@ open class UIItemInventoryItemGrid(
touchDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Button, extra info, self
protected val useHighlightingManager: Boolean = true, // only used by UIItemCraftingCandidateGrid which addresses buttons directly to set highlighting
open protected val highlightEquippedItem: Boolean = true, // for some UIs that only cares about getting equipped slot number but not highlighting
colourTheme: InventoryCellColourTheme = defaultInventoryCellTheme
private val colourTheme: InventoryCellColourTheme = defaultInventoryCellTheme
) : UIItem(parentUI, initialX, initialY) {
// deal with the moving position
@@ -225,10 +225,8 @@ open class UIItemInventoryItemGrid(
private val iconPosX = if (drawScrollOnRightside)
posX + width + LIST_TO_CONTROL_GAP
else
posX - LIST_TO_CONTROL_GAP - catBar.catIcons.tileW + 2
posX - LIST_TO_CONTROL_GAP - catBar.catIcons.tileW
private fun getIconPosY(index: Int) =
posY - 1 + (4 + UIItemInventoryElemWide.height - catBar.catIcons.tileH) * index
/** Long/compact mode buttons */
val gridModeButtons = Array<UIItemImageButton>(2) { index ->
@@ -321,6 +319,9 @@ open class UIItemInventoryItemGrid(
private val upDownButtonGapToDots = 7 // apparent gap may vary depend on the texture itself
private fun getIconPosY(index: Int) =
posY + 8 + 26 * index
override fun render(batch: SpriteBatch, camera: Camera) {
val posXDelta = posX - oldPosX
itemGrid.forEach { it.posX += posXDelta }
@@ -332,7 +333,7 @@ open class UIItemInventoryItemGrid(
}
fun getScrollDotYHeight(i: Int) = scrollUpButton.posY + 10 + upDownButtonGapToDots + 10 * i
fun getScrollDotYHeight(i: Int) = scrollUpButton.posY + 14 + upDownButtonGapToDots + 10 * i
scrollDownButton.posY = getScrollDotYHeight(itemPageCount) + upDownButtonGapToDots
@@ -345,6 +346,13 @@ open class UIItemInventoryItemGrid(
}
if (!hideSidebar) {
// draw the tray
batch.color = Toolkit.Theme.COL_CELL_FILL
Toolkit.fillArea(batch, iconPosX - 4, getIconPosY(0) - 8, 28, height)
// cell border
batch.color = colourTheme.cellHighlightNormalCol
Toolkit.drawBoxBorder(batch, iconPosX - 4, getIconPosY(0) - 8, 28, height)
gridModeButtons.forEach { it.render(batch, camera) }
scrollUpButton.render(batch, camera)
scrollDownButton.render(batch, camera)
@@ -356,7 +364,7 @@ open class UIItemInventoryItemGrid(
batch.color = colour
batch.draw(
catBar.catIcons.get(if (i == itemPage) 20 else 21, 0),
scrollUpButton.posX.toFloat(),
iconPosX.toFloat(),
getScrollDotYHeight(i).toFloat()
)
}
@@ -369,8 +377,8 @@ open class UIItemInventoryItemGrid(
walletText.forEachIndexed { index, it ->
batch.draw(
walletFont.get(0, it - '0'),
gridModeButtons[0].posX.toFloat(), // scroll button size: 20px, font width: 20 px
gridModeButtons[0].posY + height - index * walletFont.tileH - 1f
gridModeButtons[0].posX - 1f, // scroll button size: 20px, font width: 20 px
gridModeButtons[0].posY + height - index * walletFont.tileH - 18f
)
}
}

View File

@@ -416,17 +416,17 @@ class UIItemControlPaletteBaloon(val parent: UIKeyboardControlPanel, initialX: I
// texts. Sorted in the same way as UIItemControlPaletteBaloon.iconButtons
batch.color = Color.WHITE
App.fontGame.draw(batch, Lang["GAME_ACTION_MOVE_VERB"], col0 + 72, posY + 43)
App.fontGame.draw(batch, Lang["GAME_ACTION_JUMP"], col1 + 40, posY + 43)
App.fontGame.draw(batch, Lang["GAME_ACTION_MOVE_VERB"], col0 + 72, posY + 41)
App.fontGame.draw(batch, Lang["GAME_ACTION_JUMP"], col1 + 40, posY + 41)
App.fontGame.draw(batch, Lang["GAME_INVENTORY"], col0 + 40, row1)
App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2)
App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3)
App.fontGame.draw(batch, Lang["GAME_ACTION_QUICKSEL"], col0 + 40, row4)
App.fontGame.draw(batch, Lang["GAME_INVENTORY"], col0 + 40, row1 - 2)
App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2 - 2)
App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3 - 2)
App.fontGame.draw(batch, Lang["GAME_ACTION_QUICKSEL"], col0 + 40, row4 - 2)
App.fontGame.draw(batch, Lang["GAME_ACTION_ZOOM"], col1 + 40, row1)
App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2)
App.fontGame.draw(batch, Lang["MENU_LABEL_MENU"], col1 + 40, row3)
App.fontGame.draw(batch, Lang["GAME_ACTION_ZOOM"], col1 + 40, row1 - 2)
App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2 - 2)
App.fontGame.draw(batch, Lang["MENU_LABEL_MENU"], col1 + 40, row3 - 2)
}

View File

@@ -532,17 +532,19 @@ class UIItemPlayerCells(
private val litCol = Toolkit.Theme.COL_MOUSE_UP
private val cellCol = CELL_COL
private val defaultCol = Color.WHITE
private val defaultCol = Toolkit.Theme.COL_INACTIVE
private val hruleCol = Color(1f,1f,1f,0.35f)
private val hruleColLit = litCol.cpy().sub(0f,0f,0f,0.65f)
private val icons = CommonResourcePool.getAsTextureRegionPack("inventory_category")
private var highlightCol: Color = defaultCol
private var highlightTextCol: Color = defaultCol
override fun update(delta: Float) {
super.update(delta)
highlightCol = if (mouseUp) litCol else defaultCol
highlightTextCol = if (mouseUp) litCol else Toolkit.Theme.COL_LIST_DEFAULT
}
override fun render(batch: SpriteBatch, camera: Camera) {
@@ -632,11 +634,12 @@ class UIItemPlayerCells(
Toolkit.drawBoxBorder(batch, posX + 115, posY + 33, width - 114, 88)
// texts
batch.color = highlightTextCol
val playTimeTextLen = App.fontGame.getWidth(totalPlayTime)
App.fontGame.draw(batch, playerName, x + 146f, y + height - 82f)
App.fontGame.draw(batch, worldName, x + 146f, y + height - 53f)
App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 24f)
App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 24f)
App.fontGame.draw(batch, playerName, x + 146f, y + height - 84f)
App.fontGame.draw(batch, worldName, x + 146f, y + height - 55f)
App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 26f)
App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 26f)
// icons
batch.draw(icons.get(24,0), x + 120f, y + height - 82f) // player name
batch.draw(icons.get(12,0), x + 119f, y + height - 53f) // world map
@@ -734,7 +737,7 @@ class UIItemWorldCells(
private val colourBad = Color(0xFF0011FF.toInt())
private val cellCol = CELL_COL
private var highlightCol: Color = Color.WHITE
private var highlightCol: Color = Toolkit.Theme.COL_LIST_DEFAULT
override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
UILoadGovernor.worldDisk = skimmer
@@ -746,7 +749,7 @@ class UIItemWorldCells(
override fun update(delta: Float) {
super.update(delta)
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Color.WHITE
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
}
override fun render(batch: SpriteBatch, camera: Camera) {
@@ -805,7 +808,7 @@ class UIItemWorldCells(
App.fontSmallNumbers.draw(batch, "${skimmer.diskFile.length().ushr(10)} KiB", x + 3f, y + height - 16f)
// savegame name
if (saveDamaged) batch.color = colourBad
App.fontGame.draw(batch, saveName, x + 3f, y + 1f)
App.fontGame.draw(batch, saveName, x + 3f, y + -1f)
super.render(batch, camera)
batch.color = Color.WHITE

View File

@@ -14,6 +14,7 @@ import net.torvald.terrarum.Second
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.NEW_WORLD_SIZE
import net.torvald.terrarum.modulebasegame.WorldgenLoadScreen
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.savegame.ByteArray64Reader
@@ -34,7 +35,7 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
private val normalTex = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/normal.png")))
private val smallTex = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/small.png")))
private val tex = arrayOf(smallTex, normalTex, largeTex, hugeTex)
private val tex = arrayOf(/*smallTex, */normalTex, largeTex, hugeTex)
override var width = 480
override var height = 480
@@ -42,9 +43,9 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
private val drawX = (Toolkit.drawWidth - width) / 2
private val drawY = (App.scr.height - height) / 2
private val radioCellWidth = 100
private val radioCellWidth = 116
private val inputWidth = 340
private val radioX = (width - (radioCellWidth * (if (App.IS_DEVELOPMENT_BUILD) 5 else 4) + 9)) / 2
private val radioX = (width - (radioCellWidth * NEW_WORLD_SIZE.size + 9)) / 2
private val inputX = width - inputWidth
private val sizeSelY = 186 + 40
@@ -56,15 +57,15 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
if (App.IS_DEVELOPMENT_BUILD)
listOf(
{ Lang["CONTEXT_DESCRIPTION_TINY"] },
{ Lang["CONTEXT_DESCRIPTION_SMALL"] },
{ Lang["MENU_SETTING_MEDIUM"] }, // ;p
// { Lang["CONTEXT_DESCRIPTION_TINY"] }, // only available for World Portal
{ Lang["CONTEXT_DESCRIPTION_SMALL"] }, // ;p
{ Lang["CONTEXT_DESCRIPTION_BIG"] },
{ Lang["CONTEXT_DESCRIPTION_HUGE"] }
)
else
listOf(
{ Lang["CONTEXT_DESCRIPTION_SMALL"] },
{ Lang["MENU_SETTING_MEDIUM"] }, // ;p
// { Lang["CONTEXT_DESCRIPTION_TINY"] }, // only available for World Portal
{ Lang["CONTEXT_DESCRIPTION_SMALL"] }, // ;p
{ Lang["CONTEXT_DESCRIPTION_BIG"] },
{ Lang["CONTEXT_DESCRIPTION_HUGE"] }
)
@@ -85,8 +86,6 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
private val goButton = UIItemTextButton(this, "MENU_LABEL_CONFIRM_BUTTON", drawX + width/2 + (width/2 - goButtonWidth) / 2, drawY + height - 24, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
init {
tex.forEach { it.flip(false, false) }
goButton.touchDownListener = { _, _, _, _ ->
// printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")
@@ -98,7 +97,7 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
catch (e: NumberFormatException) {
XXHash64.hash(seedInput.getTextOrPlaceholder().toByteArray(Charsets.UTF_8), 10000)
}
val (wx, wy) = TerrarumIngame.WORLDSIZE[sizeSelector.selection]
val (wx, wy) = TerrarumIngame.NEW_WORLD_SIZE[sizeSelector.selection]
val worldParam = TerrarumIngame.NewGameParams(
player, TerrarumIngame.NewWorldParameters(
wx, wy, seed, nameInput.getTextOrPlaceholder()

View File

@@ -37,7 +37,7 @@ class UIQuickslotBar : UICanvas() {
companion object {
const val SLOT_COUNT = 10
const val DISPLAY_OPACITY = 0.8f
const val DISPLAY_OPACITY = 0.92f
const val COMMON_OPEN_CLOSE = 0.12f
}
@@ -85,9 +85,10 @@ class UIQuickslotBar : UICanvas() {
for (i in 0 until SLOT_COUNT) {
val qs = actor.inventory.getQuickslotItem(i)
val item = ItemCodex[qs?.itm]
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
val image = if (i == selection)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
else
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item)

View File

@@ -26,7 +26,7 @@ class UIQuickslotPie : UICanvas() {
private val slotCount = UIQuickslotBar.SLOT_COUNT
private val slotDistanceFromCentre: Double
get() = cellSize * 2.5 * handler.scale
get() = cellSize * 2.666 * handler.scale
override var width: Int = cellSize * 7
override var height: Int = width
@@ -36,7 +36,7 @@ class UIQuickslotPie : UICanvas() {
*/
override var openCloseTime: Second = COMMON_OPEN_CLOSE
private val smallenSize = 0.93f
private val smallenSize = 0.92f
var selection: Int = -1
@@ -66,6 +66,7 @@ class UIQuickslotPie : UICanvas() {
for (i in 0 until slotCount) {
val qs = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslotItem(i)
val item = ItemCodex[qs?.itm]
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
// set position
val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise
@@ -73,7 +74,7 @@ class UIQuickslotPie : UICanvas() {
// draw cells
val image = if (i == selection)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
else
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item)

View File

@@ -26,7 +26,7 @@ class UIScreenZoom : UICanvas(
override var width = App.fontGame.getWidth(zoomText)
override var height = App.fontGame.lineHeight.toInt()
override var openCloseTime = COMMON_OPEN_CLOSE
override var openCloseTime = 0.25f
override val mouseUp = false

View File

@@ -190,7 +190,7 @@ internal class UIStorageChest : UICanvas(
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
val chestName = chestNameFun()
val playerName = INGAME.actorNowPlaying!!.actorValue.getAsString(AVKey.NAME).orEmpty().let { it.ifBlank { Lang["GAME_INVENTORY"] } }
val encumbBarXPos = itemListPlayer.posX + itemListPlayer.width - UIInventoryCells.weightBarWidth
val encumbBarXPos = itemListPlayer.posX + itemListPlayer.width - UIInventoryCells.weightBarWidth + 36
val encumbBarTextXPos = encumbBarXPos - 6 - App.fontGame.getWidth(encumbranceText)
val yEnd = -UIInventoryFull.YPOS_CORRECTION + (App.scr.height + UIInventoryFull.internalHeight).div(2).toFloat() // directly copied from UIInventoryFull.yEnd
val encumbBarYPos = yEnd - 20 + 3 // dunno why but extra 3 px is needed
@@ -224,7 +224,7 @@ internal class UIStorageChest : UICanvas(
App.fontGame.draw(batch, playerName, thisOffsetX2 + (cellsWidth - App.fontGame.getWidth(playerName)) / 2, thisOffsetY - 30)
// control hint
App.fontGame.draw(batch, controlHelp, thisOffsetX + 2f, encumbBarYPos - 3)
App.fontGame.draw(batch, controlHelp, thisOffsetX - 34f, encumbBarYPos - 3)
// encumb text
batch.color = Color.WHITE

View File

@@ -35,10 +35,10 @@ class UITooltip : UICanvas() {
val textMarginX = 4
override var width: Int
get() = msgWidth + (textMarginX + Toolkit.baloonTile.tileW) * 2
get() = msgWidth + (textMarginX + 36) * 2
set(value) { throw Error("You are not supposed to set the width of the tooltip manually.") }
override var height: Int
get() = Toolkit.baloonTile.tileH * 2 + font.lineHeight.toInt()
get() = 36 * 2 + font.lineHeight.toInt()
set(value) { throw Error("You are not supposed to set the height of the tooltip manually.") }
override fun renderUI(batch: SpriteBatch, camera: Camera) {

View File

@@ -4,9 +4,17 @@ import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.YPOS_CORRECTION
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.drawBackground
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalHeight
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.getKeycapConsole
import net.torvald.unicode.getKeycapPC
/**
* Structure:
@@ -18,18 +26,16 @@ import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
*
* Created by minjaesong on 2023-05-19.
*/
class UIWorldPortal : UICanvas() {
class UIWorldPortal : UICanvas(
toggleKeyLiteral = App.getConfigInt("control_key_inventory"),
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
) {
override var width = App.scr.width
override var height = App.scr.height
override var width: Int = Toolkit.drawWidth
override var height: Int = App.scr.height
val gradStartCol = Color(0x404040_60)
val gradEndCol = Color(0x000000_70)
val gradHeight = 48f
val controlHelpHeight = App.fontGame.lineHeight
private var panelTransitionLocked = false
@@ -43,23 +49,33 @@ class UIWorldPortal : UICanvas() {
fun requestTransition(target: Int) = transitionPanel.requestTransition(target)
val catBar = UIItemInventoryCatBar(
val catBar = UIItemWorldPortalTopBar(
this,
(width - UIInventoryFull.catBarWidth) / 2,
42 - UIInventoryFull.YPOS_CORRECTION + (App.scr.height - UIInventoryFull.internalHeight) / 2,
UIInventoryFull.internalWidth,
UIInventoryFull.catBarWidth,
true
0,
42 - YPOS_CORRECTION + (App.scr.height - internalHeight) / 2,
) { i -> if (!panelTransitionLocked) requestTransition(i) }
private val SP = "\u3000 "
val portalListingControlHelp: String
get() = if (App.environment == RunningEnvironment.PC)
"${getKeycapPC(App.getConfigInt("control_key_up"))}${getKeycapPC(App.getConfigInt("control_key_down"))}" +
" ${Lang["MENU_CONTROLS_SCROLL"]}" +
"$SP${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
else
"${getKeycapConsole('R')} ${Lang["MENU_CONTROLS_SCROLL"]}" +
"$SP${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]}" +
"$SP${App.gamepadLabelLT} ${Lang["GAME_WORLD_SEARCH"]}" +
"$SP${App.gamepadLabelRT} ${Lang["GAME_INVENTORY"]}"
private val transitionalSearch = UIWorldPortalSearch(this)
private val transitionalListing = UIWorldPortalListing(this)
private val transitionalCargo = UIWorldPortalCargo(this)
private val transitionPanel = UIItemHorizontalFadeSlide(
this,
(width - UIInventoryFull.internalWidth) / 2,
UIInventoryFull.INVENTORY_CELLS_OFFSET_Y(),
(width - internalWidth) / 2,
INVENTORY_CELLS_OFFSET_Y(),
width,
App.scr.height,
1f,
@@ -74,7 +90,10 @@ class UIWorldPortal : UICanvas() {
}
internal var xEnd = (width + internalWidth).div(2).toFloat()
private set
internal var yEnd = -YPOS_CORRECTION + (App.scr.height + internalHeight).div(2).toFloat()
private set
@@ -84,13 +103,19 @@ class UIWorldPortal : UICanvas() {
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {
UIInventoryFull.drawBackground(batch, handler.opacity)
drawBackground(batch, handler.opacity)
// UI items
catBar.render(batch, camera)
transitionPanel.render(batch, camera)
}
override fun show() {
super.show()
transitionPanel.show()
INGAME.setTooltipMessage(null)
}
override fun dispose() {
catBar.dispose()
}
@@ -102,11 +127,13 @@ class UIWorldPortal : UICanvas() {
override fun doOpening(delta: Float) {
super.doOpening(delta)
resetUI()
INGAME.pause()
INGAME.setTooltipMessage(null)
}
override fun doClosing(delta: Float) {
super.doClosing(delta)
INGAME.resume()
INGAME.setTooltipMessage(null)
}
@@ -123,4 +150,83 @@ class UIWorldPortal : UICanvas() {
INGAME.setTooltipMessage(null) // required!
}
}
class UIItemWorldPortalTopBar(
parentUI: UIWorldPortal,
initialX: Int,
initialY: Int,
val panelTransitionReqFun: (Int) -> Unit = {} // for side buttons; for the selection change, override selectionChangeListener
) : UIItem(parentUI, initialX, initialY) {
override val width = 580
override val height = 25
init {
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
}
CommonResourcePool.loadAll()
}
private val genericIcons: TextureRegionPack = CommonResourcePool.getAsTextureRegionPack("inventory_category")
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
private val catIconImages = listOf(
icons.get(0, 0),
genericIcons.get(16,0),
icons.get(1, 0),
genericIcons.get(17,0),
icons.get(2, 0),
)
private val catIconLabels = listOf(
"CONTEXT_WORLD_SEARCH",
"",
"CONTEXT_WORLD_LIST",
"GAME_INVENTORY",
"",
)
private val buttonGapSize = 120
private val highlighterYPos = icons.tileH + 4
var selection = 2
private val buttons = Array<UIItemImageButton>(5) {
val xoff = if (it == 1) -32 else if (it == 3) 32 else 0
UIItemImageButton(
parentUI,
catIconImages[it],
activeBackCol = Color(0),
backgroundCol = Color(0),
highlightBackCol = Color(0),
activeBackBlendMode = BlendMode.NORMAL,
initialX = (Toolkit.drawWidth - width) / 2 + it * (buttonGapSize + 20) + xoff,
initialY = posY,
inactiveCol = if (it % 2 == 0) Color.WHITE else Color(0xffffff7f.toInt()),
activeCol = if (it % 2 == 0) Toolkit.Theme.COL_MOUSE_UP else Color(0xffffff7f.toInt()),
highlightable = (it % 2 == 0)
)
}
override fun render(batch: SpriteBatch, camera: Camera) {
super.render(batch, camera)
// button
buttons.forEach { it.render(batch, camera) }
// label
batch.color = Color.WHITE
val text = Lang[catIconLabels[selection]]
App.fontGame.draw(batch, text, buttons[selection].posX + 10 - (App.fontGame.getWidth(text) / 2), posY + highlighterYPos + 4)
blendNormalStraightAlpha(batch)
}
override fun dispose() {
}
}

View File

@@ -2,20 +2,32 @@ package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap
import net.torvald.terrarum.savegame.DiskSkimmer
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.getCellCountVertically
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
import net.torvald.terrarum.savegame.*
import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.serialise.ascii85toUUID
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItem
import net.torvald.terrarum.ui.UIItemTextButton
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.EMDASH
import java.time.Instant
import java.time.format.DateTimeFormatter
import java.util.*
import java.util.zip.GZIPInputStream
/**
* Created by minjaesong on 2023-05-19.
@@ -26,31 +38,24 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
override var width: Int = Toolkit.drawWidth
override var height: Int = App.scr.height
private val cellHeight = 48
private val buttonHeight = 24
private val gridGap = listGap
private var worldList: List<Pair<UUID, DiskSkimmer>>
private var selectedWorld: DiskSkimmer? = null
private val cellCol = UIInventoryFull.CELL_COL
private var highlightCol: Color = Color.WHITE
private val gridGap = 10
private val thumbw = 360
private val thumbh = 240
private val thumbw = 378
private val textAreaW = thumbw - 32
private val thumbh = 252
private val hx = Toolkit.drawWidth.div(2)
private val y = INVENTORY_CELLS_OFFSET_Y()
private val y = INVENTORY_CELLS_OFFSET_Y() + 1
private val listCount = UIInventoryFull.CELLS_VRT
private val listHeight = cellHeight * listCount + gridGap * (listCount - 1)
private val listCount = getCellCountVertically(UIItemWorldCellsSimple.height, gridGap)
private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap)
private val deleteButtonWidth = 80
private val buttonReset = UIItemTextButton(this,
"MENU_LABEL_DELETE_WORLD",
private val memoryGaugeWidth = textAreaW
private val deleteButtonWidth = (thumbw - gridGap) / 2
private val buttonDeleteWorld = UIItemTextButton(this,
"MENU_LABEL_DELETE",
hx - gridGap/2 - deleteButtonWidth,
y + listHeight - buttonHeight,
deleteButtonWidth,
@@ -58,71 +63,338 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
hasBorder = true,
alignment = UIItemTextButton.Companion.Alignment.CENTRE
)
private val buttonRenameWorld = UIItemTextButton(this,
"MENU_LABEL_RENAME",
buttonDeleteWorld.posX - gridGap - deleteButtonWidth,
y + listHeight - buttonHeight,
deleteButtonWidth,
readFromLang = true,
hasBorder = true,
alignment = UIItemTextButton.Companion.Alignment.CENTRE
)
private val worldList = ArrayList<WorldInfo>()
data class WorldInfo(
val uuid: UUID,
val diskSkimmer: DiskSkimmer,
val dimensionInChunks: Int,
val seed: Long,
val lastPlayedString: String,
val totalPlayedString: String,
val screenshot: TextureRegion?,
) {
fun dispose() {
screenshot?.texture?.dispose()
}
}
init {
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga")), 20, 20).also {
it.flip(false, false)
}
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
}
CommonResourcePool.loadAll()
addUIitem(buttonReset)
addUIitem(buttonRenameWorld)
addUIitem(buttonDeleteWorld)
}
worldList = (INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").map {
private var chunksUsed = 0
private val chunksMax = 100000
private lateinit var worldCells: Array<UIItemWorldCellsSimple>
private var selected: UIItemWorldCellsSimple? = null
private var selectedIndex: Int? = null
override fun show() {
worldList.clear()
(INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").filter { it.isNotBlank() }.map {
it.ascii85toUUID().let { it to App.savegameWorlds[it] }
}.filter { it.second != null } as List<Pair<UUID, DiskSkimmer>>
}
}.filter { it.second != null }.mapIndexed { index, (uuid, disk) ->
var chunksCount = 0
var seed = 0L
var lastPlayed = 0L
var totalPlayed = 0L
var w = 0
var h = 0
var thumb: TextureRegion? = null
JsonFetcher.readFromJsonString(ByteArray64Reader(disk!!.requestFile(-1)!!.contents.getContent() as ByteArray64, Common.CHARSET)).let {
JsonFetcher.forEachSiblings(it) { name, value ->
if (name == "width") w = value.asInt()
if (name == "height") h = value.asInt()
if (name == "generatorSeed") seed = value.asLong()
if (name == "lastPlayTime") lastPlayed = value.asLong()
if (name == "totalPlayTime") totalPlayed = value.asLong()
}
}
chunksCount = (w / CHUNK_W) * (h / CHUNK_H)
override fun updateUI(delta: Float) {
disk.requestFile(-2)?.let {
val zippedTga = (it.contents as EntryFile).bytes
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
val tgaFileContents = gzin.readAllBytes(); gzin.close()
}
val thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
val thumbTex = Texture(thumbPixmap)
thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
thumb = TextureRegion(thumbTex)
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {
batch.inUse {
// draw background //
// screencap panel
batch.color = cellCol
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
// draw border //
// screencap panel
batch.color = highlightCol
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2)
// memory gauge
Toolkit.drawBoxBorder(batch, hx - 330 - gridGap/2 - 1, y + listHeight - 1, 240 + 2, buttonHeight + 2)
uiItems.forEach { it.render(batch, camera) }
WorldInfo(uuid, disk, chunksCount, seed, lastPlayed.toTimestamp(), totalPlayed.toDurationStamp(), thumb)
}.let {
worldList.addAll(it)
}
chunksUsed = worldList.sumOf { it.dimensionInChunks }
worldCells = Array(maxOf(worldList.size, listCount)) {
UIItemWorldCellsSimple(
this,
hx + gridGap / 2,
y + (gridGap + UIItemWorldCellsSimple.height) * it,
worldList.getOrNull(it),
worldList.getOrNull(it)?.diskSkimmer?.getDiskName(Common.CHARSET)
).also { button ->
button.clickOnceListener = { _, _, _ ->
selected = button
selectedIndex = it
updateUIbyButtonSelection()
}
}
}
uiItems.forEach { it.show() }
worldCells.forEach { it.show() }
selected = null
updateUIbyButtonSelection()
}
private fun Long.toTimestamp() = Instant.ofEpochSecond(this)
.atZone(TimeZone.getDefault().toZoneId())
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
private fun Long.toDurationStamp(): String {
val s = this % 60
val m = (this / 60) % 60
val h = (this / 3600) % 24
val d = this / 86400
return if (d == 0L)
"${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
else
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
}
private val nullTimestamp = "0000-00-00 --:--:--"
private val nullDurationStamp = "--h--m--s"
private fun Int.chunkCountToWorldSize() = when(this) {
in 0 until 2000 -> "CONTEXT_DESCRIPTION_TINY"
in 2000 until 4500 -> "CONTEXT_DESCRIPTION_SMALL"
in 4500 until 10000 -> "CONTEXT_DESCRIPTION_BIG"
else -> "CONTEXT_DESCRIPTION_HUGE"
}
override fun updateUI(delta: Float) {
uiItems.forEach { it.update(delta) }
worldCells.forEach { it.update(delta) }
}
private val iconGap = 12f
private val iconSize = 30f
private val textualListHeight = 30f
private val iconSizeGap = iconSize + iconGap
private fun updateUIbyButtonSelection() {
worldTexts = listOf(
// last played
icons.get(2, 1) to (selected?.worldInfo?.lastPlayedString ?: nullTimestamp),
// total played
icons.get(0, 2) to (selected?.worldInfo?.totalPlayedString ?: nullDurationStamp),
// world size
icons.get(1, 2) to (Lang.getOrNull(selected?.worldInfo?.dimensionInChunks?.chunkCountToWorldSize()) ?: "$EMDASH"),
)
selectedWorldThumb = selected?.worldInfo?.screenshot
worldCells.forEach {
it.highlighted = (selected == it && selected?.worldInfo != null)
}
}
private lateinit var worldTexts: List<Pair<TextureRegion, String>>
private var selectedWorldThumb: TextureRegion? = null
val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
override fun renderUI(batch: SpriteBatch, camera: Camera) {
val memoryGaugeXpos = hx - memoryGaugeWidth - gridGap/2
val memoryGaugeYpos = y + listHeight - buttonHeight - gridGap - buttonHeight
val textXpos = memoryGaugeXpos + 3
// draw background //
// screencap panel
batch.color = UIInventoryFull.CELL_COL
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
// draw border //
// screencap panel
batch.color = if (selected?.worldInfo == null) Toolkit.Theme.COL_INVENTORY_CELL_BORDER else Toolkit.Theme.COL_INACTIVE
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2)
// memory gauge
val barCol = UIItemInventoryCellCommonRes.getHealthMeterColour(chunksMax - chunksUsed, 0, chunksMax)
val barBack = barCol mul UIItemInventoryCellCommonRes.meterBackDarkening
batch.color = Toolkit.Theme.COL_CELL_FILL
Toolkit.fillArea(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt(), memoryGaugeYpos, buttonHeight + 6, buttonHeight)
batch.color = Toolkit.Theme.COL_INACTIVE
Toolkit.drawBoxBorder(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt() - 1, memoryGaugeYpos - 1, buttonHeight + 7, buttonHeight + 2)
batch.color = Color.WHITE
batch.draw(icons.get(2, 2), textXpos - iconSizeGap, memoryGaugeYpos + 2f)
batch.color = Toolkit.Theme.COL_INACTIVE
Toolkit.drawBoxBorder(batch, memoryGaugeXpos - 1, memoryGaugeYpos - 1, memoryGaugeWidth + 2, buttonHeight + 2)
batch.color = barBack
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, memoryGaugeWidth, buttonHeight)
batch.color = barCol
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (chunksUsed / chunksMax.toFloat())).ceilInt(), buttonHeight)
batch.color = Color.WHITE
if (selected?.worldInfo != null) {
// background for texts panel
batch.color = Toolkit.Theme.COL_CELL_FILL
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y + thumbh + 3, thumbw, 10 + worldTexts.size * textualListHeight.toInt())
batch.color = Toolkit.Theme.COL_INACTIVE
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y + thumbh + 2, thumbw + 2, 10 + worldTexts.size * textualListHeight.toInt() + 2)
// some texts
batch.color = Color.WHITE
worldTexts.forEachIndexed { index, (icon, str) ->
batch.draw(icon, textXpos - iconSizeGap + 6, y + thumbh + 3+10 + textualListHeight * index)
App.fontGame.draw(batch, str, textXpos + 6f, y + thumbh + 3+10 + textualListHeight * index - 2f)
}
// size indicator on the memory gauge
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (selected?.worldInfo!!.dimensionInChunks / chunksMax.toFloat())).ceilInt(), buttonHeight)
// thumbnail
selected?.worldInfo?.screenshot?.let {
batch.draw(it, (hx - thumbw - gridGap/2).toFloat(), y.toFloat(), thumbw.toFloat(), thumbh.toFloat())
}
}
uiItems.forEach { it.render(batch, camera) }
worldCells.forEach { it.render(batch, camera) }
// control hints
batch.color = Color.WHITE
App.fontGame.draw(batch, full.portalListingControlHelp, hx - thumbw - gridGap/2 + 2, (full.yEnd - 20).toInt())
}
override fun hide() {
uiItems.forEach { it.hide() }
worldCells.forEach { it.hide() }
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
}
override fun dispose() {
uiItems.forEach { it.dispose() }
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
}
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
if (this.isVisible && mouseInScreen(screenX, screenY)) {
uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) }
worldCells.forEach { it.touchDown(screenX, screenY, pointer, button) }
handler.subUIs.forEach { it.touchDown(screenX, screenY, pointer, button) }
return true
}
else return false
}
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
if (this.isVisible) {
uiItems.forEach { it.touchUp(screenX, screenY, pointer, button) }
worldCells.forEach { it.touchUp(screenX, screenY, pointer, button) }
handler.subUIs.forEach { it.touchUp(screenX, screenY, pointer, button) }
return true
}
else return false
}
}
class UIItemWorldCellsSimple(
parent: UILoadDemoSavefiles,
parent: UIWorldPortalListing,
initialX: Int,
initialY: Int,
val skimmer: DiskSkimmer
internal val worldInfo: UIWorldPortalListing.WorldInfo? = null,
internal val worldName: String? = null,
) : UIItem(parent, initialX, initialY) {
override val width: Int = 360
companion object {
const val width = 378
const val height = 46
}
override val width: Int = 378
override val height: Int = 46
private val cellCol = UIInventoryFull.CELL_COL
private var highlightCol: Color = Color.WHITE
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
var highlighted = false
override fun show() {
super.show()
}
override fun hide() {
super.hide()
}
override fun update(delta: Float) {
super.update(delta)
}
override fun render(batch: SpriteBatch, camera: Camera) {
super.render(batch, camera)
// draw background
batch.color = UIInventoryFull.CELL_COL
Toolkit.fillArea(batch, posX, posY, width, height)
val mouseUp = mouseUp && worldInfo != null
val bcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INVENTORY_CELL_BORDER else Toolkit.Theme.COL_INACTIVE)
val tcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INACTIVE else Toolkit.Theme.COL_LIST_DEFAULT)
// draw border
batch.color = bcol
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2)
// draw texts
batch.color = tcol
batch.draw(icons.get(0, 1), posX + 4f, posY + 1f)
App.fontGame.draw(batch, worldName ?: "$EMDASH", posX + 32, posY - 1)
batch.draw(icons.get(1, 1), posX + 4f, posY + 25f)
App.fontGame.draw(batch, if (worldInfo?.seed == null) "$EMDASH" else "${(if (worldInfo.seed > 0) "+" else "")}${worldInfo.seed}" , posX + 32, posY + 23)
// text separator
batch.color = bcol.cpy().sub(0f,0f,0f,0.65f)
Toolkit.fillArea(batch, posX + 2, posY + 23, width - 4, 1)
}
override fun dispose() {
}

View File

@@ -363,6 +363,8 @@ removefile:
return fa.read()
}
override fun getDiskName(charset: Charset): String {
val bytes = ByteArray(268)
fa.seek(10L)

View File

@@ -215,6 +215,147 @@ object Common {
})
}
data class SpliceCmd(
var strPos: Int,
var stackDepth: Int = -1,
var objStartPos: Int = -1,
var objEndPos: Int = -1,
var prependedCommaPos: Int = -1
)
fun scanForCompanionObjects(s: String): List<SpliceCmd> {
val retBin = ArrayList<SpliceCmd>()
val state = Stack<String>().also { it.push("lit") } // lit, esc, qot
val parenStack = Stack<Char>() // { [ " '
val searchStr = "Companion"
val strCircBuf = StringBuilder()
val workBin = Stack<SpliceCmd>()
var kvMode = "key"
s.forEachIndexed { index, c ->
strCircBuf.append(c); if (strCircBuf.length > searchStr.length) strCircBuf.deleteCharAt(0)
when (c) {
'{', '[', '(' -> {
parenStack.push(c)
if (workBin.isNotEmpty()) {
workBin.peek().let {
if (it.objStartPos == -1) {
it.objStartPos = index
it.stackDepth = parenStack.size
}
}
// println("== workBin mod ==;")
// workBin.forEach { println("$it;") }
}
}
'}', ']', ')' -> {
if (workBin.isNotEmpty()) {
workBin.peek().let {
if (it.objEndPos == -1) {
if (parenStack.size == it.stackDepth) it.objEndPos = index
// println(" parenStack.size=${parenStack.size}, it=$it;")
}
}
// println("== workBin pop ==;")
// workBin.forEach { println("$it;") }
retBin.add(workBin.pop())
}
parenStack.pop()
if (kvMode == "val") {
kvMode = "key"
}
}
'\\' -> {
if (state.peek() == "esc") {
state.pop()
}
else {
state.push("esc")
}
}
'"', '\'' -> {
if (state.peek() == "esc")
state.pop()
else if (parenStack.peek() == c) {
parenStack.pop()
state.pop() // assuming no errors :p
}
else {
parenStack.push(c)
state.push("qot")
}
}
':' -> {
if (state.peek() == "lit" && kvMode == "key") {
kvMode = "val"
}
}
',' -> {
if (state.peek() == "lit" && kvMode == "val") {
kvMode = "key"
}
}
else -> {
if (state.peek() == "esc")
state.pop()
}
}
if (strCircBuf.toString() == searchStr && kvMode == "key") {
workBin.push(SpliceCmd(index))
// println("== workBin push ==;")
// workBin.forEach { println("$it;") }
}
// println("$c\t${state.peek()};")
}
return retBin
}
fun String.jsonRemoveCompanionObjects(): String {
val objectIndices = scanForCompanionObjects(this)
// search backwards for a valid comma
// terminate when '{' is reached (means the Companion was the first object)
objectIndices.forEach {
var c = it.strPos - 1
while (c > 0 && this[c] != ',' && this[c-1] != '{') {
c -= 1
}
it.prependedCommaPos = c
}
// println(objectIndices)
// splice the string
// when the search results are indeed correct, they will have the following properties:
// 1. str[objStartPos]='{' && str[objEndPos]='}'
// 2. str[strPos]='n' // as in 'Companio_n_'
// 1. fill str[prependedCommaPos : objEndPos+1] will null characters
// 2. create the new string that has null chars filtered
val sb = StringBuilder(this)
objectIndices.forEach {
for (k in it.prependedCommaPos..it.objEndPos) {
sb[k] = '\u0000'
}
}
return sb.filter { it != '\u0000' }.toString()
}
private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int)
/**

View File

@@ -21,8 +21,9 @@ object Toolkit : Disposable {
object Theme {
val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f)
val COL_CELL_FILL = Color(0x282828C8)
val COL_CELL_FILL_OPAQUE = Color(0x282828FF)
val COL_LIST_DEFAULT = Color.WHITE
val COL_LIST_DEFAULT = Color.WHITE // white
val COL_INACTIVE = Color.LIGHT_GRAY
val COL_SELECTED = Color(0x00f8ff_ff) // cyan, HIGHLY SATURATED
val COL_MOUSE_UP = Color(0xfff066_ff.toInt()) // yellow (all yellows are of low saturation according to the colour science)
@@ -50,7 +51,7 @@ object Toolkit : Disposable {
private lateinit var blurWriteQuad2: Mesh
private lateinit var blurWriteQuad4: Mesh
val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
// val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
val textureWhiteSquare = Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga"))
val textureWhiteCircle = Texture(Gdx.files.internal("assets/graphics/circle_512.tga"))
@@ -70,7 +71,7 @@ object Toolkit : Disposable {
private val rng = HQRNG()
override fun dispose() {
baloonTile.dispose()
// baloonTile.dispose()
textureWhiteSquare.dispose()
textureWhiteCircle.dispose()
@@ -251,7 +252,7 @@ object Toolkit : Disposable {
fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) {
// centre area
batch.draw(baloonTile.get(1, 1), x, y, w, h)
/*batch.draw(baloonTile.get(1, 1), x, y, w, h)
// edges
batch.draw(baloonTile.get(1, 0), x, y - baloonTile.tileH, w, baloonTile.tileH.toFloat())
@@ -263,7 +264,13 @@ object Toolkit : Disposable {
batch.draw(baloonTile.get(0, 0), x - baloonTile.tileW, y - baloonTile.tileH)
batch.draw(baloonTile.get(2, 0), x + w, y - baloonTile.tileH)
batch.draw(baloonTile.get(2, 2), x + w, y + h)
batch.draw(baloonTile.get(0, 2), x - baloonTile.tileW, y + h)
batch.draw(baloonTile.get(0, 2), x - baloonTile.tileW, y + h)*/
batch.color = Theme.COL_CELL_FILL_OPAQUE
fillArea(batch, x - 4, y - 4, w + 8, h + 8)
batch.color = Theme.COL_INACTIVE
drawBoxBorder(batch, x - 4, y - 4, w + 8, h + 8)
}
private var init = false

View File

@@ -154,6 +154,7 @@ abstract class UICanvas(
*/
open fun doOpening(delta: Float) {
handler.opacity = handler.openCloseCounter / openCloseTime
}
/**

View File

@@ -72,7 +72,7 @@ class UIItemInlineRadioButtons(
val xpos = getCellX(i)
val text = labelfuns[i]()
val tw = App.fontGame.getWidth(text)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
}
}
@@ -83,7 +83,7 @@ class UIItemInlineRadioButtons(
Toolkit.drawBoxBorder(batch, xpos - 1, posY - 1, cellWidth + 2, height + 2)
val text = labelfuns[mouseOnSelection]()
val tw = App.fontGame.getWidth(text)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
}
// selection borders and text
@@ -92,7 +92,7 @@ class UIItemInlineRadioButtons(
Toolkit.drawBoxBorder(batch, xpos - 1, posY - 1, cellWidth + 2, height + 2)
val text = labelfuns[selection]()
val tw = App.fontGame.getWidth(text)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
super.render(batch, camera)

View File

@@ -85,12 +85,12 @@ class UIItemModuleInfoCell(
batch.draw(modIcon, initialX + 35f, initialY + 12f)
batch.shader = null
batch.color = Color.WHITE
App.fontGame.draw(batch, "$ccZero${modName.toUpperCase()}$ccNum $modVer", initialX + 86f + 3f, initialY + 2f)
App.fontGame.draw(batch, "$ccZero${modName.toUpperCase()}$ccNum $modVer", initialX + 86f + 3f, initialY.toFloat())
if (modErrored)
App.fontGame.draw(batch, "$emphRed${modErrors.first().cause?.message}", initialX + 86f + 3f, initialY + 26f)
App.fontGame.draw(batch, "$emphRed${modErrors.first().cause?.message}", initialX + 86f + 3f, initialY + 24f)
else
App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 26f)
App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 50f)
App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 24f)
App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 48f)
if (modErrored) {
batch.draw(CommonResourcePool.getAsTextureRegion("basegame_errored_icon32"), initialX + width - 40f, initialY + 8f + 12f)

View File

@@ -158,7 +158,7 @@ class UIItemSpinner(
// draw text
batch.color = UIItemTextLineInput.TEXTINPUT_COL_TEXT
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
App.fontGame.draw(batch, textCache, posX + buttonW + 3f + (fboWidth - textCacheLen).div(2), posY + 2f)
App.fontGame.draw(batch, textCache, posX + buttonW + 3f + (fboWidth - textCacheLen).div(2), posY.toFloat())
super.render(batch, camera)
}

View File

@@ -517,7 +517,7 @@ class UIItemTextLineInput(
0
// TODO support alignment-right
App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, 0f)
App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, -2f)
} }
textCommitListener(getTextOrPlaceholder())
}
@@ -587,7 +587,8 @@ class UIItemTextLineInput(
batch.draw(labels.get(8,2), btn2PosX + 2f, posY + 2f)
// state of the candidates are concurrently changing, so we buffer them
val localCandidates = ArrayList<CodepointSequence>(); candidates.forEach { localCandidates.add(it) }
val localCandidates = ArrayList<CodepointSequence>()
candidates.forEach { localCandidates.add(it) }
// draw candidates view
if (localCandidates.isNotEmpty() && ime != null) {
@@ -618,7 +619,7 @@ class UIItemTextLineInput(
val candidateNum = listOf(i+48,46,32)
App.fontGame.draw(batch, CodepointSequence(candidateNum + localCandidates[i]),
candidatePosX + (i / halfcount) * (longestCandidateW + 3) + 2,
candidatePosY + (i % halfcount) * 20 // using hard-coded 20 instead of the actual font height of 24
candidatePosY + (i % halfcount) * 20 - 2 // using hard-coded 20 instead of the actual font height of 24
)
}
@@ -639,7 +640,7 @@ class UIItemTextLineInput(
Toolkit.drawBoxBorder(batch, candidatePosX - 1, candidatePosY - 1, candidateWinW + 2, candidateWinH + 2)
val previewTextWidth = textWidths[0]
App.fontGame.draw(batch, localCandidates[0], candidatePosX + (candidateWinW - previewTextWidth) / 2, candidatePosY)
App.fontGame.draw(batch, localCandidates[0], candidatePosX + (candidateWinW - previewTextWidth) / 2, candidatePosY - 2)
}
}

View File

@@ -197,7 +197,7 @@ class UIItemTextSelector(
val t = labelCache[selection]
val tw = App.fontGame.getWidth(t)
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
App.fontGame.draw(batch, t, posX + buttonW + 3 + (fboWidth - tw) / 2, posY + 2)
App.fontGame.draw(batch, t, posX + buttonW + 3 + (fboWidth - tw) / 2, posY)
}
// palette
else {
@@ -226,7 +226,7 @@ class UIItemTextSelector(
val tw = App.fontGame.getWidth(t)
App.fontGame.draw(batch, t,
palX + (palW - tw) / 2,
getPalItemPosY(index)
getPalItemPosY(index) - 2
)
}
}

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.utils
import com.badlogic.gdx.utils.JsonReader
import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.App.printdbg
import java.io.Reader
/**
* Created by minjaesong on 2016-02-15.
@@ -18,9 +19,7 @@ object JsonFetcher {
printdbg(this, "Reading JSON $jsonFilePath")
if (jsonString == null) {
throw Error("[JsonFetcher] jsonString is null!")
}
if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
return JsonReader().parse(jsonString.toString())
}
@@ -32,13 +31,15 @@ object JsonFetcher {
printdbg(this, "Reading JSON ${jsonFile.path}")
if (jsonString == null) {
throw Error("[JsonFetcher] jsonString is null!")
}
if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
return JsonReader().parse(jsonString.toString())
}
fun readFromJsonString(stringReader: Reader): JsonValue {
return JsonReader().parse(stringReader.readText())
}
@Throws(java.io.IOException::class)
private fun readJsonFileAsString(path: String) {
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(

View File

@@ -349,12 +349,12 @@ object LightmapRenderer {
val shadeBoxCopy = it.shadeBoxList.subList(0, it.shadeBoxList.size) // make copy to prevent ConcurrentModificationException
val scale = it.scale
// put lanterns to the area the luminantBox is occupying
// put lanterns to the area the lightBox is occupying
lightBoxCopy.forEach { (lightBox, colour) ->
val lightBoxX = it.hitbox.startX + (lightBox.startX * scale)
val lightBoxY = it.hitbox.startY + (lightBox.startY * scale)
val lightBoxW = lightBox.width * scale
val lightBoxH = lightBox.height * scale
val lightBoxW = lightBox.width * scale - 1
val lightBoxH = lightBox.height * scale - 1
for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.div(TILE_SIZE).floorInt()
@@ -368,12 +368,12 @@ object LightmapRenderer {
}
}
// put shades to the area the luminantBox is occupying
// put shades to the area the shadeBox is occupying
shadeBoxCopy.forEach { (shadeBox, colour) ->
val lightBoxX = it.hitbox.startX + (shadeBox.startX * scale)
val lightBoxY = it.hitbox.startY + (shadeBox.startY * scale)
val lightBoxW = shadeBox.width * scale
val lightBoxH = shadeBox.height * scale
val lightBoxW = shadeBox.width * scale - 1
val lightBoxH = shadeBox.height * scale - 1
for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.div(TILE_SIZE).floorInt()

View File

@@ -7,7 +7,7 @@ The main game directory is composed of following directories:
```
.Terrarum
+ Players
- "${PlayerName}-${UUID}", TVDA {
- "${UUID}", TVDA {
[-1] player JSON,
[-2] spritedef,
[-3] !optional! spritedef-glow,
@@ -23,7 +23,7 @@ The main game directory is composed of following directories:
- <e.g. Disk GUID>, TEVD { * }
- <this directory can have anything>
+ Worlds
- "${WorldName}-${UUID}", TVDA {
- "${UUID}", TVDA {
[-1] world JSON with Player Data,
[actorID] actors (mainly fixtures) JSON,
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,

BIN
work_files/graphics/gui/hrule.kra LFS Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More