mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 02:24:05 +09:00
Compare commits
25 Commits
test-cvec-
...
unsafe-arr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f8c3591c2 | ||
|
|
a1d51d4028 | ||
|
|
593a528d32 | ||
|
|
4a99722f71 | ||
|
|
97f8aa6e6e | ||
|
|
85ab1b823d | ||
|
|
812e9e5b76 | ||
|
|
a87866438f | ||
|
|
c692928c1a | ||
|
|
5ff0c22b0f | ||
|
|
eb1273c561 | ||
|
|
50c110f34b | ||
|
|
c180953d7d | ||
|
|
a1ac9b177a | ||
|
|
c50d07b541 | ||
|
|
56fdb2f556 | ||
|
|
d2ddca85a6 | ||
|
|
9aa002f4cc | ||
|
|
3a5fcb9ba0 | ||
|
|
7d5a37cd6d | ||
|
|
75c79d8ca2 | ||
|
|
0b7a3a5636 | ||
|
|
c5e0de2393 | ||
|
|
19fb5b1319 | ||
|
|
2fff2c24cf |
5
.idea/compiler.xml
generated
5
.idea/compiler.xml
generated
@@ -4,10 +4,7 @@
|
|||||||
<annotationProcessing>
|
<annotationProcessing>
|
||||||
<profile default="true" name="Default" enabled="true" />
|
<profile default="true" name="Default" enabled="true" />
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
<bytecodeTargetLevel target="10">
|
<bytecodeTargetLevel target="8" />
|
||||||
<module name="terrarum_main" target="11" />
|
|
||||||
<module name="terrarum_test" target="11" />
|
|
||||||
</bytecodeTargetLevel>
|
|
||||||
</component>
|
</component>
|
||||||
<component name="JavacSettings">
|
<component name="JavacSettings">
|
||||||
<option name="PREFER_TARGET_JDK_COMPILER" value="false" />
|
<option name="PREFER_TARGET_JDK_COMPILER" value="false" />
|
||||||
|
|||||||
8
.idea/markdown-exported-files.xml
generated
Normal file
8
.idea/markdown-exported-files.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MarkdownExportedFiles">
|
||||||
|
<htmlFiles />
|
||||||
|
<imageFiles />
|
||||||
|
<otherFiles />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -38,7 +38,7 @@
|
|||||||
<property name="caretWidth" class="java.lang.Integer" />
|
<property name="caretWidth" class="java.lang.Integer" />
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_10" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
Binary file not shown.
BIN
assets/graphics/gui/message_black_tileable.tga
LFS
Normal file
BIN
assets/graphics/gui/message_black_tileable.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/blocks/4091.tga
LFS
Normal file
BIN
assets/mods/basegame/blocks/4091.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/blocks/4092.tga
LFS
Normal file
BIN
assets/mods/basegame/blocks/4092.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/blocks/4093.tga
LFS
Normal file
BIN
assets/mods/basegame/blocks/4093.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/blocks/4094.tga
LFS
Normal file
BIN
assets/mods/basegame/blocks/4094.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/blocks/4095.tga
LFS
Normal file
BIN
assets/mods/basegame/blocks/4095.tga
LFS
Normal file
Binary file not shown.
@@ -98,6 +98,11 @@
|
|||||||
"256";"256";"BLOCK_LANTERN_IRON_REGULAR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"N/A";"FXTR";"0";"0";"0";"0";"0";"0";"16";"1.0000";"0.6372";"0.0000";"0.0000";"N/A";"N/A"
|
"256";"256";"BLOCK_LANTERN_IRON_REGULAR";"0.0312";"0.0312";"0.0312";"0.0312";"1";"N/A";"FXTR";"0";"0";"0";"0";"0";"0";"16";"1.0000";"0.6372";"0.0000";"0.0000";"N/A";"N/A"
|
||||||
"257";"257";"BLOCK_SUNSTONE";"0.1252";"0.1252";"0.1252";"0.1252";"1";"N/A";"ROCK";"1";"0";"0";"0";"2";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
"257";"257";"BLOCK_SUNSTONE";"0.1252";"0.1252";"0.1252";"0.1252";"1";"N/A";"ROCK";"1";"0";"0";"0";"2";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
||||||
"258";"258";"BLOCK_DAYLIGHT_CAPACITOR";"0.1252";"0.1252";"0.1252";"0.1252";"1";"N/A";"GLAS";"1";"0";"0";"0";"3";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
"258";"258";"BLOCK_DAYLIGHT_CAPACITOR";"0.1252";"0.1252";"0.1252";"0.1252";"1";"N/A";"GLAS";"1";"0";"0";"0";"3";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
||||||
|
"4091";"0";"ACTORBLOCK_NO_COLLISION";"0.0";"0.0";"0.0";"0.0";"1";"1";"NULL";"0";"0";"0";"0";"0";"0";"0";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A"
|
||||||
|
"4092";"0";"ACTORBLOCK_FULL_COLLISION";"0.0";"0.0";"0.0";"0.0";"1";"1";"NULL";"0";"0";"0";"0";"0";"0";"0";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A"
|
||||||
|
"4093";"0";"ACTORBLOCK_ALLOW_MOVE_DOWN";"0.0";"0.0";"0.0";"0.0";"1";"1";"NULL";"0";"1";"0";"0";"0";"0";"0";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A"
|
||||||
|
"4094";"0";"ACTORBLOCK_NO_PASS_RIGHT";"0.0";"0.0";"0.0";"0.0";"1";"1";"NULL";"0";"0";"0";"0";"0";"0";"0";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A"
|
||||||
|
"4095";"0";"ACTORBLOCK_NO_PASS_LEFT";"0.0";"0.0";"0.0";"0.0";"1";"1";"NULL";"0";"0";"0";"0";"0";"0";"0";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A"
|
||||||
"4096";"0";"BLOCK_WATER";"0.1016";"0.0744";"0.0508";"0.0826";"100";"1000";"WATR";"0";"0";"0";"0";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"005599A6";"16"
|
"4096";"0";"BLOCK_WATER";"0.1016";"0.0744";"0.0508";"0.0826";"100";"1000";"WATR";"0";"0";"0";"0";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"005599A6";"16"
|
||||||
"4097";"0";"BLOCK_LAVA";"0.9696";"0.9696";"0.9696";"0.9696";"100";"2600";"ROCK";"0";"0";"0";"0";"0";"0";"16";"0.7664";"0.2032";"0.0000";"0.0000";"FF4600E6";"32"
|
"4097";"0";"BLOCK_LAVA";"0.9696";"0.9696";"0.9696";"0.9696";"100";"2600";"ROCK";"0";"0";"0";"0";"0";"0";"16";"0.7664";"0.2032";"0.0000";"0.0000";"FF4600E6";"32"
|
||||||
"-1";"0";"BLOCK_NULL";"4.0000";"4.0000";"4.0000";"4.0000";"-1";"2600";"NULL";"0";"0";"1";"0";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
"-1";"0";"BLOCK_NULL";"4.0000";"4.0000";"4.0000";"4.0000";"-1";"2600";"NULL";"0";"0";"1";"0";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A"
|
||||||
|
|||||||
|
Binary file not shown.
@@ -14,29 +14,25 @@ entrypoint=net.torvald.terrarum.modulebasegame.EntryPoint
|
|||||||
# Release date in YYYY-MM-DD
|
# Release date in YYYY-MM-DD
|
||||||
releasedate=2017-07-14
|
releasedate=2017-07-14
|
||||||
|
|
||||||
# The version, must be ^[0-9]+(\.[0-9]+)*$ in regex
|
# The version, must follow Semver 2.0.0 scheme (https://semver.org/)
|
||||||
# e.g. 0.1 0.1.1347
|
|
||||||
# e.g. 1 1.0.58385.02
|
|
||||||
# e.g. 26558 0.0.0.0.0.1
|
|
||||||
version=0.2.0
|
version=0.2.0
|
||||||
|
|
||||||
# External JARs the module might use, separate multiple by semicolon (;)
|
# External JARs the module might use, separate multiple by semicolon (;)
|
||||||
libraries=
|
libraries=
|
||||||
|
|
||||||
# Modules that must be pre-installed, separate multiple by semicolon (;)
|
# Modules that must be pre-installed, separate multiple by semicolon (;)
|
||||||
# Dependency syntax: "module name space allowed 444.44+"
|
# Dependency syntax: "module's identification name (aka folder name) spaces allowed versionnumber"
|
||||||
# Versionnumber: + means equal or higher, ! means this exact number, - denotes interval, * is wildcard
|
# Versionnumber: + means equal or higher, ! means this exact number, - denotes interval, * is wildcard
|
||||||
# the default is equal or lower
|
# the default is equal or lower. When fields are omitted (e.g. 3, 1.65), those fields will be ignored
|
||||||
# e.g. 1.4+ would allow 1.4, 0.6, 1.13, 1.42, 1.4.0, 1.4.4456
|
# e.g. 1.4+ would allow any future versions including 1.4.0; PATCH versions are ignored: 1.6.0, 1.13.0, 1.42.0, 1.4.0, 1.4.4456
|
||||||
# e.g. 10+.2 would allow 10.2, 10.1, 11.0 but would not allow any integer version (v10.0 != v10)
|
# e.g. 4.2.25 would allow any future versions including 4.2.25; any older patches such as 4.2.17 will be disallowd
|
||||||
# e.g. 10.4! would allow 10.4, 9.4, 8.4, 7.4
|
# e.g. 10.4! is same as 10.4; would allow any PATCH versions as the numbers is ignored
|
||||||
# e.g. 10.3-11.4 would allow 10.3, 10.7, 10.12676, 11.0, 11.4 but not integer v11, 10.3.12 etc.
|
# e.g. 10.3-11.4 would allow any versions between and including stated versions; PATCH versions are ignored: 10.3.0, 10.7.0, 10.3.676, 11.0.0, 11.4.9999
|
||||||
# e.g. 13!.5 would allow 13.0, 13.1, 13.2, 13.3, 13.4 and 13.5
|
# e.g. 10.3.2-10.4.5 would allow any versions between and including stated versions; PATCH versions are checked
|
||||||
# e.g. * would allow any version possible
|
# e.g. 3!.1+ would allow any future MINOR versions including 3.1; PATH versions are ignored: 3.1, 3.4.22, 3.6, 3.1415926
|
||||||
# e.g. *.* would allow any version on that scheme
|
# e.g. * would allow any version possible, as it won't check MINOR and PATCH versions
|
||||||
# e.g. *! would only allow all integer version
|
|
||||||
# NOTE: it's your responsibility that your mod's version scheme would not be a total mess!
|
# NOTE: it's your responsibility that your mod's version scheme would not be a total mess!
|
||||||
# real world examples:
|
# real world examples:
|
||||||
# BaseGame 1.0+; CommandLineRenewed 2!.0+; Basegame 1!.0+; ScreenRecorder *; MyScrRecHack 1.*
|
# basegame 1.0.0+; command line refresh 2!.+; my_little_hack 0.*
|
||||||
# Can you decode them? This is for hypothetical screen recorder mod.
|
# Can you decode them? This is for hypothetical screen recorder mod.
|
||||||
dependency=
|
dependency=
|
||||||
Binary file not shown.
BIN
lib/AppleJavaExtensions-1.4.jar.gz
LFS
Normal file
BIN
lib/AppleJavaExtensions-1.4.jar.gz
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/gdx-backend-lwjgl3.jar.gz
LFS
Normal file
BIN
lib/gdx-backend-lwjgl3.jar.gz
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/gdx-controllers-lwjgl3.jar.gz
LFS
Normal file
BIN
lib/gdx-controllers-lwjgl3.jar.gz
LFS
Normal file
Binary file not shown.
BIN
lib/gdx-nightly-20170610.zip
LFS
BIN
lib/gdx-nightly-20170610.zip
LFS
Binary file not shown.
BIN
lib/gdx-nightly-20170610.zip.gz
LFS
Normal file
BIN
lib/gdx-nightly-20170610.zip.gz
LFS
Normal file
Binary file not shown.
BIN
lib/gdx-nightly-20181111.zip
LFS
BIN
lib/gdx-nightly-20181111.zip
LFS
Binary file not shown.
BIN
lib/gdx-nightly-20181111.zip.gz
LFS
Normal file
BIN
lib/gdx-nightly-20181111.zip.gz
LFS
Normal file
Binary file not shown.
BIN
lib/gdx-nightly-20190112.zip
LFS
BIN
lib/gdx-nightly-20190112.zip
LFS
Binary file not shown.
BIN
lib/gdx-nightly-20190112.zip.gz
LFS
Normal file
BIN
lib/gdx-nightly-20190112.zip.gz
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/jogg-0.0.7.jar.gz
LFS
Normal file
BIN
lib/jogg-0.0.7.jar.gz
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/jorbis-0.0.17.jar.gz
LFS
Normal file
BIN
lib/jorbis-0.0.17.jar.gz
LFS
Normal file
Binary file not shown.
BIN
lib/libjinput.zip
LFS
BIN
lib/libjinput.zip
LFS
Binary file not shown.
BIN
lib/libjinput.zip.gz
LFS
Normal file
BIN
lib/libjinput.zip.gz
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/luaj-jse-3.0.2.jar
Normal file
BIN
lib/luaj-jse-3.0.2.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/source/luaj-sources-3.0.2.jar
Normal file
BIN
lib/source/luaj-sources-3.0.2.jar
Normal file
Binary file not shown.
@@ -1,367 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011 See AUTHORS file.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
package com.badlogic.gdx.backends.lwjgl.audio;
|
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
import org.lwjgl.LWJGLException;
|
|
||||||
import org.lwjgl.openal.AL;
|
|
||||||
import org.lwjgl.openal.AL10;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Audio;
|
|
||||||
import com.badlogic.gdx.audio.AudioDevice;
|
|
||||||
import com.badlogic.gdx.audio.AudioRecorder;
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
|
||||||
import com.badlogic.gdx.utils.IntArray;
|
|
||||||
import com.badlogic.gdx.utils.IntMap;
|
|
||||||
import com.badlogic.gdx.utils.LongMap;
|
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
|
|
||||||
import static org.lwjgl.openal.AL10.*;
|
|
||||||
|
|
||||||
/** @author Nathan Sweet */
|
|
||||||
public class OpenALAudio implements Audio {
|
|
||||||
private final int deviceBufferSize;
|
|
||||||
private final int deviceBufferCount;
|
|
||||||
private IntArray idleSources, allSources;
|
|
||||||
private LongMap<Integer> soundIdToSource;
|
|
||||||
private IntMap<Long> sourceToSoundId;
|
|
||||||
private long nextSoundId = 0;
|
|
||||||
private ObjectMap<String, Class<? extends OpenALSound>> extensionToSoundClass = new ObjectMap();
|
|
||||||
private ObjectMap<String, Class<? extends OpenALMusic>> extensionToMusicClass = new ObjectMap();
|
|
||||||
private OpenALSound[] recentSounds;
|
|
||||||
private int mostRecetSound = -1;
|
|
||||||
|
|
||||||
Array<OpenALMusic> music = new Array(false, 1, OpenALMusic.class);
|
|
||||||
boolean noDevice = false;
|
|
||||||
|
|
||||||
public OpenALAudio () {
|
|
||||||
this(16, 9, 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenALAudio (int simultaneousSources, int deviceBufferCount, int deviceBufferSize) {
|
|
||||||
this.deviceBufferSize = deviceBufferSize;
|
|
||||||
this.deviceBufferCount = deviceBufferCount;
|
|
||||||
|
|
||||||
registerSound("ogg", Ogg.Sound.class);
|
|
||||||
registerMusic("ogg", Ogg.Music.class);
|
|
||||||
registerSound("wav", Wav.Sound.class);
|
|
||||||
registerMusic("wav", Wav.Music.class);
|
|
||||||
registerSound("mp3", Mp3.Sound.class);
|
|
||||||
registerMusic("mp3", Mp3.Music.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
AL.create();
|
|
||||||
} catch (LWJGLException ex) {
|
|
||||||
noDevice = true;
|
|
||||||
ex.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
allSources = new IntArray(false, simultaneousSources);
|
|
||||||
for (int i = 0; i < simultaneousSources; i++) {
|
|
||||||
int sourceID = alGenSources();
|
|
||||||
if (alGetError() != AL_NO_ERROR) break;
|
|
||||||
allSources.add(sourceID);
|
|
||||||
}
|
|
||||||
idleSources = new IntArray(allSources);
|
|
||||||
soundIdToSource = new LongMap<Integer>();
|
|
||||||
sourceToSoundId = new IntMap<Long>();
|
|
||||||
|
|
||||||
FloatBuffer orientation = (FloatBuffer)BufferUtils.createFloatBuffer(6)
|
|
||||||
.put(new float[] {0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f}).flip();
|
|
||||||
alListener(AL_ORIENTATION, orientation);
|
|
||||||
FloatBuffer velocity = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] {0.0f, 0.0f, 0.0f}).flip();
|
|
||||||
alListener(AL_VELOCITY, velocity);
|
|
||||||
FloatBuffer position = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] {0.0f, 0.0f, 0.0f}).flip();
|
|
||||||
alListener(AL_POSITION, position);
|
|
||||||
|
|
||||||
recentSounds = new OpenALSound[simultaneousSources];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerSound (String extension, Class<? extends OpenALSound> soundClass) {
|
|
||||||
if (extension == null) throw new IllegalArgumentException("extension cannot be null.");
|
|
||||||
if (soundClass == null) throw new IllegalArgumentException("soundClass cannot be null.");
|
|
||||||
extensionToSoundClass.put(extension, soundClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerMusic (String extension, Class<? extends OpenALMusic> musicClass) {
|
|
||||||
if (extension == null) throw new IllegalArgumentException("extension cannot be null.");
|
|
||||||
if (musicClass == null) throw new IllegalArgumentException("musicClass cannot be null.");
|
|
||||||
extensionToMusicClass.put(extension, musicClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenALSound newSound (FileHandle file) {
|
|
||||||
if (file == null) throw new IllegalArgumentException("file cannot be null.");
|
|
||||||
Class<? extends OpenALSound> soundClass = extensionToSoundClass.get(file.extension().toLowerCase());
|
|
||||||
if (soundClass == null) throw new GdxRuntimeException("Unknown file extension for sound: " + file);
|
|
||||||
try {
|
|
||||||
return soundClass.getConstructor(new Class[] {OpenALAudio.class, FileHandle.class}).newInstance(this, file);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new GdxRuntimeException("Error creating sound " + soundClass.getName() + " for file: " + file, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenALMusic newMusic (FileHandle file) {
|
|
||||||
if (file == null) throw new IllegalArgumentException("file cannot be null.");
|
|
||||||
Class<? extends OpenALMusic> musicClass = extensionToMusicClass.get(file.extension().toLowerCase());
|
|
||||||
if (musicClass == null) throw new GdxRuntimeException("Unknown file extension for music: " + file);
|
|
||||||
try {
|
|
||||||
return musicClass.getConstructor(new Class[] {OpenALAudio.class, FileHandle.class}).newInstance(this, file);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new GdxRuntimeException("Error creating music " + musicClass.getName() + " for file: " + file, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int obtainSource (boolean isMusic) {
|
|
||||||
if (noDevice) return 0;
|
|
||||||
for (int i = 0, n = idleSources.size; i < n; i++) {
|
|
||||||
int sourceId = idleSources.get(i);
|
|
||||||
int state = alGetSourcei(sourceId, AL_SOURCE_STATE);
|
|
||||||
if (state != AL_PLAYING && state != AL_PAUSED) {
|
|
||||||
if (isMusic) {
|
|
||||||
idleSources.removeIndex(i);
|
|
||||||
} else {
|
|
||||||
if (sourceToSoundId.containsKey(sourceId)) {
|
|
||||||
long soundId = sourceToSoundId.get(sourceId);
|
|
||||||
sourceToSoundId.remove(sourceId);
|
|
||||||
soundIdToSource.remove(soundId);
|
|
||||||
}
|
|
||||||
|
|
||||||
long soundId = nextSoundId++;
|
|
||||||
sourceToSoundId.put(sourceId, soundId);
|
|
||||||
soundIdToSource.put(soundId, sourceId);
|
|
||||||
}
|
|
||||||
alSourceStop(sourceId);
|
|
||||||
alSourcei(sourceId, AL_BUFFER, 0);
|
|
||||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, 1);
|
|
||||||
AL10.alSourcef(sourceId, AL10.AL_PITCH, 1);
|
|
||||||
AL10.alSource3f(sourceId, AL10.AL_POSITION, 0, 0, 1f);
|
|
||||||
return sourceId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeSource (int sourceID) {
|
|
||||||
if (noDevice) return;
|
|
||||||
alSourceStop(sourceID);
|
|
||||||
alSourcei(sourceID, AL_BUFFER, 0);
|
|
||||||
if (sourceToSoundId.containsKey(sourceID)) {
|
|
||||||
long soundId = sourceToSoundId.remove(sourceID);
|
|
||||||
soundIdToSource.remove(soundId);
|
|
||||||
}
|
|
||||||
idleSources.add(sourceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeBuffer (int bufferID) {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0, n = idleSources.size; i < n; i++) {
|
|
||||||
int sourceID = idleSources.get(i);
|
|
||||||
if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) {
|
|
||||||
if (sourceToSoundId.containsKey(sourceID)) {
|
|
||||||
long soundId = sourceToSoundId.remove(sourceID);
|
|
||||||
soundIdToSource.remove(soundId);
|
|
||||||
}
|
|
||||||
alSourceStop(sourceID);
|
|
||||||
alSourcei(sourceID, AL_BUFFER, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopSourcesWithBuffer (int bufferID) {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0, n = idleSources.size; i < n; i++) {
|
|
||||||
int sourceID = idleSources.get(i);
|
|
||||||
if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) {
|
|
||||||
if (sourceToSoundId.containsKey(sourceID)) {
|
|
||||||
long soundId = sourceToSoundId.remove(sourceID);
|
|
||||||
soundIdToSource.remove(soundId);
|
|
||||||
}
|
|
||||||
alSourceStop(sourceID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pauseSourcesWithBuffer (int bufferID) {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0, n = idleSources.size; i < n; i++) {
|
|
||||||
int sourceID = idleSources.get(i);
|
|
||||||
if (alGetSourcei(sourceID, AL_BUFFER) == bufferID)
|
|
||||||
alSourcePause(sourceID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resumeSourcesWithBuffer (int bufferID) {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0, n = idleSources.size; i < n; i++) {
|
|
||||||
int sourceID = idleSources.get(i);
|
|
||||||
if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) {
|
|
||||||
if (alGetSourcei(sourceID, AL_SOURCE_STATE) == AL_PAUSED)
|
|
||||||
alSourcePlay(sourceID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update () {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0; i < music.size; i++)
|
|
||||||
music.items[i].update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSoundId (int sourceId) {
|
|
||||||
if (!sourceToSoundId.containsKey(sourceId)) return -1;
|
|
||||||
return sourceToSoundId.get(sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopSound (long soundId) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
alSourceStop(sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pauseSound (long soundId) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
alSourcePause(sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resumeSound (long soundId) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
if (alGetSourcei(sourceId, AL_SOURCE_STATE) == AL_PAUSED)
|
|
||||||
alSourcePlay(sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoundGain (long soundId, float volume) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoundLooping (long soundId, boolean looping) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
alSourcei(sourceId, AL10.AL_LOOPING, looping ? AL10.AL_TRUE : AL10.AL_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoundPitch (long soundId, float pitch) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
AL10.alSourcef(sourceId, AL10.AL_PITCH, pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSoundPan (long soundId, float pan, float volume) {
|
|
||||||
if (!soundIdToSource.containsKey(soundId)) return;
|
|
||||||
int sourceId = soundIdToSource.get(soundId);
|
|
||||||
|
|
||||||
AL10.alSource3f(sourceId, AL10.AL_POSITION, MathUtils.cos((pan - 1) * MathUtils.PI / 2), 0,
|
|
||||||
MathUtils.sin((pan + 1) * MathUtils.PI / 2));
|
|
||||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose () {
|
|
||||||
if (noDevice) return;
|
|
||||||
for (int i = 0, n = allSources.size; i < n; i++) {
|
|
||||||
int sourceID = allSources.get(i);
|
|
||||||
int state = alGetSourcei(sourceID, AL_SOURCE_STATE);
|
|
||||||
if (state != AL_STOPPED) alSourceStop(sourceID);
|
|
||||||
alDeleteSources(sourceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceToSoundId.clear();
|
|
||||||
soundIdToSource.clear();
|
|
||||||
|
|
||||||
AL.destroy();
|
|
||||||
while (AL.isCreated()) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(10);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AudioDevice newAudioDevice (int sampleRate, final boolean isMono) {
|
|
||||||
if (noDevice) return new AudioDevice() {
|
|
||||||
@Override
|
|
||||||
public void writeSamples (float[] samples, int offset, int numSamples) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeSamples (short[] samples, int offset, int numSamples) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVolume (float volume) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isMono () {
|
|
||||||
return isMono;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getLatency () {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose () {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return new OpenALAudioDevice(this, sampleRate, isMono, deviceBufferSize, deviceBufferCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AudioRecorder newAudioRecorder (int samplingRate, boolean isMono) {
|
|
||||||
if (noDevice) return new AudioRecorder() {
|
|
||||||
@Override
|
|
||||||
public void read (short[] samples, int offset, int numSamples) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose () {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return new JavaSoundAudioRecorder(samplingRate, isMono);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retains a list of the most recently played sounds and stops the sound played least recently if necessary for a new sound to
|
|
||||||
* play */
|
|
||||||
protected void retain (OpenALSound sound, boolean stop) {
|
|
||||||
// Move the pointer ahead and wrap
|
|
||||||
mostRecetSound++;
|
|
||||||
mostRecetSound %= recentSounds.length;
|
|
||||||
|
|
||||||
if (stop) {
|
|
||||||
// Stop the least recent sound (the one we are about to bump off the buffer)
|
|
||||||
if (recentSounds[mostRecetSound] != null) recentSounds[mostRecetSound].stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
recentSounds[mostRecetSound] = sound;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes the disposed sound from the least recently played list */
|
|
||||||
public void forget (OpenALSound sound) {
|
|
||||||
for (int i = 0; i < recentSounds.length; i++) {
|
|
||||||
if (recentSounds[i] == sound) recentSounds[i] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,561 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011 See AUTHORS file.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
package com.badlogic.gdx.graphics;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.NumberUtils;
|
|
||||||
|
|
||||||
/** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the
|
|
||||||
* internal values after execution.
|
|
||||||
*
|
|
||||||
* @author mzechner */
|
|
||||||
public class Color {
|
|
||||||
public static final Color WHITE = new Color(1, 1, 1,1);
|
|
||||||
public static final Color LIGHT_GRAY = new Color(0xbfbfbfff);
|
|
||||||
public static final Color GRAY = new Color(0x7f7f7fff);
|
|
||||||
public static final Color DARK_GRAY = new Color(0x3f3f3fff);
|
|
||||||
public static final Color BLACK = new Color(0, 0, 0, 1);
|
|
||||||
|
|
||||||
/** Convenience for frequently used <code>WHITE.toFloatBits()</code> */
|
|
||||||
public static final float WHITE_FLOAT_BITS = WHITE.toFloatBits();
|
|
||||||
|
|
||||||
public static final Color CLEAR = new Color(0, 0, 0, 0);
|
|
||||||
|
|
||||||
public static final Color BLUE = new Color(0, 0, 1, 1);
|
|
||||||
public static final Color NAVY = new Color(0, 0, 0.5f, 1);
|
|
||||||
public static final Color ROYAL = new Color(0x4169e1ff);
|
|
||||||
public static final Color SLATE = new Color(0x708090ff);
|
|
||||||
public static final Color SKY = new Color(0x87ceebff);
|
|
||||||
public static final Color CYAN = new Color(0, 1, 1, 1);
|
|
||||||
public static final Color TEAL = new Color(0, 0.5f, 0.5f, 1);
|
|
||||||
|
|
||||||
public static final Color GREEN = new Color(0x00ff00ff);
|
|
||||||
public static final Color CHARTREUSE = new Color(0x7fff00ff);
|
|
||||||
public static final Color LIME = new Color(0x32cd32ff);
|
|
||||||
public static final Color FOREST = new Color(0x228b22ff);
|
|
||||||
public static final Color OLIVE = new Color(0x6b8e23ff);
|
|
||||||
|
|
||||||
public static final Color YELLOW = new Color(0xffff00ff);
|
|
||||||
public static final Color GOLD = new Color(0xffd700ff);
|
|
||||||
public static final Color GOLDENROD = new Color(0xdaa520ff);
|
|
||||||
public static final Color ORANGE = new Color(0xffa500ff);
|
|
||||||
|
|
||||||
public static final Color BROWN = new Color(0x8b4513ff);
|
|
||||||
public static final Color TAN = new Color(0xd2b48cff);
|
|
||||||
public static final Color FIREBRICK = new Color(0xb22222ff);
|
|
||||||
|
|
||||||
public static final Color RED = new Color(0xff0000ff);
|
|
||||||
public static final Color SCARLET = new Color(0xff341cff);
|
|
||||||
public static final Color CORAL = new Color(0xff7f50ff);
|
|
||||||
public static final Color SALMON = new Color(0xfa8072ff);
|
|
||||||
public static final Color PINK = new Color(0xff69b4ff);
|
|
||||||
public static final Color MAGENTA = new Color(1, 0, 1, 1);
|
|
||||||
|
|
||||||
public static final Color PURPLE = new Color(0xa020f0ff);
|
|
||||||
public static final Color VIOLET = new Color(0xee82eeff);
|
|
||||||
public static final Color MAROON = new Color(0xb03060ff);
|
|
||||||
|
|
||||||
/** the red, green, blue and alpha components **/
|
|
||||||
public float r, g, b, a;
|
|
||||||
|
|
||||||
/** Constructs a new Color with all components set to 0. */
|
|
||||||
public Color () {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see #rgba8888ToColor(Color, int) */
|
|
||||||
public Color (int rgba8888) {
|
|
||||||
rgba8888ToColor(this, rgba8888);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructor, sets the components of the color
|
|
||||||
*
|
|
||||||
* @param r the red component
|
|
||||||
* @param g the green component
|
|
||||||
* @param b the blue component
|
|
||||||
* @param a the alpha component */
|
|
||||||
public Color (float r, float g, float b, float a) {
|
|
||||||
this.r = r;
|
|
||||||
this.g = g;
|
|
||||||
this.b = b;
|
|
||||||
this.a = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructs a new color using the given color
|
|
||||||
*
|
|
||||||
* @param color the color */
|
|
||||||
public Color (Color color) {
|
|
||||||
set(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets this color to the given color.
|
|
||||||
*
|
|
||||||
* @param color the Color */
|
|
||||||
public Color set (Color color) {
|
|
||||||
this.r = color.r;
|
|
||||||
this.g = color.g;
|
|
||||||
this.b = color.b;
|
|
||||||
this.a = color.a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Multiplies the this color and the given color
|
|
||||||
*
|
|
||||||
* @param color the color
|
|
||||||
* @return this color. */
|
|
||||||
public Color mul (Color color) {
|
|
||||||
this.r *= color.r;
|
|
||||||
this.g *= color.g;
|
|
||||||
this.b *= color.b;
|
|
||||||
this.a *= color.a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Multiplies all components of this Color with the given value.
|
|
||||||
*
|
|
||||||
* @param value the value
|
|
||||||
* @return this color */
|
|
||||||
public Color mul (float value) {
|
|
||||||
this.r *= value;
|
|
||||||
this.g *= value;
|
|
||||||
this.b *= value;
|
|
||||||
this.a *= value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the given color to this color.
|
|
||||||
*
|
|
||||||
* @param color the color
|
|
||||||
* @return this color */
|
|
||||||
public Color add (Color color) {
|
|
||||||
this.r += color.r;
|
|
||||||
this.g += color.g;
|
|
||||||
this.b += color.b;
|
|
||||||
this.a += color.a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Subtracts the given color from this color
|
|
||||||
*
|
|
||||||
* @param color the color
|
|
||||||
* @return this color */
|
|
||||||
public Color sub (Color color) {
|
|
||||||
this.r -= color.r;
|
|
||||||
this.g -= color.g;
|
|
||||||
this.b -= color.b;
|
|
||||||
this.a -= color.a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets this Color's component values.
|
|
||||||
*
|
|
||||||
* @param r Red component
|
|
||||||
* @param g Green component
|
|
||||||
* @param b Blue component
|
|
||||||
* @param a Alpha component
|
|
||||||
*
|
|
||||||
* @return this Color for chaining */
|
|
||||||
public Color set (float r, float g, float b, float a) {
|
|
||||||
this.r = r;
|
|
||||||
this.g = g;
|
|
||||||
this.b = b;
|
|
||||||
this.a = a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets this color's component values through an integer representation.
|
|
||||||
*
|
|
||||||
* @return this Color for chaining
|
|
||||||
* @see #rgba8888ToColor(Color, int) */
|
|
||||||
public Color set (int rgba) {
|
|
||||||
rgba8888ToColor(this, rgba);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the given color component values to this Color's values.
|
|
||||||
*
|
|
||||||
* @param r Red component
|
|
||||||
* @param g Green component
|
|
||||||
* @param b Blue component
|
|
||||||
* @param a Alpha component
|
|
||||||
*
|
|
||||||
* @return this Color for chaining */
|
|
||||||
public Color add (float r, float g, float b, float a) {
|
|
||||||
this.r += r;
|
|
||||||
this.g += g;
|
|
||||||
this.b += b;
|
|
||||||
this.a += a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Subtracts the given values from this Color's component values.
|
|
||||||
*
|
|
||||||
* @param r Red component
|
|
||||||
* @param g Green component
|
|
||||||
* @param b Blue component
|
|
||||||
* @param a Alpha component
|
|
||||||
*
|
|
||||||
* @return this Color for chaining */
|
|
||||||
public Color sub (float r, float g, float b, float a) {
|
|
||||||
this.r -= r;
|
|
||||||
this.g -= g;
|
|
||||||
this.b -= b;
|
|
||||||
this.a -= a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Multiplies this Color's color components by the given ones.
|
|
||||||
*
|
|
||||||
* @param r Red component
|
|
||||||
* @param g Green component
|
|
||||||
* @param b Blue component
|
|
||||||
* @param a Alpha component
|
|
||||||
*
|
|
||||||
* @return this Color for chaining */
|
|
||||||
public Color mul (float r, float g, float b, float a) {
|
|
||||||
this.r *= r;
|
|
||||||
this.g *= g;
|
|
||||||
this.b *= b;
|
|
||||||
this.a *= a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
|
|
||||||
* this color.
|
|
||||||
* @param target The target color
|
|
||||||
* @param t The interpolation coefficient
|
|
||||||
* @return This color for chaining. */
|
|
||||||
public Color lerp (final Color target, final float t) {
|
|
||||||
this.r += t * (target.r - this.r);
|
|
||||||
this.g += t * (target.g - this.g);
|
|
||||||
this.b += t * (target.b - this.b);
|
|
||||||
this.a += t * (target.a - this.a);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
|
|
||||||
* this color.
|
|
||||||
* @param r The red component of the target color
|
|
||||||
* @param g The green component of the target color
|
|
||||||
* @param b The blue component of the target color
|
|
||||||
* @param a The alpha component of the target color
|
|
||||||
* @param t The interpolation coefficient
|
|
||||||
* @return This color for chaining. */
|
|
||||||
public Color lerp (final float r, final float g, final float b, final float a, final float t) {
|
|
||||||
this.r += t * (r - this.r);
|
|
||||||
this.g += t * (g - this.g);
|
|
||||||
this.b += t * (b - this.b);
|
|
||||||
this.a += t * (a - this.a);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Multiplies the RGB values by the alpha. */
|
|
||||||
public Color premultiplyAlpha () {
|
|
||||||
r *= a;
|
|
||||||
g *= a;
|
|
||||||
b *= a;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals (Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Color color = (Color)o;
|
|
||||||
return toIntBits() == color.toIntBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode () {
|
|
||||||
int result = (r != +0.0f ? NumberUtils.floatToIntBits(r) : 0);
|
|
||||||
result = 31 * result + (g != +0.0f ? NumberUtils.floatToIntBits(g) : 0);
|
|
||||||
result = 31 * result + (b != +0.0f ? NumberUtils.floatToIntBits(b) : 0);
|
|
||||||
result = 31 * result + (a != +0.0f ? NumberUtils.floatToIntBits(a) : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Alpha is compressed
|
|
||||||
* from 0-255 to 0-254 to avoid using float bits in the NaN range (see {@link NumberUtils#intToFloatColor(int)}).
|
|
||||||
* @return the packed color as a 32-bit float */
|
|
||||||
public float toFloatBits () {
|
|
||||||
int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r));
|
|
||||||
return NumberUtils.intToFloatColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Packs the color components into a 32-bit integer with the format ABGR.
|
|
||||||
* @return the packed color as a 32-bit int. */
|
|
||||||
public int toIntBits () {
|
|
||||||
return ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the color encoded as hex string with the format RRGGBBAA. */
|
|
||||||
public String toString () {
|
|
||||||
String value = Integer
|
|
||||||
.toHexString(((int)(255 * r) << 24) | ((int)(255 * g) << 16) | ((int)(255 * b) << 8) | ((int)(255 * a)));
|
|
||||||
while (value.length() < 8)
|
|
||||||
value = "0" + value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a new color from a hex string with the format RRGGBBAA.
|
|
||||||
* @see #toString() */
|
|
||||||
public static Color valueOf (String hex) {
|
|
||||||
hex = hex.charAt(0) == '#' ? hex.substring(1) : hex;
|
|
||||||
int r = Integer.valueOf(hex.substring(0, 2), 16);
|
|
||||||
int g = Integer.valueOf(hex.substring(2, 4), 16);
|
|
||||||
int b = Integer.valueOf(hex.substring(4, 6), 16);
|
|
||||||
int a = hex.length() != 8 ? 255 : Integer.valueOf(hex.substring(6, 8), 16);
|
|
||||||
return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Note that no range
|
|
||||||
* checking is performed for higher performance.
|
|
||||||
* @param r the red component, 0 - 255
|
|
||||||
* @param g the green component, 0 - 255
|
|
||||||
* @param b the blue component, 0 - 255
|
|
||||||
* @param a the alpha component, 0 - 255
|
|
||||||
* @return the packed color as a float
|
|
||||||
* @see NumberUtils#intToFloatColor(int) */
|
|
||||||
public static float toFloatBits (int r, int g, int b, int a) {
|
|
||||||
int color = (a << 24) | (b << 16) | (g << 8) | r;
|
|
||||||
float floatColor = NumberUtils.intToFloatColor(color);
|
|
||||||
return floatColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float.
|
|
||||||
* @return the packed color as a 32-bit float
|
|
||||||
* @see NumberUtils#intToFloatColor(int) */
|
|
||||||
public static float toFloatBits (float r, float g, float b, float a) {
|
|
||||||
int color = ((int)(255 * a) << 24) | ((int)(255 * b) << 16) | ((int)(255 * g) << 8) | ((int)(255 * r));
|
|
||||||
return NumberUtils.intToFloatColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Packs the color components into a 32-bit integer with the format ABGR. Note that no range checking is performed for higher
|
|
||||||
* performance.
|
|
||||||
* @param r the red component, 0 - 255
|
|
||||||
* @param g the green component, 0 - 255
|
|
||||||
* @param b the blue component, 0 - 255
|
|
||||||
* @param a the alpha component, 0 - 255
|
|
||||||
* @return the packed color as a 32-bit int */
|
|
||||||
public static int toIntBits (int r, int g, int b, int a) {
|
|
||||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int alpha (float alpha) {
|
|
||||||
return (int)(alpha * 255.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int luminanceAlpha (float luminance, float alpha) {
|
|
||||||
return ((int)(luminance * 255.0f) << 8) | (int)(alpha * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgb565 (float r, float g, float b) {
|
|
||||||
return ((int)(r * 31) << 11) | ((int)(g * 63) << 5) | (int)(b * 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgba4444 (float r, float g, float b, float a) {
|
|
||||||
return ((int)(r * 15) << 12) | ((int)(g * 15) << 8) | ((int)(b * 15) << 4) | (int)(a * 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgb888 (float r, float g, float b) {
|
|
||||||
return ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgba8888 (float r, float g, float b, float a) {
|
|
||||||
return ((int)(r * 255) << 24) | ((int)(g * 255) << 16) | ((int)(b * 255) << 8) | (int)(a * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int argb8888 (float a, float r, float g, float b) {
|
|
||||||
return ((int)(a * 255) << 24) | ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgb565 (Color color) {
|
|
||||||
return ((int)(color.r * 31) << 11) | ((int)(color.g * 63) << 5) | (int)(color.b * 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgba4444 (Color color) {
|
|
||||||
return ((int)(color.r * 15) << 12) | ((int)(color.g * 15) << 8) | ((int)(color.b * 15) << 4) | (int)(color.a * 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgb888 (Color color) {
|
|
||||||
return ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int rgba8888 (Color color) {
|
|
||||||
return ((int)(color.r * 255) << 24) | ((int)(color.g * 255) << 16) | ((int)(color.b * 255) << 8) | (int)(color.a * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int argb8888 (Color color) {
|
|
||||||
return ((int)(color.a * 255) << 24) | ((int)(color.r * 255) << 16) | ((int)(color.g * 255) << 8) | (int)(color.b * 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified integer value in the format RGB565. This is inverse to the rgb565(r, g, b)
|
|
||||||
* method.
|
|
||||||
*
|
|
||||||
* @param color The Color to be modified.
|
|
||||||
* @param value An integer color value in RGB565 format. */
|
|
||||||
public static void rgb565ToColor (Color color, int value) {
|
|
||||||
color.r = ((value & 0x0000F800) >>> 11) / 31f;
|
|
||||||
color.g = ((value & 0x000007E0) >>> 5) / 63f;
|
|
||||||
color.b = ((value & 0x0000001F) >>> 0) / 31f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified integer value in the format RGBA4444. This is inverse to the rgba4444(r, g,
|
|
||||||
* b, a) method.
|
|
||||||
*
|
|
||||||
* @param color The Color to be modified.
|
|
||||||
* @param value An integer color value in RGBA4444 format. */
|
|
||||||
public static void rgba4444ToColor (Color color, int value) {
|
|
||||||
color.r = ((value & 0x0000f000) >>> 12) / 15f;
|
|
||||||
color.g = ((value & 0x00000f00) >>> 8) / 15f;
|
|
||||||
color.b = ((value & 0x000000f0) >>> 4) / 15f;
|
|
||||||
color.a = ((value & 0x0000000f)) / 15f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified integer value in the format RGB888. This is inverse to the rgb888(r, g, b)
|
|
||||||
* method.
|
|
||||||
*
|
|
||||||
* @param color The Color to be modified.
|
|
||||||
* @param value An integer color value in RGB888 format. */
|
|
||||||
public static void rgb888ToColor (Color color, int value) {
|
|
||||||
color.r = ((value & 0x00ff0000) >>> 16) / 255f;
|
|
||||||
color.g = ((value & 0x0000ff00) >>> 8) / 255f;
|
|
||||||
color.b = ((value & 0x000000ff)) / 255f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified integer value in the format RGBA8888. This is inverse to the rgba8888(r, g,
|
|
||||||
* b, a) method.
|
|
||||||
*
|
|
||||||
* @param color The Color to be modified.
|
|
||||||
* @param value An integer color value in RGBA8888 format. */
|
|
||||||
public static void rgba8888ToColor (Color color, int value) {
|
|
||||||
color.r = ((value & 0xff000000) >>> 24) / 255f;
|
|
||||||
color.g = ((value & 0x00ff0000) >>> 16) / 255f;
|
|
||||||
color.b = ((value & 0x0000ff00) >>> 8) / 255f;
|
|
||||||
color.a = ((value & 0x000000ff)) / 255f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a,
|
|
||||||
* r, g, b) method
|
|
||||||
*
|
|
||||||
* @param color The Color to be modified.
|
|
||||||
* @param value An integer color value in ARGB8888 format. */
|
|
||||||
public static void argb8888ToColor (Color color, int value) {
|
|
||||||
color.a = ((value & 0xff000000) >>> 24) / 255f;
|
|
||||||
color.r = ((value & 0x00ff0000) >>> 16) / 255f;
|
|
||||||
color.g = ((value & 0x0000ff00) >>> 8) / 255f;
|
|
||||||
color.b = ((value & 0x000000ff)) / 255f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the Color components using the specified float value in the format ABGB8888.
|
|
||||||
* @param color The Color to be modified. */
|
|
||||||
public static void abgr8888ToColor (Color color, float value) {
|
|
||||||
int c = NumberUtils.floatToIntColor(value);
|
|
||||||
color.a = ((c & 0xff000000) >>> 24) / 255f;
|
|
||||||
color.b = ((c & 0x00ff0000) >>> 16) / 255f;
|
|
||||||
color.g = ((c & 0x0000ff00) >>> 8) / 255f;
|
|
||||||
color.r = ((c & 0x000000ff)) / 255f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the RGB Color components using the specified Hue-Saturation-Value. Note that HSV components are voluntary not clamped
|
|
||||||
* to preserve high range color and can range beyond typical values.
|
|
||||||
* @param h The Hue in degree from 0 to 360
|
|
||||||
* @param s The Saturation from 0 to 1
|
|
||||||
* @param v The Value (brightness) from 0 to 1
|
|
||||||
* @return The modified Color for chaining. */
|
|
||||||
public Color fromHsv (float h, float s, float v) {
|
|
||||||
float x = (h / 60f + 6) % 6;
|
|
||||||
int i = (int)x;
|
|
||||||
float f = x - i;
|
|
||||||
float p = v * (1 - s);
|
|
||||||
float q = v * (1 - s * f);
|
|
||||||
float t = v * (1 - s * (1 - f));
|
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
r = v;
|
|
||||||
g = t;
|
|
||||||
b = p;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
r = q;
|
|
||||||
g = v;
|
|
||||||
b = p;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
r = p;
|
|
||||||
g = v;
|
|
||||||
b = t;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
r = p;
|
|
||||||
g = q;
|
|
||||||
b = v;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
r = t;
|
|
||||||
g = p;
|
|
||||||
b = v;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
r = v;
|
|
||||||
g = p;
|
|
||||||
b = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
//return clamp();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets RGB components using the specified Hue-Saturation-Value. This is a convenient method for
|
|
||||||
* {@link #fromHsv(float, float, float)}. This is the inverse of {@link #toHsv(float[])}.
|
|
||||||
* @param hsv The Hue, Saturation and Value components in that order.
|
|
||||||
* @return The modified Color for chaining. */
|
|
||||||
public Color fromHsv (float[] hsv) {
|
|
||||||
return fromHsv(hsv[0], hsv[1], hsv[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Extract Hue-Saturation-Value. This is the inverse of {@link #fromHsv(float[])}.
|
|
||||||
* @param hsv The HSV array to be modified.
|
|
||||||
* @return HSV components for chaining. */
|
|
||||||
public float[] toHsv (float[] hsv) {
|
|
||||||
float max = Math.max(Math.max(r, g), b);
|
|
||||||
float min = Math.min(Math.min(r, g), b);
|
|
||||||
float range = max - min;
|
|
||||||
if (range == 0) {
|
|
||||||
hsv[0] = 0;
|
|
||||||
} else if (max == r) {
|
|
||||||
hsv[0] = (60 * (g - b) / range + 360) % 360;
|
|
||||||
} else if (max == g) {
|
|
||||||
hsv[0] = 60 * (b - r) / range + 120;
|
|
||||||
} else {
|
|
||||||
hsv[0] = 60 * (r - g) / range + 240;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max > 0) {
|
|
||||||
hsv[1] = 1 - min / max;
|
|
||||||
} else {
|
|
||||||
hsv[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
hsv[2] = max;
|
|
||||||
|
|
||||||
return hsv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return a copy of this color */
|
|
||||||
public Color cpy () {
|
|
||||||
return new Color(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
src/module-info.java.wtf
Normal file
16
src/module-info.java.wtf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
module terrarum {
|
||||||
|
requires gdx;
|
||||||
|
requires gdx.backend.lwjgl;
|
||||||
|
requires gdx.controllers;
|
||||||
|
requires jxinput;
|
||||||
|
requires gson;
|
||||||
|
requires GetCpuName;
|
||||||
|
requires TerrarumSansBitmap;
|
||||||
|
requires kotlin.stdlib;
|
||||||
|
requires java.desktop;
|
||||||
|
requires java.logging;
|
||||||
|
requires TerranVirtualDisk;
|
||||||
|
requires commons.codec;
|
||||||
|
requires commons.csv;
|
||||||
|
requires Terrarum.Joise;
|
||||||
|
}
|
||||||
@@ -32,7 +32,17 @@ class KDHeapifiedTree(actors: List<ActorWBMovable>) {
|
|||||||
private fun Int.getActor() = nodes[this]
|
private fun Int.getActor() = nodes[this]
|
||||||
private fun Int.getLeft() = this * 2 + 1
|
private fun Int.getLeft() = this * 2 + 1
|
||||||
private fun Int.getRight() = this * 2 + 2
|
private fun Int.getRight() = this * 2 + 2
|
||||||
private fun Int.set(value: ActorWBMovable?) { nodes[this] = value }
|
private fun Int.set(value: ActorWBMovable?) {
|
||||||
|
try {
|
||||||
|
nodes[this] = value
|
||||||
|
}
|
||||||
|
catch (_: ArrayIndexOutOfBoundsException) {
|
||||||
|
// modification of the private fun expandArray()
|
||||||
|
val prevNodes = nodes.copyOf() + value
|
||||||
|
Array<ActorWBMovable?>(prevNodes.size * 2, { null })
|
||||||
|
create(prevNodes.toList(), 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
private fun Int.setLeftChild(value: ActorWBMovable?) { nodes[this.getLeft()] = value }
|
private fun Int.setLeftChild(value: ActorWBMovable?) { nodes[this.getLeft()] = value }
|
||||||
private fun Int.setRightChild(value: ActorWBMovable?) { nodes[this.getRight()] = value }
|
private fun Int.setRightChild(value: ActorWBMovable?) { nodes[this.getRight()] = value }
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package net.torvald.aa
|
package net.torvald.aa
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
|
import net.torvald.terrarum.gameactors.Hitbox
|
||||||
|
import net.torvald.terrarum.sqr
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2019-04-18.
|
* Created by minjaesong on 2019-04-18.
|
||||||
*/
|
*/
|
||||||
/*class KDTree(points: List<ActorWithBody>) {
|
class KDTree(points: List<ActorWithBody>) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DIMENSION = 2
|
const val DIMENSION = 2
|
||||||
@@ -15,7 +19,7 @@ package net.torvald.aa
|
|||||||
root = create(points, 0)
|
root = create(points, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findNearest(query: ActorWithBody) = getNearest(root!!, query, 0)
|
fun findNearest(query: ActorWithBody) = getNearest(root!!, query.hitbox, 0)
|
||||||
|
|
||||||
private fun create(points: List<ActorWithBody>, depth: Int): KDNode? {
|
private fun create(points: List<ActorWithBody>, depth: Int): KDNode? {
|
||||||
if (points.isEmpty()) {
|
if (points.isEmpty()) {
|
||||||
@@ -34,21 +38,21 @@ package net.torvald.aa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNearest(currentNode: KDNode, query: ActorWithBody, depth: Int = 0): KDNode {
|
private fun getNearest(currentNode: KDNode, actorHitbox: Hitbox, depth: Int = 0): KDNode {
|
||||||
val direction = currentNode.compare(query, depth % DIMENSION)
|
val direction = currentNode.compare(actorHitbox, depth % DIMENSION)
|
||||||
|
|
||||||
val next = if (direction < 0) currentNode.left else currentNode.right
|
val next = if (direction < 0) currentNode.left else currentNode.right
|
||||||
val other = if (direction < 0) currentNode.right else currentNode.left
|
val other = if (direction < 0) currentNode.right else currentNode.left
|
||||||
var best = if (next == null) currentNode else getNearest(next, query, depth + 1) // traverse to leaf
|
var best = if (next == null) currentNode else getNearest(next, actorHitbox, depth + 1) // traverse to leaf
|
||||||
|
|
||||||
if (currentNode.position.distSqr(query) < best.position.distSqr(query)) {
|
if (currentNode.position.distSqr(actorHitbox) < best.position.distSqr(actorHitbox)) {
|
||||||
best = currentNode
|
best = currentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other != null) {
|
if (other != null) {
|
||||||
if (currentNode.position.dimDistSqr(query, depth % DIMENSION) < best.position.distSqr(query)) {
|
if (currentNode.position.dimDistSqr(actorHitbox, depth % DIMENSION) < best.position.distSqr(actorHitbox)) {
|
||||||
val bestCandidate = getNearest(other, query, depth + 1)
|
val bestCandidate = getNearest(other, actorHitbox, depth + 1)
|
||||||
if (bestCandidate.position.distSqr(query) < best.position.distSqr(query)) {
|
if (bestCandidate.position.distSqr(actorHitbox) < best.position.distSqr(actorHitbox)) {
|
||||||
best = bestCandidate
|
best = bestCandidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,14 +62,15 @@ package net.torvald.aa
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class KDNode(val left: KDNode?, val right: KDNode?, val actor: ActorWithBody, val position: Hitbox) {
|
data class KDNode(val left: KDNode?, val right: KDNode?, val actor: ActorWithBody, val position: Hitbox) {
|
||||||
fun compare(other: ActorWithBody, dimension: Int) = other.getDimensionalPoint(dimension) - this.position.getDimensionalPoint(dimension)
|
//fun compare(other: ActorWithBody, dimension: Int) = other.getDimensionalPoint(dimension) - this.position.getDimensionalPoint(dimension)
|
||||||
|
fun compare(other: Hitbox, dimension: Int) = other.getDimensionalPoint(dimension) - this.position.getDimensionalPoint(dimension)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Hitbox.distSqr(other: Hitbox) {
|
private fun Hitbox.distSqr(other: Hitbox): Double {
|
||||||
var dist = 0.0
|
var dist = 0.0
|
||||||
for (i in 0 until DIMENSION)
|
for (i in 0 until DIMENSION)
|
||||||
dist += (this.getDimensionalPoint(i) - other.getDimensionalPoint(i)).sqr()
|
dist += (this.getDimensionalPoint(i) - other.getDimensionalPoint(i)).sqr()
|
||||||
|
return dist
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Hitbox.dimDistSqr(other: Hitbox, dimension: Int) = other.getDimensionalPoint(dimension).minus(this.getDimensionalPoint(dimension)).sqr()
|
private fun Hitbox.dimDistSqr(other: Hitbox, dimension: Int) = other.getDimensionalPoint(dimension).minus(this.getDimensionalPoint(dimension)).sqr()
|
||||||
@@ -74,4 +79,4 @@ package net.torvald.aa
|
|||||||
internal fun ActorWithBody.getDimensionalPoint(depth: Int) = this.hitbox.getDimensionalPoint(depth)
|
internal fun ActorWithBody.getDimensionalPoint(depth: Int) = this.hitbox.getDimensionalPoint(depth)
|
||||||
// TODO take ROUNDWORLD into account
|
// TODO take ROUNDWORLD into account
|
||||||
internal fun Hitbox.getDimensionalPoint(depth: Int) =
|
internal fun Hitbox.getDimensionalPoint(depth: Int) =
|
||||||
if (depth % KDTree.DIMENSION == 0) this.canonicalX else this.canonicalY*/
|
if (depth % KDTree.DIMENSION == 0) this.canonicalX else this.canonicalY
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.colourutil
|
package net.torvald.colourutil
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.colourutil.CIELChabUtil.toLCh
|
import net.torvald.colourutil.CIELChabUtil.toLCh
|
||||||
import net.torvald.colourutil.CIELChabUtil.toLab
|
import net.torvald.colourutil.CIELChabUtil.toLab
|
||||||
@@ -7,7 +8,6 @@ import net.torvald.colourutil.CIELabUtil.toLab
|
|||||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
/**
|
/**
|
||||||
* Cylindrical modification of CIELab colour space
|
* Cylindrical modification of CIELab colour space
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package net.torvald.colourutil
|
package net.torvald.colourutil
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.colourutil.CIELabUtil.toLab
|
import net.torvald.colourutil.CIELabUtil.toLab
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A modification of CIEXYZ that is useful for surface colours
|
* A modification of CIEXYZ that is useful for surface colours
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.torvald.colourutil
|
|||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
import net.torvald.colourutil.CIEXYZUtil.toColor
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
import net.torvald.colourutil.CIEXYZUtil.toRGB
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||||
|
|||||||
478
src/net/torvald/gdx/graphics/Cvec.kt
Normal file
478
src/net/torvald/gdx/graphics/Cvec.kt
Normal file
@@ -0,0 +1,478 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011 See AUTHORS file.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.torvald.gdx.graphics
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.utils.NumberUtils
|
||||||
|
|
||||||
|
/** A color class, holding the r, g, b and alpha component as floats in the range [0,1]. All methods perform clamping on the
|
||||||
|
* internal values after execution.
|
||||||
|
*
|
||||||
|
* @author mzechner
|
||||||
|
*/
|
||||||
|
class Cvec {
|
||||||
|
|
||||||
|
/** the red, green, blue and alpha components */
|
||||||
|
var r: Float = 0.toFloat()
|
||||||
|
var g: Float = 0.toFloat()
|
||||||
|
var b: Float = 0.toFloat()
|
||||||
|
var a: Float = 0.toFloat()
|
||||||
|
|
||||||
|
/** Constructs a new Cvec with all components set to 0. */
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
/** @see .rgba8888ToCvec
|
||||||
|
*/
|
||||||
|
constructor(rgba8888: Int) {
|
||||||
|
rgba8888ToCvec(this, rgba8888)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(color: Color) {
|
||||||
|
this.r = color.r
|
||||||
|
this.g = color.g
|
||||||
|
this.b = color.b
|
||||||
|
this.a = color.a
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor, sets the components of the color
|
||||||
|
*
|
||||||
|
* @param r the red component
|
||||||
|
* @param g the green component
|
||||||
|
* @param b the blue component
|
||||||
|
* @param a the alpha component
|
||||||
|
*/
|
||||||
|
constructor(r: Float, g: Float, b: Float, a: Float) {
|
||||||
|
this.r = r
|
||||||
|
this.g = g
|
||||||
|
this.b = b
|
||||||
|
this.a = a
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs a new color using the given color
|
||||||
|
*
|
||||||
|
* @param color the color
|
||||||
|
*/
|
||||||
|
constructor(color: Cvec) {
|
||||||
|
set(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets this color to the given color.
|
||||||
|
*
|
||||||
|
* @param color the Cvec
|
||||||
|
*/
|
||||||
|
fun set(color: Cvec): Cvec {
|
||||||
|
this.r = color.r
|
||||||
|
this.g = color.g
|
||||||
|
this.b = color.b
|
||||||
|
this.a = color.a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies the this color and the given color
|
||||||
|
*
|
||||||
|
* @param color the color
|
||||||
|
* @return this color.
|
||||||
|
*/
|
||||||
|
fun mul(color: Cvec): Cvec {
|
||||||
|
this.r *= color.r
|
||||||
|
this.g *= color.g
|
||||||
|
this.b *= color.b
|
||||||
|
this.a *= color.a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies all components of this Cvec with the given value.
|
||||||
|
*
|
||||||
|
* @param value the value
|
||||||
|
* @return this color
|
||||||
|
*/
|
||||||
|
fun mul(value: Float): Cvec {
|
||||||
|
this.r *= value
|
||||||
|
this.g *= value
|
||||||
|
this.b *= value
|
||||||
|
this.a *= value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds the given color to this color.
|
||||||
|
*
|
||||||
|
* @param color the color
|
||||||
|
* @return this color
|
||||||
|
*/
|
||||||
|
fun add(color: Cvec): Cvec {
|
||||||
|
this.r += color.r
|
||||||
|
this.g += color.g
|
||||||
|
this.b += color.b
|
||||||
|
this.a += color.a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Subtracts the given color from this color
|
||||||
|
*
|
||||||
|
* @param color the color
|
||||||
|
* @return this color
|
||||||
|
*/
|
||||||
|
fun sub(color: Cvec): Cvec {
|
||||||
|
this.r -= color.r
|
||||||
|
this.g -= color.g
|
||||||
|
this.b -= color.b
|
||||||
|
this.a -= color.a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets this Cvec's component values.
|
||||||
|
*
|
||||||
|
* @param r Red component
|
||||||
|
* @param g Green component
|
||||||
|
* @param b Blue component
|
||||||
|
* @param a Alpha component
|
||||||
|
*
|
||||||
|
* @return this Cvec for chaining
|
||||||
|
*/
|
||||||
|
operator fun set(r: Float, g: Float, b: Float, a: Float): Cvec {
|
||||||
|
this.r = r
|
||||||
|
this.g = g
|
||||||
|
this.b = b
|
||||||
|
this.a = a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets this color's component values through an integer representation.
|
||||||
|
*
|
||||||
|
* @return this Cvec for chaining
|
||||||
|
* @see .rgba8888ToCvec
|
||||||
|
*/
|
||||||
|
fun set(rgba: Int): Cvec {
|
||||||
|
rgba8888ToCvec(this, rgba)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds the given color component values to this Cvec's values.
|
||||||
|
*
|
||||||
|
* @param r Red component
|
||||||
|
* @param g Green component
|
||||||
|
* @param b Blue component
|
||||||
|
* @param a Alpha component
|
||||||
|
*
|
||||||
|
* @return this Cvec for chaining
|
||||||
|
*/
|
||||||
|
fun add(r: Float, g: Float, b: Float, a: Float): Cvec {
|
||||||
|
this.r += r
|
||||||
|
this.g += g
|
||||||
|
this.b += b
|
||||||
|
this.a += a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Subtracts the given values from this Cvec's component values.
|
||||||
|
*
|
||||||
|
* @param r Red component
|
||||||
|
* @param g Green component
|
||||||
|
* @param b Blue component
|
||||||
|
* @param a Alpha component
|
||||||
|
*
|
||||||
|
* @return this Cvec for chaining
|
||||||
|
*/
|
||||||
|
fun sub(r: Float, g: Float, b: Float, a: Float): Cvec {
|
||||||
|
this.r -= r
|
||||||
|
this.g -= g
|
||||||
|
this.b -= b
|
||||||
|
this.a -= a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies this Cvec's color components by the given ones.
|
||||||
|
*
|
||||||
|
* @param r Red component
|
||||||
|
* @param g Green component
|
||||||
|
* @param b Blue component
|
||||||
|
* @param a Alpha component
|
||||||
|
*
|
||||||
|
* @return this Cvec for chaining
|
||||||
|
*/
|
||||||
|
fun mul(r: Float, g: Float, b: Float, a: Float): Cvec {
|
||||||
|
this.r *= r
|
||||||
|
this.g *= g
|
||||||
|
this.b *= b
|
||||||
|
this.a *= a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
|
||||||
|
* this color.
|
||||||
|
* @param target The target color
|
||||||
|
* @param t The interpolation coefficient
|
||||||
|
* @return This color for chaining.
|
||||||
|
*/
|
||||||
|
fun lerp(target: Cvec, t: Float): Cvec {
|
||||||
|
this.r += t * (target.r - this.r)
|
||||||
|
this.g += t * (target.g - this.g)
|
||||||
|
this.b += t * (target.b - this.b)
|
||||||
|
this.a += t * (target.a - this.a)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Linearly interpolates between this color and the target color by t which is in the range [0,1]. The result is stored in
|
||||||
|
* this color.
|
||||||
|
* @param r The red component of the target color
|
||||||
|
* @param g The green component of the target color
|
||||||
|
* @param b The blue component of the target color
|
||||||
|
* @param a The alpha component of the target color
|
||||||
|
* @param t The interpolation coefficient
|
||||||
|
* @return This color for chaining.
|
||||||
|
*/
|
||||||
|
fun lerp(r: Float, g: Float, b: Float, a: Float, t: Float): Cvec {
|
||||||
|
this.r += t * (r - this.r)
|
||||||
|
this.g += t * (g - this.g)
|
||||||
|
this.b += t * (b - this.b)
|
||||||
|
this.a += t * (a - this.a)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies the RGB values by the alpha. */
|
||||||
|
fun premultiplyAlpha(): Cvec {
|
||||||
|
r *= a
|
||||||
|
g *= a
|
||||||
|
b *= a
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(o: Any?): Boolean {
|
||||||
|
if (this === o) return true
|
||||||
|
if (o == null || javaClass != o.javaClass) return false
|
||||||
|
val color = o as Cvec?
|
||||||
|
return toIntBits() == color!!.toIntBits()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = if (r != +0.0f) NumberUtils.floatToIntBits(r) else 0
|
||||||
|
result = 31 * result + if (g != +0.0f) NumberUtils.floatToIntBits(g) else 0
|
||||||
|
result = 31 * result + if (b != +0.0f) NumberUtils.floatToIntBits(b) else 0
|
||||||
|
result = 31 * result + if (a != +0.0f) NumberUtils.floatToIntBits(a) else 0
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Packs the color components into a 32-bit integer with the format ABGR and then converts it to a float. Alpha is compressed
|
||||||
|
* from 0-255 to 0-254 to avoid using float bits in the NaN range (see [NumberUtils.intToFloatColor]).
|
||||||
|
* @return the packed color as a 32-bit float
|
||||||
|
*/
|
||||||
|
fun toFloatBits(): Float {
|
||||||
|
val color = (255 * a).toInt() shl 24 or ((255 * b).toInt() shl 16) or ((255 * g).toInt() shl 8) or (255 * r).toInt()
|
||||||
|
return NumberUtils.intToFloatColor(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Packs the color components into a 32-bit integer with the format ABGR.
|
||||||
|
* @return the packed color as a 32-bit int.
|
||||||
|
*/
|
||||||
|
fun toIntBits(): Int {
|
||||||
|
return (255 * a).toInt() shl 24 or ((255 * b).toInt() shl 16) or ((255 * g).toInt() shl 8) or (255 * r).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the color encoded as hex string with the format RRGGBBAA. */
|
||||||
|
override fun toString(): String {
|
||||||
|
var value = Integer
|
||||||
|
.toHexString((255 * r).toInt() shl 24 or ((255 * g).toInt() shl 16) or ((255 * b).toInt() shl 8) or (255 * a).toInt())
|
||||||
|
while (value.length < 8)
|
||||||
|
value = "0$value"
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the RGB Cvec components using the specified Hue-Saturation-Value. Note that HSV components are voluntary not clamped
|
||||||
|
* to preserve high range color and can range beyond typical values.
|
||||||
|
* @param h The Hue in degree from 0 to 360
|
||||||
|
* @param s The Saturation from 0 to 1
|
||||||
|
* @param v The Value (brightness) from 0 to 1
|
||||||
|
* @return The modified Cvec for chaining.
|
||||||
|
*/
|
||||||
|
fun fromHsv(h: Float, s: Float, v: Float): Cvec {
|
||||||
|
val x = (h / 60f + 6) % 6
|
||||||
|
val i = x.toInt()
|
||||||
|
val f = x - i
|
||||||
|
val p = v * (1 - s)
|
||||||
|
val q = v * (1 - s * f)
|
||||||
|
val t = v * (1 - s * (1 - f))
|
||||||
|
when (i) {
|
||||||
|
0 -> {
|
||||||
|
r = v
|
||||||
|
g = t
|
||||||
|
b = p
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
r = q
|
||||||
|
g = v
|
||||||
|
b = p
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
r = p
|
||||||
|
g = v
|
||||||
|
b = t
|
||||||
|
}
|
||||||
|
3 -> {
|
||||||
|
r = p
|
||||||
|
g = q
|
||||||
|
b = v
|
||||||
|
}
|
||||||
|
4 -> {
|
||||||
|
r = t
|
||||||
|
g = p
|
||||||
|
b = v
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
r = v
|
||||||
|
g = p
|
||||||
|
b = q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return clamp();
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets RGB components using the specified Hue-Saturation-Value. This is a convenient method for
|
||||||
|
* [.fromHsv]. This is the inverse of [.toHsv].
|
||||||
|
* @param hsv The Hue, Saturation and Value components in that order.
|
||||||
|
* @return The modified Cvec for chaining.
|
||||||
|
*/
|
||||||
|
fun fromHsv(hsv: FloatArray): Cvec {
|
||||||
|
return fromHsv(hsv[0], hsv[1], hsv[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extract Hue-Saturation-Value. This is the inverse of [.fromHsv].
|
||||||
|
* @param hsv The HSV array to be modified.
|
||||||
|
* @return HSV components for chaining.
|
||||||
|
*/
|
||||||
|
fun toHsv(hsv: FloatArray): FloatArray {
|
||||||
|
val max = Math.max(Math.max(r, g), b)
|
||||||
|
val min = Math.min(Math.min(r, g), b)
|
||||||
|
val range = max - min
|
||||||
|
if (range == 0f) {
|
||||||
|
hsv[0] = 0f
|
||||||
|
}
|
||||||
|
else if (max == r) {
|
||||||
|
hsv[0] = (60 * (g - b) / range + 360) % 360
|
||||||
|
}
|
||||||
|
else if (max == g) {
|
||||||
|
hsv[0] = 60 * (b - r) / range + 120
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hsv[0] = 60 * (r - g) / range + 240
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max > 0) {
|
||||||
|
hsv[1] = 1 - min / max
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hsv[1] = 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
hsv[2] = max
|
||||||
|
|
||||||
|
return hsv
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a copy of this color
|
||||||
|
*/
|
||||||
|
fun cpy(): Cvec {
|
||||||
|
return Cvec(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val WHITE = Cvec(1f, 1f, 1f, 1f)
|
||||||
|
|
||||||
|
/** Returns a new color from a hex string with the format RRGGBBAA.
|
||||||
|
* @see .toString
|
||||||
|
*/
|
||||||
|
fun valueOf(hex: String): Cvec {
|
||||||
|
var hex = hex
|
||||||
|
hex = if (hex[0] == '#') hex.substring(1) else hex
|
||||||
|
val r = Integer.valueOf(hex.substring(0, 2), 16)
|
||||||
|
val g = Integer.valueOf(hex.substring(2, 4), 16)
|
||||||
|
val b = Integer.valueOf(hex.substring(4, 6), 16)
|
||||||
|
val a = if (hex.length != 8) 255 else Integer.valueOf(hex.substring(6, 8), 16)
|
||||||
|
return Cvec(r / 255f, g / 255f, b / 255f, a / 255f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Packs the color components into a 32-bit integer with the format ABGR. Note that no range checking is performed for higher
|
||||||
|
* performance.
|
||||||
|
* @param r the red component, 0 - 255
|
||||||
|
* @param g the green component, 0 - 255
|
||||||
|
* @param b the blue component, 0 - 255
|
||||||
|
* @param a the alpha component, 0 - 255
|
||||||
|
* @return the packed color as a 32-bit int
|
||||||
|
*/
|
||||||
|
fun toIntBits(r: Int, g: Int, b: Int, a: Int): Int {
|
||||||
|
return a shl 24 or (b shl 16) or (g shl 8) or r
|
||||||
|
}
|
||||||
|
|
||||||
|
fun alpha(alpha: Float): Int {
|
||||||
|
return (alpha * 255.0f).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rgba8888(r: Float, g: Float, b: Float, a: Float): Int {
|
||||||
|
return (r * 255).toInt() shl 24 or ((g * 255).toInt() shl 16) or ((b * 255).toInt() shl 8) or (a * 255).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun argb8888(a: Float, r: Float, g: Float, b: Float): Int {
|
||||||
|
return (a * 255).toInt() shl 24 or ((r * 255).toInt() shl 16) or ((g * 255).toInt() shl 8) or (b * 255).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rgba8888(color: Cvec): Int {
|
||||||
|
return (color.r * 255).toInt() shl 24 or ((color.g * 255).toInt() shl 16) or ((color.b * 255).toInt() shl 8) or (color.a * 255).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun argb8888(color: Cvec): Int {
|
||||||
|
return (color.a * 255).toInt() shl 24 or ((color.r * 255).toInt() shl 16) or ((color.g * 255).toInt() shl 8) or (color.b * 255).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the Cvec components using the specified integer value in the format RGBA8888. This is inverse to the rgba8888(r, g,
|
||||||
|
* b, a) method.
|
||||||
|
*
|
||||||
|
* @param color The Cvec to be modified.
|
||||||
|
* @param value An integer color value in RGBA8888 format.
|
||||||
|
*/
|
||||||
|
fun rgba8888ToCvec(color: Cvec, value: Int) {
|
||||||
|
color.r = (value and -0x1000000).ushr(24) / 255f
|
||||||
|
color.g = (value and 0x00ff0000).ushr(16) / 255f
|
||||||
|
color.b = (value and 0x0000ff00).ushr(8) / 255f
|
||||||
|
color.a = (value and 0x000000ff) / 255f
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the Cvec components using the specified integer value in the format ARGB8888. This is the inverse to the argb8888(a,
|
||||||
|
* r, g, b) method
|
||||||
|
*
|
||||||
|
* @param color The Cvec to be modified.
|
||||||
|
* @param value An integer color value in ARGB8888 format.
|
||||||
|
*/
|
||||||
|
fun argb8888ToCvec(color: Cvec, value: Int) {
|
||||||
|
color.a = (value and -0x1000000).ushr(24) / 255f
|
||||||
|
color.r = (value and 0x00ff0000).ushr(16) / 255f
|
||||||
|
color.g = (value and 0x0000ff00).ushr(8) / 255f
|
||||||
|
color.b = (value and 0x000000ff) / 255f
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the Cvec components using the specified float value in the format ABGB8888.
|
||||||
|
* @param color The Cvec to be modified.
|
||||||
|
*/
|
||||||
|
fun abgr8888ToCvec(color: Cvec, value: Float) {
|
||||||
|
val c = NumberUtils.floatToIntColor(value)
|
||||||
|
color.a = (c and -0x1000000).ushr(24) / 255f
|
||||||
|
color.b = (c and 0x00ff0000).ushr(16) / 255f
|
||||||
|
color.g = (c and 0x0000ff00).ushr(8) / 255f
|
||||||
|
color.r = (c and 0x000000ff) / 255f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.badlogic.gdx.graphics;
|
package net.torvald.gdx.graphics;
|
||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.utils.StreamUtils;
|
import com.badlogic.gdx.utils.StreamUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
0
src/net/torvald/gdx/lwjgl/audio/OpenALAudio.java
Normal file
0
src/net/torvald/gdx/lwjgl/audio/OpenALAudio.java
Normal file
@@ -5,23 +5,15 @@ import com.badlogic.gdx.Gdx
|
|||||||
import com.badlogic.gdx.Screen
|
import com.badlogic.gdx.Screen
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.math.Affine2
|
|
||||||
import com.jme3.math.FastMath
|
|
||||||
import net.torvald.colourutil.CIEYXY
|
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toColorRaw
|
import net.torvald.colourutil.CIEXYZUtil.toColorRaw
|
||||||
import net.torvald.colourutil.CIEXYZUtil.toColor
|
import net.torvald.colourutil.CIEXYZUtil.toXYZ
|
||||||
import net.torvald.colourutil.RGB
|
import net.torvald.colourutil.CIEYXY
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import java.awt.BorderLayout
|
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
|
|
||||||
const val WIDTH = 1200
|
const val WIDTH = 1200
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplication
|
|||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.PixmapIO2
|
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.gdxClearAndSetBlend
|
import net.torvald.terrarum.gdxClearAndSetBlend
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
|
|||||||
@@ -13,20 +13,20 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
import com.github.strikerx3.jxinput.XInputDevice;
|
import com.github.strikerx3.jxinput.XInputDevice;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import net.torvald.gdx.graphics.PixmapIO2;
|
||||||
import net.torvald.getcpuname.GetCpuName;
|
import net.torvald.getcpuname.GetCpuName;
|
||||||
import net.torvald.terrarum.blockstats.MinimapComposer;
|
|
||||||
import net.torvald.terrarum.controller.GdxControllerAdapter;
|
import net.torvald.terrarum.controller.GdxControllerAdapter;
|
||||||
import net.torvald.terrarum.controller.TerrarumController;
|
import net.torvald.terrarum.controller.TerrarumController;
|
||||||
import net.torvald.terrarum.controller.XinputControllerAdapter;
|
import net.torvald.terrarum.controller.XinputControllerAdapter;
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler;
|
import net.torvald.terrarum.gamecontroller.KeyToggler;
|
||||||
import net.torvald.terrarum.imagefont.TinyAlphNum;
|
import net.torvald.terrarum.imagefont.TinyAlphNum;
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame;
|
import net.torvald.terrarum.modulebasegame.Ingame;
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer;
|
|
||||||
import net.torvald.terrarum.utils.JsonFetcher;
|
import net.torvald.terrarum.utils.JsonFetcher;
|
||||||
import net.torvald.terrarum.utils.JsonWriter;
|
import net.torvald.terrarum.utils.JsonWriter;
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer;
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer;
|
||||||
@@ -256,8 +256,8 @@ public class AppLoader implements ApplicationListener {
|
|||||||
public static TextureRegion logo;
|
public static TextureRegion logo;
|
||||||
public static AudioDevice audioDevice;
|
public static AudioDevice audioDevice;
|
||||||
|
|
||||||
private Color gradWhiteTop = new Color(0xf8f8f8ff);
|
private com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff);
|
||||||
private Color gradWhiteBottom = new Color(0xd8d8d8ff);
|
private com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff);
|
||||||
|
|
||||||
public Screen screen;
|
public Screen screen;
|
||||||
public static int screenW = 0;
|
public static int screenW = 0;
|
||||||
@@ -286,6 +286,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
|
|
||||||
public static CommonResourcePool resourcePool;
|
public static CommonResourcePool resourcePool;
|
||||||
public static HashSet<File> tempFilePool = new HashSet();
|
public static HashSet<File> tempFilePool = new HashSet();
|
||||||
|
public static HashSet<Disposable> disposableSingletonsPool = new HashSet();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
@@ -517,11 +518,12 @@ public class AppLoader implements ApplicationListener {
|
|||||||
screen.dispose();
|
screen.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
IngameRenderer.INSTANCE.dispose();
|
//IngameRenderer.INSTANCE.dispose();
|
||||||
PostProcessor.INSTANCE.dispose();
|
//PostProcessor.INSTANCE.dispose();
|
||||||
MinimapComposer.INSTANCE.dispose();
|
//MinimapComposer.INSTANCE.dispose();
|
||||||
|
//FloatDrawer.INSTANCE.dispose();
|
||||||
|
|
||||||
Terrarum.INSTANCE.dispose();
|
//Terrarum.INSTANCE.dispose();
|
||||||
|
|
||||||
shaderBayerSkyboxFill.dispose();
|
shaderBayerSkyboxFill.dispose();
|
||||||
shaderHicolour.dispose();
|
shaderHicolour.dispose();
|
||||||
@@ -539,6 +541,8 @@ public class AppLoader implements ApplicationListener {
|
|||||||
textureWhiteCircle.dispose();
|
textureWhiteCircle.dispose();
|
||||||
logo.getTexture().dispose();
|
logo.getTexture().dispose();
|
||||||
|
|
||||||
|
disposableSingletonsPool.forEach(Disposable::dispose);
|
||||||
|
|
||||||
ModMgr.INSTANCE.disposeMods();
|
ModMgr.INSTANCE.disposeMods();
|
||||||
|
|
||||||
deleteTempfiles();
|
deleteTempfiles();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package net.torvald.terrarum
|
|||||||
import com.badlogic.gdx.files.FileHandle
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import javax.naming.OperationNotSupportedException
|
import net.torvald.gdx.graphics.Cvec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-06-17.
|
* Created by minjaesong on 2017-06-17.
|
||||||
@@ -19,9 +19,11 @@ class GdxColorMap {
|
|||||||
height = pixmap.height
|
height = pixmap.height
|
||||||
is2D = pixmap.height > 1
|
is2D = pixmap.height > 1
|
||||||
|
|
||||||
data = kotlin.IntArray(pixmap.width * pixmap.height) {
|
dataRaw = kotlin.IntArray(pixmap.width * pixmap.height) {
|
||||||
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
|
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
|
||||||
}
|
}
|
||||||
|
dataGdxColor = dataRaw.map { Color(it) }.toTypedArray()
|
||||||
|
dataCvec = dataRaw.map { Cvec(it) }.toTypedArray()
|
||||||
|
|
||||||
pixmap.dispose()
|
pixmap.dispose()
|
||||||
}
|
}
|
||||||
@@ -31,39 +33,49 @@ class GdxColorMap {
|
|||||||
height = pixmap.height
|
height = pixmap.height
|
||||||
is2D = pixmap.height > 1
|
is2D = pixmap.height > 1
|
||||||
|
|
||||||
data = kotlin.IntArray(pixmap.width * pixmap.height) {
|
dataRaw = kotlin.IntArray(pixmap.width * pixmap.height) {
|
||||||
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
|
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
|
||||||
}
|
}
|
||||||
|
dataGdxColor = dataRaw.map { Color(it) }.toTypedArray()
|
||||||
|
dataCvec = dataRaw.map { Cvec(it) }.toTypedArray()
|
||||||
|
|
||||||
if (disposePixmap) pixmap.dispose()
|
if (disposePixmap) pixmap.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(color: Color) {
|
constructor(color: Color) {
|
||||||
data = intArrayOf(color.toIntBits())
|
dataRaw = intArrayOf(color.toIntBits())
|
||||||
|
dataGdxColor = dataRaw.map { Color(it) }.toTypedArray()
|
||||||
|
dataCvec = dataRaw.map { Cvec(it) }.toTypedArray()
|
||||||
width = 1
|
width = 1
|
||||||
height = 1
|
height = 1
|
||||||
is2D = false
|
is2D = false
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(gradStart: Color, gradEnd: Color) {
|
constructor(gradStart: Color, gradEnd: Color) {
|
||||||
data = intArrayOf(gradStart.toIntBits(), gradEnd.toIntBits())
|
dataRaw = intArrayOf(gradStart.toIntBits(), gradEnd.toIntBits())
|
||||||
|
dataGdxColor = dataRaw.map { Color(it) }.toTypedArray()
|
||||||
|
dataCvec = dataRaw.map { Cvec(it) }.toTypedArray()
|
||||||
width = 1
|
width = 1
|
||||||
height = 2
|
height = 2
|
||||||
is2D = true
|
is2D = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private val data: IntArray
|
private val dataRaw: IntArray
|
||||||
|
private val dataGdxColor: Array<Color>
|
||||||
|
private val dataCvec: Array<Cvec>
|
||||||
val width: Int
|
val width: Int
|
||||||
val height: Int
|
val height: Int
|
||||||
val is2D: Boolean
|
val is2D: Boolean
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun get(x: Int, y: Int): Color = Color(data[y * width + x])
|
fun get(x: Int, y: Int): Color = dataGdxColor[y * width + x]
|
||||||
operator fun get(x: Int): Color = if (is2D) throw OperationNotSupportedException("This is 2D color map") else Color(data[x])
|
operator fun get(x: Int): Color = if (is2D) throw UnsupportedOperationException("This is 2D color map") else dataGdxColor[x]
|
||||||
|
|
||||||
fun getRaw(x: Int, y: Int): RGBA8888 = data[y * width + x]
|
fun getRaw(x: Int, y: Int): RGBA8888 = dataRaw[y * width + x]
|
||||||
fun getRaw(x: Int): RGBA8888 = if (is2D) throw OperationNotSupportedException("This is 2D color map") else data[x]
|
fun getRaw(x: Int): RGBA8888 = if (is2D) throw UnsupportedOperationException("This is 2D color map") else dataRaw[x]
|
||||||
|
|
||||||
|
//fun getAsCvec(x: Int, y: Int): Cvec = dataCvec[y * width + x]
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
|
|||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import com.jme3.math.FastMath
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum
|
|||||||
import com.badlogic.gdx.Screen
|
import com.badlogic.gdx.Screen
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
@@ -74,7 +75,15 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You ABSOLUTELY must call this in your child classes (```super.dispose()```) and the AppLoader to properly
|
||||||
|
* dispose of the world, which uses unsafe memory allocation.
|
||||||
|
* Failing to do this will result to a memory leak!
|
||||||
|
*/
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
printdbg(this, "Thank you for properly disposing the world!")
|
||||||
|
|
||||||
|
world.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
@@ -94,16 +103,18 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* I have decided that left and right clicks must do the same thing, so no secondary use from now on. --Torvald on 2019-05-26
|
||||||
|
*
|
||||||
* Event for triggering held item's `startSecondaryUse(Float)`
|
* Event for triggering held item's `startSecondaryUse(Float)`
|
||||||
*/
|
*/
|
||||||
open fun worldSecondaryClickStart(delta: Float) {
|
//open fun worldSecondaryClickStart(delta: Float) { }
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* I have decided that left and right clicks must do the same thing, so no secondary use from now on. --Torvald on 2019-05-26
|
||||||
|
*
|
||||||
* Event for triggering held item's `endSecondaryUse(Float)`
|
* Event for triggering held item's `endSecondaryUse(Float)`
|
||||||
*/
|
*/
|
||||||
open fun worldSecondaryClickEnd(delta: Float) {
|
//open fun worldSecondaryClickEnd(delta: Float) { }
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event for triggering fixture update when something is placed/removed on the world.
|
* Event for triggering fixture update when something is placed/removed on the world.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
import com.badlogic.gdx.math.Matrix4
|
import com.badlogic.gdx.math.Matrix4
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
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
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||||
@@ -18,7 +19,7 @@ import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
|||||||
/**
|
/**
|
||||||
* Must be called by the App Loader
|
* Must be called by the App Loader
|
||||||
*/
|
*/
|
||||||
object PostProcessor {
|
object PostProcessor : Disposable {
|
||||||
|
|
||||||
private lateinit var batch: SpriteBatch // not nulling to save some lines of code
|
private lateinit var batch: SpriteBatch // not nulling to save some lines of code
|
||||||
private lateinit var shapeRenderer: ShapeRenderer
|
private lateinit var shapeRenderer: ShapeRenderer
|
||||||
@@ -40,7 +41,11 @@ object PostProcessor {
|
|||||||
|
|
||||||
private var functionRowHelper = Texture(Gdx.files.internal("assets/graphics/function_row_help.png"))
|
private var functionRowHelper = Texture(Gdx.files.internal("assets/graphics/function_row_help.png"))
|
||||||
|
|
||||||
fun dispose() {
|
init {
|
||||||
|
AppLoader.disposableSingletonsPool.add(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
batch.dispose()
|
batch.dispose()
|
||||||
shapeRenderer.dispose()
|
shapeRenderer.dispose()
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
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.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
@@ -37,7 +38,7 @@ typealias RGBA8888 = Int
|
|||||||
*
|
*
|
||||||
* LibGDX Version Created by minjaesong on 2017-06-15.
|
* LibGDX Version Created by minjaesong on 2017-06-15.
|
||||||
*/
|
*/
|
||||||
object Terrarum : Screen {
|
object Terrarum : Screen, Disposable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All singleplayer "Player" must have this exact reference ID.
|
* All singleplayer "Player" must have this exact reference ID.
|
||||||
@@ -212,6 +213,9 @@ object Terrarum : Screen {
|
|||||||
|
|
||||||
setGamepadButtonLabels()
|
setGamepadButtonLabels()
|
||||||
|
|
||||||
|
|
||||||
|
AppLoader.disposableSingletonsPool.add(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setGamepadButtonLabels() {
|
private fun setGamepadButtonLabels() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
import net.torvald.terrarumsansbitmap.gdx.GameFontBase
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,10 @@ import net.torvald.terrarum.modulebasegame.gameworld.WorldTime
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
||||||
import net.torvald.terrarum.modulebasegame.weather.WeatherMixer
|
import net.torvald.terrarum.modulebasegame.weather.WeatherMixer
|
||||||
import net.torvald.terrarum.serialise.ReadLayerData
|
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import java.io.FileInputStream
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-09-02.
|
* Created by minjaesong on 2017-09-02.
|
||||||
@@ -129,7 +127,10 @@ class TitleScreen(val batch: SpriteBatch) : Screen {
|
|||||||
printdbg(this, "Intro pre-load")
|
printdbg(this, "Intro pre-load")
|
||||||
|
|
||||||
|
|
||||||
demoWorld = ReadLayerData(FileInputStream(ModMgr.getFile("basegame", "demoworld")))
|
demoWorld = GameWorldExtension(1, 64, 64, 0L, 0L, 0)
|
||||||
|
|
||||||
|
printdbg(this, "Demo world gen complete")
|
||||||
|
|
||||||
// set time to summer
|
// set time to summer
|
||||||
demoWorld.time.addTime(WorldTime.DAY_LENGTH * 32)
|
demoWorld.time.addTime(WorldTime.DAY_LENGTH * 32)
|
||||||
|
|
||||||
@@ -138,7 +139,7 @@ class TitleScreen(val batch: SpriteBatch) : Screen {
|
|||||||
cameraNodes = kotlin.FloatArray(nodeCount) { it ->
|
cameraNodes = kotlin.FloatArray(nodeCount) { it ->
|
||||||
val tileXPos = (demoWorld.width.toFloat() * it / nodeCount).floorInt()
|
val tileXPos = (demoWorld.width.toFloat() * it / nodeCount).floorInt()
|
||||||
var travelDownCounter = 0
|
var travelDownCounter = 0
|
||||||
while (!BlockCodex[demoWorld.getTileFromTerrain(tileXPos, travelDownCounter)].isSolid) {
|
while (travelDownCounter < demoWorld.height && !BlockCodex[demoWorld.getTileFromTerrain(tileXPos, travelDownCounter)].isSolid) {
|
||||||
travelDownCounter += 4
|
travelDownCounter += 4
|
||||||
}
|
}
|
||||||
travelDownCounter * CreateTileAtlas.TILE_SIZE.toFloat()
|
travelDownCounter * CreateTileAtlas.TILE_SIZE.toFloat()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.modulebasegame.Ingame
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
||||||
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.toItemCountText
|
||||||
import net.torvald.terrarum.ui.UIItemTextButton
|
import net.torvald.terrarum.ui.UIItemTextButton
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -90,6 +91,8 @@ class UIItemInventoryElem(
|
|||||||
|
|
||||||
|
|
||||||
if (item != null && itemImage != null) {
|
if (item != null && itemImage != null) {
|
||||||
|
val amountString = amount.toItemCountText()
|
||||||
|
|
||||||
blendNormal(batch)
|
blendNormal(batch)
|
||||||
|
|
||||||
// item image
|
// item image
|
||||||
@@ -103,7 +106,7 @@ class UIItemInventoryElem(
|
|||||||
if (AppLoader.IS_DEVELOPMENT_BUILD) {
|
if (AppLoader.IS_DEVELOPMENT_BUILD) {
|
||||||
Terrarum.fontGame.draw(batch,
|
Terrarum.fontGame.draw(batch,
|
||||||
// print static id, dynamic id, and count
|
// print static id, dynamic id, and count
|
||||||
"${item!!.originalID}/${item!!.dynamicID}" + (if (amount > 0 && item!!.stackable) "$fwsp($amount)" else if (amount != 1) "$fwsp!!$amount!!" else ""),
|
"${item!!.originalID}/${item!!.dynamicID}" + (if (amount > 0 && item!!.stackable) "$fwsp($amountString)" else if (amount != 1) "$fwsp!!$amountString!!" else ""),
|
||||||
posX + textOffsetX,
|
posX + textOffsetX,
|
||||||
posY + textOffsetY
|
posY + textOffsetY
|
||||||
)
|
)
|
||||||
@@ -111,7 +114,7 @@ class UIItemInventoryElem(
|
|||||||
else {
|
else {
|
||||||
Terrarum.fontGame.draw(batch,
|
Terrarum.fontGame.draw(batch,
|
||||||
// print name and amount in parens
|
// print name and amount in parens
|
||||||
item!!.name + (if (amount > 0 && item!!.stackable) "$fwsp($amount)" else if (amount != 1) "$fwsp!!$amount!!" else "") +
|
item!!.name + (if (amount > 0 && item!!.stackable) "$fwsp($amountString)" else if (amount != 1) "$fwsp!!$amountString!!" else "") +
|
||||||
// TEMPORARY print eqipped slot info as well
|
// TEMPORARY print eqipped slot info as well
|
||||||
(if (equippedSlot != null) " ${0xE081.toChar()}\$$equippedSlot" else ""),
|
(if (equippedSlot != null) " ${0xE081.toChar()}\$$equippedSlot" else ""),
|
||||||
|
|
||||||
@@ -188,7 +191,7 @@ class UIItemInventoryElem(
|
|||||||
// equip da shit
|
// equip da shit
|
||||||
val itemEquipSlot = item!!.equipPosition
|
val itemEquipSlot = item!!.equipPosition
|
||||||
if (itemEquipSlot == GameItem.EquipPosition.NULL) {
|
if (itemEquipSlot == GameItem.EquipPosition.NULL) {
|
||||||
TODO("Equip position is NULL, does this mean it's single-consume items like a potion?")
|
TODO("Equip position is NULL, does this mean it's single-consume items like a potion? (from item: \"$item\" with itemID: ${item?.originalID}/${item?.dynamicID})")
|
||||||
}
|
}
|
||||||
|
|
||||||
val player = (Terrarum.ingame!! as Ingame).actorNowPlaying
|
val player = (Terrarum.ingame!! as Ingame).actorNowPlaying
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.modulebasegame.Ingame
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
||||||
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.toItemCountText
|
||||||
import net.torvald.terrarum.ui.UIItemTextButton
|
import net.torvald.terrarum.ui.UIItemTextButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,7 +108,7 @@ class UIItemInventoryElemSimple(
|
|||||||
}
|
}
|
||||||
// draw item count when applicable
|
// draw item count when applicable
|
||||||
else if (item!!.stackable) {
|
else if (item!!.stackable) {
|
||||||
val amountString = amount.toString()
|
val amountString = amount.toItemCountText()
|
||||||
|
|
||||||
// highlight item count (blocks/walls) if the item is equipped
|
// highlight item count (blocks/walls) if the item is equipped
|
||||||
if (equippedSlot != null) {
|
if (equippedSlot != null) {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ object Block {
|
|||||||
const val DAYLIGHT_CAPACITOR = 258
|
const val DAYLIGHT_CAPACITOR = 258
|
||||||
|
|
||||||
|
|
||||||
const val ACTORBLOCK_NO_COLLISION = 4191
|
const val ACTORBLOCK_NO_COLLISION = 4091
|
||||||
const val ACTORBLOCK_FULL_COLLISION = 4092
|
const val ACTORBLOCK_FULL_COLLISION = 4092
|
||||||
const val ACTORBLOCK_ALLOW_MOVE_DOWN = 4093
|
const val ACTORBLOCK_ALLOW_MOVE_DOWN = 4093
|
||||||
const val ACTORBLOCK_NO_PASS_RIGHT = 4094
|
const val ACTORBLOCK_NO_PASS_RIGHT = 4094
|
||||||
@@ -127,4 +127,12 @@ object Block {
|
|||||||
const val WATER = 4095
|
const val WATER = 4095
|
||||||
|
|
||||||
const val NULL = -1
|
const val NULL = -1
|
||||||
|
|
||||||
|
val actorblocks = listOf(
|
||||||
|
ACTORBLOCK_NO_COLLISION,
|
||||||
|
ACTORBLOCK_FULL_COLLISION,
|
||||||
|
ACTORBLOCK_ALLOW_MOVE_DOWN,
|
||||||
|
ACTORBLOCK_NO_PASS_RIGHT,
|
||||||
|
ACTORBLOCK_NO_PASS_LEFT
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package net.torvald.terrarum.blockproperties
|
package net.torvald.terrarum.blockproperties
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.AppLoader.printmsg
|
import net.torvald.terrarum.AppLoader.printmsg
|
||||||
import net.torvald.terrarum.gameworld.FluidType
|
import net.torvald.terrarum.gameworld.FluidType
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.MapLayer
|
|
||||||
import net.torvald.terrarum.gameworld.PairedMapLayer
|
|
||||||
import net.torvald.terrarum.utils.CSVFetcher
|
import net.torvald.terrarum.utils.CSVFetcher
|
||||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||||
import org.apache.commons.csv.CSVRecord
|
import org.apache.commons.csv.CSVRecord
|
||||||
@@ -20,7 +18,7 @@ object BlockCodex {
|
|||||||
private var blockProps = HashMap<Int, BlockProp>()
|
private var blockProps = HashMap<Int, BlockProp>()
|
||||||
|
|
||||||
/** 4096 */
|
/** 4096 */
|
||||||
const val MAX_TERRAIN_TILES = MapLayer.RANGE * PairedMapLayer.RANGE
|
const val MAX_TERRAIN_TILES = GameWorld.TILES_SUPPORTED
|
||||||
|
|
||||||
private val nullProp = BlockProp()
|
private val nullProp = BlockProp()
|
||||||
|
|
||||||
@@ -110,7 +108,7 @@ object BlockCodex {
|
|||||||
prop.shadeColG = floatVal(record, "shdg") / LightmapRenderer.MUL_FLOAT
|
prop.shadeColG = floatVal(record, "shdg") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.shadeColB = floatVal(record, "shdb") / LightmapRenderer.MUL_FLOAT
|
prop.shadeColB = floatVal(record, "shdb") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.shadeColA = floatVal(record, "shduv") / LightmapRenderer.MUL_FLOAT
|
prop.shadeColA = floatVal(record, "shduv") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.opacity = Color(prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA)
|
prop.opacity = Cvec(prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA)
|
||||||
|
|
||||||
prop.strength = intVal(record, "str")
|
prop.strength = intVal(record, "str")
|
||||||
prop.density = intVal(record, "dsty")
|
prop.density = intVal(record, "dsty")
|
||||||
@@ -119,7 +117,7 @@ object BlockCodex {
|
|||||||
prop.lumColG = floatVal(record, "lumg") / LightmapRenderer.MUL_FLOAT
|
prop.lumColG = floatVal(record, "lumg") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.lumColB = floatVal(record, "lumb") / LightmapRenderer.MUL_FLOAT
|
prop.lumColB = floatVal(record, "lumb") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.lumColA = floatVal(record, "lumuv") / LightmapRenderer.MUL_FLOAT
|
prop.lumColA = floatVal(record, "lumuv") / LightmapRenderer.MUL_FLOAT
|
||||||
prop.internalLumCol = Color(prop.lumColR, prop.lumColG, prop.lumColB, prop.lumColA)
|
prop.internalLumCol = Cvec(prop.lumColR, prop.lumColG, prop.lumColB, prop.lumColA)
|
||||||
|
|
||||||
prop.friction = intVal(record, "fr")
|
prop.friction = intVal(record, "fr")
|
||||||
prop.viscosity = intVal(record, "vscs")
|
prop.viscosity = intVal(record, "vscs")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.torvald.terrarum.blockproperties
|
package net.torvald.terrarum.blockproperties
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-02-16.
|
* Created by minjaesong on 2016-02-16.
|
||||||
@@ -17,7 +17,7 @@ class BlockProp {
|
|||||||
var shadeColB = 0f
|
var shadeColB = 0f
|
||||||
var shadeColA = 0f
|
var shadeColA = 0f
|
||||||
|
|
||||||
lateinit var opacity: Color
|
lateinit var opacity: Cvec
|
||||||
|
|
||||||
var strength: Int = 0
|
var strength: Int = 0
|
||||||
var density: Int = 0
|
var density: Int = 0
|
||||||
@@ -36,12 +36,12 @@ class BlockProp {
|
|||||||
var lumColG = 0f
|
var lumColG = 0f
|
||||||
var lumColB = 0f
|
var lumColB = 0f
|
||||||
var lumColA = 0f
|
var lumColA = 0f
|
||||||
lateinit var internalLumCol: Color
|
lateinit var internalLumCol: Cvec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param luminosity
|
* @param luminosity
|
||||||
*/
|
*/
|
||||||
inline val luminosity: Color
|
inline val luminosity: Cvec
|
||||||
get() = BlockPropUtil.getDynamicLumFunc(internalLumCol, dynamicLuminosityFunction)
|
get() = BlockPropUtil.getDynamicLumFunc(internalLumCol, dynamicLuminosityFunction)
|
||||||
|
|
||||||
var drop: Int = 0
|
var drop: Int = 0
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package net.torvald.terrarum.blockproperties
|
package net.torvald.terrarum.blockproperties
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.Second
|
import net.torvald.terrarum.Second
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
@@ -37,7 +37,7 @@ object BlockPropUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTorchFlicker(baseLum: Color): Color {
|
private fun getTorchFlicker(baseLum: Cvec): Cvec {
|
||||||
val funcY = FastMath.interpolateCatmullRom(0.0f, flickerFuncX / flickerFuncDomain,
|
val funcY = FastMath.interpolateCatmullRom(0.0f, flickerFuncX / flickerFuncDomain,
|
||||||
flickerP0, flickerP1, flickerP2, flickerP3
|
flickerP0, flickerP1, flickerP2, flickerP3
|
||||||
)
|
)
|
||||||
@@ -45,13 +45,13 @@ object BlockPropUtil {
|
|||||||
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSlowBreath(baseLum: Color): Color {
|
private fun getSlowBreath(baseLum: Cvec): Cvec {
|
||||||
val funcY = FastMath.sin(FastMath.PI * breathFuncX / breathCycleDuration) * breathRange
|
val funcY = FastMath.sin(FastMath.PI * breathFuncX / breathCycleDuration) * breathRange
|
||||||
|
|
||||||
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPulsate(baseLum: Color): Color {
|
private fun getPulsate(baseLum: Cvec): Cvec {
|
||||||
val funcY = FastMath.sin(FastMath.PI * pulsateFuncX / pulsateCycleDuration) * pulsateRange
|
val funcY = FastMath.sin(FastMath.PI * pulsateFuncX / pulsateCycleDuration) * pulsateRange
|
||||||
|
|
||||||
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
||||||
@@ -91,7 +91,7 @@ object BlockPropUtil {
|
|||||||
|
|
||||||
private fun linearInterpolation1D(a: Float, b: Float, x: Float) = a * (1 - x) + b * x
|
private fun linearInterpolation1D(a: Float, b: Float, x: Float) = a * (1 - x) + b * x
|
||||||
|
|
||||||
fun getDynamicLumFunc(baseLum: Color, type: Int): Color {
|
fun getDynamicLumFunc(baseLum: Cvec, type: Int): Cvec {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
1 -> getTorchFlicker(baseLum)
|
1 -> getTorchFlicker(baseLum)
|
||||||
2 -> (Terrarum.ingame!!.world).globalLight.cpy().mul(LightmapRenderer.DIV_FLOAT) // current global light
|
2 -> (Terrarum.ingame!!.world).globalLight.cpy().mul(LightmapRenderer.DIV_FLOAT) // current global light
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package net.torvald.terrarum.blockstats
|
|||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.MapLayer
|
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
@@ -71,11 +70,5 @@ object BlockStats {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
|
|
||||||
* @return copy of the stat data
|
|
||||||
*/
|
|
||||||
val statCopy: ShortArray
|
|
||||||
get() = Arrays.copyOf(tilestat, MapLayer.RANGE)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.blockstats
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
@@ -12,7 +13,7 @@ import net.torvald.terrarum.gameworld.GameWorld
|
|||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
|
|
||||||
object MinimapComposer {
|
object MinimapComposer : Disposable {
|
||||||
|
|
||||||
// strategy: mosaic the textures, maximum texture size is 4 096.
|
// strategy: mosaic the textures, maximum texture size is 4 096.
|
||||||
|
|
||||||
@@ -66,6 +67,8 @@ object MinimapComposer {
|
|||||||
init {
|
init {
|
||||||
totalWidth = minimap.width
|
totalWidth = minimap.width
|
||||||
totalHeight = minimap.height
|
totalHeight = minimap.height
|
||||||
|
|
||||||
|
AppLoader.disposableSingletonsPool.add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
@@ -147,7 +150,7 @@ object MinimapComposer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
override fun dispose() {
|
||||||
liveTiles.forEach { it.dispose() }
|
liveTiles.forEach { it.dispose() }
|
||||||
minimap.dispose()
|
minimap.dispose()
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.concurrent
|
package net.torvald.terrarum.concurrent
|
||||||
|
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
typealias RunnableFun = () -> Unit
|
typealias RunnableFun = () -> Unit
|
||||||
/** Int: index of the processing core */
|
/** Int: index of the processing core */
|
||||||
@@ -12,7 +13,7 @@ typealias ThreadableFun = (Int) -> Unit
|
|||||||
object ThreadParallel {
|
object ThreadParallel {
|
||||||
val threadCount = Terrarum.THREADS // modify this to your taste
|
val threadCount = Terrarum.THREADS // modify this to your taste
|
||||||
|
|
||||||
private val pool: Array<Thread?> = Array(threadCount, { null })
|
private val pool: Array<Thread?> = Array(threadCount) { null }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map Runnable object to certain index of the thread pool.
|
* Map Runnable object to certain index of the thread pool.
|
||||||
@@ -189,13 +190,19 @@ object ParallelUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IntRange.sliceEvenly(slices: Int): List<IntRange> {
|
fun IntProgression.sliceEvenly(slices: Int): List<IntProgression> {
|
||||||
if (this.step != 1) throw UnsupportedOperationException("Sorry, step != 1")
|
if (this.step.absoluteValue != 1) throw UnsupportedOperationException("Sorry, step != +1/-1")
|
||||||
val size = this.last - this.first + 1f
|
val size = (this.last - this.first).absoluteValue + (this.step.toFloat()).absoluteValue
|
||||||
|
|
||||||
return (0 until slices).map {
|
// println(size)
|
||||||
size.div(slices).times(it).roundInt() until
|
|
||||||
size.div(slices).times(it + 1).roundInt()
|
return if (this.first < this.last) (0 until slices).map {
|
||||||
|
this.first + size.div(slices).times(it).roundInt() ..
|
||||||
|
this.first + size.div(slices).times(it + 1).roundInt() - 1
|
||||||
|
}
|
||||||
|
else (0 until slices).map {
|
||||||
|
this.first - size.div(slices).times(it).roundInt() downTo
|
||||||
|
this.first - size.div(slices).times(it + 1).roundInt() + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package net.torvald.terrarum.console
|
package net.torvald.terrarum.console
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
|
||||||
import net.torvald.terrarum.modulebasegame.weather.WeatherMixer
|
import net.torvald.terrarum.modulebasegame.weather.WeatherMixer
|
||||||
|
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-02-17.
|
* Created by minjaesong on 2016-02-17.
|
||||||
@@ -18,7 +17,7 @@ internal object SetGlobalLightOverride : ConsoleCommand {
|
|||||||
val g = args[2].toFloat()
|
val g = args[2].toFloat()
|
||||||
val b = args[3].toFloat()
|
val b = args[3].toFloat()
|
||||||
val a = args[4].toFloat()
|
val a = args[4].toFloat()
|
||||||
val GL = Color(r, g, b, a)
|
val GL = Cvec(r, g, b, a)
|
||||||
|
|
||||||
WeatherMixer.globalLightOverridden = true
|
WeatherMixer.globalLightOverridden = true
|
||||||
(Terrarum.ingame!!.world).globalLight = GL
|
(Terrarum.ingame!!.world).globalLight = GL
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import net.torvald.terrarum.gameworld.GameWorld
|
|||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
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
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
@@ -1390,8 +1389,6 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
|
|
||||||
// FIXME test me: this extra IF statement is supposed to not draw actors that's outside of the camera.
|
// FIXME test me: this extra IF statement is supposed to not draw actors that's outside of the camera.
|
||||||
// basic code without offsetX/Y DOES work, but obviously offsets are not tested.
|
// basic code without offsetX/Y DOES work, but obviously offsets are not tested.
|
||||||
if (hitbox.startX - offsetX in WorldCamera.x - hitbox.width - offsetX..WorldCamera.x + WorldCamera.width + offsetX &&
|
|
||||||
hitbox.endY + offsetY in WorldCamera.y - hitbox.height - offsetY..WorldCamera.y + WorldCamera.height + offsetY) {
|
|
||||||
if (WorldCamera.xCentre > leftsidePadding && centrePosPoint.x <= rightsidePadding) {
|
if (WorldCamera.xCentre > leftsidePadding && centrePosPoint.x <= rightsidePadding) {
|
||||||
// camera center neg, actor center pos
|
// camera center neg, actor center pos
|
||||||
sprite.render(batch,
|
sprite.render(batch,
|
||||||
@@ -1416,7 +1413,6 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActorValueChange(key: String, value: Any?) {
|
override fun onActorValueChange(key: String, value: Any?) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.dyn4j.geometry.Vector2
|
|||||||
*
|
*
|
||||||
* Created by minjaesong on 2016-01-15.
|
* Created by minjaesong on 2016-01-15.
|
||||||
*/
|
*/
|
||||||
class Hitbox(x1: Double, y1: Double, width: Double, height: Double, var suppressWarning: Boolean = false) {
|
class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppressWarning: Boolean = true) {
|
||||||
|
|
||||||
@Volatile var hitboxStart: Point2d
|
@Volatile var hitboxStart: Point2d
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.torvald.terrarum.gameactors
|
package net.torvald.terrarum.gameactors
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-02-19.
|
* Created by minjaesong on 2016-02-19.
|
||||||
@@ -26,7 +26,7 @@ interface Luminous {
|
|||||||
actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
|
actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
var color: Color
|
var color: Cvec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arguments:
|
* Arguments:
|
||||||
|
|||||||
@@ -58,12 +58,14 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
// 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 (ingame.uiContainer.map { if ((it.isOpening || it.isOpened) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right?
|
||||||
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) {
|
if (
|
||||||
|
Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) ||
|
||||||
|
Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
||||||
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
ingame.worldPrimaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
}
|
}
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) {
|
/*if Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary")) {
|
||||||
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
ingame.worldSecondaryClickStart(AppLoader.UPDATE_RATE.toFloat())
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,12 +148,14 @@ class IngameController(val ingame: Ingame) : InputAdapter() {
|
|||||||
// fire world click events; the event is defined as Ingame's (or any others') WorldClick event
|
// 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 (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")) {
|
if (
|
||||||
|
button == AppLoader.getConfigInt("mouseprimary") ||
|
||||||
|
button == AppLoader.getConfigInt("mousesecondary")) {
|
||||||
ingame.worldPrimaryClickEnd(AppLoader.UPDATE_RATE.toFloat())
|
ingame.worldPrimaryClickEnd(AppLoader.UPDATE_RATE.toFloat())
|
||||||
}
|
}
|
||||||
if (button == AppLoader.getConfigInt("mousesecondary")) {
|
/*if (button == AppLoader.getConfigInt("mousesecondary")) {
|
||||||
ingame.worldSecondaryClickEnd(AppLoader.UPDATE_RATE.toFloat())
|
ingame.worldSecondaryClickEnd(AppLoader.UPDATE_RATE.toFloat())
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,13 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
/**
|
/**
|
||||||
* Where to equip the item.
|
* Where to equip the item.
|
||||||
*
|
*
|
||||||
* Can't use 'open val' as GSON don't like that
|
* Can't use 'open val' as GSON doesn't like that. Initialise this property like:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* init {
|
||||||
|
* equipPosition = EquipPosition.HAND_GRIP
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
var equipPosition: Int = EquipPosition.NULL
|
var equipPosition: Int = EquipPosition.NULL
|
||||||
|
|
||||||
@@ -165,6 +171,8 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
open fun startPrimaryUse(delta: Float): Boolean = false
|
open fun startPrimaryUse(delta: Float): Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* I have decided that left and right clicks must do the same thing, so no secondary use from now on. --Torvald on 2019-05-26
|
||||||
|
*
|
||||||
* Apply effects (continuously or not) while secondary button is down
|
* Apply effects (continuously or not) while secondary button is down
|
||||||
* The item will NOT be consumed, so you will want to consume it yourself by inventory.consumeItem(item)
|
* The item will NOT be consumed, so you will want to consume it yourself by inventory.consumeItem(item)
|
||||||
*
|
*
|
||||||
@@ -174,7 +182,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
*
|
*
|
||||||
* note: DO NOT super() this!
|
* note: DO NOT super() this!
|
||||||
*/
|
*/
|
||||||
open fun startSecondaryUse(delta: Float): Boolean = false
|
//open fun startSecondaryUse(delta: Float): Boolean = false
|
||||||
|
|
||||||
open fun endPrimaryUse(delta: Float): Boolean = false
|
open fun endPrimaryUse(delta: Float): Boolean = false
|
||||||
open fun endSecondaryUse(delta: Float): Boolean = false
|
open fun endSecondaryUse(delta: Float): Boolean = false
|
||||||
|
|||||||
147
src/net/torvald/terrarum/gameworld/BlockLayer.kt
Normal file
147
src/net/torvald/terrarum/gameworld/BlockLayer.kt
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
|
import sun.misc.Unsafe
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2016-01-17.
|
||||||
|
*/
|
||||||
|
open class BlockLayer(val width: Int, val height: Int) : Disposable {
|
||||||
|
|
||||||
|
private val unsafe: Unsafe
|
||||||
|
init {
|
||||||
|
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
|
||||||
|
unsafeConstructor.isAccessible = true
|
||||||
|
unsafe = unsafeConstructor.newInstance()
|
||||||
|
}
|
||||||
|
private var unsafeArrayInitialised = false
|
||||||
|
|
||||||
|
private var layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data Byte array representation of the layer, where:
|
||||||
|
* - every 2n-th byte is lowermost 8 bits of the tile number
|
||||||
|
* - every (2n+1)th byte is uppermost 4 (4096 blocks) or 8 (65536 blocks) bits of the tile number.
|
||||||
|
*
|
||||||
|
* When 4096-block mode is being used, every (2n+1)th byte is filled in this format:
|
||||||
|
* ```
|
||||||
|
* (MSB) 0 0 0 0 a b c d (LSB)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* In other words, the valid range for the every (2n+1)th byte is 0..15.
|
||||||
|
*
|
||||||
|
* TL;DR: LITTLE ENDIAN PLEASE
|
||||||
|
*/
|
||||||
|
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
|
||||||
|
unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())
|
||||||
|
data.forEachIndexed { index, byte -> unsafe.putByte(layerPtr + index, byte) }
|
||||||
|
unsafeArrayInitialised = true
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (!unsafeArrayInitialised) {
|
||||||
|
unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0)
|
||||||
|
unsafeArrayInitialised = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator over blocks of type `Int`.
|
||||||
|
*
|
||||||
|
* @return an Iterator.
|
||||||
|
*/
|
||||||
|
fun blocksIterator(): Iterator<Int> {
|
||||||
|
return object : Iterator<Int> {
|
||||||
|
|
||||||
|
private var iteratorCount = 0
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return iteratorCount < width * height
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Int {
|
||||||
|
val y = iteratorCount / width
|
||||||
|
val x = iteratorCount % width
|
||||||
|
// advance counter
|
||||||
|
iteratorCount += 2
|
||||||
|
|
||||||
|
val offset = 2 * (y * width + x)
|
||||||
|
val lsb = unsafe.getByte(layerPtr + offset)
|
||||||
|
val msb = unsafe.getByte(layerPtr + offset + 1)
|
||||||
|
|
||||||
|
//return data[y * width + x]
|
||||||
|
return lsb.toUint() + msb.toUint().shl(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator over stored bytes.
|
||||||
|
*
|
||||||
|
* @return an Iterator.
|
||||||
|
*/
|
||||||
|
fun bytesIterator(): Iterator<Byte> {
|
||||||
|
return object : Iterator<Byte> {
|
||||||
|
|
||||||
|
private var iteratorCount = 0
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return iteratorCount < width * height
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Byte {
|
||||||
|
val y = iteratorCount / width
|
||||||
|
val x = iteratorCount % width
|
||||||
|
// advance counter
|
||||||
|
iteratorCount += 1
|
||||||
|
|
||||||
|
return unsafe.getByte(layerPtr + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun unsafeGetTile(x: Int, y: Int): Int {
|
||||||
|
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||||
|
val lsb = unsafe.getByte(layerPtr + offset)
|
||||||
|
val msb = unsafe.getByte(layerPtr + offset + 1)
|
||||||
|
|
||||||
|
return lsb.toUint() + msb.toUint().shl(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun unsafeSetTile(x: Int, y: Int, tile: Int) {
|
||||||
|
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||||
|
|
||||||
|
val lsb = tile.and(0xff).toByte()
|
||||||
|
val msb = tile.ushr(8).and(0xff).toByte()
|
||||||
|
|
||||||
|
unsafe.putByte(layerPtr + offset, lsb)
|
||||||
|
unsafe.putByte(layerPtr + offset + 1, msb)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
|
||||||
|
*/
|
||||||
|
internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
|
||||||
|
val offset = 2 * blockOffset
|
||||||
|
|
||||||
|
val lsb = tile.and(0xff).toByte()
|
||||||
|
val msb = tile.ushr(8).and(0xff).toByte()
|
||||||
|
|
||||||
|
unsafe.putByte(layerPtr + offset, lsb)
|
||||||
|
unsafe.putByte(layerPtr + offset + 1, msb)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
unsafe.freeMemory(layerPtr)
|
||||||
|
printdbg(this, "BlockLayer successfully freed")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Transient val BYTES_PER_BLOCK = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
package net.torvald.terrarum.gameworld
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
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
|
||||||
@@ -17,14 +18,14 @@ import kotlin.math.sign
|
|||||||
|
|
||||||
typealias BlockAddress = Long
|
typealias BlockAddress = Long
|
||||||
|
|
||||||
open class GameWorld {
|
open class GameWorld : Disposable {
|
||||||
|
|
||||||
var worldName: String = "New World"
|
var worldName: String = "New World"
|
||||||
/** Index start at 1 */
|
/** Index start at 1 */
|
||||||
var worldIndex: Int
|
var worldIndex: Int
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
throw Error("World index start at 1; you entered $value")
|
throw Error("World index start at 1; you've entered $value")
|
||||||
|
|
||||||
printdbg(this, "Creation of new world with index $value, called by:")
|
printdbg(this, "Creation of new world with index $value, called by:")
|
||||||
Thread.currentThread().stackTrace.forEach {
|
Thread.currentThread().stackTrace.forEach {
|
||||||
@@ -46,17 +47,12 @@ open class GameWorld {
|
|||||||
val loadTime: Long = System.currentTimeMillis() / 1000L
|
val loadTime: Long = System.currentTimeMillis() / 1000L
|
||||||
|
|
||||||
//layers
|
//layers
|
||||||
@TEMzPayload("WALL", TEMzPayload.EIGHT_MSB)
|
@TEMzPayload("WALL", TEMzPayload.TWELVE_BITS_LITTLE)
|
||||||
val layerWall: MapLayer
|
val layerWall: BlockLayer
|
||||||
@TEMzPayload("TERR", TEMzPayload.EIGHT_MSB)
|
@TEMzPayload("TERR", TEMzPayload.EIGHT_MSB)
|
||||||
val layerTerrain: MapLayer
|
val layerTerrain: BlockLayer
|
||||||
//val layerWire: MapLayer
|
//val layerWire: MapLayer
|
||||||
|
|
||||||
@TEMzPayload("WALL", TEMzPayload.FOUR_LSB)
|
|
||||||
val layerWallLowBits: PairedMapLayer
|
|
||||||
@TEMzPayload("TERR", TEMzPayload.FOUR_LSB)
|
|
||||||
val layerTerrainLowBits: PairedMapLayer
|
|
||||||
|
|
||||||
//val layerThermal: MapLayerHalfFloat // in Kelvins
|
//val layerThermal: MapLayerHalfFloat // in Kelvins
|
||||||
//val layerFluidPressure: MapLayerHalfFloat // (milibar - 1000)
|
//val layerFluidPressure: MapLayerHalfFloat // (milibar - 1000)
|
||||||
|
|
||||||
@@ -90,7 +86,7 @@ open class GameWorld {
|
|||||||
/** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */
|
/** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */
|
||||||
var gravitation: Vector2 = Vector2(0.0, 9.80665)
|
var gravitation: Vector2 = Vector2(0.0, 9.80665)
|
||||||
/** 0.0..1.0+ */
|
/** 0.0..1.0+ */
|
||||||
var globalLight = Color(0f,0f,0f,0f)
|
var globalLight = Cvec(0f, 0f, 0f, 0f)
|
||||||
var averageTemperature = 288f // 15 deg celsius; simulates global warming
|
var averageTemperature = 288f // 15 deg celsius; simulates global warming
|
||||||
|
|
||||||
|
|
||||||
@@ -108,11 +104,9 @@ open class GameWorld {
|
|||||||
this.spawnX = width / 2
|
this.spawnX = width / 2
|
||||||
this.spawnY = 200
|
this.spawnY = 200
|
||||||
|
|
||||||
layerTerrain = MapLayer(width, height)
|
layerTerrain = BlockLayer(width, height)
|
||||||
layerWall = MapLayer(width, height)
|
layerWall = BlockLayer(width, height)
|
||||||
//layerWire = MapLayer(width, height)
|
//layerWire = MapLayer(width, height)
|
||||||
layerTerrainLowBits = PairedMapLayer(width, height)
|
|
||||||
layerWallLowBits = PairedMapLayer(width, height)
|
|
||||||
|
|
||||||
wallDamages = HashMap()
|
wallDamages = HashMap()
|
||||||
terrainDamages = HashMap()
|
terrainDamages = HashMap()
|
||||||
@@ -140,8 +134,6 @@ open class GameWorld {
|
|||||||
layerTerrain = layerData.layerTerrain
|
layerTerrain = layerData.layerTerrain
|
||||||
layerWall = layerData.layerWall
|
layerWall = layerData.layerWall
|
||||||
//layerWire = layerData.layerWire
|
//layerWire = layerData.layerWire
|
||||||
layerTerrainLowBits = layerData.layerTerrainLowBits
|
|
||||||
layerWallLowBits = layerData.layerWallLowBits
|
|
||||||
|
|
||||||
wallDamages = layerData.wallDamages
|
wallDamages = layerData.wallDamages
|
||||||
terrainDamages = layerData.terrainDamages
|
terrainDamages = layerData.terrainDamages
|
||||||
@@ -163,23 +155,6 @@ open class GameWorld {
|
|||||||
this.totalPlayTime = totalPlayTime
|
this.totalPlayTime = totalPlayTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get 2d array data of terrain
|
|
||||||
|
|
||||||
* @return byte[][] terrain layer
|
|
||||||
*/
|
|
||||||
val terrainArray: ByteArray
|
|
||||||
get() = layerTerrain.data
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get 2d array data of wall
|
|
||||||
|
|
||||||
* @return byte[][] wall layer
|
|
||||||
*/
|
|
||||||
val wallArray: ByteArray
|
|
||||||
get() = layerWall.data
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get 2d array data of wire
|
* Get 2d array data of wire
|
||||||
|
|
||||||
@@ -190,34 +165,18 @@ open class GameWorld {
|
|||||||
|
|
||||||
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1))
|
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1))
|
||||||
|
|
||||||
fun getTileFromWall(x: Int, y: Int): Int? {
|
fun getTileFromWall(x: Int, y: Int): Int {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
val wall: Int? = layerWall.getTile(x, y)
|
if (y !in 0 until height) throw Error("Y coord out of world boundary: $y")
|
||||||
val wallDamage: Int? = getWallLowBits(x, y)
|
|
||||||
return if (wall == null || wallDamage == null)
|
return layerWall.unsafeGetTile(x, y)
|
||||||
null
|
|
||||||
else
|
|
||||||
wall * PairedMapLayer.RANGE + wallDamage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTileFromTerrain(x: Int, y: Int): Int? {
|
fun getTileFromTerrain(x: Int, y: Int): Int {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
val terrain: Int? = layerTerrain.getTile(x, y)
|
if (y !in 0 until height) throw Error("Y coord out of world boundary: $y")
|
||||||
val terrainDamage: Int? = getTerrainLowBits(x, y)
|
|
||||||
return if (terrain == null || terrainDamage == null)
|
|
||||||
null
|
|
||||||
else
|
|
||||||
terrain * PairedMapLayer.RANGE + terrainDamage
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getWallLowBits(x: Int, y: Int): Int? {
|
return layerTerrain.unsafeGetTile(x, y)
|
||||||
val (x, y) = coerceXY(x, y)
|
|
||||||
return layerWallLowBits.getData(x, y)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTerrainLowBits(x: Int, y: Int): Int? {
|
|
||||||
val (x, y) = coerceXY(x, y)
|
|
||||||
return layerTerrainLowBits.getData(x, y)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,57 +185,45 @@ open class GameWorld {
|
|||||||
* *
|
* *
|
||||||
* @param y
|
* @param y
|
||||||
* *
|
* *
|
||||||
* @param combinedTilenum Item id of the wall block. Less-than-4096-value is permitted.
|
* @param tilenum Item id of the wall block. Less-than-4096-value is permitted.
|
||||||
*/
|
*/
|
||||||
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
|
fun setTileWall(x: Int, y: Int, tilenum: 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...
|
val tilenum = tilenum % TILES_SUPPORTED // does work without this, but to be safe...
|
||||||
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the tile of wall as specified, with damage value of zero.
|
|
||||||
* @param x
|
|
||||||
* *
|
|
||||||
* @param y
|
|
||||||
* *
|
|
||||||
* @param combinedTilenum Item id of the terrain block, <4096
|
|
||||||
*/
|
|
||||||
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
|
|
||||||
val (x, y) = coerceXY(x, y)
|
|
||||||
setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
|
|
||||||
val (x, y) = coerceXY(x, y)
|
|
||||||
val oldWall = getTileFromWall(x, y)
|
val oldWall = getTileFromWall(x, y)
|
||||||
layerWall.setTile(x, y, tile)
|
layerWall.unsafeSetTile(x, y, tilenum)
|
||||||
layerWallLowBits.setData(x, y, damage)
|
|
||||||
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
||||||
|
|
||||||
if (oldWall != null)
|
Terrarum.ingame?.queueWallChangedEvent(oldWall, tilenum, LandUtil.getBlockAddr(this, x, y))
|
||||||
Terrarum.ingame?.queueWallChangedEvent(oldWall, tile.toUint() * PairedMapLayer.RANGE + damage, LandUtil.getBlockAddr(this, x, y))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set the tile of wall as specified, with damage value of zero.
|
||||||
|
*
|
||||||
* Warning: this function alters fluid lists: be wary of call order!
|
* Warning: this function alters fluid lists: be wary of call order!
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* *
|
||||||
|
* @param y
|
||||||
|
* *
|
||||||
|
* @param tilenum Item id of the terrain block, <4096
|
||||||
*/
|
*/
|
||||||
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
|
fun setTileTerrain(x: Int, y: Int, tilenum: Int) {
|
||||||
val (x, y) = coerceXY(x, y)
|
val (x, y) = coerceXY(x, y)
|
||||||
|
|
||||||
val oldTerrain = getTileFromTerrain(x, y)
|
val oldTerrain = getTileFromTerrain(x, y)
|
||||||
layerTerrain.setTile(x, y, tile)
|
layerTerrain.unsafeSetTile(x, y, tilenum)
|
||||||
layerTerrainLowBits.setData(x, y, damage)
|
|
||||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||||
terrainDamages.remove(blockAddr)
|
terrainDamages.remove(blockAddr)
|
||||||
|
|
||||||
if (BlockCodex[tile * PairedMapLayer.RANGE + damage].isSolid) {
|
if (BlockCodex[tilenum].isSolid) {
|
||||||
fluidFills.remove(blockAddr)
|
fluidFills.remove(blockAddr)
|
||||||
fluidTypes.remove(blockAddr)
|
fluidTypes.remove(blockAddr)
|
||||||
}
|
}
|
||||||
// fluid tiles-item should be modified so that they will also place fluid onto their respective map
|
// fluid tiles-item should be modified so that they will also place fluid onto their respective map
|
||||||
|
|
||||||
if (oldTerrain != null)
|
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, tilenum, LandUtil.getBlockAddr(this, x, y))
|
||||||
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, tile.toUint() * PairedMapLayer.RANGE + damage, LandUtil.getBlockAddr(this, x, y))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fun setTileWire(x: Int, y: Int, tile: Byte) {
|
/*fun setTileWire(x: Int, y: Int, tile: Byte) {
|
||||||
@@ -514,16 +461,19 @@ open class GameWorld {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
layerWall.dispose()
|
||||||
|
layerTerrain.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Transient val WALL = 0
|
@Transient const val WALL = 0
|
||||||
@Transient val TERRAIN = 1
|
@Transient const val TERRAIN = 1
|
||||||
@Transient val WIRE = 2
|
@Transient const val WIRE = 2
|
||||||
|
|
||||||
/** 4096 */
|
@Transient const val TILES_SUPPORTED = 4096
|
||||||
@Transient val TILES_SUPPORTED = MapLayer.RANGE * PairedMapLayer.RANGE
|
//@Transient val SIZEOF: Byte = 2
|
||||||
@Transient val SIZEOF: Byte = MapLayer.SIZEOF
|
@Transient const val LAYERS: Byte = 4 // terrain, wall (layerTerrainLowBits + layerWallLowBits), wire
|
||||||
@Transient val LAYERS: Byte = 4 // terrain, wall (layerTerrainLowBits + layerWallLowBits), wire
|
|
||||||
|
|
||||||
fun makeNullWorld() = GameWorld(1, 1, 1, 0, 0, 0)
|
fun makeNullWorld() = GameWorld(1, 1, 1, 0, 0, 0)
|
||||||
}
|
}
|
||||||
@@ -555,5 +505,6 @@ annotation class TEMzPayload(val payloadName: String, val arg: Int) {
|
|||||||
const val INT48_FLOAT_PAIR = 2
|
const val INT48_FLOAT_PAIR = 2
|
||||||
const val INT48_SHORT_PAIR = 3
|
const val INT48_SHORT_PAIR = 3
|
||||||
const val INT48_INT_PAIR = 4
|
const val INT48_INT_PAIR = 4
|
||||||
|
const val TWELVE_BITS_LITTLE = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
package net.torvald.terrarum.gameworld
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by minjaesong on 2016-01-17.
|
|
||||||
*/
|
|
||||||
open class MapLayer : Iterable<Byte> {
|
|
||||||
|
|
||||||
val width: Int; val height: Int
|
|
||||||
internal @Volatile var data: ByteArray // in parallel programming: do not trust your register; always read freshly from RAM!
|
|
||||||
|
|
||||||
constructor(width: Int, height: Int) {
|
|
||||||
this.width = width
|
|
||||||
this.height = height
|
|
||||||
data = ByteArray(width * height)
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(width: Int, height: Int, data: ByteArray) {
|
|
||||||
this.data = data
|
|
||||||
this.width = width
|
|
||||||
this.height = height
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an iterator over elements of type `T`.
|
|
||||||
|
|
||||||
* @return an Iterator.
|
|
||||||
*/
|
|
||||||
override fun iterator(): Iterator<Byte> {
|
|
||||||
return object : Iterator<Byte> {
|
|
||||||
|
|
||||||
private var iteratorCount = 0
|
|
||||||
|
|
||||||
override fun hasNext(): Boolean {
|
|
||||||
return iteratorCount < width * height
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun next(): Byte {
|
|
||||||
val y = iteratorCount / width
|
|
||||||
val x = iteratorCount % width
|
|
||||||
// advance counter
|
|
||||||
iteratorCount += 1
|
|
||||||
|
|
||||||
return data[y * width + x]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun getTile(x: Int, y: Int): Int? {
|
|
||||||
return if (x !in 0..width - 1 || y !in 0..height - 1)
|
|
||||||
null
|
|
||||||
else
|
|
||||||
data[y * width + x].toUint()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun setTile(x: Int, y: Int, tile: Byte) {
|
|
||||||
data[y * width + x] = tile
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Transient const val RANGE = 256
|
|
||||||
@Transient const val SIZEOF: Byte = 1 // 1 for 8-bit, 2 for 16-bit, ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
|
|
||||||
@@ -3,7 +3,7 @@ package net.torvald.terrarum.gameworld
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-02-15.
|
* Created by minjaesong on 2016-02-15.
|
||||||
*/
|
*/
|
||||||
open class PairedMapLayer : Iterable<Byte> {
|
/*open class PairedMapLayer : Iterable<Byte> {
|
||||||
|
|
||||||
val width: Int; val height: Int
|
val width: Int; val height: Int
|
||||||
|
|
||||||
@@ -87,4 +87,4 @@ open class PairedMapLayer : Iterable<Byte> {
|
|||||||
@Transient const val RANGE = 16
|
@Transient const val RANGE = 16
|
||||||
@Transient const val SIZEOF: Byte = 1 // 1 for 8-bit, 2 for 16-bit, ...
|
@Transient const val SIZEOF: Byte = 1 // 1 for 8-bit, 2 for 16-bit, ...
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.InputAdapter
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
@@ -279,7 +280,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
gameWorld.time.setTimeOfToday(WorldTime.HOUR_SEC * 10)
|
gameWorld.time.setTimeOfToday(WorldTime.HOUR_SEC * 10)
|
||||||
gameWorld.globalLight = Color(.8f,.8f,.8f,.8f)
|
gameWorld.globalLight = Cvec(.8f, .8f, .8f, .8f)
|
||||||
|
|
||||||
essentialOverlays.add(blockPointingCursor)
|
essentialOverlays.add(blockPointingCursor)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.WorldGenerator
|
|||||||
import net.torvald.terrarum.ui.ConsoleWindow
|
import net.torvald.terrarum.ui.ConsoleWindow
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||||
|
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.TILE_SIZE
|
||||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
@@ -404,7 +405,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
ItemCodex[itemOnGrip]?.endPrimaryUse(delta)
|
ItemCodex[itemOnGrip]?.endPrimaryUse(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun worldSecondaryClickStart(delta: Float) {
|
// I have decided that left and right clicks must do the same thing, so no secondary use from now on. --Torvald on 2019-05-26
|
||||||
|
/*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
|
val consumptionSuccessful = ItemCodex[itemOnGrip]?.startSecondaryUse(delta) ?: false
|
||||||
if (consumptionSuccessful)
|
if (consumptionSuccessful)
|
||||||
@@ -414,7 +416,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
override fun worldSecondaryClickEnd(delta: Float) {
|
override fun worldSecondaryClickEnd(delta: Float) {
|
||||||
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
val itemOnGrip = actorNowPlaying?.inventory?.itemEquipped?.get(GameItem.EquipPosition.HAND_GRIP)
|
||||||
ItemCodex[itemOnGrip]?.endSecondaryUse(delta)
|
ItemCodex[itemOnGrip]?.endSecondaryUse(delta)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -474,8 +476,12 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var worldWidth: Double = 0.0
|
||||||
|
|
||||||
|
|
||||||
protected fun updateGame(delta: Float) {
|
protected fun updateGame(delta: Float) {
|
||||||
val world = this.world as GameWorldExtension
|
val world = this.world as GameWorldExtension
|
||||||
|
worldWidth = world.width.toDouble() * TILE_SIZE
|
||||||
|
|
||||||
particlesActive = 0
|
particlesActive = 0
|
||||||
|
|
||||||
@@ -562,7 +568,6 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun filterVisibleActors() {
|
private fun filterVisibleActors() {
|
||||||
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen() }
|
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen() }
|
||||||
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen() }
|
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen() }
|
||||||
@@ -602,10 +607,16 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send message to notifier UI and toggle the UI as opened. */
|
/** Send message to notifier UI and toggle the UI as opened. */
|
||||||
fun sendNotification(msg1: String, msg2: String? = null) {
|
fun sendNotification(messages: Array<String>) {
|
||||||
(notifier as Notification).sendNotification(if (msg2 != null) arrayOf(msg1, msg2) else arrayOf(msg1))
|
(notifier as Notification).sendNotification(messages.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendNotification(messages: List<String>) {
|
||||||
|
(notifier as Notification).sendNotification(messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendNotification(singleMessage: String) = sendNotification(listOf(singleMessage))
|
||||||
|
|
||||||
fun wakeDormantActors() {
|
fun wakeDormantActors() {
|
||||||
var actorContainerSize = actorContainerInactive.size
|
var actorContainerSize = actorContainerInactive.size
|
||||||
var i = 0
|
var i = 0
|
||||||
@@ -710,29 +721,39 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
min(// take min of normal position and wrapped (x < 0) position
|
min(// take min of normal position and wrapped (x < 0) position
|
||||||
(a.hitbox.centeredX - p.hitbox.centeredX).sqr() +
|
(a.hitbox.centeredX - p.hitbox.centeredX).sqr() +
|
||||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||||
(a.hitbox.centeredX - p.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE).sqr() +
|
((a.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||||
(a.hitbox.centeredX - p.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE).sqr() +
|
((a.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr()
|
(a.hitbox.centeredY - p.hitbox.centeredY).sqr()
|
||||||
)
|
)
|
||||||
private fun distToCameraSqr(a: ActorWithBody) =
|
private fun distToCameraSqr(a: ActorWithBody) =
|
||||||
min(
|
min(
|
||||||
(a.hitbox.startX - WorldCamera.x).sqr() +
|
(a.hitbox.centeredX - WorldCamera.xCentre).sqr() +
|
||||||
(a.hitbox.startY - WorldCamera.y).sqr(),
|
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||||
(a.hitbox.startX - WorldCamera.x + world.width * CreateTileAtlas.TILE_SIZE).sqr() +
|
((a.hitbox.centeredX + world.width * CreateTileAtlas.TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||||
(a.hitbox.startY - WorldCamera.y).sqr(),
|
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||||
(a.hitbox.startX - WorldCamera.x - world.width * CreateTileAtlas.TILE_SIZE).sqr() +
|
((a.hitbox.centeredX - world.width * CreateTileAtlas.TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||||
(a.hitbox.startY - WorldCamera.y).sqr()
|
(a.hitbox.centeredY - WorldCamera.yCentre).sqr()
|
||||||
)
|
)
|
||||||
|
|
||||||
/** whether the actor is within screen */
|
/** whether the actor is within screen */
|
||||||
private fun ActorWithBody.inScreen() =
|
private fun ActorWithBody.inScreen() =
|
||||||
distToCameraSqr(this) <=
|
|
||||||
(Terrarum.WIDTH.plus(this.hitbox.width.div(2)).
|
|
||||||
times(1 / screenZoom).sqr() +
|
|
||||||
Terrarum.HEIGHT.plus(this.hitbox.height.div(2)).
|
|
||||||
times(1 / screenZoom).sqr())
|
|
||||||
|
|
||||||
|
// y
|
||||||
|
this.hitbox.endY >= WorldCamera.y && this.hitbox.startY <= WorldCamera.yEnd
|
||||||
|
|
||||||
|
&&
|
||||||
|
|
||||||
|
// x: camera is on the right side of the seam
|
||||||
|
((this.hitbox.endX - worldWidth >= WorldCamera.x && this.hitbox.startX - worldWidth <= WorldCamera.xEnd) ||
|
||||||
|
// x: camera in on the left side of the seam
|
||||||
|
(this.hitbox.endX + worldWidth >= WorldCamera.x && this.hitbox.startX + worldWidth <= WorldCamera.xEnd) ||
|
||||||
|
// x: neither
|
||||||
|
(this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd))
|
||||||
|
|
||||||
|
|
||||||
|
private val cameraWindowX = WorldCamera.x.toDouble()..WorldCamera.xEnd.toDouble()
|
||||||
|
private val cameraWindowY = WorldCamera.y.toDouble()..WorldCamera.yEnd.toDouble()
|
||||||
|
|
||||||
/** whether the actor is within update range */
|
/** whether the actor is within update range */
|
||||||
private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr()
|
private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr()
|
||||||
@@ -989,6 +1010,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
it.handler.dispose()
|
it.handler.dispose()
|
||||||
it.dispose()
|
it.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
super.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import com.badlogic.gdx.Input
|
|||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.badlogic.gdx.utils.ScreenUtils
|
import com.badlogic.gdx.utils.ScreenUtils
|
||||||
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
@@ -23,7 +25,7 @@ import javax.swing.JFileChooser
|
|||||||
*
|
*
|
||||||
* For the entire render path, see AppLoader.
|
* For the entire render path, see AppLoader.
|
||||||
*/
|
*/
|
||||||
object IngameRenderer {
|
object IngameRenderer : Disposable {
|
||||||
/** for non-private use, use with care! */
|
/** for non-private use, use with care! */
|
||||||
lateinit var batch: SpriteBatch
|
lateinit var batch: SpriteBatch
|
||||||
private lateinit var camera: OrthographicCamera
|
private lateinit var camera: OrthographicCamera
|
||||||
@@ -61,6 +63,17 @@ object IngameRenderer {
|
|||||||
|
|
||||||
private var debugMode = 0
|
private var debugMode = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
AppLoader.disposableSingletonsPool.add(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
var renderingActorsCount = 0
|
||||||
|
private set
|
||||||
|
var renderingUIsCount = 0
|
||||||
|
private set
|
||||||
|
//var renderingParticleCount = 0
|
||||||
|
// private set
|
||||||
|
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
gamePaused: Boolean,
|
gamePaused: Boolean,
|
||||||
world: GameWorldExtension,
|
world: GameWorldExtension,
|
||||||
@@ -73,6 +86,15 @@ object IngameRenderer {
|
|||||||
player: ActorWithBody? = null,
|
player: ActorWithBody? = null,
|
||||||
uisToDraw: ArrayList<UICanvas>? = null
|
uisToDraw: ArrayList<UICanvas>? = null
|
||||||
) {
|
) {
|
||||||
|
renderingActorsCount = (actorsRenderBehind?.size ?: 0) +
|
||||||
|
(actorsRenderMiddle?.size ?: 0) +
|
||||||
|
(actorsRenderMidTop?.size ?: 0) +
|
||||||
|
(actorsRenderFront?.size ?: 0) +
|
||||||
|
(actorsRenderOverlay?.size ?: 0)
|
||||||
|
//renderingParticleCount = particlesContainer?.size ?: 0
|
||||||
|
//renderingParticleCount = (particlesContainer?.buffer?.map { (!it.flagDespawn).toInt() } ?: listOf(0)).sum()
|
||||||
|
renderingUIsCount = ((uisToDraw?.map { it.isVisible.toInt() }) ?: listOf(0)).sum()
|
||||||
|
|
||||||
|
|
||||||
if (uisToDraw != null) {
|
if (uisToDraw != null) {
|
||||||
uiListToDraw = uisToDraw
|
uiListToDraw = uisToDraw
|
||||||
@@ -604,7 +626,7 @@ object IngameRenderer {
|
|||||||
|
|
||||||
private val TILE_SIZEF = CreateTileAtlas.TILE_SIZE.toFloat()
|
private val TILE_SIZEF = CreateTileAtlas.TILE_SIZE.toFloat()
|
||||||
|
|
||||||
fun dispose() {
|
override fun dispose() {
|
||||||
fboRGB.dispose()
|
fboRGB.dispose()
|
||||||
fboA.dispose()
|
fboA.dispose()
|
||||||
fboRGB_lightMixed.dispose()
|
fboRGB_lightMixed.dispose()
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.console
|
|||||||
|
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.console.ConsoleCommand
|
import net.torvald.terrarum.console.ConsoleCommand
|
||||||
import net.torvald.terrarum.langpack.Lang
|
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10,19 +9,14 @@ import net.torvald.terrarum.modulebasegame.Ingame
|
|||||||
*/
|
*/
|
||||||
internal object SetBulletin : ConsoleCommand {
|
internal object SetBulletin : ConsoleCommand {
|
||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
send(Lang["ERROR_SAVE_CORRUPTED"], Lang["MENU_LABEL_CONTINUE_QUESTION"])
|
//send(Lang["ERROR_SAVE_CORRUPTED"], Lang["MENU_LABEL_CONTINUE_QUESTION"])
|
||||||
|
|
||||||
|
(Terrarum.ingame!! as Ingame).sendNotification(args.sliceArray(1..args.lastIndex))
|
||||||
|
println("sent notifinator")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun printUsage() {
|
override fun printUsage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Actually send notifinator
|
|
||||||
* @param message real message
|
|
||||||
*/
|
|
||||||
fun send(msg1: String, msg2: String? = null) {
|
|
||||||
(Terrarum.ingame!! as Ingame).sendNotification(msg1, msg2)
|
|
||||||
println("sent notifinator")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.spriteanimation.HasAssembledSprite
|
import net.torvald.spriteanimation.HasAssembledSprite
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
@@ -68,8 +68,8 @@ open class ActorHumanoid(
|
|||||||
if (houseDesignation != null) houseDesignation!!.clear()
|
if (houseDesignation != null) houseDesignation!!.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override var color: Color
|
override var color: Cvec
|
||||||
get() = Color(
|
get() = Cvec(
|
||||||
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||||
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||||
(actorValue.getAsFloat(AVKey.LUMB) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
(actorValue.getAsFloat(AVKey.LUMB) ?: 0f) / LightmapRenderer.MUL_FLOAT,
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.gameworld.toUint
|
import net.torvald.terrarum.gameworld.toUint
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|||||||
@@ -4,15 +4,19 @@ import net.torvald.terrarum.IngameInstance
|
|||||||
import net.torvald.terrarum.Point2i
|
import net.torvald.terrarum.Point2i
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-06-17.
|
* Created by minjaesong on 2016-06-17.
|
||||||
*/
|
*/
|
||||||
open class FixtureBase(val blockBox: BlockBox, val blockBoxProps: BlockBoxProps = BlockBoxProps(0)) :
|
open class FixtureBase(blockBox0: BlockBox, val blockBoxProps: BlockBoxProps = BlockBoxProps(0), renderOrder: RenderOrder = RenderOrder.MIDDLE) :
|
||||||
// disabling physics (not allowing the fixture to move) WILL make things easier in many ways
|
// disabling physics (not allowing the fixture to move) WILL make things easier in many ways
|
||||||
ActorWBMovable(RenderOrder.BEHIND, immobileBody = true, usePhysics = false), CuedByTerrainChange {
|
ActorWBMovable(renderOrder, immobileBody = true, usePhysics = false), CuedByTerrainChange {
|
||||||
|
|
||||||
|
var blockBox: BlockBox = blockBox0
|
||||||
|
protected set // something like TapestryObject will want to redefine this
|
||||||
|
|
||||||
private val world: GameWorld
|
private val world: GameWorld
|
||||||
get() = Terrarum.ingame!!.world
|
get() = Terrarum.ingame!!.world
|
||||||
@@ -42,20 +46,51 @@ open class FixtureBase(val blockBox: BlockBox, val blockBoxProps: BlockBoxProps
|
|||||||
// posY: bottom of the blockBox
|
// posY: bottom of the blockBox
|
||||||
// using the actor's hitbox
|
// using the actor's hitbox
|
||||||
|
|
||||||
for (x in posX until posX + blockBox.width) {
|
|
||||||
|
// check for existing blocks (and fixtures)
|
||||||
|
var hasCollision = false
|
||||||
|
checkForCollision@
|
||||||
for (y in posY until posY + blockBox.height) {
|
for (y in posY until posY + blockBox.height) {
|
||||||
|
for (x in posX until posX + blockBox.width) {
|
||||||
|
val tile = world.getTileFromTerrain(x, y)
|
||||||
|
if (BlockCodex[tile].isSolid || tile in Block.actorblocks) {
|
||||||
|
hasCollision = true
|
||||||
|
break@checkForCollision
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCollision) return false
|
||||||
|
|
||||||
|
|
||||||
|
// fill the area with the filler blocks
|
||||||
|
for (y in posY until posY + blockBox.height) {
|
||||||
|
for (x in posX until posX + blockBox.width) {
|
||||||
|
if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) {
|
||||||
|
// if the collision type is allow_move_down, only the top surface tile should be "the platform"
|
||||||
|
// lower part must not have such property (think of the table!)
|
||||||
|
// TODO does this ACTUALLY work ?!
|
||||||
|
world.setTileTerrain(x, y, if (y == posY) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION)
|
||||||
|
}
|
||||||
|
else
|
||||||
world.setTileTerrain(x, y, blockBox.collisionType)
|
world.setTileTerrain(x, y, blockBox.collisionType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the position of this actor
|
||||||
worldBlockPos = Point2i(posX, posY)
|
worldBlockPos = Point2i(posX, posY)
|
||||||
|
|
||||||
|
val posXoff = (TSIZE % (this.sprite?.cellWidth ?: 0)) / 2
|
||||||
|
|
||||||
this.isVisible = true
|
this.isVisible = true
|
||||||
this.hitbox.setFromWidthHeight(posX * TSIZE, posY * TSIZE, blockBox.width * TSIZE, blockBox.height * TSIZE)
|
this.hitbox.setFromWidthHeight(posX * TSIZE + posXoff, posY * TSIZE, blockBox.width * TSIZE, blockBox.height * TSIZE)
|
||||||
|
|
||||||
|
// actually add this actor into the world
|
||||||
|
Terrarum.ingame!!.addNewActor(this)
|
||||||
|
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
return true // TODO for the tests' sake, just get fucking spawned
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,13 +188,17 @@ inline class BlockBoxProps(val flags: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To not define the blockbox, simply use BlockBox.NULL
|
||||||
|
*
|
||||||
|
* Null blockbox means the fixture won't bar any block placement. Fixtures like paintings will want to have such feature. (e.g. torch placed on top; buried)
|
||||||
|
*
|
||||||
* @param collisionType Collision type defined in BlockBox.Companion
|
* @param collisionType Collision type defined in BlockBox.Companion
|
||||||
* @param width Width of the block box, tile-wise
|
* @param width Width of the block box, tile-wise
|
||||||
* @param height Height of the block box, tile-wise
|
* @param height Height of the block box, tile-wise
|
||||||
*/
|
*/
|
||||||
data class BlockBox(var collisionType: Int, var width: Int, var height: Int) {
|
data class BlockBox(val collisionType: Int, val width: Int, val height: Int) {
|
||||||
|
|
||||||
fun redefine(collisionType: Int, width: Int, height: Int) {
|
/*fun redefine(collisionType: Int, width: Int, height: Int) {
|
||||||
redefine(collisionType)
|
redefine(collisionType)
|
||||||
redefine(width, height)
|
redefine(width, height)
|
||||||
}
|
}
|
||||||
@@ -171,7 +210,7 @@ data class BlockBox(var collisionType: Int, var width: Int, var height: Int) {
|
|||||||
|
|
||||||
fun redefine(collisionType: Int) {
|
fun redefine(collisionType: Int) {
|
||||||
this.collisionType = collisionType
|
this.collisionType = collisionType
|
||||||
}
|
}*/
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val NO_COLLISION = Block.ACTORBLOCK_NO_COLLISION
|
const val NO_COLLISION = Block.ACTORBLOCK_NO_COLLISION
|
||||||
@@ -179,5 +218,7 @@ data class BlockBox(var collisionType: Int, var width: Int, var height: Int) {
|
|||||||
const val ALLOW_MOVE_DOWN = Block.ACTORBLOCK_ALLOW_MOVE_DOWN
|
const val ALLOW_MOVE_DOWN = Block.ACTORBLOCK_ALLOW_MOVE_DOWN
|
||||||
const val NO_PASS_RIGHT = Block.ACTORBLOCK_NO_PASS_RIGHT
|
const val NO_PASS_RIGHT = Block.ACTORBLOCK_NO_PASS_RIGHT
|
||||||
const val NO_PASS_LEFT = Block.ACTORBLOCK_NO_PASS_LEFT
|
const val NO_PASS_LEFT = Block.ACTORBLOCK_NO_PASS_LEFT
|
||||||
|
|
||||||
|
val NULL = BlockBox(NO_COLLISION, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
@@ -13,11 +13,9 @@ import java.util.*
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-06-17.
|
* Created by minjaesong on 2016-06-17.
|
||||||
*/
|
*/
|
||||||
internal class FixtureTikiTorch : FixtureBase(
|
internal class FixtureTikiTorch : FixtureBase(BlockBox(BlockBox.NO_COLLISION, 1, 2)), Luminous {
|
||||||
BlockBox(BlockBox.NO_COLLISION, 1, 2)
|
|
||||||
), Luminous {
|
|
||||||
|
|
||||||
override var color: Color
|
override var color: Cvec
|
||||||
get() = BlockCodex[Block.TORCH].luminosity
|
get() = BlockCodex[Block.TORCH].luminosity
|
||||||
set(value) {
|
set(value) {
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
|
import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ object PlayerBuilderSigrid {
|
|||||||
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, 9995) // wire piece
|
||||||
inventory.add(8467, 9995) // test tiki torch
|
inventory.add(8467, 385930603) // test tiki torch
|
||||||
inventory.add(9000) // TEST water bucket
|
inventory.add(9000) // TEST water bucket
|
||||||
inventory.add(9001) // TEST lava bucket
|
inventory.add(9001) // TEST lava bucket
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.Point2d
|
import net.torvald.terrarum.Point2d
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
@@ -31,8 +32,8 @@ open class ProjectileSimple(
|
|||||||
val speed: Int
|
val speed: Int
|
||||||
|
|
||||||
|
|
||||||
override var color: Color
|
override var color: Cvec
|
||||||
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Color).cpy()
|
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Cvec).cpy()
|
||||||
set(value) {
|
set(value) {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -118,8 +119,8 @@ open class ProjectileSimple(
|
|||||||
val OFFSET_LUMINOSITY = 4
|
val OFFSET_LUMINOSITY = 4
|
||||||
val bulletDatabase = arrayOf(
|
val bulletDatabase = arrayOf(
|
||||||
// damage, display colour, no gravity, speed
|
// damage, display colour, no gravity, speed
|
||||||
arrayOf(7, Color(0xFF5429_FF.toInt()), true, 40, 32),
|
arrayOf(7, Cvec(0xFF5429_FF.toInt()), true, 40, 32),
|
||||||
arrayOf(8, Color(0xFF5429_FF.toInt()), true, 20, 0)
|
arrayOf(8, Cvec(0xFF5429_FF.toInt()), true, 20, 0)
|
||||||
// ...
|
// ...
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|||||||
* Created by minjaesong on 2017-01-07.
|
* Created by minjaesong on 2017-01-07.
|
||||||
*/
|
*/
|
||||||
class TapestryObject(pixmap: Pixmap, val artName: String, val artAuthor: String) :
|
class TapestryObject(pixmap: Pixmap, val artName: String, val artAuthor: String) :
|
||||||
FixtureBase(BlockBox(BlockBox.NO_COLLISION, 1, 1)) // placeholder blockbox
|
FixtureBase(BlockBox(BlockBox.NO_COLLISION, 1, 1), renderOrder = RenderOrder.BEHIND) // placeholder blockbox
|
||||||
{
|
{
|
||||||
|
|
||||||
// physics = false only speeds up for ~2 frames with 50 tapestries
|
// physics = false only speeds up for ~2 frames with 50 tapestries
|
||||||
@@ -28,7 +28,7 @@ class TapestryObject(pixmap: Pixmap, val artName: String, val artAuthor: String)
|
|||||||
// you CAN'T destroy the image
|
// you CAN'T destroy the image
|
||||||
|
|
||||||
// redefine blockbox
|
// redefine blockbox
|
||||||
blockBox.redefine(texture.width.div(TILE_SIZEF).ceilInt(), texture.height.div(TILE_SIZEF).ceilInt())
|
blockBox = BlockBox(BlockBox.NO_COLLISION, texture.width.div(TILE_SIZEF).ceilInt(), texture.height.div(TILE_SIZEF).ceilInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(delta: Float) {
|
override fun update(delta: Float) {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameactors
|
package net.torvald.terrarum.modulebasegame.gameactors
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameactors.Hitbox
|
import net.torvald.terrarum.gameactors.Hitbox
|
||||||
import net.torvald.terrarum.gameactors.Luminous
|
import net.torvald.terrarum.gameactors.Luminous
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-04-26.
|
* Created by minjaesong on 2016-04-26.
|
||||||
@@ -21,7 +20,7 @@ class WeaponSwung(val itemID: Int) : ActorWBMovable(RenderOrder.MIDTOP), Luminou
|
|||||||
actorValue[AVKey.LUMINOSITY] = value
|
actorValue[AVKey.LUMINOSITY] = value
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
override var color: Color
|
override var color: Cvec
|
||||||
get() = throw UnsupportedOperationException()
|
get() = throw UnsupportedOperationException()
|
||||||
set(value) {
|
set(value) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import net.torvald.terrarum.Point2d
|
|||||||
import net.torvald.terrarum.Point2i
|
import net.torvald.terrarum.Point2i
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
import net.torvald.terrarum.gameitem.GameItem
|
import net.torvald.terrarum.gameitem.GameItem
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
import net.torvald.terrarum.modulebasegame.Ingame
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
@@ -26,6 +26,7 @@ object BlockBase {
|
|||||||
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
||||||
|
|
||||||
// check for collision with actors (BLOCK only)
|
// check for collision with actors (BLOCK only)
|
||||||
|
// FIXME properly fix the collision detection: it OVERRIDES the tiki-torches which should not happen AT ALL
|
||||||
if (gameItem.inventoryCategory == GameItem.Category.BLOCK) {
|
if (gameItem.inventoryCategory == GameItem.Category.BLOCK) {
|
||||||
var ret1 = true
|
var ret1 = true
|
||||||
ingame.actorContainerActive.forEach {
|
ingame.actorContainerActive.forEach {
|
||||||
|
|||||||
@@ -25,10 +25,15 @@ class TikiTorchTester(originalID: ItemID) : GameItem(originalID) {
|
|||||||
get() = AppLoader.resourcePool.getAsTextureRegion("itemplaceholder_48")
|
get() = AppLoader.resourcePool.getAsTextureRegion("itemplaceholder_48")
|
||||||
override var baseToolSize: Double? = baseMass
|
override var baseToolSize: Double? = baseMass
|
||||||
|
|
||||||
|
init {
|
||||||
|
equipPosition = EquipPosition.HAND_GRIP
|
||||||
|
}
|
||||||
|
|
||||||
override fun startPrimaryUse(delta: Float): Boolean {
|
override fun startPrimaryUse(delta: Float): Boolean {
|
||||||
val torch = FixtureTikiTorch()
|
val torch = FixtureTikiTorch()
|
||||||
|
|
||||||
return torch.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - torch.blockBox.height + 1)
|
return torch.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - torch.blockBox.height + 1)
|
||||||
// return true when placed, false when cannot be placed
|
// return true when placed, false when cannot be placed
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.gameworld
|
package net.torvald.terrarum.modulebasegame.gameworld
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.aa.KDHeapifiedTree
|
import net.torvald.aa.KDTree
|
||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
@@ -52,7 +52,7 @@ object WorldSimulator {
|
|||||||
private val ingame = Terrarum.ingame!!
|
private val ingame = Terrarum.ingame!!
|
||||||
private val world = ingame.world
|
private val world = ingame.world
|
||||||
|
|
||||||
private var actorsKDTree: KDHeapifiedTree? = null
|
private var actorsKDTree: KDTree? = null
|
||||||
|
|
||||||
fun resetForThisFrame() {
|
fun resetForThisFrame() {
|
||||||
actorsKDTree = null
|
actorsKDTree = null
|
||||||
@@ -61,7 +61,7 @@ object WorldSimulator {
|
|||||||
operator fun invoke(player: ActorHumanoid?, delta: Float) {
|
operator fun invoke(player: ActorHumanoid?, delta: Float) {
|
||||||
// build the kdtree that will be used during a single frame of updating
|
// build the kdtree that will be used during a single frame of updating
|
||||||
if (actorsKDTree == null)
|
if (actorsKDTree == null)
|
||||||
actorsKDTree = KDHeapifiedTree(ingame.actorContainerActive.filter { it is ActorWBMovable })
|
actorsKDTree = KDTree(ingame.actorContainerActive.filter { it is ActorWBMovable })
|
||||||
|
|
||||||
//printdbg(this, "============================")
|
//printdbg(this, "============================")
|
||||||
|
|
||||||
|
|||||||
43
src/net/torvald/terrarum/modulebasegame/ui/FloatDrawer.kt
Normal file
43
src/net/torvald/terrarum/modulebasegame/ui/FloatDrawer.kt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.terrarum.AppLoader
|
||||||
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2019-05-24.
|
||||||
|
*/
|
||||||
|
object FloatDrawer : Disposable {
|
||||||
|
|
||||||
|
val tile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 8, 8)
|
||||||
|
|
||||||
|
init {
|
||||||
|
AppLoader.disposableSingletonsPool.add(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the Float at given position in given size. The size is that of the centre area, excluding the edges. Size of the edges are 8x8 pixels.
|
||||||
|
*/
|
||||||
|
operator fun invoke(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) {
|
||||||
|
// centre area
|
||||||
|
batch.draw(tile.get(1, 1), x, y, w, h)
|
||||||
|
|
||||||
|
// edges
|
||||||
|
batch.draw(tile.get(1, 0), x, y - tile.tileH, w, tile.tileH.toFloat())
|
||||||
|
batch.draw(tile.get(1, 2), x, y + h, w, tile.tileH.toFloat())
|
||||||
|
batch.draw(tile.get(0, 1), x - tile.tileW, y, tile.tileW.toFloat(), h)
|
||||||
|
batch.draw(tile.get(2, 1), x + w, y, tile.tileW.toFloat(), h)
|
||||||
|
|
||||||
|
// corners
|
||||||
|
batch.draw(tile.get(0, 0), x - tile.tileW, y - tile.tileH)
|
||||||
|
batch.draw(tile.get(2, 0), x + w, y - tile.tileH)
|
||||||
|
batch.draw(tile.get(2, 2), x + w, y + h)
|
||||||
|
batch.draw(tile.get(0, 2), x - tile.tileW, y + h)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
tile.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,15 +8,12 @@ import net.torvald.terrarum.Second
|
|||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.blendNormal
|
import net.torvald.terrarum.blendNormal
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-01-23.
|
* Created by minjaesong on 2016-01-23.
|
||||||
*/
|
*/
|
||||||
class Notification : UICanvas() {
|
class Notification : UICanvas() {
|
||||||
|
|
||||||
private val segment = SEGMENT_BLACK
|
|
||||||
|
|
||||||
private var fontCol: Color = Color.WHITE // assuming alpha of 1.0
|
private var fontCol: Color = Color.WHITE // assuming alpha of 1.0
|
||||||
|
|
||||||
override var openCloseTime: Second = OPEN_CLOSE_TIME
|
override var openCloseTime: Second = OPEN_CLOSE_TIME
|
||||||
@@ -28,14 +25,14 @@ class Notification : UICanvas() {
|
|||||||
|
|
||||||
override var width: Int = 500
|
override var width: Int = 500
|
||||||
|
|
||||||
override var height: Int = segment.tileH
|
override var height: Int = 0
|
||||||
private val visibleTime = Math.min(
|
private val visibleTime = Math.min(
|
||||||
AppLoader.getConfigInt("notificationshowuptime"),
|
AppLoader.getConfigInt("notificationshowuptime"),
|
||||||
SHOWUP_MAX
|
SHOWUP_MAX
|
||||||
) / 1000f
|
) / 1000f
|
||||||
private var displayTimer = 0f
|
private var displayTimer = 0f
|
||||||
|
|
||||||
internal var message: Array<String> = Array(MESSAGES_DISPLAY) { "" }
|
internal var message: List<String> = listOf("")
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -51,9 +48,6 @@ class Notification : UICanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val textAreaHeight = 48f
|
|
||||||
private val imageToTextAreaDelta = (segment.tileH - textAreaHeight) / 2
|
|
||||||
|
|
||||||
private val drawColor = Color(1f, 1f, 1f, 1f)
|
private val drawColor = Color(1f, 1f, 1f, 1f)
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
@@ -64,26 +58,22 @@ class Notification : UICanvas() {
|
|||||||
val realTextWidth = 12 + if (message.size == 1)
|
val realTextWidth = 12 + if (message.size == 1)
|
||||||
Terrarum.fontGame.getWidth(message[0])
|
Terrarum.fontGame.getWidth(message[0])
|
||||||
else
|
else
|
||||||
maxOf(Terrarum.fontGame.getWidth(message[0]), Terrarum.fontGame.getWidth(message[1]))
|
message.map { Terrarum.fontGame.getWidth(it) }.sorted().last()
|
||||||
val displayedTextWidth = maxOf(240, realTextWidth)
|
val displayedTextWidth = maxOf(240, realTextWidth)
|
||||||
|
|
||||||
// force the UI to the centre of the screen
|
// force the UI to the centre of the screen
|
||||||
this.posX = (Terrarum.WIDTH - displayedTextWidth) / 2
|
this.posX = (Terrarum.WIDTH - displayedTextWidth) / 2
|
||||||
|
|
||||||
|
val textHeight = message.size * Terrarum.fontGame.lineHeight
|
||||||
|
|
||||||
batch.color = drawColor
|
batch.color = drawColor
|
||||||
|
|
||||||
batch.draw(segment.get(0, 0), -segment.tileW.toFloat(), 0f)
|
FloatDrawer(batch, 0f, -textHeight, displayedTextWidth.toFloat(), textHeight)
|
||||||
batch.draw(segment.get(1, 0), 0f, 0f, displayedTextWidth.toFloat(), segment.tileH.toFloat())
|
|
||||||
batch.draw(segment.get(2, 0), displayedTextWidth.toFloat(), 0f)
|
|
||||||
|
|
||||||
batch.color = fontCol
|
batch.color = fontCol
|
||||||
message.forEachIndexed { index, s ->
|
message.forEachIndexed { index, s ->
|
||||||
val xoff = 6 + (displayedTextWidth - realTextWidth) / 2
|
val xoff = 6 + (displayedTextWidth - realTextWidth) / 2
|
||||||
val y = if (message.size == 1)
|
val y = -textHeight + Terrarum.fontGame.lineHeight * index
|
||||||
-2 + imageToTextAreaDelta + 0.5f * (textAreaHeight / 2) + (textAreaHeight / 2 - Terrarum.fontGame.lineHeight) / 2
|
|
||||||
else
|
|
||||||
-1 + imageToTextAreaDelta + index * (textAreaHeight / 2) + (textAreaHeight / 2 - Terrarum.fontGame.lineHeight) / 2
|
|
||||||
Terrarum.fontGame.draw(batch, s, LRmargin + xoff, y)
|
Terrarum.fontGame.draw(batch, s, LRmargin + xoff, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +99,7 @@ class Notification : UICanvas() {
|
|||||||
endClosingFade(this)
|
endClosingFade(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendNotification(message: Array<String>) {
|
fun sendNotification(message: List<String>) {
|
||||||
this.message = message
|
this.message = message
|
||||||
handler.openCloseCounter = 0f
|
handler.openCloseCounter = 0f
|
||||||
handler.opacity = 0f
|
handler.opacity = 0f
|
||||||
@@ -121,12 +111,6 @@ class Notification : UICanvas() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// private int messagesShowingIndex = 0;
|
// private int messagesShowingIndex = 0;
|
||||||
val MESSAGES_DISPLAY = 2
|
|
||||||
val OPEN_CLOSE_TIME = 0.16f
|
val OPEN_CLOSE_TIME = 0.16f
|
||||||
|
|
||||||
|
|
||||||
// will be disposed by Terrarum (application main instance)
|
|
||||||
val SEGMENT_BLACK = TextureRegionPack("assets/graphics/gui/message_black.tga", 8, 56)
|
|
||||||
val SEGMENT_WHITE = TextureRegionPack("assets/graphics/gui/message_white.tga", 8, 56)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.*
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import net.torvald.terrarum.*
|
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
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import net.torvald.terrarum.GdxColorMap
|
import net.torvald.terrarum.GdxColorMap
|
||||||
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.gameitem.GameItem
|
import net.torvald.terrarum.gameitem.GameItem
|
||||||
import net.torvald.terrarum.ui.UIItem
|
import net.torvald.terrarum.ui.UIItem
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@@ -47,4 +48,15 @@ object UIItemInventoryCellCommonRes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getHealthMeterColour(value: Int, start: Int, end: Int) = getHealthMeterColour(value.toFloat(), start.toFloat(), end.toFloat())
|
fun getHealthMeterColour(value: Int, start: Int, end: Int) = getHealthMeterColour(value.toFloat(), start.toFloat(), end.toFloat())
|
||||||
|
|
||||||
|
fun Int.toItemCountText() = (if (this < 0) "-" else "") + when (this.abs()) {
|
||||||
|
in 0..999999 -> "$this"
|
||||||
|
in 1_000_000..999_999_999 -> "${this / 1_000_000}.${this.rem(1_000_000) / 10_000}M"
|
||||||
|
else -> "${this / 1_000_000_000}.${this.rem(1_000_000_000) / 10_000_000}B"
|
||||||
|
|
||||||
|
// 1 000 000 000
|
||||||
|
// 2 147 483 647
|
||||||
|
|
||||||
|
// -2.14B
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,5 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.ui
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Camera
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
|
||||||
import net.torvald.random.HQRNG
|
|
||||||
import net.torvald.terrarum.modulebasegame.Ingame
|
|
||||||
import net.torvald.terrarum.LoadScreen
|
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.modulebasegame.BuildingMaker
|
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
|
||||||
import net.torvald.terrarum.ui.UIItemTextButtonList
|
|
||||||
|
|
||||||
/*class UITitleRemoConRoot : UICanvas() {
|
/*class UITitleRemoConRoot : UICanvas() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package net.torvald.terrarum.modulebasegame.ui
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Camera
|
import com.badlogic.gdx.graphics.Camera
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Texture
|
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.Second
|
import net.torvald.terrarum.Second
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2017-11-25.
|
* Created by minjaesong on 2017-11-25.
|
||||||
@@ -22,38 +20,33 @@ class UITooltip : UICanvas() {
|
|||||||
msgWidth = font.getWidth(value)
|
msgWidth = font.getWidth(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val textures = TextureRegionPack("assets/graphics/gui/tooltip_black.tga", 8, 36)
|
|
||||||
|
|
||||||
private val font = Terrarum.fontGame
|
private val font = Terrarum.fontGame
|
||||||
private var msgWidth = 0
|
private var msgWidth = 0
|
||||||
|
|
||||||
val textMarginX = 4
|
val textMarginX = 4
|
||||||
|
|
||||||
override var width: Int
|
override var width: Int
|
||||||
get() = msgWidth + (textMarginX + textures.tileW) * 2
|
get() = msgWidth + (textMarginX + FloatDrawer.tile.tileW) * 2
|
||||||
set(value) { throw Error("You are not supposed to set the width of the tooltip manually.") }
|
set(value) { throw Error("You are not supposed to set the width of the tooltip manually.") }
|
||||||
override var height: Int
|
override var height: Int
|
||||||
get() = textures.tileH
|
get() = FloatDrawer.tile.tileH * 2 + font.lineHeight.toInt()
|
||||||
set(value) { throw Error("You are not supposed to set the height of the tooltip manually.") }
|
set(value) { throw Error("You are not supposed to set the height of the tooltip manually.") }
|
||||||
|
|
||||||
|
|
||||||
init {
|
|
||||||
textures.texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
val mouseX = 4f
|
val mouseX = 4f
|
||||||
val mouseY = 6f
|
val mouseY = 6f
|
||||||
|
|
||||||
val tooltipY = mouseY - textures.tileH
|
val tooltipY = mouseY - height
|
||||||
|
|
||||||
val txtW = msgWidth + 2f * textMarginX
|
val txtW = msgWidth + 2f * textMarginX
|
||||||
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
batch.draw(textures.get(0, 0), mouseX, tooltipY)
|
|
||||||
batch.draw(textures.get(1, 0), mouseX + textures.tileW, tooltipY, txtW, height.toFloat())
|
FloatDrawer(batch, mouseX - textMarginX, tooltipY, txtW, font.lineHeight)
|
||||||
batch.draw(textures.get(2, 0), mouseX + textures.tileW + txtW, tooltipY)
|
font.draw(batch, message,
|
||||||
font.draw(batch, message, mouseX + textures.tileW + textMarginX, mouseY - textures.tileH + (textures.tileH - font.lineHeight) / 2)
|
mouseX,
|
||||||
|
mouseY - height
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateUI(delta: Float) {
|
override fun updateUI(delta: Float) {
|
||||||
@@ -73,7 +66,6 @@ class UITooltip : UICanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
textures.dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.graphics.GL20
|
import com.badlogic.gdx.graphics.GL20
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import net.torvald.colourutil.CIELuvUtil
|
import net.torvald.colourutil.CIELuvUtil
|
||||||
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.GdxColorMap
|
import net.torvald.terrarum.GdxColorMap
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
@@ -51,7 +52,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
lateinit var mixedWeather: BaseModularWeather
|
lateinit var mixedWeather: BaseModularWeather
|
||||||
|
|
||||||
val globalLightNow = Color(0)
|
val globalLightNow = Cvec(0)
|
||||||
|
|
||||||
// Weather indices
|
// Weather indices
|
||||||
const val WEATHER_GENERIC = "generic"
|
const val WEATHER_GENERIC = "generic"
|
||||||
@@ -178,10 +179,10 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
/**
|
/**
|
||||||
* Get a GL of specific time
|
* Get a GL of specific time
|
||||||
*/
|
*/
|
||||||
fun getGlobalLightOfTime(timeInSec: Int): Color =
|
fun getGlobalLightOfTime(timeInSec: Int): Cvec =
|
||||||
getGradientColour(currentWeather.skyboxGradColourMap, 2, timeInSec)
|
getGradientColour(currentWeather.skyboxGradColourMap, 2, timeInSec)
|
||||||
|
|
||||||
fun getGradientColour(colorMap: GdxColorMap, row: Int, timeInSec: Int): Color {
|
fun getGradientColour(colorMap: GdxColorMap, row: Int, timeInSec: Int): Cvec {
|
||||||
val dataPointDistance = WorldTime.DAY_LENGTH / colorMap.width
|
val dataPointDistance = WorldTime.DAY_LENGTH / colorMap.width
|
||||||
|
|
||||||
val phaseThis: Int = timeInSec / dataPointDistance // x-coord in gradmap
|
val phaseThis: Int = timeInSec / dataPointDistance // x-coord in gradmap
|
||||||
@@ -193,7 +194,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
// interpolate R, G, B and A
|
// interpolate R, G, B and A
|
||||||
val scale = (timeInSec % dataPointDistance).toFloat() / dataPointDistance // [0.0, 1.0]
|
val scale = (timeInSec % dataPointDistance).toFloat() / dataPointDistance // [0.0, 1.0]
|
||||||
|
|
||||||
val newCol = CIELuvUtil.getGradient(scale, colourThis, colourNext)
|
val newCol = colourThis.cpy().lerp(colourNext, scale)//CIELuvUtil.getGradient(scale, colourThis, colourNext)
|
||||||
|
|
||||||
/* // very nice monitor code
|
/* // very nice monitor code
|
||||||
// 65 -> 66 | 300 | 19623 | RGB8(255, 0, 255) -[41%]-> RGB8(193, 97, 23) | * `230`40`160`
|
// 65 -> 66 | 300 | 19623 | RGB8(255, 0, 255) -[41%]-> RGB8(193, 97, 23) | * `230`40`160`
|
||||||
@@ -203,7 +204,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
" | ${colourThis.toStringRGB()} -[${scale.times(100).toInt()}%]-> ${colourNext.toStringRGB()}" +
|
" | ${colourThis.toStringRGB()} -[${scale.times(100).toInt()}%]-> ${colourNext.toStringRGB()}" +
|
||||||
" | * `$r`$g`$b`")*/
|
" | * `$r`$g`$b`")*/
|
||||||
|
|
||||||
return newCol
|
return Cvec(newCol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWeatherList(classification: String) = weatherList[classification]!!
|
fun getWeatherList(classification: String) = weatherList[classification]!!
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.worldgenerator
|
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||||
|
|
||||||
import net.torvald.random.HQRNG
|
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import com.sudoplay.joise.Joise
|
import com.sudoplay.joise.Joise
|
||||||
import com.sudoplay.joise.module.*
|
import com.sudoplay.joise.module.*
|
||||||
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.LoadScreen
|
import net.torvald.terrarum.LoadScreen
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.concurrent.ThreadParallel
|
import net.torvald.terrarum.concurrent.ThreadParallel
|
||||||
import net.torvald.terrarum.modulebasegame.RNGConsumer
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.roundInt
|
import net.torvald.terrarum.roundInt
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ object WorldGenerator {
|
|||||||
*/
|
*/
|
||||||
fun generateMap() {
|
fun generateMap() {
|
||||||
random = HQRNG(SEED)
|
random = HQRNG(SEED)
|
||||||
println("[mapgenerator] Seed: " + SEED)
|
printdbg(this, "Seed: " + SEED)
|
||||||
|
|
||||||
worldOceanPosition = if (random.nextBoolean()) TYPE_OCEAN_LEFT else TYPE_OCEAN_RIGHT
|
worldOceanPosition = if (random.nextBoolean()) TYPE_OCEAN_LEFT else TYPE_OCEAN_RIGHT
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ object WorldGenerator {
|
|||||||
val joise = Joise(ground_select)
|
val joise = Joise(ground_select)
|
||||||
|
|
||||||
// fill the area as Joise map
|
// fill the area as Joise map
|
||||||
println("[mapgenerator] Raising and eroding terrain...")
|
printdbg(this, "Raising and eroding terrain...")
|
||||||
LoadScreen.addMessage("Raising and eroding terrain...")
|
LoadScreen.addMessage("Raising and eroding terrain...")
|
||||||
for (y in 0..(TERRAIN_UNDULATION - 1)) {
|
for (y in 0..(TERRAIN_UNDULATION - 1)) {
|
||||||
for (x in 0..WIDTH) {
|
for (x in 0..WIDTH) {
|
||||||
@@ -549,7 +549,7 @@ object WorldGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun placeGlacierMount(heightMap: IntArray) {
|
private fun placeGlacierMount(heightMap: IntArray) {
|
||||||
println("[mapgenerator] Putting glacier...")
|
printdbg(this, "Putting glacier...")
|
||||||
|
|
||||||
// raise
|
// raise
|
||||||
for (i in heightMap.indices) {
|
for (i in heightMap.indices) {
|
||||||
@@ -579,7 +579,7 @@ object WorldGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun heightMapToObjectMap(fs: IntArray) {
|
private fun heightMapToObjectMap(fs: IntArray) {
|
||||||
println("[mapgenerator] Shaping world as processed...")
|
printdbg(this, "Shaping world as processed...")
|
||||||
|
|
||||||
// iterate for heightmap
|
// iterate for heightmap
|
||||||
for (x in 0..WIDTH - 1) {
|
for (x in 0..WIDTH - 1) {
|
||||||
@@ -602,7 +602,7 @@ object WorldGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fillMapByNoiseMap() {
|
private fun fillMapByNoiseMap() {
|
||||||
println("[mapgenerator] Shaping world...")
|
printdbg(this, "Shaping world...")
|
||||||
LoadScreen.addMessage("Reticulating splines...") // RETICULATING SPLINES
|
LoadScreen.addMessage("Reticulating splines...") // RETICULATING SPLINES
|
||||||
// generate dirt-stone transition line
|
// generate dirt-stone transition line
|
||||||
// use catmull spline
|
// use catmull spline
|
||||||
@@ -686,7 +686,7 @@ object WorldGenerator {
|
|||||||
filter: NoiseFilter = NoiseFilterQuadratic,
|
filter: NoiseFilter = NoiseFilterQuadratic,
|
||||||
filterStart: Double = NOISE_GRAD_START,
|
filterStart: Double = NOISE_GRAD_START,
|
||||||
filterEnd: Double = NOISE_GRAD_END) {
|
filterEnd: Double = NOISE_GRAD_END) {
|
||||||
println("[mapgenerator] " + message)
|
printdbg(this, "" + message)
|
||||||
|
|
||||||
for (y in 0..HEIGHT - 1) {
|
for (y in 0..HEIGHT - 1) {
|
||||||
for (x in 0..WIDTH - 1) {
|
for (x in 0..WIDTH - 1) {
|
||||||
@@ -716,7 +716,7 @@ object WorldGenerator {
|
|||||||
filter: NoiseFilter = NoiseFilterQuadratic,
|
filter: NoiseFilter = NoiseFilterQuadratic,
|
||||||
filterStart: Double = NOISE_GRAD_START,
|
filterStart: Double = NOISE_GRAD_START,
|
||||||
filterEnd: Double = NOISE_GRAD_END) {
|
filterEnd: Double = NOISE_GRAD_END) {
|
||||||
println("[mapgenerator] " + message)
|
printdbg(this, "" + message)
|
||||||
|
|
||||||
for (y in 0..HEIGHT - 1) {
|
for (y in 0..HEIGHT - 1) {
|
||||||
for (x in 0..WIDTH - 1) {
|
for (x in 0..WIDTH - 1) {
|
||||||
@@ -747,7 +747,7 @@ object WorldGenerator {
|
|||||||
filter: NoiseFilter = NoiseFilterQuadratic,
|
filter: NoiseFilter = NoiseFilterQuadratic,
|
||||||
filterStart: Double = NOISE_GRAD_START,
|
filterStart: Double = NOISE_GRAD_START,
|
||||||
filterEnd: Double = NOISE_GRAD_END) {
|
filterEnd: Double = NOISE_GRAD_END) {
|
||||||
println("[mapgenerator] " + message)
|
printdbg(this, "" + message)
|
||||||
|
|
||||||
for (y in 0..HEIGHT - 1) {
|
for (y in 0..HEIGHT - 1) {
|
||||||
for (x in 0..WIDTH - 1) {
|
for (x in 0..WIDTH - 1) {
|
||||||
@@ -797,7 +797,7 @@ object WorldGenerator {
|
|||||||
private val islandSpacing = 1024
|
private val islandSpacing = 1024
|
||||||
|
|
||||||
private fun generateFloatingIslands() {
|
private fun generateFloatingIslands() {
|
||||||
println("[mapgenerator] Placing floating islands...")
|
printdbg(this, "Placing floating islands...")
|
||||||
LoadScreen.addMessage("Placing floating islands...")
|
LoadScreen.addMessage("Placing floating islands...")
|
||||||
|
|
||||||
val nIslandsMax = Math.round(world.width * 6f / 8192f)
|
val nIslandsMax = Math.round(world.width * 6f / 8192f)
|
||||||
@@ -830,7 +830,7 @@ object WorldGenerator {
|
|||||||
/* Flood */
|
/* Flood */
|
||||||
|
|
||||||
private fun floodBottomLava() {
|
private fun floodBottomLava() {
|
||||||
/*println("[mapgenerator] Flooding with lava...")
|
/*printdbg(this, "Flooding with lava...")
|
||||||
LoadScreen.addMessage("Flooding with lava...")
|
LoadScreen.addMessage("Flooding with lava...")
|
||||||
for (i in HEIGHT * 14 / 15..HEIGHT - 1) {
|
for (i in HEIGHT * 14 / 15..HEIGHT - 1) {
|
||||||
for (j in 0..WIDTH - 1) {
|
for (j in 0..WIDTH - 1) {
|
||||||
@@ -844,7 +844,7 @@ object WorldGenerator {
|
|||||||
/* Plant */
|
/* Plant */
|
||||||
|
|
||||||
private fun plantGrass() {
|
private fun plantGrass() {
|
||||||
println("[mapgenerator] Planting grass...")
|
printdbg(this, "Planting grass...")
|
||||||
LoadScreen.addMessage("Planting grass...")
|
LoadScreen.addMessage("Planting grass...")
|
||||||
|
|
||||||
/* TODO composing dirt and stone
|
/* TODO composing dirt and stone
|
||||||
@@ -910,7 +910,7 @@ object WorldGenerator {
|
|||||||
"yellow"
|
"yellow"
|
||||||
else
|
else
|
||||||
"white"
|
"white"
|
||||||
println("[mapgenerator] Beach sand type: $thisSandStr")
|
printdbg(this, "Beach sand type: $thisSandStr")
|
||||||
|
|
||||||
var ix = 0
|
var ix = 0
|
||||||
while (ix < OCEAN_WIDTH * 1.5) {
|
while (ix < OCEAN_WIDTH * 1.5) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user