diff --git a/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col12.class b/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col12.class
deleted file mode 100644
index 3dd25f212..000000000
Binary files a/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col12.class and /dev/null differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col256.class b/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col256.class
new file mode 100644
index 000000000..2e224caf0
Binary files /dev/null and b/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col256.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col4096.class b/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col4096.class
new file mode 100644
index 000000000..023e54185
Binary files /dev/null and b/out/production/Terrarum_renewed/com/Torvald/ColourUtil/Col4096.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontBase.class b/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontBase.class
index fa6d72d0d..98970f60a 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontBase.class and b/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontBase.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontWhite.class b/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontWhite.class
index fdb2426e4..76b65cc11 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontWhite.class and b/out/production/Terrarum_renewed/com/Torvald/ImageFont/GameFontWhite.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Rand/HighQualityRandom.class b/out/production/Terrarum_renewed/com/Torvald/Rand/HQRNG.class
similarity index 66%
rename from out/production/Terrarum_renewed/com/Torvald/Rand/HighQualityRandom.class
rename to out/production/Terrarum_renewed/com/Torvald/Rand/HQRNG.class
index 5f4b32050..8b8e124b6 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Rand/HighQualityRandom.class and b/out/production/Terrarum_renewed/com/Torvald/Rand/HQRNG.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/ActorWithBody.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/ActorWithBody.class
index 422263aa7..5316f1e3e 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/ActorWithBody.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/ActorWithBody.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/CreatureBuildFactory.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/CreatureBuildFactory.class
index 116a28557..d28829271 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/CreatureBuildFactory.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/CreatureBuildFactory.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PBFSigrid.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PBFSigrid.class
index bf2bb238f..46d4703b6 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PBFSigrid.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PBFSigrid.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/Player.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/Player.class
index d7ed4b61d..01c65c373 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/Player.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/Player.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PlayerBuildFactory.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PlayerBuildFactory.class
index 55228ea94..db2372411 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PlayerBuildFactory.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Actors/PlayerBuildFactory.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CatStdout.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CatStdout.class
new file mode 100644
index 000000000..a07b4e372
Binary files /dev/null and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CatStdout.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CommandDict.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CommandDict.class
index 66e8fc0df..c0a250852 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CommandDict.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/CommandDict.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/ExportMap.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/ExportMap.class
index c51a4a7bf..1db4479d5 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/ExportMap.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/ConsoleCommand/ExportMap.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Game.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Game.class
index 02f2076a4..554ac7ea4 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Game.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Game.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MISC_FEATURES b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MISC_FEATURES
new file mode 100644
index 000000000..6ce71a3d1
--- /dev/null
+++ b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MISC_FEATURES
@@ -0,0 +1,4 @@
+* Drawing
+
+- Players can create their own décors (hang on wall), dresses.
+- Two looms (3-3-2 colour mode, 4096 colour mode)
\ No newline at end of file
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapCamera.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapCamera.class
index 681a7b13b..0364dc54c 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapCamera.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapCamera.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapDrawer.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapDrawer.class
index 1899c33cc..63bfce6ef 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapDrawer.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapDrawer/MapDrawer.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.class
index 1bbecc634..ab7e26b6b 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/MapGenerator.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/MapGenerator.class
index 366abf65e..51cb24843 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/MapGenerator.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/MapGenerator.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise.class
index 1c5115e6d..1ee31b50b 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.class
index 8ba17518b..aae4c1d99 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Terrarum.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Terrarum.class
index e58b91120..4af13fcbd 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/Terrarum.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/Terrarum.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/Terrarum/UserInterface/ConsoleWindow.class b/out/production/Terrarum_renewed/com/Torvald/Terrarum/UserInterface/ConsoleWindow.class
index fceff5a9a..5a437e649 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/Terrarum/UserInterface/ConsoleWindow.class and b/out/production/Terrarum_renewed/com/Torvald/Terrarum/UserInterface/ConsoleWindow.class differ
diff --git a/out/production/Terrarum_renewed/com/Torvald/spriteAnimation/SpriteAnimation.class b/out/production/Terrarum_renewed/com/Torvald/spriteAnimation/SpriteAnimation.class
index a6bc49f9c..9adeca035 100644
Binary files a/out/production/Terrarum_renewed/com/Torvald/spriteAnimation/SpriteAnimation.class and b/out/production/Terrarum_renewed/com/Torvald/spriteAnimation/SpriteAnimation.class differ
diff --git a/out/production/Terrarum_renewed/com/jme3/math/FastMath.class b/out/production/Terrarum_renewed/com/jme3/math/FastMath.class
index a9d0dbbd2..4ac4affc4 100644
Binary files a/out/production/Terrarum_renewed/com/jme3/math/FastMath.class and b/out/production/Terrarum_renewed/com/jme3/math/FastMath.class differ
diff --git a/res/books/hangul_test.txt b/res/books/hangul_test.txt
new file mode 100644
index 000000000..28974fdd0
--- /dev/null
+++ b/res/books/hangul_test.txt
@@ -0,0 +1,66 @@
+낮에는 따사로운 인간적인 여자
+커피 한잔의 여유를 아는 품격 있는 여자
+밤이 오면 심장이 뜨거워지는 여자
+그런 반전 있는 여자
+
+나는 사나이
+낮에는 너만큼 따사로운 그런 사나이
+커피 식기도 전에 원샷 때리는 사나이
+밤이 오면 심장이 터져버리는 사나이
+그런 사나이
+
+아름다워 사랑스러워
+그래 너 hey 그래 바로 너 hey
+아름다워 사랑스러워
+그래 너 hey 그래 바로 너 hey
+지금부터 갈 데까지 가볼까
+
+오빤 강남스타일
+강남스타
+오빤 강남스타일
+강남스타일
+오빤 강남스타일
+
+Eh- Sexy Lady
+오빤 강남스타일
+Eh- Sexy Lady
+오오오오
+
+정숙해 보이지만 놀 땐 노는 여자
+이때다 싶으면 묶었던 머리 푸는 여자
+가렸지만 웬만한 노출보다 야한 여자
+그런 감각적인 여자
+
+나는 사나이
+점잖아 보이지만 놀 땐 노는 사나이
+때가 되면 완전 미쳐버리는 사나이
+근육보다 사상이 울퉁불퉁한 사나이
+그런 사나이
+
+아름다워 사랑스러워
+그래 너 hey 그래 바로 너 hey
+아름다워 사랑스러워
+그래 너 hey 그래 바로 너 hey
+지금부터 갈 데까지 가볼까
+
+오빤 강남스타일
+강남스타일
+오빤 강남스타일
+강남스타일
+오빤 강남스타일
+
+Eh- Sexy Lady
+오빤 강남스타일
+Eh- Sexy Lady
+오오오오
+
+뛰는 놈 그 위에 나는 놈
+baby baby 나는 뭘 좀 아는 놈
+뛰는 놈 그 위에 나는 놈
+baby baby 나는 뭘 좀 아는 놈
+You know what I'm saying
+오빤 강남스타일
+Eh- Sexy Lady
+오빤 강남스타일
+Eh- Sexy Lady
+오빤 강남스타일
diff --git a/res/books/isl_test.txt b/res/books/isl_test.txt
new file mode 100644
index 000000000..815a2b273
--- /dev/null
+++ b/res/books/isl_test.txt
@@ -0,0 +1,38 @@
+Sjá snjóinn glitra á fjallinu í nótt, ekkert fótspor hér að sjá
+Eitt einsemdar konungsríki, og ég virðist, drottningin
+Vindurinn gnauðar eins og ólgan inni í mér
+Gat ei byrgt það inni en ég reyndi samt
+
+Hleyp þeim ei inn lát þau ei sjá
+Vertu góða stelpan sem þú varst
+Feldu, bældu, seg þeim ei frá
+En þau vita það þá
+
+Þetta er nóg, þetta er nóg. Get ei lengur haldið í mér
+Þetta er nóg, þetta er nóg. Ég sný burt og skelli á eftir mér
+Mig varðar ei, hvað þau segja við því
+Látið geysa storm, kuldinn hann hefur ei háð mér neitt
+
+Það er merkilegt hvað fjarlægð, gerir allt svo ofursmátt
+Og hræðslan sem hafði tökin, virðist missa allan mátt
+
+Ég þarf að sjá hvað ég get gert, og reyná verk mín umtalsvert
+Og boð og bönn ei halda mér
+Ég er frjáls
+
+Þetta er nóg, þetta er nóg. Uppi í himni eins og vindablær
+Þetta er nóg, komið nóg. Og tár mín enginn sér fær
+Hér ég stend, og hér ég verð
+Látið geysa storm
+
+Minn máttur þyrlast gegnum loftið niðrá jörð
+Mín sál er hringiða úr frosnum brotamyndum gjörð
+Ein hugsun kristalla sem ískalt sprengigos
+Ég aldrei aftur sný, það var sem eitt sinn var
+
+Þetta er nóg, þetta er nóg. Og ég rís eins og morgunsól
+Þetta er nóg, þetta er nóg. Þessi þæga stelpa fór
+Hér ég stend, ein um bjartan dag
+Látið geysa storm
+
+Kuldinn hann hefur ei háð mér neitt
diff --git a/res/books/kana_test.txt b/res/books/kana_test.txt
new file mode 100644
index 000000000..7286d2632
--- /dev/null
+++ b/res/books/kana_test.txt
@@ -0,0 +1,29 @@
+せかいいち みんなの にんきもの
+それは かのじょの こと アシュリー
+ひとめ みれば だれもが ふりむく
+あたりまえ アシュリーだもん
+
+せかいじゅう みんなが あこがれる
+それは かのじょの こと アシュリー
+アシュリー さまの まほうは さいこう
+こんやも パーティーよ
+
+なわ ぶな ぬー わらいの じゅもん
+じお いら うん なんの じゅもん
+いお でぃ えむ おぼえ られない
+ああ いや たいくつ
+
+せかいいち みんなの にんきもの
+それは かのじょの こと アシュリー
+アシュリー さまの まほうは さいこう
+こわい もの なしよ
+
+よぞらの うみ あまたの ほし
+いつも ひとりきり
+みんなと なかよく したいの
+どうしたら いいの
+
+せかいいち みんなの にんきもの
+それは かのじょの こと アシュリー
+アシュリー さまの まほうは さいこう
+こんやも パーティーよ
diff --git a/res/books/polyglot_test.txt b/res/books/polyglot_test.txt
new file mode 100644
index 000000000..a5ec4519c
--- /dev/null
+++ b/res/books/polyglot_test.txt
@@ -0,0 +1,31 @@
+The snow glows white on the mountain tonight, not a footprint to be seen
+Un royaume de solitude, ma place est là pour toujours
+Der Wind, er heult so wie der Sturm ganz tief in mir
+Het werd mij te veel, hoe ik mijn best ook deed
+
+[han logographics not supported]
+Visa ingenting, vad du än gör, allt är förstört
+
+ありの ままの すがた みせるのよ
+Libre soy, libre soy, ¡libertad sin vuelta atrás!
+Wszystkim wbrew na ten gest mnie stać
+Jöjjön száz orkán, és közben a szívemen ül a jég
+
+Desde la distancia, ¡qué pequeño todo es!
+I les pors que em dominaven per sempre han fugit
+Non è un difetto, è una virtù! e non la fermerò mai più,
+내 맘대로 자유롭게 살래!
+
+Сад је крај, сад је крај На крилима ветра сам
+[han logographics not supported]
+Estou aqui, e vou ficar! Venha a tempestade
+
+Kuasaku buat hidup bercelaru
+Подвластны мне мороз и лёд, ну что за дивный дар
+Og som krystaller står en tanke ganske klar
+Ще спра да бъда аз на миналото в плен
+
+La den gå, la den gå, jeg skal stige lik solen nå
+[thai language not supported]
+Je suis là, comme je l'ai rêvé
+En de storm raast door! De vrieskou, daar zat ik toch al niet mee
\ No newline at end of file
diff --git a/res/books/runic_short_2.txt b/res/books/runic_short_2.txt
index 950189836..b9d33a413 100644
--- a/res/books/runic_short_2.txt
+++ b/res/books/runic_short_2.txt
@@ -1,16 +1,16 @@
-᛭ᚱᛂᚴᛋ᛬ᛏᛂᛁᚢᚯᛋ᛬ᚴᚢᛂ᛭
+᛭ᚱᛂᚴᛋ᛬ᛏᛂᛁᚢᚬᛋ᛬ᚴᚢᛂ᛭
-᛬ᚱᚽᚴᛋ᛬ᚽᛋᛏ᛬ᛋᚢ᛬ᚾᛒᚢᛏᛚᚢᛋ᛬
-᛬ᚱᚽᚴᛋ᛬ᛋᚢᚼᚾᚢᛉ᛬ᚢᛚᚾᛏᚢ᛬
-᛬ᛏᚢᛋᛁᚢ᛬ᚴᚽᚢᛏᚢᚱᛉ᛬ᛒᚱᚽᚴᛋᛏ᛬
-᛫ᛋᚢᚼᚾᚢᛋ᛬ᛉᚬᛁ᛬ᚴᚾᛁᚽᛏᚢᛏ᛫
-᛬ᚴᛂᛁᛏᚯᚱ᛬ᛏᚯᛘ᛬ᚱᛂᚴᛘ᛬ᚢᛂᚢᚴᛂᛏ᛬
-᛫ᛁᛅᚴᛂᛋᚢᚯ᛬ᛏᛂᛁᚢᚯᛘ᛬ᚢᛂᚱᚢᚾᚯᛘ᛫
-᛬ᚢᛒᚢ᛬ᚱᛂᚴᛋ᛬ᛏᛂᛁᚢᚯᛘ᛬ᚢᛂᚱᚢᚾᚢᛘ᛬ᛋᛂᛋᚢᛚᛂ᛬ᚾᚢ᛬ᛏᛂᛁᚢᚯᛘ᛬ᛁᛅᚴᛂᛏᚢ᛬
-᛫ᚴᛚᚢᛏᛁ᛬ᛘᚯᛁ᛬ᛒᛏᛂᚱ᛬ᚢᛂᚱᚢᚾᛂ᛫
-᛬ᛏᛂᛁᚢᚯᛋ᛬ᚢᛂᚱᚢᚾᚯᛋ᛬ᛏᛁᚢᛂᛋ᛬ᚾᛘᛏᛅ᛬ᚴᚢᛅᛏ᛬
+᛬ᚱᛂᚴᛋ᛬ᛂᛋᛏ᛬ᛋᚢ᛬ᚾᛒᚢᛏᛚᚢᛋ᛬
+᛬ᚱᛂᚴᛋ᛬ᛋᚢᚼᚾᚢᛘ᛬ᚢᛚᚾᛏᚢ᛬
+᛬ᛏᚢᛋᛁᚢ᛬ᚴᛂᚢᛏᚢᚱᛘ᛬ᛒᚱᛂᚴᛋᛏ᛬
+᛫ᛋᚢᚼᚾᚢᛋ᛬ᛘᚬᛁ᛬ᚴᚾᛁᛂᛏᚢᛏ᛫
+᛬ᚴᛂᛁᛏᚬᚱ᛬ᛏᚬᛘ᛬ᚱᛂᚴᛘ᛬ᚢᛂᚢᚴᛂᛏ᛬
+᛫ᛁᛅᚴᛂᛋᚢᚬ᛬ᛏᛂᛁᚢᚬᛘ᛬ᚢᛂᚱᚢᚾᚬᛘ᛫
+᛬ᚢᛒᚢ᛬ᚱᛂᚴᛋ᛬ᛏᛂᛁᚢᚬᛘ᛬ᚢᛂᚱᚢᚾᚢᛘ᛬ᛋᛂᛋᚢᛚᛂ᛬ᚾᚢ᛬ᛏᛂᛁᚢᚬᛘ᛬ᛁᛅᚴᛂᛏᚢ᛬
+᛫ᚴᛚᚢᛏᛁ᛬ᛘᚬᛁ᛬ᛒᛏᛂᚱ᛬ᚢᛂᚱᚢᚾᛂ᛫
+᛬ᛏᛂᛁᚢᚬᛋ᛬ᚢᛂᚱᚢᚾᚬᛋ᛬ᛏᛁᚢᛂᛋ᛬ᚾᛘᛏᛅ᛬ᚴᚢᛅᛏ᛬
᛫ᚴᚢᛁᛏ᛬ᚢᛂᛚᛋᛁ᛫
᛫ᛋᚢᚼᚾᚢᛘ᛬ᚢᛂᛚᛘᛁ᛫
᛫ᛏᚢᛏ᛬ᛂᛋᛏᚢ᛫
-᛬ᚢᛂᚢᚴᛂᛏ᛬ᛚᛂᚢᚴᚢᛋ᛬ᛏᛂᛁᚢᚯᛋ᛬ᚢᛂᚱᚢᚾᚯᛋ᛬
-᛬ᚾᚢ᛬ᚱᛂᚴᛋ᛬ᛒᚯᛏᚾᛁ᛬ᛋᚢᚼᚾᚢᛘ᛬ᚴᛂᚴᚢᚾᛂ᛬
\ No newline at end of file
+᛬ᚢᛂᚢᚴᛂᛏ᛬ᛚᛂᚢᚴᚢᛋ᛬ᛏᛂᛁᚢᚬᛋ᛬ᚢᛂᚱᚢᚾᚬᛋ᛬
+᛬ᚾᚢ᛬ᚱᛂᚴᛋ᛬ᛒᚬᛏᚾᛁ᛬ᛋᚢᚼᚾᚢᛘ᛬ᚴᛂᚴᚢᚾᛂ᛬
\ No newline at end of file
diff --git a/res/graphics/colourkey12.png b/res/graphics/colourkey12.png
new file mode 100644
index 000000000..26c22a75e
Binary files /dev/null and b/res/graphics/colourkey12.png differ
diff --git a/res/graphics/fonts/cjkpunct.png b/res/graphics/fonts/cjkpunct.png
new file mode 100644
index 000000000..fec0886e1
Binary files /dev/null and b/res/graphics/fonts/cjkpunct.png differ
diff --git a/res/graphics/fonts/kana.png b/res/graphics/fonts/kana.png
new file mode 100644
index 000000000..00845443d
Binary files /dev/null and b/res/graphics/fonts/kana.png differ
diff --git a/res/graphics/terrain/terrainplusplus.png b/res/graphics/terrain/terrainplusplus.png
index 15fcdffd5..7f7bf9dac 100644
Binary files a/res/graphics/terrain/terrainplusplus.png and b/res/graphics/terrain/terrainplusplus.png differ
diff --git a/src/com/Torvald/ColourUtil/Col12.java b/src/com/Torvald/ColourUtil/Col12.java
deleted file mode 100644
index caf138d1f..000000000
--- a/src/com/Torvald/ColourUtil/Col12.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.Torvald.ColourUtil;
-
-import org.newdawn.slick.Color;
-
-/**
- * Created by minjaesong on 16-01-23.
- */
-public class Col12 {
-
- private short data;
-
- /**
- * Create new Col12 format
- * @param data 0x000-0xFFF, in RGB
- */
- public Col12(int data) {
- this.data = (short) data;
- }
-
- public Color create(int i) {
- if (i > 0xFFF || i < 0) {
- throw new IllegalArgumentException("Colour range: #000 - #FFF");
- }
- int r = (i & 0xF00) >> 8;
- int g = (i & 0x0F0) >> 4;
- int b = i & 0x00F;
-
- return new Color(
- (r << 4) | r
- , (g << 4) | g
- , (b << 4) | b
- );
- }
-
- public byte[] toByteArray() {
- byte[] ret = new byte[3];
- int r = (data & 0xF00) >> 8;
- int g = (data & 0x0F0) >> 4;
- int b = data & 0x00F;
-
- ret[0] = (byte) ((r << 4) | r);
- ret[1] = (byte) ((g << 4) | g);
- ret[2] = (byte) ((b << 4) | b);
-
- return ret;
- }
-
-}
diff --git a/src/com/Torvald/ColourUtil/Col256.java b/src/com/Torvald/ColourUtil/Col256.java
new file mode 100644
index 000000000..a673ab880
--- /dev/null
+++ b/src/com/Torvald/ColourUtil/Col256.java
@@ -0,0 +1,73 @@
+package com.Torvald.ColourUtil;
+
+import org.newdawn.slick.Color;
+
+/**
+ * Created by minjaesong on 16-02-07.
+ *
+ * 3-3-2 256 colour RGB
+ */
+public class Col256 {
+
+ private byte data;
+
+ /**
+ * Create new Col256 format.
+ * @param data 0x00-0xFF
+ */
+ public Col256(int data) {
+ this.data = (byte) data;
+ }
+
+ public Col256(int r, int g, int b) {
+ if (r > 7 || g > 7 || b > 3) {
+ throw new IllegalArgumentException("Colour range: RG: 0-7, B:0-4");
+ }
+
+ data = (byte) (r << 5 | g << 2 | b);
+ }
+
+ /**
+ * Create Col256 colour and convert it to Slick Color
+ * @param i
+ * @return
+ */
+ public Color create(int i) {
+ if (i > 0xFF || i < 0) {
+ throw new IllegalArgumentException("Colour range: #00 - #FF");
+ }
+ int r = (i & 0b11100000) >> 5;
+ int g = (i & 0b00011100) >> 2;
+ int b = i & 0b00000011;
+
+ return create(r, g, b);
+ }
+
+ /**
+ * Create Col256 colour and convert it to Slick Color
+ * @return
+ */
+ public Color create(int r, int g, int b) {
+ if (r > 7 || g > 7 || b > 3) {
+ throw new IllegalArgumentException("Colour range: RG: 0-7, B:0-4");
+ }
+
+ int[] colIndex3 = {0, 36, 73, 109, 146, 182, 219, 255};
+ int[] colIndex2 = {0, 85, 170, 255};
+
+ return new Color(
+ colIndex3[r]
+ , colIndex3[g]
+ , colIndex2[b]
+ );
+ }
+
+ /**
+ * Retrieve raw RGB value
+ * @return 0bRRRGGGBB
+ */
+ public byte getByte() {
+ return data;
+ }
+
+}
diff --git a/src/com/Torvald/ColourUtil/Col4096.java b/src/com/Torvald/ColourUtil/Col4096.java
new file mode 100644
index 000000000..8ba8a4833
--- /dev/null
+++ b/src/com/Torvald/ColourUtil/Col4096.java
@@ -0,0 +1,79 @@
+package com.Torvald.ColourUtil;
+
+import org.newdawn.slick.Color;
+
+/**
+ * Created by minjaesong on 16-01-23.
+ *
+ * 12-bit RGB
+ */
+public class Col4096 {
+
+ private short data;
+
+ /**
+ * Create new Col4096 format.
+ * @param data 0xARGB
+ */
+ public Col4096(int data) {
+ this.data = (short) data;
+ }
+
+ /**
+ * Create Col4096 colour and convert it to Slick Color
+ * @param i
+ * @return
+ */
+ public Color create(int i) {
+ if (i > 0xFFF) {
+ int a = (i & 0xF000) >> 12;
+ int r = (i & 0x0F00) >> 8;
+ int g = (i & 0x00F0) >> 4;
+ int b = i & 0x000F;
+
+ return new Color(
+ (r << 4) | r
+ , (g << 4) | g
+ , (b << 4) | b
+ , (a << 4) | a
+ );
+ }
+ else {
+ int r = (i & 0xF00) >> 8;
+ int g = (i & 0x0F0) >> 4;
+ int b = i & 0x00F;
+
+ return new Color(
+ (r << 4) | r
+ , (g << 4) | g
+ , (b << 4) | b
+ );
+ }
+ }
+
+ /**
+ * Convert to 3 byte values, for raster imaging.
+ * @return byte[RR, GG, BB] e.g. 0x4B3 -> 0x44, 0xBB, 0x33
+ */
+ public byte[] toByteArray() {
+ byte[] ret = new byte[3];
+ int r = (data & 0xF00) >> 8;
+ int g = (data & 0x0F0) >> 4;
+ int b = data & 0x00F;
+
+ ret[0] = (byte) ((r << 4) | r);
+ ret[1] = (byte) ((g << 4) | g);
+ ret[2] = (byte) ((b << 4) | b);
+
+ return ret;
+ }
+
+ /**
+ * Retrieve raw ARGB value
+ * @return 0xARGB
+ */
+ public short getShort() {
+ return data;
+ }
+
+}
diff --git a/src/com/Torvald/ImageFont/GameFontBase.java b/src/com/Torvald/ImageFont/GameFontBase.java
index 9a7754fe7..68b0da141 100644
--- a/src/com/Torvald/ImageFont/GameFontBase.java
+++ b/src/com/Torvald/ImageFont/GameFontBase.java
@@ -15,6 +15,8 @@ public class GameFontBase implements Font {
static SpriteSheet runicSheet;
static SpriteSheet extASheet;
static SpriteSheet extASheetEF;
+ static SpriteSheet kanaSheet;
+ static SpriteSheet cjkPunct;
static final int JUNG_COUNT = 21;
static final int JONG_COUNT = 28;
@@ -24,7 +26,8 @@ public class GameFontBase implements Font {
static final int W_LATIN_WIDE = 9; // width of regular letters, including m
static final int W_LATIN_NARROW = 5; // width of letter f, t, i, l
static final int H = 20;
- static final int H_CJK = 16;
+ static final int H_HANGUL = 16;
+ static final int H_KANA = 20;
static final int SHEET_ASCII_EM = 0;
static final int SHEET_ASCII_EF = 1;
@@ -32,6 +35,8 @@ public class GameFontBase implements Font {
static final int SHEET_RUNIC = 3;
static final int SHEET_EXTA_EM = 4;
static final int SHEET_EXTA_EF = 5;
+ static final int SHEET_KANA = 6;
+ static final int SHEET_CJK_PUNCT = 7;
static SpriteSheet[] sheetKey;
static final Character[] asciiEFList = {
@@ -47,12 +52,20 @@ public class GameFontBase implements Font {
* Runic letters list used for game. The set is
* Younger Futhark + Medieval rune 'e' + Punct + Runic Almanac
*
+ * BEWARE OF SIMILAR-LOOKING RUNES, especially:
+ *
+ * * Algiz ᛉ instead of Maðr ᛘ
+ *
+ * * Short-Twig Hagall ᚽ instead of Runic Letter E ᛂ
+ *
+ * * Runic Letter OE ᚯ instead of Óss ᚬ
+ *
* Examples:
* ᛭ᛋᛁᚴᚱᛁᚦᛦ᛭
* ᛭ᛂᛚᛋᛅ᛭ᛏᚱᚢᛏᚾᛁᚾᚴᚢᚾᛅ᛬ᛅᚱᚾᛅᛏᛅᛚᛋ
*/
static final Character[] runicList = {
- 'ᚠ','ᚢ','ᚦ','ᚯ','ᚱ','ᚴ','ᚼ','ᚾ','ᛁ','ᛅ','ᛋ','ᛏ','ᛒ','ᛘ','ᛚ','ᛦ'
+ 'ᚠ','ᚢ','ᚦ','ᚬ','ᚱ','ᚴ','ᚼ','ᚾ','ᛁ','ᛅ','ᛋ','ᛏ','ᛒ','ᛘ','ᛚ','ᛦ'
,'ᛂ','᛬','᛫','᛭','ᛮ','ᛯ','ᛰ'
};
@@ -90,6 +103,14 @@ public class GameFontBase implements Font {
return (c >= 0x100 && c < 0x180);
}
+ private boolean isKana(char c) {
+ return (c >= 0x3040 && c < 0x3100);
+ }
+
+ private boolean isCJKPunct(char c) {
+ return (c >= 0x3000 && c < 0x3040);
+ }
+
private int asciiEFindexX(char c) {
return (Arrays.asList(asciiEFList).indexOf(c) % 16);
}
@@ -114,6 +135,22 @@ public class GameFontBase implements Font {
return (Arrays.asList(runicList).indexOf(c) / 16);
}
+ private int kanaIndexX(char c) {
+ return (c - 0x3040) % 16;
+ }
+
+ private int kanaIndexY(char c) {
+ return (c - 0x3040) / 16;
+ }
+
+ private int cjkPunctIndexX(char c) {
+ return (c - 0x3000) % 16;
+ }
+
+ private int cjkPunctIndexY(char c) {
+ return (c - 0x3000) / 16;
+ }
+
@Override
public int getWidth(String s) {
int len = 0;
@@ -122,7 +159,7 @@ public class GameFontBase implements Font {
switch (getSheetType(c)) {
case SHEET_ASCII_EF:
len += W_LATIN_NARROW; break;
- case SHEET_HANGUL:
+ case SHEET_HANGUL: case SHEET_KANA: case SHEET_CJK_PUNCT:
len += W_CJK_DRAW; break;
default:
len += W_LATIN_WIDE;
@@ -159,7 +196,7 @@ public class GameFontBase implements Font {
Math.round(x
+ getWidth(s.substring(0, i))
)
- , Math.round((H - H_CJK) + y)
+ , Math.round((H - H_HANGUL) / 2 + y + 1)
, hanPos[0]
, hanPos[1]
);
@@ -200,20 +237,37 @@ public class GameFontBase implements Font {
sheetX = (ch - 0x100) % 16;
sheetY = (ch - 0x100) / 16;
break;
+ case SHEET_KANA:
+ sheetX = kanaIndexX(ch);
+ sheetY = kanaIndexY(ch);
+ break;
+ case SHEET_CJK_PUNCT:
+ sheetX = cjkPunctIndexX(ch);
+ sheetY = cjkPunctIndexY(ch);
+ break;
default:
sheetX = ch % 16;
sheetY = ch / 16;
break;
}
- sheetKey[prevInstance].renderInUse(
- Math.round(x
- + getWidth(s.substring(0, i))
- )
- , Math.round(y)
- , sheetX
- , sheetY
- );
+ try {
+ sheetKey[prevInstance].renderInUse(
+ Math.round(x
+ + getWidth(s.substring(0, i))
+ )
+ , Math.round(y)
+ , sheetX
+ , sheetY
+ );
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ System.out.println("char: '" + ch + "' (" + String.valueOf((int) ch) + ")");
+ System.out.println("sheet: " + prevInstance);
+ System.out.println("sheetX: " + sheetX);
+ System.out.println("sheetY: " + sheetY);
+ e.printStackTrace();
+ }
}
@@ -229,6 +283,8 @@ public class GameFontBase implements Font {
else if (isRunic(c)) return SHEET_RUNIC;
else if (isExtA(c)) return SHEET_EXTA_EM;
else if (isExtAEF(c)) return SHEET_EXTA_EF;
+ else if (isKana(c)) return SHEET_KANA;
+ else if (isCJKPunct(c)) return SHEET_CJK_PUNCT;
else return SHEET_ASCII_EM;
}
diff --git a/src/com/Torvald/ImageFont/GameFontBlack.java b/src/com/Torvald/ImageFont/GameFontBlack.java
index f1b2e847f..c63a83cfb 100644
--- a/src/com/Torvald/ImageFont/GameFontBlack.java
+++ b/src/com/Torvald/ImageFont/GameFontBlack.java
@@ -13,7 +13,7 @@ public class GameFontBlack extends GameFontBase {
hangulSheet = new SpriteSheet(
"./res/graphics/fonts/han_atlas_black.png"
- , W_CJK, H_CJK
+ , W_CJK, H_HANGUL
);
asciiSheet = new SpriteSheet(
"./res/graphics/fonts/ascii_majuscule_black.png"
diff --git a/src/com/Torvald/ImageFont/GameFontWhite.java b/src/com/Torvald/ImageFont/GameFontWhite.java
index 8cefa51d5..b10b4396b 100644
--- a/src/com/Torvald/ImageFont/GameFontWhite.java
+++ b/src/com/Torvald/ImageFont/GameFontWhite.java
@@ -12,7 +12,7 @@ public class GameFontWhite extends GameFontBase {
hangulSheet = new SpriteSheet(
"./res/graphics/fonts/han_atlas.png"
- , W_CJK, H_CJK
+ , W_CJK, H_HANGUL
);
asciiSheet = new SpriteSheet(
"./res/graphics/fonts/ascii_majuscule.png"
@@ -34,6 +34,14 @@ public class GameFontWhite extends GameFontBase {
"./res/graphics/fonts/LatinExtA_ef.png"
, W_LATIN_NARROW, H
);
+ kanaSheet = new SpriteSheet(
+ "./res/graphics/fonts/kana.png"
+ , W_CJK, H_KANA
+ );
+ cjkPunct = new SpriteSheet(
+ "./res/graphics/fonts/cjkpunct.png"
+ , W_CJK, H_KANA
+ );
SpriteSheet[] shk = {
asciiSheet
@@ -42,6 +50,8 @@ public class GameFontWhite extends GameFontBase {
, runicSheet
, extASheet
, extASheetEF
+ , kanaSheet
+ , cjkPunct
};
sheetKey = shk;
}
diff --git a/src/com/Torvald/Rand/HighQualityRandom.java b/src/com/Torvald/Rand/HQRNG.java
similarity index 94%
rename from src/com/Torvald/Rand/HighQualityRandom.java
rename to src/com/Torvald/Rand/HQRNG.java
index 43c392b0d..594bc7d8f 100644
--- a/src/com/Torvald/Rand/HighQualityRandom.java
+++ b/src/com/Torvald/Rand/HQRNG.java
@@ -13,17 +13,17 @@ import java.util.Random;
* @author Numerical Recipes
*/
-public class HighQualityRandom extends Random {
+public class HQRNG extends Random {
//private Lock l = new ReentrantLock();
private long u;
private long v = 4101842887655102017L;
private long w = 1;
- public HighQualityRandom() {
+ public HQRNG() {
this(System.nanoTime());
}
- public HighQualityRandom(long seed) {
+ public HQRNG(long seed) {
//l.lock();
u = seed ^ v;
nextLong();
diff --git a/src/com/Torvald/Terrarum/Actors/ActorWithBody.java b/src/com/Torvald/Terrarum/Actors/ActorWithBody.java
index 070b11bc6..c043eee0c 100644
--- a/src/com/Torvald/Terrarum/Actors/ActorWithBody.java
+++ b/src/com/Torvald/Terrarum/Actors/ActorWithBody.java
@@ -1,6 +1,6 @@
package com.Torvald.Terrarum.Actors;
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
import com.Torvald.Terrarum.MapDrawer.MapDrawer;
import com.Torvald.Terrarum.Terrarum;
import com.Torvald.spriteAnimation.SpriteAnimation;
@@ -35,7 +35,9 @@ public class ActorWithBody implements Actor, Visible, Glowing {
private @NotNull float veloX, veloY;
private final float VELO_HARD_LIMIT = 10000;
- private boolean grounded = false;
+ boolean grounded = false;
+ boolean walledLeft = false;
+ boolean walledRight = false;
SpriteAnimation sprite;
@Nullable SpriteAnimation spriteGlow;
@@ -55,7 +57,8 @@ public class ActorWithBody implements Actor, Visible, Glowing {
private float scale = 1;
private float mass = 1f;
- private static int TSIZE = MapDrawer.TILE_SIZE;
+ private static final int TSIZE = MapDrawer.TILE_SIZE;
+ private static final int AUTO_CLIMB_RATE = TSIZE / 4;
/**
* Gravitational Constant G. Load from GameMap.
@@ -69,6 +72,11 @@ public class ActorWithBody implements Actor, Visible, Glowing {
private float gravitation;
private final float DRAG_COEFF = 1f;
+ private final int CONTACT_AREA_TOP = 0;
+ private final int CONTACT_AREA_RIGHT = 1;
+ private final int CONTACT_AREA_BOTTOM = 2;
+ private final int CONTACT_AREA_LEFT = 3;
+
/**
* A constant to make falling faster so that the game is more playable
*/
@@ -77,10 +85,19 @@ public class ActorWithBody implements Actor, Visible, Glowing {
long referenceID;
public ActorWithBody() {
- referenceID = new HighQualityRandom(0x7E22A211AAL).nextLong();
+ referenceID = new HQRNG(0x7E22A211AAL).nextLong();
actorValue = new ActorValue();
}
+ /**
+ *
+ * @param w
+ * @param h
+ * @param tx +: translate drawn sprite to LEFT.
+ * @param ty +: translate drawn sprite to DOWN.
+ * @see ActorWithBody#drawBody(GameContainer, Graphics)
+ * @see ActorWithBody#drawGlow(GameContainer, Graphics)
+ */
public void setHitboxDimension(int w, int h, int tx, int ty) {
baseHitboxH = h;
baseHitboxW = w;
@@ -131,17 +148,16 @@ public class ActorWithBody implements Actor, Visible, Glowing {
if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT;
// Set 'next' positions to fiddle with
- updateNextHitbox(delta_t);
-
if (!playerNoClip()) {
+ updateNextHitboxY();
updateVerticalPos();
+ updateHitboxY();
+
+ updateNextHitboxX();
updateHorizontalPos();
+ updateHitboxX();
}
- // Apply previous fiddling
- updateHitbox();
-
-
/**
* clamp position
*/
@@ -156,87 +172,6 @@ public class ActorWithBody implements Actor, Visible, Glowing {
}
}
- @Override
- public void drawGlow(GameContainer gc, Graphics g) {
- if (visible && spriteGlow != null) {
- if (!sprite.flippedHorizontal()) {
- spriteGlow.render(g
- , Math.round(hitbox.getPosX() - (hitboxTranslateX * scale))
- , Math.round(hitbox.getPosY() - hitboxTranslateY * scale)
- - (baseSpriteHeight - baseHitboxH) * scale
- + 1
- , scale
- );
- }
- else {
- spriteGlow.render(g
- , Math.round(hitbox.getPosX() - scale)
- , Math.round(hitbox.getPosY() - hitboxTranslateY * scale)
- - (baseSpriteHeight - baseHitboxH) * scale
- + 1
- , scale
- );
- }
- }
- }
-
- @Override
- public void drawBody(GameContainer gc, Graphics g) {
- if (visible) {
- if (!sprite.flippedHorizontal()) {
- sprite.render(g
- , Math.round(hitbox.getPosX() - (hitboxTranslateX * scale))
- , Math.round(hitbox.getPosY() - hitboxTranslateY * scale)
- - (baseSpriteHeight - baseHitboxH) * scale
- + 1
- , scale
- );
- }
- else {
- sprite.render(g
- , Math.round(hitbox.getPosX() - scale)
- , Math.round(hitbox.getPosY() - hitboxTranslateY * scale)
- - (baseSpriteHeight - baseHitboxH) * scale
- + 1
- , scale
- );
- }
- }
- }
-
- @Override
- public void updateGlowSprite(GameContainer gc, int delta_t) {
- if (spriteGlow != null) {
- spriteGlow.update(delta_t);
- }
- }
-
- @Override
- public void updateBodySprite(GameContainer gc, int delta_t) {
- sprite.update(delta_t);
- }
-
- boolean collideBottomAndAdjusted() {
- // noclip off?
- int feetTileX = clampWtile(Math.round((nextHitbox.getPointedX()) / TSIZE));
- int feetTileY = clampHtile(FastMath.floor(nextHitbox.getPointedY() / TSIZE));
-
- if (feetTileX < 0) feetTileX = 0;
- if (feetTileY < 0) feetTileY = 0;
-
- int feetTile = Terrarum.game.map.getTileFromTerrain(feetTileX, feetTileY);
-
- if (feetTile != 0) {
- nextHitbox.setPositionYFromPoint(
- feetTileY * TSIZE
- );
- return true;
- }
- else {
- return false;
- }
- }
-
/**
* Apply gravitation to the every falling body (unless not levitating)
*
@@ -266,37 +201,338 @@ public class ActorWithBody implements Actor, Visible, Glowing {
}
private void updateVerticalPos() {
- if (collideBottomAndAdjusted()) {
+ if (collidedBottomAndAdjusted()) {
grounded = true;
veloY = 0;
}
else {
grounded = false;
}
+
+ if (collidedTopAndAdjusted()) {
+ veloY = 0;
+ }
+ }
+
+ boolean collidedBottomAndAdjusted() {
+ if (getContactArea(CONTACT_AREA_BOTTOM, 0, 1) == 0) {
+ return false;
+ }
+ /**
+ * seemingly adjusted and one pixel below has ground
+ *
+ * seemingly adjusted: adjustHitBottom sets position one pixel above the ground
+ * (stepping on ground in-game look, as the sprite render is one pixel offseted to Y)
+ */
+ else if (getContactArea(CONTACT_AREA_BOTTOM, 0, 1) > 0
+ && getContactArea(CONTACT_AREA_BOTTOM, 0, 0) == 0) {
+ return true;
+ }
+ else {
+ adjustHitBottom();
+ return true;
+ }
+ }
+
+ boolean collidedTopAndAdjusted() {
+ if (getContactArea(CONTACT_AREA_TOP, 0, -1) == 0) {
+ return false;
+ }
+ /**
+ * seemingly adjusted and one pixel below has ground
+ *
+ * seemingly adjusted: adjustHitBottom sets position one pixel above the ground
+ * (stepping on ground in-game look, as the sprite render is one pixel offseted to Y)
+ */
+ else if (getContactArea(CONTACT_AREA_TOP, 0, -1) > 0
+ && getContactArea(CONTACT_AREA_TOP, 0, 0) == 0) {
+ return true;
+ }
+ else {
+ adjustHitTop();
+ return true;
+ }
}
private void updateHorizontalPos() {
-
+ if (collidedRightAndAdjusted()) { // treat as 'event--collided right'
+ veloX = 0;
+ walledRight = true;
+ }
+ else if (collidedLeftAndAdjusted()) { // treat as 'event--collided left'
+ veloX = 0;
+ walledLeft = true;
+ }
+ else {
+ walledRight = false;
+ walledLeft = false;
+ }
}
- private void updateNextHitbox(int delta_t) {
+ boolean collidedRightAndAdjusted() {
+ if (getContactArea(CONTACT_AREA_RIGHT, 1, 0) == 0) {
+ return false;
+ }
+ /**
+ * seemingly adjusted and one pixel below has ground
+ *
+ * seemingly adjusted: adjustHitBottom sets position one pixel above the ground
+ * (stepping on ground in-game look, as the sprite render is one pixel offseted to Y)
+ */
+ else if (getContactArea(CONTACT_AREA_RIGHT, 1, 0) > 0
+ && getContactArea(CONTACT_AREA_RIGHT, 0, 0) == 0) {
+ return true;
+ }
+ else {
+ adjustHitRight();
+ return true;
+ }
+ }
+
+ boolean collidedLeftAndAdjusted() {
+ if (getContactArea(CONTACT_AREA_LEFT, -1, 0) == 0) {
+ return false;
+ }
+ /**
+ * seemingly adjusted and one pixel below has ground
+ *
+ * seemingly adjusted: adjustHitBottom sets position one pixel above the ground
+ * (stepping on ground in-game look, as the sprite render is one pixel offseted to Y)
+ */
+ else if (getContactArea(CONTACT_AREA_LEFT, -1, 0) > 0
+ && getContactArea(CONTACT_AREA_LEFT, 0, 0) == 0) {
+ return true;
+ }
+ else {
+ adjustHitLeft();
+ return true;
+ }
+ }
+
+ private void updateNextHitboxX() {
nextHitbox.set(
hitbox.getPosX() + veloX
+ , hitbox.getPosY()
+ , baseHitboxW * scale
+ , baseHitboxH * scale
+ );
+ }
+
+ private void updateNextHitboxY() {
+ nextHitbox.set(
+ hitbox.getPosX()
, hitbox.getPosY() + veloY
, baseHitboxW * scale
, baseHitboxH * scale
);
}
- private void updateHitbox() {
+ private void updateHitboxX() {
hitbox.set(
nextHitbox.getPosX()
+ , hitbox.getPosY()
+ , baseHitboxW * scale
+ , baseHitboxH * scale
+ );
+ }
+
+ private void updateHitboxY() {
+ hitbox.set(
+ hitbox.getPosX()
, nextHitbox.getPosY()
, baseHitboxW * scale
, baseHitboxH * scale
);
}
+ private void adjustHitBottom() {
+ int tY = 0;
+ int contactArea = getContactArea(CONTACT_AREA_BOTTOM, 0, 0);
+ for (int lim = 0; lim < TSIZE; lim++) {
+ /**
+ * get contact area and move up and get again.
+ * keep track of this value, and some point they will be set as lowest
+ * and become static. The very point where the value first became lowest
+ * is the value what we want.
+ */
+ int newContactArea = getContactArea(CONTACT_AREA_BOTTOM, 0, -lim);
+
+ if (newContactArea < contactArea) {
+ tY = -lim;
+ }
+ contactArea = newContactArea;
+ }
+ nextHitbox.setPositionYFromPoint(FastMath.ceil(nextHitbox.getPointedY() + tY));
+ }
+
+ private void adjustHitTop() {
+ int tY = 0;
+ int contactArea = getContactArea(CONTACT_AREA_TOP, 0, 0);
+ for (int lim = 0; lim < TSIZE; lim++) {
+ /**
+ * get contact area and move up and get again.
+ * keep track of this value, and some point they will be set as lowest
+ * and become static. The very point where the value first became lowest
+ * is the value what we want.
+ */
+ int newContactArea = getContactArea(CONTACT_AREA_TOP, 0, lim);
+
+ if (newContactArea < contactArea) {
+ tY = lim;
+ }
+ contactArea = newContactArea;
+ }
+ nextHitbox.setPositionYFromPoint(FastMath.floor(nextHitbox.getPointedY() + tY));
+ }
+
+ private void adjustHitRight() {
+ int tX = 0;
+ int contactArea = getContactArea(CONTACT_AREA_RIGHT, 0, 0);
+ for (int lim = 0; lim < TSIZE; lim++) {
+ /**
+ * get contact area and move up and get again.
+ * keep track of this value, and some point they will be set as lowest
+ * and become static. The very point where the value first became lowest
+ * is the value what we want.
+ */
+ int newContactArea = getContactArea(CONTACT_AREA_RIGHT, -lim, 0);
+
+ if (newContactArea < contactArea) {
+ tX = -lim;
+ }
+ contactArea = newContactArea;
+ }
+ //nextHitbox.setPositionYFromPoint(nextHitbox.getPointedX() + tX);
+ nextHitbox.set(
+ FastMath.ceil(nextHitbox.getPosX() + tX)
+ , nextHitbox.getPosY()
+ , nextHitbox.getWidth()
+ , nextHitbox.getHeight()
+ );
+ }
+
+ private void adjustHitLeft() {
+ int tX = 0;
+ int contactArea = getContactArea(CONTACT_AREA_LEFT, 0, 0);
+ for (int lim = 0; lim < TSIZE; lim++) {
+ /**
+ * get contact area and move up and get again.
+ * keep track of this value, and some point they will be set as lowest
+ * and become static. The very point where the value first became lowest
+ * is the value what we want.
+ */
+ int newContactArea = getContactArea(CONTACT_AREA_LEFT, lim, 0);
+
+ if (newContactArea < contactArea) {
+ tX = lim;
+ }
+ contactArea = newContactArea;
+ }
+ //nextHitbox.setPositionYFromPoint(nextHitbox.getPointedX() + tX);
+ nextHitbox.set(
+ FastMath.floor(nextHitbox.getPosX() + tX)
+ , nextHitbox.getPosY()
+ , nextHitbox.getWidth()
+ , nextHitbox.getHeight()
+ );
+ }
+
+ private int getContactArea(int side, int translateX, int translateY) {
+ int contactAreaCounter = 0;
+ for (int i = 0
+ ; i < Math.round((side % 2 == 0) ? nextHitbox.getWidth() : nextHitbox.getHeight())
+ ; i++) {
+ // set tile positions
+ int tileX = 0, tileY = 0;
+ if (side == CONTACT_AREA_BOTTOM) {
+ tileX = div16(Math.round(nextHitbox.getHitboxStart().getX()) + i + translateX);
+ tileY = div16(FastMath.floor(nextHitbox.getHitboxEnd().getY()) + translateY);
+ }
+ else if (side == CONTACT_AREA_TOP) {
+ tileX = div16(Math.round(nextHitbox.getHitboxStart().getX()) + i + translateX);
+ tileY = div16(FastMath.ceil(nextHitbox.getHitboxStart().getY()) + translateY);
+ }
+ else if (side == CONTACT_AREA_RIGHT) {
+ tileX = div16(FastMath.floor(nextHitbox.getHitboxEnd().getX()) + translateX);
+ tileY = div16(Math.round(nextHitbox.getHitboxStart().getY()) + i + translateY);
+ }
+ else if (side == CONTACT_AREA_LEFT) {
+ tileX = div16(FastMath.ceil(nextHitbox.getHitboxStart().getX()) + translateX);
+ tileY = div16(Math.round(nextHitbox.getHitboxStart().getY()) + i + translateY);
+ }
+ else {
+ throw new IllegalArgumentException(String.valueOf(side) + ": Wrong side input");
+ }
+
+ // evaluate
+ if (Terrarum.game.map.getTileFromTerrain(tileX, tileY) > 0) {
+ contactAreaCounter += 1;
+ }
+ }
+
+ return contactAreaCounter;
+ }
+
+ @Override
+ public void drawGlow(GameContainer gc, Graphics g) {
+ if (visible && spriteGlow != null) {
+ if (!sprite.flippedHorizontal()) {
+ spriteGlow.render(g
+ , (hitbox.getPosX() - (hitboxTranslateX * scale))
+ , (hitbox.getPosY() + (hitboxTranslateY * scale))
+ - (baseSpriteHeight - baseHitboxH) * scale
+ + 1
+ , scale
+ );
+ }
+ else {
+ spriteGlow.render(g
+ , (hitbox.getPosX() - scale)
+ , (hitbox.getPosY() + (hitboxTranslateY * scale))
+ - (baseSpriteHeight - baseHitboxH) * scale
+ + 1
+ , scale
+ );
+ }
+ }
+ }
+
+ @Override
+ public void drawBody(GameContainer gc, Graphics g) {
+ if (visible) {
+ if (!sprite.flippedHorizontal()) {
+ sprite.render(g
+ , (hitbox.getPosX() - (hitboxTranslateX * scale))
+ , (hitbox.getPosY() + (hitboxTranslateY * scale))
+ - (baseSpriteHeight - baseHitboxH) * scale
+ + 1
+ , scale
+ );
+ }
+ else {
+ sprite.render(g
+ , (hitbox.getPosX() - scale)
+ , (hitbox.getPosY() + (hitboxTranslateY * scale))
+ - (baseSpriteHeight - baseHitboxH) * scale
+ + 1
+ , scale
+ );
+ }
+ }
+ }
+
+ @Override
+ public void updateGlowSprite(GameContainer gc, int delta_t) {
+ if (spriteGlow != null) {
+ spriteGlow.update(delta_t);
+ }
+ }
+
+ @Override
+ public void updateBodySprite(GameContainer gc, int delta_t) {
+ sprite.update(delta_t);
+ }
+
@Override
public long getRefID() {
return referenceID;
@@ -360,12 +596,14 @@ public class ActorWithBody implements Actor, Visible, Glowing {
}
private static int div16(int x) {
- if (x < 0) { throw new IllegalArgumentException("Positive integer only!"); }
+ if (x < 0) { throw new IllegalArgumentException("div16: Positive integer only:"
+ + String.valueOf(x)); }
return (x & 0x7FFF_FFFF) >> 4;
}
private static int mod16(int x) {
- if (x < 0) { throw new IllegalArgumentException("Positive integer only!"); }
+ if (x < 0) { throw new IllegalArgumentException("mod16: Positive integer only:"
+ + String.valueOf(x)); }
return x & 0b1111;
}
@@ -421,6 +659,14 @@ public class ActorWithBody implements Actor, Visible, Glowing {
return grounded;
}
+ public boolean isWalledLeft() {
+ return walledLeft;
+ }
+
+ public boolean isWalledRight() {
+ return walledRight;
+ }
+
public int getBaseHitboxW() {
return baseHitboxW;
}
@@ -452,4 +698,8 @@ public class ActorWithBody implements Actor, Visible, Glowing {
public void setUpdate(boolean update) {
this.update = update;
}
+
+ private int clampMulOfTSize(float v) {
+ return (Math.round(v) / TSIZE) * TSIZE;
+ }
}
diff --git a/src/com/Torvald/Terrarum/Actors/CreatureBuildFactory.java b/src/com/Torvald/Terrarum/Actors/CreatureBuildFactory.java
index e7a778fde..b8bcf94b2 100644
--- a/src/com/Torvald/Terrarum/Actors/CreatureBuildFactory.java
+++ b/src/com/Torvald/Terrarum/Actors/CreatureBuildFactory.java
@@ -1,7 +1,7 @@
package com.Torvald.Terrarum.Actors;
import com.Torvald.Rand.Fudge3;
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.newdawn.slick.SlickException;
@@ -67,7 +67,7 @@ public class CreatureBuildFactory {
for (String s : elemSet) {
float baseValue = jsonObject.get(s).getAsFloat();
// roll fudge dice and get value [-3, 3] as [0, 6]
- int varSelected = new Fudge3().create(new HighQualityRandom()).roll() + 3;
+ int varSelected = new Fudge3().create(new HQRNG()).roll() + 3;
// get multiplier from json. Assuming percentile
int multiplier = jsonObject.get(s + "variable").getAsJsonArray().get(varSelected).getAsInt();
float realValue = baseValue * multiplier / 100f;
diff --git a/src/com/Torvald/Terrarum/Actors/PBFSigrid.java b/src/com/Torvald/Terrarum/Actors/PBFSigrid.java
index 0b06f8238..70a56f1bd 100644
--- a/src/com/Torvald/Terrarum/Actors/PBFSigrid.java
+++ b/src/com/Torvald/Terrarum/Actors/PBFSigrid.java
@@ -52,7 +52,7 @@ public class PBFSigrid {
p.actorValue.set("name", "Sigrid");
- p.setHitboxDimension(20, 47, 7, 0);
+ p.setHitboxDimension(17, 47, 9, 0);
p.inventory = new ActorInventory((int) p.actorValue.get("encumbrance"), true);
diff --git a/src/com/Torvald/Terrarum/Actors/Player.java b/src/com/Torvald/Terrarum/Actors/Player.java
index c135ce69b..2151ab8fe 100644
--- a/src/com/Torvald/Terrarum/Actors/Player.java
+++ b/src/com/Torvald/Terrarum/Actors/Player.java
@@ -1,6 +1,5 @@
package com.Torvald.Terrarum.Actors;
-import com.Torvald.Terrarum.Game;
import com.Torvald.Terrarum.GameControl.EnumKeyFunc;
import com.Torvald.Terrarum.GameControl.KeyMap;
import com.Torvald.Terrarum.Terrarum;
@@ -8,12 +7,16 @@ import com.Torvald.spriteAnimation.SpriteAnimation;
import com.jme3.math.FastMath;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
+import org.lwjgl.input.Controller;
+import org.lwjgl.input.Controllers;
import org.newdawn.slick.*;
+import java.io.Serializable;
+
/**
* Created by minjaesong on 15-12-31.
*/
-public class Player extends ActorWithBody implements Controllable, Pocketed {
+public class Player extends ActorWithBody implements Controllable, Pocketed, Serializable {
@Nullable public Controllable vehicleRiding;
@@ -21,7 +24,7 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
int walkPowerCounter = 0;
private final int WALK_FRAMES_TO_MAX_ACCEL = 6;
- public float readonly_totalX = 0;
+ public float readonly_totalX = 0, readonly_totalY = 0;
boolean jumping = false;
@@ -42,6 +45,9 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
public final long PLAYER_REF_ID = 0x51621D;
+ private final float AXIS_POSMAX = 1.0f;
+ private final int GAMEPAD_JUMP = 5;
+
/**
* Creates new Player instance with empty elements (sprites, actorvalue, etc.).
*
@@ -73,34 +79,74 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
* FastMath.pow(super.getScale(), 3));
}
- private void walkHorizontal(boolean left) {
- readonly_totalX = super.getVeloX()
+ /**
+ *
+ * @param left (even if the game is joypad controlled, you must give valid value)
+ * @param absAxisVal (set AXIS_POSMAX if keyboard controlled)
+ */
+ private void walkHorizontal(boolean left, float absAxisVal) {
+ if ((!super.isWalledLeft() && left) || (!super.isWalledRight() && !left)) {
+ readonly_totalX = super.getVeloX()
+ +
+ actorValue.getAsFloat("accel")
+ * actorValue.getAsFloat("accelmult")
+ * FastMath.sqrt(super.getScale())
+ * applyAccelRealism(walkPowerCounter)
+ * (left ? -1 : 1)
+ * absAxisVal;
+
+ super.setVeloX(readonly_totalX);
+
+ if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) {
+ walkPowerCounter += 1;
+ }
+
+ // Clamp veloX
+ super.setVeloX(
+ absClamp(super.getVeloX()
+ , actorValue.getAsFloat("speed")
+ * actorValue.getAsFloat("speedmult")
+ * FastMath.sqrt(super.getScale())
+ )
+ );
+
+ // Heading flag
+ if (left)
+ walkHeading = LEFT;
+ else
+ walkHeading = RIGHT;
+ }
+ }
+
+ /**
+ *
+ * @param up (even if the game is joypad controlled, you must give valid value)
+ * @param absAxisVal (set AXIS_POSMAX if keyboard controlled)
+ */
+ private void walkVertical(boolean up, float absAxisVal) {
+ readonly_totalY = super.getVeloY()
+
actorValue.getAsFloat("accel")
* actorValue.getAsFloat("accelmult")
* FastMath.sqrt(super.getScale())
* applyAccelRealism(walkPowerCounter)
- * (left ? -1 : 1);
+ * (up ? -1 : 1)
+ * absAxisVal;
- super.setVeloX(readonly_totalX);
+ super.setVeloY(readonly_totalY);
if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) {
walkPowerCounter += 1;
}
// Clamp veloX
- super.setVeloX(
- absClamp(super.getVeloX()
- , actorValue.getAsFloat("speed")
- * actorValue.getAsFloat("speedmult")
- * FastMath.sqrt(super.getScale())
- ));
-
- // Heading flag
- if (left)
- walkHeading = LEFT;
- else
- walkHeading = RIGHT;
+ super.setVeloY(
+ absClamp(super.getVeloY()
+ , actorValue.getAsFloat("speed")
+ * actorValue.getAsFloat("speedmult")
+ * FastMath.sqrt(super.getScale())
+ )
+ );
}
/**
@@ -130,30 +176,6 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
return 0.5f + 0.5f * -FastMath.cos(10 * x / (WALK_FRAMES_TO_MAX_ACCEL * FastMath.PI));
}
- private void walkVertical(boolean up) {
- super.setVeloY(super.getVeloY()
- +
- actorValue.getAsFloat("accel")
- * actorValue.getAsFloat("accelmult")
- * FastMath.sqrt(super.getScale())
- * applyAccelRealism(walkPowerCounter)
- * (up ? -1 : 1)
- );
-
- if (walkPowerCounter < WALK_FRAMES_TO_MAX_ACCEL) {
- walkPowerCounter += 1;
- }
-
- // Clamp veloX
- super.setVeloY(
- absClamp(super.getVeloY()
- , actorValue.getAsFloat("speed")
- * actorValue.getAsFloat("speedmult")
- * FastMath.sqrt(super.getScale())
- )
- );
- }
-
private void walkHStop() {
if (super.getVeloX() > 0) {
super.setVeloX(super.getVeloX()
@@ -232,94 +254,137 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
}
public void processInput(Input input) {
+ Controller gamepad = null;
+ float axisX = 0, axisY = 0, axisRX = 0, axisRY = 0;
+ if (Terrarum.hasController) {
+ gamepad = Controllers.getController(0);
+ axisX = gamepad.getAxisValue(0);
+ axisY = gamepad.getAxisValue(1);
+ axisRX = gamepad.getAxisValue(2);
+ axisRY = gamepad.getAxisValue(3);
+
+ if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0;
+ if (Math.abs(axisY) < Terrarum.CONTROLLER_DEADZONE) axisY = 0;
+ if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0;
+ if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0;
+ }
+
/**
* L-R stop
*/
- // ↑F, ↑S
- if (!isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
- && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
- walkHStop();
- prevHMoveKey = KEY_NULL;
+ if (Terrarum.hasController) {
+ if (axisX == 0) {
+ walkHStop();
+ }
+ }
+ else {
+ // ↑F, ↑S
+ if (!isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
+ walkHStop();
+ prevHMoveKey = KEY_NULL;
+ }
}
/**
* U-D stop
*/
- // ↑E
- // ↑D
- if (isNoClip()
- &&!isFuncDown(input, EnumKeyFunc.MOVE_UP)
- && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
- walkVStop();
- prevVMoveKey = KEY_NULL;
+ if (Terrarum.hasController) {
+ if (axisY == 0) {
+ walkVStop();
+ }
+ }
+ else {
+ // ↑E
+ // ↑D
+ if (isNoClip()
+ && !isFuncDown(input, EnumKeyFunc.MOVE_UP)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
+ walkVStop();
+ prevVMoveKey = KEY_NULL;
+ }
}
/**
* Left/Right movement
*/
- // ↑F, ↓S
- if (isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)
- && !isFuncDown(input, EnumKeyFunc.MOVE_LEFT)) {
- walkHorizontal(false);
- prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT);
+ if (Terrarum.hasController) {
+ if (axisX != 0) {
+ walkHorizontal(axisX < 0, AXIS_POSMAX);
+ }
}
- // ↓F, ↑S
- else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
- && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
- walkHorizontal(true);
- prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT);
- }
- // ↓F, ↓S
- else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
- && isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
- if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) {
- walkHorizontal(false);
+ else {
+ // ↑F, ↓S
+ if (isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_LEFT)) {
+ walkHorizontal(false, AXIS_POSMAX);
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT);
}
- else if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)) {
- walkHorizontal(true);
+ // ↓F, ↑S
+ else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
+ walkHorizontal(true, AXIS_POSMAX);
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT);
}
+ // ↓F, ↓S
+ else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
+ && isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
+ if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) {
+ walkHorizontal(false, AXIS_POSMAX);
+ prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT);
+ }
+ else if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)) {
+ walkHorizontal(true, AXIS_POSMAX);
+ prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT);
+ }
+ }
}
/**
* Up/Down movement
*/
-
if (noClip) {
- // ↑E
- // ↓D
- if (isFuncDown(input, EnumKeyFunc.MOVE_DOWN)
- && !isFuncDown(input, EnumKeyFunc.MOVE_UP)) {
- walkVertical(false);
- prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN);
+ if (Terrarum.hasController) {
+ if (axisY != 0) {
+ walkVertical(axisY > 0, AXIS_POSMAX);
+ }
}
- // ↓E
- // ↑D
- else if (isFuncDown(input, EnumKeyFunc.MOVE_UP)
- && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
- walkVertical(true);
- prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP);
- }
- // ↓E
- // ↓D
- else if (isFuncDown(input, EnumKeyFunc.MOVE_UP)
- && isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
- if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) {
- walkVertical(false);
+ else {
+ // ↑E
+ // ↓D
+ if (isFuncDown(input, EnumKeyFunc.MOVE_DOWN)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_UP)) {
+ walkVertical(false, AXIS_POSMAX);
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN);
}
- else if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)) {
- walkVertical(true);
+ // ↓E
+ // ↑D
+ else if (isFuncDown(input, EnumKeyFunc.MOVE_UP)
+ && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
+ walkVertical(true, AXIS_POSMAX);
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP);
}
+ // ↓E
+ // ↓D
+ else if (isFuncDown(input, EnumKeyFunc.MOVE_UP)
+ && isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
+ if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) {
+ walkVertical(false, AXIS_POSMAX);
+ prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN);
+ }
+ else if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)) {
+ walkVertical(true, AXIS_POSMAX);
+ prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP);
+ }
+ }
}
}
/**
* Jump control
*/
- if (isFuncDown(input, EnumKeyFunc.JUMP)) {
+ if (isFuncDown(input, EnumKeyFunc.JUMP)
+ || (Terrarum.hasController && gamepad.isButtonPressed(GAMEPAD_JUMP))) {
if (!noClip) {
if (super.isGrounded()) {
jumping = true;
@@ -327,7 +392,7 @@ public class Player extends ActorWithBody implements Controllable, Pocketed {
}
}
else {
- walkVertical(true);
+ walkVertical(true, AXIS_POSMAX);
}
}
else {
diff --git a/src/com/Torvald/Terrarum/Actors/PlayerBuildFactory.java b/src/com/Torvald/Terrarum/Actors/PlayerBuildFactory.java
index 20994ec65..29cf6545b 100644
--- a/src/com/Torvald/Terrarum/Actors/PlayerBuildFactory.java
+++ b/src/com/Torvald/Terrarum/Actors/PlayerBuildFactory.java
@@ -1,14 +1,9 @@
package com.Torvald.Terrarum.Actors;
-import com.Torvald.Rand.Fudge3;
-import com.Torvald.Rand.HighQualityRandom;
-import com.google.gson.*;
import org.newdawn.slick.SlickException;
import java.io.IOException;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
/**
* Created by minjaesong on 16-02-03.
diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java b/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java
new file mode 100644
index 000000000..418348a68
--- /dev/null
+++ b/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java
@@ -0,0 +1,34 @@
+package com.Torvald.Terrarum.ConsoleCommand;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+
+/**
+ * Created by minjaesong on 16-02-10.
+ */
+public class CatStdout implements ConsoleCommand {
+ @Override
+ public void execute(String[] args) {
+
+ Echo echo = new Echo();
+
+ if (args.length == 1) {
+ printUsage();
+ return;
+ }
+
+ try {
+ Files.lines(FileSystems.getDefault().getPath(args[1])).forEach(echo::execute);
+ }
+ catch (IOException e) {
+ echo.execute("CatStdout: could not read file -- IOException");
+ }
+
+ }
+
+ @Override
+ public void printUsage() {
+ new Echo().execute("usage: cat 'path/to/text/file");
+ }
+}
diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/CommandDict.java b/src/com/Torvald/Terrarum/ConsoleCommand/CommandDict.java
index 36a4c55a6..67cd466ec 100644
--- a/src/com/Torvald/Terrarum/ConsoleCommand/CommandDict.java
+++ b/src/com/Torvald/Terrarum/ConsoleCommand/CommandDict.java
@@ -25,6 +25,7 @@ public class CommandDict {
dict.put("setlocale", new SetLocale());
dict.put("zoom", new Zoom());
dict.put("teleport", new TeleportPlayer());
+ dict.put("cat", new CatStdout());
}
public static ConsoleCommand getCommand(String commandName) {
diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java b/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java
index 834639613..832634aad 100644
--- a/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java
+++ b/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java
@@ -1,9 +1,7 @@
package com.Torvald.Terrarum.ConsoleCommand;
-import com.Torvald.ColourUtil.Col12;
+import com.Torvald.ColourUtil.Col4096;
import com.Torvald.Terrarum.Terrarum;
-import com.Torvald.Terrarum.Game;
-import org.newdawn.slick.Color;
import javax.imageio.ImageIO;
import java.awt.*;
@@ -51,7 +49,7 @@ public class ExportMap implements ConsoleCommand {
private static final byte WATER = (byte) 239;
private static final byte LAVA = (byte) 255;
- private Hashtable colorTable = new Hashtable<>();
+ private Hashtable colorTable = new Hashtable<>();
@Override
public void execute(String[] args) {
@@ -61,7 +59,7 @@ public class ExportMap implements ConsoleCommand {
mapData = new byte[Terrarum.game.map.width * Terrarum.game.map.height * 3];
for (byte tile : Terrarum.game.map.getLayerTerrain()) {
- byte[] colArray = colorTable.getOrDefault(tile, new Col12(0xFFF))
+ byte[] colArray = colorTable.getOrDefault(tile, new Col4096(0xFFF))
.toByteArray();
for (int i = 0; i < 3; i++) {
@@ -121,34 +119,34 @@ public class ExportMap implements ConsoleCommand {
}
private void buildColorTable() {
- colorTable.put(AIR, new Col12(0xCEF));
- colorTable.put(STONE, new Col12(0x887));
- colorTable.put(DIRT, new Col12(0x763));
- colorTable.put(GRASS, new Col12(0x251));
+ colorTable.put(AIR, new Col4096(0xCEF));
+ colorTable.put(STONE, new Col4096(0x887));
+ colorTable.put(DIRT, new Col4096(0x763));
+ colorTable.put(GRASS, new Col4096(0x251));
- colorTable.put(COPPER, new Col12(0x6A8));
- colorTable.put(IRON, new Col12(0xC75));
- colorTable.put(GOLD, new Col12(0xCB6));
- colorTable.put(ILMENITE, new Col12(0x8AB));
- colorTable.put(AURICHALCUM, new Col12(0xD92));
+ colorTable.put(COPPER, new Col4096(0x6A8));
+ colorTable.put(IRON, new Col4096(0xC75));
+ colorTable.put(GOLD, new Col4096(0xCB6));
+ colorTable.put(ILMENITE, new Col4096(0x8AB));
+ colorTable.put(AURICHALCUM, new Col4096(0xD92));
- colorTable.put(DIAMOND, new Col12(0x9CE));
- colorTable.put(RUBY, new Col12(0xB10));
- colorTable.put(EMERALD, new Col12(0x0B1));
- colorTable.put(SAPPHIRE, new Col12(0x01B));
- colorTable.put(TOPAZ, new Col12(0xC70));
- colorTable.put(AMETHYST, new Col12(0x70C));
+ colorTable.put(DIAMOND, new Col4096(0x9CE));
+ colorTable.put(RUBY, new Col4096(0xB10));
+ colorTable.put(EMERALD, new Col4096(0x0B1));
+ colorTable.put(SAPPHIRE, new Col4096(0x01B));
+ colorTable.put(TOPAZ, new Col4096(0xC70));
+ colorTable.put(AMETHYST, new Col4096(0x70C));
- colorTable.put(WATER, new Col12(0x038));
- colorTable.put(LAVA, new Col12(0xF50));
+ colorTable.put(WATER, new Col4096(0x038));
+ colorTable.put(LAVA, new Col4096(0xF50));
- colorTable.put(SAND, new Col12(0xDCA));
- colorTable.put(GRAVEL, new Col12(0x664));
+ colorTable.put(SAND, new Col4096(0xDCA));
+ colorTable.put(GRAVEL, new Col4096(0x664));
- colorTable.put(ICE_NATURAL, new Col12(0x9AB));
- colorTable.put(ICE_MAGICAL, new Col12(0x7AC));
- colorTable.put(ICE_FRAGILE, new Col12(0x6AF));
- colorTable.put(SNOW, new Col12(0xCDE));
+ colorTable.put(ICE_NATURAL, new Col4096(0x9AB));
+ colorTable.put(ICE_MAGICAL, new Col4096(0x7AC));
+ colorTable.put(ICE_FRAGILE, new Col4096(0x6AF));
+ colorTable.put(SNOW, new Col4096(0xCDE));
}
diff --git a/src/com/Torvald/Terrarum/Game.java b/src/com/Torvald/Terrarum/Game.java
index cf33f6331..c1a7273bd 100644
--- a/src/com/Torvald/Terrarum/Game.java
+++ b/src/com/Torvald/Terrarum/Game.java
@@ -59,7 +59,11 @@ public class Game extends BasicGameState {
private Shader shaderBlurH;
private Shader shaderBlurV;
- public Game() throws SlickException {
+ public Game() throws SlickException { }
+
+ @Override
+ public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws
+ SlickException {
new GameController();
KeyMap.build();
GameController.setKeyMap(new KeyMap());
@@ -83,7 +87,7 @@ public class Game extends BasicGameState {
MapGenerator.attachMap(map);
MapGenerator.setSeed(0x51621D);
- //MapGenerator.setSeed(new HighQualityRandom().nextLong());
+ //MapGenerator.setSeed(new HQRNG().nextLong());
MapGenerator.generateMap();
new CommandDict();
@@ -122,11 +126,6 @@ public class Game extends BasicGameState {
uiContainer.add(msgtest);
}
- @Override
- public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws
- SlickException {
- }
-
public Player getPlayer() {
return player;
}
@@ -136,6 +135,7 @@ public class Game extends BasicGameState {
setAppTitle();
MapDrawer.update(gc, delta_t);
+ MapCamera.update(gc, delta_t);
GameController.processInput(gc.getInput());
@@ -177,10 +177,6 @@ public class Game extends BasicGameState {
@Override
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) {
- // shader12BitCol.setUniformIntVariable("pixelSize", 1);
- // shader12BitCol.startShader();
- // shaderBlurH.startShader();
- // shaderBlurV.startShader();
drawSkybox(g);
@@ -190,37 +186,30 @@ public class Game extends BasicGameState {
, -MapCamera.getCameraY() * screenZoom
);
+ MapCamera.renderBehind(gc, g);
+
actorContainer.forEach(
- actor -> {
- if (actor instanceof Visible) {
- ((Visible) actor).drawBody(gc, g);
- }
- }
+ actor -> { if (actor instanceof Visible) ((Visible) actor).drawBody(gc, g); }
);
actorContainer.forEach(
- actor -> {
- if (actor instanceof Glowing) {
- ((Glowing) actor).drawGlow(gc, g);
- }
- }
+ actor -> { if (actor instanceof Glowing) ((Glowing) actor).drawGlow(gc, g); }
);
+
+ MapCamera.renderFront(gc, g);
MapDrawer.render(gc, g);
- // Slick's MODE_COLOR_MULTIPLY is clearly broken... using GL11
LightmapRenderer.renderLightMap();
- GL11.glEnable(GL11.GL_BLEND);
- GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA);
- // draw lightmap
+ setBlendModeMul();
LightmapRenderer.draw(g);
- // draw environment colour overlay
// MapDrawer.drawEnvOverlay(g);
- GL11.glDisable(GL11.GL_BLEND);
- g.setDrawMode(Graphics.MODE_NORMAL);
+ setBlendModeNormal();
uiContainer.forEach(ui -> ui.render(gc, g));
debugWindow.render(gc, g);
consoleHandler.render(gc, g);
//bulletin.render(gc, g);
+
+ GL11.glEnd();
}
private Color[] getGradientColour(int timeSec) {
@@ -282,4 +271,14 @@ public class Game extends BasicGameState {
GradientFill skyColourFill = new GradientFill(0, 0, colourTable[0], 0, Terrarum.HEIGHT, colourTable[1]);
g.fill(skyBox, skyColourFill);
}
+
+ private void setBlendModeMul() {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ private void setBlendModeNormal() {
+ GL11.glDisable(GL11.GL_BLEND);
+ Terrarum.appgc.getGraphics().setDrawMode(Graphics.MODE_NORMAL);
+ }
}
diff --git a/src/com/Torvald/Terrarum/MISC_FEATURES b/src/com/Torvald/Terrarum/MISC_FEATURES
new file mode 100644
index 000000000..6ce71a3d1
--- /dev/null
+++ b/src/com/Torvald/Terrarum/MISC_FEATURES
@@ -0,0 +1,4 @@
+* Drawing
+
+- Players can create their own décors (hang on wall), dresses.
+- Two looms (3-3-2 colour mode, 4096 colour mode)
\ No newline at end of file
diff --git a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.java b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.java
index 19046a585..dbc444997 100644
--- a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.java
+++ b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.java
@@ -136,24 +136,31 @@ public class MapCamera {
// position - (WH / 2)
cameraX = clamp(
- Math.round(player.pointedPosX() - (renderWidth / 2))
+ Math.round(player.getNextHitbox().getPointedX() - (renderWidth / 2))
, map.width * TSIZE - renderWidth
);
cameraY = clamp(
- Math.round(player.pointedPosY() - (renderHeight / 2))
+ Math.round(player.getNextHitbox().getPointedY() - (renderHeight / 2))
, map.height * TSIZE - renderHeight
);
}
- public static void render(GameContainer gc, Graphics g) {
+ public static void renderBehind(GameContainer gc, Graphics g) {
/**
* render to camera
*/
- drawTiles(WALL);
- drawTiles(TERRAIN);
+ setBlendModeNormal();
+ drawTiles(WALL, false);
+ drawTiles(TERRAIN, false);
}
- private static void drawTiles(int mode) {
+ public static void renderFront(GameContainer gc, Graphics g) {
+ setBlendModeMul();
+ drawTiles(TERRAIN, true);
+ setBlendModeNormal();
+ }
+
+ private static void drawTiles(int mode, boolean drawModeTilesBlendMul) {
int for_y_start = div16(cameraY);
int for_x_start = div16(cameraX);
@@ -222,10 +229,16 @@ public class MapCamera {
int thisTileX = nearbyTilesInfo;
int thisTileY = thisTile;
-
- if (isBlendMul((byte) thisTile)) setBlendModeMul();
- else setBlendModeNormal();
- drawTile(TERRAIN, x, y, thisTileX, thisTileY);
+ if (drawModeTilesBlendMul) {
+ if (isBlendMul((byte) thisTile)) drawTile(TERRAIN, x, y, thisTileX, thisTileY);
+ }
+ else {
+ // currently it draws all the transparent tile and colour mixes
+ // on top of the previously drawn tile
+ // TODO check wether it works as intended when skybox is dark
+ // add instruction "if (!isBlendMul((byte) thisTile))"
+ drawTile(TERRAIN, x, y, thisTileX, thisTileY);
+ }
}
else {
drawTile(mode, x, y, mod16(thisTile), div16(thisTile));
@@ -236,7 +249,6 @@ public class MapCamera {
}
tilesetBook[mode].endUse();
- setBlendModeNormal();
}
private static int getGrassInfo(int x, int y, int from, int to) {
diff --git a/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.java b/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.java
index a683fe3a7..3695710b2 100644
--- a/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.java
+++ b/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.java
@@ -31,11 +31,9 @@ public class MapDrawer {
}
public static void update(GameContainer gc, int delta_t) {
- MapCamera.update(gc, delta_t);
}
public static void render(GameContainer gc, Graphics g) {
- MapCamera.render(gc, g);
}
public static void drawEnvOverlay(Graphics g) {
diff --git a/src/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.java b/src/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.java
index 065163a7c..49fe68071 100644
--- a/src/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.java
+++ b/src/com/Torvald/Terrarum/MapGenerator/FloatingIslandsPreset.java
@@ -1,17 +1,17 @@
package com.Torvald.Terrarum.MapGenerator;
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
public class FloatingIslandsPreset {
public static int presets = 5;
- static int[][] generatePreset(HighQualityRandom random) {
+ static int[][] generatePreset(HQRNG random) {
int index = random.nextInt(presets);
return generatePreset(index, random);
}
- static int[][] generatePreset(int index, HighQualityRandom random){
+ static int[][] generatePreset(int index, HQRNG random){
if (index == 0){
return processPreset(random, FloatingIslePreset01.data, FloatingIslePreset01.w, FloatingIslePreset01.h);
}
@@ -30,7 +30,7 @@ public class FloatingIslandsPreset {
return null;
}
- private static int[][] processPreset(HighQualityRandom random, int[] preset, int w, int h){
+ private static int[][] processPreset(HQRNG random, int[] preset, int w, int h){
int[][] temp = new int[h][w];
int counter = 0;
boolean mirrored = random.nextBoolean();
diff --git a/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.java b/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.java
index eb678bec7..83ff56859 100644
--- a/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.java
+++ b/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.java
@@ -1,6 +1,6 @@
package com.Torvald.Terrarum.MapGenerator;
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
import com.Torvald.Terrarum.GameMap.GameMap;
import com.jme3.math.FastMath;
import com.sun.istack.internal.NotNull;
@@ -8,7 +8,7 @@ import com.sun.istack.internal.NotNull;
public class MapGenerator {
@NotNull private static GameMap map;
- private static HighQualityRandom random;
+ private static HQRNG random;
//private static float[] noiseArray;
@NotNull private static long seed;
@NotNull private static int width;
@@ -93,7 +93,7 @@ public class MapGenerator {
* Generate terrain and override attached map
*/
public static void generateMap() {
- random = new HighQualityRandom(seed);
+ random = new HQRNG(seed);
System.out.println("[MapGenerator] Seed: " + seed);
worldOceanPosition = random.nextBoolean() ? TYPE_OCEAN_LEFT : TYPE_OCEAN_RIGHT;
diff --git a/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise.java b/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise.java
index a78ba6e95..d32ff4cab 100644
--- a/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise.java
+++ b/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise.java
@@ -1,6 +1,6 @@
package com.Torvald.Terrarum.MapGenerator;
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
import com.jme3.math.FastMath;
public class SimplexNoise {
@@ -30,7 +30,7 @@ public class SimplexNoise {
frequencys = new float[numberOfOctaves];
amplitudes = new float[numberOfOctaves];
- HighQualityRandom rnd = new HighQualityRandom(seed);
+ HQRNG rnd = new HQRNG(seed);
for (int i = 0; i < numberOfOctaves; i++) {
octaves[i] = new SimplexNoise_octave(rnd.nextInt());
diff --git a/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.java b/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.java
index 867f556fd..3387c3061 100644
--- a/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.java
+++ b/src/com/Torvald/Terrarum/MapGenerator/SimplexNoise_octave.java
@@ -17,7 +17,7 @@ package com.Torvald.Terrarum.MapGenerator;
*
*/
-import com.Torvald.Rand.HighQualityRandom;
+import com.Torvald.Rand.HQRNG;
public class SimplexNoise_octave { // Simplex noise in 2D, 3D and 4D
@@ -64,7 +64,7 @@ public class SimplexNoise_octave { // Simplex noise in 2D, 3D and 4D
}
//the random for the swaps
- HighQualityRandom rand=new HighQualityRandom(seed);
+ HQRNG rand=new HQRNG(seed);
//the seed determines the swaps that occur between the default order and the order we're actually going to use
for(int i=0;i 0);
+ if (hasController) {
+ for (int c = 0; c < Controllers.getController(0).getAxisCount(); c++) {
+ Controllers.getController(0).setDeadZone(c, CONTROLLER_DEADZONE);
+ }
+ }
+
game = new Game();
addState(game);
}
diff --git a/src/com/Torvald/Terrarum/UserInterface/ConsoleWindow.java b/src/com/Torvald/Terrarum/UserInterface/ConsoleWindow.java
index b5b3e5d3e..e757edb09 100644
--- a/src/com/Torvald/Terrarum/UserInterface/ConsoleWindow.java
+++ b/src/com/Torvald/Terrarum/UserInterface/ConsoleWindow.java
@@ -85,7 +85,7 @@ public class ConsoleWindow implements UICanvas {
else if ((key >= 2 && key <= 13)
|| (key >= 16 && key <= 27)
|| (key >= 30 && key <= 40)
- || (key >= 44 && key <= 52)
+ || (key >= 44 && key <= 53)
|| (commandInputPool.length() > 0 && key == 57)){
commandInputPool.append(c);
inputCursorPos += 1;
diff --git a/src/com/Torvald/spriteAnimation/SpriteAnimation.java b/src/com/Torvald/spriteAnimation/SpriteAnimation.java
index 9a9557734..5cd7ec35e 100644
--- a/src/com/Torvald/spriteAnimation/SpriteAnimation.java
+++ b/src/com/Torvald/spriteAnimation/SpriteAnimation.java
@@ -7,6 +7,7 @@ package com.Torvald.spriteAnimation;
import com.Torvald.Terrarum.Game;
import com.Torvald.Terrarum.Terrarum;
+import com.jme3.math.FastMath;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
@@ -149,10 +150,10 @@ public class SpriteAnimation {
flippedImage.startUse();
flippedImage.drawEmbedded(
- Math.round(posX * Terrarum.game.screenZoom)
- , Math.round(posY * Terrarum.game.screenZoom)
- , width * scale
- , height * scale
+ FastMath.floor(posX * Terrarum.game.screenZoom)
+ , FastMath.floor(posY * Terrarum.game.screenZoom)
+ , FastMath.floor(width * scale)
+ , FastMath.floor(height * scale)
);
flippedImage.endUse();
}
diff --git a/src/com/jme3/math/FastMath.java b/src/com/jme3/math/FastMath.java
index c70529e48..46e1bce8e 100644
--- a/src/com/jme3/math/FastMath.java
+++ b/src/com/jme3/math/FastMath.java
@@ -70,8 +70,6 @@ final public class FastMath {
public static final float DEG_TO_RAD = PI / 180.0f;
/** A value to multiply a radian value by, to convert it to degrees. */
public static final float RAD_TO_DEG = 180.0f / PI;
- /** A precreated random object for random numbers. */
- public static final Random rand = new Random(System.currentTimeMillis());
/**
* Returns true if the number is a power of 2 (2,4,8,16...)
@@ -655,30 +653,6 @@ final public class FastMath {
* (m10 * det12 - m11 * det02 + m12 * det01));
}
- /**
- * Returns a random float between 0 and 1.
- *
- * @return A random float between 0.0f (inclusive) to
- * 1.0f (exclusive).
- */
- public static float nextRandomFloat() {
- return rand.nextFloat();
- }
-
- /**
- * Returns a random float between min and max.
- *
- * @return A random int between min (inclusive) to
- * max (inclusive).
- */
- public static int nextRandomInt(int min, int max) {
- return (int) (nextRandomFloat() * (max - min + 1)) + min;
- }
-
- public static int nextRandomInt() {
- return rand.nextInt();
- }
-
/**
* Converts a point from Spherical coordinates to Cartesian (using positive
* Y as up) and stores the results in the store var.
diff --git a/src/shader/Shader.java b/src/shader/Shader.java
index 584804791..60ef571ce 100755
--- a/src/shader/Shader.java
+++ b/src/shader/Shader.java
@@ -22,43 +22,43 @@ import org.newdawn.slick.util.ResourceLoader;
public class Shader {
public static final int BRIEF = 128;
public static final int MODERATE = 512;
- public static final int VERBOSE = 1024;
+ public static final int VERBOSE = 1024;
private static final int NOT_LOADED = -1;
private static final String ERR_LOCATION =
"Warning: variable %s could not be found. " +
"Ensure the name is spelled correctly\n";
private static int logging = MODERATE;
-
+
private ShaderResourceManager srm;
/**
- * ID of the Shader. A Shader may have programID of
+ * ID of the Shader. A Shader may have programID of
* -1 only before construction is completed, or
* after the Shader is deleted
*/
private int programID = NOT_LOADED;
private Map vars = new HashMap();
-
-
+
+
private Shader(ShaderResourceManager srm,
Collection vertex,
Collection fragment)throws SlickException{
this.srm = srm;
StringBuilder errorMessage = new StringBuilder();
-
+
programID = GL20.glCreateProgram();
-
+
int[] shaderIds = new int[vertex.size() + fragment.size()];
int index = 0;
-
+
//Load Vertex Shaders
- for(String vertShader: vertex){
+ for(String vertShader: vertex){
int vsid = srm.getVertexShaderID(vertShader);
srm.createProgramShaderDependancy(programID, vsid);
-
+
//Add to shader ids array
shaderIds[index] = vsid;
index++;
-
+
//Check for errors with shader
if(!compiledSuccessfully(vsid)){
errorMessage.append("Vertex Shader ");
@@ -67,20 +67,20 @@ public class Shader {
errorMessage.append(getShaderInfoLog(vsid));
errorMessage.append("\n\n");
}
-
+
scanSource(vertShader);
}
-
-
+
+
//Load Fragment Shaders
- for(String fragShader: fragment){
+ for(String fragShader: fragment){
int fsid = srm.getFragementShaderID(fragShader);
srm.createProgramShaderDependancy(programID, fsid);
//Add to shader ids array
shaderIds[index] = fsid;
index++;
-
+
//Check for errors with shader
if(!compiledSuccessfully(fsid)){
errorMessage.append("Fragment Shader ");
@@ -89,10 +89,10 @@ public class Shader {
errorMessage.append(getShaderInfoLog(fsid));
errorMessage.append("\n\n");
}
-
+
scanSource(fragShader);
}
-
+
//Attach shaders to program
for(int i=0; i l2 = new ArrayList();
l2.add(fragmentFileName);
-
+
return new Shader(ShaderResourceManagerImpl.getSRM(),
l1,
l2);
}
-
-
-
+
+
+
/**
* Reverts GL context back to the fixed pixel pipeline.
*/
public static void forceFixedShader(){
GL20.glUseProgram(0);
}
-
-
-
+
+
+
/**
* Sets the number of characters to be returned when printing
* errors. Suggested values are the constants
@@ -159,8 +159,8 @@ public class Shader {
logging = detailLevel;
}
-
-
+
+
/**
* Deletes this shader and unloads all free resources.
* TODO should this be called from finalise(), or is
@@ -170,9 +170,9 @@ public class Shader {
srm.removeProgram(programID);
programID = NOT_LOADED;
}
-
-
-
+
+
+
/**
* Returns true if this Shader has been deleted.
* @return true if this Shader has been deleted.
@@ -180,9 +180,9 @@ public class Shader {
public boolean isDeleted(){
return programID == NOT_LOADED;
}
-
-
-
+
+
+
/**
* Activates the shader.
*/
@@ -194,10 +194,10 @@ public class Shader {
forceFixedShader(); //Not sure why this is necessary but it is.
GL20.glUseProgram(programID);
}
-
-
-
-//UNIFORM SETTERS
+
+
+
+//UNIFORM SETTERS
/**
* Sets the value of the uniform integer Variable name.
* @param name the variable to set.
@@ -206,28 +206,28 @@ public class Shader {
public Shader setUniformIntVariable(String name, int value){
return setUniformIntVariable(name, new int[]{value});
}
-
-
-
+
+
+
public Shader setUniformIntVariable(String name, int v0, int v1){
return setUniformIntVariable(name, new int[]{v0, v1});
}
-
-
-
+
+
+
public Shader setUniformIntVariable(String name,
int v0, int v1, int v2){
return setUniformIntVariable(name, new int[]{v0, v1, v2});
}
-
-
-
+
+
+
public Shader setUniformIntVariable(String name,
int v0, int v1, int v2, int v3){
return setUniformIntVariable(name, new int[]{v0, v1, v2, v3});
}
-
-
+
+
public Shader setUniformIntVariable(String name, int[] values){
ShaderVariable var = vars.get(name);
if(var==null){
@@ -238,8 +238,8 @@ public class Shader {
return this;
}
-
-
+
+
/**
* Sets the value of the uniform integer Variable
* name.
@@ -249,31 +249,31 @@ public class Shader {
public Shader setUniformFloatVariable(String name, float value){
return setUniformFloatVariable(name, new float[]{value});
}
-
-
-
+
+
+
public Shader setUniformFloatVariable(String name,
float v0, float v1){
return setUniformFloatVariable(name, new float[]{v0, v1});
}
-
-
-
+
+
+
public Shader setUniformFloatVariable(String name,
float v0, float v1, float v2){
return setUniformFloatVariable(name, new float[]{v0, v1, v2});
}
-
-
-
+
+
+
public Shader setUniformFloatVariable(String name,
float v0, float v1,
float v2, float v3){
return setUniformFloatVariable(name, new float[]{v0, v1, v2, v3});
}
-
-
-
+
+
+
public Shader setUniformFloatVariable(String name, float[] values){
ShaderVariable var = vars.get(name);
if(var==null){
@@ -283,9 +283,9 @@ public class Shader {
}
return this;
}
-
-
-
+
+
+
//TODO implement using ShaderVariable
//TODO Test
public Shader setUniformMatrix(String name,
@@ -293,7 +293,7 @@ public class Shader {
float[][] matrix){
//Convert matrix format
FloatBuffer matBuffer = matrixPrepare(matrix);
-
+
//Get uniform location
int location = GL20.glGetUniformLocation(programID, name);
printError(name);
@@ -307,12 +307,12 @@ public class Shader {
case 4: GL20.glUniformMatrix4(location, transpose, matBuffer);
break;
}
-
+
return this;
}
-
-
-
+
+
+
private FloatBuffer matrixPrepare(float[][] matrix){
//Check argument validity
if(matrix==null){
@@ -327,7 +327,7 @@ public class Shader {
throw new IllegalArgumentException("The matrix must have an equal number of rows and columns.");
}
float[] unrolled = new float[row*col];
-
+
for(int i=0;i
* @param shaderID
@@ -355,8 +355,8 @@ public class Shader {
return GL20.glGetShader(shaderID, GL20.GL_COMPILE_STATUS)==GL11.GL_TRUE;
}
-
-
+
+
/**
* Returns true if the shader program linked successfully.
* @return true if the shader program linked successfully.
@@ -366,15 +366,15 @@ public class Shader {
return true;
// return GL20.glGetShader(programID, GL20.GL_LINK_STATUS)==GL11.GL_TRUE;
}
-
-
-
+
+
+
private String getShaderInfoLog(int shaderID){
return GL20.glGetShaderInfoLog(shaderID, logging).trim();
}
-
-
-
+
+
+
private String getProgramInfoLog(){
return GL20.glGetProgramInfoLog(programID, logging).trim();
}