mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 04:24:05 +09:00
Compare commits
22 Commits
v0.3.2-tes
...
v0.3.2-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d5fd984d7 | ||
|
|
8d0d84fbf8 | ||
|
|
eb2c716691 | ||
|
|
ac53f821e2 | ||
|
|
cd6df71347 | ||
|
|
ac553ed156 | ||
|
|
8c5c986cbf | ||
|
|
a0f597865e | ||
|
|
bafd0d9f7c | ||
|
|
e259fc2f3b | ||
|
|
ebbb121b8c | ||
|
|
331e89b4df | ||
|
|
98a6c9ae70 | ||
|
|
1646871ddf | ||
|
|
76bfc0fde4 | ||
|
|
ef6f39632d | ||
|
|
a3ecd4a4f4 | ||
|
|
065f80224f | ||
|
|
34fb046968 | ||
|
|
43da6cc5d8 | ||
|
|
fccc2162f6 | ||
|
|
c554df9b98 |
14
.idea/libraries/io_github_classgraph.xml
generated
Normal file
14
.idea/libraries/io_github_classgraph.xml
generated
Normal 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>
|
||||
@@ -16,5 +16,6 @@
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
|
||||
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
|
||||
<orderEntry type="library" name="io.github.classgraph" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -24,5 +24,6 @@
|
||||
<orderEntry type="library" name="badlogicgames.gdx.backend.lwjgl3" level="project" />
|
||||
<orderEntry type="library" name="jetbrains.kotlin.reflect" level="project" />
|
||||
<orderEntry type="library" name="jetbrains.kotlin.test" level="project" />
|
||||
<orderEntry type="library" name="io.github.classgraph" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
BIN
assets/graphics/gui/hrule.tga
LFS
Normal file
BIN
assets/graphics/gui/hrule.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
@@ -26,5 +26,6 @@
|
||||
"MENU_LABEL_KEYCONFIG_HELP1": "Click On the Keycap to Assign Actions",
|
||||
"MENU_LABEL_IME_TOGGLE": "Toggle IME",
|
||||
"MENU_LABEL_PASTE_FROM_CLIPBOARD": "Paste from Cliboard",
|
||||
"MENU_OPTIONS_PERFORMANCE": "Performance"
|
||||
"MENU_OPTIONS_PERFORMANCE": "Performance",
|
||||
"MENU_LABEL_DELETE": "Delete"
|
||||
}
|
||||
Binary file not shown.
@@ -14,4 +14,6 @@ id;classname
|
||||
258;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorBirch
|
||||
259;net.torvald.terrarum.modulebasegame.gameitems.ItemSwingingDoorRosewood
|
||||
|
||||
320;net.torvald.terrarum.modulebasegame.gameitems.ItemWorldPortal
|
||||
|
||||
999999;net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,5 +16,8 @@
|
||||
"GAME_ACTION_QUICKSEL": "Quick Select",
|
||||
"GAME_ACTION_CRAFT": "Craft",
|
||||
"GAME_CRAFTING": "Crafting",
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items"
|
||||
"GAME_CRAFTABLE_ITEMS": "Craftable Items",
|
||||
"CONTEXT_WORLD_SEARCH": "World Search",
|
||||
"CONTEXT_WORLD_LIST": "Worlds List",
|
||||
"MENU_LABEL_RENAME": "Rename"
|
||||
}
|
||||
BIN
assets/mods/basegame/sprites/fixtures/portal_device.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/portal_device.tga
LFS
Normal file
Binary file not shown.
@@ -1,11 +1,11 @@
|
||||
id;drop;name;renderclass;accept;inputcount;inputtype;outputtype;javaclass;inventoryimg;branching
|
||||
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,9;1
|
||||
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,10;1
|
||||
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,11;1
|
||||
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,1,2;1
|
||||
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,2,9;1
|
||||
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,3,9;1
|
||||
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items16,4,9;1
|
||||
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,4;1
|
||||
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,1,4;1
|
||||
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,2,4;1
|
||||
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,0;1
|
||||
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,3,4;1
|
||||
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,4,4;1
|
||||
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,5,4;1
|
||||
|
||||
|
||||
# accept: which wiretype (defined elsewhere) the wires acceps. Use comma to separate multiple. N/A for electronic components (aka not wires)
|
||||
|
||||
|
BIN
assets/mods/dwarventech/items/items.tga
LFS
Normal file
BIN
assets/mods/dwarventech/items/items.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/android-lint/common-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/common-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/guava-31.0.1-jre.jar
LFS
Normal file
BIN
lib/android-lint/guava-31.0.1-jre.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/intellij-core-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/intellij-core-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/kotlin-compiler-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/kotlin-compiler-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/kxml2-2.3.0.jar
LFS
Normal file
BIN
lib/android-lint/kxml2-2.3.0.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/layoutlib-api-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/layoutlib-api-31.0.1.jar
LFS
Normal file
Binary file not shown.
127
lib/android-lint/lint-31.0.1.pom
Normal file
127
lib/android-lint/lint-31.0.1.pom
Normal 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>
|
||||
BIN
lib/android-lint/lint-api-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/lint-api-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/lint-checks-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/lint-checks-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/manifest-merger-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/manifest-merger-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/protos-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/protos-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/sdk-common-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/sdk-common-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/sdklib-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/sdklib-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/shared-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/shared-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/tracker-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/tracker-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/android-lint/uast-31.0.1.jar
LFS
Normal file
BIN
lib/android-lint/uast-31.0.1.jar
LFS
Normal file
Binary file not shown.
BIN
lib/classgraph-4.8.157-javadoc.jar
LFS
Normal file
BIN
lib/classgraph-4.8.157-javadoc.jar
LFS
Normal file
Binary file not shown.
BIN
lib/classgraph-4.8.157-sources.jar
LFS
Normal file
BIN
lib/classgraph-4.8.157-sources.jar
LFS
Normal file
Binary file not shown.
BIN
lib/classgraph-4.8.157.jar
LFS
Normal file
BIN
lib/classgraph-4.8.157.jar
LFS
Normal file
Binary file not shown.
@@ -118,6 +118,7 @@ object CommonResourcePool {
|
||||
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)
|
||||
fun getAsTextureRegion(identifier: String) = getAs<TextureRegion>(identifier)
|
||||
fun getAsTexture(identifier: String) = getAs<Texture>(identifier)
|
||||
fun getAsItemSheet(identifier: String) = getAs<ItemSheet>(identifier)
|
||||
|
||||
fun dispose() {
|
||||
pool.forEach { (name, u) ->
|
||||
|
||||
49
src/net/torvald/terrarum/ItemSheet.kt
Normal file
49
src/net/torvald/terrarum/ItemSheet.kt
Normal 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()
|
||||
}
|
||||
}
|
||||
113
src/net/torvald/terrarum/QuickDirtyLint.kt
Normal file
113
src/net/torvald/terrarum/QuickDirtyLint.kt
Normal 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}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -627,7 +627,7 @@ fun Double.sqrt() = Math.sqrt(this)
|
||||
fun Float.sqrt() = FastMath.sqrt(this)
|
||||
fun Int.abs() = this.absoluteValue
|
||||
fun Double.bipolarClamp(limit: Double) = this.coerceIn(-limit, limit)
|
||||
fun Boolean.toInt() = if (this) 1 else 0
|
||||
fun Boolean.toInt(shift: Int = 0) = if (this) 1.shl(shift) else 0
|
||||
fun Int.bitCount() = java.lang.Integer.bitCount(this)
|
||||
fun Long.bitCount() = java.lang.Long.bitCount(this)
|
||||
|
||||
|
||||
@@ -136,11 +136,11 @@ class UIItemInventoryCatBar(
|
||||
private val underlineColour = Color(0xeaeaea_40.toInt())
|
||||
private val underlineHighlightColour = mainButtons[0].highlightCol
|
||||
|
||||
private var highlighterXPos = mainButtons[selectedIndex].posX.toFloat()
|
||||
private var highlighterXPos = mainButtons[selectedIndex].posX
|
||||
private var highlighterXStart = highlighterXPos
|
||||
private var highlighterXEnd = highlighterXPos
|
||||
|
||||
private val highlighterYPos = catIcons.tileH + 4f
|
||||
private val highlighterYPos = catIcons.tileH + 4
|
||||
private var highlighterMoving = false
|
||||
private val highlighterMoveDuration: Second = 0.15f
|
||||
private var highlighterMoveTimer: Second = 0f
|
||||
@@ -196,11 +196,11 @@ class UIItemInventoryCatBar(
|
||||
highlighterMoveTimer += delta
|
||||
|
||||
highlighterXPos = Movement.moveQuick(
|
||||
highlighterXStart,
|
||||
highlighterXEnd,
|
||||
highlighterXStart.toFloat(),
|
||||
highlighterXEnd.toFloat(),
|
||||
highlighterMoveTimer,
|
||||
highlighterMoveDuration
|
||||
)
|
||||
).roundToInt()
|
||||
|
||||
if (highlighterMoveTimer > highlighterMoveDuration) {
|
||||
highlighterMoveTimer = 0f
|
||||
@@ -224,10 +224,10 @@ class UIItemInventoryCatBar(
|
||||
// normal stuffs
|
||||
val oldIndex = selectedIndex
|
||||
|
||||
highlighterXStart = mainButtons[selectedIndex].posX.toFloat() // using old selectedIndex
|
||||
highlighterXStart = mainButtons[selectedIndex].posX // using old selectedIndex
|
||||
selectedIndex = index
|
||||
highlighterMoving = true
|
||||
highlighterXEnd = mainButtons[selectedIndex].posX.toFloat() // using new selectedIndex
|
||||
highlighterXEnd = mainButtons[selectedIndex].posX // using new selectedIndex
|
||||
|
||||
selectionChangeListener?.invoke(oldIndex, index)
|
||||
}
|
||||
@@ -290,12 +290,12 @@ class UIItemInventoryCatBar(
|
||||
if (selectedPanel == 1) {
|
||||
// indicator
|
||||
batch.color = underlineHighlightColour
|
||||
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2).round(), posY + highlighterYPos)
|
||||
batch.draw(underlineIndTex, (highlighterXPos - buttonGapSize / 2), posY + highlighterYPos.toFloat())
|
||||
|
||||
// label
|
||||
batch.color = Color.WHITE
|
||||
catIconsLabels[selectedIcon]().let {
|
||||
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2).toFloat(), posY + highlighterYPos + 4)
|
||||
App.fontGame.draw(batch, it, posX + ((width - App.fontGame.getWidth(it)) / 2), posY + highlighterYPos + 4)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
97
src/net/torvald/terrarum/UnserialisableTypeIssueRegistry.kt
Normal file
97
src/net/torvald/terrarum/UnserialisableTypeIssueRegistry.kt
Normal 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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@@ -148,5 +148,5 @@ object AVKey {
|
||||
*
|
||||
* example value: `"SIxM+kGlrjZgLx5Zeqz7,;:UIZ5Q=2WT35SgKpOp.,vvf'fNW3G<ROimy(Y;E<,-mdtr5|^RGOqr0x*T*lC,YABr1oQwErKG)pGC'gUG"`
|
||||
*/
|
||||
const val WORLD_PORTAL_DICT = ""
|
||||
const val WORLD_PORTAL_DICT = "worldportaldict"
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.ReferencingRanges
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
import net.torvald.terrarum.savegame.toBigEndian
|
||||
import net.torvald.terrarum.utils.PasswordBase32
|
||||
@@ -82,6 +84,9 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
||||
|
||||
if (this is Pocketed)
|
||||
inventory.actor = this
|
||||
if (this is ActorHumanoid && vehicleRidingActorID != null) {
|
||||
vehicleRiding = INGAME.getActorByID(vehicleRidingActorID!!) as Controllable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -241,6 +241,7 @@ object IME {
|
||||
TerrarumIMEConf(name, copying, lang, candidatesCount, if (keysymtable == null) keysyms else null, if (keysymtable == null) null else keysymtable, mode),
|
||||
{ headkey, shifted, alted, lowLayerKeysym ->
|
||||
val a = jsval.invokeMember("accept", headkey, shifted, alted, lowLayerKeysym)
|
||||
// println(a.getArrayElement(0).asString().map { it.code.toString(16) })
|
||||
a.getArrayElement(0).asString().toCanditates() to a.getArrayElement(1).asString()
|
||||
}, {
|
||||
jsval.invokeMember("backspace").asString().toCanditates()
|
||||
|
||||
@@ -29,7 +29,7 @@ class IMEDictionary(private val filename: String) {
|
||||
private var dictLoaded = false
|
||||
|
||||
private fun loadDict() {
|
||||
val reader = FileReader(File("assets/keylayout/", filename))
|
||||
val reader = FileReader(File("assets/keylayout/", filename), Charsets.UTF_8)
|
||||
reader.forEachLine {
|
||||
if (it.contains(',')) {
|
||||
val (key, value) = it.split(',')
|
||||
|
||||
@@ -13,6 +13,9 @@ import net.torvald.terrarum.itemproperties.Material
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
import net.torvald.terrarum.savegame.ByteArray64
|
||||
import net.torvald.terrarum.utils.HashArray
|
||||
import net.torvald.terrarum.utils.ZipCodedStr
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
typealias ItemID = String
|
||||
|
||||
@@ -123,6 +123,9 @@ object Lang {
|
||||
|
||||
private val bindOp = ">>="
|
||||
|
||||
fun getOrNull(key: String?, capitalise: Boolean = true) =
|
||||
if (key == null) null else get(key, capitalise)
|
||||
|
||||
/**
|
||||
* Syntax example:
|
||||
*
|
||||
|
||||
@@ -28,14 +28,8 @@ class EntryPoint : ModuleEntryPoint() {
|
||||
printdbg(this, "Hello, world!")
|
||||
|
||||
// load common resources to the AssetsManager
|
||||
CommonResourcePool.addToLoadingList("$moduleName.items16") {
|
||||
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items.tga"), 16, 16)
|
||||
}
|
||||
CommonResourcePool.addToLoadingList("$moduleName.items24") {
|
||||
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items24.tga"), 24, 24)
|
||||
}
|
||||
CommonResourcePool.addToLoadingList("$moduleName.items48") {
|
||||
TextureRegionPack(ModMgr.getGdxFile(moduleName, "items/items48.tga"), 48, 48)
|
||||
CommonResourcePool.addToLoadingList("$moduleName.items") {
|
||||
ItemSheet(ModMgr.getGdxFile(moduleName, "items/items.tga"))
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
|
||||
@@ -144,10 +144,11 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
val SIZE_NORMAL = Point2i(9000, 2250)
|
||||
val SIZE_LARGE = Point2i(13500, 2970)
|
||||
val SIZE_HUGE = Point2i(22500, 4500)
|
||||
val WORLDSIZE = if (App.IS_DEVELOPMENT_BUILD)
|
||||
arrayOf(Point2i(2880, 1350), SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
|
||||
val NEW_WORLD_SIZE = if (App.IS_DEVELOPMENT_BUILD)
|
||||
arrayOf(Point2i(2880, 1350), /*SIZE_SMALL, */SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
|
||||
else
|
||||
arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
|
||||
arrayOf(/*SIZE_SMALL, */SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
|
||||
val WORLDPORTAL_NEW_WORLD_SIZE = arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE)
|
||||
|
||||
val worldgenThreadExecutor = ThreadExecutor()
|
||||
}
|
||||
@@ -1263,9 +1264,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
val fixturesUnderHand = ArrayList<FixtureBase>()
|
||||
val mobsUnderHand = ArrayList<ActorWithBody>()
|
||||
actorsUnderMouse.forEach {
|
||||
if (it is FixtureBase && it.mainUI == null)
|
||||
if (it is FixtureBase) // && it.mainUI == null) // pickup avail check must be done against fixture.canBeDespawned
|
||||
fixturesUnderHand.add(it)
|
||||
else
|
||||
else if (it !is FixtureBase)
|
||||
mobsUnderHand.add(it)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
private lateinit var demoWorld: GameWorld
|
||||
private lateinit var cameraNodes: FloatArray // camera Y-pos
|
||||
private val cameraAI = object : ActorAI {
|
||||
|
||||
private var firstTime = true
|
||||
private val lookaheadDist = 100.0
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
this.physProp = physProp
|
||||
}
|
||||
|
||||
var vehicleRiding: Controllable? = null // usually player only
|
||||
|
||||
@Transient internal var vehicleRiding: Controllable? = null // usually player only
|
||||
var vehicleRidingActorID: ActorID? = null
|
||||
|
||||
|
||||
/** Must be set by PlayerFactory */
|
||||
|
||||
@@ -244,7 +244,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
|
||||
if (canBeDespawned) {
|
||||
printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
|
||||
printStackTrace(this)
|
||||
// printStackTrace(this)
|
||||
|
||||
// remove filler block
|
||||
forEachBlockbox { x, y, _, _ ->
|
||||
@@ -312,7 +312,13 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
}
|
||||
|
||||
override fun flagDespawn() {
|
||||
if (canBeDespawned) flagDespawn = true
|
||||
if (canBeDespawned) {
|
||||
printdbg(this, "Fixture at (${this.intTilewiseHitbox}) flagging despawn: ${this.javaClass.canonicalName}")
|
||||
flagDespawn = true
|
||||
}
|
||||
else {
|
||||
printdbg(this, "Fixture at (${this.intTilewiseHitbox}) CANNOT be despawned: ${this.javaClass.canonicalName}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ class FixtureLogicSignalEmitter : FixtureBase, Electric {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_source.tga")
|
||||
|
||||
density = 1400.0
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, 1)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, TILE_SIZE, TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
|
||||
@@ -23,7 +23,7 @@ internal class FixtureStorageChest : FixtureBase {
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, 1)
|
||||
|
||||
makeNewSprite(TextureRegionPack(CommonResourcePool.getAsTextureRegion("itemplaceholder_16").texture, 16, 16)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
|
||||
@@ -126,7 +126,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
|
||||
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList)[0].light = opacity
|
||||
|
||||
// define physical size
|
||||
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0)
|
||||
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 1)
|
||||
blockBox = BlockBox(BlockBox.FULL_COLLISION, tilewiseHitboxWidth, tilewiseHitboxHeight)
|
||||
|
||||
doorHoldLength = hashMapOf(
|
||||
|
||||
@@ -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).***
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,8 @@ import net.torvald.terrarum.itemproperties.Material
|
||||
*/
|
||||
open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
|
||||
|
||||
override lateinit var ai: ActorAI
|
||||
var aiName: String = ""
|
||||
@Transient override lateinit var ai: ActorAI
|
||||
|
||||
companion object {
|
||||
val DEFAULT_COLLISION_TYPE = COLLISION_DYNAMIC
|
||||
@@ -26,6 +27,7 @@ open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
|
||||
|
||||
constructor(ai: ActorAI, born: Long) : super(born) {
|
||||
this.ai = ai
|
||||
this.aiName = ai::class.java.canonicalName
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
@@ -13,7 +13,7 @@ import net.torvald.terrarum.gameactors.*
|
||||
*/
|
||||
class PhysTestLuarLander : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT), Controllable {
|
||||
|
||||
private val texture = Texture(ModMgr.getGdxFile("basegame", "sprites/phystest_lunarlander.tga"))
|
||||
@Transient private val texture = Texture(ModMgr.getGdxFile("basegame", "sprites/phystest_lunarlander.tga"))
|
||||
|
||||
override val hitbox: Hitbox
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ object PlayerBuilderSigrid {
|
||||
inventory.add("item@basegame:258", 995) // doors
|
||||
inventory.add("item@basegame:259", 995) // doors
|
||||
|
||||
inventory.add("item@basegame:320", 1) // portal
|
||||
|
||||
WireCodex.getAll().forEach {
|
||||
try {
|
||||
inventory.add(it.id, 9995)
|
||||
|
||||
@@ -28,7 +28,7 @@ class ItemSwingingDoorOak(originalID: ItemID) :
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
override val makeFixture: () -> FixtureBase = {
|
||||
@Transient override val makeFixture: () -> FixtureBase = {
|
||||
FixtureSwingingDoorOak()
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class ItemSwingingDoorEbony(originalID: ItemID) :
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
override val makeFixture: () -> FixtureBase = {
|
||||
@Transient override val makeFixture: () -> FixtureBase = {
|
||||
FixtureSwingingDoorEbony()
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class ItemSwingingDoorBirch(originalID: ItemID) :
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
override val makeFixture: () -> FixtureBase = {
|
||||
@Transient override val makeFixture: () -> FixtureBase = {
|
||||
FixtureSwingingDoorBirch()
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ class ItemSwingingDoorRosewood(originalID: ItemID) :
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
override val makeFixture: () -> FixtureBase = {
|
||||
@Transient override val makeFixture: () -> FixtureBase = {
|
||||
FixtureSwingingDoorRosewood()
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torval
|
||||
equipPosition = EquipPosition.HAND_GRIP
|
||||
}
|
||||
|
||||
override val makeFixture: () -> FixtureBase = {
|
||||
@Transient override val makeFixture: () -> FixtureBase = {
|
||||
FixtureTapestry(
|
||||
Gdx.files.internal("assets/monkey_island").readBytes(),
|
||||
Block.PLANK_NORMAL
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -121,7 +121,7 @@ class PickaxeCopper(originalID: ItemID) : GameItem(originalID) {
|
||||
override val materialId = "CUPR"
|
||||
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(0,0)
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(0,0)
|
||||
|
||||
init {
|
||||
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
@@ -151,7 +151,7 @@ class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
|
||||
override val materialId = "IRON"
|
||||
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(1,0)
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1,0)
|
||||
|
||||
init {
|
||||
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
@@ -181,7 +181,7 @@ class PickaxeSteel(originalID: ItemID) : GameItem(originalID) {
|
||||
override val materialId = "STAL"
|
||||
override var baseMass = material.density.toDouble() / MaterialCodex["IRON"].density * BASE_MASS_AND_SIZE
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items24").get(2,0)
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(2,0)
|
||||
|
||||
init {
|
||||
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
|
||||
@@ -94,7 +94,7 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID) {
|
||||
override val isDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegionPack("basegame.items16").get(0, 9)
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1, 3)
|
||||
|
||||
init {
|
||||
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
|
||||
@@ -24,7 +24,7 @@ class WirePieceSignalWire(originalID: ItemID, private val atlasID: String, priva
|
||||
override val isDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegionPack(atlasID).get(sheetX, sheetY)
|
||||
get() = CommonResourcePool.getAsItemSheet(atlasID).get(sheetX, sheetY)
|
||||
|
||||
init {
|
||||
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
|
||||
@@ -33,8 +33,9 @@ object ItemSlotImageFactory {
|
||||
return ItemSlotImage(slotImage.get(number, 0 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item))
|
||||
}
|
||||
|
||||
fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?): ItemSlotImage {
|
||||
return ItemSlotImage(slotImage.get(number, 1 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item))
|
||||
fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?, hasGauge: Boolean): ItemSlotImage {
|
||||
val y = if (hasGauge && isBlack) 9 else if (hasGauge && !isBlack) 8 else if (!hasGauge && isBlack) 3 else 1
|
||||
return ItemSlotImage(slotImage.get(number, y), ItemCodex.getItemImage(item))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -465,7 +465,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
|
||||
|
||||
// control hints
|
||||
val controlHintXPos = thisOffsetX.toFloat()
|
||||
val controlHintXPos = thisOffsetX + 2f
|
||||
blendNormalStraightAlpha(batch)
|
||||
App.fontGame.draw(batch, controlHelp, controlHintXPos, full.yEnd - 20)
|
||||
|
||||
@@ -475,7 +475,7 @@ class UICrafting(val full: UIInventoryFull) : UICanvas(), HasInventory {
|
||||
// encumbrance meter
|
||||
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
|
||||
// encumbrance bar will go one row down if control help message is too long
|
||||
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth
|
||||
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth + 36
|
||||
val encumbBarTextXPos = encumbBarXPos - 6 - App.fontGame.getWidth(encumbranceText)
|
||||
val encumbBarYPos = full.yEnd-20 + 3f +
|
||||
if (App.fontGame.getWidth(full.listControlHelp) + 2 + controlHintXPos >= encumbBarTextXPos)
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.ceilInt
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELL_COL
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.TIMES
|
||||
|
||||
/**
|
||||
@@ -43,6 +46,13 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
private val optionsYpos = IntArray(options.size + 1)
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("gui_hrule") {
|
||||
TextureRegionPack(Gdx.files.internal("assets/graphics/gui/hrule.tga"), 216, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
|
||||
|
||||
var akku = 0
|
||||
options.forEachIndexed { index, row ->
|
||||
val option = row[2]
|
||||
@@ -60,10 +70,10 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
}
|
||||
optionsYpos[optionsYpos.lastIndex] = akku
|
||||
}
|
||||
|
||||
override var width = 420
|
||||
override var width = 560
|
||||
override var height = optionsYpos.last()
|
||||
|
||||
private val hrule = CommonResourcePool.getAsTextureRegionPack("gui_hrule")
|
||||
|
||||
private val spinnerWidth = 140
|
||||
private val drawX = (Toolkit.drawWidth - width) / 2
|
||||
@@ -170,7 +180,14 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
|
||||
else
|
||||
drawX + width/2 - panelgap - labelWidth // right aligned at the middle of the panel, offsetted by panelgap
|
||||
|
||||
App.fontGame.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index].toFloat())
|
||||
App.fontGame.draw(batch, label, xpos.toFloat(), drawY + optionsYpos[index] - 2f)
|
||||
|
||||
// draw hrule
|
||||
if (mode == "h1") {
|
||||
val ruleWidth = ((width - 24 - labelWidth) / 2).toFloat()
|
||||
batch.draw(hrule.get(0,0), xpos - 24f - ruleWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
||||
batch.draw(hrule.get(0,1), xpos + 24f + labelWidth, drawY + optionsYpos[index].toFloat(), ruleWidth, hrule.tileH.toFloat())
|
||||
}
|
||||
}
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ private class UIItemInputKeycap(
|
||||
batch.draw(labels.get(21,2), (posX + (width - 20) / 2).toFloat(), posY + 4f)
|
||||
else {
|
||||
val keysymw = App.fontGame.getWidth(keysym)
|
||||
App.fontGame.draw(batch, keysym, posX + (width - keysymw) / 2, posY + 4)
|
||||
App.fontGame.draw(batch, keysym, posX + (width - keysymw) / 2, posY + 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ internal class UIInventoryCells(
|
||||
|
||||
|
||||
// control hints
|
||||
val controlHintXPos = full.offsetX
|
||||
val controlHintXPos = full.offsetX - 34
|
||||
blendNormalStraightAlpha(batch)
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, full.listControlHelp, controlHintXPos, full.yEnd - 20)
|
||||
|
||||
@@ -39,9 +39,13 @@ class UIInventoryFull(
|
||||
const val YPOS_CORRECTION = 16 // another hard-coding. X_X
|
||||
|
||||
const val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
|
||||
const val CELLS_HOR = 10
|
||||
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
|
||||
(UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap)
|
||||
const val CELLS_HOR = 12
|
||||
|
||||
fun getCellCountVertically(cellHeight: Int, gapHeight: Int = UIItemInventoryItemGrid.listGap): Int {
|
||||
return (App.scr.height - REQUIRED_MARGIN - 134 + gapHeight) / // 134 is another magic number
|
||||
(cellHeight + gapHeight)
|
||||
}
|
||||
val CELLS_VRT: Int; get() = getCellCountVertically(UIItemInventoryElemSimple.height, UIItemInventoryItemGrid.listGap)
|
||||
|
||||
const val itemListToEquipViewGap = UIItemInventoryItemGrid.listGap // used to be 24; figured out that the extra gap does nothig
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ abstract class UIItemInventoryCellBase(
|
||||
|
||||
object UIItemInventoryCellCommonRes {
|
||||
val meterColourMap = GdxColorMap(Gdx.files.internal("./assets/clut/health_bar_colouring_4096.tga"))
|
||||
val meterBackDarkening = Color(0x828282ff.toInt())
|
||||
val meterBackDarkening = Color(0x666666ff.toInt())
|
||||
|
||||
fun getHealthMeterColour(value: Float, start: Float, end: Float): Color {
|
||||
if (start > end) throw IllegalArgumentException("Start value is greater than end value: $start..$end")
|
||||
|
||||
@@ -48,7 +48,7 @@ open class UIItemInventoryItemGrid(
|
||||
touchDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Button, extra info, self
|
||||
protected val useHighlightingManager: Boolean = true, // only used by UIItemCraftingCandidateGrid which addresses buttons directly to set highlighting
|
||||
open protected val highlightEquippedItem: Boolean = true, // for some UIs that only cares about getting equipped slot number but not highlighting
|
||||
colourTheme: InventoryCellColourTheme = defaultInventoryCellTheme
|
||||
private val colourTheme: InventoryCellColourTheme = defaultInventoryCellTheme
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
// deal with the moving position
|
||||
@@ -225,10 +225,8 @@ open class UIItemInventoryItemGrid(
|
||||
private val iconPosX = if (drawScrollOnRightside)
|
||||
posX + width + LIST_TO_CONTROL_GAP
|
||||
else
|
||||
posX - LIST_TO_CONTROL_GAP - catBar.catIcons.tileW + 2
|
||||
posX - LIST_TO_CONTROL_GAP - catBar.catIcons.tileW
|
||||
|
||||
private fun getIconPosY(index: Int) =
|
||||
posY - 1 + (4 + UIItemInventoryElemWide.height - catBar.catIcons.tileH) * index
|
||||
|
||||
/** Long/compact mode buttons */
|
||||
val gridModeButtons = Array<UIItemImageButton>(2) { index ->
|
||||
@@ -321,6 +319,9 @@ open class UIItemInventoryItemGrid(
|
||||
|
||||
private val upDownButtonGapToDots = 7 // apparent gap may vary depend on the texture itself
|
||||
|
||||
private fun getIconPosY(index: Int) =
|
||||
posY + 8 + 26 * index
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
val posXDelta = posX - oldPosX
|
||||
itemGrid.forEach { it.posX += posXDelta }
|
||||
@@ -332,7 +333,7 @@ open class UIItemInventoryItemGrid(
|
||||
}
|
||||
|
||||
|
||||
fun getScrollDotYHeight(i: Int) = scrollUpButton.posY + 10 + upDownButtonGapToDots + 10 * i
|
||||
fun getScrollDotYHeight(i: Int) = scrollUpButton.posY + 14 + upDownButtonGapToDots + 10 * i
|
||||
|
||||
|
||||
scrollDownButton.posY = getScrollDotYHeight(itemPageCount) + upDownButtonGapToDots
|
||||
@@ -345,6 +346,13 @@ open class UIItemInventoryItemGrid(
|
||||
}
|
||||
|
||||
if (!hideSidebar) {
|
||||
// draw the tray
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, iconPosX - 4, getIconPosY(0) - 8, 28, height)
|
||||
// cell border
|
||||
batch.color = colourTheme.cellHighlightNormalCol
|
||||
Toolkit.drawBoxBorder(batch, iconPosX - 4, getIconPosY(0) - 8, 28, height)
|
||||
|
||||
gridModeButtons.forEach { it.render(batch, camera) }
|
||||
scrollUpButton.render(batch, camera)
|
||||
scrollDownButton.render(batch, camera)
|
||||
@@ -356,7 +364,7 @@ open class UIItemInventoryItemGrid(
|
||||
batch.color = colour
|
||||
batch.draw(
|
||||
catBar.catIcons.get(if (i == itemPage) 20 else 21, 0),
|
||||
scrollUpButton.posX.toFloat(),
|
||||
iconPosX.toFloat(),
|
||||
getScrollDotYHeight(i).toFloat()
|
||||
)
|
||||
}
|
||||
@@ -369,8 +377,8 @@ open class UIItemInventoryItemGrid(
|
||||
walletText.forEachIndexed { index, it ->
|
||||
batch.draw(
|
||||
walletFont.get(0, it - '0'),
|
||||
gridModeButtons[0].posX.toFloat(), // scroll button size: 20px, font width: 20 px
|
||||
gridModeButtons[0].posY + height - index * walletFont.tileH - 1f
|
||||
gridModeButtons[0].posX - 1f, // scroll button size: 20px, font width: 20 px
|
||||
gridModeButtons[0].posY + height - index * walletFont.tileH - 18f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,17 +416,17 @@ class UIItemControlPaletteBaloon(val parent: UIKeyboardControlPanel, initialX: I
|
||||
|
||||
// texts. Sorted in the same way as UIItemControlPaletteBaloon.iconButtons
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_MOVE_VERB"], col0 + 72, posY + 43)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_JUMP"], col1 + 40, posY + 43)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_MOVE_VERB"], col0 + 72, posY + 41)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_JUMP"], col1 + 40, posY + 41)
|
||||
|
||||
App.fontGame.draw(batch, Lang["GAME_INVENTORY"], col0 + 40, row1)
|
||||
App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_QUICKSEL"], col0 + 40, row4)
|
||||
App.fontGame.draw(batch, Lang["GAME_INVENTORY"], col0 + 40, row1 - 2)
|
||||
App.fontGame.draw(batch, Lang["GAME_CRAFTING"], col0 + 40, row2 - 2)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_GRAPPLE"], col0 + 40, row3 - 2)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_QUICKSEL"], col0 + 40, row4 - 2)
|
||||
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_ZOOM"], col1 + 40, row1)
|
||||
App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2)
|
||||
App.fontGame.draw(batch, Lang["MENU_LABEL_MENU"], col1 + 40, row3)
|
||||
App.fontGame.draw(batch, Lang["GAME_ACTION_ZOOM"], col1 + 40, row1 - 2)
|
||||
App.fontGame.draw(batch, Lang["MENU_LABEL_IME_TOGGLE"], col1 + 40, row2 - 2)
|
||||
App.fontGame.draw(batch, Lang["MENU_LABEL_MENU"], col1 + 40, row3 - 2)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -532,17 +532,19 @@ class UIItemPlayerCells(
|
||||
|
||||
private val litCol = Toolkit.Theme.COL_MOUSE_UP
|
||||
private val cellCol = CELL_COL
|
||||
private val defaultCol = Color.WHITE
|
||||
private val defaultCol = Toolkit.Theme.COL_INACTIVE
|
||||
private val hruleCol = Color(1f,1f,1f,0.35f)
|
||||
private val hruleColLit = litCol.cpy().sub(0f,0f,0f,0.65f)
|
||||
|
||||
private val icons = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
|
||||
private var highlightCol: Color = defaultCol
|
||||
private var highlightTextCol: Color = defaultCol
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
highlightCol = if (mouseUp) litCol else defaultCol
|
||||
highlightTextCol = if (mouseUp) litCol else Toolkit.Theme.COL_LIST_DEFAULT
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
@@ -632,11 +634,12 @@ class UIItemPlayerCells(
|
||||
Toolkit.drawBoxBorder(batch, posX + 115, posY + 33, width - 114, 88)
|
||||
|
||||
// texts
|
||||
batch.color = highlightTextCol
|
||||
val playTimeTextLen = App.fontGame.getWidth(totalPlayTime)
|
||||
App.fontGame.draw(batch, playerName, x + 146f, y + height - 82f)
|
||||
App.fontGame.draw(batch, worldName, x + 146f, y + height - 53f)
|
||||
App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 24f)
|
||||
App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 24f)
|
||||
App.fontGame.draw(batch, playerName, x + 146f, y + height - 84f)
|
||||
App.fontGame.draw(batch, worldName, x + 146f, y + height - 55f)
|
||||
App.fontGame.draw(batch, lastPlayTime, x + 146f, y + height - 26f)
|
||||
App.fontGame.draw(batch, totalPlayTime, x + width - 5f - playTimeTextLen, y + height - 26f)
|
||||
// icons
|
||||
batch.draw(icons.get(24,0), x + 120f, y + height - 82f) // player name
|
||||
batch.draw(icons.get(12,0), x + 119f, y + height - 53f) // world map
|
||||
@@ -734,7 +737,7 @@ class UIItemWorldCells(
|
||||
private val colourBad = Color(0xFF0011FF.toInt())
|
||||
private val cellCol = CELL_COL
|
||||
|
||||
private var highlightCol: Color = Color.WHITE
|
||||
private var highlightCol: Color = Toolkit.Theme.COL_LIST_DEFAULT
|
||||
|
||||
override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int ->
|
||||
UILoadGovernor.worldDisk = skimmer
|
||||
@@ -746,7 +749,7 @@ class UIItemWorldCells(
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Color.WHITE
|
||||
highlightCol = if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_LIST_DEFAULT
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
@@ -805,7 +808,7 @@ class UIItemWorldCells(
|
||||
App.fontSmallNumbers.draw(batch, "${skimmer.diskFile.length().ushr(10)} KiB", x + 3f, y + height - 16f)
|
||||
// savegame name
|
||||
if (saveDamaged) batch.color = colourBad
|
||||
App.fontGame.draw(batch, saveName, x + 3f, y + 1f)
|
||||
App.fontGame.draw(batch, saveName, x + 3f, y + -1f)
|
||||
|
||||
super.render(batch, camera)
|
||||
batch.color = Color.WHITE
|
||||
|
||||
@@ -14,6 +14,7 @@ import net.torvald.terrarum.Second
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.NEW_WORLD_SIZE
|
||||
import net.torvald.terrarum.modulebasegame.WorldgenLoadScreen
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.savegame.ByteArray64Reader
|
||||
@@ -34,7 +35,7 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
private val normalTex = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/normal.png")))
|
||||
private val smallTex = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/small.png")))
|
||||
|
||||
private val tex = arrayOf(smallTex, normalTex, largeTex, hugeTex)
|
||||
private val tex = arrayOf(/*smallTex, */normalTex, largeTex, hugeTex)
|
||||
|
||||
override var width = 480
|
||||
override var height = 480
|
||||
@@ -42,9 +43,9 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
private val drawX = (Toolkit.drawWidth - width) / 2
|
||||
private val drawY = (App.scr.height - height) / 2
|
||||
|
||||
private val radioCellWidth = 100
|
||||
private val radioCellWidth = 116
|
||||
private val inputWidth = 340
|
||||
private val radioX = (width - (radioCellWidth * (if (App.IS_DEVELOPMENT_BUILD) 5 else 4) + 9)) / 2
|
||||
private val radioX = (width - (radioCellWidth * NEW_WORLD_SIZE.size + 9)) / 2
|
||||
private val inputX = width - inputWidth
|
||||
|
||||
private val sizeSelY = 186 + 40
|
||||
@@ -56,15 +57,15 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
if (App.IS_DEVELOPMENT_BUILD)
|
||||
listOf(
|
||||
{ Lang["CONTEXT_DESCRIPTION_TINY"] },
|
||||
{ Lang["CONTEXT_DESCRIPTION_SMALL"] },
|
||||
{ Lang["MENU_SETTING_MEDIUM"] }, // ;p
|
||||
// { Lang["CONTEXT_DESCRIPTION_TINY"] }, // only available for World Portal
|
||||
{ Lang["CONTEXT_DESCRIPTION_SMALL"] }, // ;p
|
||||
{ Lang["CONTEXT_DESCRIPTION_BIG"] },
|
||||
{ Lang["CONTEXT_DESCRIPTION_HUGE"] }
|
||||
)
|
||||
else
|
||||
listOf(
|
||||
{ Lang["CONTEXT_DESCRIPTION_SMALL"] },
|
||||
{ Lang["MENU_SETTING_MEDIUM"] }, // ;p
|
||||
// { Lang["CONTEXT_DESCRIPTION_TINY"] }, // only available for World Portal
|
||||
{ Lang["CONTEXT_DESCRIPTION_SMALL"] }, // ;p
|
||||
{ Lang["CONTEXT_DESCRIPTION_BIG"] },
|
||||
{ Lang["CONTEXT_DESCRIPTION_HUGE"] }
|
||||
)
|
||||
@@ -85,8 +86,6 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
private val goButton = UIItemTextButton(this, "MENU_LABEL_CONFIRM_BUTTON", drawX + width/2 + (width/2 - goButtonWidth) / 2, drawY + height - 24, goButtonWidth, true, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
||||
|
||||
init {
|
||||
tex.forEach { it.flip(false, false) }
|
||||
|
||||
goButton.touchDownListener = { _, _, _, _ ->
|
||||
// printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")
|
||||
|
||||
@@ -98,7 +97,7 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
catch (e: NumberFormatException) {
|
||||
XXHash64.hash(seedInput.getTextOrPlaceholder().toByteArray(Charsets.UTF_8), 10000)
|
||||
}
|
||||
val (wx, wy) = TerrarumIngame.WORLDSIZE[sizeSelector.selection]
|
||||
val (wx, wy) = TerrarumIngame.NEW_WORLD_SIZE[sizeSelector.selection]
|
||||
val worldParam = TerrarumIngame.NewGameParams(
|
||||
player, TerrarumIngame.NewWorldParameters(
|
||||
wx, wy, seed, nameInput.getTextOrPlaceholder()
|
||||
|
||||
@@ -37,7 +37,7 @@ class UIQuickslotBar : UICanvas() {
|
||||
|
||||
companion object {
|
||||
const val SLOT_COUNT = 10
|
||||
const val DISPLAY_OPACITY = 0.8f
|
||||
const val DISPLAY_OPACITY = 0.92f
|
||||
const val COMMON_OPEN_CLOSE = 0.12f
|
||||
}
|
||||
|
||||
@@ -85,9 +85,10 @@ class UIQuickslotBar : UICanvas() {
|
||||
for (i in 0 until SLOT_COUNT) {
|
||||
val qs = actor.inventory.getQuickslotItem(i)
|
||||
val item = ItemCodex[qs?.itm]
|
||||
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
|
||||
|
||||
val image = if (i == selection)
|
||||
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item)
|
||||
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
|
||||
else
|
||||
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item)
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class UIQuickslotPie : UICanvas() {
|
||||
private val slotCount = UIQuickslotBar.SLOT_COUNT
|
||||
|
||||
private val slotDistanceFromCentre: Double
|
||||
get() = cellSize * 2.5 * handler.scale
|
||||
get() = cellSize * 2.666 * handler.scale
|
||||
override var width: Int = cellSize * 7
|
||||
override var height: Int = width
|
||||
|
||||
@@ -36,7 +36,7 @@ class UIQuickslotPie : UICanvas() {
|
||||
*/
|
||||
override var openCloseTime: Second = COMMON_OPEN_CLOSE
|
||||
|
||||
private val smallenSize = 0.93f
|
||||
private val smallenSize = 0.92f
|
||||
|
||||
var selection: Int = -1
|
||||
|
||||
@@ -66,6 +66,7 @@ class UIQuickslotPie : UICanvas() {
|
||||
for (i in 0 until slotCount) {
|
||||
val qs = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslotItem(i)
|
||||
val item = ItemCodex[qs?.itm]
|
||||
val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true
|
||||
|
||||
// set position
|
||||
val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise
|
||||
@@ -73,7 +74,7 @@ class UIQuickslotPie : UICanvas() {
|
||||
|
||||
// draw cells
|
||||
val image = if (i == selection)
|
||||
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item)
|
||||
ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge)
|
||||
else
|
||||
ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item)
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class UIScreenZoom : UICanvas(
|
||||
override var width = App.fontGame.getWidth(zoomText)
|
||||
override var height = App.fontGame.lineHeight.toInt()
|
||||
|
||||
override var openCloseTime = COMMON_OPEN_CLOSE
|
||||
override var openCloseTime = 0.25f
|
||||
|
||||
override val mouseUp = false
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ internal class UIStorageChest : UICanvas(
|
||||
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
|
||||
val chestName = chestNameFun()
|
||||
val playerName = INGAME.actorNowPlaying!!.actorValue.getAsString(AVKey.NAME).orEmpty().let { it.ifBlank { Lang["GAME_INVENTORY"] } }
|
||||
val encumbBarXPos = itemListPlayer.posX + itemListPlayer.width - UIInventoryCells.weightBarWidth
|
||||
val encumbBarXPos = itemListPlayer.posX + itemListPlayer.width - UIInventoryCells.weightBarWidth + 36
|
||||
val encumbBarTextXPos = encumbBarXPos - 6 - App.fontGame.getWidth(encumbranceText)
|
||||
val yEnd = -UIInventoryFull.YPOS_CORRECTION + (App.scr.height + UIInventoryFull.internalHeight).div(2).toFloat() // directly copied from UIInventoryFull.yEnd
|
||||
val encumbBarYPos = yEnd - 20 + 3 // dunno why but extra 3 px is needed
|
||||
@@ -224,7 +224,7 @@ internal class UIStorageChest : UICanvas(
|
||||
App.fontGame.draw(batch, playerName, thisOffsetX2 + (cellsWidth - App.fontGame.getWidth(playerName)) / 2, thisOffsetY - 30)
|
||||
|
||||
// control hint
|
||||
App.fontGame.draw(batch, controlHelp, thisOffsetX + 2f, encumbBarYPos - 3)
|
||||
App.fontGame.draw(batch, controlHelp, thisOffsetX - 34f, encumbBarYPos - 3)
|
||||
|
||||
// encumb text
|
||||
batch.color = Color.WHITE
|
||||
|
||||
@@ -35,10 +35,10 @@ class UITooltip : UICanvas() {
|
||||
val textMarginX = 4
|
||||
|
||||
override var width: Int
|
||||
get() = msgWidth + (textMarginX + Toolkit.baloonTile.tileW) * 2
|
||||
get() = msgWidth + (textMarginX + 36) * 2
|
||||
set(value) { throw Error("You are not supposed to set the width of the tooltip manually.") }
|
||||
override var height: Int
|
||||
get() = Toolkit.baloonTile.tileH * 2 + font.lineHeight.toInt()
|
||||
get() = 36 * 2 + font.lineHeight.toInt()
|
||||
set(value) { throw Error("You are not supposed to set the height of the tooltip manually.") }
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
|
||||
@@ -4,9 +4,17 @@ import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.YPOS_CORRECTION
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.drawBackground
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalHeight
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.getKeycapConsole
|
||||
import net.torvald.unicode.getKeycapPC
|
||||
|
||||
/**
|
||||
* Structure:
|
||||
@@ -18,18 +26,16 @@ import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
|
||||
*
|
||||
* Created by minjaesong on 2023-05-19.
|
||||
*/
|
||||
class UIWorldPortal : UICanvas() {
|
||||
class UIWorldPortal : UICanvas(
|
||||
toggleKeyLiteral = App.getConfigInt("control_key_inventory"),
|
||||
toggleButtonLiteral = App.getConfigInt("control_gamepad_start"),
|
||||
) {
|
||||
|
||||
override var width = App.scr.width
|
||||
override var height = App.scr.height
|
||||
override var width: Int = Toolkit.drawWidth
|
||||
override var height: Int = App.scr.height
|
||||
|
||||
|
||||
|
||||
val gradStartCol = Color(0x404040_60)
|
||||
val gradEndCol = Color(0x000000_70)
|
||||
val gradHeight = 48f
|
||||
|
||||
|
||||
val controlHelpHeight = App.fontGame.lineHeight
|
||||
|
||||
private var panelTransitionLocked = false
|
||||
@@ -43,23 +49,33 @@ class UIWorldPortal : UICanvas() {
|
||||
fun requestTransition(target: Int) = transitionPanel.requestTransition(target)
|
||||
|
||||
|
||||
val catBar = UIItemInventoryCatBar(
|
||||
val catBar = UIItemWorldPortalTopBar(
|
||||
this,
|
||||
(width - UIInventoryFull.catBarWidth) / 2,
|
||||
42 - UIInventoryFull.YPOS_CORRECTION + (App.scr.height - UIInventoryFull.internalHeight) / 2,
|
||||
UIInventoryFull.internalWidth,
|
||||
UIInventoryFull.catBarWidth,
|
||||
true
|
||||
0,
|
||||
42 - YPOS_CORRECTION + (App.scr.height - internalHeight) / 2,
|
||||
) { i -> if (!panelTransitionLocked) requestTransition(i) }
|
||||
|
||||
|
||||
private val SP = "\u3000 "
|
||||
val portalListingControlHelp: String
|
||||
get() = if (App.environment == RunningEnvironment.PC)
|
||||
"${getKeycapPC(App.getConfigInt("control_key_up"))}${getKeycapPC(App.getConfigInt("control_key_down"))}" +
|
||||
" ${Lang["MENU_CONTROLS_SCROLL"]}" +
|
||||
"$SP${getKeycapPC(App.getConfigInt("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
|
||||
else
|
||||
"${getKeycapConsole('R')} ${Lang["MENU_CONTROLS_SCROLL"]}" +
|
||||
"$SP${App.gamepadLabelStart} ${Lang["GAME_ACTION_CLOSE"]}" +
|
||||
"$SP${App.gamepadLabelLT} ${Lang["GAME_WORLD_SEARCH"]}" +
|
||||
"$SP${App.gamepadLabelRT} ${Lang["GAME_INVENTORY"]}"
|
||||
|
||||
|
||||
private val transitionalSearch = UIWorldPortalSearch(this)
|
||||
private val transitionalListing = UIWorldPortalListing(this)
|
||||
private val transitionalCargo = UIWorldPortalCargo(this)
|
||||
private val transitionPanel = UIItemHorizontalFadeSlide(
|
||||
this,
|
||||
(width - UIInventoryFull.internalWidth) / 2,
|
||||
UIInventoryFull.INVENTORY_CELLS_OFFSET_Y(),
|
||||
(width - internalWidth) / 2,
|
||||
INVENTORY_CELLS_OFFSET_Y(),
|
||||
width,
|
||||
App.scr.height,
|
||||
1f,
|
||||
@@ -74,7 +90,10 @@ class UIWorldPortal : UICanvas() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal var xEnd = (width + internalWidth).div(2).toFloat()
|
||||
private set
|
||||
internal var yEnd = -YPOS_CORRECTION + (App.scr.height + internalHeight).div(2).toFloat()
|
||||
private set
|
||||
|
||||
|
||||
|
||||
@@ -84,13 +103,19 @@ class UIWorldPortal : UICanvas() {
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
UIInventoryFull.drawBackground(batch, handler.opacity)
|
||||
drawBackground(batch, handler.opacity)
|
||||
|
||||
// UI items
|
||||
catBar.render(batch, camera)
|
||||
transitionPanel.render(batch, camera)
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
transitionPanel.show()
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
catBar.dispose()
|
||||
}
|
||||
@@ -102,11 +127,13 @@ class UIWorldPortal : UICanvas() {
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
resetUI()
|
||||
INGAME.pause()
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun doClosing(delta: Float) {
|
||||
super.doClosing(delta)
|
||||
INGAME.resume()
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
@@ -124,3 +151,82 @@ class UIWorldPortal : UICanvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,20 +2,32 @@ package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap
|
||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.getCellCountVertically
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.ascii85toUUID
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItem
|
||||
import net.torvald.terrarum.ui.UIItemTextButton
|
||||
import net.torvald.terrarum.utils.JsonFetcher
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.EMDASH
|
||||
import java.time.Instant
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-05-19.
|
||||
@@ -26,31 +38,24 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
|
||||
override var width: Int = Toolkit.drawWidth
|
||||
override var height: Int = App.scr.height
|
||||
|
||||
private val cellHeight = 48
|
||||
private val buttonHeight = 24
|
||||
private val gridGap = listGap
|
||||
|
||||
private var worldList: List<Pair<UUID, DiskSkimmer>>
|
||||
private var selectedWorld: DiskSkimmer? = null
|
||||
|
||||
|
||||
private val cellCol = UIInventoryFull.CELL_COL
|
||||
private var highlightCol: Color = Color.WHITE
|
||||
private val gridGap = 10
|
||||
|
||||
|
||||
|
||||
|
||||
private val thumbw = 360
|
||||
private val thumbh = 240
|
||||
private val thumbw = 378
|
||||
private val textAreaW = thumbw - 32
|
||||
private val thumbh = 252
|
||||
private val hx = Toolkit.drawWidth.div(2)
|
||||
private val y = INVENTORY_CELLS_OFFSET_Y()
|
||||
private val y = INVENTORY_CELLS_OFFSET_Y() + 1
|
||||
|
||||
private val listCount = UIInventoryFull.CELLS_VRT
|
||||
private val listHeight = cellHeight * listCount + gridGap * (listCount - 1)
|
||||
private val listCount = getCellCountVertically(UIItemWorldCellsSimple.height, gridGap)
|
||||
private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap)
|
||||
|
||||
private val deleteButtonWidth = 80
|
||||
private val buttonReset = UIItemTextButton(this,
|
||||
"MENU_LABEL_DELETE_WORLD",
|
||||
private val memoryGaugeWidth = textAreaW
|
||||
private val deleteButtonWidth = (thumbw - gridGap) / 2
|
||||
private val buttonDeleteWorld = UIItemTextButton(this,
|
||||
"MENU_LABEL_DELETE",
|
||||
hx - gridGap/2 - deleteButtonWidth,
|
||||
y + listHeight - buttonHeight,
|
||||
deleteButtonWidth,
|
||||
@@ -58,71 +63,338 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
|
||||
hasBorder = true,
|
||||
alignment = UIItemTextButton.Companion.Alignment.CENTRE
|
||||
)
|
||||
private val buttonRenameWorld = UIItemTextButton(this,
|
||||
"MENU_LABEL_RENAME",
|
||||
buttonDeleteWorld.posX - gridGap - deleteButtonWidth,
|
||||
y + listHeight - buttonHeight,
|
||||
deleteButtonWidth,
|
||||
readFromLang = true,
|
||||
hasBorder = true,
|
||||
alignment = UIItemTextButton.Companion.Alignment.CENTRE
|
||||
)
|
||||
|
||||
private val worldList = ArrayList<WorldInfo>()
|
||||
data class WorldInfo(
|
||||
val uuid: UUID,
|
||||
val diskSkimmer: DiskSkimmer,
|
||||
val dimensionInChunks: Int,
|
||||
val seed: Long,
|
||||
val lastPlayedString: String,
|
||||
val totalPlayedString: String,
|
||||
val screenshot: TextureRegion?,
|
||||
) {
|
||||
fun dispose() {
|
||||
screenshot?.texture?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
|
||||
TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga")), 20, 20).also {
|
||||
it.flip(false, false)
|
||||
}
|
||||
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
|
||||
addUIitem(buttonReset)
|
||||
addUIitem(buttonRenameWorld)
|
||||
addUIitem(buttonDeleteWorld)
|
||||
|
||||
}
|
||||
|
||||
worldList = (INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").map {
|
||||
private var chunksUsed = 0
|
||||
private val chunksMax = 100000
|
||||
|
||||
private lateinit var worldCells: Array<UIItemWorldCellsSimple>
|
||||
|
||||
private var selected: UIItemWorldCellsSimple? = null
|
||||
private var selectedIndex: Int? = null
|
||||
|
||||
override fun show() {
|
||||
worldList.clear()
|
||||
(INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").filter { it.isNotBlank() }.map {
|
||||
it.ascii85toUUID().let { it to App.savegameWorlds[it] }
|
||||
}.filter { it.second != null } as List<Pair<UUID, DiskSkimmer>>
|
||||
}.filter { it.second != null }.mapIndexed { index, (uuid, disk) ->
|
||||
|
||||
var chunksCount = 0
|
||||
var seed = 0L
|
||||
var lastPlayed = 0L
|
||||
var totalPlayed = 0L
|
||||
var w = 0
|
||||
var h = 0
|
||||
var thumb: TextureRegion? = null
|
||||
|
||||
JsonFetcher.readFromJsonString(ByteArray64Reader(disk!!.requestFile(-1)!!.contents.getContent() as ByteArray64, Common.CHARSET)).let {
|
||||
JsonFetcher.forEachSiblings(it) { name, value ->
|
||||
if (name == "width") w = value.asInt()
|
||||
if (name == "height") h = value.asInt()
|
||||
if (name == "generatorSeed") seed = value.asLong()
|
||||
if (name == "lastPlayTime") lastPlayed = value.asLong()
|
||||
if (name == "totalPlayTime") totalPlayed = value.asLong()
|
||||
}
|
||||
}
|
||||
chunksCount = (w / CHUNK_W) * (h / CHUNK_H)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
WorldInfo(uuid, disk, chunksCount, seed, lastPlayed.toTimestamp(), totalPlayed.toDurationStamp(), thumb)
|
||||
}.let {
|
||||
worldList.addAll(it)
|
||||
}
|
||||
|
||||
|
||||
|
||||
chunksUsed = worldList.sumOf { it.dimensionInChunks }
|
||||
|
||||
worldCells = Array(maxOf(worldList.size, listCount)) {
|
||||
UIItemWorldCellsSimple(
|
||||
this,
|
||||
hx + gridGap / 2,
|
||||
y + (gridGap + UIItemWorldCellsSimple.height) * it,
|
||||
worldList.getOrNull(it),
|
||||
worldList.getOrNull(it)?.diskSkimmer?.getDiskName(Common.CHARSET)
|
||||
).also { button ->
|
||||
button.clickOnceListener = { _, _, _ ->
|
||||
selected = button
|
||||
selectedIndex = it
|
||||
updateUIbyButtonSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiItems.forEach { it.show() }
|
||||
worldCells.forEach { it.show() }
|
||||
selected = null
|
||||
|
||||
updateUIbyButtonSelection()
|
||||
}
|
||||
|
||||
private fun Long.toTimestamp() = Instant.ofEpochSecond(this)
|
||||
.atZone(TimeZone.getDefault().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||
private fun Long.toDurationStamp(): String {
|
||||
val s = this % 60
|
||||
val m = (this / 60) % 60
|
||||
val h = (this / 3600) % 24
|
||||
val d = this / 86400
|
||||
return if (d == 0L)
|
||||
"${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
else
|
||||
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
}
|
||||
private val nullTimestamp = "0000-00-00 --:--:--"
|
||||
private val nullDurationStamp = "--h--m--s"
|
||||
private fun Int.chunkCountToWorldSize() = when(this) {
|
||||
in 0 until 2000 -> "CONTEXT_DESCRIPTION_TINY"
|
||||
in 2000 until 4500 -> "CONTEXT_DESCRIPTION_SMALL"
|
||||
in 4500 until 10000 -> "CONTEXT_DESCRIPTION_BIG"
|
||||
else -> "CONTEXT_DESCRIPTION_HUGE"
|
||||
}
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
|
||||
uiItems.forEach { it.update(delta) }
|
||||
worldCells.forEach { it.update(delta) }
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
private val iconGap = 12f
|
||||
private val iconSize = 30f
|
||||
private val textualListHeight = 30f
|
||||
private val iconSizeGap = iconSize + iconGap
|
||||
|
||||
batch.inUse {
|
||||
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 = cellCol
|
||||
batch.color = UIInventoryFull.CELL_COL
|
||||
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
|
||||
|
||||
|
||||
// draw border //
|
||||
// screencap panel
|
||||
batch.color = highlightCol
|
||||
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
|
||||
Toolkit.drawBoxBorder(batch, hx - 330 - gridGap/2 - 1, y + listHeight - 1, 240 + 2, buttonHeight + 2)
|
||||
val barCol = UIItemInventoryCellCommonRes.getHealthMeterColour(chunksMax - chunksUsed, 0, chunksMax)
|
||||
val barBack = barCol mul UIItemInventoryCellCommonRes.meterBackDarkening
|
||||
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt(), memoryGaugeYpos, buttonHeight + 6, buttonHeight)
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt() - 1, memoryGaugeYpos - 1, buttonHeight + 7, buttonHeight + 2)
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(icons.get(2, 2), textXpos - iconSizeGap, memoryGaugeYpos + 2f)
|
||||
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, memoryGaugeXpos - 1, memoryGaugeYpos - 1, memoryGaugeWidth + 2, buttonHeight + 2)
|
||||
batch.color = barBack
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, memoryGaugeWidth, buttonHeight)
|
||||
batch.color = barCol
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (chunksUsed / chunksMax.toFloat())).ceilInt(), buttonHeight)
|
||||
|
||||
batch.color = Color.WHITE
|
||||
if (selected?.worldInfo != null) {
|
||||
// background for texts panel
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y + thumbh + 3, thumbw, 10 + worldTexts.size * textualListHeight.toInt())
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y + thumbh + 2, thumbw + 2, 10 + worldTexts.size * textualListHeight.toInt() + 2)
|
||||
|
||||
// some texts
|
||||
batch.color = Color.WHITE
|
||||
worldTexts.forEachIndexed { index, (icon, str) ->
|
||||
batch.draw(icon, textXpos - iconSizeGap + 6, y + thumbh + 3+10 + textualListHeight * index)
|
||||
App.fontGame.draw(batch, str, textXpos + 6f, y + thumbh + 3+10 + textualListHeight * index - 2f)
|
||||
}
|
||||
// size indicator on the memory gauge
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (selected?.worldInfo!!.dimensionInChunks / chunksMax.toFloat())).ceilInt(), buttonHeight)
|
||||
|
||||
// thumbnail
|
||||
selected?.worldInfo?.screenshot?.let {
|
||||
batch.draw(it, (hx - thumbw - gridGap/2).toFloat(), y.toFloat(), thumbw.toFloat(), thumbh.toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
worldCells.forEach { it.render(batch, camera) }
|
||||
|
||||
// control hints
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, full.portalListingControlHelp, hx - thumbw - gridGap/2 + 2, (full.yEnd - 20).toInt())
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
uiItems.forEach { it.hide() }
|
||||
worldCells.forEach { it.hide() }
|
||||
|
||||
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
uiItems.forEach { it.dispose() }
|
||||
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
}
|
||||
|
||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (this.isVisible && mouseInScreen(screenX, screenY)) {
|
||||
uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
worldCells.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
handler.subUIs.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
|
||||
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (this.isVisible) {
|
||||
uiItems.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
worldCells.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
handler.subUIs.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UIItemWorldCellsSimple(
|
||||
parent: UILoadDemoSavefiles,
|
||||
parent: UIWorldPortalListing,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
val skimmer: DiskSkimmer
|
||||
internal val worldInfo: UIWorldPortalListing.WorldInfo? = null,
|
||||
internal val worldName: String? = null,
|
||||
) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
override val width: Int = 360
|
||||
companion object {
|
||||
const val width = 378
|
||||
const val height = 46
|
||||
}
|
||||
|
||||
override val width: Int = 378
|
||||
override val height: Int = 46
|
||||
|
||||
private val cellCol = UIInventoryFull.CELL_COL
|
||||
private var highlightCol: Color = Color.WHITE
|
||||
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
|
||||
|
||||
var highlighted = false
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
super.hide()
|
||||
}
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
super.render(batch, camera)
|
||||
|
||||
|
||||
// draw background
|
||||
batch.color = UIInventoryFull.CELL_COL
|
||||
Toolkit.fillArea(batch, posX, posY, width, height)
|
||||
|
||||
val mouseUp = mouseUp && worldInfo != null
|
||||
|
||||
val bcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INVENTORY_CELL_BORDER else Toolkit.Theme.COL_INACTIVE)
|
||||
val tcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INACTIVE else Toolkit.Theme.COL_LIST_DEFAULT)
|
||||
|
||||
// draw border
|
||||
batch.color = bcol
|
||||
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2)
|
||||
// draw texts
|
||||
batch.color = tcol
|
||||
batch.draw(icons.get(0, 1), posX + 4f, posY + 1f)
|
||||
App.fontGame.draw(batch, worldName ?: "$EMDASH", posX + 32, posY - 1)
|
||||
batch.draw(icons.get(1, 1), posX + 4f, posY + 25f)
|
||||
App.fontGame.draw(batch, if (worldInfo?.seed == null) "$EMDASH" else "${(if (worldInfo.seed > 0) "+" else "")}${worldInfo.seed}" , posX + 32, posY + 23)
|
||||
// text separator
|
||||
batch.color = bcol.cpy().sub(0f,0f,0f,0.65f)
|
||||
Toolkit.fillArea(batch, posX + 2, posY + 23, width - 4, 1)
|
||||
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
@@ -363,6 +363,8 @@ removefile:
|
||||
return fa.read()
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun getDiskName(charset: Charset): String {
|
||||
val bytes = ByteArray(268)
|
||||
fa.seek(10L)
|
||||
|
||||
@@ -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)
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,8 +21,9 @@ object Toolkit : Disposable {
|
||||
object Theme {
|
||||
val COL_INVENTORY_CELL_BORDER = Color(1f, 1f, 1f, 0.25f)
|
||||
val COL_CELL_FILL = Color(0x282828C8)
|
||||
val COL_CELL_FILL_OPAQUE = Color(0x282828FF)
|
||||
|
||||
val COL_LIST_DEFAULT = Color.WHITE
|
||||
val COL_LIST_DEFAULT = Color.WHITE // white
|
||||
val COL_INACTIVE = Color.LIGHT_GRAY
|
||||
val COL_SELECTED = Color(0x00f8ff_ff) // cyan, HIGHLY SATURATED
|
||||
val COL_MOUSE_UP = Color(0xfff066_ff.toInt()) // yellow (all yellows are of low saturation according to the colour science)
|
||||
@@ -50,7 +51,7 @@ object Toolkit : Disposable {
|
||||
private lateinit var blurWriteQuad2: Mesh
|
||||
private lateinit var blurWriteQuad4: Mesh
|
||||
|
||||
val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
|
||||
// val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
|
||||
|
||||
val textureWhiteSquare = Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga"))
|
||||
val textureWhiteCircle = Texture(Gdx.files.internal("assets/graphics/circle_512.tga"))
|
||||
@@ -70,7 +71,7 @@ object Toolkit : Disposable {
|
||||
private val rng = HQRNG()
|
||||
|
||||
override fun dispose() {
|
||||
baloonTile.dispose()
|
||||
// baloonTile.dispose()
|
||||
textureWhiteSquare.dispose()
|
||||
textureWhiteCircle.dispose()
|
||||
|
||||
@@ -251,7 +252,7 @@ object Toolkit : Disposable {
|
||||
|
||||
fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) {
|
||||
// centre area
|
||||
batch.draw(baloonTile.get(1, 1), x, y, w, h)
|
||||
/*batch.draw(baloonTile.get(1, 1), x, y, w, h)
|
||||
|
||||
// edges
|
||||
batch.draw(baloonTile.get(1, 0), x, y - baloonTile.tileH, w, baloonTile.tileH.toFloat())
|
||||
@@ -263,7 +264,13 @@ object Toolkit : Disposable {
|
||||
batch.draw(baloonTile.get(0, 0), x - baloonTile.tileW, y - baloonTile.tileH)
|
||||
batch.draw(baloonTile.get(2, 0), x + w, y - baloonTile.tileH)
|
||||
batch.draw(baloonTile.get(2, 2), x + w, y + h)
|
||||
batch.draw(baloonTile.get(0, 2), x - baloonTile.tileW, y + h)
|
||||
batch.draw(baloonTile.get(0, 2), x - baloonTile.tileW, y + h)*/
|
||||
|
||||
|
||||
batch.color = Theme.COL_CELL_FILL_OPAQUE
|
||||
fillArea(batch, x - 4, y - 4, w + 8, h + 8)
|
||||
batch.color = Theme.COL_INACTIVE
|
||||
drawBoxBorder(batch, x - 4, y - 4, w + 8, h + 8)
|
||||
}
|
||||
|
||||
private var init = false
|
||||
|
||||
@@ -154,6 +154,7 @@ abstract class UICanvas(
|
||||
*/
|
||||
open fun doOpening(delta: Float) {
|
||||
handler.opacity = handler.openCloseCounter / openCloseTime
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,7 +72,7 @@ class UIItemInlineRadioButtons(
|
||||
val xpos = getCellX(i)
|
||||
val text = labelfuns[i]()
|
||||
val tw = App.fontGame.getWidth(text)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ class UIItemInlineRadioButtons(
|
||||
Toolkit.drawBoxBorder(batch, xpos - 1, posY - 1, cellWidth + 2, height + 2)
|
||||
val text = labelfuns[mouseOnSelection]()
|
||||
val tw = App.fontGame.getWidth(text)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
|
||||
}
|
||||
|
||||
// selection borders and text
|
||||
@@ -92,7 +92,7 @@ class UIItemInlineRadioButtons(
|
||||
Toolkit.drawBoxBorder(batch, xpos - 1, posY - 1, cellWidth + 2, height + 2)
|
||||
val text = labelfuns[selection]()
|
||||
val tw = App.fontGame.getWidth(text)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY + 2)
|
||||
App.fontGame.draw(batch, text, xpos + (cellWidth - tw) / 2, posY)
|
||||
|
||||
|
||||
super.render(batch, camera)
|
||||
|
||||
@@ -85,12 +85,12 @@ class UIItemModuleInfoCell(
|
||||
batch.draw(modIcon, initialX + 35f, initialY + 12f)
|
||||
batch.shader = null
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, "$ccZero${modName.toUpperCase()}$ccNum $modVer", initialX + 86f + 3f, initialY + 2f)
|
||||
App.fontGame.draw(batch, "$ccZero${modName.toUpperCase()}$ccNum $modVer", initialX + 86f + 3f, initialY.toFloat())
|
||||
if (modErrored)
|
||||
App.fontGame.draw(batch, "$emphRed${modErrors.first().cause?.message}", initialX + 86f + 3f, initialY + 26f)
|
||||
App.fontGame.draw(batch, "$emphRed${modErrors.first().cause?.message}", initialX + 86f + 3f, initialY + 24f)
|
||||
else
|
||||
App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 26f)
|
||||
App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 50f)
|
||||
App.fontGame.draw(batch, "$ccDesc$modDesc", initialX + 86f + 3f, initialY + 24f)
|
||||
App.fontGame.draw(batch, "$ccZero2$modAuthor$ccNum2 $modDate", initialX + 86f + 3f, initialY + 48f)
|
||||
|
||||
if (modErrored) {
|
||||
batch.draw(CommonResourcePool.getAsTextureRegion("basegame_errored_icon32"), initialX + width - 40f, initialY + 8f + 12f)
|
||||
|
||||
@@ -158,7 +158,7 @@ class UIItemSpinner(
|
||||
// draw text
|
||||
batch.color = UIItemTextLineInput.TEXTINPUT_COL_TEXT
|
||||
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
|
||||
App.fontGame.draw(batch, textCache, posX + buttonW + 3f + (fboWidth - textCacheLen).div(2), posY + 2f)
|
||||
App.fontGame.draw(batch, textCache, posX + buttonW + 3f + (fboWidth - textCacheLen).div(2), posY.toFloat())
|
||||
|
||||
super.render(batch, camera)
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ class UIItemTextLineInput(
|
||||
0
|
||||
// TODO support alignment-right
|
||||
|
||||
App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, 0f)
|
||||
App.fontGameFBO.draw(it, text, -1f*cursorDrawScroll + textDrawOffset, -2f)
|
||||
} }
|
||||
textCommitListener(getTextOrPlaceholder())
|
||||
}
|
||||
@@ -587,7 +587,8 @@ class UIItemTextLineInput(
|
||||
batch.draw(labels.get(8,2), btn2PosX + 2f, posY + 2f)
|
||||
|
||||
// state of the candidates are concurrently changing, so we buffer them
|
||||
val localCandidates = ArrayList<CodepointSequence>(); candidates.forEach { localCandidates.add(it) }
|
||||
val localCandidates = ArrayList<CodepointSequence>()
|
||||
candidates.forEach { localCandidates.add(it) }
|
||||
|
||||
// draw candidates view
|
||||
if (localCandidates.isNotEmpty() && ime != null) {
|
||||
@@ -618,7 +619,7 @@ class UIItemTextLineInput(
|
||||
val candidateNum = listOf(i+48,46,32)
|
||||
App.fontGame.draw(batch, CodepointSequence(candidateNum + localCandidates[i]),
|
||||
candidatePosX + (i / halfcount) * (longestCandidateW + 3) + 2,
|
||||
candidatePosY + (i % halfcount) * 20 // using hard-coded 20 instead of the actual font height of 24
|
||||
candidatePosY + (i % halfcount) * 20 - 2 // using hard-coded 20 instead of the actual font height of 24
|
||||
)
|
||||
}
|
||||
|
||||
@@ -639,7 +640,7 @@ class UIItemTextLineInput(
|
||||
Toolkit.drawBoxBorder(batch, candidatePosX - 1, candidatePosY - 1, candidateWinW + 2, candidateWinH + 2)
|
||||
|
||||
val previewTextWidth = textWidths[0]
|
||||
App.fontGame.draw(batch, localCandidates[0], candidatePosX + (candidateWinW - previewTextWidth) / 2, candidatePosY)
|
||||
App.fontGame.draw(batch, localCandidates[0], candidatePosX + (candidateWinW - previewTextWidth) / 2, candidatePosY - 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ class UIItemTextSelector(
|
||||
val t = labelCache[selection]
|
||||
val tw = App.fontGame.getWidth(t)
|
||||
// batch.draw(fbo.colorBufferTexture, posX + buttonW + 3f, posY + 2f, fbo.width.toFloat(), fbo.height.toFloat())
|
||||
App.fontGame.draw(batch, t, posX + buttonW + 3 + (fboWidth - tw) / 2, posY + 2)
|
||||
App.fontGame.draw(batch, t, posX + buttonW + 3 + (fboWidth - tw) / 2, posY)
|
||||
}
|
||||
// palette
|
||||
else {
|
||||
@@ -226,7 +226,7 @@ class UIItemTextSelector(
|
||||
val tw = App.fontGame.getWidth(t)
|
||||
App.fontGame.draw(batch, t,
|
||||
palX + (palW - tw) / 2,
|
||||
getPalItemPosY(index)
|
||||
getPalItemPosY(index) - 2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.utils
|
||||
import com.badlogic.gdx.utils.JsonReader
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import java.io.Reader
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-02-15.
|
||||
@@ -18,9 +19,7 @@ object JsonFetcher {
|
||||
|
||||
printdbg(this, "Reading JSON $jsonFilePath")
|
||||
|
||||
if (jsonString == null) {
|
||||
throw Error("[JsonFetcher] jsonString is null!")
|
||||
}
|
||||
if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
|
||||
|
||||
return JsonReader().parse(jsonString.toString())
|
||||
}
|
||||
@@ -32,13 +31,15 @@ object JsonFetcher {
|
||||
|
||||
printdbg(this, "Reading JSON ${jsonFile.path}")
|
||||
|
||||
if (jsonString == null) {
|
||||
throw Error("[JsonFetcher] jsonString is null!")
|
||||
}
|
||||
if (jsonString == null) throw Error("[JsonFetcher] jsonString is null!")
|
||||
|
||||
return JsonReader().parse(jsonString.toString())
|
||||
}
|
||||
|
||||
fun readFromJsonString(stringReader: Reader): JsonValue {
|
||||
return JsonReader().parse(stringReader.readText())
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
private fun readJsonFileAsString(path: String) {
|
||||
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
|
||||
|
||||
@@ -349,12 +349,12 @@ object LightmapRenderer {
|
||||
val shadeBoxCopy = it.shadeBoxList.subList(0, it.shadeBoxList.size) // make copy to prevent ConcurrentModificationException
|
||||
val scale = it.scale
|
||||
|
||||
// put lanterns to the area the luminantBox is occupying
|
||||
// put lanterns to the area the lightBox is occupying
|
||||
lightBoxCopy.forEach { (lightBox, colour) ->
|
||||
val lightBoxX = it.hitbox.startX + (lightBox.startX * scale)
|
||||
val lightBoxY = it.hitbox.startY + (lightBox.startY * scale)
|
||||
val lightBoxW = lightBox.width * scale
|
||||
val lightBoxH = lightBox.height * scale
|
||||
val lightBoxW = lightBox.width * scale - 1
|
||||
val lightBoxH = lightBox.height * scale - 1
|
||||
for (y in lightBoxY.div(TILE_SIZE).floorInt()
|
||||
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
|
||||
for (x in lightBoxX.div(TILE_SIZE).floorInt()
|
||||
@@ -368,12 +368,12 @@ object LightmapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// put shades to the area the luminantBox is occupying
|
||||
// put shades to the area the shadeBox is occupying
|
||||
shadeBoxCopy.forEach { (shadeBox, colour) ->
|
||||
val lightBoxX = it.hitbox.startX + (shadeBox.startX * scale)
|
||||
val lightBoxY = it.hitbox.startY + (shadeBox.startY * scale)
|
||||
val lightBoxW = shadeBox.width * scale
|
||||
val lightBoxH = shadeBox.height * scale
|
||||
val lightBoxW = shadeBox.width * scale - 1
|
||||
val lightBoxH = shadeBox.height * scale - 1
|
||||
for (y in lightBoxY.div(TILE_SIZE).floorInt()
|
||||
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
|
||||
for (x in lightBoxX.div(TILE_SIZE).floorInt()
|
||||
|
||||
@@ -7,7 +7,7 @@ The main game directory is composed of following directories:
|
||||
```
|
||||
.Terrarum
|
||||
+ Players
|
||||
- "${PlayerName}-${UUID}", TVDA {
|
||||
- "${UUID}", TVDA {
|
||||
[-1] player JSON,
|
||||
[-2] spritedef,
|
||||
[-3] !optional! spritedef-glow,
|
||||
@@ -23,7 +23,7 @@ The main game directory is composed of following directories:
|
||||
- <e.g. Disk GUID>, TEVD { * }
|
||||
- <this directory can have anything>
|
||||
+ Worlds
|
||||
- "${WorldName}-${UUID}", TVDA {
|
||||
- "${UUID}", TVDA {
|
||||
[-1] world JSON with Player Data,
|
||||
[actorID] actors (mainly fixtures) JSON,
|
||||
[0x1_0000_0000L or (layerNumber shl 24) or chunkNumber] chunk data,
|
||||
|
||||
BIN
work_files/graphics/gui/hrule.kra
LFS
Normal file
BIN
work_files/graphics/gui/hrule.kra
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
work_files/graphics/items/dwarventech_items.kra
LFS
Normal file
BIN
work_files/graphics/items/dwarventech_items.kra
LFS
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user