diff --git a/assets/mods/basegame/locales/en/game.json b/assets/mods/basegame/locales/en/game.json index 67cc21ca0..35c8c3dfc 100644 --- a/assets/mods/basegame/locales/en/game.json +++ b/assets/mods/basegame/locales/en/game.json @@ -9,6 +9,8 @@ "MENU_LABEL_MENU": "Menu", "MENU_LABEL_PREV_SAVES": "Previous Saves", "MENU_LABEL_RENAME": "Rename", + "MENU_LABEL_USE_CODE": "Use Code", + "MENU_MONITOR_CALI_TITLE": "Check Monitor", "GAME_ACTION_CRAFT": "Craft", "GAME_ACTION_GRAPPLE": "Grapple", "GAME_ACTION_QUICKSEL": "Quick Select", diff --git a/assets/mods/basegame/locales/en/sentences.json b/assets/mods/basegame/locales/en/sentences.json index c1549ffaf..289891052 100644 --- a/assets/mods/basegame/locales/en/sentences.json +++ b/assets/mods/basegame/locales/en/sentences.json @@ -3,9 +3,9 @@ "CONTEXT_IMPORT_AVATAR_INSTRUCTION_1": "1. Place the Avatar file into the following directory:", "CONTEXT_IMPORT_AVATAR_INSTRUCTION_2": "", "CONTEXT_IMPORT_AVATAR_INSTRUCTION_3": "2. Enter the name of the file below, then press Import", - "ERROR_AVATAR_ALREADY_EXISTS": "The Avatar already exists.", "CONTEXT_WORLD_CODE_SHARE_1": "Other people sharing the device can play on this", "CONTEXT_WORLD_CODE_SHARE_2": "world when you are away.", "CONTEXT_WORLD_CODE_SHARE_3": "", - "CONTEXT_WORLD_CODE_SHARE_4": "Share the code below so the other people can join!" + "CONTEXT_WORLD_CODE_SHARE_4": "Share the code below so the other people can join!", + "ERROR_AVATAR_ALREADY_EXISTS": "The Avatar already exists." } \ No newline at end of file diff --git a/assets/mods/basegame/locales/koKR/game.json b/assets/mods/basegame/locales/koKR/game.json index 5b404947b..f2fb52047 100644 --- a/assets/mods/basegame/locales/koKR/game.json +++ b/assets/mods/basegame/locales/koKR/game.json @@ -9,6 +9,7 @@ "MENU_LABEL_MENU": "메뉴", "MENU_LABEL_PREV_SAVES": "이전 세이브", "MENU_LABEL_RENAME": "이름 바꾸기", + "MENU_LABEL_USE_CODE": "코드 사용", "MENU_MONITOR_CALI_TITLE": "모니터 확인", "GAME_ACTION_CRAFT": "제작하기", "GAME_ACTION_GRAPPLE": "매달리기", diff --git a/assets/mods/basegame/locales/koKR/sentences.json b/assets/mods/basegame/locales/koKR/sentences.json index dc35da24e..c83b44d09 100644 --- a/assets/mods/basegame/locales/koKR/sentences.json +++ b/assets/mods/basegame/locales/koKR/sentences.json @@ -2,5 +2,9 @@ "CONTEXT_THIS_IS_A_WORLD_CURRENTLY_PLAYING": "현재 플레이 중인 월드입니다.", "CONTEXT_IMPORT_AVATAR_INSTRUCTION_1": "1. 아바타 파일을 다음 폴더에 넣어주세요", "CONTEXT_IMPORT_AVATAR_INSTRUCTION_3": "2. 아바타 파일 이름을 아래에 입력하고 가져오기를 눌러주세요", + "CONTEXT_WORLD_CODE_SHARE_1": "자리를 비운 동안 같은 기기를 공유하는 다른 사람이 이 월드를", + "CONTEXT_WORLD_CODE_SHARE_2": "플레이할 수 있도록 합니다.", + "CONTEXT_WORLD_CODE_SHARE_3": "", + "CONTEXT_WORLD_CODE_SHARE_4": "아래의 코드를 공유해 다른 사람을 초대하세요!", "ERROR_AVATAR_ALREADY_EXISTS": "이미 존재하는 아바타입니다." } \ No newline at end of file diff --git a/assets/mods/basegame/weathers/WeatherGeneric.json b/assets/mods/basegame/weathers/WeatherGeneric.json index 0cab4ed28..423ccff06 100644 --- a/assets/mods/basegame/weathers/WeatherGeneric.json +++ b/assets/mods/basegame/weathers/WeatherGeneric.json @@ -6,8 +6,9 @@ "cloudChance": 125, "cloudGamma": [0.45, 2.4], "cloudGammaVariance": [0.1, 0.0], - "windSpeed": 0.25, - "windSpeedVariance": 1.0, + "windSpeed": 0.35, + "windSpeedVariance": 0.4, + "windSpeedDamping": 0.5, "clouds": { "cumulonimbus": { "filename": "cloud_large.png", "tw": 2048, "th": 1024, "probability": 0.2, diff --git a/assets/mods/basegame/weathers/WeatherGeneric2.json b/assets/mods/basegame/weathers/WeatherGeneric2.json index ee5086973..e38ea69b6 100644 --- a/assets/mods/basegame/weathers/WeatherGeneric2.json +++ b/assets/mods/basegame/weathers/WeatherGeneric2.json @@ -6,8 +6,9 @@ "cloudChance": 800, "cloudGamma": [0.6, 2.4], "cloudGammaVariance": [0.1, 0.0], - "windSpeed": 0.25, - "windSpeedVariance": 1.0, + "windSpeed": 0.35, + "windSpeedVariance": 0.4, + "windSpeedDamping": 0.5, "clouds": { "cumulonimbus": { "filename": "cloud_large.png", "tw": 2048, "th": 1024, "probability": 0.02, diff --git a/assets/mods/basegame/weathers/WeatherOvercast.json b/assets/mods/basegame/weathers/WeatherOvercast.json index 4bf0cfd93..205ca6db2 100644 --- a/assets/mods/basegame/weathers/WeatherOvercast.json +++ b/assets/mods/basegame/weathers/WeatherOvercast.json @@ -8,6 +8,7 @@ "cloudGammaVariance": [0.0, 0.0], "windSpeed": 10.45, "windSpeedVariance": 0.5, + "windSpeedDamping": 0.0, "clouds": { "cumulus": { "filename": "cloud_normal.png", "tw": 1024, "th": 512, "probability": 0.1, diff --git a/src/com/badlogic/gdx/graphics/glutils/Float16FrameBuffer.java b/src/com/badlogic/gdx/graphics/glutils/Float16FrameBuffer.java index dd59a53ce..4e4560c30 100644 --- a/src/com/badlogic/gdx/graphics/glutils/Float16FrameBuffer.java +++ b/src/com/badlogic/gdx/graphics/glutils/Float16FrameBuffer.java @@ -41,7 +41,7 @@ public class Float16FrameBuffer extends FrameBuffer { } else { FloatFrameBufferBuilder bufferBuilder = new FloatFrameBufferBuilder(width, height); - bufferBuilder.addFloatAttachment(GL30.GL_RGBA16F, GL30.GL_RGBA, GL30.GL_FLOAT, false); // FIXME sporadic black screen on GL_RGBA16F? or maybe it was Plasma bugging out? + bufferBuilder.addFloatAttachment(GL30.GL_RGBA16F, GL30.GL_RGBA, GL30.GL_FLOAT, false); if (hasDepth) bufferBuilder.addBasicDepthRenderBuffer(); this.bufferBuilder = bufferBuilder; } diff --git a/src/net/torvald/terrarum/RNGConsumer.kt b/src/net/torvald/terrarum/RNGConsumer.kt index b5238d591..31c091c9d 100644 --- a/src/net/torvald/terrarum/RNGConsumer.kt +++ b/src/net/torvald/terrarum/RNGConsumer.kt @@ -7,7 +7,7 @@ internal interface RNGConsumer { val RNG: HQRNG - fun loadFromSave(s0: Long, s1: Long) { + fun loadFromSave(ingame: IngameInstance, s0: Long, s1: Long) { RNG.setSeed(s0, s1) } diff --git a/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt b/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt index 33d8b0533..c2d91e2b6 100644 --- a/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt +++ b/src/net/torvald/terrarum/blockproperties/BlockPropUtil.kt @@ -108,7 +108,7 @@ object BlockPropUtil { return when (prop.dynamicLuminosityFunction) { 1 -> getTorchFlicker(prop) 2 -> (INGAME.world).globalLight.cpy() // current global light - 3 -> WeatherMixer.getGlobalLightOfTimeOfNoon().cpy() // daylight at noon + 3 -> WeatherMixer.getGlobalLightOfTimeOfNoon(WeatherMixer.weatherDict["generic01"]!!).cpy() // daylight at noon 4 -> getSlowBreath(prop) 5 -> getPulsate(prop) else -> prop.baseLumCol diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index ba9bed9fc..2ddc66a19 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -14,6 +14,9 @@ import net.torvald.terrarum.itemproperties.ItemTable import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.utils.* +import net.torvald.terrarum.weather.WeatherMixer +import net.torvald.terrarum.weather.WeatherSchedule +import net.torvald.terrarum.weather.Weatherbox import net.torvald.util.SortedArrayList import org.dyn4j.geometry.Vector2 import java.util.* @@ -139,6 +142,33 @@ open class GameWorld( @Deprecated("This value is only used for savegames; DO NOT USE THIS", ReplaceWith("INGAME.actorContainerActive", "net.torvald.terrarum.INGAME")) internal val actors = ArrayList() // only filled up on save and load; DO NOT USE THIS + var weatherbox = Weatherbox() + + init { + weatherbox.initWith(WeatherMixer.weatherDict["generic01"]!!, 7200L) + val currentWeather = weatherbox.currentWeather + // TEST FILL WITH RANDOM VALUES + (0..6).map { WeatherMixer.takeUniformRand(0f..1f) }.let { + weatherbox.windDir.pM2 = it[1] + weatherbox.windDir.pM1 = it[2] + weatherbox.windDir.p0 = it[3] + weatherbox.windDir.p1 = it[4] + weatherbox.windDir.p2 = it[5] + weatherbox.windDir.p3 = it[6] + } + (0..6).map { WeatherMixer.takeUniformRand(-1f..1f) }.let { + weatherbox.windSpeed.pM2 = currentWeather.getRandomWindSpeed(it[0], it[1]) + weatherbox.windSpeed.pM1 = currentWeather.getRandomWindSpeed(it[1], it[2]) + weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[2], it[3]) + weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[3], it[4]) + weatherbox.windSpeed.p2 = currentWeather.getRandomWindSpeed(it[4], it[5]) + weatherbox.windSpeed.p3 = currentWeather.getRandomWindSpeed(it[5], it[6]) + } + + // the savegame loader will overwrite whatever the initial value we have here + } + + /** * Create new world */ diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index b0f5115ea..4543c00a7 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -302,7 +302,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { IngameRenderer.setRenderedWorld(gameWorld) - WeatherMixer.internalReset() + WeatherMixer.internalReset(this) } override fun show() { diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 5c7671c0d..07c7a64d5 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -332,8 +332,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { else { printdbg(this, "Ingame setting things up from the savegame") - RoguelikeRandomiser.loadFromSave(codices.world.randSeeds[0], codices.world.randSeeds[1]) - WeatherMixer.loadFromSave(codices.world.randSeeds[2], codices.world.randSeeds[3]) + RoguelikeRandomiser.loadFromSave(this, codices.world.randSeeds[0], codices.world.randSeeds[1]) + WeatherMixer.loadFromSave(this, codices.world.randSeeds[2], codices.world.randSeeds[3]) // Terrarum.itemCodex.loadFromSave(codices.item) // Terrarum.apocryphas = HashMap(codices.apocryphas) @@ -503,7 +503,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { actorGamer = player forceAddActor(player) - WeatherMixer.internalReset() + WeatherMixer.internalReset(this) UILoadGovernor.worldUUID = world.worldIndex } diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index cd603c297..b5e60dc67 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -212,8 +212,8 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) { IngameRenderer.setRenderedWorld(demoWorld) - WeatherMixer.internalReset() - WeatherMixer.titleScreenInitWeather() + WeatherMixer.internalReset(this) + WeatherMixer.titleScreenInitWeather(this.world.weatherbox) // load a half-gradient texture that would be used throughout the titlescreen and its sub UIs diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt index 6bc1de0b7..d90f0318f 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt @@ -30,11 +30,12 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { override var height: Int = App.scr.height private val gameMenu = arrayOf( - "MENU_IO_SAVE_GAME", - "MENU_OPTIONS_CONTROLS", - "MENU_LABEL_IME", - "MENU_LABEL_LANGUAGE", - "MENU_LABEL_QUIT", + "MENU_IO_SAVE_GAME", + "MENU_OPTIONS_CONTROLS", + "MENU_LABEL_IME", + "MENU_LABEL_LANGUAGE", + "MENU_LABEL_SHARE", + "MENU_LABEL_QUIT", ) private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size private val gameMenuListWidth = 400 @@ -83,6 +84,7 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { private val keyConfigUI = UIKeyboardControlPanel(null) private val languageUI = UITitleLanguage(null) private val keyboardSetupUI = UIIMEConfig(null) + private val shareUI = UIShare() private var oldScreen = 0 private var screen = 0 @@ -155,6 +157,9 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { screen = 5; gameMenuButtons.deselect() } 4 -> { + screen = 6; gameMenuButtons.deselect() + } + 5 -> { screen = 2; gameMenuButtons.deselect() } } @@ -172,82 +177,92 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { } } + private val controlHintX = ((width - 480) / 2).toFloat() + // Completely unrelated to the gameMenuButtons order private val screens = arrayOf( - gameMenuButtons, keyboardSetupUI, areYouSureMainMenuButtons, savingUI, keyConfigUI, languageUI + gameMenuButtons, keyboardSetupUI, areYouSureMainMenuButtons, savingUI, keyConfigUI, languageUI, shareUI ) // `screens` order private val screenRenders = arrayOf( - { batch: SpriteBatch, camera: OrthographicCamera -> - // control hints - App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) - // text buttons - gameMenuButtons.render(batch, camera) - }, - { batch: SpriteBatch, camera: OrthographicCamera -> - // control hints - App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) - keyboardSetupUI.render(batch, camera) - }, - { batch: SpriteBatch, camera: OrthographicCamera -> - // control hints - App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) - areYouSureMainMenuButtons.render(batch, camera) - }, - { batch: SpriteBatch, camera: OrthographicCamera -> - savingUI.render(batch, camera) - }, - { batch: SpriteBatch, camera: OrthographicCamera -> - // control hints - App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) - keyConfigUI.render(batch, camera) - }, - { batch: SpriteBatch, camera: OrthographicCamera -> - // control hints - App.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20) - languageUI.render(batch, camera) - }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + // text buttons + gameMenuButtons.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + keyboardSetupUI.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + areYouSureMainMenuButtons.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + savingUI.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + keyConfigUI.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + languageUI.render(batch, camera) + }, + { batch: SpriteBatch, camera: OrthographicCamera -> + // control hints + App.fontGame.draw(batch, full.gameMenuControlHelp, controlHintX, full.yEnd - 20) + shareUI.render(batch, camera) + }, ) // `screens` order private val screenTouchDowns = arrayOf( - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> - keyboardSetupUI.touchDown(screenX, screenY, pointer, button) - }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> - keyConfigUI.touchDown(screenX, screenY, pointer, button) - }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - ) + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> + keyboardSetupUI.touchDown(screenX, screenY, pointer, button) + }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> + keyConfigUI.touchDown(screenX, screenY, pointer, button) + }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + ) // `screens` order private val screenTouchUps = arrayOf( - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> - keyboardSetupUI.touchUp(screenX, screenY, pointer, button) - }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> - keyConfigUI.touchUp(screenX, screenY, pointer, button) - }, - { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, - ) + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> + keyboardSetupUI.touchUp(screenX, screenY, pointer, button) + }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> + keyConfigUI.touchUp(screenX, screenY, pointer, button) + }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + { screenX: Int, screenY: Int, pointer: Int, button: Int -> }, + ) // `screens` order private val screenScrolls = arrayOf( - { amountX: Float, amountY: Float -> }, - { amountX: Float, amountY: Float -> - keyboardSetupUI.scrolled(amountX, amountY) - }, - { amountX: Float, amountY: Float -> }, - { amountX: Float, amountY: Float -> }, - { amountX: Float, amountY: Float -> }, - { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> + keyboardSetupUI.scrolled(amountX, amountY) + }, + { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> }, + { amountX: Float, amountY: Float -> }, ) override fun show() { diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIShare.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIShare.kt new file mode 100644 index 000000000..39ea76f8f --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIShare.kt @@ -0,0 +1,79 @@ +package net.torvald.terrarum.modulebasegame.ui + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.App +import net.torvald.terrarum.INGAME +import net.torvald.terrarum.imagefont.BigAlphNum +import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.serialise.toBig64 +import net.torvald.terrarum.ui.Toolkit +import net.torvald.terrarum.ui.UICanvas +import net.torvald.terrarum.utils.PasswordBase32 + +class UIShare : UICanvas() { + + override var width = 434 + override var height = 480 + + private val drawX = (Toolkit.drawWidth - width) / 2 + private val drawY = (App.scr.height - height) / 2 + + override fun updateUI(delta: Float) { + uiItems.forEach { it.update(delta) } + } + + private var shareCode = "" + private var dash = ' ' + + override fun show() { + shareCode = PasswordBase32.encode( + INGAME.world.worldIndex.mostSignificantBits.toBig64() + + INGAME.world.worldIndex.mostSignificantBits.toBig64() + ).let { it.substring(0, it.indexOf('=')) }.let { + "${it.substring(0..3)}$dash${it.substring(4..5)}$dash${it.substring(6..10)}$dash${it.substring(11..15)}$dash${it.substring(16..20)}$dash${it.substring(21)}" + } + + App.printdbg(this, shareCode) + + wotKeys = (1..4).map { Lang["CONTEXT_WORLD_CODE_SHARE_$it", false] } + } + + private lateinit var wotKeys: List + + override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) { + batch.color = Color.WHITE + + val textY = drawY + (height/2) - App.fontGame.lineHeight.toInt() * 4 - 2 + val codeY = textY + App.fontGame.lineHeight.toInt() * 5 + + // share code background + batch.color = Toolkit.Theme.COL_INVENTORY_CELL_BORDER + Toolkit.drawBoxBorder(batch, drawX - 1, codeY - 1, width + 2, BigAlphNum.H + 12) + batch.color = Toolkit.Theme.COL_CELL_FILL + Toolkit.fillArea(batch, drawX, codeY, width, BigAlphNum.H + 10) + + // share code + batch.color = Toolkit.Theme.COL_MOUSE_UP + Toolkit.drawTextCentered(batch, App.fontBigNumbers, shareCode, width, drawX, codeY + 5) + + // texts + batch.color = Color.WHITE + + val textboxWidth = wotKeys.maxOf { App.fontGame.getWidth(it) } + val tx = drawX + (width - textboxWidth) / 2 + wotKeys.forEachIndexed { i, s -> + App.fontGame.draw(batch, s, tx, textY + App.fontGame.lineHeight.toInt() * i) + } + + + uiItems.forEach { it.render(batch, camera) } + + } + + override fun dispose() { + } + + +} diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt index f4d652472..1a608826d 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalListing.kt @@ -60,7 +60,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { private val listHeight = UIItemWorldCellsSimple.height + (listCount - 1) * (UIItemWorldCellsSimple.height + gridGap) private val memoryGaugeWidth = textAreaW - private val buttonWidth = (UIItemWorldCellsSimple.width + thumbw - 3 * gridGap) / 5 // thumbw + cellw + gridgap = 4*gridgap + 5x + private val buttonWidth = (UIItemWorldCellsSimple.width + thumbw - 2 * gridGap) / 4 // thumbw + cellw + gridgap = 4*gridgap + 5x private val buttonsY = y + listHeight + gridGap private val screencapX = hx - thumbw - gridGap/2 @@ -109,7 +109,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { } } } - private val buttonShare = UIItemTextButton(this, + /*private val buttonShare = UIItemTextButton(this, { Lang["MENU_LABEL_SHARE"] }, screencapX + (buttonWidth + gridGap) * 3, buttonsY, @@ -121,10 +121,10 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { full.queueUpShareScr() full.changePanelTo(1) } - } + }*/ private val buttonDelete = UIItemTextButton(this, { Lang["MENU_LABEL_DELETE_WORLD"] }, - screencapX + (buttonWidth + gridGap) * 4, + screencapX + (buttonWidth + gridGap) * 3, buttonsY, buttonWidth, hasBorder = true, @@ -159,7 +159,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { buttonRename.isEnabled = false buttonDelete.isEnabled = false buttonTeleport.isEnabled = false - buttonShare.isEnabled = false +// buttonShare.isEnabled = false currentWorldSelected = false } @@ -171,7 +171,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { buttonRename.isEnabled = true buttonDelete.isEnabled = info.uuid != INGAME.world.worldIndex buttonTeleport.isEnabled = info.uuid != INGAME.world.worldIndex - buttonShare.isEnabled = true +// buttonShare.isEnabled = true currentWorldSelected = info.uuid == INGAME.world.worldIndex } } @@ -186,7 +186,7 @@ class UIWorldPortalListing(val full: UIWorldPortal) : UICanvas() { addUIitem(buttonRename) addUIitem(buttonTeleport) addUIitem(buttonSearch) - addUIitem(buttonShare) +// addUIitem(buttonShare) addUIitem(navRemoCon) } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalShare.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalShare.kt index c095cd543..5b6bae691 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalShare.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalShare.kt @@ -18,7 +18,7 @@ import net.torvald.terrarum.utils.PasswordBase32 class UIWorldPortalShare(private val full: UIWorldPortal) : UICanvas() { override var width = 434 - override var height = 400 + override var height = 480 private val drawX = (Toolkit.drawWidth - width) / 2 private val drawY = (App.scr.height - height) / 2 diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index ded4838d3..ae3df48e9 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -348,17 +348,18 @@ class BasicDebugInfoWindow : UICanvas() { private fun drawWeatherInfo(batch: SpriteBatch) { + val weatherbox = INGAME.world.weatherbox val drawX = App.scr.width - 170 val drawXf = drawX.toFloat() - drawWeatherStateBox(batch, WeatherMixer.weatherbox.windSpeed, "WindSpd", drawX, App.scr.height - 140 - 120, WeatherMixer.currentWeather.windSpeed * (1.0 + WeatherMixer.currentWeather.windSpeedVariance)) - drawWeatherStateBox(batch, WeatherMixer.weatherbox.windDir, "WindDir", drawX, App.scr.height - 140) + drawWeatherStateBox(batch, weatherbox.windSpeed, "WindSpd", drawX, App.scr.height - 140 - 120, weatherbox.currentWeather.windSpeed * (1.0 + weatherbox.currentWeather.windSpeedVariance)) + drawWeatherStateBox(batch, weatherbox.windDir, "WindDir", drawX, App.scr.height - 140) // draw weather schedule - val schedYstart = App.scr.height - 140 - 120 - 13f * (WeatherMixer.weatherbox.weatherSchedule.size + 3) - App.fontSmallNumbers.draw(batch, "$ccY== WeatherSched [${WeatherMixer.weatherbox.weatherSchedule.size}] ==", drawXf, schedYstart) - WeatherMixer.weatherbox.weatherSchedule.forEachIndexed { index, weather -> - val sek = if (index == 0) WeatherMixer.weatherbox.updateAkku else 0 + val schedYstart = App.scr.height - 140 - 120 - 13f * (weatherbox.weatherSchedule.size + 3) + App.fontSmallNumbers.draw(batch, "$ccY== WeatherSched [${weatherbox.weatherSchedule.size}] ==", drawXf, schedYstart) + weatherbox.weatherSchedule.forEachIndexed { index, weather -> + val sek = if (index == 0) weatherbox.updateAkku else 0 App.fontSmallNumbers.draw(batch, "$ccY${weather.weather.identifier} $ccG${weather.duration - sek}", drawXf, schedYstart + 13 * (index + 1)) } } diff --git a/src/net/torvald/terrarum/weather/BaseModularWeather.kt b/src/net/torvald/terrarum/weather/BaseModularWeather.kt index 4667bc639..d126937b3 100644 --- a/src/net/torvald/terrarum/weather/BaseModularWeather.kt +++ b/src/net/torvald/terrarum/weather/BaseModularWeather.kt @@ -25,6 +25,7 @@ data class BaseModularWeather( val cloudChance: Float, val windSpeed: Float, val windSpeedVariance: Float, + val windSpeedDamping: Float, val cloudGamma: Vector2, val cloudGammaVariance: Vector2, var clouds: List, // sorted by CloudProps.probability @@ -36,9 +37,10 @@ data class BaseModularWeather( /** * @param rnd random number between -1 and +1 */ - fun getRandomWindSpeed(rnd: Float): Float { + fun getRandomWindSpeed(old: Float, rnd: Float): Float { val v = 1f + rnd.absoluteValue * windSpeedVariance - return if (rnd < 0) windSpeed / v else windSpeed * v + val r = if (rnd < 0) windSpeed / v else windSpeed * v + return FastMath.interpolateLinear(windSpeedDamping, old, r) } fun getRandomCloudGamma(rnd1: Float, rnd2: Float): Vector2 { diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index a85bd817b..a5368e075 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -60,6 +60,7 @@ internal object WeatherMixer : RNGConsumer { 0f, 0f, 0f, + 0f, Vector2(1f, 1f), Vector2(0f, 0f), listOf() @@ -72,10 +73,6 @@ internal object WeatherMixer : RNGConsumer { val weatherDB: HashMap> // search by classification val weatherDict: HashMap // search by identifier - val currentWeather: BaseModularWeather - get() = weatherbox.currentWeather -// var nextWeather: BaseModularWeather - private var forceWindVec: Vector3? = null val globalLightNow = Cvec(0) @@ -106,9 +103,6 @@ internal object WeatherMixer : RNGConsumer { private var astrumOffY = 0f - var weatherbox = Weatherbox() - - // Clouds are merely a response to the current Weatherbox status // private val clouds = SortedArrayList() @@ -118,15 +112,15 @@ internal object WeatherMixer : RNGConsumer { val cloudSpawnMax: Int get() = 256 shl (App.getConfigInt("maxparticles") / 256) - override fun loadFromSave(s0: Long, s1: Long) { - super.loadFromSave(s0, s1) + override fun loadFromSave(ingame: IngameInstance, s0: Long, s1: Long) { + super.loadFromSave(ingame, s0, s1) internalReset(s0, s1) - initClouds() + initClouds(ingame.world.weatherbox.currentWeather) } - fun internalReset() { + fun internalReset(ingame: IngameInstance) { internalReset(RNG.state0, RNG.state1) - initClouds() + initClouds(ingame.world.weatherbox.currentWeather) } fun internalReset(s0: Long, s1: Long) { @@ -144,27 +138,6 @@ internal object WeatherMixer : RNGConsumer { windVector = Vector3(-0.98f, 0f, 0.21f) oldCamPos.set(WorldCamera.camVector) - - weatherbox = Weatherbox() - weatherbox.initWith(weatherDict["generic01"]!!, 7200L) - - // TEST FILL WITH RANDOM VALUES - (0..6).map { takeUniformRand(0f..1f) }.let { - weatherbox.windDir.pM2 = it[1] - weatherbox.windDir.pM1 = it[2] - weatherbox.windDir.p0 = it[3] - weatherbox.windDir.p1 = it[4] - weatherbox.windDir.p2 = it[5] - weatherbox.windDir.p3 = it[6] - } - (0..6).map { takeUniformRand(-1f..1f) }.let { - weatherbox.windSpeed.pM2 = currentWeather.getRandomWindSpeed(it[1]) - weatherbox.windSpeed.pM1 = currentWeather.getRandomWindSpeed(it[2]) - weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[3]) - weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[4]) - weatherbox.windSpeed.p2 = currentWeather.getRandomWindSpeed(it[5]) - weatherbox.windSpeed.p3 = currentWeather.getRandomWindSpeed(it[6]) - } } init { @@ -206,8 +179,8 @@ internal object WeatherMixer : RNGConsumer { // currentWeather = weatherList[WEATHER_GENERIC]!![0] // force set weather - weatherbox.update(world) - updateWind() + world.weatherbox.update(world) + updateWind(world.weatherbox) updateClouds(delta, world) @@ -236,7 +209,7 @@ internal object WeatherMixer : RNGConsumer { if (it > PI) it - TWO_PI else it } - private fun updateWind() { + private fun updateWind(weatherbox: Weatherbox) { val currentWindSpeed = weatherbox.windSpeed.value val currentWindDir = weatherbox.windDir.value * HALF_PI @@ -270,6 +243,7 @@ internal object WeatherMixer : RNGConsumer { val camvec = WorldCamera.camVector val camvec2 = camvec.cpy() val testCamDelta = camvec.cpy().sub(oldCamPos) + val currentWeather = world.weatherbox.currentWeather // adjust camDelta to accomodate ROUNDWORLD if (testCamDelta.x.absoluteValue > world.width * TILE_SIZEF / 2f) { @@ -353,11 +327,11 @@ internal object WeatherMixer : RNGConsumer { private val scrHscaler = App.scr.height / 720f private val cloudSizeMult = App.scr.wf / TerrarumScreenSize.defaultW - private fun takeUniformRand(range: ClosedFloatingPointRange) = + fun takeUniformRand(range: ClosedFloatingPointRange) = FastMath.interpolateLinear(Math.random().toFloat(), range.start, range.endInclusive) - private fun takeTriangularRand(range: ClosedFloatingPointRange) = + fun takeTriangularRand(range: ClosedFloatingPointRange) = FastMath.interpolateLinear((Math.random() + Math.random()).div(2f).toFloat(), range.start, range.endInclusive) - private fun takeGaussianRand(range: ClosedFloatingPointRange) = + fun takeGaussianRand(range: ClosedFloatingPointRange) = FastMath.interpolateLinear((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()).div(8f).toFloat(), range.start, range.endInclusive) /** @@ -481,7 +455,7 @@ internal object WeatherMixer : RNGConsumer { } } - private fun initClouds() { + private fun initClouds(currentWeather: BaseModularWeather) { val hCloudSize = 1024f // multiplier is an empirical value that depends on the 'rZ' // it does converge at ~6, but having it as an initial state does not make it stay converged @@ -498,10 +472,10 @@ internal object WeatherMixer : RNGConsumer { } } - internal fun titleScreenInitWeather() { + internal fun titleScreenInitWeather(weatherbox: Weatherbox) { weatherbox.initWith(weatherDict["titlescreen"]!!, Long.MAX_VALUE) forceWindVec = Vector3(-0.98f, 0f, -0.21f).scl(1f/30f) // value taken from TitleScreen.kt; search for 'demoWorld.worldTime.timeDelta = ' - initClouds() + initClouds(weatherbox.currentWeather) } private fun Array.addAtFreeSpot(obj: T) { @@ -545,6 +519,7 @@ internal object WeatherMixer : RNGConsumer { private val turbidityDomainSize = 533.3333f private fun drawSkybox(camera: OrthographicCamera, batch: FlippingSpriteBatch, world: GameWorld) { + val currentWeather = world.weatherbox.currentWeather val parallaxZeroPos = (world.height / 3f) // we will not care for nextSkybox for now @@ -650,7 +625,7 @@ internal object WeatherMixer : RNGConsumer { /** * Get a GL of specific time */ - fun getGlobalLightOfTimeOfNoon(): Cvec { + fun getGlobalLightOfTimeOfNoon(currentWeather: BaseModularWeather): Cvec { currentWeather.daylightClut.let { it.get(it.width - 1, 0) }.let { return Cvec(it.r, it.g, it.b, it.a) } @@ -804,6 +779,7 @@ internal object WeatherMixer : RNGConsumer { cloudChance = JSON.getFloat("cloudChance"), windSpeed = JSON.getFloat("windSpeed"), windSpeedVariance = JSON.getFloat("windSpeedVariance"), + windSpeedDamping = JSON.getFloat("windSpeedDamping"), cloudGamma = JSON["cloudGamma"].asFloatArray().let { Vector2(it[0], it[1]) }, cloudGammaVariance = JSON["cloudGammaVariance"].asFloatArray().let { Vector2(it[0], it[1]) }, clouds = cloudsMap, diff --git a/src/net/torvald/terrarum/weather/Weatherbox.kt b/src/net/torvald/terrarum/weather/Weatherbox.kt index 1761b30ba..cf387d200 100644 --- a/src/net/torvald/terrarum/weather/Weatherbox.kt +++ b/src/net/torvald/terrarum/weather/Weatherbox.kt @@ -15,7 +15,7 @@ class Weatherbox { companion object { private val WIND_DIR_TIME_UNIT = 3600f * 6 // every 6hr - private val WIND_SPEED_TIME_UNIT = 3600f * 1 // every 2hr + private val WIND_SPEED_TIME_UNIT = 360f * 5 // every 0.5hr private val HALF_PIF = 1.5707964f private val PIF = 3.1415927f @@ -44,6 +44,7 @@ class Weatherbox { get() = weatherSchedule[0].duration fun initWith(initWeather: BaseModularWeather, duration: Long) { + weatherSchedule.clear() weatherSchedule.add(WeatherSchedule(initWeather, duration)) } @@ -70,8 +71,8 @@ class Weatherbox { } private fun updateWind(world: GameWorld) { - windSpeed.update(world.worldTime.timeDelta / WIND_SPEED_TIME_UNIT) { - currentWeather.getRandomWindSpeed(takeUniformRand(-1f..1f)) + windSpeed.update(world.worldTime.timeDelta / WIND_SPEED_TIME_UNIT) { lastValue -> + currentWeather.getRandomWindSpeed(lastValue, takeUniformRand(-1f..1f)) } windDir.update( world.worldTime.timeDelta / WIND_DIR_TIME_UNIT) { RNG.nextFloat() * 4f } } @@ -120,7 +121,7 @@ open class WeatherStateBox( } - open fun update(xdelta: Float, next: () -> Float) { + open fun update(xdelta: Float, next: (Float) -> Float) { // if (!::polynomial.isInitialized) updatePolynomials() synchronized(WeatherMixer.RNG) { @@ -132,7 +133,7 @@ open class WeatherStateBox( p0 = p1 p1 = p2 p2 = p3 - p3 = next() + p3 = next(p2) } // updatePolynomials() } diff --git a/src/net/torvald/unsafe/UnsafePtr.kt b/src/net/torvald/unsafe/UnsafePtr.kt index 44858f755..a3e127287 100644 --- a/src/net/torvald/unsafe/UnsafePtr.kt +++ b/src/net/torvald/unsafe/UnsafePtr.kt @@ -113,8 +113,8 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) { // appear (e.g. getting garbage values when it fucking shouldn't) // using ifs instead of assertions: inactive assert statements still slows down the app -// if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") } -// if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") } + if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") } + if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") } } operator fun get(index: Long): Byte {