diff --git a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt index b0d9ba256..f574fd48d 100644 --- a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt +++ b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt @@ -12,8 +12,9 @@ import net.torvald.UnsafeHelper */ internal class UnsafeCvecArray(val width: Int, val height: Int) { - private val TOTAL_SIZE_IN_BYTES = 16L * (width + 1) * (height + 1) + val TOTAL_SIZE_IN_BYTES = 16L * (width + 1) * (height + 1) private val array = UnsafeHelper.allocate(TOTAL_SIZE_IN_BYTES) + val ptr = array.ptr private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x) diff --git a/src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused b/src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused deleted file mode 100644 index b75d3fa6a..000000000 --- a/src/net/torvald/terrarum/FuckingWorldRenderer.kt.unused +++ /dev/null @@ -1,1508 +0,0 @@ -package net.torvald.terrarum.modulebasegame - -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.Input -import com.badlogic.gdx.Screen -import com.badlogic.gdx.graphics.* -import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.glutils.FrameBuffer - -import net.torvald.dataclass.CircularArray -import net.torvald.terrarum.blockproperties.BlockPropUtil -import net.torvald.terrarum.blockstats.BlockStats -import net.torvald.terrarum.concurrent.ThreadParallel -import net.torvald.terrarum.console.* -import net.torvald.terrarum.gameactors.* -import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver -import net.torvald.terrarum.gamecontroller.IngameController -import net.torvald.terrarum.gamecontroller.KeyToggler -import net.torvald.terrarum.gameworld.GameWorld -import net.torvald.terrarum.gameworld.WorldSimulator -import net.torvald.terrarum.weather.WeatherMixer -import net.torvald.terrarum.worlddrawer.BlocksDrawer -import net.torvald.terrarum.worlddrawer.FeaturesDrawer -import net.torvald.terrarum.worlddrawer.LightmapRenderer -import net.torvald.terrarum.worlddrawer.WorldCamera - -import java.util.ArrayList -import java.util.concurrent.locks.Lock -import java.util.concurrent.locks.ReentrantLock - -import javax.swing.JOptionPane - -import com.badlogic.gdx.graphics.OrthographicCamera -import net.torvald.random.HQRNG -import net.torvald.terrarum.* -import net.torvald.terrarum.gameworld.fmod -import net.torvald.terrarum.console.AVTracker -import net.torvald.terrarum.console.ActorsList -import net.torvald.terrarum.console.Authenticator -import net.torvald.terrarum.console.SetGlobalLightOverride -import net.torvald.terrarum.itemproperties.ItemCodex -import net.torvald.terrarum.modulebasegame.gameactors.* -import net.torvald.terrarum.modulebasegame.imagefont.Watch7SegMain -import net.torvald.terrarum.modulebasegame.imagefont.WatchDotAlph -import net.torvald.terrarum.modulebasegame.ui.* -import net.torvald.terrarum.ui.* -import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser -import net.torvald.terrarum.modulebasegame.worldgenerator.WorldGenerator -import kotlin.system.measureNanoTime - - -/** - * Created by minjaesong on 2017-06-16. - */ - -class Ingame(batch: SpriteBatch) : IngameInstance(batch) { - - - private val ACTOR_UPDATE_RANGE = 4096 - - lateinit var world: GameWorld - lateinit var historicalFigureIDBucket: ArrayList - - /** - * list of Actors that is sorted by Actors' referenceID - */ - //val ACTORCONTAINER_INITIAL_SIZE = 64 - val PARTICLES_MAX = AppLoader.getConfigInt("maxparticles") - //val actorContainer = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - //val actorContainerInactive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - val particlesContainer = CircularArray(PARTICLES_MAX) - val uiContainer = ArrayList() - - private val actorsRenderBehind = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderMiddle = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderMidTop = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderFront = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - - lateinit var playableActorDelegate: PlayableActorDelegate // player must exist; use dummy player if there is none (required for camera) - private set - inline val player: ActorHumanoid // currently POSSESSED actor :) - get() = playableActorDelegate.actor - - //var screenZoom = 1.0f // definition moved to IngameInstance - //val ZOOM_MAXIMUM = 4.0f // definition moved to IngameInstance - //val ZOOM_MINIMUM = 0.5f // definition moved to IngameInstance - - companion object { - //val lightmapDownsample = 4f //2f: still has choppy look when the camera moves but unnoticeable when blurred - - - /** Sets camera position so that (0,0) would be top-left of the screen, (width, height) be bottom-right. */ - fun setCameraPosition(batch: SpriteBatch, camera: Camera, newX: Float, newY: Float) { - camera.position.set((-newX + AppLoader.halfScreenW).round(), (-newY + AppLoader.halfScreenH).round(), 0f) - camera.update() - batch.projectionMatrix = camera.combined - } - - - - /** - * Usage: - * - * override var referenceID: Int = generateUniqueReferenceID() - */ - fun generateUniqueReferenceID(renderOrder: Actor.RenderOrder): ActorID { - fun hasCollision(value: ActorID) = - try { - INGAME.theGameHasActor(value) || - value < ItemCodex.ACTORID_MIN || - value !in when (renderOrder) { - Actor.RenderOrder.BEHIND -> Actor.RANGE_BEHIND - Actor.RenderOrder.MIDDLE -> Actor.RANGE_MIDDLE - Actor.RenderOrder.MIDTOP -> Actor.RANGE_MIDTOP - Actor.RenderOrder.FRONT -> Actor.RANGE_FRONT - } - } - catch (gameNotInitialisedException: KotlinNullPointerException) { - false - } - - var ret: Int - do { - ret = HQRNG().nextInt().and(0x7FFFFFFF) // set new ID - } while (hasCollision(ret)) // check for collision - return ret - } - } - - - private val worldFBOformat = if (Terrarum.environment == RunningEnvironment.MOBILE) Pixmap.Format.RGBA4444 else Pixmap.Format.RGBA8888 - private val lightFBOformat = Pixmap.Format.RGB888 - - var worldDrawFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - var worldGlowFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - var worldBlendFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - // RGB elements of Lightmap for Color Vec4(R, G, B, 1.0) 24-bit - private lateinit var lightmapFboA: FrameBuffer - private lateinit var lightmapFboB: FrameBuffer - - - init { - } - - - - private val useShader: Boolean = false - private val shaderProgram = 0 - - val KEY_LIGHTMAP_RENDER = Input.Keys.F7 - - - - lateinit var debugWindow: UICanvas - lateinit var notifier: UICanvas - - lateinit var uiPieMenu: UICanvas - lateinit var uiQuickBar: UICanvas - lateinit var uiInventoryPlayer: UICanvas - lateinit var uiInventoryContainer: UICanvas - lateinit var uiVitalPrimary: UICanvas - lateinit var uiVitalSecondary: UICanvas - lateinit var uiVitalItem: UICanvas // itemcount/durability of held block or active ammo of held gun. As for the block, max value is 500. - - private lateinit var uiWatchBasic: UICanvas - private lateinit var uiWatchTierOne: UICanvas - - private lateinit var uiTooltip: UITooltip - - lateinit var uiCheatMotherfuckerNootNoot: UICheatDetected - - // UI aliases - lateinit var uiAliases: ArrayList - private set - lateinit var uiAlasesPausing: ArrayList - private set - - inline val paused: Boolean - get() = uiAlasesPausing.map { if (it.isOpened) return true else 0 }.isEmpty() // isEmply is always false, which we want - /** - * Set to false if UI is opened; set to true if UI is closed. - */ - inline val canPlayerControl: Boolean - get() = !paused // FIXME temporary behab (block movement if the game is paused or paused by UIs) - - var particlesActive = 0 - private set - - - - private lateinit var ingameUpdateThread: ThreadIngameUpdate - private lateinit var updateThreadWrapper: Thread - //private val ingameDrawThread: ThreadIngameDraw // draw must be on the main thread - - - var gameInitialised = false - private set - var gameFullyLoaded = false - private set - - - private val TILE_SIZEF = TILE_SIZEF - - ////////////// - // GDX code // - ////////////// - - - - // invert Y - fun initViewPort(width: Int, height: Int) { - // Set Y to point downwards - camera.setToOrtho(true, width.toFloat(), height.toFloat()) - - // Update camera matrix - camera.update() - - // Set viewport to restrict drawing - Gdx.gl20.glViewport(0, 0, width, height) - } - - - lateinit var gameLoadMode: GameLoadMode - lateinit var gameLoadInfoPayload: Any - - enum class GameLoadMode { - CREATE_NEW, LOAD_FROM - } - - override fun show() { - //initViewPort(AppLoader.screenW, AppLoader.screenH) - - // gameLoadMode and gameLoadInfoPayload must be set beforehand!! - - when (gameLoadMode) { - GameLoadMode.CREATE_NEW -> enter(gameLoadInfoPayload as NewWorldParameters) - GameLoadMode.LOAD_FROM -> enter(gameLoadInfoPayload as GameSaveData) - } - - LightmapRenderer.world = this.world - //BlocksDrawer.world = this.world - FeaturesDrawer.world = this.world - - gameInitialised = true - } - - data class GameSaveData( - val world: GameWorld, - val historicalFigureIDBucket: ArrayList, - val realGamePlayer: ActorHumanoid - ) - - data class NewWorldParameters( - val width: Int, - val height: Int, - val worldGenSeed: Long - // other worldgen options - ) - - /** - * Init instance by loading saved world - */ - private fun enter(gameSaveData: GameSaveData) { - if (gameInitialised) { - println("[Ingame] loaded successfully.") - } - else { - LoadScreen.addMessage("Loading world from save") - - - world = gameSaveData.world - historicalFigureIDBucket = gameSaveData.historicalFigureIDBucket - playableActorDelegate = PlayableActorDelegate(gameSaveData.realGamePlayer) - addNewActor(player) - - - - //initGame() - } - } - - /** - * Init instance by creating new world - */ - private fun enter(worldParams: NewWorldParameters) { - if (gameInitialised) { - println("[Ingame] loaded successfully.") - } - else { - LoadScreen.addMessage("${Terrarum.NAME} version ${AppLoader.getVERSION_STRING()}") - LoadScreen.addMessage("Creating new world") - - - // init map as chosen size - world = GameWorld(worldParams.width, worldParams.height) - - // generate terrain for the map - WorldGenerator.attachMap(world) - WorldGenerator.SEED = worldParams.worldGenSeed - WorldGenerator.generateMap() - - - historicalFigureIDBucket = ArrayList() - - - RoguelikeRandomiser.seed = HQRNG().nextLong() - - - // add new player and put it to actorContainer - //playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) - //playableActorDelegate = PlayableActorDelegate(PlayerBuilderTestSubject1()) - //addNewActor(player) - - - // test actor - //addNewActor(PlayerBuilderCynthia()) - - - //initGame() - } - } - - private val ingameController = IngameController(this) - - /** Load rest of the game with GL context */ - fun postInit() { - //LightmapRenderer.world = this.world - BlocksDrawer.world = this.world - //FeaturesDrawer.world = this.world - - - MegaRainGovernor // invoke MegaRain Governor - - - - Gdx.input.inputProcessor = ingameController - - - initViewPort(AppLoader.screenW, AppLoader.screenH) - - - // init console window - consoleHandler = ConsoleWindow() - consoleHandler.setPosition(0, 0) - - - // init debug window - debugWindow = BasicDebugInfoWindow() - debugWindow.setPosition(0, 0) - - // init notifier - notifier = Notification() - notifier.setPosition( - (AppLoader.screenW - notifier.width) / 2, AppLoader.screenH - notifier.height) - - - - - // >- queue up game UIs that should pause the world -< - // inventory - /*uiInventoryPlayer = UIInventory(player, - width = 900, - height = AppLoader.screenH - 160, - categoryWidth = 210, - toggleKeyLiteral = AppLoader.getConfigInt("keyinventory") - )*/ - /*uiInventoryPlayer.setPosition( - -uiInventoryPlayer.width, - 70 - )*/ - uiInventoryPlayer = UIInventoryFull(player, - toggleKeyLiteral = AppLoader.getConfigInt("keyinventory") - ) - uiInventoryPlayer.setPosition(0, 0) - - // >- lesser UIs -< - // quick bar - uiQuickBar = UIQuickBar() - uiQuickBar.isVisible = true - uiQuickBar.setPosition((AppLoader.screenW - uiQuickBar.width) / 2 + 12, -10) - - // pie menu - uiPieMenu = UIPieMenu() - uiPieMenu.setPosition(AppLoader.halfScreenW, AppLoader.halfScreenH) - - // vital metre - // fill in getter functions by - // (uiAliases[UI_QUICK_BAR]!!.UI as UIVitalMetre).vitalGetterMax = { some_function } - //uiVitalPrimary = UIVitalMetre(player, { 80f }, { 100f }, Color.red, 2, customPositioning = true) - //uiVitalPrimary.setAsAlwaysVisible() - //uiVitalSecondary = UIVitalMetre(player, { 73f }, { 100f }, Color(0x00dfff), 1) customPositioning = true) - //uiVitalSecondary.setAsAlwaysVisible() - //uiVitalItem = UIVitalMetre(player, { null }, { null }, Color(0xffcc00), 0, customPositioning = true) - //uiVitalItem.setAsAlwaysVisible() - - // basic watch-style notification bar (temperature, new mail) - uiWatchBasic = UIBasicNotifier(player) - uiWatchBasic.setAsAlwaysVisible() - uiWatchBasic.setPosition(AppLoader.screenW - uiWatchBasic.width, 0) - - uiWatchTierOne = UITierOneWatch(player) - uiWatchTierOne.setAsAlwaysVisible() - uiWatchTierOne.setPosition(AppLoader.screenW - uiWatchTierOne.width, uiWatchBasic.height - 2) - - - uiTooltip = UITooltip() - - - uiCheatMotherfuckerNootNoot = UICheatDetected() - - - // batch-process uiAliases - uiAliases = arrayListOf( - // drawn first - //uiVitalPrimary, - //uiVitalSecondary, - //uiVitalItem, - - uiPieMenu, - uiQuickBar, - uiWatchBasic, - uiWatchTierOne, - uiTooltip - // drawn last - ) - uiAlasesPausing = arrayListOf( - uiInventoryPlayer, - //uiInventoryContainer, - consoleHandler, - uiCheatMotherfuckerNootNoot - ) - uiAlasesPausing.forEach { addUI(it) } // put them all to the UIContainer - uiAliases.forEach { addUI(it) } // put them all to the UIContainer - - - - ingameUpdateThread = ThreadIngameUpdate(this) - updateThreadWrapper = Thread(ingameUpdateThread, "Terrarum UpdateThread") - - - - LightmapRenderer.fireRecalculateEvent() - - - - - - // some sketchy test code here - - - - }// END enter - - - protected var updateDeltaCounter = 0.0 - protected val updateRate = 1.0 / Terrarum.TARGET_INTERNAL_FPS - - private var firstTimeRun = true - - /////////////// - // prod code // - /////////////// - private class ThreadIngameUpdate(val ingame: Ingame): Runnable { - override fun run() { - var updateTries = 0 - while (ingame.updateDeltaCounter >= ingame.updateRate) { - ingame.updateGame(AppLoader.UPDATE_RATE) - ingame.updateDeltaCounter -= ingame.updateRate - updateTries++ - - if (updateTries >= Terrarum.UPDATE_CATCHUP_MAX_TRIES) { - break - } - } - } - } - - override fun render(delta: Float) { - // Q&D solution for LoadScreen and Ingame, where while LoadScreen is working, Ingame now no longer has GL Context - // there's still things to load which needs GL context to be present - if (!gameFullyLoaded) { - - if (gameLoadMode == GameLoadMode.CREATE_NEW) { - playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) - - // go to spawn position - player.setPosition( - world.spawnX * TILE_SIZED, - world.spawnY * TILE_SIZED - ) - - addNewActor(player) - } - - postInit() - - - gameFullyLoaded = true - } - - - - - - Gdx.graphics.setTitle(AppLoader.GAME_NAME + - " $EMDASH F: ${Gdx.graphics.framesPerSecond} (${Terrarum.TARGET_INTERNAL_FPS})" + - " $EMDASH M: ${Terrarum.memInUse}M / ${Terrarum.memTotal}M / ${Terrarum.memXmx}M" - ) - - // ASYNCHRONOUS UPDATE AND RENDER // - - - /** UPDATE CODE GOES HERE */ - updateDeltaCounter += delta - - - - if (false && AppLoader.getConfigBoolean("multithread")) { // NO MULTITHREADING: camera don't like concurrent modification (jittery actor movements) - if (firstTimeRun || updateThreadWrapper.state == Thread.State.TERMINATED) { - updateThreadWrapper = Thread(ingameUpdateThread, "Terrarum UpdateThread") - updateThreadWrapper.start() - - if (firstTimeRun) firstTimeRun = false - } - // else, NOP; - } - else { - var updateTries = 0 - while (updateDeltaCounter >= updateRate) { - - //updateGame(delta) - AppLoader.measureDebugTime("Ingame.update") { updateGame(delta) } - - updateDeltaCounter -= updateRate - updateTries++ - - if (updateTries >= Terrarum.UPDATE_CATCHUP_MAX_TRIES) { - break - } - } - } - - - - /** RENDER CODE GOES HERE */ - //renderGame(batch) - AppLoader.measureDebugTime("Ingame.render") { renderGame(batch) } - } - - protected fun updateGame(delta: Float) { - particlesActive = 0 - - - KeyToggler.update() - ingameController.update(delta) - - - if (!paused) { - - /////////////////////////// - // world-related updates // - /////////////////////////// - BlockPropUtil.dynamicLumFuncTickClock() - world.updateWorldTime(delta) - //WorldSimulator(player, delta) - WeatherMixer.update(delta, player) - BlockStats.update() - if (!(CommandDict["setgl"] as SetGlobalLightOverride).lightOverride) - world.globalLight = WeatherMixer.globalLightNow - - - //////////////////////////// - // camera-related updates // - //////////////////////////// - FeaturesDrawer.update(delta) - WorldCamera.update(world, player) - - - - /////////////////////////// - // actor-related updates // - /////////////////////////// - repossessActor() - - // determine whether the inactive actor should be activated - wakeDormantActors() - // determine whether the actor should keep being activated or be dormant - KillOrKnockdownActors() - updateActors(delta) - particlesContainer.forEach { if (!it.flagDespawn) particlesActive++; it.update(delta) } - // TODO thread pool(?) - CollisionSolver.process() - } - - - //////////////////////// - // ui-related updates // - //////////////////////// - uiContainer.forEach { it.update(delta) } - debugWindow.update(delta) - notifier.update(delta) - - // update debuggers using javax.swing // - if (Authenticator.b()) { - AVTracker.update() - ActorsList.update() - } - } - - - private fun renderGame(batch: SpriteBatch) { - Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - - //camera.position.set(-WorldCamera.x.toFloat(), -WorldCamera.y.toFloat(), 0f) // make camara work - //camera.position.set(0f, 0f, 0f) // make camara work - //batch.projectionMatrix = camera.combined - - - - LightmapRenderer.fireRecalculateEvent() - - - - worldBlendFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - worldDrawFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - worldGlowFrameBuffer.inAction(null, null) { - Gdx.gl.glClearColor(0f,0f,0f,1f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) - Gdx.gl.glEnable(GL20.GL_BLEND) - Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) - } - - - fun moveCameraToWorldCoord() { - // using custom code for camera; this is obscure and tricky - camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work - camera.update() - batch.projectionMatrix = camera.combined - } - - - /////////////////////////// - // draw world to the FBO // - /////////////////////////// - processBlur(lightmapFboA, lightmapFboB, LightmapRenderer.DRAW_FOR_RGB) - - worldDrawFrameBuffer.inAction(camera, batch) { - - - // draw-with-poly doesn't want to co-op with peasant spriteBatch... (it hides sprites) - - batch.inUse { - batch.shader = null - batch.color = Color.WHITE - blendNormal() - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderWall(batch) - - - - batch.inUse { - moveCameraToWorldCoord() - actorsRenderBehind.forEach { it.drawBody(batch) } - particlesContainer.forEach { it.drawBody(batch) } - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderTerrain(batch) - - - - batch.inUse { - ///////////////// - // draw actors // - ///////////////// - moveCameraToWorldCoord() - actorsRenderMiddle.forEach { it.drawBody(batch) } - actorsRenderMidTop.forEach { it.drawBody(batch) } - player.drawBody(batch) - actorsRenderFront.forEach { it.drawBody(batch) } - // --> Change of blend mode <-- introduced by children of ActorWithBody // - - - ///////////////////////////// - // draw map related stuffs // - ///////////////////////////// - } - - - - setCameraPosition(0f, 0f) - BlocksDrawer.renderFront(batch, false) - - - - batch.inUse { - // --> blendNormal() <-- by BlocksDrawer.renderFront - FeaturesDrawer.drawEnvOverlay(batch) - - - - - // mix lighpmap canvas to this canvas (Colors -- RGB channel) - if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw - setCameraPosition(0f, 0f) - batch.shader = Terrarum.shaderBayer - batch.shader.setUniformf("rcount", 64f) - batch.shader.setUniformf("gcount", 64f) - batch.shader.setUniformf("bcount", 64f) // de-banding - - val lightTex = lightmapFboB.colorBufferTexture // A or B? flipped in Y means you chose wrong buffer; use one that works correctly - lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) // blocky feeling for A E S T H E T I C S - - if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal() - else blendMul() - - batch.color = Color.WHITE - val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) - batch.draw(lightTex, - xrem, - yrem, - lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample - //lightTex.width.toFloat(), lightTex.height.toFloat() // for debugging - ) - - } - - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is REALLY needed; it really depresses me - batch.shader = null - - - // move camera back to its former position - // using custom code for camera; this is obscure and tricky - camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work - camera.update() - batch.projectionMatrix = camera.combined - - } - } - - - ////////////////////////// - // draw glow to the FBO // - ////////////////////////// - processBlur(lightmapFboA, lightmapFboB, LightmapRenderer.DRAW_FOR_ALPHA) - - worldGlowFrameBuffer.inAction(camera, batch) { - batch.inUse { - batch.shader = null - - - batch.color = Color.WHITE - blendNormal() - - - - ////////////////////// - // draw actor glows // - ////////////////////// - moveCameraToWorldCoord() - actorsRenderBehind.forEach { it.drawGlow(batch) } - particlesContainer.forEach { it.drawGlow(batch) } - actorsRenderMiddle.forEach { it.drawGlow(batch) } - actorsRenderMidTop.forEach { it.drawGlow(batch) } - player.drawGlow(batch) - actorsRenderFront.forEach { it.drawGlow(batch) } - // --> blendNormal() <-- introduced by childs of ActorWithBody // - - - - // mix lighpmap canvas to this canvas (UV lights -- A channel written on RGB as greyscale image) - if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw - setCameraPosition(0f, 0f) - batch.shader = Terrarum.shaderBayer - batch.shader.setUniformf("rcount", 64f) - batch.shader.setUniformf("gcount", 64f) - batch.shader.setUniformf("bcount", 64f) // de-banding - - val lightTex = lightmapFboB.colorBufferTexture // A or B? flipped in Y means you chose wrong buffer; use one that works correctly - lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) // blocky feeling for A E S T H E T I C S - - if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal() - else blendMul() - - batch.color = Color.WHITE - val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) - batch.draw(lightTex, - xrem, - yrem, - lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample - //lightTex.width.toFloat(), lightTex.height.toFloat() // for debugging - ) - - } - - - blendNormal() - } - } - - - worldBlendFrameBuffer.inAction(camera, batch) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - - - // draw blended world - val worldTex = worldDrawFrameBuffer.colorBufferTexture // WORLD: light_color must be applied beforehand - val glowTex = worldGlowFrameBuffer.colorBufferTexture // GLOW: light_uvlight must be applied beforehand - - worldTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - glowTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - - worldTex.bind(0) - glowTex.bind(1) - - - Terrarum.shaderBlendGlow.begin() - Terrarum.shaderBlendGlow.setUniformMatrix("u_projTrans", camera.combined) - Terrarum.shaderBlendGlow.setUniformi("u_texture", 0) - Terrarum.shaderBlendGlow.setUniformi("tex1", 1) - Terrarum.fullscreenQuad.render(Terrarum.shaderBlendGlow, GL20.GL_TRIANGLES) - Terrarum.shaderBlendGlow.end() - - - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // don't know why it is REALLY needed; it really depresses me - - - batch.inUse { - batch.color = Color.WHITE - blendNormal() - - batch.shader = null - } - } - - - ///////////////////////// - // draw to main screen // - ///////////////////////// - camera.setToOrtho(true, AppLoader.screenWf, AppLoader.screenHf) - batch.projectionMatrix = camera.combined - batch.inUse { - - batch.shader = null - - setCameraPosition(0f, 0f) - batch.color = Color.WHITE - blendNormal() - - - /////////////////////////// - // draw skybox to screen // - /////////////////////////// - - WeatherMixer.render(camera, world) - - - - - ///////////////////////////////// - // draw framebuffers to screen // - ///////////////////////////////// - - - - val blendedTex = worldBlendFrameBuffer.colorBufferTexture - blendedTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - batch.color = Color.WHITE - batch.shader = null - blendNormal() - batch.draw(blendedTex, 0f, 0f, blendedTex.width.toFloat(), blendedTex.height.toFloat()) - - - - - - // an old code. - /*batch.shader = null - val worldTex = worldDrawFrameBuffer.colorBufferTexture // WORLD: light_color must be applied beforehand - val glowTex = worldGlowFrameBuffer.colorBufferTexture // GLOW: light_uvlight must be applied beforehand - - - batch.draw(worldTex, 0f, 0f, worldTex.width.toFloat(), worldTex.height.toFloat())*/ - - - - batch.shader = null - - //////////////////////// - // debug informations // - //////////////////////// - - blendNormal() - // draw reference ID if debugWindow is open - if (debugWindow.isVisible) { - - actorContainer.forEachIndexed { i, actor -> - if (actor is ActorWithBody) { - batch.color = Color.WHITE - AppLoader.fontSmallNumbers.draw(batch, - actor.referenceID.toString(), - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 - ) - } - } - } - // debug physics - if (KeyToggler.isOn(Input.Keys.F11)) { - actorContainer.forEachIndexed { i, actor -> - if (actor is ActorWithPhysics) { - /*shapeRenderer.inUse(ShapeRenderer.ShapeType.Line) { - shapeRenderer.color = Color(1f, 0f, 1f, 1f) - //shapeRenderer.lineWidth = 1f - shapeRenderer.rect( - actor.hitbox.startX.toFloat(), - actor.hitbox.startY.toFloat(), - actor.hitbox.width.toFloat(), - actor.hitbox.height.toFloat() - ) - }*/ - - // velocity - batch.color = Color.CHARTREUSE//TerrarumSansBitmap.codeToCol["g"] - AppLoader.fontSmallNumbers.draw(batch, - "${0x7F.toChar()}X ${actor.externalForce.x}", - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 + 8 - ) - AppLoader.fontSmallNumbers.draw(batch, - "${0x7F.toChar()}Y ${actor.externalForce.y}", - actor.hitbox.startX.toFloat(), - actor.hitbox.canonicalY.toFloat() + 4 + 8 * 2 - ) - } - } - } - // fluidmap debug - if (KeyToggler.isOn(Input.Keys.F4)) { - WorldSimulator.drawFluidMapDebug(batch) - } - - - - - ///////////////////////////// - // draw some overlays (UI) // - ///////////////////////////// - - uiContainer.forEach { - if (it != consoleHandler) { - batch.color = Color.WHITE - it.render(batch, camera) - } - } - - debugWindow.render(batch, camera) - // make sure console draws on top of other UIs - consoleHandler.render(batch, camera) - notifier.render(batch, camera) - - - blendNormal() - } - - } - - fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer, mode: Int) { - val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image - val blurRadius = 4f / lightmapDownsample // (5, 4f); using low numbers for pixel-y aesthetics - - var blurWriteBuffer = lightmapFboA - var blurReadBuffer = lightmapFboB - - - lightmapFboA.inAction(null, null) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - } - lightmapFboB.inAction(null, null) { - Gdx.gl.glClearColor(0f, 0f, 0f, 0f) - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - } - - - if (mode == LightmapRenderer.DRAW_FOR_RGB) { - // initialise readBuffer with untreated lightmap - blurReadBuffer.inAction(camera, batch) { - batch.inUse { - blendNormal(batch) - batch.color = Color.WHITE - LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_RGB) - } - } - } - else { - // initialise readBuffer with untreated lightmap - blurReadBuffer.inAction(camera, batch) { - batch.inUse { - blendNormal(batch) - batch.color = Color.WHITE - LightmapRenderer.draw(batch, LightmapRenderer.DRAW_FOR_ALPHA) - } - } - } - - - - if (!KeyToggler.isOn(Input.Keys.F8)) { - for (i in 0 until blurIterations) { - blurWriteBuffer.inAction(camera, batch) { - - batch.inUse { - val texture = blurReadBuffer.colorBufferTexture - - texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - - - batch.shader = Terrarum.shaderBlur - batch.shader.setUniformf("iResolution", - blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat()) - batch.shader.setUniformf("flip", 1f) - if (i % 2 == 0) - batch.shader.setUniformf("direction", blurRadius, 0f) - else - batch.shader.setUniformf("direction", 0f, blurRadius) - - - batch.color = Color.WHITE - batch.draw(texture, 0f, 0f) - - - // swap - val t = blurWriteBuffer - blurWriteBuffer = blurReadBuffer - blurReadBuffer = t - } - } - } - } - else { - blurWriteBuffer = blurReadBuffer - } - } - - - - private fun repossessActor() { - // check if currently pocessed actor is removed from game - if (!theGameHasActor(player)) { - // re-possess canonical player - if (theGameHasActor(Player.PLAYER_REF_ID)) - changePossession(Player.PLAYER_REF_ID) - else - changePossession(0x51621D) // FIXME fallback debug mode (FIXME is there for a reminder visible in ya IDE) - } - } - - private fun changePossession(newActor: PlayableActorDelegate) { - if (!theGameHasActor(player)) { - throw IllegalArgumentException("No such actor in the game: $newActor") - } - - playableActorDelegate = newActor - WorldSimulator(player, AppLoader.UPDATE_RATE) - } - - private fun changePossession(refid: Int) { - // TODO prevent possessing other player on multiplayer - - if (!theGameHasActor(refid)) { - throw IllegalArgumentException( - "No such actor in the game: $refid (elemsActive: ${actorContainer.size}, " + - "elemsInactive: ${actorContainerInactive.size})") - } - - // take care of old delegate - playableActorDelegate!!.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE - // accept new delegate - playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid) - playableActorDelegate!!.actor.collisionType = ActorWithPhysics.COLLISION_KINEMATIC - WorldSimulator(player, AppLoader.UPDATE_RATE) - } - - /** Send message to notifier UI and toggle the UI as opened. */ - fun sendNotification(msg: Array) { - (notifier as Notification).sendNotification(msg) - } - - fun wakeDormantActors() { - var actorContainerSize = actorContainerInactive.size - var i = 0 - while (i < actorContainerSize) { // loop through actorContainerInactive - val actor = actorContainerInactive[i] - if (actor is ActorWithBody && actor.inUpdateRange()) { - activateDormantActor(actor) // duplicates are checked here - actorContainerSize -= 1 - i-- // array removed 1 elem, so we also decrement counter by 1 - } - i++ - } - } - - /** - * determine whether the actor should be active or dormant by its distance from the player. - * If the actor must be dormant, the target actor will be put to the list specifically for them. - * if the actor is not to be dormant, it will be just ignored. - */ - fun KillOrKnockdownActors() { - var actorContainerSize = actorContainer.size - var i = 0 - while (i < actorContainerSize) { // loop through actorContainer - val actor = actorContainer[i] - val actorIndex = i - // kill actors flagged to despawn - if (actor.flagDespawn) { - removeActor(actor) - actorContainerSize -= 1 - i-- // array removed 1 elem, so we also decrement counter by 1 - } - // inactivate distant actors - else if (actor is ActorWithBody && !actor.inUpdateRange()) { - if (actor !is Projectile) { // if it's a projectile, don't inactivate it; just kill it. - actorContainerInactive.add(actor) // naïve add; duplicates are checked when the actor is re-activated - } - actorContainer.removeAt(actorIndex) - actorContainerSize -= 1 - i-- // array removed 1 elem, so we also decrement counter by 1 - } - i++ - } - } - - /** - * Update actors concurrently. - * - * NOTE: concurrency for actor updating is currently disabled because of it's poor performance - */ - fun updateActors(delta: Float) { - if (false) { // don't multithread this for now, it's SLOWER //if (Terrarum.MULTITHREAD && actorContainer.size > Terrarum.THREADS) { - val actors = actorContainer.size.toFloat() - // set up indices - for (i in 0..Terrarum.THREADS - 1) { - ThreadParallel.map( - i, - ThreadActorUpdate( - actors.div(Terrarum.THREADS).times(i).roundToInt(), - actors.div(Terrarum.THREADS).times(i.plus(1)).roundToInt() - 1 - ), - "ActorUpdate" - ) - } - - ThreadParallel.startAll() - - playableActorDelegate?.update(delta) - } - else { - actorContainer.forEach { - if (it != playableActorDelegate?.actor) { - it.update(delta) - - if (it is Pocketed) { - it.inventory.forEach { inventoryEntry -> - inventoryEntry.item.effectWhileInPocket(delta) - if (it.equipped(inventoryEntry.item)) { - inventoryEntry.item.effectWhenEquipped(delta) - } - } - } - } - } - playableActorDelegate?.update(delta) - //AmmoMeterProxy(player, uiVitalItem.UI as UIVitalMetre) - } - } - - fun Double.sqr() = this * this - fun Int.sqr() = this * this - fun min(vararg d: Double): Double { - var ret = Double.MAX_VALUE - d.forEach { if (it < ret) ret = it } - return ret - } - private fun distToActorSqr(a: ActorWithBody, p: ActorWithBody) = - min(// take min of normal position and wrapped (x < 0) position - (a.hitbox.centeredX - p.hitbox.centeredX).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), - (a.hitbox.centeredX - p.hitbox.centeredX + world.width * TILE_SIZE).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), - (a.hitbox.centeredX - p.hitbox.centeredX - world.width * TILE_SIZE).sqr() + - (a.hitbox.centeredY - p.hitbox.centeredY).sqr() - ) - private fun distToCameraSqr(a: ActorWithBody) = - min( - (a.hitbox.startX - WorldCamera.x).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr(), - (a.hitbox.startX - WorldCamera.x + world.width * TILE_SIZE).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr(), - (a.hitbox.startX - WorldCamera.x - world.width * TILE_SIZE).sqr() + - (a.hitbox.startY - WorldCamera.y).sqr() - ) - - /** whether the actor is within screen */ - private fun ActorWithBody.inScreen() = - distToCameraSqr(this) <= - (AppLoader.screenW.plus(this.hitbox.width.div(2)). - times(1 / screenZoom).sqr() + - AppLoader.screenH.plus(this.hitbox.height.div(2)). - times(1 / screenZoom).sqr()) - - - /** whether the actor is within update range */ - private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr() - - override fun removeActor(ID: Int) = removeActor(getActorByID(ID)) - /** - * get index of the actor and delete by the index. - * we can do this as the list is guaranteed to be sorted - * and only contains unique values. - * - * Any values behind the index will be automatically pushed to front. - * This is how remove function of [java.util.ArrayList] is defined. - */ - override fun removeActor(actor: Actor) { - if (actor.referenceID == player.referenceID || actor.referenceID == 0x51621D) // do not delete this magic - throw RuntimeException("Attempted to remove player.") - val indexToDelete = actorContainer.binarySearch(actor.referenceID!!) - if (indexToDelete >= 0) { - actorContainer.removeAt(indexToDelete) - - // indexToDelete >= 0 means that the actor certainly exists in the game - // which means we don't need to check if i >= 0 again - if (actor is ActorWithBody) { - when (actor.renderOrder) { - Actor.RenderOrder.BEHIND -> { - val i = actorsRenderBehind.binarySearch(actor.referenceID!!) - actorsRenderBehind.removeAt(i) - } - Actor.RenderOrder.MIDDLE -> { - val i = actorsRenderMiddle.binarySearch(actor.referenceID!!) - actorsRenderMiddle.removeAt(i) - } - Actor.RenderOrder.MIDTOP -> { - val i = actorsRenderMidTop.binarySearch(actor.referenceID!!) - actorsRenderMidTop.removeAt(i) - } - Actor.RenderOrder.FRONT -> { - val i = actorsRenderFront.binarySearch(actor.referenceID!!) - actorsRenderFront.removeAt(i) - } - } - } - } - } - - /** - * Check for duplicates, append actor and sort the list - */ - override fun addNewActor(actor: Actor) { - if (theGameHasActor(actor.referenceID!!)) { - throw Error("The actor $actor already exists in the game") - } - else { - actorContainer.add(actor) - insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor - - if (actor is ActorWithBody) { - when (actor.renderOrder) { - Actor.RenderOrder.BEHIND -> { - actorsRenderBehind.add(actor); insertionSortLastElemAV(actorsRenderBehind) - } - Actor.RenderOrder.MIDDLE -> { - actorsRenderMiddle.add(actor); insertionSortLastElemAV(actorsRenderMiddle) - } - Actor.RenderOrder.MIDTOP -> { - actorsRenderMidTop.add(actor); insertionSortLastElemAV(actorsRenderMidTop) - } - Actor.RenderOrder.FRONT -> { - actorsRenderFront.add(actor); insertionSortLastElemAV(actorsRenderFront) - } - } - } - } - } - - fun activateDormantActor(actor: Actor) { - if (!isInactive(actor.referenceID!!)) { - if (isActive(actor.referenceID!!)) - throw Error("The actor $actor is already activated") - else - throw Error("The actor $actor already exists in the game") - } - else { - actorContainerInactive.remove(actor) - actorContainer.add(actor) - insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor - - if (actor is ActorWithBody) { - when (actor.renderOrder) { - Actor.RenderOrder.BEHIND -> { - actorsRenderBehind.add(actor); insertionSortLastElemAV(actorsRenderBehind) - } - Actor.RenderOrder.MIDDLE -> { - actorsRenderMiddle.add(actor); insertionSortLastElemAV(actorsRenderMiddle) - } - Actor.RenderOrder.MIDTOP -> { - actorsRenderMidTop.add(actor); insertionSortLastElemAV(actorsRenderMidTop) - } - Actor.RenderOrder.FRONT -> { - actorsRenderFront.add(actor); insertionSortLastElemAV(actorsRenderFront) - } - } - } - } - } - - fun addParticle(particle: ParticleBase) { - particlesContainer.add(particle) - } - - fun addUI(ui: UICanvas) { - // check for exact duplicates - if (uiContainer.contains(ui)) { - throw IllegalArgumentException( - "Exact copy of the UI already exists: The instance of ${ui.javaClass.simpleName}" - ) - } - - uiContainer.add(ui) - } - - private fun insertionSortLastElemAV(arr: ArrayList) { // out-projection doesn't work, duh - lock(ReentrantLock()) { - var j = arr.lastIndex - 1 - val x = arr.last() - while (j >= 0 && arr[j] > x) { - arr[j + 1] = arr[j] - j -= 1 - } - arr[j + 1] = x - } - } - - fun setTooltipMessage(message: String?) { - if (message == null) { - uiTooltip.setAsClose() - } - else { - if (uiTooltip.isClosed || uiTooltip.isClosing) { - uiTooltip.setAsOpen() - } - uiTooltip.message = message - } - } - - override fun pause() { - // TODO no pause when off-focus on desktop - } - - override fun resume() { - } - - override fun hide() { - dispose() - } - - - - private var lightmapInitialised = false // to avoid nullability of lightmapFBO - - /** - * @param width same as AppLoader.screenW - * @param height same as AppLoader.screenH - * @see net.torvald.terrarum.Terrarum - */ - override fun resize(width: Int, height: Int) { - - BlocksDrawer.resize(AppLoader.screenW, AppLoader.screenH) - LightmapRenderer.resize(AppLoader.screenW, AppLoader.screenH) - MegaRainGovernor.resize() - - worldDrawFrameBuffer.dispose() - worldDrawFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - worldGlowFrameBuffer.dispose() - worldGlowFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - worldBlendFrameBuffer.dispose() - worldBlendFrameBuffer = FrameBuffer(worldFBOformat, AppLoader.screenW, AppLoader.screenH, false) - - if (lightmapInitialised) { - lightmapFboA.dispose() - lightmapFboB.dispose() - } - lightmapFboA = FrameBuffer( - lightFBOformat, - LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - false - ) - lightmapFboB = FrameBuffer( - lightFBOformat, - LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt(), - false - ) - lightmapInitialised = true // are you the first time? - - - // Set up viewport when window is resized - initViewPort(AppLoader.screenW, AppLoader.screenH) - - - - if (gameInitialised) { - LightmapRenderer.fireRecalculateEvent() - } - - - if (gameFullyLoaded) { - // resize UIs - - notifier.setPosition( - (AppLoader.screenW - notifier.width) / 2, AppLoader.screenH - notifier.height) - - // inventory - /*uiInventoryPlayer = - UIInventory(player, - width = 840, - height = AppLoader.screenH - 160, - categoryWidth = 210 - )*/ - - - // basic watch-style notification bar (temperature, new mail) - uiWatchBasic.setPosition(AppLoader.screenW - uiWatchBasic.width, 0) - uiWatchTierOne.setPosition(AppLoader.screenW - uiWatchTierOne.width, uiWatchBasic.height - 2) - } - - - println("[Ingame] Resize event") - } - - override fun dispose() { - worldDrawFrameBuffer.dispose() - worldGlowFrameBuffer.dispose() - worldBlendFrameBuffer.dispose() - lightmapFboA.dispose() - lightmapFboB.dispose() - - actorsRenderBehind.forEach { it.dispose() } - actorsRenderMiddle.forEach { it.dispose() } - actorsRenderMidTop.forEach { it.dispose() } - actorsRenderFront.forEach { it.dispose() } - - uiAliases.forEach { it.dispose() } - uiAlasesPausing.forEach { it.dispose() } - - - WatchDotAlph.dispose() - Watch7SegMain.dispose() - WatchDotAlph.dispose() - - ItemSlotImageBuilder.dispose() - - MessageWindow.SEGMENT_BLACK.dispose() - MessageWindow.SEGMENT_WHITE.dispose() - } - - - /** - * WARNING! this function flushes batch; use this sparingly! - * - * Camera will be moved so that (newX, newY) would be sit on the top-left edge. - */ - fun setCameraPosition(newX: Float, newY: Float) { - setCameraPosition(batch, camera, newX, newY) - } - - -} diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 853ae409f..660921fb6 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -152,6 +152,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { init { + particlesContainer.overwritingPolicy = { + it.dispose() + } } @@ -1300,10 +1303,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { IngameRenderer.resize(App.scr.width, App.scr.height) val drawWidth = Toolkit.drawWidth - if (gameInitialised) { - //LightmapRenderer.fireRecalculateEvent() - } - if (gameFullyLoaded) { // resize UIs diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayableActorDelegate.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayableActorDelegate.kt deleted file mode 100644 index aab3763db..000000000 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayableActorDelegate.kt +++ /dev/null @@ -1,30 +0,0 @@ -package net.torvald.terrarum.modulebasegame.gameactors - -/** - * A wrapper to support instant player changing (or possessing other NPCs maybe) - * - * @param actor : here you 'attach' the actor you wish to control - * Created by minjaesong on 2016-10-23. - */ -@Deprecated("The ingame should discriminate 'theRealGamer' and 'actorNowPlaying'") -class PlayableActorDelegate(@Transient val actor: ActorHumanoid) { - - /*init { - if (actor !is Controllable) - throw IllegalArgumentException("Player must be 'Controllable'!") - } - - - fun update(delta: Float) { - //val oldTilewisePos = actor.hIntTilewiseHitbox - - actor.update(delta) - - // fire lightmap recalculate event upon tilewise pos change - //val newTilewisePos = actor.hIntTilewiseHitbox - //if (oldTilewisePos != newTilewisePos) { - // LightmapRenderer.fireRecalculateEvent() - //} - // not going to work: think about stationery tiki torches, global lights, etc - }*/ -} \ No newline at end of file