KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt

339 lines
11 KiB
Kotlin

package ru.dbotthepony.kstarbound
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import com.sun.jna.Native
import org.apache.logging.log4j.LogManager
import org.lwjgl.Version
import org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose
import ru.dbotthepony.kstarbound.client.StarboundClient
import ru.dbotthepony.kstarbound.client.render.Animator
import ru.dbotthepony.kstarbound.defs.animation.AnimationDefinition
import ru.dbotthepony.kstarbound.defs.item.DynamicItemDefinition
import ru.dbotthepony.kstarbound.io.BTreeDB
import ru.dbotthepony.kstarbound.lua.LuaState
import ru.dbotthepony.kstarbound.world.ChunkPos
import ru.dbotthepony.kstarbound.world.entities.ItemEntity
import ru.dbotthepony.kstarbound.world.entities.PlayerEntity
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
import java.io.ByteArrayInputStream
import java.io.DataInputStream
import java.io.File
import java.util.Random
import java.util.zip.Inflater
private val LOGGER = LogManager.getLogger()
fun main() {
val starbound = Starbound()
LOGGER.info("Running LWJGL ${Version.getVersion()}")
//Thread.sleep(6_000L)
val db = BTreeDB(File("F:\\SteamLibrary\\steamapps\\common\\Starbound - Unstable\\storage\\universe\\389760395_938904237_-238610574_5.world"))
//val db = BTreeDB(File("world.world"))
val client = StarboundClient(starbound)
//Starbound.addFilePath(File("./unpacked_assets/"))
starbound.addPakPath(File("J:\\Steam\\steamapps\\common\\Starbound\\assets\\packed.pak"))
/*for (folder in File("J:\\Steam\\steamapps\\workshop\\content\\211820").list()!!) {
val f = File("J:\\Steam\\steamapps\\workshop\\content\\211820\\$folder\\contents.pak")
if (f.exists()) {
starbound.addPakPath(f)
}
}*/
//Starbound.addPakPath(File("packed.pak"))
starbound.initializeGame { finished, replaceStatus, status ->
client.putDebugLog(status, replaceStatus)
}
client.onTermination {
starbound.terminateLoading = true
}
val ent = PlayerEntity(client.world!!)
starbound.onInitialize {
var find = 0L
var set = 0L
var parse = 0L
//for (chunkX in 17 .. 18) {
for (chunkX in 14 .. 24) {
// for (chunkY in 21 .. 21) {
for (chunkY in 18 .. 24) {
var t = System.currentTimeMillis()
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
find += System.currentTimeMillis() - t
if (data != null) {
val chunk = client.world!!.computeIfAbsent(ChunkPos(chunkX, chunkY))
val inflater = Inflater()
inflater.setInput(data)
t = System.currentTimeMillis()
val output = ByteArray(64_000)
val actual = inflater.inflate(output)
val reader = DataInputStream(ByteArrayInputStream(output))
parse += System.currentTimeMillis() - t
reader.skipBytes(3)
var hitTile = false
t = System.currentTimeMillis()
for (y in 0 .. 31) {
for (x in 0 .. 31) {
val materialID = reader.readUnsignedShort()
val getMat = starbound.tilesByID[materialID]
if (getMat != null) {
chunk.foreground[x, y].material = getMat.value
hitTile = true
}
// reader.skipBytes(1) // Foreground hue shift
// reader.skipBytes(1) // Foreground color variant
val colorShift = reader.readUnsignedByte()
val colorVariant = reader.readUnsignedByte()
val modifier = reader.readUnsignedShort()
val getModifier = starbound.tileModifiersByID[modifier]
chunk.foreground[x, y].color = colorVariant
chunk.foreground[x, y].setHueShift(colorShift)
if (getModifier != null && getMat != null) {
chunk.foreground[x, y].modifier = getModifier.value
}
val modifierHueShift = reader.readUnsignedByte()
chunk.foreground[x, y].setModifierHueShift(modifierHueShift)
val materialID2 = reader.readUnsignedShort()
val getMat2 = starbound.tilesByID[materialID2]
if (getMat2 != null) {
chunk.background[x, y].material = getMat2.value
hitTile = true
}
// reader.skipBytes(1) // Background hue shift
// reader.skipBytes(1) // Background color variant
val colorShift2 = reader.readUnsignedByte()
val colorVariant2 = reader.readUnsignedByte()
val modifier2 = reader.readUnsignedShort()
val getModifier2 = starbound.tileModifiersByID[modifier2]
if (getModifier2 != null && getMat2 != null) {
chunk.background[x, y].modifier = getModifier2.value
}
chunk.background[x, y].color = colorVariant2
chunk.background[x, y].setHueShift(colorShift2)
val modifierHueShift2 = reader.readUnsignedByte()
chunk.background[x, y].setModifierHueShift(modifierHueShift2)
val liquid = reader.readUnsignedByte()
val liquidLevel = reader.readFloat()
val liquidPressure = reader.readFloat()
val liquidIsInfinite = reader.readBoolean()
val collisionMap = reader.readUnsignedByte()
val dungeonId = reader.readUnsignedShort()
val biome = reader.readUnsignedByte()
val envBiome = reader.readUnsignedByte()
val indestructible = reader.readBoolean()
val unknown = reader.readUnsignedByte()
val getLiquid = starbound.liquidByID[liquid]
if (getLiquid != null) {
val state = chunk.setLiquid(x, y, getLiquid.value)!!
state.isInfinite = liquidIsInfinite
state.pressure = liquidPressure
state.level = liquidLevel
}
}
}
set += System.currentTimeMillis() - t
if (hitTile) {
//println(chunk.chunk.posVector2d)
// ent.position = chunk.chunk.posVector2d + Vector2d(16.0, 34.0)
}
}
}
}
println("$find $set $parse")
//client.world!!.parallax = Starbound.parallaxAccess["garden"]
val item = starbound.items.values.random()
val rand = java.util.Random()
for (i in 0 .. 10) {
val item = ItemEntity(client.world!!, item.value)
item.position = Vector2d(600.0 + 16.0 + i, 721.0 + 48.0)
item.spawn()
item.movement.applyVelocity(Vector2d(rand.nextDouble() * 1000.0 - 500.0, rand.nextDouble() * 1000.0 - 500.0))
}
// println(Starbound.statusEffects["firecharge"])
starbound.pathStack.push("/animations/dust4")
val def = starbound.gson.fromJson(starbound.locate("/animations/dust4/dust4.animation").reader(), AnimationDefinition::class.java)
starbound.pathStack.pop()
val animator = Animator(client.world!!, def)
client.onPostDrawWorld {
animator.render(client.gl.matrixStack)
}
}
//ent.position += Vector2d(y = 14.0, x = -10.0)
ent.position = Vector2d(600.0 + 16.0, 721.0 + 48.0)
client.camera.pos.x = 578f
client.camera.pos.y = 695f
client.onDrawGUI {
client.gl.font.render("${ent.position}", y = 100f, scale = 0.25f)
client.gl.font.render("${ent.movement.velocity}", y = 120f, scale = 0.25f)
client.gl.font.render("${client.camera.pos} ${client.settings.zoom}", y = 140f, scale = 0.25f)
client.gl.font.render("${ChunkPos.fromTilePosition(client.camera.pos.toDoubleVector())}", y = 160f, scale = 0.25f)
}
client.onPreDrawWorld {
//client.camera.pos.x = ent.pos.x.toFloat()
//client.camera.pos.y = ent.pos.y.toFloat()
}
/*val lightRenderer = LightRenderer(client.gl)
lightRenderer.resizeFramebuffer(client.viewportWidth, client.viewportHeight)
client.onViewportChanged(lightRenderer::resizeFramebuffer)
lightRenderer.addShadowGeometry(object : LightRenderer.ShadowGeometryRenderer {
override fun renderHardGeometry(lightPosition: Vector2f, stack: Matrix4fStack, program: GLHardLightGeometryProgram) {
val builder = lightRenderer.builder
builder.begin()
builder.quad(-6f, 0f, -2f, 2f)
builder.quad(0f, 0f, 2f, 2f)
builder.upload()
builder.draw(GL_LINES)
}
override fun renderSoftGeometry(lightPosition: Vector2f, stack: Matrix4fStack, program: GLSoftLightGeometryProgram) {
val builder = lightRenderer.builderSoft
builder.begin()
builder.shadowQuad(-6f, 0f, -2f, 2f)
builder.shadowQuad(0f, 0f, 2f, 2f)
builder.upload()
builder.draw(GL_TRIANGLES)
}
})
client.onPostDrawWorld {
lightRenderer.begin()
for ((lightPosition, color) in listOf(
(client.screenToWorld(client.mouseCoordinatesF)) to Color.RED,
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(0.1f)) to Color.GREEN,
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(-0.1f)) to Color.BLUE,
)) {
lightRenderer.renderSoftLight(lightPosition, color, radius = 40f)
}
for ((lightPosition, color) in listOf(
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(10.1f)) to Color.RED,
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(10.1f)) to Color.GREEN,
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(9.9f)) to Color.BLUE,
)) {
//lightRenderer.renderSoftLight(lightPosition, color, radius = 10f)
}
lightRenderer.renderOutputAdditive()
}*/
client.gl.box2dRenderer.drawShapes = false
client.gl.box2dRenderer.drawPairs = false
client.gl.box2dRenderer.drawAABB = false
client.gl.box2dRenderer.drawJoints = false
//ent.spawn()
client.input.addScrollCallback { _, x, y ->
if (y > 0.0) {
client.settings.zoom *= y.toFloat() * 2f
} else if (y < 0.0) {
client.settings.zoom /= -y.toFloat() * 2f
}
}
while (client.renderFrame()) {
starbound.pollCallbacks()
//ent.think(client.frameRenderTime)
//client.camera.pos.x = ent.position.x.toFloat()
//client.camera.pos.y = ent.position.y.toFloat()
client.camera.pos.x += if (client.input.KEY_LEFT_DOWN || client.input.KEY_A_DOWN) -client.frameRenderTime.toFloat() * 32f / client.settings.zoom else 0f
client.camera.pos.x += if (client.input.KEY_RIGHT_DOWN || client.input.KEY_D_DOWN) client.frameRenderTime.toFloat() * 32f / client.settings.zoom else 0f
client.camera.pos.y += if (client.input.KEY_UP_DOWN || client.input.KEY_W_DOWN) client.frameRenderTime.toFloat() * 32f / client.settings.zoom else 0f
client.camera.pos.y += if (client.input.KEY_DOWN_DOWN || client.input.KEY_S_DOWN) -client.frameRenderTime.toFloat() * 32f / client.settings.zoom else 0f
//println(client.camera.velocity.toDoubleVector() * client.frameRenderTime * 0.1)
//if (ent.onGround)
//ent.velocity += client.camera.velocity.toDoubleVector() * client.frameRenderTime * 0.1
/*if (client.input.KEY_LEFT_DOWN) {
ent.movement.moveDirection = Move.MOVE_LEFT
} else if (client.input.KEY_RIGHT_DOWN) {
ent.movement.moveDirection = Move.MOVE_RIGHT
} else {
ent.movement.moveDirection = Move.STAND_STILL
}
if (client.input.KEY_SPACE_PRESSED && ent.movement.onGround) {
ent.movement.requestJump()
} else if (client.input.KEY_SPACE_RELEASED) {
ent.movement.recallJump()
}*/
if (client.input.KEY_ESCAPE_PRESSED) {
glfwSetWindowShouldClose(client.window, true)
}
//ent.wantsToDuck = client.input.KEY_DOWN_DOWN
//if (chunkA != null && glfwGetTime() < 10.0) {
// val tile = Starbound.getTileDefinition("alienrock")
//chunkA!!.foreground[rand.nextInt(0, CHUNK_SIZE_FF), rand.nextInt(0, CHUNK_SIZE_FF)] = tile
//}
}
}