mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +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()
|
||||
}
|
||||
@@ -654,21 +655,21 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
// what if there's multiple of such fixtures? whatever, you are supposed to DISALLOW such situation.
|
||||
for (kk in actorsUnderMouse.indices) {
|
||||
if (mouseInInteractableRange(actor) {
|
||||
actorsUnderMouse[kk].mainUI?.let {
|
||||
uiOpened = true
|
||||
actorsUnderMouse[kk].mainUI?.let {
|
||||
uiOpened = true
|
||||
|
||||
// property 'uiFixture' is a dedicated property that the TerrarumIngame recognises.
|
||||
// when it's not null, the UI will be updated and rendered
|
||||
// when the UI is closed, it'll be replaced with a null value
|
||||
uiFixture = it
|
||||
it.setPosition(
|
||||
(Toolkit.drawWidth - it.width) / 4,
|
||||
(App.scr.height - it.height) / 4 // what the fuck?
|
||||
)
|
||||
it.setAsOpen()
|
||||
}
|
||||
0L
|
||||
} == 0L) break
|
||||
// property 'uiFixture' is a dedicated property that the TerrarumIngame recognises.
|
||||
// when it's not null, the UI will be updated and rendered
|
||||
// when the UI is closed, it'll be replaced with a null value
|
||||
uiFixture = it
|
||||
it.setPosition(
|
||||
(Toolkit.drawWidth - it.width) / 4,
|
||||
(App.scr.height - it.height) / 4 // what the fuck?
|
||||
)
|
||||
it.setAsOpen()
|
||||
}
|
||||
0L
|
||||
} == 0L) break
|
||||
}
|
||||
|
||||
if (!uiOpened) {
|
||||
@@ -1263,9 +1264,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
val fixturesUnderHand = ArrayList<FixtureBase>()
|
||||
val mobsUnderHand = ArrayList<ActorWithBody>()
|
||||
actorsUnderMouse.forEach {
|
||||
if (it is FixtureBase && it.mainUI == null)
|
||||
if (it is FixtureBase) // && it.mainUI == null) // pickup avail check must be done against fixture.canBeDespawned
|
||||
fixturesUnderHand.add(it)
|
||||
else
|
||||
else if (it !is FixtureBase)
|
||||
mobsUnderHand.add(it)
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class Notification : UICanvas() {
|
||||
message.forEachIndexed { index, s ->
|
||||
val xoff = 6 + (displayedTextWidth - realTextWidth) / 2
|
||||
val y = -textHeight + App.fontGame.lineHeight * index
|
||||
App.fontGame.draw(batch, s, LRmargin + xoff, y)
|
||||
App.fontGame.draw(batch, s, LRmargin + xoff, y )
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -123,4 +150,83 @@ class UIWorldPortal : UICanvas() {
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class UIItemWorldPortalTopBar(
|
||||
parentUI: UIWorldPortal,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
val panelTransitionReqFun: (Int) -> Unit = {} // for side buttons; for the selection change, override selectionChangeListener
|
||||
) : UIItem(parentUI, initialX, initialY) {
|
||||
|
||||
override val width = 580
|
||||
override val height = 25
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
|
||||
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
}
|
||||
|
||||
private val genericIcons: TextureRegionPack = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
|
||||
private val catIconImages = listOf(
|
||||
icons.get(0, 0),
|
||||
genericIcons.get(16,0),
|
||||
icons.get(1, 0),
|
||||
genericIcons.get(17,0),
|
||||
icons.get(2, 0),
|
||||
)
|
||||
private val catIconLabels = listOf(
|
||||
"CONTEXT_WORLD_SEARCH",
|
||||
"",
|
||||
"CONTEXT_WORLD_LIST",
|
||||
"GAME_INVENTORY",
|
||||
"",
|
||||
)
|
||||
private val buttonGapSize = 120
|
||||
private val highlighterYPos = icons.tileH + 4
|
||||
|
||||
var selection = 2
|
||||
|
||||
private val buttons = Array<UIItemImageButton>(5) {
|
||||
val xoff = if (it == 1) -32 else if (it == 3) 32 else 0
|
||||
UIItemImageButton(
|
||||
parentUI,
|
||||
catIconImages[it],
|
||||
activeBackCol = Color(0),
|
||||
backgroundCol = Color(0),
|
||||
highlightBackCol = Color(0),
|
||||
activeBackBlendMode = BlendMode.NORMAL,
|
||||
initialX = (Toolkit.drawWidth - width) / 2 + it * (buttonGapSize + 20) + xoff,
|
||||
initialY = posY,
|
||||
inactiveCol = if (it % 2 == 0) Color.WHITE else Color(0xffffff7f.toInt()),
|
||||
activeCol = if (it % 2 == 0) Toolkit.Theme.COL_MOUSE_UP else Color(0xffffff7f.toInt()),
|
||||
highlightable = (it % 2 == 0)
|
||||
)
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
super.render(batch, camera)
|
||||
|
||||
// button
|
||||
buttons.forEach { it.render(batch, camera) }
|
||||
|
||||
// label
|
||||
batch.color = Color.WHITE
|
||||
val text = Lang[catIconLabels[selection]]
|
||||
App.fontGame.draw(batch, text, buttons[selection].posX + 10 - (App.fontGame.getWidth(text) / 2), posY + highlighterYPos + 4)
|
||||
|
||||
|
||||
blendNormalStraightAlpha(batch)
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,20 +2,32 @@ package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Camera
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap
|
||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.getCellCountVertically
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
|
||||
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.ascii85toUUID
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItem
|
||||
import net.torvald.terrarum.ui.UIItemTextButton
|
||||
import net.torvald.terrarum.utils.JsonFetcher
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.EMDASH
|
||||
import java.time.Instant
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-05-19.
|
||||
@@ -26,31 +38,24 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
|
||||
override var width: Int = Toolkit.drawWidth
|
||||
override var height: Int = App.scr.height
|
||||
|
||||
private val cellHeight = 48
|
||||
private val buttonHeight = 24
|
||||
private val gridGap = listGap
|
||||
|
||||
private var worldList: List<Pair<UUID, DiskSkimmer>>
|
||||
private var selectedWorld: DiskSkimmer? = null
|
||||
|
||||
|
||||
private val cellCol = UIInventoryFull.CELL_COL
|
||||
private var highlightCol: Color = Color.WHITE
|
||||
private val gridGap = 10
|
||||
|
||||
|
||||
|
||||
|
||||
private val thumbw = 360
|
||||
private val thumbh = 240
|
||||
private val thumbw = 378
|
||||
private val textAreaW = thumbw - 32
|
||||
private val thumbh = 252
|
||||
private val hx = Toolkit.drawWidth.div(2)
|
||||
private val y = INVENTORY_CELLS_OFFSET_Y()
|
||||
private val y = INVENTORY_CELLS_OFFSET_Y() + 1
|
||||
|
||||
private val listCount = UIInventoryFull.CELLS_VRT
|
||||
private val listHeight = cellHeight * listCount + gridGap * (listCount - 1)
|
||||
private val listCount = getCellCountVertically(UIItemWorldCellsSimple.height, gridGap)
|
||||
private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap)
|
||||
|
||||
private val deleteButtonWidth = 80
|
||||
private val buttonReset = UIItemTextButton(this,
|
||||
"MENU_LABEL_DELETE_WORLD",
|
||||
private val memoryGaugeWidth = textAreaW
|
||||
private val deleteButtonWidth = (thumbw - gridGap) / 2
|
||||
private val buttonDeleteWorld = UIItemTextButton(this,
|
||||
"MENU_LABEL_DELETE",
|
||||
hx - gridGap/2 - deleteButtonWidth,
|
||||
y + listHeight - buttonHeight,
|
||||
deleteButtonWidth,
|
||||
@@ -58,71 +63,338 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() {
|
||||
hasBorder = true,
|
||||
alignment = UIItemTextButton.Companion.Alignment.CENTRE
|
||||
)
|
||||
private val buttonRenameWorld = UIItemTextButton(this,
|
||||
"MENU_LABEL_RENAME",
|
||||
buttonDeleteWorld.posX - gridGap - deleteButtonWidth,
|
||||
y + listHeight - buttonHeight,
|
||||
deleteButtonWidth,
|
||||
readFromLang = true,
|
||||
hasBorder = true,
|
||||
alignment = UIItemTextButton.Companion.Alignment.CENTRE
|
||||
)
|
||||
|
||||
private val worldList = ArrayList<WorldInfo>()
|
||||
data class WorldInfo(
|
||||
val uuid: UUID,
|
||||
val diskSkimmer: DiskSkimmer,
|
||||
val dimensionInChunks: Int,
|
||||
val seed: Long,
|
||||
val lastPlayedString: String,
|
||||
val totalPlayedString: String,
|
||||
val screenshot: TextureRegion?,
|
||||
) {
|
||||
fun dispose() {
|
||||
screenshot?.texture?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("terrarum-basegame-worldportalicons") {
|
||||
TextureRegion(Texture(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga")), 20, 20).also {
|
||||
it.flip(false, false)
|
||||
}
|
||||
TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/worldportal_catbar.tga"), 30, 20)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
|
||||
addUIitem(buttonReset)
|
||||
addUIitem(buttonRenameWorld)
|
||||
addUIitem(buttonDeleteWorld)
|
||||
|
||||
}
|
||||
|
||||
worldList = (INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").map {
|
||||
private var chunksUsed = 0
|
||||
private val chunksMax = 100000
|
||||
|
||||
private lateinit var worldCells: Array<UIItemWorldCellsSimple>
|
||||
|
||||
private var selected: UIItemWorldCellsSimple? = null
|
||||
private var selectedIndex: Int? = null
|
||||
|
||||
override fun show() {
|
||||
worldList.clear()
|
||||
(INGAME.actorGamer.actorValue.getAsString(AVKey.WORLD_PORTAL_DICT) ?: "").split(",").filter { it.isNotBlank() }.map {
|
||||
it.ascii85toUUID().let { it to App.savegameWorlds[it] }
|
||||
}.filter { it.second != null } as List<Pair<UUID, DiskSkimmer>>
|
||||
}
|
||||
}.filter { it.second != null }.mapIndexed { index, (uuid, disk) ->
|
||||
|
||||
var chunksCount = 0
|
||||
var seed = 0L
|
||||
var lastPlayed = 0L
|
||||
var totalPlayed = 0L
|
||||
var w = 0
|
||||
var h = 0
|
||||
var thumb: TextureRegion? = null
|
||||
|
||||
JsonFetcher.readFromJsonString(ByteArray64Reader(disk!!.requestFile(-1)!!.contents.getContent() as ByteArray64, Common.CHARSET)).let {
|
||||
JsonFetcher.forEachSiblings(it) { name, value ->
|
||||
if (name == "width") w = value.asInt()
|
||||
if (name == "height") h = value.asInt()
|
||||
if (name == "generatorSeed") seed = value.asLong()
|
||||
if (name == "lastPlayTime") lastPlayed = value.asLong()
|
||||
if (name == "totalPlayTime") totalPlayed = value.asLong()
|
||||
}
|
||||
}
|
||||
chunksCount = (w / CHUNK_W) * (h / CHUNK_H)
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
disk.requestFile(-2)?.let {
|
||||
val zippedTga = (it.contents as EntryFile).bytes
|
||||
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
|
||||
val tgaFileContents = gzin.readAllBytes(); gzin.close()
|
||||
|
||||
}
|
||||
val thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
|
||||
val thumbTex = Texture(thumbPixmap)
|
||||
thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||
thumb = TextureRegion(thumbTex)
|
||||
}
|
||||
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
|
||||
batch.inUse {
|
||||
|
||||
// draw background //
|
||||
// screencap panel
|
||||
batch.color = cellCol
|
||||
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
|
||||
|
||||
|
||||
// draw border //
|
||||
// screencap panel
|
||||
batch.color = highlightCol
|
||||
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2)
|
||||
// memory gauge
|
||||
Toolkit.drawBoxBorder(batch, hx - 330 - gridGap/2 - 1, y + listHeight - 1, 240 + 2, buttonHeight + 2)
|
||||
|
||||
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
WorldInfo(uuid, disk, chunksCount, seed, lastPlayed.toTimestamp(), totalPlayed.toDurationStamp(), thumb)
|
||||
}.let {
|
||||
worldList.addAll(it)
|
||||
}
|
||||
|
||||
|
||||
|
||||
chunksUsed = worldList.sumOf { it.dimensionInChunks }
|
||||
|
||||
worldCells = Array(maxOf(worldList.size, listCount)) {
|
||||
UIItemWorldCellsSimple(
|
||||
this,
|
||||
hx + gridGap / 2,
|
||||
y + (gridGap + UIItemWorldCellsSimple.height) * it,
|
||||
worldList.getOrNull(it),
|
||||
worldList.getOrNull(it)?.diskSkimmer?.getDiskName(Common.CHARSET)
|
||||
).also { button ->
|
||||
button.clickOnceListener = { _, _, _ ->
|
||||
selected = button
|
||||
selectedIndex = it
|
||||
updateUIbyButtonSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiItems.forEach { it.show() }
|
||||
worldCells.forEach { it.show() }
|
||||
selected = null
|
||||
|
||||
updateUIbyButtonSelection()
|
||||
}
|
||||
|
||||
private fun Long.toTimestamp() = Instant.ofEpochSecond(this)
|
||||
.atZone(TimeZone.getDefault().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||
private fun Long.toDurationStamp(): String {
|
||||
val s = this % 60
|
||||
val m = (this / 60) % 60
|
||||
val h = (this / 3600) % 24
|
||||
val d = this / 86400
|
||||
return if (d == 0L)
|
||||
"${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
else
|
||||
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||
}
|
||||
private val nullTimestamp = "0000-00-00 --:--:--"
|
||||
private val nullDurationStamp = "--h--m--s"
|
||||
private fun Int.chunkCountToWorldSize() = when(this) {
|
||||
in 0 until 2000 -> "CONTEXT_DESCRIPTION_TINY"
|
||||
in 2000 until 4500 -> "CONTEXT_DESCRIPTION_SMALL"
|
||||
in 4500 until 10000 -> "CONTEXT_DESCRIPTION_BIG"
|
||||
else -> "CONTEXT_DESCRIPTION_HUGE"
|
||||
}
|
||||
|
||||
override fun updateUI(delta: Float) {
|
||||
uiItems.forEach { it.update(delta) }
|
||||
worldCells.forEach { it.update(delta) }
|
||||
}
|
||||
|
||||
private val iconGap = 12f
|
||||
private val iconSize = 30f
|
||||
private val textualListHeight = 30f
|
||||
private val iconSizeGap = iconSize + iconGap
|
||||
|
||||
private fun updateUIbyButtonSelection() {
|
||||
worldTexts = listOf(
|
||||
// last played
|
||||
icons.get(2, 1) to (selected?.worldInfo?.lastPlayedString ?: nullTimestamp),
|
||||
// total played
|
||||
icons.get(0, 2) to (selected?.worldInfo?.totalPlayedString ?: nullDurationStamp),
|
||||
// world size
|
||||
icons.get(1, 2) to (Lang.getOrNull(selected?.worldInfo?.dimensionInChunks?.chunkCountToWorldSize()) ?: "$EMDASH"),
|
||||
)
|
||||
|
||||
selectedWorldThumb = selected?.worldInfo?.screenshot
|
||||
|
||||
worldCells.forEach {
|
||||
it.highlighted = (selected == it && selected?.worldInfo != null)
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var worldTexts: List<Pair<TextureRegion, String>>
|
||||
private var selectedWorldThumb: TextureRegion? = null
|
||||
|
||||
val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
|
||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||
val memoryGaugeXpos = hx - memoryGaugeWidth - gridGap/2
|
||||
val memoryGaugeYpos = y + listHeight - buttonHeight - gridGap - buttonHeight
|
||||
val textXpos = memoryGaugeXpos + 3
|
||||
|
||||
// draw background //
|
||||
// screencap panel
|
||||
batch.color = UIInventoryFull.CELL_COL
|
||||
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y, thumbw, thumbh)
|
||||
|
||||
|
||||
// draw border //
|
||||
// screencap panel
|
||||
batch.color = if (selected?.worldInfo == null) Toolkit.Theme.COL_INVENTORY_CELL_BORDER else Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y - 1, thumbw + 2, thumbh + 2)
|
||||
|
||||
|
||||
// memory gauge
|
||||
val barCol = UIItemInventoryCellCommonRes.getHealthMeterColour(chunksMax - chunksUsed, 0, chunksMax)
|
||||
val barBack = barCol mul UIItemInventoryCellCommonRes.meterBackDarkening
|
||||
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt(), memoryGaugeYpos, buttonHeight + 6, buttonHeight)
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, (memoryGaugeXpos - iconSizeGap + 10).toInt() - 1, memoryGaugeYpos - 1, buttonHeight + 7, buttonHeight + 2)
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(icons.get(2, 2), textXpos - iconSizeGap, memoryGaugeYpos + 2f)
|
||||
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, memoryGaugeXpos - 1, memoryGaugeYpos - 1, memoryGaugeWidth + 2, buttonHeight + 2)
|
||||
batch.color = barBack
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, memoryGaugeWidth, buttonHeight)
|
||||
batch.color = barCol
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (chunksUsed / chunksMax.toFloat())).ceilInt(), buttonHeight)
|
||||
|
||||
batch.color = Color.WHITE
|
||||
if (selected?.worldInfo != null) {
|
||||
// background for texts panel
|
||||
batch.color = Toolkit.Theme.COL_CELL_FILL
|
||||
Toolkit.fillArea(batch, hx - thumbw - gridGap/2, y + thumbh + 3, thumbw, 10 + worldTexts.size * textualListHeight.toInt())
|
||||
batch.color = Toolkit.Theme.COL_INACTIVE
|
||||
Toolkit.drawBoxBorder(batch, hx - thumbw - gridGap/2 - 1, y + thumbh + 2, thumbw + 2, 10 + worldTexts.size * textualListHeight.toInt() + 2)
|
||||
|
||||
// some texts
|
||||
batch.color = Color.WHITE
|
||||
worldTexts.forEachIndexed { index, (icon, str) ->
|
||||
batch.draw(icon, textXpos - iconSizeGap + 6, y + thumbh + 3+10 + textualListHeight * index)
|
||||
App.fontGame.draw(batch, str, textXpos + 6f, y + thumbh + 3+10 + textualListHeight * index - 2f)
|
||||
}
|
||||
// size indicator on the memory gauge
|
||||
Toolkit.fillArea(batch, memoryGaugeXpos, memoryGaugeYpos, (memoryGaugeWidth * (selected?.worldInfo!!.dimensionInChunks / chunksMax.toFloat())).ceilInt(), buttonHeight)
|
||||
|
||||
// thumbnail
|
||||
selected?.worldInfo?.screenshot?.let {
|
||||
batch.draw(it, (hx - thumbw - gridGap/2).toFloat(), y.toFloat(), thumbw.toFloat(), thumbh.toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uiItems.forEach { it.render(batch, camera) }
|
||||
worldCells.forEach { it.render(batch, camera) }
|
||||
|
||||
// control hints
|
||||
batch.color = Color.WHITE
|
||||
App.fontGame.draw(batch, full.portalListingControlHelp, hx - thumbw - gridGap/2 + 2, (full.yEnd - 20).toInt())
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
uiItems.forEach { it.hide() }
|
||||
worldCells.forEach { it.hide() }
|
||||
|
||||
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
uiItems.forEach { it.dispose() }
|
||||
worldCells.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
worldList.forEach { try { it.dispose() } catch (_: GdxRuntimeException) {} }
|
||||
}
|
||||
|
||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (this.isVisible && mouseInScreen(screenX, screenY)) {
|
||||
uiItems.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
worldCells.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
handler.subUIs.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
|
||||
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (this.isVisible) {
|
||||
uiItems.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
worldCells.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
handler.subUIs.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||
return true
|
||||
}
|
||||
else return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UIItemWorldCellsSimple(
|
||||
parent: UILoadDemoSavefiles,
|
||||
parent: UIWorldPortalListing,
|
||||
initialX: Int,
|
||||
initialY: Int,
|
||||
val skimmer: DiskSkimmer
|
||||
internal val worldInfo: UIWorldPortalListing.WorldInfo? = null,
|
||||
internal val worldName: String? = null,
|
||||
) : UIItem(parent, initialX, initialY) {
|
||||
|
||||
override val width: Int = 360
|
||||
companion object {
|
||||
const val width = 378
|
||||
const val height = 46
|
||||
}
|
||||
|
||||
override val width: Int = 378
|
||||
override val height: Int = 46
|
||||
|
||||
private val cellCol = UIInventoryFull.CELL_COL
|
||||
private var highlightCol: Color = Color.WHITE
|
||||
private val icons = CommonResourcePool.getAsTextureRegionPack("terrarum-basegame-worldportalicons")
|
||||
|
||||
var highlighted = false
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
super.hide()
|
||||
}
|
||||
|
||||
override fun update(delta: Float) {
|
||||
super.update(delta)
|
||||
}
|
||||
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
super.render(batch, camera)
|
||||
|
||||
|
||||
// draw background
|
||||
batch.color = UIInventoryFull.CELL_COL
|
||||
Toolkit.fillArea(batch, posX, posY, width, height)
|
||||
|
||||
val mouseUp = mouseUp && worldInfo != null
|
||||
|
||||
val bcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INVENTORY_CELL_BORDER else Toolkit.Theme.COL_INACTIVE)
|
||||
val tcol = if (highlighted || mouseUp && mousePushed) Toolkit.Theme.COL_SELECTED
|
||||
else if (mouseUp) Toolkit.Theme.COL_MOUSE_UP else (if (worldInfo == null) Toolkit.Theme.COL_INACTIVE else Toolkit.Theme.COL_LIST_DEFAULT)
|
||||
|
||||
// draw border
|
||||
batch.color = bcol
|
||||
Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2)
|
||||
// draw texts
|
||||
batch.color = tcol
|
||||
batch.draw(icons.get(0, 1), posX + 4f, posY + 1f)
|
||||
App.fontGame.draw(batch, worldName ?: "$EMDASH", posX + 32, posY - 1)
|
||||
batch.draw(icons.get(1, 1), posX + 4f, posY + 25f)
|
||||
App.fontGame.draw(batch, if (worldInfo?.seed == null) "$EMDASH" else "${(if (worldInfo.seed > 0) "+" else "")}${worldInfo.seed}" , posX + 32, posY + 23)
|
||||
// text separator
|
||||
batch.color = bcol.cpy().sub(0f,0f,0f,0.65f)
|
||||
Toolkit.fillArea(batch, posX + 2, posY + 23, width - 4, 1)
|
||||
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
@@ -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.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user