mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-09 18:14:06 +09:00
new collision displacer: got one-block-ceiling-passthru bug, but otherwise tolerable
This commit is contained in:
@@ -2,10 +2,13 @@ varying vec4 v_color;
|
|||||||
varying vec2 v_texCoords;
|
varying vec2 v_texCoords;
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 color = texture2D(u_texture, v_texCoords);
|
vec4 color = texture2D(u_texture, v_texCoords).rgba;
|
||||||
color = floor(15.0 * color + 0.5) / 15.0;
|
|
||||||
|
color.r = floor(15.0 * color.r + 0.5) / 15.0;
|
||||||
|
color.g = floor(15.0 * color.g + 0.5) / 15.0;
|
||||||
|
color.b = floor(15.0 * color.b + 0.5) / 15.0;
|
||||||
|
// a: passthrough
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
59
assets/4096_bayer.frag
Normal file
59
assets/4096_bayer.frag
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uniform mat4 Bayer;
|
||||||
|
uniform float monitorGamma;
|
||||||
|
|
||||||
|
vec4 gammaIn(vec4 col) {
|
||||||
|
return pow(col, vec4(vec3(monitorGamma), 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 gammaOut(vec4 col) {
|
||||||
|
return pow(col, vec4(vec3(1.0 / monitorGamma), 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// create texture coordinates based on pixelSize //
|
||||||
|
float pixelSize = 1.0;
|
||||||
|
|
||||||
|
vec2 pixelSizeVec = vec2(float(pixelSize), float(pixelSize));
|
||||||
|
|
||||||
|
vec2 discrete = (gl_FragCoord.xy + 0.001) / v_texCoords / pixelSizeVec;
|
||||||
|
//vec2 discrete = (gl_FragCoord.xy) / v_texCoords / pixelSizeVec;
|
||||||
|
|
||||||
|
discrete = floor(discrete * v_texCoords) / discrete;
|
||||||
|
|
||||||
|
vec4 color = texture2D(u_texture, discrete).rgba;
|
||||||
|
|
||||||
|
|
||||||
|
// add Bayer matrix entry to current pixel //
|
||||||
|
vec2 entry = mod(gl_FragCoord.xy / pixelSizeVec, vec2(4, 4));
|
||||||
|
|
||||||
|
color.r = color.r + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
|
||||||
|
color.g = color.g + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
|
||||||
|
color.b = color.b + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
|
||||||
|
//color.a = color.a + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
|
||||||
|
|
||||||
|
|
||||||
|
// find nearest 8-bit color //
|
||||||
|
color.r = floor(15.0 * color.r + 0.5) / 15.0;
|
||||||
|
color.g = floor(15.0 * color.g + 0.5) / 15.0;
|
||||||
|
color.b = floor(15.0 * color.b + 0.5) / 15.0;
|
||||||
|
//color.a = floor(15.0 * color.a + 0.5) / 15.0;
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//vec4 color = texture2D(u_texture, v_texCoords);
|
||||||
|
//color = floor(15.0 * color + 0.5) / 15.0;
|
||||||
|
//
|
||||||
|
//gl_FragColor = color;
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_texCoords;
|
varying vec2 v_texCoords;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.badlogic.gdx.graphics.GL20
|
|||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
|
import com.badlogic.gdx.math.Matrix4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-07-05.
|
* Created by minjaesong on 2017-07-05.
|
||||||
@@ -37,6 +38,11 @@ object ColorLimiterTest : ApplicationAdapter() {
|
|||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
|
|
||||||
shader4096 = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096.frag"))
|
shader4096 = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096.frag"))
|
||||||
|
shader4096.begin()
|
||||||
|
//shader4096.setUniformMatrix("Bayer", Matrix4(floatArrayOf(0f,8f,2f,10f,12f,4f,14f,6f,3f,11f,1f,9f,15f,7f,13f,5f)))
|
||||||
|
shader4096.end()
|
||||||
|
|
||||||
|
|
||||||
img = Texture("assets/test_texture.tga")
|
img = Texture("assets/test_texture.tga")
|
||||||
|
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
@@ -51,7 +57,7 @@ object ColorLimiterTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = shader4096
|
batch.shader = shader4096
|
||||||
//batch.shader.setUniformf("iResolution", Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())
|
//batch.shader.setUniformf("monitorGamma", 2.2f)
|
||||||
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
batch.draw(img, 0f, 0f)
|
batch.draw(img, 0f, 0f)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
private val ACTOR_UPDATE_RANGE = 4096
|
private val ACTOR_UPDATE_RANGE = 4096
|
||||||
|
|
||||||
lateinit var world: GameWorld
|
lateinit var world: GameWorld
|
||||||
|
lateinit var historicalFigureIDBucket: ArrayList<Int>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list of Actors that is sorted by Actors' referenceID
|
* list of Actors that is sorted by Actors' referenceID
|
||||||
@@ -76,9 +77,19 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
val lightmapDownsample = 1f
|
val lightmapDownsample = 1f
|
||||||
}
|
}
|
||||||
|
|
||||||
var worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT, true)
|
|
||||||
var lightmapFboA = FrameBuffer(Pixmap.Format.RGBA8888, TerrarumGDX.WIDTH.div(lightmapDownsample.toInt()), TerrarumGDX.HEIGHT.div(lightmapDownsample.toInt()), true)
|
private val worldFBOformat = Pixmap.Format.RGBA4444 // just a future-proof for mobile
|
||||||
var lightmapFboB = FrameBuffer(Pixmap.Format.RGBA8888, TerrarumGDX.WIDTH.div(lightmapDownsample.toInt()), TerrarumGDX.HEIGHT.div(lightmapDownsample.toInt()), true)
|
private val lightFBOformat = Pixmap.Format.RGBA8888
|
||||||
|
|
||||||
|
var worldDrawFrameBuffer = FrameBuffer(worldFBOformat, TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT, true)
|
||||||
|
var lightmapFboA = FrameBuffer(lightFBOformat, TerrarumGDX.WIDTH.div(lightmapDownsample.toInt()), TerrarumGDX.HEIGHT.div(lightmapDownsample.toInt()), true)
|
||||||
|
var lightmapFboB = FrameBuffer(lightFBOformat, TerrarumGDX.WIDTH.div(lightmapDownsample.toInt()), TerrarumGDX.HEIGHT.div(lightmapDownsample.toInt()), true)
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
println("worldDrawFrameBuffer.colorBufferTexture.textureData.format: ${worldDrawFrameBuffer.colorBufferTexture.textureData.format}")
|
||||||
|
println("lightmapFboB.colorBufferTexture.textureData.format: ${lightmapFboB.colorBufferTexture.textureData.format}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader
|
//private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader
|
||||||
@@ -152,15 +163,28 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
initViewPort(TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT)
|
initViewPort(TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class GameSaveData(
|
||||||
|
val world: GameWorld,
|
||||||
|
val historicalFigureIDBucket: ArrayList<Int>,
|
||||||
|
val realGamePlayer: ActorHumanoid
|
||||||
|
)
|
||||||
|
|
||||||
|
fun enter(gameSaveData: GameSaveData) {
|
||||||
|
world = gameSaveData.world
|
||||||
|
historicalFigureIDBucket = gameSaveData.historicalFigureIDBucket
|
||||||
|
playableActorDelegate = PlayableActorDelegate(gameSaveData.realGamePlayer)
|
||||||
|
addNewActor(player!!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initGame()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new world
|
||||||
|
*/
|
||||||
fun enter() {
|
fun enter() {
|
||||||
|
|
||||||
Gdx.input.inputProcessor = GameController
|
|
||||||
|
|
||||||
|
|
||||||
initViewPort(TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT)
|
|
||||||
|
|
||||||
|
|
||||||
// load things when the game entered this "state"
|
// load things when the game entered this "state"
|
||||||
// load necessary shaders
|
// load necessary shaders
|
||||||
//shader12BitCol = Shader.makeShader("./assets/4096.vert", "./assets/4096.frag")
|
//shader12BitCol = Shader.makeShader("./assets/4096.vert", "./assets/4096.frag")
|
||||||
@@ -176,6 +200,9 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
WorldGenerator.generateMap()
|
WorldGenerator.generateMap()
|
||||||
|
|
||||||
|
|
||||||
|
historicalFigureIDBucket = ArrayList<Int>()
|
||||||
|
|
||||||
|
|
||||||
RoguelikeRandomiser.seed = HQRNG().nextLong()
|
RoguelikeRandomiser.seed = HQRNG().nextLong()
|
||||||
|
|
||||||
|
|
||||||
@@ -190,6 +217,17 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initGame()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initGame() {
|
||||||
|
|
||||||
|
Gdx.input.inputProcessor = GameController
|
||||||
|
|
||||||
|
|
||||||
|
initViewPort(TerrarumGDX.WIDTH, TerrarumGDX.HEIGHT)
|
||||||
|
|
||||||
|
|
||||||
// init console window
|
// init console window
|
||||||
consoleHandler = UIHandler(ConsoleWindow())
|
consoleHandler = UIHandler(ConsoleWindow())
|
||||||
consoleHandler.setPosition(0, 0)
|
consoleHandler.setPosition(0, 0)
|
||||||
@@ -391,7 +429,7 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
///////////////////
|
///////////////////
|
||||||
// blur lightmap //
|
// blur lightmap //
|
||||||
///////////////////
|
///////////////////
|
||||||
val blurIterations = 3 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image
|
val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image
|
||||||
val blurRadius = 4f / lightmapDownsample // (3, 4f); using low numbers for pixel-y aesthetics
|
val blurRadius = 4f / lightmapDownsample // (3, 4f); using low numbers for pixel-y aesthetics
|
||||||
|
|
||||||
|
|
||||||
@@ -401,7 +439,7 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
lightmapFboA.inAction(null, null) {
|
lightmapFboB.inAction(null, null) {
|
||||||
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
Gdx.gl.glClearColor(0f, 0f, 0f, 0f)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
@@ -423,7 +461,11 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
blurReadBuffer.inAction(camera, batch) {
|
blurReadBuffer.inAction(camera, batch) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
// using custom code for camera; this is obscure and tricky
|
// using custom code for camera; this is obscure and tricky
|
||||||
camera.position.set((WorldCamera.gdxCamX / lightmapDownsample).round(), (WorldCamera.gdxCamY / lightmapDownsample).round(), 0f) // make camara work
|
camera.position.set(
|
||||||
|
(WorldCamera.gdxCamX / lightmapDownsample).round(),
|
||||||
|
(WorldCamera.gdxCamY / lightmapDownsample).round(),
|
||||||
|
0f
|
||||||
|
) // make camara work
|
||||||
camera.update()
|
camera.update()
|
||||||
batch.projectionMatrix = camera.combined
|
batch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
@@ -445,7 +487,8 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
|
|
||||||
batch.shader = TerrarumGDX.shaderBlur
|
batch.shader = TerrarumGDX.shaderBlur
|
||||||
batch.shader.setUniformf("iResolution", blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat())
|
batch.shader.setUniformf("iResolution",
|
||||||
|
blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat())
|
||||||
batch.shader.setUniformf("flip", 1f)
|
batch.shader.setUniformf("flip", 1f)
|
||||||
if (i % 2 == 0)
|
if (i % 2 == 0)
|
||||||
batch.shader.setUniformf("direction", blurRadius, 0f)
|
batch.shader.setUniformf("direction", blurRadius, 0f)
|
||||||
@@ -480,7 +523,6 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
|
|
||||||
|
|
||||||
// using custom code for camera; this is obscure and tricky
|
// using custom code for camera; this is obscure and tricky
|
||||||
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||||
camera.update()
|
camera.update()
|
||||||
@@ -519,16 +561,26 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
// mix lighpmap canvas to this canvas
|
// mix lighpmap canvas to this canvas
|
||||||
if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw
|
if (!KeyToggler.isOn(Input.Keys.F6)) { // F6 to disable lightmap draw
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
|
batch.shader = null
|
||||||
|
|
||||||
val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom!
|
val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom!
|
||||||
|
|
||||||
lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
lightTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||||
|
|
||||||
if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal()
|
if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal()
|
||||||
else blendMul()
|
else blendMul()
|
||||||
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
batch.draw(lightTex, 0f, 0f, lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample)
|
batch.draw(lightTex,
|
||||||
|
0f, 0f,
|
||||||
|
lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
batch.shader = null
|
||||||
|
|
||||||
|
|
||||||
// move camera back to its former position
|
// move camera back to its former position
|
||||||
// using custom code for camera; this is obscure and tricky
|
// using custom code for camera; this is obscure and tricky
|
||||||
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
camera.position.set(WorldCamera.gdxCamX, WorldCamera.gdxCamY, 0f) // make camara work
|
||||||
@@ -567,9 +619,11 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
// draw framebuffers to screen //
|
// draw framebuffers to screen //
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
WeatherMixer.render(batch)
|
WeatherMixer.render(batch)
|
||||||
|
|
||||||
|
batch.flush()
|
||||||
|
|
||||||
|
batch.shader = null
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
val worldTex = worldDrawFrameBuffer.colorBufferTexture // TODO zoom!
|
val worldTex = worldDrawFrameBuffer.colorBufferTexture // TODO zoom!
|
||||||
worldTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
worldTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
||||||
@@ -577,6 +631,8 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
batch.shader = null
|
||||||
|
|
||||||
batch.color = Color.RED
|
batch.color = Color.RED
|
||||||
batch.fillRect(0f, 0f, 16f, 16f)
|
batch.fillRect(0f, 0f, 16f, 16f)
|
||||||
|
|
||||||
@@ -640,7 +696,7 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// draw some overlays (UI) //
|
// draw some overlays (UI) //
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
uiContainer.forEach { if (it != consoleHandler) it.render(batch) } // FIXME draws black of grey coloured box on top right
|
uiContainer.forEach { if (it != consoleHandler) it.render(batch) }
|
||||||
|
|
||||||
debugWindow.render(batch)
|
debugWindow.render(batch)
|
||||||
// make sure console draws on top of other UIs
|
// make sure console draws on top of other UIs
|
||||||
@@ -842,7 +898,9 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
// TODO prevent possessing other player on multiplayer
|
// TODO prevent possessing other player on multiplayer
|
||||||
|
|
||||||
if (!theGameHasActor(refid)) {
|
if (!theGameHasActor(refid)) {
|
||||||
throw IllegalArgumentException("No such actor in the game: $refid (elemsActive: ${actorContainer.size}, elemsInactive: ${actorContainerInactive.size})")
|
throw IllegalArgumentException(
|
||||||
|
"No such actor in the game: $refid (elemsActive: ${actorContainer.size}, " +
|
||||||
|
"elemsInactive: ${actorContainerInactive.size})")
|
||||||
}
|
}
|
||||||
|
|
||||||
// take care of old delegate
|
// take care of old delegate
|
||||||
@@ -975,8 +1033,10 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
/** whether the actor is within screen */
|
/** whether the actor is within screen */
|
||||||
private fun ActorWithBody.inScreen() =
|
private fun ActorWithBody.inScreen() =
|
||||||
distToCameraSqr(this) <=
|
distToCameraSqr(this) <=
|
||||||
(TerrarumGDX.WIDTH.plus(this.hitbox.width.div(2)).times(1 / TerrarumGDX.ingame!!.screenZoom).sqr() +
|
(TerrarumGDX.WIDTH.plus(this.hitbox.width.div(2)).
|
||||||
TerrarumGDX.HEIGHT.plus(this.hitbox.height.div(2)).times(1 / TerrarumGDX.ingame!!.screenZoom).sqr())
|
times(1 / TerrarumGDX.ingame!!.screenZoom).sqr() +
|
||||||
|
TerrarumGDX.HEIGHT.plus(this.hitbox.height.div(2)).
|
||||||
|
times(1 / TerrarumGDX.ingame!!.screenZoom).sqr())
|
||||||
|
|
||||||
|
|
||||||
/** whether the actor is within update range */
|
/** whether the actor is within update range */
|
||||||
@@ -1111,7 +1171,9 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
fun addUI(ui: UIHandler) {
|
fun addUI(ui: UIHandler) {
|
||||||
// check for exact duplicates
|
// check for exact duplicates
|
||||||
if (uiContainer.contains(ui)) {
|
if (uiContainer.contains(ui)) {
|
||||||
throw IllegalArgumentException("Exact copy of the UI already exists: The instance of ${ui.UI.javaClass.simpleName}")
|
throw IllegalArgumentException(
|
||||||
|
"Exact copy of the UI already exists: The instance of ${ui.UI.javaClass.simpleName}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
uiContainer.add(ui)
|
uiContainer.add(ui)
|
||||||
@@ -1126,7 +1188,11 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
index = actorContainerInactive.binarySearch(ID)
|
index = actorContainerInactive.binarySearch(ID)
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
JOptionPane.showMessageDialog(null, "Actor with ID $ID does not exist.", null, JOptionPane.ERROR_MESSAGE)
|
JOptionPane.showMessageDialog(
|
||||||
|
null,
|
||||||
|
"Actor with ID $ID does not exist.",
|
||||||
|
null, JOptionPane.ERROR_MESSAGE
|
||||||
|
)
|
||||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1203,11 +1269,11 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
worldDrawFrameBuffer.dispose()
|
worldDrawFrameBuffer.dispose()
|
||||||
worldDrawFrameBuffer = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true)
|
worldDrawFrameBuffer = FrameBuffer(worldFBOformat, width, height, true)
|
||||||
lightmapFboA.dispose()
|
lightmapFboA.dispose()
|
||||||
lightmapFboA = FrameBuffer(Pixmap.Format.RGBA8888, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
lightmapFboA = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
||||||
lightmapFboB.dispose()
|
lightmapFboB.dispose()
|
||||||
lightmapFboB = FrameBuffer(Pixmap.Format.RGBA8888, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
lightmapFboB = FrameBuffer(lightFBOformat, width.div(lightmapDownsample.toInt()), height.div(lightmapDownsample.toInt()), true)
|
||||||
|
|
||||||
|
|
||||||
// Set up viewport when window is resized
|
// Set up viewport when window is resized
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
|
import com.badlogic.gdx.math.Matrix4
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonPrimitive
|
import com.google.gson.JsonPrimitive
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
@@ -50,7 +51,6 @@ fun main(args: Array<String>) {
|
|||||||
config.height = 742
|
config.height = 742
|
||||||
config.backgroundFPS = 9999
|
config.backgroundFPS = 9999
|
||||||
config.foregroundFPS = 9999
|
config.foregroundFPS = 9999
|
||||||
//config.useGL30 = true
|
|
||||||
config.title = GAME_NAME
|
config.title = GAME_NAME
|
||||||
|
|
||||||
LwjglApplication(TerrarumGDX, config)
|
LwjglApplication(TerrarumGDX, config)
|
||||||
@@ -242,6 +242,8 @@ object TerrarumGDX : ApplicationAdapter() {
|
|||||||
|
|
||||||
|
|
||||||
lateinit var shaderBlur: ShaderProgram
|
lateinit var shaderBlur: ShaderProgram
|
||||||
|
lateinit var shader4096: ShaderProgram
|
||||||
|
lateinit var shader4096Bayer: ShaderProgram
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -301,6 +303,14 @@ object TerrarumGDX : ApplicationAdapter() {
|
|||||||
|
|
||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
shaderBlur = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
shaderBlur = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
||||||
|
shader4096 = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096.frag"))
|
||||||
|
shader4096Bayer = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096_bayer.frag"))
|
||||||
|
|
||||||
|
shader4096Bayer.begin()
|
||||||
|
shader4096Bayer.setUniformMatrix("Bayer", Matrix4(floatArrayOf(0f,8f,2f,10f,12f,4f,14f,6f,3f,11f,1f,9f,15f,7f,13f,5f)))
|
||||||
|
shader4096Bayer.setUniformf("monitorGamma", 2.2f)
|
||||||
|
shader4096Bayer.end()
|
||||||
|
|
||||||
|
|
||||||
ModMgr // invoke Module Manager, will also invoke BlockCodex
|
ModMgr // invoke Module Manager, will also invoke BlockCodex
|
||||||
ItemCodex // invoke Item Codex
|
ItemCodex // invoke Item Codex
|
||||||
|
|||||||
@@ -196,15 +196,6 @@ object TestTestMain : ApplicationAdapter() {
|
|||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
blurShader = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
blurShader = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag"))
|
||||||
|
|
||||||
// culprit #4
|
|
||||||
blurShader.begin()
|
|
||||||
blurShader.setUniformf("dir", 0f, 0f); //direction of blur; nil for now
|
|
||||||
blurShader.setUniformf("resolution", maxOf(TerrarumGDX.WIDTH.toFloat(), TerrarumGDX.HEIGHT.toFloat())) //size of FBO texture
|
|
||||||
blurShader.setUniformf("radius", 9f) //radius of blur
|
|
||||||
blurShader.end()
|
|
||||||
|
|
||||||
Gdx.graphics.isContinuousRendering = true // culprit #3
|
|
||||||
|
|
||||||
|
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
*/
|
*/
|
||||||
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
||||||
|
|
||||||
inline val tilewiseHitbox: Hitbox
|
val tilewiseHitbox: Hitbox
|
||||||
get() = Hitbox.fromTwoPoints(
|
get() = Hitbox.fromTwoPoints(
|
||||||
hitbox.startX.div(TILE_SIZE).floor(),
|
hitbox.startX.div(TILE_SIZE).floor(),
|
||||||
hitbox.startY.div(TILE_SIZE).floor(),
|
hitbox.startY.div(TILE_SIZE).floor(),
|
||||||
@@ -104,7 +104,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
@Transient val MASS_LOWEST = 0.1 // Kilograms
|
@Transient val MASS_LOWEST = 0.1 // Kilograms
|
||||||
/** Apparent mass. Use "avBaseMass" for base mass */
|
/** Apparent mass. Use "avBaseMass" for base mass */
|
||||||
inline val mass: Double
|
val mass: Double
|
||||||
get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT * Math.pow(scale, 3.0)
|
get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT * Math.pow(scale, 3.0)
|
||||||
/*set(value) { // use "var avBaseMass: Double"
|
/*set(value) { // use "var avBaseMass: Double"
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
@@ -185,7 +185,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
@Transient private val gravitation: Vector2 = world.gravitation
|
@Transient private val gravitation: Vector2 = world.gravitation
|
||||||
@Transient val DRAG_COEFF_DEFAULT = 1.2
|
@Transient val DRAG_COEFF_DEFAULT = 1.2
|
||||||
/** Drag coefficient. Parachutes have much higher value than bare body (1.2) */
|
/** Drag coefficient. Parachutes have much higher value than bare body (1.2) */
|
||||||
inline var dragCoefficient: Double
|
var dragCoefficient: Double
|
||||||
get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT
|
get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
@@ -541,7 +541,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
fun debug1(wut: Any?) {
|
fun debug1(wut: Any?) {
|
||||||
// vvvvv set it true to make debug print work
|
// vvvvv set it true to make debug print work
|
||||||
if (false) println(wut)
|
if (true) println(wut)
|
||||||
}
|
}
|
||||||
fun debug2(wut: Any?) {
|
fun debug2(wut: Any?) {
|
||||||
// vvvvv set it true to make debug print work
|
// vvvvv set it true to make debug print work
|
||||||
@@ -622,10 +622,10 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
val newHitbox = hitbox.reassign(sixteenStep[collidingStep])
|
val newHitbox = hitbox.reassign(sixteenStep[collidingStep])
|
||||||
|
|
||||||
var selfCollisionStatus = 0
|
var selfCollisionStatus = 0
|
||||||
if (isWalled(newHitbox, COLLIDING_LEFT)) selfCollisionStatus += COLL_LEFTSIDE
|
if (isWalled(newHitbox, COLLIDING_LEFT)) selfCollisionStatus += COLL_LEFTSIDE // 1
|
||||||
if (isWalled(newHitbox, COLLIDING_RIGHT)) selfCollisionStatus += COLL_RIGHTSIDE
|
if (isWalled(newHitbox, COLLIDING_RIGHT)) selfCollisionStatus += COLL_RIGHTSIDE // 4
|
||||||
if (isWalled(newHitbox, COLLIDING_TOP)) selfCollisionStatus += COLL_TOPSIDE
|
if (isWalled(newHitbox, COLLIDING_TOP)) selfCollisionStatus += COLL_TOPSIDE // 8
|
||||||
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE
|
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE // 2
|
||||||
|
|
||||||
// fixme UP and RIGHT && LEFT and DOWN bug
|
// fixme UP and RIGHT && LEFT and DOWN bug
|
||||||
|
|
||||||
@@ -645,34 +645,81 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
4, 14 -> { newHitbox.translatePosX( - newHitbox.endX.modTileDelta()) ; bounceX = true }
|
4, 14 -> { newHitbox.translatePosX( - newHitbox.endX.modTileDelta()) ; bounceX = true }
|
||||||
8, 13 -> { newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta()); bounceY = true }
|
8, 13 -> { newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta()); bounceY = true }
|
||||||
2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true }
|
2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true }
|
||||||
// two-side collision
|
|
||||||
3 -> {
|
|
||||||
debug1("translateX: ${(TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE)}")
|
|
||||||
newHitbox.translatePosX((TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE))
|
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
|
||||||
bounceX = true; bounceY = true
|
|
||||||
}
|
|
||||||
6 -> {
|
|
||||||
debug1("translateX: ${( - newHitbox.endX.modTileDelta())}")
|
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
|
||||||
bounceX = true; bounceY = true
|
|
||||||
}
|
|
||||||
9 -> {
|
|
||||||
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta())
|
|
||||||
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta())
|
|
||||||
bounceX = true; bounceY = true
|
|
||||||
}
|
|
||||||
12 -> {
|
|
||||||
debug1("translateY: ${(TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE)}")
|
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
|
||||||
newHitbox.translatePosY((TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE))
|
|
||||||
bounceX = true; bounceY = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// two-side collision
|
||||||
if (selfCollisionStatus in listOf(3,6,9,12)) {
|
if (selfCollisionStatus in listOf(3,6,9,12)) {
|
||||||
debug1("twoside collision $selfCollisionStatus")
|
debug1("twoside collision $selfCollisionStatus")
|
||||||
|
|
||||||
|
// !! this code is based on Dyn4j Vector's coord system; V(1,0) -> 0, V(0,1) -> pi, V(0,-1) -> -pi !! //
|
||||||
|
|
||||||
|
// we can use selfCollisionStatus to tell which of those four side we care
|
||||||
|
|
||||||
|
// points to the EDGE of the tile in world dimension (don't use this directly to get tilewise coord!!)
|
||||||
|
val offendingTileWorldX = if (selfCollisionStatus in listOf(6, 12))
|
||||||
|
newHitbox.endX.div(TILE_SIZE).floor() * TILE_SIZE
|
||||||
|
else
|
||||||
|
newHitbox.startX.div(TILE_SIZE).ceil() * TILE_SIZE
|
||||||
|
|
||||||
|
// points to the EDGE of the tile in world dimension (don't use this directly to get tilewise coord!!)
|
||||||
|
val offendingTileWorldY = if (selfCollisionStatus in listOf(3, 6))
|
||||||
|
newHitbox.endY.div(TILE_SIZE).floor() * TILE_SIZE
|
||||||
|
else
|
||||||
|
newHitbox.startY.div(TILE_SIZE).ceil() * TILE_SIZE
|
||||||
|
|
||||||
|
val offendingHitboxPointX = if (selfCollisionStatus in listOf(6, 12))
|
||||||
|
newHitbox.endX
|
||||||
|
else
|
||||||
|
newHitbox.startX
|
||||||
|
|
||||||
|
val offendingHitboxPointY = if (selfCollisionStatus in listOf(3, 6))
|
||||||
|
newHitbox.endY
|
||||||
|
else
|
||||||
|
newHitbox.startY
|
||||||
|
|
||||||
|
val angleOfIncidence = vectorSum.direction.toPositiveRad()
|
||||||
|
val angleThreshold = (Vector2(offendingHitboxPointX, offendingHitboxPointY) -
|
||||||
|
Vector2(offendingTileWorldX, offendingTileWorldY)).direction.toPositiveRad()
|
||||||
|
|
||||||
|
|
||||||
|
val displacementAbs = Vector2(
|
||||||
|
(offendingTileWorldX - offendingHitboxPointX).abs(),
|
||||||
|
(offendingTileWorldY - offendingHitboxPointY).abs()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// conditions should be four? for 4 corners?
|
||||||
|
// or mathe works regardless?
|
||||||
|
// (need to account for I < TH; I > TH; I == TH)
|
||||||
|
|
||||||
|
val displacementUnitVector =
|
||||||
|
if (angleOfIncidence == angleThreshold)
|
||||||
|
-vectorSum
|
||||||
|
else {
|
||||||
|
when (selfCollisionStatus) {
|
||||||
|
3 -> if (angleOfIncidence > angleThreshold) Vector2(1.0, 0.0) else Vector2(0.0, -1.0)
|
||||||
|
6 -> if (angleOfIncidence > angleThreshold) Vector2(0.0, -1.0) else Vector2(-1.0, 0.0)
|
||||||
|
9 -> if (angleOfIncidence > angleThreshold) Vector2(0.0, 1.0) else Vector2(1.0, 0.0)
|
||||||
|
12 -> if (angleOfIncidence > angleThreshold) Vector2(-1.0, 0.0) else Vector2(0.0, 1.0)
|
||||||
|
else -> throw InternalError("Blame hardware or universe")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val finalDisplacement =
|
||||||
|
if (angleOfIncidence == angleThreshold)
|
||||||
|
displacementUnitVector
|
||||||
|
else
|
||||||
|
Vector2(
|
||||||
|
displacementAbs.x * displacementUnitVector.x,
|
||||||
|
displacementAbs.y * displacementUnitVector.y
|
||||||
|
)
|
||||||
|
|
||||||
|
newHitbox.translate(finalDisplacement)
|
||||||
|
|
||||||
|
|
||||||
|
bounceX = angleOfIncidence == angleThreshold || displacementUnitVector.x != 0.0
|
||||||
|
bounceY = angleOfIncidence == angleThreshold || displacementUnitVector.y != 0.0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -712,113 +759,6 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
/*val BLOCK_LEFTSIDE = 1
|
|
||||||
val BLOCK_BOTTOMSIDE = 2
|
|
||||||
val BLOCK_RIGHTSIDE = 4
|
|
||||||
val BLOCK_TOPSIDE = 8
|
|
||||||
fun getBlockCondition(hitbox: Hitbox, blockAddress: BlockAddress): Int {
|
|
||||||
val blockX = (blockAddress % world.width) * TILE_SIZE
|
|
||||||
val blockY = (blockAddress / world.width) * TILE_SIZE
|
|
||||||
var ret = 0
|
|
||||||
|
|
||||||
// test leftside
|
|
||||||
if (hitbox.startX >= blockX && hitbox.startX < blockX + TILE_SIZE) { // TEST ME: <= or <
|
|
||||||
ret += BLOCK_LEFTSIDE
|
|
||||||
}
|
|
||||||
// test bottomside
|
|
||||||
if (hitbox.endY >= blockY && hitbox.endY < blockY + TILE_SIZE) {
|
|
||||||
ret += BLOCK_BOTTOMSIDE
|
|
||||||
}
|
|
||||||
// test rightside
|
|
||||||
if (hitbox.endX >= blockX && hitbox.endX < blockX + TILE_SIZE) {
|
|
||||||
ret += BLOCK_RIGHTSIDE
|
|
||||||
}
|
|
||||||
// test topside
|
|
||||||
if (hitbox.startY >= blockY && hitbox.startY < blockY + TILE_SIZE) {
|
|
||||||
ret += BLOCK_TOPSIDE
|
|
||||||
}
|
|
||||||
|
|
||||||
// cancel two superpositions (change 0b-numbers if you've changed side indices!)
|
|
||||||
//if (ret and 0b1010 == 0b1010) ret = ret and 0b0101
|
|
||||||
//if (ret and 0b0101 == 0b0101) ret = ret and 0b1010
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
infix fun Int.hasSide(side: Int) = this and side != 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var bounceX = false
|
|
||||||
var bounceY = false
|
|
||||||
// collision NOT detected
|
|
||||||
if (collidingStep == null) {
|
|
||||||
hitbox.translate(vectorSum)
|
|
||||||
// grounded = false
|
|
||||||
}
|
|
||||||
// collision detected
|
|
||||||
else {
|
|
||||||
//debug1("Collision detected")
|
|
||||||
|
|
||||||
val newHitbox = hitbox.clone() // this line is wrong (must be hitbox.reassign(sixteenStep[collidingStep])) HOWEVER the following method is also wrong; think about the case where I am placed exactly in between two tiles)
|
|
||||||
// see if four sides of hitbox CROSSES the tile
|
|
||||||
// that information should be able to tell where the hitbox be pushed
|
|
||||||
// blocks can have up to 4 status at once
|
|
||||||
affectingTiles.forEach { blockAddr ->
|
|
||||||
val blockCollStatus = getBlockCondition(newHitbox, blockAddr)
|
|
||||||
|
|
||||||
if (blockCollStatus != 0) debug4("--> blockCollStat: $blockCollStatus")
|
|
||||||
|
|
||||||
// displacements (no ELSE IFs!) superpositions are filtered in getBlockCondition()
|
|
||||||
if (blockCollStatus hasSide BLOCK_LEFTSIDE) {
|
|
||||||
val displacement = TILE_SIZE - newHitbox.startX.modTileDelta()
|
|
||||||
newHitbox.translatePosX(displacement)
|
|
||||||
bounceX = true
|
|
||||||
|
|
||||||
debug4("--> leftside")
|
|
||||||
}
|
|
||||||
if (blockCollStatus hasSide BLOCK_RIGHTSIDE) {
|
|
||||||
val displacement = newHitbox.endX.modTileDelta()
|
|
||||||
newHitbox.translatePosX(displacement)
|
|
||||||
bounceX = true
|
|
||||||
|
|
||||||
debug4("--> rightside")
|
|
||||||
}
|
|
||||||
if (blockCollStatus hasSide BLOCK_TOPSIDE) {
|
|
||||||
val displacement = TILE_SIZE - newHitbox.startY.modTileDelta()
|
|
||||||
newHitbox.translatePosY(displacement)
|
|
||||||
bounceY = true
|
|
||||||
|
|
||||||
debug4("--> topside")
|
|
||||||
}
|
|
||||||
if (blockCollStatus hasSide BLOCK_BOTTOMSIDE) {
|
|
||||||
val displacement = newHitbox.endY.modTileDelta()
|
|
||||||
newHitbox.translatePosY(displacement)
|
|
||||||
bounceY = true
|
|
||||||
|
|
||||||
debug4("--> bottomside")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hitbox.reassign(newHitbox)
|
|
||||||
|
|
||||||
|
|
||||||
// bounce X/Y
|
|
||||||
if (bounceX) {
|
|
||||||
externalForce.x *= elasticity
|
|
||||||
controllerMoveDelta?.let { controllerMoveDelta!!.x *= elasticity }
|
|
||||||
}
|
|
||||||
if (bounceY) {
|
|
||||||
externalForce.y *= elasticity
|
|
||||||
controllerMoveDelta?.let { controllerMoveDelta!!.y *= elasticity }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// grounded = true
|
|
||||||
|
|
||||||
}// end of collision not detected*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// if collision not detected, just don't care; it's not your job to apply moveDelta
|
// if collision not detected, just don't care; it's not your job to apply moveDelta
|
||||||
@@ -1458,35 +1398,44 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
/**
|
/**
|
||||||
* Apparent strength. 1 000 is default value
|
* Apparent strength. 1 000 is default value
|
||||||
*/
|
*/
|
||||||
internal inline val avStrength: Double
|
internal val avStrength: Double
|
||||||
get() = (actorValue.getAsDouble(AVKey.STRENGTH) ?: 1000.0) *
|
get() = (actorValue.getAsDouble(AVKey.STRENGTH) ?: 1000.0) *
|
||||||
(actorValue.getAsDouble(AVKey.STRENGTHBUFF) ?: 1.0) * scale
|
(actorValue.getAsDouble(AVKey.STRENGTHBUFF) ?: 1.0) * scale
|
||||||
internal inline var avBaseStrength: Double?
|
internal var avBaseStrength: Double?
|
||||||
get() = actorValue.getAsDouble(AVKey.STRENGTH)
|
get() = actorValue.getAsDouble(AVKey.STRENGTH)
|
||||||
set(value) {
|
set(value) {
|
||||||
actorValue[AVKey.STRENGTH] = value!!
|
actorValue[AVKey.STRENGTH] = value!!
|
||||||
}
|
}
|
||||||
internal inline var avBaseMass: Double
|
internal var avBaseMass: Double
|
||||||
get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT
|
inline get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT
|
||||||
set(value) {
|
set(value) {
|
||||||
|
if (value <= 0 || value.isNaN() || value.isInfinite())
|
||||||
|
throw IllegalArgumentException("Tried to set base mass to invalid value ($value)")
|
||||||
actorValue[AVKey.BASEMASS] = value
|
actorValue[AVKey.BASEMASS] = value
|
||||||
}
|
}
|
||||||
internal inline val avAcceleration: Double
|
internal val avAcceleration: Double
|
||||||
get() = actorValue.getAsDouble(AVKey.ACCEL)!! *
|
get() = actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||||
actorValue.getAsDouble(AVKey.ACCELBUFF)!! *
|
actorValue.getAsDouble(AVKey.ACCELBUFF)!! *
|
||||||
accelMultMovement *
|
accelMultMovement *
|
||||||
scale.sqrt()
|
scale.sqrt()
|
||||||
internal inline val avSpeedCap: Double
|
internal val avSpeedCap: Double
|
||||||
get() = actorValue.getAsDouble(AVKey.SPEED)!! *
|
get() = actorValue.getAsDouble(AVKey.SPEED)!! *
|
||||||
actorValue.getAsDouble(AVKey.SPEEDBUFF)!! *
|
actorValue.getAsDouble(AVKey.SPEEDBUFF)!! *
|
||||||
speedMultByTile *
|
speedMultByTile *
|
||||||
scale.sqrt()
|
scale.sqrt()
|
||||||
|
|
||||||
|
private fun Double.toPositiveRad() = // rad(0..2pi, -2pi..0) -> rad(0..4pi)
|
||||||
|
if (this >= -2 * Math.PI && this < 0.0)
|
||||||
|
4 * Math.PI - this
|
||||||
|
else
|
||||||
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Int.sqr(): Int = this * this
|
inline fun Int.sqr(): Int = this * this
|
||||||
inline fun Double.floorInt() = Math.floor(this).toInt()
|
inline fun Double.floorInt() = Math.floor(this).toInt()
|
||||||
inline fun Float.floorInt() = FastMath.floor(this)
|
inline fun Float.floorInt() = FastMath.floor(this)
|
||||||
inline fun Float.floor() = FastMath.floor(this).toFloat()
|
inline fun Float.floor() = FastMath.floor(this).toFloat()
|
||||||
|
inline fun Double.ceilInt() = Math.ceil(this).toInt()
|
||||||
inline fun Float.ceilInt() = FastMath.ceil(this)
|
inline fun Float.ceilInt() = FastMath.ceil(this)
|
||||||
inline fun Double.round() = Math.round(this).toDouble()
|
inline fun Double.round() = Math.round(this).toDouble()
|
||||||
inline fun Double.floor() = Math.floor(this)
|
inline fun Double.floor() = Math.floor(this)
|
||||||
@@ -1498,12 +1447,12 @@ inline fun Double.sqr() = this * this
|
|||||||
inline fun Double.sqrt() = Math.sqrt(this)
|
inline fun Double.sqrt() = Math.sqrt(this)
|
||||||
inline fun Float.sqrt() = FastMath.sqrt(this)
|
inline fun Float.sqrt() = FastMath.sqrt(this)
|
||||||
inline fun Int.abs() = if (this < 0) -this else this
|
inline fun Int.abs() = if (this < 0) -this else this
|
||||||
inline fun Double.bipolarClamp(limit: Double) =
|
fun Double.bipolarClamp(limit: Double) =
|
||||||
if (this > 0 && this > limit) limit
|
if (this > 0 && this > limit) limit
|
||||||
else if (this < 0 && this < -limit) -limit
|
else if (this < 0 && this < -limit) -limit
|
||||||
else this
|
else this
|
||||||
|
|
||||||
inline fun absMax(left: Double, right: Double): Double {
|
fun absMax(left: Double, right: Double): Double {
|
||||||
if (left > 0 && right > 0)
|
if (left > 0 && right > 0)
|
||||||
if (left > right) return left
|
if (left > right) return left
|
||||||
else return right
|
else return right
|
||||||
@@ -1518,8 +1467,8 @@ inline fun absMax(left: Double, right: Double): Double {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr()
|
fun Double.magnSqr() = if (this >= 0.0) this.sqr() else -this.sqr()
|
||||||
inline fun Double.sign() = if (this > 0.0) 1.0 else if (this < 0.0) -1.0 else 0.0
|
fun Double.sign() = if (this > 0.0) 1.0 else if (this < 0.0) -1.0 else 0.0
|
||||||
|
|
||||||
fun interpolateLinear(scale: Double, startValue: Double, endValue: Double): Double {
|
fun interpolateLinear(scale: Double, startValue: Double, endValue: Double): Double {
|
||||||
if (startValue == endValue) {
|
if (startValue == endValue) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package net.torvald.terrarum.gameactors
|
package net.torvald.terrarum.gameactors
|
||||||
|
|
||||||
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.terrarum.TerrarumGDX
|
||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
|
|
||||||
typealias AnyPlayer = HistoricalFigure
|
typealias AnyPlayer = HistoricalFigure
|
||||||
@@ -18,6 +20,25 @@ open class HistoricalFigure(
|
|||||||
realAirFriction: Boolean = false
|
realAirFriction: Boolean = false
|
||||||
) : ActorWithPhysics(Actor.RenderOrder.MIDDLE, realAirFriction) {
|
) : ActorWithPhysics(Actor.RenderOrder.MIDDLE, realAirFriction) {
|
||||||
|
|
||||||
|
val historicalFigureIdentifier: Int = generateHistoricalFigureIdentifier()
|
||||||
|
|
||||||
|
private fun generateHistoricalFigureIdentifier(): Int {
|
||||||
|
fun hasCollision(value: Int) =
|
||||||
|
try {
|
||||||
|
TerrarumGDX.ingame!!.historicalFigureIDBucket.contains(value)
|
||||||
|
}
|
||||||
|
catch (gameNotInitialisedException: KotlinNullPointerException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret: Int
|
||||||
|
do {
|
||||||
|
ret = HQRNG().nextInt() // set new ID
|
||||||
|
} while (hasCollision(ret)) // check for collision
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.actorValue["_bornyear"] = born.year
|
this.actorValue["_bornyear"] = born.year
|
||||||
this.actorValue["_borndays"] = born.yearlyDay
|
this.actorValue["_borndays"] = born.yearlyDay
|
||||||
|
|||||||
Reference in New Issue
Block a user