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="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
<orderEntry type="library" name="io.github.classgraph" level="project" />
</component> </component>
</module> </module>

View File

@@ -24,5 +24,6 @@
<orderEntry type="library" name="badlogicgames.gdx.backend.lwjgl3" level="project" /> <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.reflect" level="project" />
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" /> <orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
<orderEntry type="library" name="io.github.classgraph" level="project" />
</component> </component>
</module> </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_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
"MENU_LABEL_IME_TOGGLE": "Toggle IME", "MENU_LABEL_IME_TOGGLE": "Toggle IME",
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Cliboard", "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 258;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorBirch
259;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorRosewood 259;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorRosewood
320;net.torvald.terrarum.modulebasegame.gameitems.ItemWorldPortal
999999;net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry 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_QUICKSEL": "Quick Select",
"GAME_ACTION_CRAFT": "Craft", "GAME_ACTION_CRAFT": "Craft",
"GAME_CRAFTING": "Crafting", "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 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 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.items16,1,10;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.items16,1,11;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.items16,1,2;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.items16,2,9;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.items16,3,9;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.items16,4,9;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) # 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 getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier) fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)
fun getAsTexture(identifier: String) = getAs<Texture>(identifier) fun getAsTexture(identifier: String) = getAs<Texture>(identifier)
fun getAsItemSheet(identifier: String) = getAs<ItemSheet>(identifier)
fun dispose() { fun dispose() {
pool.forEach { (name, u) -> 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 Float.sqrt() = FastMath.sqrt(this)
fun Int.abs() = this.absoluteValue fun Int.abs() = this.absoluteValue
fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit) 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 Int.bitCount() = java.lang.Integer.bitCount(this)
fun Long.bitCount() = java.lang.Long.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 underlineColour = Color(0xeaeaea_40.toInt())
private val underlineHighlightColour = mainButtons[0].highlightCol 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 highlighterXStart = highlighterXPos
private var highlighterXEnd = highlighterXPos private var highlighterXEnd = highlighterXPos
private val highlighterYPos = catIcons.tileH + 4f private val highlighterYPos = catIcons.tileH + 4
private var highlighterMoving = false private var highlighterMoving = false
private val highlighterMoveDuration: Second = 0.15f private val highlighterMoveDuration: Second = 0.15f
private var highlighterMoveTimer: Second = 0f private var highlighterMoveTimer: Second = 0f
@@ -196,11 +196,11 @@ class UIItemInventoryCatBar(
highlighterMoveTimer += delta highlighterMoveTimer += delta
highlighterXPos = Movement.moveQuick( highlighterXPos = Movement.moveQuick(
highlighterXStart, highlighterXStart.toFloat(),
highlighterXEnd, highlighterXEnd.toFloat(),
highlighterMoveTimer, highlighterMoveTimer,
highlighterMoveDuration highlighterMoveDuration
) ).roundToInt()
if (highlighterMoveTimer > highlighterMoveDuration) { if (highlighterMoveTimer > highlighterMoveDuration) {
highlighterMoveTimer = 0f highlighterMoveTimer = 0f
@@ -224,10 +224,10 @@ class UIItemInventoryCatBar(
// normal stuffs // normal stuffs
val oldIndex = selectedIndex val oldIndex = selectedIndex
highlighterXStart = mainButtons[selectedIndex].posX.toFloat() // using old selectedIndex highlighterXStart = mainButtons[selectedIndex].posX // using old selectedIndex
selectedIndex = index selectedIndex = index
highlighterMoving = true highlighterMoving = true
highlighterXEnd = mainButtons[selectedIndex].posX.toFloat() // using new selectedIndex highlighterXEnd = mainButtons[selectedIndex].posX // using new selectedIndex
selectionChangeListener?.invoke(oldIndex, index) selectionChangeListener?.invoke(oldIndex, index)
} }
@@ -290,12 +290,12 @@ class UIItemInventoryCatBar(
if (selectedPanel == 1) { if (selectedPanel == 1) {
// indicator // indicator
batch.color = underlineHighlightColour batch.color = underlineHighlightColour
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2).round(), posY + highlighterYPos) batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2), posY + highlighterYPos.toFloat())
// label // label
batch.color = Color.WHITE batch.color = Color.WHITE
catIconsLabels[selectedIcon]().let { 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"` * 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 package net.torvald.terrarum.gameactors
import net.torvald.random.HQRNG import net.torvald.random.HQRNG
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ReferencingRanges import net.torvald.terrarum.ReferencingRanges
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.savegame.toBigEndian import net.torvald.terrarum.savegame.toBigEndian
import net.torvald.terrarum.utils.PasswordBase32 import net.torvald.terrarum.utils.PasswordBase32
@@ -82,6 +84,9 @@ abstract class Actor : Comparable<Actor>, Runnable {
if (this is Pocketed) if (this is Pocketed)
inventory.actor = this 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), TerrarumIMEConf(name, copying, lang, candidatesCount, if (keysymtable == null) keysyms else null, if (keysymtable == null) null else keysymtable, mode),
{ headkey, shifted, alted, lowLayerKeysym -> { headkey, shifted, alted, lowLayerKeysym ->
val a = jsval.invokeMember("accept", 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() a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString()
}, { }, {
jsval.invokeMember("backspace").asString().toCanditates() jsval.invokeMember("backspace").asString().toCanditates()

View File

@@ -29,7 +29,7 @@ class IMEDictionary(private val filename: String) {
private var dictLoaded = false private var dictLoaded = false
private fun loadDict() { private fun loadDict() {
val reader = FileReader(File("assets/keylayout/", filename)) val reader = FileReader(File("assets/keylayout/", filename), Charsets.UTF_8)
reader.forEachLine { reader.forEachLine {
if (it.contains(',')) { if (it.contains(',')) {
val (key, value) = it.split(',') 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.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed 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 import org.dyn4j.geometry.Vector2
typealias ItemID = String typealias ItemID = String

View File

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

View File

@@ -28,14 +28,8 @@ class EntryPoint : ModuleEntryPoint() {
printdbg(this, "Hello, world!") printdbg(this, "Hello, world!")
// load common resources to the AssetsManager // load common resources to the AssetsManager
CommonResourcePool.addToLoadingList("$moduleName.items16") { CommonResourcePool.addToLoadingList("$moduleName.items") {
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items.tga"), 16, 16) ItemSheet(ModMgr.getGdxFile(moduleName, "items/items.tga"))
}
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.loadAll() CommonResourcePool.loadAll()

View File

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

View File

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

View File

@@ -37,8 +37,8 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
this.physProp = physProp 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 */ /** Must be set by PlayerFactory */

View File

@@ -244,7 +244,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
if (canBeDespawned) { if (canBeDespawned) {
printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}") printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
printStackTrace(this) // printStackTrace(this)
// remove filler block // remove filler block
forEachBlockbox { x, y, _, _ -> forEachBlockbox { x, y, _, _ ->
@@ -312,7 +312,13 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
} }
override fun flagDespawn() { 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") val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_source.tga")
density = 1400.0 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 { makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE)).let {
it.setRowsAndFrames(1,1) it.setRowsAndFrames(1,1)

View File

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

View File

@@ -126,7 +126,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity (if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity
// define physical size // 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) blockBox = BlockBox(BlockBox.FULL_COLLISION, tilewiseHitboxWidth, tilewiseHitboxHeight)
doorHoldLength = hashMapOf( 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 { open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
override lateinit var ai: ActorAI var aiName: String = ""
@Transient override lateinit var ai: ActorAI
companion object { companion object {
val DEFAULT_COLLISION_TYPE = COLLISION_DYNAMIC val DEFAULT_COLLISION_TYPE = COLLISION_DYNAMIC
@@ -26,6 +27,7 @@ open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
constructor(ai: ActorAI, born: Long) : super(born) { constructor(ai: ActorAI, born: Long) : super(born) {
this.ai = ai this.ai = ai
this.aiName = ai::class.java.canonicalName
} }
init { init {

View File

@@ -13,7 +13,7 @@ import net.torvald.terrarum.gameactors.*
*/ */
class PhysTestLuarLander : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT), Controllable { 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 override val hitbox: Hitbox

View File

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

View File

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

View File

@@ -30,7 +30,7 @@ class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torval
equipPosition = EquipPosition.HAND_GRIP equipPosition = EquipPosition.HAND_GRIP
} }
override val makeFixture: () -> FixtureBase = { @Transient override val makeFixture: () -> FixtureBase = {
FixtureTapestry( FixtureTapestry(
Gdx.files.internal("assets/monkey_island").readBytes(), Gdx.files.internal("assets/monkey_island").readBytes(),
Block.PLANK_NORMAL 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 val materialId = "CUPR"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(0,0) get() = CommonResourcePool.getAsItemSheet("basegame.items").get(0,0)
init { init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP super.equipPosition = GameItem.EquipPosition.HAND_GRIP
@@ -151,7 +151,7 @@ class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
override val materialId = "IRON" override val materialId = "IRON"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(1,0) get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1,0)
init { init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP super.equipPosition = GameItem.EquipPosition.HAND_GRIP
@@ -181,7 +181,7 @@ class PickaxeSteel(originalID: ItemID) : GameItem(originalID) {
override val materialId = "STAL" override val materialId = "STAL"
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(2,0) get() = CommonResourcePool.getAsItemSheet("basegame.items").get(2,0)
init { init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP super.equipPosition = GameItem.EquipPosition.HAND_GRIP

View File

@@ -94,7 +94,7 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID) {
override val isDynamic = false override val isDynamic = false
override val materialId = "" override val materialId = ""
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items16").get(0, 9) get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1, 3)
init { init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP 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 isDynamic = false
override val materialId = "" override val materialId = ""
override val itemImage: TextureRegion override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegionPack(atlasID).get(sheetX, sheetY) get() = CommonResourcePool.getAsItemSheet(atlasID).get(sheetX, sheetY)
init { init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP 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)) return ItemSlotImage(slotImage.get(number, 0 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item))
} }
fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?): ItemSlotImage { fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?, hasGauge: Boolean): ItemSlotImage {
return ItemSlotImage(slotImage.get(number, 1 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item)) 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 -> message.forEachIndexed { index, s ->
val xoff = 6 + (displayedTextWidth - realTextWidth) / 2 val xoff = 6 + (displayedTextWidth - realTextWidth) / 2
val y = -textHeight + App.fontGame.lineHeight * index 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 // control hints
val controlHintXPos = thisOffsetX.toFloat() val controlHintXPos = thisOffsetX + 2f
blendNormalStraightAlpha(batch) blendNormalStraightAlpha(batch)
App.fontGame.draw(batch, controlHelp, controlHintXPos, full.yEnd - 20) App.fontGame.draw(batch, controlHelp, controlHintXPos, full.yEnd - 20)
@@ -475,7 +475,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
// encumbrance meter // encumbrance meter
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"] val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
// encumbrance bar will go one row down if control help message is too long // 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 encumbBarTextXPos = encumbBarXPos - 6 - App.fontGame.getWidth(encumbranceText)
val encumbBarYPos = full.yEnd-20 + 3f + val encumbBarYPos = full.yEnd-20 + 3f +
if (App.fontGame.getWidth(full.listControlHelp) + 2 + controlHintXPos >= encumbBarTextXPos) if (App.fontGame.getWidth(full.listControlHelp) + 2 + controlHintXPos >= encumbBarTextXPos)

View File

@@ -1,14 +1,17 @@
package net.torvald.terrarum.modulebasegame.ui package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.ceilInt import net.torvald.terrarum.ceilInt
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
import net.torvald.terrarum.ui.* import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import net.torvald.unicode.TIMES import net.torvald.unicode.TIMES
/** /**
@@ -43,6 +46,13 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
private val optionsYpos = IntArray(options.size + 1) private val optionsYpos = IntArray(options.size + 1)
init { init {
CommonResourcePool.addToLoadingList("gui_hrule") {
TextureRegionPack(Gdx.files.internal("assets/graphics/gui/hrule.tga"), 216, 20)
}
CommonResourcePool.loadAll()
var akku = 0 var akku = 0
options.forEachIndexed { index, row -> options.forEachIndexed { index, row ->
val option = row[2] val option = row[2]
@@ -60,10 +70,10 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
} }
optionsYpos[optionsYpos.lastIndex] = akku optionsYpos[optionsYpos.lastIndex] = akku
} }
override var width = 560
override var width = 420
override var height = optionsYpos.last() override var height = optionsYpos.last()
private val hrule = CommonResourcePool.getAsTextureRegionPack("gui_hrule")
private val spinnerWidth = 140 private val spinnerWidth = 140
private val drawX = (Toolkit.drawWidth - width) / 2 private val drawX = (Toolkit.drawWidth - width) / 2
@@ -170,7 +180,14 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
else else
drawX + width/2 - panelgap - labelWidth // right aligned at the middle of the panel, offsetted by panelgap 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) } 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) batch.draw(labels.get(21,2), (posX + (width - 20) / 2).toFloat(), posY + 4f)
else { else {
val keysymw = App.fontGame.getWidth(keysym) 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 // control hints
val controlHintXPos = full.offsetX val controlHintXPos = full.offsetX - 34
blendNormalStraightAlpha(batch) blendNormalStraightAlpha(batch)
batch.color = Color.WHITE batch.color = Color.WHITE
App.fontGame.draw(batch, full.listControlHelp, controlHintXPos, full.yEnd - 20) 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 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 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 const val CELLS_HOR = 12
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
(UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) 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 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 { object UIItemInventoryCellCommonRes {
val meterColourMap = GdxColorMap(Gdx.files.internal("./assets/clut/health_bar_colouring_4096.tga")) 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 { fun getHealthMeterColour(value: Float, start: Float, end: Float): Color {
if (start > end) throw IllegalArgumentException("Start value is greater than end value: $start..$end") 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 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 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 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) { ) : UIItem(parentUI, initialX, initialY) {
// deal with the moving position // deal with the moving position
@@ -225,10 +225,8 @@ open class UIItemInventoryItemGrid(
private val iconPosX = if (drawScrollOnRightside) private val iconPosX = if (drawScrollOnRightside)
posX + width + LIST_TO_CONTROL_GAP posX + width + LIST_TO_CONTROL_GAP
else 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 */ /** Long/compact mode buttons */
val gridModeButtons = Array<UIItemImageButton>(2) { index -> 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 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) { override fun render(batch: SpriteBatch, camera: Camera) {
val posXDelta = posX - oldPosX val posXDelta = posX - oldPosX
itemGrid.forEach { it.posX += posXDelta } 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 scrollDownButton.posY = getScrollDotYHeight(itemPageCount) + upDownButtonGapToDots
@@ -345,6 +346,13 @@ open class UIItemInventoryItemGrid(
} }
if (!hideSidebar) { 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) } gridModeButtons.forEach { it.render(batch, camera) }
scrollUpButton.render(batch, camera) scrollUpButton.render(batch, camera)
scrollDownButton.render(batch, camera) scrollDownButton.render(batch, camera)
@@ -356,7 +364,7 @@ open class UIItemInventoryItemGrid(
batch.color = colour batch.color = colour
batch.draw( batch.draw(
catBar.catIcons.get(if (i == itemPage) 20 else 21, 0), catBar.catIcons.get(if (i == itemPage) 20 else 21, 0),
scrollUpButton.posX.toFloat(), iconPosX.toFloat(),
getScrollDotYHeight(i).toFloat() getScrollDotYHeight(i).toFloat()
) )
} }
@@ -369,8 +377,8 @@ open class UIItemInventoryItemGrid(
walletText.forEachIndexed { index, it -> walletText.forEachIndexed { index, it ->
batch.draw( batch.draw(
walletFont.get(0, it - '0'), walletFont.get(0, it - '0'),
gridModeButtons[0].posX.toFloat(), // scroll button size: 20px, font width: 20 px gridModeButtons[0].posX - 1f, // scroll button size: 20px, font width: 20 px
gridModeButtons[0].posY + height - index * walletFont.tileH - 1f 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 // texts. Sorted in the same way as UIItemControlPaletteBaloon.iconButtons
batch.color = Color.WHITE batch.color = Color.WHITE
App.fontGame.draw(batch, Lang["GAME_ACTION_MOVE_VERB"], col0 + 72, 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 + 43) 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_INVENTORY"], col0 + 40, row1 - 2)
App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2) App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2 - 2)
App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3) App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3 - 2)
App.fontGame.draw(batch, Lang["GAME_ACTION_QUICKSEL"], col0 + 40, row4) 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["GAME_ACTION_ZOOM"], col1 + 40, row1 - 2)
App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2) App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2 - 2)
App.fontGame.draw(batch, Lang["MENU_LABEL_MENU"], col1 + 40, row3) 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 litCol = Toolkit.Theme.COL_MOUSE_UP
private val cellCol = CELL_COL 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 hruleCol = Color(1f,1f,1f,0.35f)
private val hruleColLit = litCol.cpy().sub(0f,0f,0f,0.65f) private val hruleColLit = litCol.cpy().sub(0f,0f,0f,0.65f)
private val icons = CommonResourcePool.getAsTextureRegionPack("inventory_category") private val icons = CommonResourcePool.getAsTextureRegionPack("inventory_category")
private var highlightCol: Color = defaultCol private var highlightCol: Color = defaultCol
private var highlightTextCol: Color = defaultCol
override fun update(delta: Float) { override fun update(delta: Float) {
super.update(delta) super.update(delta)
highlightCol = if (mouseUp) litCol else defaultCol highlightCol = if (mouseUp) litCol else defaultCol
highlightTextCol = if (mouseUp) litCol else Toolkit.Theme.COL_LIST_DEFAULT
} }
override fun render(batch: SpriteBatch, camera: Camera) { override fun render(batch: SpriteBatch, camera: Camera) {
@@ -632,11 +634,12 @@ class UIItemPlayerCells(
Toolkit.drawBoxBorder(batch, posX + 115, posY + 33, width - 114, 88) Toolkit.drawBoxBorder(batch, posX + 115, posY + 33, width - 114, 88)
// texts // texts
batch.color = highlightTextCol
val playTimeTextLen = App.fontGame.getWidth(totalPlayTime) val playTimeTextLen = App.fontGame.getWidth(totalPlayTime)
App.fontGame.draw(batch, playerName, x + 146f, y + height - 82f) App.fontGame.draw(batch, playerName, x + 146f, y + height - 84f)
App.fontGame.draw(batch, worldName, x + 146f, y + height - 53f) App.fontGame.draw(batch, worldName, x + 146f, y + height - 55f)
App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 24f) App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 26f)
App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 24f) App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 26f)
// icons // icons
batch.draw(icons.get(24,0), x + 120f, y + height - 82f) // player name 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 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 colourBad = Color(0xFF0011FF.toInt())
private val cellCol = CELL_COL 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 -> override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
UILoadGovernor.worldDisk = skimmer UILoadGovernor.worldDisk = skimmer
@@ -746,7 +749,7 @@ class UIItemWorldCells(
override fun update(delta: Float) { override fun update(delta: Float) {
super.update(delta) 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) { 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) App.fontSmallNumbers.draw(batch, "${skimmer.diskFile.length().ushr(10)} KiB", x + 3f, y + height - 16f)
// savegame name // savegame name
if (saveDamaged) batch.color = colourBad 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) super.render(batch, camera)
batch.color = Color.WHITE batch.color = Color.WHITE

View File

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

View File

@@ -37,7 +37,7 @@ class UIQuickslotBar : UICanvas() {
companion object { companion object {
const val SLOT_COUNT = 10 const val SLOT_COUNT = 10
const val DISPLAY_OPACITY = 0.8f const val DISPLAY_OPACITY = 0.92f
const val COMMON_OPEN_CLOSE = 0.12f const val COMMON_OPEN_CLOSE = 0.12f
} }
@@ -85,9 +85,10 @@ class UIQuickslotBar : UICanvas() {
for (i in 0 until SLOT_COUNT) { for (i in 0 until SLOT_COUNT) {
val qs = actor.inventory.getQuickslotItem(i) val qs = actor.inventory.getQuickslotItem(i)
val item = ItemCodex[qs?.itm] val item = ItemCodex[qs?.itm]
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
val image = if (i == selection) val image = if (i == selection)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item) ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
else else
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item) 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 slotCount = UIQuickslotBar.SLOT_COUNT
private val slotDistanceFromCentre: Double private val slotDistanceFromCentre: Double
get() = cellSize * 2.5 * handler.scale get() = cellSize * 2.666 * handler.scale
override var width: Int = cellSize * 7 override var width: Int = cellSize * 7
override var height: Int = width override var height: Int = width
@@ -36,7 +36,7 @@ class UIQuickslotPie : UICanvas() {
*/ */
override var openCloseTime: Second = COMMON_OPEN_CLOSE override var openCloseTime: Second = COMMON_OPEN_CLOSE
private val smallenSize = 0.93f private val smallenSize = 0.92f
var selection: Int = -1 var selection: Int = -1
@@ -66,6 +66,7 @@ class UIQuickslotPie : UICanvas() {
for (i in 0 until slotCount) { for (i in 0 until slotCount) {
val qs = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslotItem(i) val qs = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslotItem(i)
val item = ItemCodex[qs?.itm] val item = ItemCodex[qs?.itm]
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
// set position // set position
val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise
@@ -73,7 +74,7 @@ class UIQuickslotPie : UICanvas() {
// draw cells // draw cells
val image = if (i == selection) val image = if (i == selection)
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item) ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
else else
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item) 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 width = App.fontGame.getWidth(zoomText)
override var height = App.fontGame.lineHeight.toInt() override var height = App.fontGame.lineHeight.toInt()
override var openCloseTime = COMMON_OPEN_CLOSE override var openCloseTime = 0.25f
override val mouseUp = false override val mouseUp = false

View File

@@ -190,7 +190,7 @@ internal class UIStorageChest : UICanvas(
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"] val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
val chestName = chestNameFun() val chestName = chestNameFun()
val playerName = INGAME.actorNowPlaying!!.actorValue.getAsString(AVKey.NAME).orEmpty().let { it.ifBlank { Lang["GAME_INVENTORY"] } } 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 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 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 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) App.fontGame.draw(batch, playerName, thisOffsetX2 + (cellsWidth - App.fontGame.getWidth(playerName)) / 2, thisOffsetY - 30)
// control hint // control hint
App.fontGame.draw(batch, controlHelp, thisOffsetX + 2f, encumbBarYPos - 3) App.fontGame.draw(batch, controlHelp, thisOffsetX - 34f, encumbBarYPos - 3)
// encumb text // encumb text
batch.color = Color.WHITE batch.color = Color.WHITE

View File

@@ -35,10 +35,10 @@ class UITooltip : UICanvas() {
val textMarginX = 4 val textMarginX = 4
override var width: Int 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.") } set(value) { throw Error("You are not supposed to set the width of the tooltip manually.") }
override var height: Int 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.") } set(value) { throw Error("You are not supposed to set the height of the tooltip manually.") }
override fun renderUI(batch: SpriteBatch, camera: Camera) { 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.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide 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: * Structure:
@@ -18,18 +26,16 @@ import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
* *
* Created by minjaesong on 2023-05-19. * 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 width: Int = Toolkit.drawWidth
override var height = App.scr.height 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 val controlHelpHeight = App.fontGame.lineHeight
private var panelTransitionLocked = false private var panelTransitionLocked = false
@@ -43,23 +49,33 @@ class UIWorldPortal : UICanvas() {
fun requestTransition(target: Int) = transitionPanel.requestTransition(target) fun requestTransition(target: Int) = transitionPanel.requestTransition(target)
val catBar = UIItemInventoryCatBar( val catBar = UIItemWorldPortalTopBar(
this, this,
(width - UIInventoryFull.catBarWidth) / 2, 0,
42 - UIInventoryFull.YPOS_CORRECTION + (App.scr.height - UIInventoryFull.internalHeight) / 2, 42 - YPOS_CORRECTION + (App.scr.height - internalHeight) / 2,
UIInventoryFull.internalWidth,
UIInventoryFull.catBarWidth,
true
) { i -> if (!panelTransitionLocked) requestTransition(i) } ) { 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 transitionalSearch = UIWorldPortalSearch(this)
private val transitionalListing = UIWorldPortalListing(this) private val transitionalListing = UIWorldPortalListing(this)
private val transitionalCargo = UIWorldPortalCargo(this) private val transitionalCargo = UIWorldPortalCargo(this)
private val transitionPanel = UIItemHorizontalFadeSlide( private val transitionPanel = UIItemHorizontalFadeSlide(
this, this,
(width - UIInventoryFull.internalWidth) / 2, (width - internalWidth) / 2,
UIInventoryFull.INVENTORY_CELLS_OFFSET_Y(), INVENTORY_CELLS_OFFSET_Y(),
width, width,
App.scr.height, App.scr.height,
1f, 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) { override fun renderUI(batch: SpriteBatch, camera: Camera) {
UIInventoryFull.drawBackground(batch, handler.opacity) drawBackground(batch, handler.opacity)
// UI items // UI items
catBar.render(batch, camera) catBar.render(batch, camera)
transitionPanel.render(batch, camera) transitionPanel.render(batch, camera)
} }
override fun show() {
super.show()
transitionPanel.show()
INGAME.setTooltipMessage(null)
}
override fun dispose() { override fun dispose() {
catBar.dispose() catBar.dispose()
} }
@@ -102,11 +127,13 @@ class UIWorldPortal : UICanvas() {
override fun doOpening(delta: Float) { override fun doOpening(delta: Float) {
super.doOpening(delta) super.doOpening(delta)
resetUI() resetUI()
INGAME.pause()
INGAME.setTooltipMessage(null) INGAME.setTooltipMessage(null)
} }
override fun doClosing(delta: Float) { override fun doClosing(delta: Float) {
super.doClosing(delta) super.doClosing(delta)
INGAME.resume()
INGAME.setTooltipMessage(null) INGAME.setTooltipMessage(null)
} }
@@ -123,4 +150,83 @@ class UIWorldPortal : UICanvas() {
INGAME.setTooltipMessage(null) // required! 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.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.AVKey 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.INVENTORY_CELLS_OFFSET_Y
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.getCellCountVertically
import net.torvald.terrarum.savegame.DiskSkimmer 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.serialise.ascii85toUUID
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItem import net.torvald.terrarum.ui.UIItem
import net.torvald.terrarum.ui.UIItemTextButton 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.*
import java.util.zip.GZIPInputStream
/** /**
* Created by minjaesong on 2023-05-19. * 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 width: Int = Toolkit.drawWidth
override var height: Int = App.scr.height override var height: Int = App.scr.height
private val cellHeight = 48
private val buttonHeight = 24 private val buttonHeight = 24
private val gridGap = listGap private val gridGap = 10
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 thumbw = 378
private val thumbw = 360 private val textAreaW = thumbw - 32
private val thumbh = 240 private val thumbh = 252
private val hx = Toolkit.drawWidth.div(2) 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 listCount = getCellCountVertically(UIItemWorldCellsSimple.height, gridGap)
private val listHeight = cellHeight * listCount + gridGap * (listCount - 1) private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap)
private val deleteButtonWidth = 80 private val memoryGaugeWidth = textAreaW
private val buttonReset = UIItemTextButton(this, private val deleteButtonWidth = (thumbw - gridGap) / 2
"MENU_LABEL_DELETE_WORLD", private val buttonDeleteWorld = UIItemTextButton(this,
"MENU_LABEL_DELETE",
hx - gridGap/2 - deleteButtonWidth, hx - gridGap/2 - deleteButtonWidth,
y + listHeight - buttonHeight, y + listHeight - buttonHeight,
deleteButtonWidth, deleteButtonWidth,
@@ -58,71 +63,338 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
hasBorder = true, hasBorder = true,
alignment = UIItemTextButton.Companion.Alignment.CENTRE 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 { init {
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") { CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga")), 20, 20).also { TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
it.flip(false, false)
}
} }
CommonResourcePool.loadAll() 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] } 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) { WorldInfo(uuid, disk, chunksCount, seed, lastPlayed.toTimestamp(), totalPlayed.toDurationStamp(), thumb)
}.let {
batch.inUse { worldList.addAll(it)
// 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) }
} }
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() { 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( class UIItemWorldCellsSimple(
parent: UILoadDemoSavefiles, parent: UIWorldPortalListing,
initialX: Int, initialX: Int,
initialY: Int, initialY: Int,
val skimmer: DiskSkimmer internal val worldInfo: UIWorldPortalListing.WorldInfo? = null,
internal val worldName: String? = null,
) : UIItem(parent, initialX, initialY) { ) : 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 override val height: Int = 46
private val cellCol = UIInventoryFull.CELL_COL private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
private var highlightCol: Color = Color.WHITE
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() { override fun dispose() {
} }

View File

@@ -363,6 +363,8 @@ removefile:
return fa.read() return fa.read()
} }
override fun getDiskName(charset: Charset): String { override fun getDiskName(charset: Charset): String {
val bytes = ByteArray(268) val bytes = ByteArray(268)
fa.seek(10L) 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) 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 { object Theme {
val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f) val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f)
val COL_CELL_FILL = Color(0x282828C8) 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_INACTIVE = Color.LIGHT_GRAY
val COL_SELECTED = Color(0x00f8ff_ff) // cyan, HIGHLY SATURATED 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) 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 blurWriteQuad2: Mesh
private lateinit var blurWriteQuad4: 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 textureWhiteSquare = Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga"))
val textureWhiteCircle = Texture(Gdx.files.internal("assets/graphics/circle_512.tga")) val textureWhiteCircle = Texture(Gdx.files.internal("assets/graphics/circle_512.tga"))
@@ -70,7 +71,7 @@ object Toolkit : Disposable {
private val rng = HQRNG() private val rng = HQRNG()
override fun dispose() { override fun dispose() {
baloonTile.dispose() // baloonTile.dispose()
textureWhiteSquare.dispose() textureWhiteSquare.dispose()
textureWhiteCircle.dispose() textureWhiteCircle.dispose()
@@ -251,7 +252,7 @@ object Toolkit : Disposable {
fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) { fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) {
// centre area // centre area
batch.draw(baloonTile.get(1, 1), x, y, w, h) /*batch.draw(baloonTile.get(1, 1), x, y, w, h)
// edges // edges
batch.draw(baloonTile.get(1, 0), x, y - baloonTile.tileH, w, baloonTile.tileH.toFloat()) 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(0, 0), x - baloonTile.tileW, y - baloonTile.tileH)
batch.draw(baloonTile.get(2, 0), x + w, 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(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 private var init = false

View File

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

View File

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

View File

@@ -85,12 +85,12 @@ class UIItemModuleInfoCell(
batch.draw(modIcon, initialX + 35f, initialY + 12f) batch.draw(modIcon, initialX + 35f, initialY + 12f)
batch.shader = null batch.shader = null
batch.color = Color.WHITE 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) 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 else
App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 26f) App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 24f)
App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 50f) App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 48f)
if (modErrored) { if (modErrored) {
batch.draw(CommonResourcePool.getAsTextureRegion("basegame_errored_icon32"), initialX + width - 40f, initialY + 8f + 12f) batch.draw(CommonResourcePool.getAsTextureRegion("basegame_errored_icon32"), initialX + width - 40f, initialY + 8f + 12f)

View File

@@ -158,7 +158,7 @@ class UIItemSpinner(
// draw text // draw text
batch.color = UIItemTextLineInput.TEXTINPUT_COL_TEXT batch.color = UIItemTextLineInput.TEXTINPUT_COL_TEXT
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat()) // 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) super.render(batch, camera)
} }

View File

@@ -517,7 +517,7 @@ class UIItemTextLineInput(
0 0
// TODO support alignment-right // TODO support alignment-right
App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, 0f) App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, -2f)
} } } }
textCommitListener(getTextOrPlaceholder()) textCommitListener(getTextOrPlaceholder())
} }
@@ -587,7 +587,8 @@ class UIItemTextLineInput(
batch.draw(labels.get(8,2), btn2PosX + 2f, posY + 2f) batch.draw(labels.get(8,2), btn2PosX + 2f, posY + 2f)
// state of the candidates are concurrently changing, so we buffer them // 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 // draw candidates view
if (localCandidates.isNotEmpty() && ime != null) { if (localCandidates.isNotEmpty() && ime != null) {
@@ -618,7 +619,7 @@ class UIItemTextLineInput(
val candidateNum = listOf(i+48,46,32) val candidateNum = listOf(i+48,46,32)
App.fontGame.draw(batch, CodepointSequence(candidateNum + localCandidates[i]), App.fontGame.draw(batch, CodepointSequence(candidateNum + localCandidates[i]),
candidatePosX + (i / halfcount) * (longestCandidateW + 3) + 2, 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) Toolkit.drawBoxBorder(batch, candidatePosX - 1, candidatePosY - 1, candidateWinW + 2, candidateWinH + 2)
val previewTextWidth = textWidths[0] 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 t = labelCache[selection]
val tw = App.fontGame.getWidth(t) val tw = App.fontGame.getWidth(t)
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat()) // 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 // palette
else { else {
@@ -226,7 +226,7 @@ class UIItemTextSelector(
val tw = App.fontGame.getWidth(t) val tw = App.fontGame.getWidth(t)
App.fontGame.draw(batch, t, App.fontGame.draw(batch, t,
palX + (palW - tw) / 2, 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.JsonReader
import com.badlogic.gdx.utils.JsonValue import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import java.io.Reader
/** /**
* Created by minjaesong on 2016-02-15. * Created by minjaesong on 2016-02-15.
@@ -18,9 +19,7 @@ object JsonFetcher {
printdbg(this, "Reading JSON $jsonFilePath") printdbg(this, "Reading JSON $jsonFilePath")
if (jsonString == null) { if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
throw Error("[JsonFetcher] jsonString is null!")
}
return JsonReader().parse(jsonString.toString()) return JsonReader().parse(jsonString.toString())
} }
@@ -32,13 +31,15 @@ object JsonFetcher {
printdbg(this, "Reading JSON ${jsonFile.path}") printdbg(this, "Reading JSON ${jsonFile.path}")
if (jsonString == null) { if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
throw Error("[JsonFetcher] jsonString is null!")
}
return JsonReader().parse(jsonString.toString()) return JsonReader().parse(jsonString.toString())
} }
fun readFromJsonString(stringReader: Reader): JsonValue {
return JsonReader().parse(stringReader.readText())
}
@Throws(java.io.IOException::class) @Throws(java.io.IOException::class)
private fun readJsonFileAsString(path: String) { private fun readJsonFileAsString(path: String) {
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach( 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 shadeBoxCopy = it.shadeBoxList.subList(0, it.shadeBoxList.size) // make copy to prevent ConcurrentModificationException
val scale = it.scale 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) -> lightBoxCopy.forEach { (lightBox, colour) ->
val lightBoxX = it.hitbox.startX + (lightBox.startX * scale) val lightBoxX = it.hitbox.startX + (lightBox.startX * scale)
val lightBoxY = it.hitbox.startY + (lightBox.startY * scale) val lightBoxY = it.hitbox.startY + (lightBox.startY * scale)
val lightBoxW = lightBox.width * scale val lightBoxW = lightBox.width * scale - 1
val lightBoxH = lightBox.height * scale val lightBoxH = lightBox.height * scale - 1
for (y in lightBoxY.div(TILE_SIZE).floorInt() for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) { ..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.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) -> shadeBoxCopy.forEach { (shadeBox, colour) ->
val lightBoxX = it.hitbox.startX + (shadeBox.startX * scale) val lightBoxX = it.hitbox.startX + (shadeBox.startX * scale)
val lightBoxY = it.hitbox.startY + (shadeBox.startY * scale) val lightBoxY = it.hitbox.startY + (shadeBox.startY * scale)
val lightBoxW = shadeBox.width * scale val lightBoxW = shadeBox.width * scale - 1
val lightBoxH = shadeBox.height * scale val lightBoxH = shadeBox.height * scale - 1
for (y in lightBoxY.div(TILE_SIZE).floorInt() for (y in lightBoxY.div(TILE_SIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) { ..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.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 .Terrarum
+ Players + Players
- "${PlayerName}-${UUID}", TVDA { - "${UUID}", TVDA {
[-1] player JSON, [-1] player JSON,
[-2] spritedef, [-2] spritedef,
[-3] !optional! spritedef-glow, [-3] !optional! spritedef-glow,
@@ -23,7 +23,7 @@ The main game directory is composed of following directories:
- <e.g. Disk GUID>, TEVD { * } - <e.g. Disk GUID>, TEVD { * }
- <this directory can have anything> - <this directory can have anything>
+ Worlds + Worlds
- "${WorldName}-${UUID}", TVDA { - "${UUID}", TVDA {
[-1] world JSON with Player Data, [-1] world JSON with Player Data,
[actorID] actors (mainly fixtures) JSON, [actorID] actors (mainly fixtures) JSON,
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data, [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