mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-07 09:04:05 +09:00
Compare commits
1 Commits
light-prel
...
lwjgl3-mig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f30e7fd45b |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -4,4 +4,3 @@
|
|||||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
*.opus filter=lfs diff=lfs merge=lfs -text
|
*.opus filter=lfs diff=lfs merge=lfs -text
|
||||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
|||||||
2
.idea/markdown-navigator/profiles_settings.xml
generated
2
.idea/markdown-navigator/profiles_settings.xml
generated
@@ -1,3 +1,3 @@
|
|||||||
<component name="MarkdownNavigator.ProfileManager">
|
<component name="MarkdownNavigator.ProfileManager">
|
||||||
<settings default="" pdf-export="" plain-text-search-scope="Project Files" />
|
<settings default="" pdf-export="" />
|
||||||
</component>
|
</component>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
Binary file not shown.
@@ -40,8 +40,6 @@ uniform vec4 colourFilter = vec4(1, 1, 1, 1); // used by WALL to darken it
|
|||||||
|
|
||||||
uniform ivec2 cameraTranslation = ivec2(0, 0);
|
uniform ivec2 cameraTranslation = ivec2(0, 0);
|
||||||
|
|
||||||
uniform float drawBreakage = 1f; // set it to 0f to not draw breakage; non-zero value to draw it
|
|
||||||
|
|
||||||
|
|
||||||
ivec2 getTileXY(int tileNumber) {
|
ivec2 getTileXY(int tileNumber) {
|
||||||
return ivec2(tileNumber % int(tilesInAtlas.x), tileNumber / int(tilesInAtlas.x));
|
return ivec2(tileNumber % int(tilesInAtlas.x), tileNumber / int(tilesInAtlas.x));
|
||||||
@@ -110,13 +108,7 @@ void main() {
|
|||||||
|
|
||||||
vec4 finalTile = mix(tileCol, tileAltCol, tilesBlend);
|
vec4 finalTile = mix(tileCol, tileAltCol, tilesBlend);
|
||||||
|
|
||||||
vec4 finalBreakage;
|
vec4 finalBreakage = texture2D(tilesAtlas, finalUVCoordForBreakage);
|
||||||
if (drawBreakage == 0f) {
|
|
||||||
finalBreakage = vec4(0f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
finalBreakage = texture2D(tilesAtlas, finalUVCoordForBreakage);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 finalColor = vec4(mix(finalTile.rgb, finalBreakage.rgb, finalBreakage.a), finalTile.a);
|
vec4 finalColor = vec4(mix(finalTile.rgb, finalBreakage.rgb, finalBreakage.a), finalTile.a);
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
lib/javadoc/lwjgl3-javadoc.zip
LFS
BIN
lib/javadoc/lwjgl3-javadoc.zip
LFS
Binary file not shown.
Binary file not shown.
@@ -93,13 +93,6 @@ public class Color {
|
|||||||
this.a = a;
|
this.a = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color (float c) {
|
|
||||||
this.r = c;
|
|
||||||
this.g = c;
|
|
||||||
this.b = c;
|
|
||||||
this.a = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructs a new color using the given color
|
/** Constructs a new color using the given color
|
||||||
*
|
*
|
||||||
* @param color the color */
|
* @param color the color */
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ class SpriteAssemblerApp(val gdxWindow: SpriteAssemblerPreview) : JFrame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 12)
|
panelCode.font = Font(Font.MONOSPACED, Font.PLAIN, 12)
|
||||||
panelCode.text = "Enter your descriptor code here…"
|
|
||||||
|
|
||||||
panelAnimationsList.model = DefaultListModel()
|
panelAnimationsList.model = DefaultListModel()
|
||||||
panelBodypartsList.model = DefaultListModel()
|
panelBodypartsList.model = DefaultListModel()
|
||||||
@@ -279,7 +278,7 @@ class SpriteAssemblerPreview: Game() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gdxClearAndSetBlend(bgCol)
|
gdxClearAndSetBlend(.62f,.79f,1f,1f)
|
||||||
|
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
package net.torvald.terrarum;
|
package net.torvald.terrarum;
|
||||||
|
|
||||||
import com.badlogic.gdx.ApplicationListener;
|
import com.badlogic.gdx.ApplicationListener;
|
||||||
import com.badlogic.gdx.Files;
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Screen;
|
import com.badlogic.gdx.Screen;
|
||||||
import com.badlogic.gdx.audio.AudioDevice;
|
import com.badlogic.gdx.audio.AudioDevice;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
|
||||||
import com.badlogic.gdx.controllers.Controllers;
|
import com.badlogic.gdx.controllers.Controllers;
|
||||||
import com.badlogic.gdx.graphics.*;
|
import com.badlogic.gdx.graphics.*;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
@@ -38,7 +37,6 @@ import net.torvald.util.ArrayListMap;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static net.torvald.terrarum.TerrarumKt.gdxClearAndSetBlend;
|
import static net.torvald.terrarum.TerrarumKt.gdxClearAndSetBlend;
|
||||||
@@ -87,9 +85,11 @@ public class AppLoader implements ApplicationListener {
|
|||||||
* @param appConfig LWJGL(2) Application Configuration
|
* @param appConfig LWJGL(2) Application Configuration
|
||||||
* @param injectScreen GDX Screen you want to run
|
* @param injectScreen GDX Screen you want to run
|
||||||
*/
|
*/
|
||||||
public AppLoader(LwjglApplicationConfiguration appConfig, Screen injectScreen) {
|
public AppLoader(Lwjgl3ApplicationConfiguration appConfig, Screen injectScreen, int width, int height) {
|
||||||
AppLoader.injectScreen = injectScreen;
|
AppLoader.injectScreen = injectScreen;
|
||||||
AppLoader.appConfig = appConfig;
|
AppLoader.appConfig = appConfig;
|
||||||
|
setWindowWidth = width;
|
||||||
|
setWindowHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +97,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
*
|
*
|
||||||
* @param appConfig LWJGL(2) Application Configuration
|
* @param appConfig LWJGL(2) Application Configuration
|
||||||
*/
|
*/
|
||||||
public AppLoader(LwjglApplicationConfiguration appConfig) {
|
public AppLoader(Lwjgl3ApplicationConfiguration appConfig) {
|
||||||
AppLoader.appConfig = appConfig;
|
AppLoader.appConfig = appConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,13 +176,13 @@ public class AppLoader implements ApplicationListener {
|
|||||||
private static boolean resizeRequested = false;
|
private static boolean resizeRequested = false;
|
||||||
private static Point2i resizeReqSize;
|
private static Point2i resizeReqSize;
|
||||||
|
|
||||||
public static LwjglApplicationConfiguration appConfig;
|
public static Lwjgl3ApplicationConfiguration appConfig;
|
||||||
public static GameFontBase fontGame;
|
public static GameFontBase fontGame;
|
||||||
public static TinyAlphNum fontSmallNumbers;
|
public static TinyAlphNum fontSmallNumbers;
|
||||||
|
|
||||||
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
/** A gamepad. Multiple gamepads may controll this single virtualised gamepad. */
|
||||||
public static TerrarumController gamepad = null;
|
public static TerrarumController gamepad = null;
|
||||||
public static float gamepadDeadzone = 0.3f;
|
public static float gamepadDeadzone = 0.2f;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,6 +198,9 @@ public class AppLoader implements ApplicationListener {
|
|||||||
public static final int minimumW = 1080;
|
public static final int minimumW = 1080;
|
||||||
public static final int minimumH = 720;
|
public static final int minimumH = 720;
|
||||||
|
|
||||||
|
public static int setWindowWidth;
|
||||||
|
public static int setWindowHeight;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// load configs
|
// load configs
|
||||||
getDefaultDirectory();
|
getDefaultDirectory();
|
||||||
@@ -206,34 +209,37 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
|
|
||||||
try { processor = GetCpuName.getModelName(); }
|
try { processor = GetCpuName.getModelName(); }
|
||||||
catch (IOException e1) { processor = "Unknown CPU"; }
|
catch (IOException e1) { processor = "Unknown"; }
|
||||||
try { processorVendor = GetCpuName.getCPUID(); }
|
try { processorVendor = GetCpuName.getCPUID(); }
|
||||||
catch (IOException e2) { processorVendor = "Unknown CPU"; }
|
catch (IOException e2) { processorVendor = "Unknown"; }
|
||||||
|
|
||||||
|
|
||||||
ShaderProgram.pedantic = false;
|
ShaderProgram.pedantic = false;
|
||||||
|
|
||||||
LwjglApplicationConfiguration appConfig = new LwjglApplicationConfiguration();
|
Lwjgl3ApplicationConfiguration appConfig = new Lwjgl3ApplicationConfiguration();
|
||||||
appConfig.useGL30 = true; // utilising some GL trickeries, need this to be TRUE
|
appConfig.useOpenGL3(true, 3, 0);// utilising some GL trickeries, need this to be TRUE
|
||||||
appConfig.vSyncEnabled = getConfigBoolean("usevsync");
|
appConfig.setResizable(false);
|
||||||
appConfig.resizable = false;//true;
|
appConfig.useVsync(getConfigBoolean("usevsync"));
|
||||||
//appConfig.width = 1110; // photographic ratio (1.5:1)
|
//setWindowWidth = 1110; // photographic ratio (1.5:1)
|
||||||
//appConfig.height = 740; // photographic ratio (1.5:1)
|
//setWindowHeight = 740; // photographic ratio (1.5:1)
|
||||||
appConfig.width = getConfigInt("screenwidth");
|
setWindowWidth = getConfigInt("screenwidth");
|
||||||
appConfig.height = getConfigInt("screenheight");
|
setWindowHeight = getConfigInt("screenheight");
|
||||||
appConfig.backgroundFPS = getConfigInt("displayfps");
|
appConfig.setWindowedMode(setWindowWidth, setWindowHeight);
|
||||||
appConfig.foregroundFPS = getConfigInt("displayfps");
|
appConfig.setIdleFPS(getConfigInt("displayfps"));
|
||||||
appConfig.title = GAME_NAME;
|
appConfig.setTitle(GAME_NAME);
|
||||||
appConfig.forceExit = false;
|
//appConfig.forceExit = false;
|
||||||
|
if (IS_DEVELOPMENT_BUILD) {
|
||||||
|
appConfig.enableGLDebugOutput(true, System.err);
|
||||||
|
}
|
||||||
|
|
||||||
// load app icon
|
// load app icon
|
||||||
int[] appIconSizes = new int[]{256,128,64,32,16};
|
appConfig.setWindowIcon(
|
||||||
for (int size : appIconSizes) {
|
"assets/appicon256.png",
|
||||||
String name = "assets/appicon" + size + ".png";
|
"assets/appicon128.png",
|
||||||
if (new File("./" + name).exists()) {
|
"assets/appicon64.png",
|
||||||
appConfig.addIcon(name, Files.FileType.Internal);
|
"assets/appicon32.png",
|
||||||
}
|
"assets/appicon16.png"
|
||||||
}
|
);
|
||||||
|
|
||||||
if (args.length == 1 && args[0].equals("isdev=true")) {
|
if (args.length == 1 && args[0].equals("isdev=true")) {
|
||||||
IS_DEVELOPMENT_BUILD = true;
|
IS_DEVELOPMENT_BUILD = true;
|
||||||
@@ -241,7 +247,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
//KeyToggler.INSTANCE.forceSet(Input.Keys.F11, true);
|
//KeyToggler.INSTANCE.forceSet(Input.Keys.F11, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
new LwjglApplication(new AppLoader(appConfig), appConfig);
|
new Lwjgl3Application(new AppLoader(appConfig), appConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -285,20 +291,18 @@ public class AppLoader implements ApplicationListener {
|
|||||||
private FrameBuffer renderFBO;
|
private FrameBuffer renderFBO;
|
||||||
|
|
||||||
public static CommonResourcePool resourcePool;
|
public static CommonResourcePool resourcePool;
|
||||||
public static HashSet<File> tempFilePool = new HashSet();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
resourcePool = CommonResourcePool.INSTANCE;
|
resourcePool = CommonResourcePool.INSTANCE;
|
||||||
|
|
||||||
newTempFile("wenquanyi.tga"); // temp file required by the font
|
|
||||||
|
|
||||||
|
|
||||||
// set basis of draw
|
// set basis of draw
|
||||||
logoBatch = new SpriteBatch();
|
logoBatch = new SpriteBatch();
|
||||||
camera = new OrthographicCamera(((float) appConfig.width), ((float) appConfig.height));
|
|
||||||
|
|
||||||
initViewPort(appConfig.width, appConfig.height);
|
camera = new OrthographicCamera(((float) setWindowWidth), ((float) setWindowHeight));
|
||||||
|
|
||||||
|
initViewPort(setWindowWidth, setWindowHeight);
|
||||||
|
|
||||||
// logo here :p
|
// logo here :p
|
||||||
logo = new TextureRegion(new Texture(Gdx.files.internal("assets/graphics/logo_placeholder.tga")));
|
logo = new TextureRegion(new Texture(Gdx.files.internal("assets/graphics/logo_placeholder.tga")));
|
||||||
@@ -316,7 +320,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
VertexAttribute.ColorUnpacked(),
|
VertexAttribute.ColorUnpacked(),
|
||||||
VertexAttribute.TexCoords(0)
|
VertexAttribute.TexCoords(0)
|
||||||
);
|
);
|
||||||
updateFullscreenQuad(appConfig.width, appConfig.height);
|
updateFullscreenQuad(setWindowWidth, setWindowHeight);
|
||||||
|
|
||||||
|
|
||||||
// set up renderer info variables
|
// set up renderer info variables
|
||||||
@@ -380,6 +384,13 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link http://bilgin.esme.org/BitsAndBytes/KalmanFilterforDummies
|
||||||
|
*/
|
||||||
|
private void updateKalmanRenderDelta() {
|
||||||
|
// moved to LwjglGraphics
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
Gdx.gl.glDisable(GL20.GL_DITHER);
|
Gdx.gl.glDisable(GL20.GL_DITHER);
|
||||||
@@ -412,8 +423,8 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
|
|
||||||
setCameraPosition(0f, 0f);
|
setCameraPosition(0f, 0f);
|
||||||
logoBatch.draw(logo, (appConfig.width - logo.getRegionWidth()) / 2f,
|
logoBatch.draw(logo, (setWindowWidth - logo.getRegionWidth()) / 2f,
|
||||||
(appConfig.height - logo.getRegionHeight()) / 2f
|
(setWindowHeight - logo.getRegionHeight()) / 2f
|
||||||
);
|
);
|
||||||
logoBatch.end();
|
logoBatch.end();
|
||||||
|
|
||||||
@@ -451,7 +462,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
screenshotRequested = false;
|
screenshotRequested = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Pixmap p = ScreenUtils.getFrameBufferPixmap(0, 0, appConfig.width, appConfig.height);
|
Pixmap p = ScreenUtils.getFrameBufferPixmap(0, 0, setWindowWidth, setWindowHeight);
|
||||||
PixmapIO2.writeTGA(Gdx.files.absolute(defaultDir + "/Screenshot.tga"), p, true);
|
PixmapIO2.writeTGA(Gdx.files.absolute(defaultDir + "/Screenshot.tga"), p, true);
|
||||||
p.dispose();
|
p.dispose();
|
||||||
}
|
}
|
||||||
@@ -494,8 +505,8 @@ public class AppLoader implements ApplicationListener {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
appConfig.width = screenW;
|
setWindowWidth = screenW;
|
||||||
appConfig.height = screenH;
|
setWindowHeight = screenH;
|
||||||
|
|
||||||
updateFullscreenQuad(screenW, screenH);
|
updateFullscreenQuad(screenW, screenH);
|
||||||
|
|
||||||
@@ -541,7 +552,8 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
ModMgr.INSTANCE.disposeMods();
|
ModMgr.INSTANCE.disposeMods();
|
||||||
|
|
||||||
deleteTempfiles();
|
// delete temp files
|
||||||
|
new File("./tmp_wenquanyi.tga").delete(); // FIXME this is pretty much ad-hoc
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -618,7 +630,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
|
|
||||||
private void setCameraPosition(float newX, float newY) {
|
private void setCameraPosition(float newX, float newY) {
|
||||||
camera.position.set((-newX + appConfig.width / 2), (-newY + appConfig.height / 2), 0f);
|
camera.position.set((-newX + setWindowWidth / 2), (-newY + setWindowHeight / 2), 0f);
|
||||||
camera.update();
|
camera.update();
|
||||||
logoBatch.setProjectionMatrix(camera.combined);
|
logoBatch.setProjectionMatrix(camera.combined);
|
||||||
}
|
}
|
||||||
@@ -684,7 +696,6 @@ public class AppLoader implements ApplicationListener {
|
|||||||
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
|
||||||
System.out.println(String.format("os.version = %s", OSVersion));
|
System.out.println(String.format("os.version = %s", OSVersion));
|
||||||
System.out.println(String.format("default directory: %s", defaultDir));
|
System.out.println(String.format("default directory: %s", defaultDir));
|
||||||
System.out.println(String.format("java version = %s", System.getProperty("java.version")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createDirs() {
|
private static void createDirs() {
|
||||||
@@ -698,17 +709,6 @@ public class AppLoader implements ApplicationListener {
|
|||||||
//dirs.forEach { if (!it.exists()) it.mkdirs() }
|
//dirs.forEach { if (!it.exists()) it.mkdirs() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File newTempFile(String filename) {
|
|
||||||
File tempfile = new File("./tmp_" + filename);
|
|
||||||
tempFilePool.add(tempfile);
|
|
||||||
return tempfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void deleteTempfiles() {
|
|
||||||
for (File file : tempFilePool) {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CONFIG //
|
// CONFIG //
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
|||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.ui.ConsoleWindow
|
import net.torvald.terrarum.ui.ConsoleWindow
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.locks.Lock
|
import java.util.concurrent.locks.Lock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,9 +127,6 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wire version of terrainChanged() event
|
* Wire version of terrainChanged() event
|
||||||
*
|
|
||||||
* @param old previous settings of conduits in bit set format.
|
|
||||||
* @param new current settings of conduits in bit set format.
|
|
||||||
*/
|
*/
|
||||||
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
||||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||||
@@ -145,11 +143,11 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
if (actorContainerActive.size == 0 && actorContainerInactive.size == 0)
|
if (actorContainerActive.size == 0 && actorContainerInactive.size == 0)
|
||||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||||
|
|
||||||
var actor = actorContainerActive.searchFor(ID) { it.referenceID!! }
|
var index = actorContainerActive.binarySearch(ID)
|
||||||
if (actor == null) {
|
if (index < 0) {
|
||||||
actor = actorContainerInactive.searchFor(ID) { it.referenceID!! }
|
index = actorContainerInactive.binarySearch(ID)
|
||||||
|
|
||||||
if (actor == null) {
|
if (index < 0) {
|
||||||
/*JOptionPane.showMessageDialog(
|
/*JOptionPane.showMessageDialog(
|
||||||
null,
|
null,
|
||||||
"Actor with ID $ID does not exist.",
|
"Actor with ID $ID does not exist.",
|
||||||
@@ -158,14 +156,36 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
throw IllegalArgumentException("Actor with ID $ID does not exist.")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return actor
|
return actorContainerInactive[index]
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return actor
|
return actorContainerActive[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
//fun SortedArrayList<*>.binarySearch(actor: Actor) = this.toArrayList().binarySearch(actor.referenceID!!)
|
fun ArrayList<*>.binarySearch(actor: Actor) = this.binarySearch(actor.referenceID!!)
|
||||||
//fun SortedArrayList<*>.binarySearch(ID: Int) = this.toArrayList().binarySearch(ID)
|
|
||||||
|
fun ArrayList<*>.binarySearch(ID: Int): Int {
|
||||||
|
// code from collections/Collections.kt
|
||||||
|
var low = 0
|
||||||
|
var high = this.size - 1
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
val mid = (low + high).ushr(1) // safe from overflows
|
||||||
|
|
||||||
|
val midVal = get(mid)!!
|
||||||
|
|
||||||
|
if (ID > midVal.hashCode())
|
||||||
|
low = mid + 1
|
||||||
|
else if (ID < midVal.hashCode())
|
||||||
|
high = mid - 1
|
||||||
|
else
|
||||||
|
return mid // key found
|
||||||
|
}
|
||||||
|
return -(low + 1) // key not found
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SortedArrayList<*>.binarySearch(actor: Actor) = this.toArrayList().binarySearch(actor.referenceID!!)
|
||||||
|
fun SortedArrayList<*>.binarySearch(ID: Int) = this.toArrayList().binarySearch(ID)
|
||||||
|
|
||||||
open fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
open fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
||||||
/**
|
/**
|
||||||
@@ -179,9 +199,9 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
open fun removeActor(actor: Actor?) {
|
open fun removeActor(actor: Actor?) {
|
||||||
if (actor == null) return
|
if (actor == null) return
|
||||||
|
|
||||||
val indexToDelete = actorContainerActive.searchFor(actor.referenceID!!) { it.referenceID!! }
|
val indexToDelete = actorContainerActive.binarySearch(actor.referenceID!!)
|
||||||
if (indexToDelete != null) {
|
if (indexToDelete >= 0) {
|
||||||
actorContainerActive.remove(indexToDelete)
|
actorContainerActive.removeAt(indexToDelete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,13 +223,13 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
if (actorContainerActive.size == 0)
|
if (actorContainerActive.size == 0)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
actorContainerActive.searchFor(ID) { it.referenceID!! } != null
|
actorContainerActive.binarySearch(ID) >= 0
|
||||||
|
|
||||||
fun isInactive(ID: Int): Boolean =
|
fun isInactive(ID: Int): Boolean =
|
||||||
if (actorContainerInactive.size == 0)
|
if (actorContainerInactive.size == 0)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
actorContainerInactive.searchFor(ID) { it.referenceID!! } != null
|
actorContainerInactive.binarySearch(ID) >= 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* actorContainerActive extensions
|
* actorContainerActive extensions
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
|||||||
import com.badlogic.gdx.math.Matrix4
|
import com.badlogic.gdx.math.Matrix4
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called by the App Loader
|
* Must be called by the App Loader
|
||||||
@@ -38,8 +37,6 @@ object PostProcessor {
|
|||||||
|
|
||||||
private val debugUI = BasicDebugInfoWindow()
|
private val debugUI = BasicDebugInfoWindow()
|
||||||
|
|
||||||
private var functionRowHelper = Texture(Gdx.files.internal("assets/graphics/function_row_help.png"))
|
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
batch.dispose()
|
batch.dispose()
|
||||||
shapeRenderer.dispose()
|
shapeRenderer.dispose()
|
||||||
@@ -64,7 +61,7 @@ object PostProcessor {
|
|||||||
batch.projectionMatrix = camera.combined
|
batch.projectionMatrix = camera.combined
|
||||||
|
|
||||||
shapeRenderer = ShapeRenderer()
|
shapeRenderer = ShapeRenderer()
|
||||||
Gdx.gl20.glViewport(0, 0, AppLoader.appConfig.width, AppLoader.appConfig.height)
|
Gdx.gl20.glViewport(0, 0, AppLoader.setWindowWidth, AppLoader.setWindowHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -81,25 +78,6 @@ object PostProcessor {
|
|||||||
drawSafeArea()
|
drawSafeArea()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyToggler.isOn(Input.Keys.F1)) {
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
batch.inUse {
|
|
||||||
it.draw(functionRowHelper,
|
|
||||||
(AppLoader.screenW - functionRowHelper.width) / 2f,
|
|
||||||
functionRowHelper.height.toFloat(),
|
|
||||||
functionRowHelper.width.toFloat(),
|
|
||||||
functionRowHelper.height * -1f
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (KeyToggler.isOn(Input.Keys.F10)) {
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
batch.inUse {
|
|
||||||
AppLoader.fontSmallNumbers.draw(it, "Wire draw bits: ${BlocksDrawer.drawWires.toString(2)}", 2f, 2f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (KeyToggler.isOn(Input.Keys.F3)) {
|
if (KeyToggler.isOn(Input.Keys.F3)) {
|
||||||
if (!debugUI.isOpened && !debugUI.isOpening) debugUI.setAsOpen()
|
if (!debugUI.isOpened && !debugUI.isOpening) debugUI.setAsOpen()
|
||||||
batch.inUse { debugUI.renderUI(batch, camera) }
|
batch.inUse { debugUI.renderUI(batch, camera) }
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ 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.utils.GdxRuntimeException
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.util.CircularArray
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.AppLoader.*
|
import net.torvald.terrarum.AppLoader.*
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
@@ -22,7 +23,6 @@ import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
|||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import net.torvald.util.CircularArray
|
|
||||||
import org.lwjgl.BufferUtils
|
import org.lwjgl.BufferUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
@@ -196,6 +196,7 @@ object Terrarum : Screen {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
println("$NAME version ${AppLoader.getVERSION_STRING()}")
|
println("$NAME version ${AppLoader.getVERSION_STRING()}")
|
||||||
|
println("Java Runtime version ${System.getProperty("java.version")}")
|
||||||
println("LibGDX version ${com.badlogic.gdx.Version.VERSION}")
|
println("LibGDX version ${com.badlogic.gdx.Version.VERSION}")
|
||||||
|
|
||||||
|
|
||||||
@@ -612,10 +613,6 @@ fun blendNormal(batch: SpriteBatch) {
|
|||||||
// - https://www.andersriggelsen.dk/glblendfunc.php
|
// - https://www.andersriggelsen.dk/glblendfunc.php
|
||||||
}
|
}
|
||||||
|
|
||||||
fun gdxClearAndSetBlend(color: Color) {
|
|
||||||
gdxClearAndSetBlend(color.r, color.g, color.b, color.a)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) {
|
fun gdxClearAndSetBlend(r: Float, g: Float, b: Float, a: Float) {
|
||||||
Gdx.gl.glClearColor(r,g,b,a)
|
Gdx.gl.glClearColor(r,g,b,a)
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ class BlockProp {
|
|||||||
var shadeColG = 0f
|
var shadeColG = 0f
|
||||||
var shadeColB = 0f
|
var shadeColB = 0f
|
||||||
var shadeColA = 0f
|
var shadeColA = 0f
|
||||||
var opacity: Color = Color(0)
|
|
||||||
|
lateinit var opacity: Color
|
||||||
|
|
||||||
var strength: Int = 0
|
var strength: Int = 0
|
||||||
var density: Int = 0
|
var density: Int = 0
|
||||||
@@ -35,7 +36,7 @@ class BlockProp {
|
|||||||
var lumColG = 0f
|
var lumColG = 0f
|
||||||
var lumColB = 0f
|
var lumColB = 0f
|
||||||
var lumColA = 0f
|
var lumColA = 0f
|
||||||
var internalLumCol: Color = Color(0)
|
lateinit var internalLumCol: Color
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param luminosity
|
* @param luminosity
|
||||||
|
|||||||
@@ -6,52 +6,21 @@ package net.torvald.terrarum.blockproperties
|
|||||||
object Wire {
|
object Wire {
|
||||||
|
|
||||||
/* A mapping for World's conduitTypes bits */
|
/* A mapping for World's conduitTypes bits */
|
||||||
/* Must be aligned with the sprite sheet */
|
|
||||||
const val BIT_NONE = 0
|
const val BIT_NONE = 0
|
||||||
const val BIT_SIGNAL_RED = 1
|
const val BIT_SIGNAL_RED = 1
|
||||||
const val BIT_UTILITY_PROTOTYPE = 2 // logic gates/PCLs/Diodes/Caps/etc.
|
const val BIT_UTILITY_PROTOTYPE = 2
|
||||||
const val BIT_POWER_LOW = 4
|
const val BIT_POWER_LOW = 4
|
||||||
const val BIT_POWER_HIGHT = 8
|
const val BIT_POWER_HIGHT = 8
|
||||||
const val BIT_THICKNET = 16 // the actual datagramme should be represented by another means than the ConduitFills
|
const val BIT_ETHERNET = 16
|
||||||
const val BIT_PARALLEL_8B = 32 // uses bit-to-mantissa encoding
|
|
||||||
const val BIT_PARALLEL_16B = 64 // uses bit-to-mantissa encoding. 16 bit half duplex OR 8 bit full duplex
|
|
||||||
|
|
||||||
/* A mapping for World's WiringNode.fills[] index */
|
/* A mapping for World's conduitFills[] index */
|
||||||
/*const val FILL_ID_SIGNAL_RED = 0
|
const val FILL_ID_SIGNAL_RED = 0
|
||||||
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
const val FILL_ID_UTILITY_PROTOTYPE = 1
|
||||||
|
|
||||||
fun bitToConduitFillID(bit: Int) = when(bit) {
|
fun bitToConduitFillID(bit: Int) = when(bit) {
|
||||||
BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED
|
BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED
|
||||||
BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE
|
BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE
|
||||||
else -> null
|
else -> null
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes a byte to Float's mantissa. Normal value range is 1.0..1.99609375. When decoding, the sign and exponent bits
|
|
||||||
* must be ignored. (e.g. the encoded float might have not-one-point-something value after "bitwise" add/subtraction.
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* exponent ,------- mantissa ------,
|
|
||||||
* s eeeeeeee bbbbbbbb cccccccc xxxxxxx
|
|
||||||
* s: sign (ignored)
|
|
||||||
* e: binary32 exponent (non-zero and non-255)
|
|
||||||
* b: upper octet
|
|
||||||
* c: lower octet (zero for Byte representation)
|
|
||||||
* x: not used, all zero
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* MSB of the byte is also the highest bit in the mantissa. Therefore ```0x80``` will be encoded as ```1.5```
|
|
||||||
*/
|
|
||||||
fun Byte.toFloatMantissa(): Float = Float.fromBits(0x3F800000 or (this.toInt().and(0xFF) shl 15))
|
|
||||||
fun Short.toFloatMantissa(): Float = Float.fromBits(0x3F800000 or (this.toInt().and(0xFFFF) shl 7))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function does the reversal calculation.
|
|
||||||
*
|
|
||||||
* @see net.torvald.terrarum.blockproperties.Wire.toFloatMantissa
|
|
||||||
*/
|
|
||||||
fun Float.fromMantissaToByte(): Byte = this.toRawBits().ushr(15).and(0xFF).toByte()
|
|
||||||
fun Float.fromMantissaToShort(): Short = this.toRawBits().ushr(7).and(0xFFFF).toShort()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ object CommandDict {
|
|||||||
"kill" to KillActor,
|
"kill" to KillActor,
|
||||||
"money" to MoneyDisp,
|
"money" to MoneyDisp,
|
||||||
"screenshot" to TakeScreenshot,
|
"screenshot" to TakeScreenshot,
|
||||||
"resize" to ResizeScreen,
|
//"resize" to ResizeScreen,
|
||||||
|
|
||||||
// Test codes
|
// Test codes
|
||||||
"bulletintest" to SetBulletin,
|
"bulletintest" to SetBulletin,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package net.torvald.terrarum.console
|
package net.torvald.terrarum.console
|
||||||
|
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
|
|
||||||
object ResizeScreen: ConsoleCommand {
|
object ResizeScreen: ConsoleCommand {
|
||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
if (args.size == 3) {
|
if (args.size == 3) {
|
||||||
AppLoader.resizeScreen(args[1].toInt(), args[2].toInt())
|
Terrarum.resize(args[1].toInt(), args[2].toInt())
|
||||||
}
|
}
|
||||||
else if (args.size == 2) {
|
else if (args.size == 2) {
|
||||||
when (args[1]) {
|
when (args[1]) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.torvald.terrarum.gameactors
|
package net.torvald.terrarum.gameactors
|
||||||
|
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex.ACTORID_MIN
|
import net.torvald.terrarum.itemproperties.ItemCodex.ACTORID_MIN
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable<Actor>, Runnable
|
|||||||
* Valid RefID is equal to or greater than 16777216.
|
* Valid RefID is equal to or greater than 16777216.
|
||||||
* @return Reference ID. (16777216-0x7FFF_FFFF)
|
* @return Reference ID. (16777216-0x7FFF_FFFF)
|
||||||
*/
|
*/
|
||||||
open var referenceID: ActorID = Terrarum.generateUniqueReferenceID(renderOrder) // once this was nullable without initialiser. If you're going to revert to that, add the reason why this should be nullable.
|
open var referenceID: ActorID? = null
|
||||||
var actorValue = ActorValue(this) // FIXME cyclic reference on GSON
|
var actorValue = ActorValue(this) // FIXME cyclic reference on GSON
|
||||||
@Volatile var flagDespawn = false
|
@Volatile var flagDespawn = false
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ import com.badlogic.gdx.InputAdapter
|
|||||||
import com.badlogic.gdx.controllers.Controllers
|
import com.badlogic.gdx.controllers.Controllers
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.controller.TerrarumController
|
import net.torvald.terrarum.controller.TerrarumController
|
||||||
import net.torvald.terrarum.floorInt
|
import net.torvald.terrarum.floorInt
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
|
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,16 +57,22 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
|
// Use item: assuming the player has only one effective grip (EquipPosition.HAND_GRIP)
|
||||||
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
|
||||||
if (ingame.canPlayerControl) {
|
if (ingame.canPlayerControl) {
|
||||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) ||
|
||||||
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||||
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
val player = (Terrarum.ingame!! as Ingame).actorNowPlaying
|
||||||
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
if (player == null) return
|
||||||
}
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
val itemOnGrip = player.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]
|
||||||
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
|
||||||
|
itemOnGrip?.let {
|
||||||
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
||||||
|
player.consumePrimary(ItemCodex[it]!!)
|
||||||
|
}
|
||||||
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||||
|
player.consumeSecondary(ItemCodex[it]!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,6 +192,21 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
|
||||||
|
if (ingame.canPlayerControl) {
|
||||||
|
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
||||||
|
if (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
||||||
|
|
||||||
|
if (button == AppLoader.getConfigInt("mouseprimary")) {
|
||||||
|
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
|
}
|
||||||
|
if (button == AppLoader.getConfigInt("mousesecondary")) {
|
||||||
|
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ingame.uiContainer.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
ingame.uiContainer.forEach { it.touchDown(screenX, screenY, pointer, button) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package net.torvald.terrarum.gameworld
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import net.torvald.util.SortedArrayList
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
@@ -10,7 +11,7 @@ import net.torvald.terrarum.blockproperties.Fluid
|
|||||||
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.terrarum.toInt
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.sign
|
import kotlin.math.sign
|
||||||
@@ -73,17 +74,16 @@ open class GameWorld {
|
|||||||
val fluidTypes: HashMap<BlockAddress, FluidType>
|
val fluidTypes: HashMap<BlockAddress, FluidType>
|
||||||
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
@TEMzPayload("FlFL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||||
val fluidFills: HashMap<BlockAddress, Float>
|
val fluidFills: HashMap<BlockAddress, Float>
|
||||||
|
@TEMzPayload("CtYP", TEMzPayload.INT48_INT_PAIR)
|
||||||
|
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
|
||||||
|
@TEMzPayload("CfL", TEMzPayload.INT48_FLOAT_PAIR)
|
||||||
|
val conduitFills: Array<HashMap<BlockAddress, Float>>
|
||||||
|
val conduitFills0: HashMap<BlockAddress, Float> // size of liquid packet on the block
|
||||||
|
get() = conduitFills[0]
|
||||||
|
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
|
||||||
|
get() = conduitFills[1]
|
||||||
|
|
||||||
/**
|
private val wiringNodes = SortedArrayList<WiringNode>()
|
||||||
* Single block can have multiple conduits, different types of conduits are stored separately.
|
|
||||||
*/
|
|
||||||
@TEMzPayload("WiNt", TEMzPayload.EXTERNAL_JSON)
|
|
||||||
private val wirings: HashMap<BlockAddress, SortedArrayList<WiringNode>>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised.
|
|
||||||
*/
|
|
||||||
private val wiringBlocks: HashMap<BlockAddress, Int>
|
|
||||||
|
|
||||||
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
||||||
//physics
|
//physics
|
||||||
@@ -114,13 +114,13 @@ open class GameWorld {
|
|||||||
layerTerrainLowBits = PairedMapLayer(width, height)
|
layerTerrainLowBits = PairedMapLayer(width, height)
|
||||||
layerWallLowBits = PairedMapLayer(width, height)
|
layerWallLowBits = PairedMapLayer(width, height)
|
||||||
|
|
||||||
wallDamages = HashMap()
|
wallDamages = HashMap<BlockAddress, Float>()
|
||||||
terrainDamages = HashMap()
|
terrainDamages = HashMap<BlockAddress, Float>()
|
||||||
fluidTypes = HashMap()
|
fluidTypes = HashMap<BlockAddress, FluidType>()
|
||||||
fluidFills = HashMap()
|
fluidFills = HashMap<BlockAddress, Float>()
|
||||||
|
|
||||||
wiringBlocks = HashMap()
|
conduitTypes = HashMap<BlockAddress, Int>()
|
||||||
wirings = HashMap()
|
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
||||||
|
|
||||||
// temperature layer: 2x2 is one cell
|
// temperature layer: 2x2 is one cell
|
||||||
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
|
||||||
@@ -148,8 +148,8 @@ open class GameWorld {
|
|||||||
fluidTypes = layerData.fluidTypes
|
fluidTypes = layerData.fluidTypes
|
||||||
fluidFills = layerData.fluidFills
|
fluidFills = layerData.fluidFills
|
||||||
|
|
||||||
wiringBlocks = HashMap()
|
conduitTypes = HashMap<BlockAddress, Int>()
|
||||||
wirings = HashMap()
|
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
|
||||||
|
|
||||||
spawnX = layerData.spawnX
|
spawnX = layerData.spawnX
|
||||||
spawnY = layerData.spawnY
|
spawnY = layerData.spawnY
|
||||||
@@ -210,6 +210,10 @@ open class GameWorld {
|
|||||||
terrain * PairedMapLayer.RANGE + terrainDamage
|
terrain * PairedMapLayer.RANGE + terrainDamage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getWires(x: Int, y: Int): Int {
|
||||||
|
return conduitTypes.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
||||||
|
}
|
||||||
|
|
||||||
fun getWallLowBits(x: Int, y: Int): Int? {
|
fun getWallLowBits(x: Int, y: Int): Int? {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
return layerWallLowBits.getData(x, y)
|
return layerWallLowBits.getData(x, y)
|
||||||
@@ -226,11 +230,10 @@ open class GameWorld {
|
|||||||
* *
|
* *
|
||||||
* @param y
|
* @param y
|
||||||
* *
|
* *
|
||||||
* @param combinedTilenum Item id of the wall block. Less-than-4096-value is permitted.
|
* @param combinedTilenum (tilenum * 16) + damage
|
||||||
*/
|
*/
|
||||||
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
|
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
val combinedTilenum = combinedTilenum % GameWorld.TILES_SUPPORTED // does work without this, but to be safe...
|
|
||||||
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +243,7 @@ open class GameWorld {
|
|||||||
* *
|
* *
|
||||||
* @param y
|
* @param y
|
||||||
* *
|
* *
|
||||||
* @param combinedTilenum Item id of the terrain block, <4096
|
* @param combinedTilenum (tilenum * 16) + damage
|
||||||
*/
|
*/
|
||||||
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
|
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
@@ -288,35 +291,25 @@ open class GameWorld {
|
|||||||
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun getWiringBlocks(x: Int, y: Int): Int {
|
/**
|
||||||
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
* Overrides entire bits with given value. DO NOT USE THIS if you don't know what this means, you'll want to use setWire().
|
||||||
}
|
* Besides, this function won't fire WireChangedEvent
|
||||||
|
*/
|
||||||
fun getAllConduitsFrom(x: Int, y: Int): SortedArrayList<WiringNode>? {
|
fun setWires(x: Int, y: Int, wireBits: Int) {
|
||||||
return wirings.get(LandUtil.getBlockAddr(this, x, y))
|
val (x, y) = coerceXY(x, y)
|
||||||
|
conduitTypes[LandUtil.getBlockAddr(this, x, y)] = wireBits
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param conduitTypeBit defined in net.torvald.terrarum.blockproperties.Wire, always power-of-two
|
* Sets single bit for given tile. YOU'LL WANT TO USE THIS instead of setWires()
|
||||||
|
* @param selectedWire wire-bit to modify, must be power of two
|
||||||
*/
|
*/
|
||||||
fun getConduitByTypeFrom(x: Int, y: Int, conduitTypeBit: Int): WiringNode? {
|
fun setWire(x: Int, y: Int, selectedWire: Int, bitToSet: Boolean) {
|
||||||
val conduits = getAllConduitsFrom(x, y)
|
val oldWireBits = getWires(x, y)
|
||||||
return conduits?.searchFor(conduitTypeBit) { it.typeBitMask }
|
val oldStatus = getWires(x, y) or selectedWire != 0
|
||||||
}
|
if (oldStatus != bitToSet) {
|
||||||
|
setWires(x, y, (oldWireBits and selectedWire.inv()) or (selectedWire * oldStatus.toInt()))
|
||||||
fun addNewConduitTo(x: Int, y: Int, node: WiringNode) {
|
Terrarum.ingame?.queueWireChangedEvent(selectedWire * oldStatus.toInt(), selectedWire * bitToSet.toInt(), LandUtil.getBlockAddr(this, x, y))
|
||||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
|
||||||
|
|
||||||
// check for existing type of conduit
|
|
||||||
// if there's no duplicate...
|
|
||||||
if (getWiringBlocks(x, y) and node.typeBitMask == 0) {
|
|
||||||
// store as-is
|
|
||||||
wirings.getOrPut(blockAddr) { SortedArrayList() }.add(node)
|
|
||||||
// synchronise wiringBlocks
|
|
||||||
wiringBlocks[blockAddr] = (wiringBlocks[blockAddr] ?: 0) or node.typeBitMask
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TODO("need overwriting policy for existing conduit node")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +321,7 @@ open class GameWorld {
|
|||||||
return getTileFromWall(x, y)
|
return getTileFromWall(x, y)
|
||||||
}
|
}
|
||||||
else if (mode == WIRE) {
|
else if (mode == WIRE) {
|
||||||
return getWiringBlocks(x, y)
|
return getWires(x, y)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
||||||
@@ -489,17 +482,12 @@ open class GameWorld {
|
|||||||
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
|
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private data class WiringNode(
|
||||||
* Connection rules: connect to all nearby, except:
|
|
||||||
*
|
|
||||||
* If the wire allows 3- or 4-way connection, make such connection.
|
|
||||||
* If the wire does not allow them (e.g. wire bridge, thicknet), connect top-bottom and left-right nodes.
|
|
||||||
*/
|
|
||||||
data class WiringNode(
|
|
||||||
val position: BlockAddress,
|
val position: BlockAddress,
|
||||||
/** One defined in WireCodex, always power of two */
|
/** One defined in WireCodex, always power of two */
|
||||||
val typeBitMask: Int,
|
val typeBitMask: Int,
|
||||||
var fills: Float = 0f
|
var fills: Float = 0f,
|
||||||
|
var connectedNodes: ArrayList<WiringNode>
|
||||||
) : Comparable<WiringNode> {
|
) : Comparable<WiringNode> {
|
||||||
override fun compareTo(other: WiringNode): Int {
|
override fun compareTo(other: WiringNode): Int {
|
||||||
return (this.position - other.position).sign
|
return (this.position - other.position).sign
|
||||||
@@ -547,9 +535,6 @@ inline class FluidType(val value: Int) {
|
|||||||
*/
|
*/
|
||||||
annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTERNAL_JAVAPROPERTIES = -3
|
|
||||||
const val EXTERNAL_CSV = -2
|
|
||||||
const val EXTERNAL_JSON = -1
|
|
||||||
const val EIGHT_MSB = 0
|
const val EIGHT_MSB = 0
|
||||||
const val FOUR_LSB = 1
|
const val FOUR_LSB = 1
|
||||||
const val INT48_FLOAT_PAIR = 2
|
const val INT48_FLOAT_PAIR = 2
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
internal var showSelection = true
|
internal var showSelection = true
|
||||||
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
||||||
|
|
||||||
override var referenceID: ActorID = 1048575 // custom refID
|
override var referenceID: ActorID? = 1048575 // custom refID
|
||||||
override val hitbox = Hitbox(0.0, 0.0, 16.0, 16.0)
|
override val hitbox = Hitbox(0.0, 0.0, 16.0, 16.0)
|
||||||
|
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
private var _testMarkerDrawCalls = 0L
|
private var _testMarkerDrawCalls = 0L
|
||||||
|
|
||||||
private fun generateNewBlockMarkerVisible(x: Int, y: Int) = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
private fun generateNewBlockMarkerVisible(x: Int, y: Int) = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
||||||
override var referenceID: ActorID = blockPosToRefID(x, y) // custom refID
|
override var referenceID: ActorID? = blockPosToRefID(x, y) // custom refID
|
||||||
override val hitbox = Hitbox(x * 16.0, y * 16.0, 16.0, 16.0)
|
override val hitbox = Hitbox(x * 16.0, y * 16.0, 16.0, 16.0)
|
||||||
|
|
||||||
override fun drawBody(batch: SpriteBatch) {
|
override fun drawBody(batch: SpriteBatch) {
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
package net.torvald.terrarum.modulebasegame
|
package net.torvald.terrarum.modulebasegame
|
||||||
|
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.AppLoader.IS_DEVELOPMENT_BUILD
|
import net.torvald.terrarum.AppLoader.IS_DEVELOPMENT_BUILD
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.ModMgr
|
|
||||||
import net.torvald.terrarum.ModuleEntryPoint
|
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.itemproperties.MaterialCodex
|
import net.torvald.terrarum.itemproperties.MaterialCodex
|
||||||
import net.torvald.terrarum.modulebasegame.imagefont.WatchFont
|
import net.torvald.terrarum.modulebasegame.imagefont.WatchFont
|
||||||
import net.torvald.terrarum.modulebasegame.items.BlockBase
|
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,11 +74,48 @@ class EntryPoint : ModuleEntryPoint() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun startPrimaryUse(delta: Float): Boolean {
|
override fun startPrimaryUse(delta: Float): Boolean {
|
||||||
return BlockBase.blockStartPrimaryUse(this, i, delta)
|
val ingame = Terrarum.ingame!! as Ingame
|
||||||
}
|
|
||||||
|
|
||||||
override fun effectWhenEquipped(delta: Float) {
|
val mousePoint = Point2d(Terrarum.mouseTileX.toDouble(), Terrarum.mouseTileY.toDouble())
|
||||||
BlockBase.blockEffectWhenEquipped(delta)
|
|
||||||
|
// check for collision with actors (BLOCK only)
|
||||||
|
if (this.inventoryCategory == Category.BLOCK) {
|
||||||
|
var ret1 = true
|
||||||
|
ingame.actorContainerActive.forEach {
|
||||||
|
if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint))
|
||||||
|
ret1 = false // return is not allowed here
|
||||||
|
}
|
||||||
|
if (!ret1) return ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// return false if the tile is already there
|
||||||
|
if (this.inventoryCategory == Category.BLOCK &&
|
||||||
|
this.dynamicID == ingame.world.getTileFromTerrain(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
|
||||||
|
this.inventoryCategory == Category.WALL &&
|
||||||
|
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
|
||||||
|
this.inventoryCategory == Category.WIRE &&
|
||||||
|
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWires(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// filter passed, do the job
|
||||||
|
// FIXME this is only useful for Player
|
||||||
|
if (i in ItemCodex.ITEM_TILES) {
|
||||||
|
ingame.world.setTileTerrain(
|
||||||
|
Terrarum.mouseTileX,
|
||||||
|
Terrarum.mouseTileY,
|
||||||
|
i
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ingame.world.setTileWall(
|
||||||
|
Terrarum.mouseTileX,
|
||||||
|
Terrarum.mouseTileY,
|
||||||
|
i
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -394,9 +394,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
override fun worldPrimaryClickStart(delta: Float) {
|
override fun worldPrimaryClickStart(delta: Float) {
|
||||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||||
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startPrimaryUse(delta) ?: false
|
ItemCodex[itemOnGrip]?.startPrimaryUse(delta)
|
||||||
if (consumptionSuccessful)
|
|
||||||
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun worldPrimaryClickEnd(delta: Float) {
|
override fun worldPrimaryClickEnd(delta: Float) {
|
||||||
@@ -406,9 +404,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
override fun worldSecondaryClickStart(delta: Float) {
|
override fun worldSecondaryClickStart(delta: Float) {
|
||||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||||
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startSecondaryUse(delta) ?: false
|
ItemCodex[itemOnGrip]?.startSecondaryUse(delta)
|
||||||
if (consumptionSuccessful)
|
|
||||||
actorNowPlaying?.inventory?.consumeItem(ItemCodex[itemOnGrip]!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun worldSecondaryClickEnd(delta: Float) {
|
override fun worldSecondaryClickEnd(delta: Float) {
|
||||||
@@ -751,8 +747,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic
|
if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic
|
||||||
throw RuntimeException("Attempted to remove player.")
|
throw RuntimeException("Attempted to remove player.")
|
||||||
val indexToDelete = actorContainerActive.searchForIndex(actor.referenceID!!) { it.referenceID!! }
|
val indexToDelete = actorContainerActive.binarySearch(actor.referenceID!!)
|
||||||
if (indexToDelete != null) {
|
if (indexToDelete >= 0) {
|
||||||
printdbg(this, "Removing actor $actor")
|
printdbg(this, "Removing actor $actor")
|
||||||
printStackTrace()
|
printStackTrace()
|
||||||
|
|
||||||
@@ -787,28 +783,6 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ArrayList<*>.binarySearch(actor: Actor) = this.binarySearch(actor.referenceID!!)
|
|
||||||
|
|
||||||
private fun ArrayList<*>.binarySearch(ID: Int): Int {
|
|
||||||
// code from collections/Collections.kt
|
|
||||||
var low = 0
|
|
||||||
var high = this.size - 1
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
val mid = (low + high).ushr(1) // safe from overflows
|
|
||||||
|
|
||||||
val midVal = get(mid)!!
|
|
||||||
|
|
||||||
if (ID > midVal.hashCode())
|
|
||||||
low = mid + 1
|
|
||||||
else if (ID < midVal.hashCode())
|
|
||||||
high = mid - 1
|
|
||||||
else
|
|
||||||
return mid // key found
|
|
||||||
}
|
|
||||||
return -(low + 1) // key not found
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for duplicates, append actor and sort the list
|
* Check for duplicates, append actor and sort the list
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ object IngameRenderer {
|
|||||||
LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay)
|
LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay)
|
||||||
|
|
||||||
prepLightmapRGBA()
|
prepLightmapRGBA()
|
||||||
BlocksDrawer.renderData()
|
BlocksDrawer.renderData(selectedWireBitToDraw)
|
||||||
drawToRGB(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
|
drawToRGB(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
|
||||||
drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
|
drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
|
||||||
drawOverlayActors(actorsRenderOverlay)
|
drawOverlayActors(actorsRenderOverlay)
|
||||||
@@ -214,6 +214,9 @@ object IngameRenderer {
|
|||||||
// works but some UI elements have wrong transparency -> should be fixed with Terrarum.gdxCleanAndSetBlend -- Torvald 2019-01-12
|
// works but some UI elements have wrong transparency -> should be fixed with Terrarum.gdxCleanAndSetBlend -- Torvald 2019-01-12
|
||||||
blendNormal(batch)
|
blendNormal(batch)
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
|
|
||||||
|
|
||||||
|
selectedWireBitToDraw = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -177,9 +177,7 @@ class ActorInventory(@Transient val actor: Pocketed, var maxCapacity: Int, var c
|
|||||||
false
|
false
|
||||||
|
|
||||||
|
|
||||||
fun consumeItem(item: GameItem) {
|
fun consumeItem(actor: Actor, item: GameItem) {
|
||||||
val actor = this.actor as Actor
|
|
||||||
|
|
||||||
if (item.stackable && !item.isDynamic) {
|
if (item.stackable && !item.isDynamic) {
|
||||||
remove(item, 1)
|
remove(item, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ object PlayerBuilderSigrid {
|
|||||||
inventory.add(8448) // copper pick
|
inventory.add(8448) // copper pick
|
||||||
inventory.add(8449) // iron pick
|
inventory.add(8449) // iron pick
|
||||||
inventory.add(8450) // steel pick
|
inventory.add(8450) // steel pick
|
||||||
inventory.add(8466, 9995) // wire piece
|
inventory.add(8466) // wire piece
|
||||||
inventory.add(9000) // TEST water bucket
|
inventory.add(9000) // TEST water bucket
|
||||||
inventory.add(9001) // TEST lava bucket
|
inventory.add(9001) // TEST lava bucket
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.itemproperties.ItemID
|
import net.torvald.terrarum.itemproperties.ItemID
|
||||||
@@ -78,4 +79,15 @@ interface Pocketed {
|
|||||||
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
|
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
|
||||||
fun hasItem(id: Int) = inventory.contains(id)
|
fun hasItem(id: Int) = inventory.contains(id)
|
||||||
|
|
||||||
|
|
||||||
|
fun consumePrimary(item: GameItem) {
|
||||||
|
if (item.startPrimaryUse(AppLoader.UPDATE_RATE.toFloat())) {
|
||||||
|
inventory.consumeItem(this as Actor, item) // consume on successful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consumeSecondary(item: GameItem) {
|
||||||
|
if (item.startSecondaryUse(AppLoader.UPDATE_RATE.toFloat()))
|
||||||
|
inventory.consumeItem(this as Actor, item) // consume on successful
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.items
|
|
||||||
|
|
||||||
import net.torvald.terrarum.Point2d
|
|
||||||
import net.torvald.terrarum.Point2i
|
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
import net.torvald.terrarum.itemproperties.GameItem
|
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by minjaesong on 2019-05-02.
|
|
||||||
*/
|
|
||||||
object BlockBase {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dontEncaseActors when set to true, blocks won't be placed where Actors are. You will want to set it false
|
|
||||||
* for wire items, otherwise you want it to be true.
|
|
||||||
*/
|
|
||||||
fun blockStartPrimaryUse(gameItem: GameItem, itemID: Int, delta: Float): Boolean {
|
|
||||||
val ingame = Terrarum.ingame!! as Ingame
|
|
||||||
val mousePoint = Point2d(Terrarum.mouseTileX.toDouble(), Terrarum.mouseTileY.toDouble())
|
|
||||||
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
|
||||||
|
|
||||||
// check for collision with actors (BLOCK only)
|
|
||||||
if (gameItem.inventoryCategory == GameItem.Category.BLOCK) {
|
|
||||||
var ret1 = true
|
|
||||||
ingame.actorContainerActive.forEach {
|
|
||||||
if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint))
|
|
||||||
ret1 = false // return is not allowed here
|
|
||||||
}
|
|
||||||
if (!ret1) return ret1
|
|
||||||
}
|
|
||||||
|
|
||||||
// return false if the tile is already there
|
|
||||||
if (gameItem.inventoryCategory == GameItem.Category.BLOCK &&
|
|
||||||
gameItem.dynamicID == ingame.world.getTileFromTerrain(mouseTile.x, mouseTile.y) ||
|
|
||||||
gameItem.inventoryCategory == GameItem.Category.WALL &&
|
|
||||||
gameItem.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(mouseTile.x, mouseTile.y)
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
|
|
||||||
// filter passed, do the job
|
|
||||||
// FIXME this is only useful for Player
|
|
||||||
if (itemID in ItemCodex.ITEM_TILES) {
|
|
||||||
ingame.world.setTileTerrain(
|
|
||||||
mouseTile.x,
|
|
||||||
mouseTile.y,
|
|
||||||
itemID
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ingame.world.setTileWall(
|
|
||||||
mouseTile.x,
|
|
||||||
mouseTile.y,
|
|
||||||
itemID
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun blockEffectWhenEquipped(delta: Float) {
|
|
||||||
IngameRenderer.selectedWireBitToDraw = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fun wireStartPrimaryUse(gameItem: GameItem, wireTypeBit: Int, delta: Float): Boolean {
|
|
||||||
val ingame = Terrarum.ingame!! as Ingame
|
|
||||||
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
|
||||||
|
|
||||||
// return false if the tile is already there
|
|
||||||
if (ingame.world.getWiringBlocks(mouseTile.x, mouseTile.y) and wireTypeBit != 0)
|
|
||||||
return false
|
|
||||||
|
|
||||||
// filter passed, do the job
|
|
||||||
// FIXME this is only useful for Player
|
|
||||||
ingame.world.addNewConduitTo(
|
|
||||||
mouseTile.x,
|
|
||||||
mouseTile.y,
|
|
||||||
GameWorld.WiringNode(
|
|
||||||
LandUtil.getBlockAddr(ingame.world, mouseTile.x, mouseTile.y),
|
|
||||||
wireTypeBit,
|
|
||||||
0f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun wireEffectWhenEquipped(typebit: Int, delta: Float) {
|
|
||||||
IngameRenderer.selectedWireBitToDraw = typebit
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,7 @@ import net.torvald.terrarum.blockproperties.Wire
|
|||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemID
|
import net.torvald.terrarum.itemproperties.ItemID
|
||||||
import net.torvald.terrarum.itemproperties.Material
|
import net.torvald.terrarum.itemproperties.Material
|
||||||
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,10 +32,11 @@ class WirePieceSignalWire(override val originalID: ItemID) : GameItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun startPrimaryUse(delta: Float): Boolean {
|
override fun startPrimaryUse(delta: Float): Boolean {
|
||||||
return BlockBase.wireStartPrimaryUse(this, Wire.BIT_SIGNAL_RED, delta)
|
return super.startPrimaryUse(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun effectWhenEquipped(delta: Float) {
|
override fun effectWhenEquipped(delta: Float) {
|
||||||
BlockBase.wireEffectWhenEquipped(Wire.BIT_SIGNAL_RED, delta)
|
IngameRenderer.selectedWireBitToDraw = Wire.BIT_SIGNAL_RED
|
||||||
|
//println("wires!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
BIN
src/net/torvald/terrarum/terrarum.zip
Normal file
BIN
src/net/torvald/terrarum/terrarum.zip
Normal file
Binary file not shown.
@@ -4,8 +4,8 @@ import com.badlogic.gdx.Gdx
|
|||||||
import com.badlogic.gdx.Input
|
import com.badlogic.gdx.Input
|
||||||
import com.badlogic.gdx.InputAdapter
|
import com.badlogic.gdx.InputAdapter
|
||||||
import com.badlogic.gdx.ScreenAdapter
|
import com.badlogic.gdx.ScreenAdapter
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
@@ -15,22 +15,16 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import com.sudoplay.joise.module.ModuleBasisFunction
|
import com.sudoplay.joise.module.ModuleBasisFunction
|
||||||
import com.sudoplay.joise.module.ModuleFractal
|
import com.sudoplay.joise.module.ModuleFractal
|
||||||
import com.sudoplay.joise.module.ModuleScaleDomain
|
|
||||||
import com.sudoplay.joise.module.ModuleScaleOffset
|
import com.sudoplay.joise.module.ModuleScaleOffset
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.concurrent.BlockingThreadPool
|
import net.torvald.terrarum.concurrent.BlockingThreadPool
|
||||||
import net.torvald.terrarum.concurrent.RunnableFun
|
|
||||||
import net.torvald.terrarum.concurrent.ParallelUtils.sliceEvenly
|
import net.torvald.terrarum.concurrent.ParallelUtils.sliceEvenly
|
||||||
import net.torvald.terrarum.concurrent.ThreadParallel
|
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
import net.torvald.terrarum.roundInt
|
import net.torvald.terrarum.roundInt
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.system.measureNanoTime
|
|
||||||
import kotlin.system.measureTimeMillis
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2018-12-14.
|
* Created by minjaesong on 2018-12-14.
|
||||||
@@ -50,11 +44,11 @@ class NoiseGenerator : ScreenAdapter() {
|
|||||||
Gdx.input.inputProcessor = NoiseGeneratorController(this)
|
Gdx.input.inputProcessor = NoiseGeneratorController(this)
|
||||||
|
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
camera = OrthographicCamera(AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
camera = OrthographicCamera(AppLoader.setWindowWidth.toFloat(), AppLoader.setWindowHeight.toFloat())
|
||||||
|
|
||||||
camera.setToOrtho(true, AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
camera.setToOrtho(true, AppLoader.setWindowWidth.toFloat(), AppLoader.setWindowHeight.toFloat())
|
||||||
camera.update()
|
camera.update()
|
||||||
Gdx.gl20.glViewport(0, 0, AppLoader.appConfig.width, AppLoader.appConfig.height)
|
Gdx.gl20.glViewport(0, 0, AppLoader.setWindowWidth, AppLoader.setWindowHeight)
|
||||||
|
|
||||||
pixmap = Pixmap(IMAGE_SIZE, IMAGE_SIZE, Pixmap.Format.RGBA8888)
|
pixmap = Pixmap(IMAGE_SIZE, IMAGE_SIZE, Pixmap.Format.RGBA8888)
|
||||||
texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
||||||
@@ -255,14 +249,10 @@ class NoiseGeneratorController(val host: NoiseGenerator) : InputAdapter() {
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
|
|
||||||
val appConfig = LwjglApplicationConfiguration()
|
val appConfig = Lwjgl3ApplicationConfiguration()
|
||||||
appConfig.vSyncEnabled = false
|
appConfig.useVsync(false)
|
||||||
appConfig.resizable = false//true;
|
appConfig.setResizable(false)
|
||||||
appConfig.width = 1024
|
appConfig.setWindowedMode(1024, 1024)
|
||||||
appConfig.height = 1024
|
|
||||||
appConfig.backgroundFPS = 9999
|
|
||||||
appConfig.foregroundFPS = 9999
|
|
||||||
appConfig.forceExit = false
|
|
||||||
|
|
||||||
LwjglApplication(AppLoader(appConfig, NoiseGenerator()), appConfig)
|
Lwjgl3Application(AppLoader(appConfig, NoiseGenerator(), 1024, 1024), appConfig)
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,8 @@ package net.torvald.terrarum.tests
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.InputAdapter
|
import com.badlogic.gdx.InputAdapter
|
||||||
import com.badlogic.gdx.ScreenAdapter
|
import com.badlogic.gdx.ScreenAdapter
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
@@ -67,13 +67,13 @@ class UITestPad1 : ScreenAdapter() {
|
|||||||
Yaml(treeStr)
|
Yaml(treeStr)
|
||||||
)
|
)
|
||||||
batch = SpriteBatch()
|
batch = SpriteBatch()
|
||||||
camera = OrthographicCamera(AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
camera = OrthographicCamera(AppLoader.setWindowWidth.toFloat(), AppLoader.setWindowHeight.toFloat())
|
||||||
|
|
||||||
camera.setToOrtho(true, AppLoader.appConfig.width.toFloat(), AppLoader.appConfig.height.toFloat())
|
camera.setToOrtho(true, AppLoader.setWindowWidth.toFloat(), AppLoader.setWindowHeight.toFloat())
|
||||||
camera.update()
|
camera.update()
|
||||||
Gdx.gl20.glViewport(0, 0, AppLoader.appConfig.width, AppLoader.appConfig.height)
|
Gdx.gl20.glViewport(0, 0, AppLoader.setWindowWidth, AppLoader.setWindowHeight)
|
||||||
|
|
||||||
resize(AppLoader.appConfig.width, AppLoader.appConfig.height)
|
resize(AppLoader.setWindowWidth, AppLoader.setWindowHeight)
|
||||||
|
|
||||||
nsMenu.setPosition(0, 0)
|
nsMenu.setPosition(0, 0)
|
||||||
nsMenu.setAsAlwaysVisible()
|
nsMenu.setAsAlwaysVisible()
|
||||||
@@ -148,16 +148,8 @@ class UITestPad1Controller(val host: UITestPad1) : InputAdapter() {
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
ShaderProgram.pedantic = false
|
ShaderProgram.pedantic = false
|
||||||
|
|
||||||
val appConfig = LwjglApplicationConfiguration()
|
val appConfig = Lwjgl3ApplicationConfiguration()
|
||||||
appConfig.vSyncEnabled = false
|
appConfig.setWindowedMode(1110, 740)
|
||||||
appConfig.resizable = false//true;
|
|
||||||
//appConfig.width = 1072; // IMAX ratio
|
|
||||||
//appConfig.height = 742; // IMAX ratio
|
|
||||||
appConfig.width = 1110 // photographic ratio (1.5:1)
|
|
||||||
appConfig.height = 740 // photographic ratio (1.5:1)
|
|
||||||
appConfig.backgroundFPS = 9999
|
|
||||||
appConfig.foregroundFPS = 9999
|
|
||||||
appConfig.forceExit = false
|
|
||||||
|
|
||||||
LwjglApplication(AppLoader(appConfig, UITestPad1()), appConfig)
|
Lwjgl3Application(AppLoader(appConfig, UITestPad1(), 1110, 740), appConfig)
|
||||||
}
|
}
|
||||||
@@ -150,13 +150,11 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
printLine(batch, 8, "light@cursor $ccG$lightVal")
|
printLine(batch, 8, "light@cursor $ccG$lightVal")
|
||||||
|
|
||||||
if (ingame != null) {
|
if (ingame != null) {
|
||||||
val wallNum = ingame!!.world.getTileFromWall(mouseTileX, mouseTileY) ?: -1
|
|
||||||
val tileNum = ingame!!.world.getTileFromTerrain(mouseTileX, mouseTileY) ?: -1
|
val tileNum = ingame!!.world.getTileFromTerrain(mouseTileX, mouseTileY) ?: -1
|
||||||
val wireNum = ingame!!.world.getWiringBlocks(mouseTileX, mouseTileY)
|
|
||||||
val fluid = ingame!!.world.getFluid(mouseTileX, mouseTileY)
|
val fluid = ingame!!.world.getFluid(mouseTileX, mouseTileY)
|
||||||
|
|
||||||
printLine(batch, 9, "tile@cursor ${ccO}W$ccG$wallNum ${ccO}T$ccG$tileNum ${ccO}C$ccG${wireNum.toString(2)} $ccY($mtX, $mtY)")
|
printLine(batch, 9, "tile@cursor $ccG$tileNum ($mtX, $mtY)")
|
||||||
printLine(batch, 10, "fluid@cursor ${ccO}Type $ccG${fluid.type.value} ${ccO}Fill $ccG${fluid.amount}f")
|
printLine(batch, 10, "fluid@cursor ${ccY}Type $ccM${fluid.type.value} ${ccY}Fill $ccG${fluid.amount}f")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ abstract class UICanvas(
|
|||||||
uiItems.add(uiItem)
|
uiItems.add(uiItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mouseInScreen(x: Int, y: Int) = x in 0 until AppLoader.appConfig.width && y in 0 until AppLoader.appConfig.height
|
fun mouseInScreen(x: Int, y: Int) = x in 0 until AppLoader.setWindowWidth && y in 0 until AppLoader.setWindowHeight
|
||||||
|
|
||||||
open fun mouseMoved(screenX: Int, screenY: Int): Boolean {
|
open fun mouseMoved(screenX: Int, screenY: Int): Boolean {
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import kotlin.math.roundToInt
|
|||||||
* in the shader (tiling.frag). This will not be a problem in the base game, but if you are modifying
|
* in the shader (tiling.frag). This will not be a problem in the base game, but if you are modifying
|
||||||
* this engine for your project, you must edit the shader program accordingly.
|
* this engine for your project, you must edit the shader program accordingly.
|
||||||
*
|
*
|
||||||
* To render and draw images, modify the ```selectedWireBitToDraw``` (bitset) property from the IngameRenderer.
|
|
||||||
*
|
|
||||||
* Created by minjaesong on 2016-01-19.
|
* Created by minjaesong on 2016-01-19.
|
||||||
*/
|
*/
|
||||||
internal object BlocksDrawer {
|
internal object BlocksDrawer {
|
||||||
@@ -123,8 +121,10 @@ internal object BlocksDrawer {
|
|||||||
TextureRegionPack(Texture(CreateTileAtlas.atlasWinter), TILE_SIZE, TILE_SIZE)
|
TextureRegionPack(Texture(CreateTileAtlas.atlasWinter), TILE_SIZE, TILE_SIZE)
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO make wire work with the TileAtlas system
|
// unzip tga.gz for tilesWire and tilesFluid
|
||||||
tilesWire = TextureRegionPack(ModMgr.getGdxFile("basegame", "blocks/wire.tga"), TILE_SIZE, TILE_SIZE)
|
|
||||||
|
//TODO
|
||||||
|
tilesWire = TextureRegionPack(Texture(8, 8, Pixmap.Format.RGBA8888), 1, 1)
|
||||||
tilesFluid = TextureRegionPack(Texture(CreateTileAtlas.atlasFluid), TILE_SIZE, TILE_SIZE)
|
tilesFluid = TextureRegionPack(Texture(CreateTileAtlas.atlasFluid), TILE_SIZE, TILE_SIZE)
|
||||||
|
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ internal object BlocksDrawer {
|
|||||||
// NO draw lightmap using colour filter, actors must also be hidden behind the darkness
|
// NO draw lightmap using colour filter, actors must also be hidden behind the darkness
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
internal fun renderData() {
|
internal fun renderData(wireBit: Int) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
drawTIME_T = (world as GameWorldExtension).time.TIME_T - (WorldTime.DAY_LENGTH * 15) // offset by -15 days
|
drawTIME_T = (world as GameWorldExtension).time.TIME_T - (WorldTime.DAY_LENGTH * 15) // offset by -15 days
|
||||||
@@ -198,7 +198,7 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
drawTiles(WALL)
|
drawTiles(WALL)
|
||||||
drawTiles(TERRAIN) // regular tiles
|
drawTiles(TERRAIN) // regular tiles
|
||||||
drawTiles(WIRE)
|
drawTiles(WIRE, wireBit)
|
||||||
drawTiles(FLUID)
|
drawTiles(FLUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,9 +215,6 @@ internal object BlocksDrawer {
|
|||||||
renderUsingBuffer(FLUID, projectionMatrix)
|
renderUsingBuffer(FLUID, projectionMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
var drawWires = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
internal fun drawFront(projectionMatrix: Matrix4, drawWires: Int) {
|
internal fun drawFront(projectionMatrix: Matrix4, drawWires: Int) {
|
||||||
// blend mul
|
// blend mul
|
||||||
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
|
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D)
|
||||||
@@ -231,9 +228,8 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
gdxSetBlendNormal()
|
gdxSetBlendNormal()
|
||||||
|
|
||||||
this.drawWires = drawWires
|
|
||||||
if (drawWires != 0) {
|
if (drawWires != 0) {
|
||||||
//println("Wires! draw: $drawWires") // use F10 instead
|
//println("drawing wires")
|
||||||
renderUsingBuffer(WIRE, projectionMatrix)
|
renderUsingBuffer(WIRE, projectionMatrix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,12 +261,14 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
||||||
* @return 0 -> -1, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
* @return 0 -> null, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
||||||
*/
|
*/
|
||||||
private fun Int.toBitOrd(): Int {
|
private fun Int.toBitOrd(): Int? =
|
||||||
val k = FastMath.intLog2(this, -1)
|
if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this")
|
||||||
return k
|
else {
|
||||||
}
|
val k = FastMath.intLog2(this, -1)
|
||||||
|
if (k == -1) null else k
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes to buffer. Actual draw code must be called after this operation.
|
* Writes to buffer. Actual draw code must be called after this operation.
|
||||||
@@ -278,7 +276,7 @@ internal object BlocksDrawer {
|
|||||||
* @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID.
|
* @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID.
|
||||||
* @param wire coduitTypes bit that is selected to be drawn. Must be the power of two.
|
* @param wire coduitTypes bit that is selected to be drawn. Must be the power of two.
|
||||||
*/
|
*/
|
||||||
private fun drawTiles(mode: Int) {
|
private fun drawTiles(mode: Int, wireBit: Int = 0) {
|
||||||
// can't be "WorldCamera.y / TILE_SIZE":
|
// can't be "WorldCamera.y / TILE_SIZE":
|
||||||
// ( 3 / 16) == 0
|
// ( 3 / 16) == 0
|
||||||
// (-3 / 16) == -1 <-- We want it to be '-1', not zero
|
// (-3 / 16) == -1 <-- We want it to be '-1', not zero
|
||||||
@@ -307,7 +305,7 @@ internal object BlocksDrawer {
|
|||||||
val thisTile = when (mode) {
|
val thisTile = when (mode) {
|
||||||
WALL -> world.getTileFromWall(x, y)
|
WALL -> world.getTileFromWall(x, y)
|
||||||
TERRAIN -> world.getTileFromTerrain(x, y)
|
TERRAIN -> world.getTileFromTerrain(x, y)
|
||||||
WIRE -> world.getWiringBlocks(x, y).and(drawWires).toBitOrd() * 16
|
WIRE -> world.getWires(x, y).and(wireBit).toBitOrd()
|
||||||
FLUID -> world.getFluid(x, y).type.abs()
|
FLUID -> world.getFluid(x, y).type.abs()
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
@@ -318,9 +316,6 @@ internal object BlocksDrawer {
|
|||||||
val nearbyTilesInfo = if (mode == FLUID) {
|
val nearbyTilesInfo = if (mode == FLUID) {
|
||||||
getNearbyTilesInfoFluids(x, y)
|
getNearbyTilesInfoFluids(x, y)
|
||||||
}
|
}
|
||||||
else if (mode == WIRE) {
|
|
||||||
getNearbyWiringInfo(x, y, thisTile)
|
|
||||||
}
|
|
||||||
else if (isPlatform(thisTile)) {
|
else if (isPlatform(thisTile)) {
|
||||||
getNearbyTilesInfoPlatform(x, y)
|
getNearbyTilesInfoPlatform(x, y)
|
||||||
}
|
}
|
||||||
@@ -341,16 +336,10 @@ internal object BlocksDrawer {
|
|||||||
val tileNumberBase =
|
val tileNumberBase =
|
||||||
if (mode == FLUID)
|
if (mode == FLUID)
|
||||||
CreateTileAtlas.fluidToTileNumber(world.getFluid(x, y))
|
CreateTileAtlas.fluidToTileNumber(world.getFluid(x, y))
|
||||||
else if (mode == WIRE)
|
|
||||||
thisTile
|
|
||||||
else
|
else
|
||||||
renderTag.tileNumber
|
renderTag.tileNumber
|
||||||
val tileNumber = if (mode != WIRE && thisTile == 0) 0
|
val tileNumber = if (thisTile == 0) 0
|
||||||
// special case: fluids
|
|
||||||
else if (mode == FLUID) tileNumberBase + connectLut47[nearbyTilesInfo]
|
else if (mode == FLUID) tileNumberBase + connectLut47[nearbyTilesInfo]
|
||||||
// special case: wires
|
|
||||||
else if (mode == WIRE) tileNumberBase + connectLut16[nearbyTilesInfo]
|
|
||||||
// rest of the cases: terrain and walls
|
|
||||||
else tileNumberBase + when (renderTag.maskType) {
|
else tileNumberBase + when (renderTag.maskType) {
|
||||||
CreateTileAtlas.RenderTag.MASK_NA -> 0
|
CreateTileAtlas.RenderTag.MASK_NA -> 0
|
||||||
CreateTileAtlas.RenderTag.MASK_16 -> connectLut16[nearbyTilesInfo]
|
CreateTileAtlas.RenderTag.MASK_16 -> connectLut16[nearbyTilesInfo]
|
||||||
@@ -374,11 +363,7 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
// draw a tile
|
// draw a tile
|
||||||
|
|
||||||
if (mode == WIRE && thisTile < 0) {
|
if (mode == FLUID) {
|
||||||
// no wire here, draw block id 255 (bottom right)
|
|
||||||
writeToBuffer(mode, bufferX, bufferY, 15, 15, 0)
|
|
||||||
}
|
|
||||||
else if (mode == FLUID || mode == WIRE) {
|
|
||||||
writeToBuffer(mode, bufferX, bufferY, thisTileX, thisTileY, 0)
|
writeToBuffer(mode, bufferX, bufferY, thisTileX, thisTileY, 0)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -417,25 +402,6 @@ internal object BlocksDrawer {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param wire -1 for none, 0 for signal red, 1 for untility prototype, 2 for low power, 3 for high power;
|
|
||||||
* log of bits defined in [net.torvald.terrarum.blockproperties.Wire]
|
|
||||||
*
|
|
||||||
* @return offset from the spritesheet's "base" tile number, 0..15.
|
|
||||||
*/
|
|
||||||
private fun getNearbyWiringInfo(x: Int, y: Int, wire: Int): Int {
|
|
||||||
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getWiringBlocks(it.x, it.y).and(drawWires).toBitOrd() * 16 }
|
|
||||||
|
|
||||||
var ret = 0
|
|
||||||
for (i in 0 until nearbyTiles.size) {
|
|
||||||
if (nearbyTiles[i] == wire) {
|
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getNearbyTilesInfoConMutual(x: Int, y: Int, mode: Int): Int {
|
private fun getNearbyTilesInfoConMutual(x: Int, y: Int, mode: Int): Int {
|
||||||
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
||||||
|
|
||||||
@@ -635,7 +601,6 @@ internal object BlocksDrawer {
|
|||||||
else
|
else
|
||||||
0f
|
0f
|
||||||
)
|
)
|
||||||
shader.setUniformf("drawBreakage", if (mode == WIRE) 0f else 1f)
|
|
||||||
tilesQuad.render(shader, GL20.GL_TRIANGLES)
|
tilesQuad.render(shader, GL20.GL_TRIANGLES)
|
||||||
shader.end()
|
shader.end()
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import net.torvald.terrarum.concurrent.ParallelUtils.sliceEvenly
|
|||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameactors.Luminous
|
import net.torvald.terrarum.gameactors.Luminous
|
||||||
|
import net.torvald.terrarum.gameworld.BlockAddress
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
@@ -33,7 +34,6 @@ import net.torvald.terrarum.realestate.LandUtil
|
|||||||
*/
|
*/
|
||||||
object LightmapRenderer {
|
object LightmapRenderer {
|
||||||
private const val TILE_SIZE = CreateTileAtlas.TILE_SIZE
|
private const val TILE_SIZE = CreateTileAtlas.TILE_SIZE
|
||||||
private const val SQRT2 = 1.41421356f
|
|
||||||
|
|
||||||
private var world: GameWorld = GameWorld.makeNullWorld()
|
private var world: GameWorld = GameWorld.makeNullWorld()
|
||||||
private lateinit var lightCalcShader: ShaderProgram
|
private lateinit var lightCalcShader: ShaderProgram
|
||||||
@@ -83,51 +83,7 @@ object LightmapRenderer {
|
|||||||
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
|
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
|
||||||
//private val lightmap: Array<Array<Color>> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH, { Color(0f,0f,0f,0f) }) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
|
//private val lightmap: Array<Array<Color>> = Array(LIGHTMAP_HEIGHT) { Array(LIGHTMAP_WIDTH, { Color(0f,0f,0f,0f) }) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
|
||||||
private val lightmap: Array<Color> = Array(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Color(0f,0f,0f,0f) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
|
private val lightmap: Array<Color> = Array(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Color(0f,0f,0f,0f) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4.
|
||||||
|
private val lanternMap = HashMap<BlockAddress, Color>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
||||||
/**
|
|
||||||
* Sstores both the block light sources and actor light sources.
|
|
||||||
*/
|
|
||||||
//private val lightSourcesMap = HashMap<BlockAddress, Color>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
|
||||||
private val lightSourcesMap = Array<Color>(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Color(0) }
|
|
||||||
private fun toLightOffset(y: Int, x: Int): Int {
|
|
||||||
val xpos = x - for_x_start + overscan_open
|
|
||||||
val ypos = y - for_y_start + overscan_open
|
|
||||||
val index = ypos * LIGHTMAP_WIDTH + xpos
|
|
||||||
|
|
||||||
if (index >= lightSourcesMap.size)
|
|
||||||
println("$x, $y | $xpos, $ypos | $for_x_start, $for_y_start | $index")
|
|
||||||
|
|
||||||
return index
|
|
||||||
}
|
|
||||||
private fun getLightSourceMap(worldX: Int, worldY: Int) =
|
|
||||||
lightSourcesMap[toLightOffset(worldX, worldY)]
|
|
||||||
private fun setLightSourcesMap(worldX: Int, worldY: Int, value: Color) {
|
|
||||||
lightSourcesMap[toLightOffset(worldX, worldY)] = value
|
|
||||||
}
|
|
||||||
private fun mixLightSourcesMap(worldX: Int, worldY: Int, value: Color) {
|
|
||||||
lightSourcesMap[toLightOffset(worldX, worldY)].maxAndAssign(value)
|
|
||||||
}
|
|
||||||
private fun clearLightSourcesOffset() {
|
|
||||||
for (i in 0 until lightSourcesMap.size) { lightSourcesMap[i] = Color(0) }
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Pair of: Regular shade, the former shade times 1.4142
|
|
||||||
*/
|
|
||||||
//private val shadesMap = HashMap<BlockAddress, Pair<Color, Color>>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
|
||||||
private val shadesMap = Array<Pair<Color, Color>>(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Color(0) to Color(0) }
|
|
||||||
private fun getShadesMap(worldX: Int, worldY: Int) =
|
|
||||||
shadesMap[toLightOffset(worldX, worldY)]
|
|
||||||
private fun setShadesMap(worldX: Int, worldY: Int, value: Color) {
|
|
||||||
shadesMap[toLightOffset(worldX, worldY)] = value to (value.cpy().mul(SQRT2))
|
|
||||||
}
|
|
||||||
private fun mixShadesMap(worldX: Int, worldY: Int, value: Color) {
|
|
||||||
val field = shadesMap[toLightOffset(worldX, worldY)]
|
|
||||||
val baseval = field.first.maxAndAssign(value)
|
|
||||||
field.second.set(baseval); field.second.mul(SQRT2)
|
|
||||||
}
|
|
||||||
private fun clearShadesMap() {
|
|
||||||
for (i in 0 until shadesMap.size) { shadesMap[i] = Color(0) to Color(0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
||||||
@@ -245,15 +201,8 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
//println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
|
//println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
|
||||||
|
|
||||||
// set sunlight
|
AppLoader.measureDebugTime("Renderer.Lanterns") {
|
||||||
sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT)
|
buildLanternmap(actorContainers)
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightPreload") {
|
|
||||||
// this is to recycle pre-calculated lights and shades for all 4 rounds.
|
|
||||||
// the old code always re-calculates them (calls 'getLightsAndShades()') for every blocks for every round.
|
|
||||||
// the light source information can also be used to create no-op mask? I'm sceptical about that, there must
|
|
||||||
// exist some edge cases like the other time...
|
|
||||||
buildLightSourcesMap(actorContainers)
|
|
||||||
} // usually takes 3000 ns
|
} // usually takes 3000 ns
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -270,6 +219,9 @@ object LightmapRenderer {
|
|||||||
* If you run only 4 sets, orthogonal/diagonal artefacts are bound to occur,
|
* If you run only 4 sets, orthogonal/diagonal artefacts are bound to occur,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// set sunlight
|
||||||
|
sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT)
|
||||||
|
|
||||||
// set no-op mask from solidity of the block
|
// set no-op mask from solidity of the block
|
||||||
AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
|
AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
|
||||||
noopMask.clear()
|
noopMask.clear()
|
||||||
@@ -293,7 +245,6 @@ object LightmapRenderer {
|
|||||||
// The skipping is dependent on how you get ambient light,
|
// The skipping is dependent on how you get ambient light,
|
||||||
// in this case we have 'spillage' due to the fact calculate() samples 3x3 area.
|
// in this case we have 'spillage' due to the fact calculate() samples 3x3 area.
|
||||||
|
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
||||||
// Round 2
|
// Round 2
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
@@ -380,22 +331,8 @@ object LightmapRenderer {
|
|||||||
internal data class ThreadedLightmapUpdateMessage(val x: Int, val y: Int)
|
internal data class ThreadedLightmapUpdateMessage(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
|
||||||
private var _block = 0
|
private fun buildLanternmap(actorContainers: Array<out List<ActorWithBody>?>) {
|
||||||
private var _blockProp = BlockCodex[0]
|
lanternMap.clear()
|
||||||
private var _wall = 0
|
|
||||||
private var _blockLum = Color(0)
|
|
||||||
private var _fluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
|
|
||||||
private var _fluidProp = BlockCodex[_fluid.type]
|
|
||||||
private var _tileAddr = 0L
|
|
||||||
private var _fluidAmountToCol = Color(0)
|
|
||||||
|
|
||||||
private fun buildLightSourcesMap(actorContainers: Array<out List<ActorWithBody>?>) {
|
|
||||||
clearLightSourcesOffset()
|
|
||||||
clearShadesMap()
|
|
||||||
|
|
||||||
//lightSourcesMapOffset.set(for_x_start - overscan_open, for_y_start + overscan_open)
|
|
||||||
|
|
||||||
// lanterns from actors
|
|
||||||
actorContainers.forEach { actorContainer ->
|
actorContainers.forEach { actorContainer ->
|
||||||
actorContainer?.forEach {
|
actorContainer?.forEach {
|
||||||
if (it is Luminous && it is ActorWBMovable) {
|
if (it is Luminous && it is ActorWBMovable) {
|
||||||
@@ -412,55 +349,17 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
val normalisedColor = it.color//.cpy().mul(DIV_FLOAT)
|
val normalisedColor = it.color//.cpy().mul(DIV_FLOAT)
|
||||||
|
|
||||||
//lightSourcesMap[LandUtil.getBlockAddr(world, x, y)] = normalisedColor
|
lanternMap[LandUtil.getBlockAddr(world, x, y)] = normalisedColor
|
||||||
setLightSourcesMap(x, y, normalisedColor)
|
//lanternMap[Point2i(x, y)] = normalisedColor
|
||||||
|
|
||||||
//lightSourcesMap[Point2i(x, y)] = normalisedColor
|
|
||||||
// Q&D fix for Roundworld anomaly
|
// Q&D fix for Roundworld anomaly
|
||||||
//lightSourcesMap[Point2i(x + world.width, y)] = normalisedColor
|
//lanternMap[Point2i(x + world.width, y)] = normalisedColor
|
||||||
//lightSourcesMap[Point2i(x - world.width, y)] = normalisedColor
|
//lanternMap[Point2i(x - world.width, y)] = normalisedColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// light sources and shades from a block
|
|
||||||
for (y in for_y_start - overscan_open..for_y_end + overscan_open) {
|
|
||||||
for (x in for_x_start - overscan_open..for_x_end + overscan_open) {
|
|
||||||
_block = world.getTileFromTerrain(x, y) ?: Block.STONE
|
|
||||||
_blockProp = BlockCodex[_block]
|
|
||||||
_wall = world.getTileFromWall(x, y) ?: Block.STONE
|
|
||||||
_blockLum = _blockProp.luminosity
|
|
||||||
_fluid = world.getFluid(x, y)
|
|
||||||
_fluidProp = BlockCodex[_fluid.type]
|
|
||||||
_tileAddr = LandUtil.getBlockAddr(world, x, y)
|
|
||||||
_fluidAmountToCol = Color(_fluid.amount.coerceIn(0f, 1f))
|
|
||||||
|
|
||||||
// light sources from blocks //
|
|
||||||
|
|
||||||
// mix with the existing value
|
|
||||||
mixLightSourcesMap(x, y, _blockLum)
|
|
||||||
|
|
||||||
// see if sunlight is applicable. If it does, mix with the existing value
|
|
||||||
if ((_block == AIR && _wall == AIR) || (_blockLum.nonZero() && _wall == AIR)) {
|
|
||||||
mixLightSourcesMap(x, y, sunLight)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mix the lava light
|
|
||||||
if (_fluid.type != Fluid.NULL) {
|
|
||||||
mixLightSourcesMap(x, y, _fluidProp.luminosity mul _fluidAmountToCol)
|
|
||||||
}
|
|
||||||
|
|
||||||
// deal with the shades //
|
|
||||||
|
|
||||||
// shade from the block
|
|
||||||
setShadesMap(x, y, _blockProp.opacity)
|
|
||||||
// shade from the fluid
|
|
||||||
mixShadesMap(x, y, _fluidProp.opacity mul _fluidAmountToCol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildNoopMask() {
|
private fun buildNoopMask() {
|
||||||
@@ -495,14 +394,14 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
|
|
||||||
//private val ambientAccumulator = Color(0f,0f,0f,0f)
|
//private val ambientAccumulator = Color(0f,0f,0f,0f)
|
||||||
//private val lightLevelThis = Color(0)
|
private val lightLevelThis = Color(0)
|
||||||
//private var thisTerrain = 0
|
private var thisTerrain = 0
|
||||||
//private var thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
|
private var thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
|
||||||
//private val fluidAmountToCol = Color(0)
|
private val fluidAmountToCol = Color(0)
|
||||||
//private var thisWall = 0
|
private var thisWall = 0
|
||||||
//private val thisTileLuminosity = Color(0)
|
private val thisTileLuminosity = Color(0)
|
||||||
//private val thisTileOpacity = Color(0)
|
private val thisTileOpacity = Color(0)
|
||||||
//private val thisTileOpacity2 = Color(0) // thisTileOpacity * sqrt(2)
|
private val thisTileOpacity2 = Color(0) // thisTileOpacity * sqrt(2)
|
||||||
private val sunLight = Color(0)
|
private val sunLight = Color(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -516,10 +415,7 @@ object LightmapRenderer {
|
|||||||
* - thisTileOpacity2
|
* - thisTileOpacity2
|
||||||
* - sunlight
|
* - sunlight
|
||||||
*/
|
*/
|
||||||
/*private fun getLightsAndShades(x: Int, y: Int) {
|
private fun getLightsAndShades(x: Int, y: Int) {
|
||||||
// TODO lanternmap now also holds light sources (incl. sunlight)
|
|
||||||
|
|
||||||
|
|
||||||
lightLevelThis.set(colourNull)
|
lightLevelThis.set(colourNull)
|
||||||
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
|
thisTerrain = world.getTileFromTerrain(x, y) ?: Block.STONE
|
||||||
thisFluid = world.getFluid(x, y)
|
thisFluid = world.getFluid(x, y)
|
||||||
@@ -548,9 +444,9 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// blend lantern
|
// blend lantern
|
||||||
lightLevelThis.maxAndAssign(thisTileLuminosity).maxAndAssign(lightSourcesMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
|
lightLevelThis.maxAndAssign(thisTileLuminosity).maxAndAssign(lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
|
||||||
|
|
||||||
}*/
|
}
|
||||||
|
|
||||||
private val inNoopMaskp = Point2i(0,0)
|
private val inNoopMaskp = Point2i(0,0)
|
||||||
|
|
||||||
@@ -609,9 +505,7 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
// O(9n) == O(n) where n is a size of the map
|
// O(9n) == O(n) where n is a size of the map
|
||||||
|
|
||||||
//getLightsAndShades(x, y)
|
getLightsAndShades(x, y)
|
||||||
val lightLevelThis = getLightSourceMap(x, y) // it HAS to be a cpy()...?, otherwise all cells gets the same instance
|
|
||||||
val (thisTileOpacity, thisTileOpacity2) = getShadesMap(x, y)
|
|
||||||
|
|
||||||
// calculate ambient
|
// calculate ambient
|
||||||
/* + * + 0 4 1
|
/* + * + 0 4 1
|
||||||
@@ -622,7 +516,6 @@ object LightmapRenderer {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// will "overwrite" what's there in the lightmap if it's the first pass
|
// will "overwrite" what's there in the lightmap if it's the first pass
|
||||||
// using "map"s actually makes it slower. Guess I'll keep it dirty...
|
|
||||||
// takes about 2 ms on 6700K
|
// takes about 2 ms on 6700K
|
||||||
/* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x - 1, y - 1) ?: colourNull, thisTileOpacity2))
|
/* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x - 1, y - 1) ?: colourNull, thisTileOpacity2))
|
||||||
/* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x + 1, y - 1) ?: colourNull, thisTileOpacity2))
|
/* + */lightLevelThis.maxAndAssign(darkenColoured(getLightInternal(x + 1, y - 1) ?: colourNull, thisTileOpacity2))
|
||||||
@@ -635,7 +528,7 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
|
|
||||||
//return lightLevelThis.cpy() // it HAS to be a cpy(), otherwise all cells gets the same instance
|
//return lightLevelThis.cpy() // it HAS to be a cpy(), otherwise all cells gets the same instance
|
||||||
setLightOf(lightmap, x, y, lightLevelThis)
|
setLightOf(lightmap, x, y, lightLevelThis.cpy())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLightForOpaque(x: Int, y: Int): Color? { // ...so that they wouldn't appear too dark
|
private fun getLightForOpaque(x: Int, y: Int): Color? { // ...so that they wouldn't appear too dark
|
||||||
@@ -994,4 +887,4 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Color.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt()
|
fun Color.toRGBA() = (255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt()
|
||||||
//fun Color(c: Float) = Color(c, c, c, c)
|
|
||||||
|
|||||||
@@ -39,66 +39,9 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) {
|
|||||||
|
|
||||||
fun removeAt(index: Int) = arrayList.removeAt(index)
|
fun removeAt(index: Int) = arrayList.removeAt(index)
|
||||||
fun remove(element: T) = arrayList.remove(element)
|
fun remove(element: T) = arrayList.remove(element)
|
||||||
fun removeLast() = arrayList.removeAt(arrayList.size - 1)
|
fun removeLast() = arrayList.removeAt(arrayList.size)
|
||||||
|
|
||||||
operator fun get(index: Int) = arrayList[index]
|
operator fun get(index: Int) = arrayList[index]
|
||||||
fun getOrNull(index: Int?) = if (index == null) null else get(index)
|
|
||||||
/**
|
|
||||||
* Searches for the element. Null if the element was not found
|
|
||||||
*/
|
|
||||||
fun contains(element: T): Boolean {
|
|
||||||
// code from collections/Collections.kt
|
|
||||||
var low = 0
|
|
||||||
var high = this.size - 1
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
val mid = (low + high).ushr(1) // safe from overflows
|
|
||||||
|
|
||||||
val midVal = get(mid)
|
|
||||||
|
|
||||||
if (element > midVal)
|
|
||||||
low = mid + 1
|
|
||||||
else if (element < midVal)
|
|
||||||
high = mid - 1
|
|
||||||
else
|
|
||||||
return true // key found
|
|
||||||
}
|
|
||||||
return false // key not found
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Searches the element using given predicate instead of the element itself. Returns index in the array where desired, null when there is no such element.
|
|
||||||
* element is stored.
|
|
||||||
* (e.g. search the Actor by its ID rather than the actor instance)
|
|
||||||
*
|
|
||||||
* @param searchQuery what exactly are we looking for?
|
|
||||||
* @param searchHow and where or how can it be found?
|
|
||||||
*/
|
|
||||||
fun <R: Comparable<R>> searchForIndex(searchQuery: R, searchHow: (T) -> R): Int? {
|
|
||||||
var low = 0
|
|
||||||
var high = this.size - 1
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
val mid = (low + high).ushr(1) // safe from overflows
|
|
||||||
|
|
||||||
val midVal = searchHow(get(mid))
|
|
||||||
|
|
||||||
if (searchQuery > midVal)
|
|
||||||
low = mid + 1
|
|
||||||
else if (searchQuery < midVal)
|
|
||||||
high = mid - 1
|
|
||||||
else
|
|
||||||
return mid // key found
|
|
||||||
}
|
|
||||||
return null // key not found
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Searches the element using given predicate instead of the element itself. Returns the element desired, null when there is no such element.
|
|
||||||
* (e.g. search the Actor by its ID rather than the actor instance)
|
|
||||||
*
|
|
||||||
* @param searchQuery what exactly are we looking for?
|
|
||||||
* @param searchHow and where or how can it be found?
|
|
||||||
*/
|
|
||||||
fun <R: Comparable<R>> searchFor(searchQuery: R, searchHow: (T) -> R): T? = getOrNull(searchForIndex(searchQuery, searchHow))
|
|
||||||
|
|
||||||
fun iterator() = arrayList.iterator()
|
fun iterator() = arrayList.iterator()
|
||||||
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
fun forEach(action: (T) -> Unit) = arrayList.forEach(action)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user