Compare commits

...

25 Commits

Author SHA1 Message Date
minjaesong
4f8c3591c2 80 fps with unsafe access 2019-06-08 03:00:47 +09:00
minjaesong
a1d51d4028 just a fixme tag 2019-06-07 22:16:38 +09:00
minjaesong
593a528d32 apparently I'm fucking dumb 2019-06-07 10:37:04 +09:00
minjaesong
4a99722f71 i discovered something to be looked at 2019-06-07 10:23:22 +09:00
Minjae Song
97f8aa6e6e weather to not use expensive math; colormap now also holds cvec 2019-06-05 21:22:27 +09:00
Minjae Song
85ab1b823d mod metadata: changed versioning scheme 2019-06-05 21:22:27 +09:00
minjaesong
812e9e5b76 light parallel failed attempt 2019-06-05 21:04:01 +09:00
minjaesong
a87866438f debugwindow: correct ui count 2019-06-01 04:47:20 +09:00
minjaesong
c692928c1a lightmap is now array of array because debug-ability > slight framerate drop 2019-06-01 04:06:36 +09:00
minjaesong
5ff0c22b0f cvec: java to kotlin 2019-06-01 03:49:14 +09:00
minjaesong
eb1273c561 migration wip java 9 modularise 2019-06-01 03:25:20 +09:00
minjaesong
50c110f34b fixed using wrong type of exception 2019-06-01 02:06:07 +09:00
minjaesong
c180953d7d fixtures won't spawn when there's block or other fixtures 2019-05-31 22:57:20 +09:00
minjaesong
a1ac9b177a fixing "roundworld anomaly": some actors won't render 2019-05-31 04:10:00 +09:00
minjaesong
c50d07b541 wip debugging "roundworld anomaly" 2019-05-30 23:35:01 +09:00
minjaesong
56fdb2f556 contracted itemcount string 2019-05-30 21:36:02 +09:00
minjaesong
d2ddca85a6 font: hangul update 2019-05-30 14:10:09 +09:00
minjaesong
9aa002f4cc tiki torch correctly spawns; gotta check for collision 2019-05-29 23:20:39 +09:00
minjaesong
3a5fcb9ba0 added definition for fixture null blockbox 2019-05-28 23:57:51 +09:00
minjaesong
7d5a37cd6d tiki torch spawns but is not centred 2019-05-28 22:46:10 +09:00
minjaesong
75c79d8ca2 no secondary click; tiki torch kinda spawns? 2019-05-26 22:55:50 +09:00
minjaesong
0b7a3a5636 disposable singletons to an array in loader; single float for both notification and tooltip 2019-05-24 20:38:35 +09:00
Minjae Song
c5e0de2393 stupid gimp 2019-05-22 12:57:20 +09:00
Minjae Song
19fb5b1319 tileable message float ui 2019-05-22 12:51:01 +09:00
minjaesong
2fff2c24cf cherrypicked from the branch test-cvec-for-light 2019-05-21 17:50:54 +09:00
139 changed files with 1419 additions and 2348 deletions

5
.idea/compiler.xml generated
View File

@@ -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
View 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
View File

@@ -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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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"
1 id drop name shdr shdg shdb shduv str dsty mate solid plat wall fall dlfn fv fr lumr lumg lumb lumuv colour vscs
98 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
99 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
100 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
101 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
102 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
103 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
104 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
105 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
106 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
107 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
108 -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.

View File

@@ -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.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

BIN
lib/gdx-nightly-20170610.zip.gz LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/gdx-nightly-20181111.zip.gz LFS Normal file

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

BIN
lib/jorbis-0.0.17.jar.gz LFS Normal file

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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;
}
}
}

View File

@@ -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
View 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;
}

View File

@@ -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 }

View File

@@ -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

View File

@@ -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
* *

View File

@@ -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

View File

@@ -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

View 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
}
}
}

View File

@@ -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;

View 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

View File

@@ -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

View File

@@ -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();

View File

@@ -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()

View File

@@ -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
/** /**

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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) {

View File

@@ -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
)
} }

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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)
} }

View File

@@ -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 {

View File

@@ -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
} }
} }

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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())
} }*/
} }
} }

View File

@@ -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

View 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)

View File

@@ -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
} }
} }

View File

@@ -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)

View File

@@ -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, ...
} }
} }*/

View File

@@ -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)

View File

@@ -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()
} }

View File

@@ -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()

View File

@@ -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")
}
} }

View File

@@ -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,

View File

@@ -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.*

View File

@@ -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)
} }
} }

View File

@@ -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()

View File

@@ -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
/** /**

View File

@@ -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
} }

View File

@@ -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)
// ... // ...
) )
} }

View File

@@ -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) {

View File

@@ -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) {
} }

View File

@@ -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 {

View File

@@ -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
} }
} }

View File

@@ -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, "============================")

View 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()
}
}

View File

@@ -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)
} }
} }

View File

@@ -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

View File

@@ -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
}
} }

View File

@@ -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 {

View File

@@ -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()
} }
} }

View File

@@ -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]!!

View File

@@ -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