Compare commits

..

322 Commits

Author SHA1 Message Date
Nut.andor
f9d1dbdbae feygard_1 with hash bug 2023-07-29 02:12:35 +02:00
Nut.andor
de59d8de8d Revert "worldmap bug check"
This reverts commit 718886ba3a.
2023-06-25 18:43:12 +02:00
Nut.andor
718886ba3a worldmap bug check 2023-06-25 13:27:09 +02:00
Nut.andor
cc123f76d6 whatsnew 2023-05-21 20:12:38 +02:00
Nut.andor
a6ad03c534 next version 8.7
(the former 8.7 version was renamed to 8.6.1)
2023-05-21 19:50:13 +02:00
Nut.andor
45491871e6 version 2023-05-21 18:17:44 +02:00
Nut.andor
8988f37896 potc 2023-05-21 10:33:03 +02:00
Nut.andor
09b4324873 Merge branch 'v0.8.7' 2023-05-21 10:27:32 +02:00
Nut.andor
a5a2764cb4 whatsnew 2023-05-21 10:26:44 +02:00
Nut.andor
6de4d0c374 Merge remote-tracking branch 'hosted.weblate/master' 2023-05-21 10:05:40 +02:00
Nut.andor
48c33d766b fix quest "More rats!" 2023-05-21 10:03:23 +02:00
Nut Andor
22493ee0e9 Translated using Weblate (German)
Currently translated at 86.9% (14148 of 16267 strings)
2023-05-21 10:00:28 +02:00
Nut Andor
8afc3133c6 Translated using Weblate (German)
Currently translated at 99.8% (611 of 612 strings)
2023-05-21 10:00:24 +02:00
Jiri Zizkin Zizka
d0cfa29929 Translated using Weblate (Czech)
Currently translated at 88.2% (14358 of 16267 strings)
2023-05-19 04:13:15 +02:00
Ömer Faruk Çakmak
6a51d462d7 Translated using Weblate (Turkish)
Currently translated at 33.7% (5483 of 16267 strings)
2023-05-18 21:54:14 +02:00
Jiri Zizkin Zizka
4f7cc4942c Translated using Weblate (Czech)
Currently translated at 88.1% (14336 of 16267 strings)
2023-05-15 21:55:38 +02:00
Nut.andor
6631e01b64 next version 8.7 2023-05-14 23:14:04 +02:00
Nut.andor
133dffe330 whatsnew 2023-05-13 22:22:26 +02:00
Nut.andor
6e5d17173f potc 2023-05-13 22:13:10 +02:00
Nut.andor
7463d15159 Merge branch 'v0.8.6' 2023-05-13 22:07:16 +02:00
Nut.andor
beff0f1b71 Merge remote-tracking branch 'hosted.weblate/master' 2023-05-13 22:01:01 +02:00
Nut.andor
867ed36419 Ratdom bugfix content 2023-05-13 21:55:06 +02:00
Joan Josep
387c1e126f Translated using Weblate (Catalan)
Currently translated at 100.0% (612 of 612 strings)
2023-05-13 21:49:32 +02:00
Joan Josep
c9d7cda233 Translated using Weblate (Catalan)
Currently translated at 15.4% (2515 of 16264 strings)
2023-05-13 21:49:31 +02:00
ilya
b75521da59 Translated using Weblate (Russian)
Currently translated at 95.4% (15532 of 16264 strings)
2023-05-12 10:54:34 +02:00
aircqsj
5f9ee8a410 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (612 of 612 strings)
2023-05-11 08:51:18 +02:00
aircqsj
296c3b453c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (16264 of 16264 strings)
2023-05-11 08:51:18 +02:00
aircqsj
6e2da63308 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (16262 of 16264 strings)
2023-05-09 17:53:16 +02:00
ilya
445cd9fe8e Translated using Weblate (Russian)
Currently translated at 95.2% (15496 of 16264 strings)
2023-05-09 17:52:52 +02:00
Erick Ferraz Vieira
a0cc567694 Translated using Weblate (Portuguese (Brazil))
Currently translated at 87.2% (14191 of 16264 strings)
2023-05-09 17:52:48 +02:00
Erick Ferraz Vieira
70d084fba7 Translated using Weblate (Portuguese)
Currently translated at 71.4% (11618 of 16264 strings)
2023-05-09 17:52:45 +02:00
Erick Ferraz Vieira
5236aa0bf9 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (612 of 612 strings)
2023-05-09 17:52:42 +02:00
Nut.andor
0eccb511db next version 2023-05-06 03:07:07 +02:00
Kristoffer Grundström
88c17db72b Translated using Weblate (Swedish)
Currently translated at 4.2% (690 of 16264 strings)
2023-05-03 01:48:24 +02:00
ilya
098fb95653 Translated using Weblate (Russian)
Currently translated at 93.1% (15146 of 16264 strings)
2023-05-03 01:48:21 +02:00
ilya
21d6bb7b7d Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2023-05-03 01:48:18 +02:00
Daniel Stasiak
ce91c5c7c8 Translated using Weblate (Polish)
Currently translated at 100.0% (612 of 612 strings)
2023-05-03 01:48:17 +02:00
Nut.andor
613ab9101e postfixes 2023-05-02 22:26:35 +02:00
Nut.andor
3fbc7cf65f authors + translation% 2023-05-01 20:57:16 +02:00
Nut.andor
dc18289d18 POTC 2023-05-01 03:03:36 +02:00
Nut.andor
6473e231e4 Mikhail basket 2023-05-01 02:56:49 +02:00
Nut.andor
33a61b7a57 Merge branch 'v0.8.5' 2023-05-01 02:09:07 +02:00
Nut.andor
c070a39f7c Ratdom content 2023-05-01 02:00:00 +02:00
Nut.andor
995ec0f697 active devs 2023-05-01 01:58:18 +02:00
Nut.andor
6cba6872c9 version name 2023-05-01 01:17:20 +02:00
Nut.andor
8812f664e7 authors 2023-05-01 01:15:09 +02:00
Nut.andor
d9113b2dab Merge branch 'master' into v0.8.5 2023-05-01 01:03:25 +02:00
Nut.andor
ad0025ba03 Merge remote-tracking branch 'hosted.weblate/master' 2023-05-01 00:56:15 +02:00
Nut.andor
984aa17cc0 Merge branch 'development' into v0.8.5 2023-05-01 00:45:33 +02:00
Seven
4cad05ce6b Translated using Weblate (Spanish (Argentina))
Currently translated at 0.3% (49 of 15108 strings)
2023-04-29 05:05:40 +02:00
Jiri Zizkin Zizka
197ab946be Translated using Weblate (Czech)
Currently translated at 94.5% (14291 of 15109 strings)
2023-04-29 05:05:37 +02:00
Daniel Stasiak
e4cdbc1840 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-29 05:05:34 +02:00
Seven
04f00553ae Translated using Weblate (Spanish)
Currently translated at 84.4% (12763 of 15109 strings)
2023-04-29 05:05:30 +02:00
Daniel Stasiak
0c02902ceb Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-26 11:24:53 +02:00
Seven
aba93fb15b Translated using Weblate (Spanish)
Currently translated at 84.3% (12740 of 15109 strings)
2023-04-26 11:24:50 +02:00
Seven
1c8330b99a Translated using Weblate (Spanish)
Currently translated at 100.0% (610 of 610 strings)
2023-04-25 19:50:01 +02:00
Seven
a8de7c2860 Translated using Weblate (Spanish)
Currently translated at 84.2% (12727 of 15109 strings)
2023-04-25 19:50:00 +02:00
Seven
4ca8bbfc12 Translated using Weblate (Spanish)
Currently translated at 84.0% (12700 of 15109 strings)
2023-04-25 18:53:44 +02:00
Daniel Stasiak
a5c004e4d4 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-25 18:19:25 +02:00
Seven
e957e409e0 Translated using Weblate (Spanish)
Currently translated at 83.9% (12684 of 15109 strings)
2023-04-25 18:19:21 +02:00
Jiri Zizkin Zizka
70d6340c11 Translated using Weblate (Czech)
Currently translated at 94.5% (14280 of 15109 strings)
2023-04-22 22:53:01 +02:00
Jiri Zizkin Zizka
bbbb69b175 Translated using Weblate (Czech)
Currently translated at 94.4% (14273 of 15109 strings)
2023-04-21 20:37:11 +02:00
ilya
4d5b7d8667 Translated using Weblate (Russian)
Currently translated at 100.0% (15109 of 15109 strings)
2023-04-21 20:37:08 +02:00
Daniel Stasiak
43da08f57d Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-21 20:37:04 +02:00
Jiri Zizkin Zizka
7b97367bdd Translated using Weblate (Czech)
Currently translated at 94.4% (14272 of 15109 strings)
2023-04-19 21:55:23 +02:00
Daniel Stasiak
e6fb647b99 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-19 21:55:21 +02:00
Daniel Stasiak
5e4d7aba18 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-18 10:35:09 +02:00
Daniel Stasiak
a96086b9af Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-04-17 21:14:23 +02:00
Joan Josep
0566cf899c Translated using Weblate (Catalan)
Currently translated at 100.0% (610 of 610 strings)
2023-04-17 12:49:15 +02:00
Jiri Zizkin Zizka
c8e87fb3d0 Translated using Weblate (Czech)
Currently translated at 94.4% (14265 of 15109 strings)
2023-04-17 12:49:14 +02:00
Nut.andor
0a56a0ba86 Credits for external products 2023-04-16 19:58:58 +02:00
Nut.andor
026ccde2ff Credits for external products 2023-04-16 10:33:28 +02:00
Nut.andor
7813994b81 Release Notes 2023-04-16 09:52:04 +02:00
Nut.andor
d3b070844f set high quality filters default to off 2023-04-16 09:18:45 +02:00
Emre Kaynak
7a879f99b1 Translated using Weblate (Turkish)
Currently translated at 97.5% (595 of 610 strings)
2023-04-16 06:51:16 +02:00
Jiri Zizkin Zizka
e810cdb3cb Translated using Weblate (Czech)
Currently translated at 94.3% (14257 of 15109 strings)
2023-04-16 06:51:15 +02:00
Emre Kaynak
398be07c31 Translated using Weblate (Turkish)
Currently translated at 36.1% (5455 of 15109 strings)
2023-04-16 06:51:13 +02:00
sefa mert katiç
6db4c7bb3c Translated using Weblate (Turkish)
Currently translated at 36.0% (5449 of 15109 strings)
2023-04-14 23:53:02 +02:00
Sarah Chiandotto
c402824641 Translated using Weblate (Italian)
Currently translated at 83.4% (12602 of 15109 strings)
2023-04-14 23:53:00 +02:00
Martin
abc020e8f5 Translated using Weblate (German)
Currently translated at 93.6% (14148 of 15109 strings)
2023-04-14 23:52:57 +02:00
sefa mert katiç
82caf260ce Translated using Weblate (Turkish)
Currently translated at 35.8% (5417 of 15109 strings)
2023-04-12 00:53:21 +02:00
Renald Afrenzia
cbcf5ff8ca Translated using Weblate (Indonesian)
Currently translated at 96.0% (586 of 610 strings)
2023-04-11 01:47:48 +02:00
Jiri Zizkin Zizka
39d07bf8a8 Translated using Weblate (Czech)
Currently translated at 94.2% (14245 of 15109 strings)
2023-04-11 01:47:47 +02:00
Lucas Araujo
93174f0d65 Translated using Weblate (Portuguese (Brazil))
Currently translated at 93.7% (14166 of 15109 strings)
2023-04-09 12:53:09 +02:00
Joan Josep
6afbeb9a2a Translated using Weblate (Catalan)
Currently translated at 100.0% (610 of 610 strings)
2023-04-08 11:52:57 +02:00
Lucas Araujo
a7cbd644f3 Translated using Weblate (Portuguese (Brazil))
Currently translated at 93.7% (14164 of 15109 strings)
2023-04-08 11:52:56 +02:00
Joan Josep
f674aff07c Translated using Weblate (Catalan)
Currently translated at 100.0% (610 of 610 strings)
2023-04-07 20:53:14 +02:00
Joan Josep
07b89a288c Translated using Weblate (Catalan)
Currently translated at 16.5% (2493 of 15109 strings)
2023-04-07 20:53:12 +02:00
Joan Josep
0264c418ca Translated using Weblate (Catalan)
Currently translated at 100.0% (610 of 610 strings)
2023-04-05 20:53:10 +02:00
Jiri Zizkin Zizka
494b9c47cc Translated using Weblate (Czech)
Currently translated at 94.1% (14225 of 15109 strings)
2023-04-05 20:53:09 +02:00
Pablo Jeldres
6ff6c6dd6c Translated using Weblate (Spanish)
Currently translated at 83.8% (12670 of 15109 strings)
2023-04-05 20:53:06 +02:00
Jiri Zizkin Zizka
00ab587265 Translated using Weblate (Czech)
Currently translated at 94.1% (14219 of 15109 strings)
2023-04-03 20:41:57 +02:00
Hong Quan
67fa480805 Translated using Weblate (Vietnamese)
Currently translated at 12.4% (76 of 610 strings)
2023-04-02 17:41:39 +02:00
Lucas Araujo
91db56e7a7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 93.7% (14164 of 15109 strings)
2023-04-02 17:41:38 +02:00
Cicy Chen
36d52bedad Added translation using Weblate (Chinese (Literary)) 2023-03-31 06:27:20 +02:00
Hong Quan
c36b676720 Translated using Weblate (Vietnamese)
Currently translated at 1.4% (9 of 610 strings)
2023-03-29 15:40:40 +02:00
Lustheart Faezeiros
5e0a999249 Translated using Weblate (Thai)
Currently translated at 12.7% (78 of 610 strings)
2023-03-29 15:40:40 +02:00
Jiri Zizkin Zizka
8fff4aff60 Translated using Weblate (Czech)
Currently translated at 94.1% (14218 of 15109 strings)
2023-03-29 15:40:39 +02:00
Lustheart Faezeiros
8c5344ff37 Translated using Weblate (Thai)
Currently translated at 1.2% (195 of 15109 strings)
2023-03-29 15:40:36 +02:00
ssantos
91e49b6c4a Translated using Weblate (Portuguese)
Currently translated at 76.8% (11618 of 15109 strings)
2023-03-29 15:40:34 +02:00
Hong Quan
52cfb37b21 Added translation using Weblate (Vietnamese) 2023-03-27 16:12:56 +02:00
DragonChen TW
87886f08bb Translated using Weblate (Chinese (Traditional))
Currently translated at 6.6% (998 of 15109 strings)
2023-03-26 11:32:21 +02:00
Jiri Zizkin Zizka
a31d7f9589 Translated using Weblate (Czech)
Currently translated at 93.9% (14198 of 15109 strings)
2023-03-26 11:32:19 +02:00
DragonChen TW
5600957f32 Translated using Weblate (Chinese (Traditional))
Currently translated at 6.5% (996 of 15109 strings)
2023-03-25 11:39:22 +01:00
ilya
d6840a83c9 Translated using Weblate (Russian)
Currently translated at 100.0% (610 of 610 strings)
2023-03-25 11:39:20 +01:00
DragonChen TW
06fdd39648 Translated using Weblate (Chinese (Traditional))
Currently translated at 6.5% (990 of 15109 strings)
2023-03-23 22:42:13 +01:00
ilya
b5763e7f76 Translated using Weblate (Russian)
Currently translated at 100.0% (610 of 610 strings)
2023-03-23 22:42:10 +01:00
DragonChen TW
75f01f20b9 Translated using Weblate (Chinese (Traditional))
Currently translated at 6.4% (979 of 15109 strings)
2023-03-22 14:12:10 +01:00
Hong Quan
dd366ab69e Translated using Weblate (Vietnamese)
Currently translated at 0.1% (3 of 15108 strings)
2023-03-21 21:24:23 +01:00
DragonChen TW
6ab443ec2c Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (610 of 610 strings)
2023-03-21 21:24:21 +01:00
DragonChen TW
e0056cbf5c Translated using Weblate (Chinese (Traditional))
Currently translated at 6.4% (978 of 15109 strings)
2023-03-21 21:24:20 +01:00
ilya
9f9397e1f3 Translated using Weblate (Russian)
Currently translated at 100.0% (610 of 610 strings)
2023-03-21 21:24:18 +01:00
Hong Quan
d5a43cc7e1 Added translation using Weblate (Vietnamese) 2023-03-20 17:34:05 +01:00
DragonChen TW
408d8aa8b8 Translated using Weblate (Chinese (Traditional))
Currently translated at 97.5% (595 of 610 strings)
2023-03-19 08:40:41 +01:00
DragonChen TW
1e663069e8 Translated using Weblate (Chinese (Traditional))
Currently translated at 6.4% (977 of 15109 strings)
2023-03-19 08:40:40 +01:00
Nut.andor
dbcec1a199 James' PR 54 to master - redirected to branch development
Changed XP death penalty to 20%
Give the player 9 BC by default
2023-03-18 18:53:53 +01:00
Noza
04b4193548 Translated using Weblate (Indonesian)
Currently translated at 17.0% (2580 of 15109 strings)
2023-03-14 19:44:12 +01:00
Jiri Zizkin Zizka
058803184f Translated using Weblate (Czech)
Currently translated at 93.7% (14170 of 15109 strings)
2023-03-10 22:41:53 +01:00
Jiri Zizkin Zizka
5b5912c5bc Translated using Weblate (Czech)
Currently translated at 93.7% (14170 of 15109 strings)
2023-03-09 21:42:07 +01:00
Lacrom
759e632c07 Translated using Weblate (French)
Currently translated at 84.3% (12739 of 15109 strings)
2023-03-08 16:42:04 +01:00
Johny The Pvp God
6e311ecb64 Translated using Weblate (Romanian)
Currently translated at 56.2% (343 of 610 strings)
2023-03-07 00:41:35 +01:00
Jiri Zizkin Zizka
b480fd9173 Translated using Weblate (Czech)
Currently translated at 93.7% (14170 of 15109 strings)
2023-03-07 00:41:35 +01:00
Nut.andor
226459ddb8 skill improve text clarified 2023-03-05 18:05:46 +01:00
BE Kharel
92de033bc8 Translated using Weblate (Arabic)
Currently translated at 9.6% (1459 of 15108 strings)
2023-03-04 11:41:54 +01:00
BE Kharel
faf0dd061c Translated using Weblate (Bulgarian)
Currently translated at 0.5% (89 of 15109 strings)
2023-03-04 11:41:52 +01:00
Jiri Zizkin Zizka
9eaf9ea2ed Translated using Weblate (Czech)
Currently translated at 93.7% (14168 of 15109 strings)
2023-03-04 11:41:50 +01:00
ilya
00c4f77251 Translated using Weblate (Russian)
Currently translated at 100.0% (15109 of 15109 strings)
2023-03-04 11:41:47 +01:00
Nut.andor
96ef9eedbb Content format reference 2023-02-26 01:35:28 +01:00
Nut.andor
a5d94c03e2 Migration of links to git repo AndorsTrailRelease 2023-02-26 01:34:35 +01:00
Nut.andor
9d15d380a3 Migration of links to git repo AndorsTrailRelease 2023-02-26 01:27:10 +01:00
Nut.andor
bff780c837 reformat for better reading 2023-02-26 01:11:40 +01:00
Nut.andor
0c493952c8 Migration of links to git repo AndorsTrailRelease 2023-02-25 23:47:10 +01:00
Jiri Zizkin Zizka
a1f6e1d29c Translated using Weblate (Czech)
Currently translated at 93.5% (14135 of 15109 strings)
2023-02-25 05:40:05 +01:00
aircqsj
fc71f43755 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (15105 of 15109 strings)
2023-02-25 05:40:02 +01:00
Jiri Zizkin Zizka
16afcf4886 Translated using Weblate (Czech)
Currently translated at 93.4% (14114 of 15109 strings)
2023-02-23 02:46:02 +01:00
Daniel Stasiak
b64a3c2109 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-23 02:45:59 +01:00
Casey Malessa
5c0dc66183 Translated using Weblate (Japanese)
Currently translated at 95.4% (582 of 610 strings)
2023-02-23 02:45:56 +01:00
Nut.andor
3047f653bd prep beta 2023-02-21 21:57:48 +01:00
Nut.andor
393a478d13 prep beta 2023-02-21 21:31:14 +01:00
Michael Bæk
560cb326f9 Added translation using Weblate (Danish) 2023-02-20 20:45:04 +01:00
Jiri Zizkin Zizka
3fe2d7260f Translated using Weblate (Czech)
Currently translated at 93.1% (14074 of 15109 strings)
2023-02-20 20:41:50 +01:00
Jiri Zizkin Zizka
2cd4bc7ee5 Translated using Weblate (Czech)
Currently translated at 92.6% (13997 of 15109 strings)
2023-02-15 23:40:12 +01:00
Daniel Stasiak
19468b591d Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-15 23:40:09 +01:00
ssantos
903117d32f Translated using Weblate (Portuguese)
Currently translated at 76.4% (11555 of 15109 strings)
2023-02-12 16:40:07 +01:00
Jiri Zizkin Zizka
f5bfc98c62 Translated using Weblate (Czech)
Currently translated at 92.6% (13995 of 15109 strings)
2023-02-10 11:39:33 +01:00
Daniel Stasiak
3274feb1e9 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-10 11:39:30 +01:00
Daniel Stasiak
392b4d8577 Translated using Weblate (Polish)
Currently translated at 100.0% (610 of 610 strings)
2023-02-10 11:39:28 +01:00
Yan Chen
92e4afde4b Translated using Weblate (Esperanto)
Currently translated at 17.5% (107 of 610 strings)
2023-02-08 23:40:01 +01:00
Jiri Zizkin Zizka
0c7724fe33 Translated using Weblate (Czech)
Currently translated at 100.0% (610 of 610 strings)
2023-02-08 23:40:00 +01:00
Jiri Zizkin Zizka
ca5be34fc2 Translated using Weblate (Czech)
Currently translated at 92.5% (13986 of 15109 strings)
2023-02-08 23:40:00 +01:00
Daniel Stasiak
28c3c7a0ec Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-08 23:39:57 +01:00
Daniel Stasiak
7f39cf1a6f Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-07 15:40:44 +01:00
gallegonovato
365839571a Translated using Weblate (Spanish)
Currently translated at 100.0% (610 of 610 strings)
2023-02-04 20:39:45 +01:00
Daniel Stasiak
5c3a04ca77 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-04 20:39:45 +01:00
Nut.andor
758a580063 changed png 2023-02-04 01:28:09 +01:00
Daniel Stasiak
ad5dbc9f9d Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-03 12:00:45 +01:00
Casey Malessa
4a86680928 Translated using Weblate (Japanese)
Currently translated at 92.2% (13933 of 15109 strings)
2023-02-03 12:00:42 +01:00
ilya
ece63cf442 Translated using Weblate (Russian)
Currently translated at 100.0% (15109 of 15109 strings)
2023-02-01 22:45:44 +01:00
Daniel Stasiak
b487140a1b Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-02-01 22:45:42 +01:00
Casey Malessa
ad72bf8895 Translated using Weblate (Japanese)
Currently translated at 92.1% (13928 of 15109 strings)
2023-02-01 22:45:40 +01:00
Nut.andor
5919c429d2 Next version 2023-01-31 22:14:49 +01:00
Nut.andor
0b6580e7c9 whatsNew 69 v0.8.4.1 2023-01-31 21:14:03 +01:00
Nut.andor
6efb2b3860 unneeded files bloats the apk 2023-01-31 21:14:03 +01:00
ilya
7ae084073f Translated using Weblate (Russian)
Currently translated at 100.0% (15109 of 15109 strings)
2023-01-31 19:42:48 +01:00
Daniel Stasiak
36df0b1732 Translated using Weblate (Polish)
Currently translated at 91.8% (13884 of 15109 strings)
2023-01-31 19:42:45 +01:00
ilya
b8fb100bd5 Translated using Weblate (Russian)
Currently translated at 100.0% (610 of 610 strings)
2023-01-31 19:42:44 +01:00
Nut.andor
82b904d176 target 31 needed for Google Play + export 2023-01-30 22:04:10 +01:00
Nut.andor
111aca868c hotfix 2023-01-29 22:40:51 +01:00
Nut.andor
2171c16d47 whatsNew 2023-01-29 18:38:37 +01:00
Nut.andor
acd4d84783 potc 2023-01-29 18:25:36 +01:00
Nut.andor
cc25cc97f1 Translations 2023-01-29 18:10:15 +01:00
Nut.andor
93ecebc448 Merge branch 'V0.8.4'
# Conflicts:
#	AndorsTrail/app/src/main/AndroidManifest.xml
#	AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java
2023-01-29 17:58:55 +01:00
Nut.andor
f5713a3eb2 Merge remote-tracking branch 'hosted.weblate/master' 2023-01-29 17:51:49 +01:00
Jiri Zizkin Zizka
90001bb4d6 Translated using Weblate (Czech)
Currently translated at 93.0% (13958 of 14998 strings)
2023-01-29 17:48:01 +01:00
Daniel Stasiak
357cab9b1e Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14998 strings)
2023-01-29 17:47:58 +01:00
Jiri Zizkin Zizka
5ea272f286 Translated using Weblate (Czech)
Currently translated at 100.0% (602 of 602 strings)
2023-01-28 00:57:24 +01:00
Jiri Zizkin Zizka
0c876bd1c5 Translated using Weblate (Czech)
Currently translated at 92.9% (13934 of 14998 strings)
2023-01-28 00:57:24 +01:00
Daniel Stasiak
0ac2999694 Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14998 strings)
2023-01-28 00:57:22 +01:00
Nut.andor
49af3c4b6d some more map fixex 2023-01-24 21:30:37 +01:00
Nut.andor
2a54b31d31 beta version nbr 2023-01-24 21:29:05 +01:00
Nut.andor
64766ce50a potc 2023-01-24 20:47:39 +01:00
Nut.andor
311accfdd3 prep for beta 2023-01-24 20:21:38 +01:00
Nut.andor
2b5bf2fa4a Merge remote-tracking branch 'origin/V0.8.4' into V0.8.4 2023-01-21 13:32:42 +01:00
Nut
64342c96d7 Merge pull request #51 from OMGeeky/import-export-fix-1
Import/Export improvements
2023-01-21 13:31:28 +01:00
OMGeeky
f8649bb0a5 Cleanup 2023-01-21 12:55:16 +01:00
Nut.andor
fde6608c26 translations, copyright 2023-01-21 01:06:55 +01:00
Nut.andor
3f339c14a2 translations, copyright 2023-01-21 00:40:52 +01:00
Nut.andor
922db05c4d Merge remote-tracking branch 'hosted.weblate/master' into V0.8.4 2023-01-21 00:31:16 +01:00
Eduardo
b849de8b66 Translated using Weblate (Portuguese (Brazil))
Currently translated at 94.4% (14159 of 14998 strings)
2023-01-21 00:21:55 +01:00
Eduardo
f798b29729 Translated using Weblate (Portuguese)
Currently translated at 76.4% (11470 of 14998 strings)
2023-01-21 00:21:51 +01:00
MARCO ACORTE
e58e7a2588 Translated using Weblate (Italian)
Currently translated at 83.9% (12598 of 14998 strings)
2023-01-21 00:21:50 +01:00
Eduardo
a1ef339831 Translated using Weblate (Portuguese)
Currently translated at 76.4% (11466 of 14998 strings)
2023-01-20 00:59:15 +01:00
gallegonovato
2002d51f6b Translated using Weblate (Spanish)
Currently translated at 100.0% (602 of 602 strings)
2023-01-15 19:50:17 +01:00
Nut.andor
025283b70b ratdom graphics 2023-01-14 00:57:13 +01:00
Predrag
577b1aa034 Translated using Weblate (Serbian)
Currently translated at 1.8% (275 of 14997 strings)
2023-01-13 10:52:03 +01:00
Ömer Faruk Çakmak
da637c0cc8 Translated using Weblate (Turkish)
Currently translated at 36.1% (5416 of 14998 strings)
2023-01-13 10:52:01 +01:00
Vincenzo De Concilio
d026ff690a Translated using Weblate (Italian)
Currently translated at 96.8% (583 of 602 strings)
2023-01-13 10:51:59 +01:00
Predrag
d14ed56669 Added translation using Weblate (Serbian) 2023-01-12 09:31:54 +01:00
Predrag
64cfacb7ff Translated using Weblate (Serbian)
Currently translated at 0.9% (144 of 14997 strings)
2023-01-11 16:55:04 +01:00
Ömer Faruk Çakmak
98a800e070 Translated using Weblate (Turkish)
Currently translated at 100.0% (602 of 602 strings)
2023-01-11 16:55:02 +01:00
Predrag
35219c8e88 Translated using Weblate (Serbian)
Currently translated at 0.5% (89 of 14997 strings)
2023-01-11 16:22:50 +01:00
Predrag
b636cad347 Added translation using Weblate (Serbian) 2023-01-11 15:35:23 +01:00
Ian Lethe (Windseeker)
733328cd29 Translated using Weblate (Korean)
Currently translated at 9.3% (1408 of 14998 strings)
2023-01-09 12:13:27 +01:00
Ian Lethe (Windseeker)
36db28f805 Translated using Weblate (Korean)
Currently translated at 9.3% (1404 of 14998 strings)
2023-01-09 08:52:00 +01:00
Szabó Péter
6d4c1c3c14 Translated using Weblate (Hungarian)
Currently translated at 89.0% (536 of 602 strings)
2023-01-08 13:52:07 +01:00
David Tamas Szabo
eadb95f8e8 Translated using Weblate (Hungarian)
Currently translated at 27.8% (4177 of 14998 strings)
2023-01-08 13:52:07 +01:00
Szabó Péter
014f67f270 Translated using Weblate (Hungarian)
Currently translated at 27.8% (4177 of 14998 strings)
2023-01-08 13:52:06 +01:00
Nut.andor
cd8657adb4 QuickLearner 5% -> 10% 2023-01-08 00:57:36 +01:00
gallegonovato
c007fc4d1c Translated using Weblate (Spanish)
Currently translated at 100.0% (602 of 602 strings)
2023-01-01 19:52:07 +01:00
gallegonovato
7e6c864ba3 Translated using Weblate (Spanish)
Currently translated at 84.3% (12658 of 14998 strings)
2023-01-01 19:52:06 +01:00
Kristoffer Grundström
f2da8f767a Translated using Weblate (Swedish)
Currently translated at 4.5% (689 of 14998 strings)
2022-12-29 13:27:04 +01:00
Nut.andor
bd856541d6 fix Burhczyd 2022-12-25 01:34:00 +01:00
Dan
bdde2176d9 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (602 of 602 strings)
2022-12-15 21:48:06 +01:00
Dan
171893a2c1 Translated using Weblate (Ukrainian)
Currently translated at 9.8% (1478 of 14998 strings)
2022-12-14 13:51:22 +01:00
rabituwu
c6c1d6d03d Translated using Weblate (Filipino)
Currently translated at 1.9% (295 of 14997 strings)
2022-12-12 14:51:24 +01:00
Nut.andor
ec8b114782 fix Burhczyd 2022-12-12 08:52:43 +01:00
Nut.andor
aaecb8ae4a Reformatting json for better reading 2022-12-11 03:56:15 +01:00
OMGeeky
4e2e3b370c formatting 2022-12-08 17:56:41 +01:00
OMGeeky
c14f8f84a0 Import/Export of the worldmap changed to zip files & some clarifications 2022-12-08 00:18:28 +01:00
Lucas Araujo
13c8012710 Translated using Weblate (Portuguese (Brazil))
Currently translated at 92.9% (13935 of 14998 strings)
2022-12-03 16:48:55 +01:00
عادل نصري
3806d77b26 Translated using Weblate (Arabic)
Currently translated at 9.7% (1457 of 14997 strings)
2022-11-30 14:48:56 +01:00
عادل نصري
af94220715 Translated using Weblate (Arabic)
Currently translated at 100.0% (602 of 602 strings)
2022-11-29 20:48:04 +01:00
عادل نصري
af07c47832 Translated using Weblate (Arabic)
Currently translated at 9.7% (1456 of 14997 strings)
2022-11-29 20:48:03 +01:00
Nut.andor
322007e5ac Next version number v0-8-4 68 2022-11-19 00:23:26 +01:00
aircqsj
af5cdb9d49 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (602 of 602 strings)
2022-11-16 13:48:29 +01:00
Nut.andor
3ada8ceaa7 V0.8.3 2022-11-13 00:54:22 +01:00
3raven
68fa0068dc Translated using Weblate (French)
Currently translated at 84.8% (12733 of 14998 strings)
2022-11-09 22:50:27 +01:00
Nut.andor
7b5fc79375 fixes from beta 2022-11-09 07:30:19 +01:00
ilya
5dfa750227 Translated using Weblate (Russian)
Currently translated at 100.0% (602 of 602 strings)
2022-11-08 19:03:26 +01:00
ilya
cbe0773310 Translated using Weblate (Russian)
Currently translated at 100.0% (602 of 602 strings)
2022-11-07 14:03:24 +01:00
Nut.andor
72a19eeb80 fixes from beta 2022-11-06 21:47:25 +01:00
Nut.andor
a993cc5a08 translation state 2022-11-05 19:07:45 +01:00
Nut.andor
83724ba408 haunted content 2022-11-05 02:03:27 +01:00
Nut.andor
a4cd8f7460 Merge branch 'pulls/1829009049/48' 2022-11-05 00:43:35 +01:00
Nut.andor
7a52bbb9f3 Merge remote-tracking branch 'origin/v0.8.3' 2022-11-05 00:40:01 +01:00
Nut.andor
3552ff8a9f translations 2022-11-05 00:31:16 +01:00
Nut.andor
0e081f3319 authors 2022-11-05 00:30:56 +01:00
Nut.andor
1d94519e1c Merge remote-tracking branch 'hosted.weblate/master' into v0.8.3 2022-11-05 00:24:11 +01:00
Hosted Weblate
0bbc6adb4b Merge branch 'origin/master' into Weblate. 2022-11-05 00:21:51 +01:00
Nut.andor
b48ddd4999 whatsnew 2022-11-04 22:44:39 +01:00
Nut.andor
be8dad981d some new / fixed graphics 2022-11-04 22:44:38 +01:00
Nut.andor
f9708f48a4 whatsnew 2022-11-04 22:38:11 +01:00
Nut.andor
155b01bdea some new / fixed graphics 2022-11-04 22:07:10 +01:00
Nut.andor
19810b2099 Import Export 2022-11-04 21:57:27 +01:00
aircqsj
c6886f7a3e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (14998 of 14998 strings)
2022-11-04 14:07:59 +01:00
OMGeeky
3bea24f9cc Fixed bug where the Logs folder would get exported instead of the Worldmap folder
+cleanup
+API level safety markers
2022-11-03 20:35:37 +01:00
Lacrom
4b8f5c4908 Translated using Weblate (French)
Currently translated at 84.7% (12717 of 14998 strings)
2022-10-29 06:34:15 +02:00
Nut
66d9618b1b Merge pull request #49 from OMGeeky/temp1
Remove ignored files
2022-10-28 22:16:00 +02:00
OMGeeky
488d6347d0 Remove ignore files that are still tracked 2022-10-28 21:39:41 +02:00
OMGeeky
51fd0d0994 Add a loading animation. 2022-10-28 18:47:08 +02:00
Lacrom
50833af145 Translated using Weblate (French)
Currently translated at 84.7% (12704 of 14998 strings)
2022-10-28 07:50:32 +02:00
Lacrom
ca7c2388aa Translated using Weblate (French)
Currently translated at 83.2% (12479 of 14998 strings)
2022-10-27 08:48:11 +02:00
Lacrom
8e7d6adca5 Translated using Weblate (French)
Currently translated at 100.0% (582 of 582 strings)
2022-10-27 08:48:09 +02:00
aircqsj
17edb96ff8 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (14998 of 14998 strings)
2022-10-23 06:10:26 +02:00
ilya
3f3869916c Translated using Weblate (Russian)
Currently translated at 100.0% (14998 of 14998 strings)
2022-10-23 06:10:24 +02:00
Elton Viana Gonçalves da Luz
1d2fc7ade7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 92.8% (13929 of 14998 strings)
2022-10-23 06:10:22 +02:00
OMGeeky
aa84e5a73d Improve import options when the target slot is already used. 2022-10-22 18:10:59 +02:00
OMGeeky
4ecf7d2dda Allow setting strings as message directly & add support for canceling the Dialog 2022-10-22 18:06:25 +02:00
Nut.andor
dca1cb676c New release version numbers and some basic files and settings 2022-10-20 00:14:37 +02:00
Nut.andor
9a4f41eac2 whatsnew 2022-10-19 23:21:43 +02:00
OMGeeky
23012b0d40 Update strings.xml 2022-10-19 22:33:06 +02:00
OMGeeky
916134bd9b Update strings.xml 2022-10-19 22:24:05 +02:00
Nut.andor
1d6777daae fix diamond 2022-10-19 20:14:29 +02:00
OMGeeky
4793751ba8 Improved error/success messages & fixed some bugs in 'Add as New' 2022-10-19 19:16:37 +02:00
OMGeeky
185c0eaf7c Enabling 'Load' button even if no saves exist (for imports) 2022-10-19 19:14:27 +02:00
Daniel Stasiak
4b50d13149 Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14998 strings)
2022-10-19 18:07:41 +02:00
이정희
23b58c3e7c Translated using Weblate (Korean)
Currently translated at 9.3% (1403 of 14998 strings)
2022-10-19 18:07:39 +02:00
Ricardo
2d5ebc3b13 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (582 of 582 strings)
2022-10-19 18:07:38 +02:00
OMGeeky
59e2e3035c Hide the import/export options on devices with an Android version below 10 (Q or api level 29) 2022-10-18 22:34:08 +02:00
OMGeeky
6d5ddfdbfa Add option to 'Add as New' on import 2022-10-18 22:15:53 +02:00
OMGeeky
f8ae18721f Allow vertically stacked buttons in Dialogs 2022-10-18 22:13:17 +02:00
Nut.andor
63bc7c3a4e whatsnew and translation status 2022-10-17 23:44:05 +02:00
OMGeeky
8e72763314 Import Export 2022-10-17 23:20:16 +02:00
Nut.andor
9310d53362 potc 2022-10-17 23:15:48 +02:00
Nut.andor
a71dcc13a3 content 0.8.2 2022-10-17 23:06:34 +02:00
Nut.andor
ea95f4ff87 actual translations generated 2022-10-17 22:33:03 +02:00
Nut.andor
f35167d112 Merge remote-tracking branch 'hosted.weblate/master' 2022-10-17 22:27:58 +02:00
Daniel Stasiak
9f935190f2 Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14995 strings)
2022-10-16 00:53:44 +02:00
Nut.andor
c11430cf6b beta icon and fileprovider 2022-10-15 22:46:16 +02:00
Daniel Stasiak
8f97a27ab7 Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14995 strings)
2022-10-13 15:56:19 +02:00
Anupam Malhotra
9e36f848dc Translated using Weblate (Hindi)
Currently translated at 0.1% (4 of 14994 strings)
2022-10-12 08:50:37 +02:00
ilya
b24d52b1da Translated using Weblate (Russian)
Currently translated at 100.0% (14995 of 14995 strings)
2022-10-12 08:50:34 +02:00
Daniel Stasiak
e2a9307560 Translated using Weblate (Polish)
Currently translated at 92.5% (13884 of 14995 strings)
2022-10-12 08:50:31 +02:00
Nut.andor
e3ac804f61 Merge branch 'pulls/1829009049/47' 2022-10-11 19:20:06 +02:00
Nut.andor
fd504d2df5 Automated copying of files for build as gradle task 2022-10-11 18:58:05 +02:00
OMGeeky
0e615d3f11 Revert accidental wrong branch stuff 2022-10-11 18:31:01 +02:00
Nut.andor
47646457ab (Pull Request #46:) Fixed problems with older Android versions (below Android 7) 2022-10-11 00:00:00 +02:00
OMGeeky
8e393b93d8 Changed lint.xml to include StringFormatMatches and StringFormatInvalid 2022-10-10 15:43:34 +02:00
OMGeeky
3289bd6fb1 Configured lint-baseline file (for automatic builds on github) 2022-10-10 15:32:21 +02:00
OMGeeky
23a331d655 Merge remote-tracking branch 'origin/fix-older-android-versions' into gradle_copy_v1 2022-10-10 15:09:01 +02:00
OMGeeky
112301c444 Create build Action
(cherry picked from commit 462b6059218b1bdc1efa582ea2463d5eb3af1c22)
2022-10-10 15:05:01 +02:00
OMGeeky
f50e4f1d38 Migrate to AndroidX 2022-10-10 14:54:08 +02:00
OMGeeky
d623c22b38 Removed ignored files 2022-10-10 14:45:01 +02:00
OMGeeky
d11bf5b0aa Automated copying of files for build as gradle task 2022-10-10 09:22:18 +02:00
Nut.andor
e30f67e327 fix Master Ale bug 2022-10-09 02:43:01 +02:00
OMGeeky
6946b1f2b3 Fixed problems with older Android versions (below Android 7) 2022-10-09 02:00:52 +02:00
Nut Andor
96a1a5760a Translated using Weblate (German)
Currently translated at 94.0% (14096 of 14995 strings)
2022-10-09 01:15:46 +02:00
Nut.andor
58b802e911 whatsnew 2022-10-08 03:41:50 +02:00
Nut.andor
f9b095565b languages 2022-10-08 03:22:32 +02:00
Nut.andor
19817eb97d Merge branch 'v0.8.2' 2022-10-08 02:58:18 +02:00
Nut.andor
f46d2aedbf content v082 (Sullengard fixes) 2022-10-08 02:56:10 +02:00
Nut.andor
913b651953 Merge remote-tracking branch 'hosted.weblate/master' into v0.8.2 2022-10-08 01:04:59 +02:00
Nut Andor
5283eed28e Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (15016 of 15016 strings)
2022-10-08 01:04:14 +02:00
Nut Andor
deb824d50e Translated using Weblate (German)
Currently translated at 93.8% (14095 of 15016 strings)
2022-10-08 01:04:12 +02:00
Nut.andor
6841d862e4 Merge remote-tracking branch 'hosted.weblate/master' into v0.8.2 2022-10-08 00:43:26 +02:00
saoloer
f94723b0cd Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (15016 of 15016 strings)
2022-10-07 18:18:35 +02:00
Jr
ab41168736 Translated using Weblate (German)
Currently translated at 93.8% (14095 of 15016 strings)
2022-10-07 18:18:33 +02:00
Jr
2d73c4687a Translated using Weblate (German)
Currently translated at 100.0% (582 of 582 strings)
2022-10-07 18:18:30 +02:00
aircqsj
e454deb8b1 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (15015 of 15016 strings)
2022-10-05 20:56:26 +02:00
Lucas Araujo
074891805a Translated using Weblate (Portuguese (Brazil))
Currently translated at 92.7% (13928 of 15016 strings)
2022-10-05 20:56:21 +02:00
Daniel Stasiak
d2d32bc4ed Translated using Weblate (Polish)
Currently translated at 92.4% (13884 of 15016 strings)
2022-10-05 20:56:20 +02:00
Daniel Stasiak
22daeb0c33 Translated using Weblate (Polish)
Currently translated at 100.0% (582 of 582 strings)
2022-10-05 20:56:17 +02:00
Nut.andor
db30253baf v0.8.2 66 2022-10-03 00:47:11 +02:00
Nut.andor
312cb7dec7 ignore workspace.xml 2022-10-03 00:44:00 +02:00
Nut.andor
7befd27951 whatsnew release version 2022-10-02 21:05:38 +02:00
aircqsj
c1e3bfa7ed Translated using Weblate (Chinese (Simplified))
Currently translated at 94.0% (14128 of 15016 strings)
2022-10-02 07:56:33 +02:00
ilya
ddec991082 Translated using Weblate (Russian)
Currently translated at 100.0% (15016 of 15016 strings)
2022-10-02 07:56:02 +02:00
ilya
25e36dc535 Translated using Weblate (Russian)
Currently translated at 100.0% (15016 of 15016 strings)
2022-09-30 18:31:04 +02:00
Jiri Zizkin Zizka
83c579a929 Translated using Weblate (Czech)
Currently translated at 100.0% (582 of 582 strings)
2022-09-29 23:16:22 +02:00
Jiri Zizkin Zizka
0c694115ee Translated using Weblate (Czech)
Currently translated at 92.7% (13932 of 15016 strings)
2022-09-29 23:16:22 +02:00
ilya
bf9723b0c1 Translated using Weblate (Russian)
Currently translated at 96.2% (14449 of 15016 strings)
2022-09-29 23:16:20 +02:00
ilya
b81bacb1fe Translated using Weblate (Russian)
Currently translated at 100.0% (582 of 582 strings)
2022-09-29 23:16:17 +02:00
496 changed files with 649496 additions and 23472 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/AndorsTrail/.idea/workspace.xml

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@@ -1,166 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="fb7bf33b-30cf-40b9-a238-3e2f6f604a8f" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="device_and_snapshot_combo_box_target[C:\Users\chris\.android\avd\Nexus_5_API_30.avd]" />
<component name="ExternalProjectsData">
<projectState path="$PROJECT_DIR$">
<ProjectState />
</projectState>
</component>
<component name="ExternalProjectsManager">
<system id="GRADLE">
<state>
<projects_view>
<tree_state>
<expand>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="AndorsTrail" type="f1a62948:ProjectNode" />
</path>
</expand>
<select />
</tree_state>
</projects_view>
</state>
</system>
</component>
<component name="GenerateSignedApkSettings">
<option name="KEY_STORE_PATH" value="C:\AT\sec\AndorsTrail.keystore" />
<option name="KEY_ALIAS" value="andorstrail" />
<option name="REMEMBER_PASSWORDS" value="true" />
<option name="BUILD_TARGET_KEY" value="apk" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectId" id="2FG0LqADbxm6Q1t3yQ9BlX5APzJ" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="ApkExportedModule" value="AndorsTrail.app" />
<property name="ExportApk.ApkPath" value="C:\AT\AndorsTrailRelease\andors-trail\AndorsTrail\app" />
<property name="ExportApk.BuildVariants" value="release" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="RunOnceActivity.cidr.known.project.marker" value="true" />
<property name="android.sdk.path" value="$USER_HOME$/AppData/Local/Android/Sdk" />
<property name="cidr.known.project.marker" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../../../sec/AndorsTrail.keystore" />
<property name="settings.editor.selected.configurable" value="device.file.explorer" />
<property name="show.inlinked.gradle.project.popup" value="false" />
</component>
<component name="RunManager">
<configuration name="&lt;template&gt;" type="Applet" default="true" selected="false">
<option name="MAIN_CLASS_NAME" />
<option name="HTML_FILE_NAME" />
<option name="HTML_USED" value="false" />
<option name="WIDTH" value="400" />
<option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<option name="VM_PARAMETERS" />
</configuration>
<configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
</configuration>
<configuration name="app" type="AndroidRunConfigurationType" factoryName="Android App">
<module name="AndorsTrail.app" />
<option name="DEPLOY" value="true" />
<option name="DEPLOY_APK_FROM_BUNDLE" value="false" />
<option name="DEPLOY_AS_INSTANT" value="false" />
<option name="ARTIFACT_NAME" value="" />
<option name="PM_INSTALL_OPTIONS" value="" />
<option name="ALL_USERS" value="false" />
<option name="ALWAYS_INSTALL_WITH_PM" value="false" />
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
<option name="MODE" value="default_activity" />
<option name="CLEAR_LOGCAT" value="false" />
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
<option name="INSPECTION_WITHOUT_ACTIVITY_RESTART" value="false" />
<option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
<option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
<option name="SELECTED_CLOUD_MATRIX_PROJECT_ID" value="" />
<option name="DEBUGGER_TYPE" value="Auto" />
<Auto>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
</Auto>
<Hybrid>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
</Hybrid>
<Java />
<Native>
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
<option name="SHOW_STATIC_VARS" value="true" />
<option name="WORKING_DIR" value="" />
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
</Native>
<Profilers>
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
<option name="STARTUP_PROFILING_ENABLED" value="false" />
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Java/Kotlin Method Sample (legacy)" />
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
</Profilers>
<option name="DEEP_LINK" value="" />
<option name="ACTIVITY_CLASS" value="" />
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="TestNG">
<option name="TEST_OBJECT" value="CLASS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<properties />
<listeners />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="fb7bf33b-30cf-40b9-a238-3e2f6f604a8f" name="Changes" comment="" />
<created>1664103080085</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1664103080085</updated>
</task>
<servers />
</component>
</project>

View File

@@ -1,23 +1,52 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
compileSdkVersion 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.gpl.rpg.AndorsTrail"
minSdkVersion 14
targetSdkVersion 30
targetSdkVersion 31
}
buildTypes {
release {
manifestPlaceholders icon_name: 'icon', fileproviderPath: 'AndorsTrail'
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
debug {
manifestPlaceholders icon_name: 'icon_beta', fileproviderPath: 'AndorsTrail.beta2'
applicationIdSuffix 'beta2'
}
}
}
dependencies {
implementation 'com.android.support:support-v4:28.0.0'
}
task copyRes(type: Copy) {
description "Copies the res folder to the modules res folder (& renames .tmx to .xml)"
from "${rootDir}/res"
into "${projectDir}/src/main/res"
rename "(.*)\\.tmx", "\$1.xml"
}
task copyTranslation(type: Copy) {
description("Copies the translation files to the modules translations folder")
from "${rootDir}/assets/translation"
into "${projectDir}/src/main/assets/translation"
}
task cleanup(type: Delete) {
description("Deletes the assets/translation and the res folder from the modules folder")
delete "${projectDir}/src/main/res", "${projectDir}/src/main/assets/translation"
}
afterEvaluate {
preBuild.dependsOn project.tasks.copyRes
preBuild.dependsOn project.tasks.copyTranslation
clean.dependsOn project.tasks.cleanup
}

View File

@@ -3,15 +3,11 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gpl.rpg.AndorsTrail"
android:versionCode="66"
android:versionName="0.8.2"
android:versionCode="73"
android:versionName="0.8.7"
android:installLocation="auto"
>
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="30"
/>
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
@@ -25,9 +21,9 @@
<application
android:name=".AndorsTrailApplication"
android:name="com.gpl.rpg.AndorsTrail.AndorsTrailApplication"
android:label="@string/app_name"
android:icon="@drawable/icon"
android:icon="@drawable/${icon_name}"
android:description="@string/app_description"
android:allowBackup="true"
android:theme="@style/AndorsTrailTheme_Blue"
@@ -36,37 +32,39 @@
android:preserveLegacyExternalStorage="true"
>
<activity
android:name=".activity.StartScreenActivity"
android:clearTaskOnLaunch="true">
android:name="com.gpl.rpg.AndorsTrail.activity.StartScreenActivity"
android:exported="true"
android:clearTaskOnLaunch="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.MainActivity"
android:name="com.gpl.rpg.AndorsTrail.activity.MainActivity"
android:label="@string/app_name"
android:theme="@style/AndorsTrailTheme_Blue.NoBackground"
/>
<activity android:name=".activity.HeroinfoActivity" />
<activity android:name=".activity.MonsterInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.ItemInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.LevelUpActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.MonsterEncounterActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.ConversationActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.ShopActivity" />
<activity android:name=".activity.AboutActivity" />
<activity android:name=".activity.LoadingActivity" />
<activity android:name=".activity.Preferences" />
<activity android:name=".activity.LoadSaveActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.ActorConditionInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.BulkSelectionInterface" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.SkillInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name=".activity.DisplayWorldMapActivity" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.MonsterInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ItemInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LevelUpActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.MonsterEncounterActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ConversationActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ShopActivity" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.AboutActivity" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LoadingActivity" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.Preferences" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.LoadSaveActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.ActorConditionInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.BulkSelectionInterface" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.SkillInfoActivity" android:theme="@style/AndorsTrailDialogTheme_Blue" />
<activity android:name="com.gpl.rpg.AndorsTrail.activity.DisplayWorldMapActivity" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.gpl.rpg.AndorsTrail.fileprovider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data

View File

@@ -24,15 +24,15 @@ public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_DEBUGRESOURCES = false;
public static final boolean DEVELOPMENT_FORCE_STARTNEWGAME = false;
public static final boolean DEVELOPMENT_FORCE_CONTINUEGAME = false;
public static final boolean DEVELOPMENT_DEBUGBUTTONS = false;
public static final boolean DEVELOPMENT_DEBUGBUTTONS = true;
public static final boolean DEVELOPMENT_FASTSPEED = false;
public static final boolean DEVELOPMENT_VALIDATEDATA = false;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
public static final String CURRENT_VERSION_DISPLAY = "0.8.2";
public static final boolean DEVELOPMENT_VALIDATEDATA = true;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = true;
public static final String CURRENT_VERSION_DISPLAY = "0.8.7";
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION;
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 66;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 73;
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
private WorldContext world = new WorldContext();

View File

@@ -2,7 +2,6 @@ package com.gpl.rpg.AndorsTrail;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
public final class AndorsTrailPreferences {
@@ -62,8 +61,6 @@ public final class AndorsTrailPreferences {
public boolean showQuickslotsWhenToolboxIsVisible = false;
public String language = "default";
public Uri exportImportFolderPath;
public int selectedTheme = 0;
public void read(final Context androidContext) {
@@ -81,7 +78,7 @@ public final class AndorsTrailPreferences {
dest.dpadTransparency = Integer.parseInt(prefs.getString("dpadtransparency", Integer.toString(DPAD_TRANSPARENCY_50_PERCENT)));
dest.dpadMinimizeable = prefs.getBoolean("dpadMinimizeable", true);
dest.optimizedDrawing = prefs.getBoolean("optimized_drawing", false);
dest.highQualityFilters = prefs.getBoolean("high_quality_filters", true);
dest.highQualityFilters = prefs.getBoolean("high_quality_filters", false);
dest.enableUiAnimations = prefs.getBoolean("enableUiAnimations", true);
dest.displayOverwriteSavegame = Integer.parseInt(prefs.getString("display_overwrite_savegame", Integer.toString(CONFIRM_OVERWRITE_SAVEGAME_ALWAYS)));
dest.quickslotsPosition = Integer.parseInt(prefs.getString("quickslots_placement", Integer.toString(QUICKSLOTS_POSITION_HORIZONTAL_CENTER_BOTTOM)));

View File

@@ -46,14 +46,15 @@ import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
import com.gpl.rpg.AndorsTrail.view.ItemContainerAdapter;
public final class Dialogs {
private static void showDialogAndPause(Dialog d, final ControllerContext context) {
private static void showDialogAndPause(CustomDialog d, final ControllerContext context) {
showDialogAndPause(d, context, null);
}
private static void showDialogAndPause(Dialog d, final ControllerContext context, final OnDismissListener onDismiss) {
private static void showDialogAndPause(CustomDialog d, final ControllerContext context, final OnDismissListener onDismiss) {
context.gameRoundController.pause();
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
@Override
@@ -195,7 +196,7 @@ public final class Dialogs {
// itemList.setPadding(20, 0, 20, 20);
itemList.setAdapter(new ItemContainerAdapter(mainActivity, world.tileManager, combinedLoot.items, world.model.player));
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
mainActivity.getResources().getString(title),
mainActivity.getResources().getDrawable(R.drawable.ui_icon_equipment),
msg,
@@ -249,7 +250,7 @@ public final class Dialogs {
}
public static void showHeroDied(final MainActivity mainActivity, final ControllerContext controllers) {
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
mainActivity.getResources().getString(R.string.dialog_game_over_title),
mainActivity.getResources().getDrawable(R.drawable.ui_icon_combat),
mainActivity.getResources().getString(R.string.dialog_game_over_text),
@@ -286,7 +287,7 @@ public final class Dialogs {
}
public static void showConfirmRest(final Activity currentActivity, final ControllerContext controllerContext, final MapObject area) {
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
currentActivity.getResources().getString(R.string.dialog_rest_title),
null,
currentActivity.getResources().getString(R.string.dialog_rest_confirm_message),
@@ -310,7 +311,7 @@ public final class Dialogs {
// .setMessage(R.string.dialog_rest_message)
// .setNeutralButton(android.R.string.ok, null)
// .create();
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
currentActivity.getResources().getString(R.string.dialog_rest_title),
null,
currentActivity.getResources().getString(R.string.dialog_rest_message),
@@ -336,7 +337,7 @@ public final class Dialogs {
text += currentActivity.getResources().getString(R.string.dialog_newversion_permission_information);
}
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
final CustomDialog d = CustomDialogFactory.createDialog(currentActivity,
currentActivity.getResources().getString(R.string.dialog_newversion_title),
null,
text,
@@ -371,7 +372,7 @@ public final class Dialogs {
}
if (!world.model.statistics.hasUnlimitedSaves()) {
final Dialog d = CustomDialogFactory.createDialog(mainActivity,
final CustomDialog d = CustomDialogFactory.createDialog(mainActivity,
mainActivity.getResources().getString(R.string.menu_save_switch_character_title),
null,
mainActivity.getResources().getString(R.string.menu_save_switch_character),
@@ -460,7 +461,7 @@ public final class Dialogs {
itemList.setAdapter(new ArrayAdapter<String>(context, R.layout.combatlog_row, android.R.id.text1, combatLogMessages));
view = itemList;
final Dialog d = CustomDialogFactory.createDialog(context,
final CustomDialog d = CustomDialogFactory.createDialog(context,
context.getResources().getString(R.string.combat_log_title),
context.getResources().getDrawable(R.drawable.ui_icon_combat),
null,

View File

@@ -23,6 +23,7 @@ import com.gpl.rpg.AndorsTrail.controller.ItemController;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
/**
* @author ejwessel
@@ -206,7 +207,7 @@ public final class BulkSelectionInterface extends AndorsTrailBaseActivity implem
// })
// .setNegativeButton(android.R.string.no, null)
// .show();
final Dialog d = CustomDialogFactory.createDialog(v.getContext(),
final CustomDialog d = CustomDialogFactory.createDialog(v.getContext(),
v.getContext().getResources().getString(R.string.bulkselection_sell_confirmation_title),
v.getContext().getResources().getDrawable(android.R.drawable.ic_dialog_info),
message,

View File

@@ -1,16 +1,17 @@
package com.gpl.rpg.AndorsTrail.activity;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.Context;
@@ -40,6 +41,7 @@ import com.gpl.rpg.AndorsTrail.savegames.Savegames.FileHeader;
import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
public final class LoadSaveActivity extends AndorsTrailBaseActivity implements OnClickListener {
private boolean isLoading = true;
@@ -95,9 +97,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
importSaves.setTag(SLOT_NUMBER_IMPORT_SAVEGAMES);
importWorldmap.setTag(SLOT_NUMBER_IMPORT_WORLDMAP);
ViewGroup exportContainer = (ViewGroup) findViewById(R.id.loadsave_export_save_container);
ViewGroup importContainer = (ViewGroup) findViewById(R.id.loadsave_import_save_container);
ViewGroup importWorldmapContainer = (ViewGroup) findViewById(R.id.loadsave_import_worldmap_container);
ViewGroup exportImportContainer = (ViewGroup) findViewById(R.id.loadsave_export_import_save_container);
addSavegameSlotButtons(slotList, params, Savegames.getUsedSavegameSlots(this));
@@ -108,19 +108,20 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
createNewSlot.setTag(SLOT_NUMBER_CREATE_NEW_SLOT);
createNewSlot.setOnClickListener(this);
newSlotContainer.setVisibility(View.VISIBLE);
exportContainer.setVisibility(View.GONE);
importContainer.setVisibility(View.GONE);
importWorldmapContainer.setVisibility(View.GONE);
exportImportContainer.setVisibility(View.GONE);
} else {
newSlotContainer.setVisibility(View.GONE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
exportSaves.setOnClickListener(this);
importSaves.setOnClickListener(this);
importWorldmap.setOnClickListener(this);
exportContainer.setVisibility(View.VISIBLE);
importContainer.setVisibility(View.VISIBLE);
importWorldmapContainer.setVisibility(View.VISIBLE);
exportImportContainer.setVisibility(View.VISIBLE);
boolean hasSavegames = !Savegames.getUsedSavegameSlots(this).isEmpty();
exportSaves.setEnabled(hasSavegames);
} else {
exportImportContainer.setVisibility(View.GONE);
}
}
}
@@ -128,14 +129,18 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
private static final int READ_EXTERNAL_STORAGE_REQUEST = 1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
@TargetApi(23)
private void checkAndRequestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_EXTERNAL_STORAGE_REQUEST);
}
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST);
}
}
}
@@ -149,11 +154,15 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
}
}
private void addSavegameSlotButtons(ViewGroup parent, LayoutParams params, List<Integer> usedSavegameSlots) {
private void addSavegameSlotButtons(ViewGroup parent,
LayoutParams params,
List<Integer> usedSavegameSlots) {
int unused = 1;
for (int slot : usedSavegameSlots) {
final FileHeader header = Savegames.quickload(this, slot);
if (header == null) continue;
if (header == null) {
continue;
}
while (unused < slot) {
Button b = new Button(this);
@@ -177,41 +186,76 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
}
}
private void cancelLoadSaveActivity(int slot) {
completeLoadSaveActivity(slot, false);
}
private void completeLoadSaveActivity(int slot) {
completeLoadSaveActivity(slot, true);
}
private void completeLoadSaveActivity(int slot, boolean success) {
Intent i = new Intent();
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
if (usedSlots.isEmpty())
slot = SLOT_NUMBER_FIRST_SLOT;
else slot = Collections.max(usedSlots) + 1;
slot = getFirstFreeSlot();
} else if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
i.putExtra("import_export", true);
} else if (slot < SLOT_NUMBER_FIRST_SLOT)
if (slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
i.putExtra("import_worldmap", true);
}
if (slot == SLOT_NUMBER_IMPORT_SAVEGAMES) {
i.putExtra("import_savegames", true);
}
if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES) {
i.putExtra("export", true);
}
} else if (slot < SLOT_NUMBER_FIRST_SLOT) {
slot = SLOT_NUMBER_FIRST_SLOT;
}
i.putExtra("slot", slot);
setResult(Activity.RESULT_OK, i);
if (success) {
setResult(Activity.RESULT_OK, i);
} else {
setResult(Activity.RESULT_CANCELED, i);
}
LoadSaveActivity.this.finish();
}
private int getFirstFreeSlot() {
int slot;
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
if (usedSlots.isEmpty()) {
slot = SLOT_NUMBER_FIRST_SLOT;
} else {
slot = Collections.max(usedSlots) + 1;
}
return slot;
}
private String getConfirmOverwriteQuestion(int slot) {
if (isLoading)
if (isLoading) {
return null;
}
return getConfirmOverwriteQuestionIgnoringLoading(slot);
}
private String getConfirmOverwriteQuestionIgnoringLoading(int slot) {
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT)
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
return null;//creating a new savegame
}
if (!Savegames.getSlotFile(slot, this).exists())
if (!Savegames.getSlotFile(slot, this).exists()) {
return null;//nothing in slot to overwrite
}
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
if (preferences.displayOverwriteSavegame
== AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
return getString(R.string.loadsave_save_overwrite_confirmation_all);
}
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
@@ -220,10 +264,14 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
final String currentPlayerName = model.player.getName();
final FileHeader header = Savegames.quickload(this, slot);
if (header == null) return null;
if (header == null) {
return null;
}
final String savedPlayerName = header.playerName;
if (currentPlayerName.equals(savedPlayerName)) return null; //if the names match
if (currentPlayerName.equals(savedPlayerName)) {
return null; //if the names match
}
return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName);
}
@@ -232,7 +280,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
public void onClick(View view) {
final int slot = (Integer) view.getTag();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switch (slot) {
case SLOT_NUMBER_IMPORT_WORLDMAP:
clickImportWorldmap();
@@ -246,8 +294,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
}
}
if (!isLoading
&& slot != SLOT_NUMBER_CREATE_NEW_SLOT
&& AndorsTrailApplication.CURRENT_VERSION == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
&& slot != SLOT_NUMBER_CREATE_NEW_SLOT
&& AndorsTrailApplication.CURRENT_VERSION
== AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
if (!isOverwriteTargetInIncompatibleVersion(slot)) {
saveOrOverwriteSavegame(slot);
}
@@ -261,7 +310,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
private void saveOrOverwriteSavegame(int slot) {
final String message = getConfirmOverwriteQuestion(slot);
if (message != null) {
showConfirmoverwriteQuestion(slot, message);
showConfirmOverwriteQuestion(slot, message);
} else {
completeLoadSaveActivity(slot);
}
@@ -269,8 +318,11 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
private boolean isOverwriteTargetInIncompatibleVersion(int slot) {
final FileHeader header = Savegames.quickload(this, slot);
if (header != null && header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
final Dialog d = CustomDialogFactory.createErrorDialog(this, "Overwriting not allowed", "You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.");
if (header != null
&& header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
"Overwriting not allowed",
"You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.");
CustomDialogFactory.show(d);
return true;
}
@@ -279,27 +331,32 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
//region Imports/Exports
//region Export
@RequiresApi(api = Build.VERSION_CODES.P)
private void exportSaveGames(Intent data) {
Uri uri = data.getData();
Context context = getApplicationContext();
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this)
.getContentResolver();
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
DocumentFile source = DocumentFile.fromFile(storageDir);
File storageDir = AndroidStorage.getStorageDirectory(context,
Constants.FILENAME_SAVEGAME_DIRECTORY);
DocumentFile target = DocumentFile.fromTreeUri(context, uri);
if (target == null) {
return;
}
DocumentFile[] files = source.listFiles();
File[] files = storageDir.listFiles();
if (files == null) {
showErrorExportingSaveGamesUnknown();
return;
}
boolean hasExistingFiles = false;
for (DocumentFile file :
files) {
for (File file : files) {
String fileName = file.getName();
if (fileName == null)
continue;
DocumentFile existingFile = target.findFile(fileName);
if (existingFile != null) {
@@ -311,52 +368,70 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
if (hasExistingFiles) {
showConfirmOverwriteByExportQuestion(resolver, target, files);
} else {
exportSaveGamesFolderContentToFolder(resolver, target, files);
exportSaveGamesFolderContentToFolder(target, files);
}
}
private void exportSaveGamesFolderContentToFolder(ContentResolver resolver, DocumentFile target, DocumentFile[] files) {
for (DocumentFile file : files) {
String fileName = file.getName();
DocumentFile existingFile = target.findFile(fileName);
boolean hasExistingFile = existingFile != null && existingFile.exists();
@RequiresApi(api = Build.VERSION_CODES.P)
private void exportSaveGamesFolderContentToFolder(DocumentFile target, File[] files) {
DocumentFile[] sourceFiles = new DocumentFile[files.length];
File[] worldmapFiles = null;
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.isFile()) {
try {
if (hasExistingFile)
existingFile.delete();
AndroidStorage.copyDocumentFileToNewOrExistingFile(file, resolver, target);
} catch (IOException e) {
e.printStackTrace();
}
} else if (file.isDirectory()) {
DocumentFile targetWorlmap = existingFile;
//if the folder exists already, put the files in the existing folder. (should not happen because of check earlier)
if (!hasExistingFile)
//create a new folder for the worldmap-files
targetWorlmap = target.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY);
if (targetWorlmap == null)//Unable to create worldmap folder for some reason
continue;
DocumentFile[] worldmapFiles = file.listFiles();
for (DocumentFile f : worldmapFiles) {
try {
AndroidStorage.copyDocumentFileToNewOrExistingFile(f, resolver, targetWorlmap);
} catch (IOException e) {
e.printStackTrace();
}
}
sourceFiles[i] = DocumentFile.fromFile(file);
} else if (file.isDirectory() && Objects.equals(file.getName(),
Constants.FILENAME_WORLDMAP_DIRECTORY)) {
worldmapFiles = file.listFiles();
}
}
Context context = this;
File[] finalWorldmapFiles = worldmapFiles;
CopyFilesToExternalFolder(target, sourceFiles, context, finalWorldmapFiles);
completeLoadSaveActivity(SLOT_NUMBER_EXPORT_SAVEGAMES);
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void CopyFilesToExternalFolder(DocumentFile target,
DocumentFile[] sourceFiles,
Context context,
File[] finalWorldmapFiles) {
AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles,
context,
target,
getString(R.string.loadsave_exporting_savegames),
(success) -> {
if (success) {
CopyWorldmapFilesAsZip(target,
context,
finalWorldmapFiles);
} else {
completeLoadSaveActivity(
SLOT_NUMBER_EXPORT_SAVEGAMES,
false);
}
});
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@RequiresApi(api = Build.VERSION_CODES.P)
private void CopyWorldmapFilesAsZip(DocumentFile target,
Context context,
File[] finalWorldmapFiles) {
AndroidStorage.createZipDocumentFileFromFilesAsync(finalWorldmapFiles,
context,
target,
Constants.FILENAME_WORLDMAP_DIRECTORY,
getString(R.string.loadsave_exporting_worldmap),
(successWorldmap) -> completeLoadSaveActivity(
SLOT_NUMBER_EXPORT_SAVEGAMES,
successWorldmap));
}
//endregion
@RequiresApi(api = Build.VERSION_CODES.P)
private void importSaveGames(Intent data) {
Uri uri = data.getData();
ClipData uris = data.getClipData();
@@ -367,7 +442,8 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
}
Context context = getApplicationContext();
ContentResolver resolver = context.getContentResolver();
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this)
.getContentResolver();
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
DocumentFile appSavegameFolder = DocumentFile.fromFile(storageDir);
@@ -376,13 +452,18 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
if (uri != null) {
uriList.add(uri);
} else {
for (int i = 0; i < uris.getItemCount(); i++)
for (int i = 0; i < uris.getItemCount(); i++) {
uriList.add(uris.getItemAt(i).getUri());
}
}
importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList);
}
private void importSaveGamesFromUris(Context context, ContentResolver resolver, DocumentFile appSavegameFolder, List<Uri> uriList) {
@RequiresApi(api = Build.VERSION_CODES.P)
private void importSaveGamesFromUris(Context context,
ContentResolver resolver,
DocumentFile appSavegameFolder,
List<Uri> uriList) {
int count = uriList.size();
ArrayList<DocumentFile> alreadyExistingFiles = new ArrayList<>();
@@ -392,10 +473,11 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
Uri item = uriList.get(i);
DocumentFile itemFile = DocumentFile.fromSingleUri(context, item);
boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder);
if (fileAlreadyExists)
if (fileAlreadyExists) {
alreadyExistingFiles.add(itemFile);
else
} else {
newFiles.add(itemFile);
}
}
if (alreadyExistingFiles.size() > 0) {
@@ -405,24 +487,51 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
}
}
private void importSaveGames(ContentResolver resolver, DocumentFile appSavegameFolder, List<DocumentFile> saveFiles) {
for (DocumentFile file : saveFiles) {
@RequiresApi(api = Build.VERSION_CODES.P)
private void importSaveGames(ContentResolver resolver,
DocumentFile appSavegameFolder,
List<DocumentFile> saveFiles) {
int size = saveFiles.size();
DocumentFile[] sources = new DocumentFile[size];
DocumentFile[] targets = new DocumentFile[size];
boolean saveAsNew = false;
for (int i = 0; i < size; i++) {
DocumentFile file = saveFiles.get(i);
if (file == null) {//null is value a marker that the next should be saved as new
saveAsNew = true;
continue;
}
int slot = getSlotFromSavegameFileName(file.getName());
importSaveGameFile(resolver, appSavegameFolder, file, slot);
}
}
if (slot == -1) {
//invalid file name
continue;
}
if (saveAsNew) {
slot = getFirstFreeSlot();
saveAsNew = false;
}
private void completeSavegameImportAndCheckIfDone(List<Integer> importsNeedingConfirmation, int slot) {
importsNeedingConfirmation.remove((Object) slot);
if (importsNeedingConfirmation.isEmpty()) {
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES);
String targetName = Savegames.getSlotFileName(slot);
sources[i] = file;
targets[i] = getOrCreateDocumentFile(appSavegameFolder, targetName);
}
AndroidStorage.copyDocumentFilesFromToAsync(sources,
this,
targets,
getString(R.string.loadsave_importing_savegames),
(sucess) -> completeLoadSaveActivity(
SLOT_NUMBER_IMPORT_SAVEGAMES,
sucess));
}
private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, DocumentFile appSavegameFolder) {
if (savegameFile == null)
if (savegameFile == null) {
return false;
}
DocumentFile foundFile = appSavegameFolder.findFile(Objects.requireNonNull(savegameFile.getName()));
return foundFile != null && foundFile.exists();
@@ -430,7 +539,6 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
private int getSlotFromSavegameFileName(String fileName) {
if (fileName == null || !fileName.startsWith(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX)) {
//TODO: Maybe output a message that the file didn't have the right name?
return -1;
}
String slotStr = fileName.substring(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX.length());
@@ -440,116 +548,110 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
slot = Integer.parseInt(slotStr);
return slot;
} catch (NumberFormatException e) {
//TODO: Maybe output a message that the file didn't have the right name?
return -1;
}
}
private void importSaveGameFile(ContentResolver resolver, DocumentFile appSavegameFolder, DocumentFile itemFile, int slot) {
String targetName = Savegames.getSlotFileName(slot);
DocumentFile targetFile = getOrCreateDocumentFile(appSavegameFolder, targetName);
if (targetFile == null || !targetName.equals(targetFile.getName())) {
showErrorImportingSaveGameUnknown();//TODO: maybe replace with a more specific error message
return;
}
try {
AndroidStorage.copyDocumentFile(itemFile, resolver, targetFile);
} catch (IOException e) {
showErrorImportingSaveGameUnknown();
e.printStackTrace();
}
}
private DocumentFile getOrCreateDocumentFile(DocumentFile folder, String targetName) {
DocumentFile targetFile = folder.findFile(targetName);//try finding the file
if (targetFile == null)//no file found, creating new one
{
targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName);
}
return targetFile;
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void importWorldmap(Intent data) {
Uri uri = data.getData();
Context context = getApplicationContext();
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
DocumentFile storageFolder = DocumentFile.fromFile(storageDir);
DocumentFile ownWorldmapFolder = storageFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
if (ownWorldmapFolder == null) {
ownWorldmapFolder = storageFolder.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY);
}
DocumentFile chosenFolder = DocumentFile.fromTreeUri(context, uri);
if (chosenFolder == null || !chosenFolder.isDirectory()) {
DocumentFile chosenZip = DocumentFile.fromSingleUri(context, uri);
if (chosenZip == null || !chosenZip.isFile()) {
showErrorImportingWorldmapWrongDirectory();
return;
}
if (!Constants.FILENAME_WORLDMAP_DIRECTORY.equals(chosenFolder.getName())) {
//user did not select the worldmap folder directly
DocumentFile file = chosenFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
if (file == null || !file.isDirectory() || !Constants.FILENAME_WORLDMAP_DIRECTORY.equals(file.getName())) {
//could not find a worldmap folder in the users selection
showErrorImportingWorldmapWrongDirectory();
return;
}
chosenFolder = file;
String chosenZipName = chosenZip.getName();
if (!chosenZipName.startsWith(Constants.FILENAME_WORLDMAP_DIRECTORY)) {
showErrorImportingWorldmapWrongDirectory();
return;
}
DocumentFile[] files = chosenFolder.listFiles();
for (DocumentFile file : files) {
if (file.isFile()) {
try {
AndroidStorage.copyDocumentFileToNewOrExistingFile(file, resolver, ownWorldmapFolder);
} catch (IOException e) {
e.printStackTrace();
}
}
}
File ownWorldmapFolder = getOwnWorldmapFolder(context);
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_WORLDMAP);
AndroidStorage.unzipDocumentFileToDirectoryAsync(chosenZip,
this,
ownWorldmapFolder,
false,
getString(R.string.loadsave_importing_worldmap),
(success) -> completeLoadSaveActivity(
SLOT_NUMBER_IMPORT_WORLDMAP,
success));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private File getOwnWorldmapFolder(Context context) {
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
File ownWorldmapFolder = null;
for (File f : storageDir.listFiles()) {
if (f.getName().equals(Constants.FILENAME_WORLDMAP_DIRECTORY)) {
ownWorldmapFolder = f;
break;
}
}
if (ownWorldmapFolder == null) {
ownWorldmapFolder = new File(storageDir, Constants.FILENAME_WORLDMAP_DIRECTORY);
ownWorldmapFolder.mkdir();
}
return ownWorldmapFolder;
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void clickExportSaveGames() {
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_EXPORT_SAVEGAMES);
showStartExportInfo(view -> startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(),
-SLOT_NUMBER_EXPORT_SAVEGAMES));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@RequiresApi(api = Build.VERSION_CODES.P)
private void clickImportSaveGames() {
startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(), -SLOT_NUMBER_IMPORT_SAVEGAMES);
showStartImportSavesInfo(view -> startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(),
-SLOT_NUMBER_IMPORT_SAVEGAMES));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@RequiresApi(api = Build.VERSION_CODES.P)
private void clickImportWorldmap() {
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_IMPORT_WORLDMAP);
showStartImportWorldmapInfo(view -> startActivityForResult(AndroidStorage.getNewSelectZipIntent(),
-SLOT_NUMBER_IMPORT_WORLDMAP));
}
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver, DocumentFile targetFolder, DocumentFile[] files) {
final Dialog d = CustomDialogFactory.createDialog(this,
getString(R.string.loadsave_export_overwrite_confirmation_title),
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.loadsave_export_overwrite_confirmation),
null,
true);
@RequiresApi(api = Build.VERSION_CODES.P)
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver,
DocumentFile targetFolder,
File[] files) {
final CustomDialog d = CustomDialogFactory.createDialog(this,
getString(R.string.loadsave_export_overwrite_confirmation_title),
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.loadsave_export_overwrite_confirmation),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.yes, v -> exportSaveGamesFolderContentToFolder(resolver, targetFolder, files));
CustomDialogFactory.addButton(d,
android.R.string.yes,
v -> exportSaveGamesFolderContentToFolder(targetFolder, files));
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d);
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void showConfirmOverwriteByImportQuestion(ContentResolver resolver,
DocumentFile appSavegameFolder,
List<DocumentFile> alreadyExistingFiles,
List<DocumentFile> newFiles) {
final String title = getString(R.string.loadsave_import_overwrite_confirmation_title);
String message = getString(R.string.loadsave_import_overwrite_confirmation);
String message = getString(R.string.loadsave_import_file_exists_question);
StringBuilder sb = new StringBuilder();
sb.append('\n');
@@ -557,48 +659,96 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
for (int i = 0; i < amount && i < 3; i++) {
ArrayList<CustomDialog> dialogs = new ArrayList<>(amount);
for (int i = 0; i < amount; i++) {
DocumentFile alreadyExistingFile = alreadyExistingFiles.get(i);
String alreadyExistingFileName = alreadyExistingFile.getName();
FileHeader fileHeader = Savegames.quickload(context, getSlotFromSavegameFileName(alreadyExistingFileName));
sb.append('\n');
String fileHeaderDesription = "";
if (fileHeader != null)
fileHeaderDesription = fileHeader.describe();
int slot = getSlotFromSavegameFileName(alreadyExistingFile.getName());
FileHeader existingFileHeader = Savegames.quickload(context, slot);
FileHeader importedFileHeader = null;
try (InputStream stream = resolver.openInputStream(alreadyExistingFile.getUri());
DataInputStream dataStream = new DataInputStream(stream)) {
importedFileHeader = new FileHeader(dataStream, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
continue;
} catch (IOException e) {
e.printStackTrace();
continue;
}
sb.append(getString(R.string.loadsave_import_overwrite_confirmation_file_pattern, alreadyExistingFileName, fileHeaderDesription));
// sb.append(alreadyExistingFile.getName());
}
if (amount > 3) {
sb.append("\n...");
}
message = message + sb;
final Dialog d = CustomDialogFactory.createDialog(this,
title,
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
message,
null,
true);
StringBuilder messageSb = new StringBuilder();
String existingFileDescription = getString(R.string.loadsave_import_existing_description,
Integer.toString(slot),
existingFileHeader.describe());
String importedFileDescription = getString(R.string.loadsave_import_imported_description,
Integer.toString(slot),
importedFileHeader.describe());
messageSb.append(getString(R.string.loadsave_import_file_exists_question,
existingFileDescription,
importedFileDescription));
CustomDialogFactory.addButton(d, android.R.string.yes, v -> newFiles.addAll(alreadyExistingFiles));
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.setDismissListener(d, dialog -> {
String m = messageSb.toString();
CustomDialog dialog = CustomDialogFactory.createDialog(this,
title,
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
m,
null,
true,
false,
true);
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_existing, v -> {
//do nothing
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
});
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_imported, v -> {
newFiles.add(alreadyExistingFile);
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
});
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_add_as_new, v -> {
newFiles.add(null);//add a null element as marker to know later if the next file
// should be imported as new or overwrite the existing one
newFiles.add(alreadyExistingFile);
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
});
CustomDialogFactory.addCancelButton(dialog, android.R.string.cancel);
CustomDialogFactory.setCancelListener(dialog, v -> {
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES, false);
});
dialogs.add(dialog);
}
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void GoToNextConflictOrFinish(ContentResolver resolver,
DocumentFile appSavegameFolder,
List<DocumentFile> newFiles,
ArrayList<CustomDialog> dialogs) {
if (dialogs.stream().count() > 0) {
CustomDialog d = dialogs.remove(0);
CustomDialogFactory.show(d);
} else {
importSaveGames(resolver, appSavegameFolder, newFiles);
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES);
});
CustomDialogFactory.show(d);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK)
if (resultCode != Activity.RESULT_OK) {
return;
}
// Uri uri = data.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switch (-requestCode) {
case SLOT_NUMBER_EXPORT_SAVEGAMES:
exportSaveGames(data);
@@ -631,48 +781,90 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
//region show Dialogs
private void showErrorImportingWorldmapWrongDirectory() {
final Dialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.loadsave_import_worldmap_unsuccessfull),
getString(R.string.loadsave_import_worldmap_unsuccessfull_wrong_directory));
//region Import/Export
@RequiresApi(api = Build.VERSION_CODES.P)
private void showStartExportInfo(OnClickListener onOk) {
final CustomDialog d = CustomDialogFactory.createDialog(this,
getString(R.string.loadsave_export),
getResources().getDrawable(android.R.drawable.ic_dialog_info),
getString(R.string.loadsave_export_info),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d);
}
private void showErrorImportingSaveGameUnknown() {
final Dialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.loadsave_import_save_unsuccessfull),
getString(R.string.loadsave_import_save_unsuccessfull_unknown));
@RequiresApi(api = Build.VERSION_CODES.P)
private void showStartImportSavesInfo(OnClickListener onOk) {
final CustomDialog d = CustomDialogFactory.createDialog(this,
getString(R.string.loadsave_import_save),
getResources().getDrawable(android.R.drawable.ic_dialog_info),
getString(R.string.loadsave_import_save_info),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d);
}
@RequiresApi(api = Build.VERSION_CODES.P)
private void showStartImportWorldmapInfo(OnClickListener onOk) {
final CustomDialog d = CustomDialogFactory.createDialog(this,
getString(R.string.loadsave_import_worldmap),
getResources().getDrawable(android.R.drawable.ic_dialog_info),
getString(R.string.loadsave_import_worldmap_info),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.yes, onOk);
CustomDialogFactory.addDismissButton(d, android.R.string.no);
CustomDialogFactory.show(d);
}
private void showErrorImportingWorldmapWrongDirectory() {
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.loadsave_import_worldmap_unsuccessfull),
getString(R.string.loadsave_import_worldmap_wrong_file));
CustomDialogFactory.show(d);
}
private void showErrorExportingSaveGamesUnknown() {
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.loadsave_export_unsuccessfull),
getString(R.string.loadsave_export_error_unknown));
CustomDialogFactory.show(d);
}
//endregion
private void showErrorLoadingEmptySlot() {
final Dialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.startscreen_error_loading_game),
getString(R.string.startscreen_error_loading_empty_slot));
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
getString(R.string.startscreen_error_loading_game),
getString(R.string.startscreen_error_loading_empty_slot));
CustomDialogFactory.show(d);
}
private void showSlotGetsDeletedOnLoadWarning(final int slot) {
final Dialog d = CustomDialogFactory.createDialog(this,
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
null,
true);
final CustomDialog d = CustomDialogFactory.createDialog(this,
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, v -> completeLoadSaveActivity(slot));
CustomDialogFactory.show(d);
}
private void showConfirmoverwriteQuestion(final int slot, String message) {
final String title =
getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
final Dialog d = CustomDialogFactory.createDialog(this,
title,
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
message,
null,
true);
private void showConfirmOverwriteQuestion(final int slot, String message) {
final String title = getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
final CustomDialog d = CustomDialogFactory.createDialog(this,
title,
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
message,
null,
true);
CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot));
CustomDialogFactory.addDismissButton(d, android.R.string.no);

View File

@@ -20,11 +20,12 @@ import com.gpl.rpg.AndorsTrail.savegames.Savegames;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CloudsAnimatorView;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
public final class LoadingActivity extends AndorsTrailBaseActivity implements OnResourcesLoadedListener, OnSceneLoadedListener {
private WorldSetup setup;
private Dialog progressDialog;
private CustomDialog progressDialog;
private CloudsAnimatorView clouds_back, clouds_mid, clouds_front;
boolean loaded = false;
@@ -165,7 +166,7 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On
}
private void showLoadingFailedDialog(int messageResourceID) {
final Dialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_failed_title), null, getResources().getString(messageResourceID), null, true);
final CustomDialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_failed_title), null, getResources().getString(messageResourceID), null, true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
@Override

View File

@@ -43,6 +43,7 @@ import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CombatView;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons;
import com.gpl.rpg.AndorsTrail.view.ItemContainerAdapter;
import com.gpl.rpg.AndorsTrail.view.MainView;
@@ -247,7 +248,7 @@ public final class MainActivity
final ItemContainerAdapter inventoryListAdapter = new QuickslotsItemContainerAdapter(lv.getContext(), world.tileManager, world.model.player.inventory.usableItems(), world.model.player, wornTiles);
lv.setAdapter(inventoryListAdapter);
final Dialog d = CustomDialogFactory.createDialog(v.getContext(),
final CustomDialog d = CustomDialogFactory.createDialog(v.getContext(),
v.getResources().getString(R.string.inventory_assign),
v.getResources().getDrawable(R.drawable.ui_icon_equipment),
v.getResources().getString(R.string.inventory_selectitem), view, false);

View File

@@ -1,14 +1,7 @@
package com.gpl.rpg.AndorsTrail.activity;
import android.content.Context;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
@@ -39,7 +32,5 @@ public final class Preferences extends PreferenceActivity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
app.setLocale(this);
}
}

View File

@@ -11,6 +11,7 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CloudsAnimatorView;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
import android.app.Activity;
import android.app.Dialog;
@@ -114,7 +115,7 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
final Dialog d = CustomDialogFactory.createDialog(this,
final CustomDialog d = CustomDialogFactory.createDialog(this,
getResources().getString(R.string.dialog_permission_information_title),
getResources().getDrawable(android.R.drawable.ic_dialog_info),
getResources().getString(R.string.dialog_permission_information),

View File

@@ -28,10 +28,8 @@ import com.gpl.rpg.AndorsTrail.Dialogs;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.WorldSetup;
import com.gpl.rpg.AndorsTrail.activity.AboutActivity;
import com.gpl.rpg.AndorsTrail.activity.LoadSaveActivity;
import com.gpl.rpg.AndorsTrail.activity.LoadingActivity;
import com.gpl.rpg.AndorsTrail.activity.Preferences;
import com.gpl.rpg.AndorsTrail.activity.StartScreenActivity;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
@@ -40,20 +38,17 @@ import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
public class StartScreenActivity_MainMenu extends Fragment {
private static final int INTENTREQUEST_PREFERENCES = 7;
public static final int INTENTREQUEST_LOADGAME = 9;
public static final int INTENTREQUEST_EXPORT_SAVE = 11;
public static final int INTENTREQUEST_IMPORT_SAVE = 13;
private boolean hasExistingGame = false;
private Button startscreen_continue;
private Button startscreen_newgame;
private Button startscreen_load;
private Button startscreen_import;
private Button startscreen_export;
private ViewGroup save_preview_holder;
private ImageView save_preview_hero_icon;
private TextView save_preview_hero_desc;
@@ -65,231 +60,224 @@ public class StartScreenActivity_MainMenu extends Fragment {
super.onCreateView(inflater, container, savedInstanceState);
if (container != null) {
container.removeAllViews();
}
if (container != null) {
container.removeAllViews();
}
View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false);
View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false);
save_preview_holder = (ViewGroup) root.findViewById(R.id.save_preview_holder);
save_preview_hero_icon = (ImageView) root.findViewById(R.id.save_preview_hero_icon);
save_preview_hero_desc = (TextView) root.findViewById(R.id.save_preview_hero_desc);
save_preview_holder = (ViewGroup) root.findViewById(R.id.save_preview_holder);
save_preview_hero_icon = (ImageView) root.findViewById(R.id.save_preview_hero_icon);
save_preview_hero_desc = (TextView) root.findViewById(R.id.save_preview_hero_desc);
startscreen_continue = (Button) root.findViewById(R.id.startscreen_continue);
startscreen_continue.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
}
});
startscreen_continue = (Button) root.findViewById(R.id.startscreen_continue);
startscreen_continue.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
}
});
startscreen_newgame = (Button) root.findViewById(R.id.startscreen_newgame);
startscreen_newgame.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (hasExistingGame) {
comfirmNewGame();
} else {
createNewGame();
}
}
});
startscreen_newgame = (Button) root.findViewById(R.id.startscreen_newgame);
startscreen_newgame.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (hasExistingGame) {
comfirmNewGame();
} else {
createNewGame();
}
}
});
Button b = (Button) root.findViewById(R.id.startscreen_about);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startActivity(new Intent(getActivity(), AboutActivity.class));
}
});
Button b = (Button) root.findViewById(R.id.startscreen_about);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startActivity(new Intent(getActivity(), AboutActivity.class));
}
});
b = (Button) root.findViewById(R.id.startscreen_preferences);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(getActivity(), Preferences.class);
StartScreenActivity_MainMenu.this.startActivityForResult(intent, INTENTREQUEST_PREFERENCES);
}
});
b = (Button) root.findViewById(R.id.startscreen_preferences);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(getActivity(), Preferences.class);
StartScreenActivity_MainMenu.this.startActivityForResult(intent, INTENTREQUEST_PREFERENCES);
}
});
startscreen_load = (Button) root.findViewById(R.id.startscreen_load);
startscreen_load.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
if (hasExistingGame && app != null && app.getWorld() != null && app.getWorld().model != null
&& app.getWorld().model.statistics != null && !app.getWorld().model.statistics.hasUnlimitedSaves()) {
final Dialog d = CustomDialogFactory.createDialog(getActivity(),
getString(R.string.startscreen_load_game),
getResources().getDrawable(android.R.drawable.ic_delete),
getString(R.string.startscreen_load_game_confirm),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
}
});
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
CustomDialogFactory.show(d);
startscreen_load = (Button) root.findViewById(R.id.startscreen_load);
startscreen_load.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
if (hasExistingGame && app != null && app.getWorld() != null && app.getWorld().model != null
&& app.getWorld().model.statistics != null && !app.getWorld().model.statistics.hasUnlimitedSaves()) {
final CustomDialog d = CustomDialogFactory.createDialog(getActivity(),
getString(R.string.startscreen_load_game),
getResources().getDrawable(android.R.drawable.ic_delete),
getString(R.string.startscreen_load_game_confirm),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
}
});
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
CustomDialogFactory.show(d);
} else {
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
}
}
});
} else {
Dialogs.showLoad(StartScreenActivity_MainMenu.this);
}
}
});
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
continueGame(true, 0, "Debug player");
} else {
continueGame(true, 0, "Player");
}
} else if (AndorsTrailApplication.DEVELOPMENT_FORCE_CONTINUEGAME) {
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
}
// if it is a new version we first fire a welcome screen in onResume
// and afterwards check the permissions
if (!isNewVersion()) {
checkAndRequestPermissions(getActivity());
migrateDataOnDemand(getActivity());
}
if (AndorsTrailApplication.DEVELOPMENT_FORCE_STARTNEWGAME) {
if (AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES) {
continueGame(true, 0, "Debug player");
} else {
continueGame(true, 0, "Player");
}
} else if (AndorsTrailApplication.DEVELOPMENT_FORCE_CONTINUEGAME) {
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
}
return root;
}
// if it is a new version we first fire a welcome screen in onResume
// and afterwards check the permissions
if (!isNewVersion()) {
checkAndRequestPermissions(getActivity());
migrateDataOnDemand(getActivity());
}
@Override
public void onResume() {
super.onResume();
return root;
}
String playerName;
String displayInfo = null;
int iconID = TileManager.CHAR_HERO;
boolean isDead = false;
@Override
public void onResume() {
super.onResume();
FileHeader header = Savegames.quickload(getActivity(), Savegames.SLOT_QUICKSAVE);
if (header != null && header.playerName != null) {
playerName = header.playerName;
displayInfo = header.displayInfo;
iconID = header.iconID;
isDead = header.isDead;
} else {
// Before fileversion 14 (v0.6.7), quicksave was stored in Shared preferences
SharedPreferences p = getActivity().getSharedPreferences("quicksave", Activity.MODE_PRIVATE);
playerName = p.getString("playername", null);
if (playerName != null) {
displayInfo = "level " + p.getInt("level", -1);
}
}
hasExistingGame = (playerName != null);
setButtonState(playerName, displayInfo, iconID, isDead);
String playerName;
String displayInfo = null;
int iconID = TileManager.CHAR_HERO;
boolean isDead = false;
if (isNewVersion()) {
Dialogs.showNewVersion(getActivity(), new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
setCurrentVersionForVersionCheck();
checkAndRequestPermissions(getActivity());
migrateDataOnDemand(getActivity());
startscreen_load.setEnabled(true);
}
});
}
FileHeader header = Savegames.quickload(getActivity(), Savegames.SLOT_QUICKSAVE);
if (header != null && header.playerName != null) {
playerName = header.playerName;
displayInfo = header.displayInfo;
iconID = header.iconID;
isDead = header.isDead;
} else {
// Before fileversion 14 (v0.6.7), quicksave was stored in Shared preferences
SharedPreferences p = getActivity().getSharedPreferences("quicksave", Activity.MODE_PRIVATE);
playerName = p.getString("playername", null);
if (playerName != null) {
displayInfo = "level " + p.getInt("level", -1);
}
}
hasExistingGame = (playerName != null);
setButtonState(playerName, displayInfo, iconID, isDead);
startscreen_load.setEnabled(true);
}
if (isNewVersion()) {
Dialogs.showNewVersion(getActivity(), new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
setCurrentVersionForVersionCheck();
checkAndRequestPermissions(getActivity());
migrateDataOnDemand(getActivity());
}
});
}
@TargetApi(29)
public void migrateDataOnDemand(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if (AndroidStorage.shouldMigrateToInternalStorage(activity.getApplicationContext())) {
final Dialog d = CustomDialogFactory.createDialog(activity,
getString(R.string.startscreen_migration_title),
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_migration_text),
null,
true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
startscreen_load.setEnabled(true);
}
});
CustomDialogFactory.show(d);
if (!AndroidStorage.migrateToInternalStorage(activity.getApplicationContext())) {
final Dialog errorDlg = CustomDialogFactory.createDialog(activity,
getString(R.string.startscreen_migration_title),
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_migration_failure),
null,
true);
CustomDialogFactory.addDismissButton(errorDlg, android.R.string.ok);
d.cancel();
CustomDialogFactory.show(errorDlg);
}
} else {
L.log("INFO: No external files or destination folder ist not empty. No data migration.");
}
} else {
L.log("INFO: No read permission on external folder. No data migration.");
}
}
}
}
private static final int READ_EXTERNAL_STORAGE_REQUEST = 1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
@TargetApi(29)
public void migrateDataOnDemand(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if (AndroidStorage.shouldMigrateToInternalStorage(activity.getApplicationContext())) {
final CustomDialog d = CustomDialogFactory.createDialog(activity,
getString(R.string.startscreen_migration_title),
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_migration_text),
null,
true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
CustomDialogFactory.show(d);
if (!AndroidStorage.migrateToInternalStorage(activity.getApplicationContext())) {
final CustomDialog errorDlg = CustomDialogFactory.createDialog(activity,
getString(R.string.startscreen_migration_title),
activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
getString(R.string.startscreen_migration_failure),
null,
true);
CustomDialogFactory.addDismissButton(errorDlg, android.R.string.ok);
d.cancel();
CustomDialogFactory.show(errorDlg);
}
} else {
L.log("INFO: No external files or destination folder ist not empty. No data migration.");
}
} else {
L.log("INFO: No read permission on external folder. No data migration.");
}
}
}
@TargetApi(23)
public static void checkAndRequestPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
}
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
}
}
}
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
listener = (OnNewGameRequestedListener) activity;
}
@TargetApi(23)
public static void checkAndRequestPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
}
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
}
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
listener = (OnNewGameRequestedListener) activity;
}
private void setButtonState(final String playerName, final String displayInfo, int iconID, boolean isDead) {
startscreen_continue.setEnabled(hasExistingGame && !isDead);
startscreen_newgame.setEnabled(true);
if (hasExistingGame) {
TileManager tm = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorld().tileManager;
tm.setImageViewTileForPlayer(getResources(), save_preview_hero_icon, iconID);
save_preview_hero_desc.setText((isDead ? getString(R.string.rip_startscreen) : "") + playerName + ", " + displayInfo);
save_preview_holder.setVisibility(View.VISIBLE);
} else {
save_preview_holder.setVisibility(View.GONE);
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
private void continueGame(boolean createNewCharacter, int loadFromSlot, String name) {
final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorldSetup();
setup.createNewCharacter = createNewCharacter;
setup.loadFromSlot = loadFromSlot;
setup.newHeroName = name;
startActivity(new Intent(getActivity(), LoadingActivity.class));
}
private void setButtonState(final String playerName, final String displayInfo, int iconID, boolean isDead) {
startscreen_continue.setEnabled(hasExistingGame && !isDead);
startscreen_newgame.setEnabled(true);
if (hasExistingGame) {
TileManager tm = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorld().tileManager;
tm.setImageViewTileForPlayer(getResources(), save_preview_hero_icon, iconID);
save_preview_hero_desc.setText((isDead ? getString(R.string.rip_startscreen) : "") + playerName + ", " + displayInfo);
save_preview_holder.setVisibility(View.VISIBLE);
} else {
save_preview_holder.setVisibility(View.GONE);
}
}
private void comfirmNewGame() {
private void continueGame(boolean createNewCharacter, int loadFromSlot, String name) {
final WorldSetup setup = AndorsTrailApplication.getApplicationFromActivity(getActivity()).getWorldSetup();
setup.createNewCharacter = createNewCharacter;
setup.loadFromSlot = loadFromSlot;
setup.newHeroName = name;
startActivity(new Intent(getActivity(), LoadingActivity.class));
}
private void comfirmNewGame() {
// new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.AndorsTrailStyle_Dialog))
// .setTitle(R.string.startscreen_newgame)
// .setMessage(R.string.startscreen_newgame_confirm)
@@ -307,39 +295,38 @@ public class StartScreenActivity_MainMenu extends Fragment {
// .create().show();
//
//
final Dialog d = CustomDialogFactory.createDialog(getActivity(),
getString(R.string.startscreen_newgame),
getResources().getDrawable(android.R.drawable.ic_delete),
getResources().getString(R.string.startscreen_newgame_confirm),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
createNewGame();
}
});
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
final CustomDialog d = CustomDialogFactory.createDialog(getActivity(),
getString(R.string.startscreen_newgame),
getResources().getDrawable(android.R.drawable.ic_delete),
getResources().getString(R.string.startscreen_newgame_confirm),
null,
true);
CustomDialogFactory.addButton(d, android.R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
createNewGame();
}
});
CustomDialogFactory.addDismissButton(d, android.R.string.cancel);
CustomDialogFactory.show(d);
CustomDialogFactory.show(d);
}
}
private static final String versionCheck = "lastversion";
private static final String versionCheck = "lastversion";
private boolean isNewVersion() {
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
int lastversion = s.getInt(versionCheck, 0);
if (lastversion >= AndorsTrailApplication.CURRENT_VERSION) return false;
return true;
}
private boolean isNewVersion() {
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
int lastversion = s.getInt(versionCheck, 0);
if (lastversion >= AndorsTrailApplication.CURRENT_VERSION) return false;
return true;
}
private void setCurrentVersionForVersionCheck() {
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
Editor e = s.edit();
e.putInt(versionCheck, AndorsTrailApplication.CURRENT_VERSION);
e.commit();
}
private void setCurrentVersionForVersionCheck() {
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
Editor e = s.edit();
e.putInt(versionCheck, AndorsTrailApplication.CURRENT_VERSION);
e.commit();
}
@Override
@@ -347,19 +334,17 @@ public class StartScreenActivity_MainMenu extends Fragment {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case INTENTREQUEST_LOADGAME:
if (resultCode != Activity.RESULT_OK) break;
final boolean wasImportOrExport = data.getBooleanExtra("import_export", false);
final int slot = data.getIntExtra("slot", 1);
if (wasImportOrExport) {
if(slot == LoadSaveActivity.SLOT_NUMBER_EXPORT_SAVEGAMES)
Toast.makeText(getActivity(),R.string.loadsave_export_save_successfull, Toast.LENGTH_LONG).show();
else if(slot == LoadSaveActivity.SLOT_NUMBER_IMPORT_SAVEGAMES)
Toast.makeText(getActivity(),R.string.loadsave_import_save_successfull, Toast.LENGTH_LONG).show();
else if(slot == LoadSaveActivity.SLOT_NUMBER_IMPORT_WORLDMAP)
Toast.makeText(getActivity(),R.string.loadsave_import_worldmap_successfull, Toast.LENGTH_LONG).show();
boolean unsuccessful = resultCode != Activity.RESULT_OK;
if(data == null) break;
break;
}
final boolean wasImportOrExport = data.getBooleanExtra("import_export", false);
if (wasImportOrExport) {
String message = getImportExportMessage(!unsuccessful, data);
Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
break;
}
if (unsuccessful) break;
final int slot = data.getIntExtra("slot", 1);
continueGame(false, slot, null);
break;
case INTENTREQUEST_PREFERENCES:
@@ -368,7 +353,24 @@ public class StartScreenActivity_MainMenu extends Fragment {
}
}
private void updatePreferences(boolean alreadyStartedLoadingResources) {
private String getImportExportMessage(boolean successful, Intent data) {
String message = "";
boolean isImportWorldmap = data.getBooleanExtra("import_worldmap", false);
boolean isImportSaves = data.getBooleanExtra("import_savegames", false);
boolean isExport = data.getBooleanExtra("export", false);
if(isImportWorldmap) {
message = getString(successful ? R.string.loadsave_import_worldmap_successfull : R.string.loadsave_import_worldmap_unsuccessfull);
} else if(isImportSaves) {
message = getString(successful ? R.string.loadsave_import_save_successfull : R.string.loadsave_import_save_unsuccessfull);
} else if(isExport) {
message = getString(successful ? R.string.loadsave_export_successfull : R.string.loadsave_export_unsuccessfull);
}
return message;
}
private void updatePreferences(boolean alreadyStartedLoadingResources) {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity());
AndorsTrailPreferences preferences = app.getPreferences();
preferences.read(getActivity());
@@ -398,17 +400,17 @@ public class StartScreenActivity_MainMenu extends Fragment {
}
public interface OnNewGameRequestedListener {
public void onNewGameRequested();
}
public interface OnNewGameRequestedListener {
public void onNewGameRequested();
}
private OnNewGameRequestedListener listener = null;
private OnNewGameRequestedListener listener = null;
private void createNewGame() {
if (listener != null) {
listener.onNewGameRequested();
}
}
private void createNewGame() {
if (listener != null) {
listener.onNewGameRequested();
}
}
}

View File

@@ -7,7 +7,7 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.Range;
public final class Constants {
public static final int PERCENT_EXP_LOST_WHEN_DIED = 30;
public static final int PERCENT_EXP_LOST_WHEN_DIED = 20;
public static final int LEVELUP_EFFECT_HEALTH = 5;
public static final int LEVELUP_EFFECT_ATK_CH = 5;
public static final int LEVELUP_EFFECT_ATK_DMG = 1;

View File

@@ -2,6 +2,7 @@ package com.gpl.rpg.AndorsTrail.controller;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.SparseIntArray;
import android.view.KeyEvent;
import android.view.View;
@@ -98,28 +99,36 @@ public final class InputController implements OnClickListener, OnLongClickListen
// Keys mapping to UP_LEFT
key = KEY_MOVE_UP_LEFT;
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_LEFT, key);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_LEFT, key);
}
keyMap.put(KeyEvent.KEYCODE_NUMPAD_7, key);
keyMap.put(KeyEvent.KEYCODE_7, key);
keyMap.put(KeyEvent.KEYCODE_MOVE_HOME, key);
// Keys mapping to UP_RIGHT
key = KEY_MOVE_UP_RIGHT;
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_RIGHT, key);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
keyMap.put(KeyEvent.KEYCODE_DPAD_UP_RIGHT, key);
}
keyMap.put(KeyEvent.KEYCODE_NUMPAD_9, key);
keyMap.put(KeyEvent.KEYCODE_9, key);
keyMap.put(KeyEvent.KEYCODE_PAGE_UP, key);
// Keys mapping to DOWN_LEFT
key = KEY_MOVE_DOWN_LEFT;
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_LEFT, key);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_LEFT, key);
}
keyMap.put(KeyEvent.KEYCODE_NUMPAD_1, key);
keyMap.put(KeyEvent.KEYCODE_1, key);
keyMap.put(KeyEvent.KEYCODE_MOVE_END, key);
// Keys mapping to DOWN_RIGHT
key = KEY_MOVE_DOWN_RIGHT;
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_RIGHT, key);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
keyMap.put(KeyEvent.KEYCODE_DPAD_DOWN_RIGHT, key);
}
keyMap.put(KeyEvent.KEYCODE_NUMPAD_3, key);
keyMap.put(KeyEvent.KEYCODE_3, key);
keyMap.put(KeyEvent.KEYCODE_PAGE_DOWN, key);

View File

@@ -19,6 +19,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
import com.gpl.rpg.AndorsTrail.util.HashMapHelper;
public final class GameStatistics {
private int deaths = 0;
@@ -36,10 +37,10 @@ public final class GameStatistics {
public void addMonsterKill(MonsterType monsterType) {
// Track monster kills by type ID, for savegame file
killedMonstersByTypeID.put(monsterType.id, killedMonstersByTypeID.getOrDefault((monsterType.id), 0) + 1);
killedMonstersByTypeID.put(monsterType.id, getNumberOfKillsForMonsterType(monsterType.id) + 1);
// Also track by name, for statistics display (multiple IDs w/same name don't matter to player)
killedMonstersByName.put(monsterType.name, killedMonstersByName.getOrDefault(monsterType.name, 0) + 1);
killedMonstersByName.put(monsterType.name, getNumberOfKillsForMonsterName(monsterType.name) + 1);
}
public void addPlayerDeath(int lostExp) {
@@ -50,8 +51,7 @@ public final class GameStatistics {
}
public void addItemUsage(ItemType type) {
final String n = type.id;
if (!usedItems.containsKey(n)) usedItems.put(n, 1);
else usedItems.put(n, usedItems.get(n) + 1);
usedItems.put(n, HashMapHelper.getOrDefault(usedItems, n,0) + 1);
}
public int getDeaths() {
@@ -73,15 +73,11 @@ public final class GameStatistics {
public boolean isDead() { return !hasUnlimitedLives() && getLivesLeft() < 1; }
public int getNumberOfKillsForMonsterType(String monsterTypeID) {
Integer v = killedMonstersByTypeID.get(monsterTypeID);
if (v == null) return 0;
return v;
return HashMapHelper.getOrDefault(killedMonstersByTypeID, monsterTypeID, 0);
}
public int getNumberOfKillsForMonsterName(String monsterName) {
Integer v = killedMonstersByName.get(monsterName);
if (v == null) return 0;
return v;
return HashMapHelper.getOrDefault(killedMonstersByName, monsterName, 0);
}
public String getTop5MostCommonlyKilledMonsters(WorldContext world, Resources res) {
@@ -144,20 +140,15 @@ public final class GameStatistics {
}
public int getNumberOfUsedItems() {
int result = 0;
for (int v : usedItems.values()) result += v;
return result;
return HashMapHelper.sumIntegerValues(usedItems);
}
public int getNumberOfTimesItemHasBeenUsed(String itemId) {
if (!usedItems.containsKey(itemId)) return 0;
return usedItems.get(itemId);
return HashMapHelper.getOrDefault(usedItems, itemId, 0);
}
public int getNumberOfKilledMonsters() {
int result = 0;
for (int v : killedMonstersByTypeID.values()) result += v;
return result;
return HashMapHelper.sumIntegerValues(killedMonstersByTypeID);
}
private static final Comparator<Entry<String, Integer>> descendingValueComparator = new Comparator<Entry<String, Integer>>() {
@@ -186,7 +177,7 @@ public final class GameStatistics {
// Also track by name, for statistics display (multiple IDs w/same name don't matter to player)
MonsterType t = world.monsterTypes.getMonsterType(id);
if (t != null) killedMonstersByName.put(t.name, killedMonstersByName.getOrDefault(t.name, 0) + value);
if (t != null) killedMonstersByName.put(t.name, getNumberOfKillsForMonsterName(t.name) + value);
}
if (fileversion <= 17) return;

View File

@@ -83,7 +83,7 @@ public final class SkillCollection {
public static final int PER_SKILLPOINT_INCREASE_COINFINDER_CHANCE_PERCENT = 30;
public static final int PER_SKILLPOINT_INCREASE_MAGICFINDER_CHANCE_PERCENT = 50;
public static final int PER_SKILLPOINT_INCREASE_COINFINDER_QUANTITY_PERCENT = 50;
public static final int PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT = 5;
public static final int PER_SKILLPOINT_INCREASE_MORE_EXP_PERCENT = 10;
public static final int PER_SKILLPOINT_INCREASE_CLEAVE_AP = 3;
public static final int PER_SKILLPOINT_INCREASE_EATER_HEALTH = 1;
public static final int PER_SKILLPOINT_INCREASE_FORTITUDE_HEALTH = 1;

View File

@@ -111,7 +111,7 @@ public final class Player extends Actor {
baseTraits.criticalSkill = 0;
baseTraits.criticalMultiplier = 1;
baseTraits.damagePotential.set(1, 1);
baseTraits.blockChance = 0;
baseTraits.blockChance = 9;
baseTraits.damageResistance = 0;
baseTraits.useItemCost = 5;
baseTraits.reequipCost = 5;

View File

@@ -308,6 +308,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.items_consumables_omi1, "items_consumables_omi1", sz1x1, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.items_feygard1, "items_feygard1", new Size(6, 2), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.items_omi2, "items_omi2", new Size(6, 5), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.items_omgeeky, "items_omgeeky", new Size(10, 3), sz1x1, mTileSize);
/*INSERT_ITEMS_TILESETS_HERE*/
loader.prepareTileset(R.drawable.monsters_armor1, "monsters_armor1", sz1x1, sz1x1, mTileSize);
@@ -435,6 +436,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.map_rock_3, "map_rock_3", new Size(6, 5), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_sign_ladder_omi2, "map_sign_ladder_omi2", new Size(8, 4), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_transition_6, "map_transition_6", new Size(18, 8), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_ratdom, "map_ratdom", new Size(18, 6), sz1x1, mTileSize);
/*INSERT_MAP_TILESETS_HERE*/
loader.prepareTileset(R.drawable.effect_blood4, "effect_blood4", new Size(7, 2), sz1x1, mTileSize);

View File

@@ -1,7 +1,6 @@
package com.gpl.rpg.AndorsTrail.savegames;
import java.io.ByteArrayOutputStream;
import java.io.Console;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -34,95 +33,99 @@ import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
import com.gpl.rpg.AndorsTrail.util.L;
public final class Savegames {
public static final int SLOT_QUICKSAVE = 0;
public static final long DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED = -1;
public static final int SLOT_QUICKSAVE = 0;
public static final long DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED = -1;
private static long lastBackup = 0;
private static long lastBackup = 0;
public static enum LoadSavegameResult {
success, unknownError, savegameIsFromAFutureVersion, cheatingDetected
}
public static boolean saveWorld(WorldContext world, Context androidContext, int slot) {
try {
final String displayInfo = androidContext.getString(R.string.savegame_currenthero_displayinfo, world.model.player.getLevel(), world.model.player.getTotalExperience(), world.model.player.getGold());
if (slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
world.model.player.savedVersion++;
}
String id = world.model.player.id;
long savedVersion = world.model.player.savedVersion;
public static enum LoadSavegameResult {
success
, unknownError
, savegameIsFromAFutureVersion
, cheatingDetected
}
// Create the savegame in a temporary memorystream first to ensure that the savegame can
// be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
saveWorld(world, bos, displayInfo);
byte[] savegame = bos.toByteArray();
bos.close();
public static boolean saveWorld(WorldContext world, Context androidContext, int slot) {
try {
final String displayInfo = androidContext.getString(R.string.savegame_currenthero_displayinfo, world.model.player.getLevel(), world.model.player.getTotalExperience(), world.model.player.getGold());
if (slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
world.model.player.savedVersion++;
}
String id = world.model.player.id;
long savedVersion = world.model.player.savedVersion;
FileOutputStream fos = getOutputFile(androidContext, slot);
fos.write(savegame);
fos.close();
// Create the savegame in a temporary memorystream first to ensure that the savegame can
// be created correctly. We don't want to trash the user's file unneccessarily if there is an error.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
saveWorld(world, bos, displayInfo);
byte[] savegame = bos.toByteArray();
bos.close();
if (!world.model.statistics.hasUnlimitedSaves()) {
if (slot != SLOT_QUICKSAVE) {
androidContext.deleteFile(Constants.FILENAME_SAVEGAME_QUICKSAVE);
writeCheatCheck(androidContext, savedVersion, id);
} else if (SystemClock.uptimeMillis() > lastBackup + 120000) {
writeBackup(androidContext, savegame, id);
lastBackup = SystemClock.uptimeMillis();
}
}
FileOutputStream fos = getOutputFile(androidContext, slot);
fos.write(savegame);
fos.close();
return true;
} catch (IOException e) {
L.log("Error saving world: " + e.toString());
return false;
}
}
if (!world.model.statistics.hasUnlimitedSaves()) {
if (slot != SLOT_QUICKSAVE) {
androidContext.deleteFile(Constants.FILENAME_SAVEGAME_QUICKSAVE);
writeCheatCheck(androidContext, savedVersion, id);
} else if (SystemClock.uptimeMillis() > lastBackup + 120000) {
writeBackup(androidContext, savegame, id);
lastBackup = SystemClock.uptimeMillis();
}
}
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
return true;
} catch (IOException e) {
L.log("Error saving world: " + e.toString());
return false;
}
}
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
File backupFile = new File(cheatDetectionFolder, playerId + "X");
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
fileOutputStream.write(savegame);
fileOutputStream.close();
}
File backupFile = new File(cheatDetectionFolder, playerId + "X");
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
fileOutputStream.write(savegame);
fileOutputStream.close();
}
public static LoadSavegameResult loadWorld(WorldContext world, ControllerContext controllers, Context androidContext, int slot) {
try {
FileHeader fh = quickload(androidContext, slot);
if (fh == null) {
return LoadSavegameResult.unknownError;
}
if (!fh.hasUnlimitedSaves && slot != SLOT_QUICKSAVE && triedToCheat(androidContext, fh)) {
return LoadSavegameResult.cheatingDetected;
}
public static LoadSavegameResult loadWorld(WorldContext world, ControllerContext controllers, Context androidContext, int slot) {
try {
FileHeader fh = quickload(androidContext, slot);
if(fh == null) {
return LoadSavegameResult.unknownError;
}
if (!fh.hasUnlimitedSaves && slot != SLOT_QUICKSAVE && triedToCheat(androidContext, fh)) {
return LoadSavegameResult.cheatingDetected;
}
FileInputStream fos = getInputFile(androidContext, slot);
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, fos, fh);
fos.close();
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
FileInputStream fos = getInputFile(androidContext, slot);
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, fos, fh);
fos.close();
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
// save to the quicksave slot before deleting the file
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
return LoadSavegameResult.unknownError;
}
getSlotFile(slot, androidContext).delete();
writeCheatCheck(androidContext, DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED, fh.playerId);
}
return result;
} catch (IOException e) {
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Error loading world: " + e.toString());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
L.log("Load error: " + sw.toString());
}
return LoadSavegameResult.unknownError;
}
}
return LoadSavegameResult.unknownError;
}
getSlotFile(slot, androidContext).delete();
writeCheatCheck(androidContext, DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED, fh.playerId);
}
return result;
} catch (IOException e) {
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Error loading world: " + e.toString());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
L.log("Load error: " + sw.toString());
}
return LoadSavegameResult.unknownError;
}
}
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
long savedVersionToCheck = 0;
@@ -138,9 +141,9 @@ public final class Savegames {
fileInputStream.close();
}
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
return true;
}
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
return true;
}
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
@@ -152,16 +155,16 @@ public final class Savegames {
savedVersionToCheck = cheatDetection.savedVersion;
}
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
}
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
}
dataInputStream.close();
fileInputStream.close();
}
dataInputStream.close();
fileInputStream.close();
}
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
}
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
}
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
if (slot == SLOT_QUICKSAVE) {
@@ -207,18 +210,18 @@ public final class Savegames {
}
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
DataOutputStream dest = new DataOutputStream(outStream);
FileHeader.writeToParcel(dest, world.model.player.getName(),
displayInfo, world.model.player.iconID,
world.model.statistics.isDead(),
world.model.statistics.hasUnlimitedSaves(),
world.model.player.id,
world.model.player.savedVersion);
world.maps.writeToParcel(dest, world);
world.model.writeToParcel(dest);
dest.close();
}
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
DataOutputStream dest = new DataOutputStream(outStream);
FileHeader.writeToParcel(dest, world.model.player.getName(),
displayInfo, world.model.player.iconID,
world.model.statistics.isDead(),
world.model.statistics.hasUnlimitedSaves(),
world.model.player.id,
world.model.player.savedVersion);
world.maps.writeToParcel(dest, world);
world.model.writeToParcel(dest);
dest.close();
}
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, InputStream inState, FileHeader fh) throws IOException {
DataInputStream src = new DataInputStream(inState);
@@ -226,42 +229,42 @@ public final class Savegames {
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
return LoadSavegameResult.savegameIsFromAFutureVersion;
world.maps.readFromParcel(src, world, controllers, header.fileversion);
world.model = new ModelContainer(src, world, controllers, header.fileversion);
src.close();
world.maps.readFromParcel(src, world, controllers, header.fileversion);
world.model = new ModelContainer(src, world, controllers, header.fileversion);
src.close();
if (header.fileversion < 45) {
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
}
onWorldLoaded(res, world, controllers);
if (header.fileversion < 45) {
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
}
return LoadSavegameResult.success;
}
onWorldLoaded(res, world, controllers);
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
controllers.mapController.resetMapsNotRecentlyVisited();
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMaps.map, res, false);
controllers.gameRoundController.resetRoundTimers();
}
return LoadSavegameResult.success;
}
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
controllers.mapController.resetMapsNotRecentlyVisited();
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMaps.map, res, false);
controllers.gameRoundController.resetRoundTimers();
}
public static FileHeader quickload(Context androidContext, int slot) {
try {
if (slot != SLOT_QUICKSAVE) {
File f = getSlotFile(slot, androidContext);
if (!f.exists()) return null;
}
FileInputStream fos = getInputFile(androidContext, slot);
DataInputStream src = new DataInputStream(fos);
final FileHeader header = new FileHeader(src, false);
src.close();
fos.close();
return header;
} catch (Exception e) {
return null;
}
}
public static FileHeader quickload(Context androidContext, int slot) {
try {
if (slot != SLOT_QUICKSAVE) {
File f = getSlotFile(slot, androidContext);
if (!f.exists()) return null;
}
FileInputStream fos = getInputFile(androidContext, slot);
DataInputStream src = new DataInputStream(fos);
final FileHeader header = new FileHeader(src, false);
src.close();
fos.close();
return header;
} catch (Exception e) {
return null;
}
}
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
@@ -273,14 +276,14 @@ public final class Savegames {
dataOutputStream.close();
fileOutputStream.close();
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
dataOutputStream = new DataOutputStream(fileOutputStream);
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
dataOutputStream.close();
fileOutputStream.close();
}
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
dataOutputStream = new DataOutputStream(fileOutputStream);
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
dataOutputStream.close();
fileOutputStream.close();
}
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
public static List<Integer> getUsedSavegameSlots(Context context) {
try {
@@ -303,22 +306,22 @@ public final class Savegames {
}
}
private static final class CheatDetection {
public final int fileversion;
public final long savedVersion;
private static final class CheatDetection {
public final int fileversion;
public final long savedVersion;
// ====== PARCELABLE ===================================================================
// ====== PARCELABLE ===================================================================
public CheatDetection(DataInputStream src) throws IOException {
this.fileversion = src.readInt();
this.savedVersion = src.readLong();
}
public CheatDetection(DataInputStream src) throws IOException {
this.fileversion = src.readInt();
this.savedVersion = src.readLong();
}
public static void writeToParcel(DataOutputStream dest, long savedVersion) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeLong(savedVersion);
}
}
public static void writeToParcel(DataOutputStream dest, long savedVersion) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeLong(savedVersion);
}
}
public static final class FileHeader {
@@ -332,12 +335,12 @@ public final class Savegames {
public final String playerId;
public final long savedVersion;
public String describe() {
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
}
public String describe() {
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
}
// ====== PARCELABLE ===================================================================
// ====== PARCELABLE ===================================================================
public FileHeader(DataInputStream src, boolean skipIcon) throws IOException {
int fileversion = src.readInt();
@@ -352,40 +355,40 @@ public final class Savegames {
this.displayInfo = null;
}
if (fileversion >= 43) {
int id = src.readInt();
if (skipIcon || id > TileManager.LAST_HERO) {
this.iconID = TileManager.CHAR_HERO_0;
this.skipIcon = true;
} else {
this.iconID = id;
}
} else {
this.iconID = TileManager.CHAR_HERO_0;
}
if (fileversion >= 43) {
int id = src.readInt();
if (skipIcon || id > TileManager.LAST_HERO) {
this.iconID = TileManager.CHAR_HERO_0;
this.skipIcon = true;
} else {
this.iconID = id;
}
} else {
this.iconID = TileManager.CHAR_HERO_0;
}
if (fileversion >= 49) {
this.isDead = src.readBoolean();
this.hasUnlimitedSaves = src.readBoolean();
this.playerId = src.readUTF();
this.savedVersion = src.readLong();
} else {
this.isDead = false;
this.hasUnlimitedSaves = true;
this.playerId = "";
this.savedVersion = 0;
}
}
if (fileversion >= 49) {
this.isDead = src.readBoolean();
this.hasUnlimitedSaves = src.readBoolean();
this.playerId = src.readUTF();
this.savedVersion = src.readLong();
} else {
this.isDead = false;
this.hasUnlimitedSaves = true;
this.playerId = "";
this.savedVersion = 0;
}
}
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeUTF(playerName);
dest.writeUTF(displayInfo);
dest.writeInt(iconID);
dest.writeBoolean(isDead);
dest.writeBoolean(hasUnlimitedSaves);
dest.writeUTF(playerId);
dest.writeLong(savedVersion);
}
}
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeUTF(playerName);
dest.writeUTF(displayInfo);
dest.writeInt(iconID);
dest.writeBoolean(isDead);
dest.writeBoolean(hasUnlimitedSaves);
dest.writeUTF(playerId);
dest.writeLong(savedVersion);
}
}
}

View File

@@ -6,20 +6,30 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.content.FileProvider;
import android.support.v4.provider.DocumentFile;
import android.webkit.MimeTypeMap;
import android.os.Handler;
import android.os.Looper;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.util.BackgroundWorker.BackgroundWorkerCallback;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.CancellationException;
import java.util.function.Consumer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public final class AndroidStorage {
public static File getStorageDirectory(Context context, String name) {
@@ -33,16 +43,16 @@ public final class AndroidStorage {
public static boolean shouldMigrateToInternalStorage(Context context) {
boolean ret = false;
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY);
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(),
Constants.FILENAME_SAVEGAME_DIRECTORY);
File internalSaveGameDirectory = getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
if (externalSaveGameDirectory.exists()
&& externalSaveGameDirectory.isDirectory()
&& externalSaveGameDirectory.listFiles().length > 0
&& (
!internalSaveGameDirectory.exists()
|| internalSaveGameDirectory.isDirectory() && internalSaveGameDirectory.listFiles().length < 2)
) {
&& externalSaveGameDirectory.isDirectory()
&& externalSaveGameDirectory.listFiles().length > 0
&& (!internalSaveGameDirectory.exists()
|| internalSaveGameDirectory.isDirectory()
&& internalSaveGameDirectory.listFiles().length < 2)) {
ret = true;
}
return ret;
@@ -51,11 +61,11 @@ public final class AndroidStorage {
public static boolean migrateToInternalStorage(Context context) {
try {
copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER),
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY),
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
} catch (IOException e) {
L.log("Error migrating data: " + e.toString());
L.log("Error migrating data: " + e);
return false;
}
return true;
@@ -96,68 +106,187 @@ public final class AndroidStorage {
}
}
@RequiresApi(api = Build.VERSION_CODES.P)
public static void createZipDocumentFileFromFilesAsync(File[] files,
Context context,
DocumentFile targetDirectory,
String fileName,
String loadingMessage,
Consumer<Boolean> callback) {
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
progressDialog.setOnCancelListener(dialog -> worker.cancel());
ContentResolver resolver = context.getContentResolver();
Handler handler = Handler.createAsync(Looper.getMainLooper());
worker.setTask(workerCallback -> {
try {
workerCallback.onInitialize();
//region create zip file
File zip = File.createTempFile("temp_worldmap", ".zip");
try (OutputStream out = new FileOutputStream(zip)) {
ZipOutputStream zipOut = new ZipOutputStream(out);
for (int i = 0; i < files.length; i++) {
File file = files[i];
try (FileInputStream fis = new FileInputStream(file)) {
workerCallback.onProgress((float) i / files.length);
zipOut.putNextEntry(new ZipEntry(file.getName()));
copyStream(fis, zipOut);
zipOut.closeEntry();
}
}
zipOut.close();
}
//endregion
DocumentFile worldmapZip = DocumentFile.fromFile(zip);
DocumentFile worldmapTarget = targetDirectory.createFile("application/zip", fileName);
if (worldmapTarget != null && worldmapTarget.exists()) {
AndroidStorage.copyDocumentFile(worldmapZip, resolver, worldmapTarget);
workerCallback.onComplete(true);
} else {
throw new FileNotFoundException("Could not create File");
}
} catch (NullPointerException e) {
if (worker.isCancelled()) {
workerCallback.onFailure(new CancellationException("Cancelled"));
} else {
workerCallback.onFailure(e);
}
} catch (Exception e) {
workerCallback.onFailure(e);
}
});
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
worker.run();
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFolder) throws IOException {
copyDocumentFileToNewOrExistingFile(sourceFile, resolver, targetFolder, Constants.NO_FILE_EXTENSION_MIME_TYPE);
}
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFolder, String mimeType) throws IOException {
public static void unzipToDirectory(File zipFile,
File targetDirectory,
boolean overwriteNotSkip) throws IOException {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
}
}
@RequiresApi(api = Build.VERSION_CODES.P)
public static void unzipDocumentFileToDirectoryAsync(DocumentFile zipFile,
Context context,
File targetDirectory,
boolean overwriteNotSkip,
String loadingMessage,
Consumer<Boolean> callback) {
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
progressDialog.setOnCancelListener(dialog -> worker.cancel());
ContentResolver resolver = context.getContentResolver();
Handler handler = Handler.createAsync(Looper.getMainLooper());
worker.setTask(workerCallback -> {
try {
workerCallback.onInitialize();
workerCallback.onProgress(-1);//set dummy progress since we don't know the
// progress of the unzip
unzipDocumentFileToDirectory(zipFile, resolver, targetDirectory, overwriteNotSkip);
workerCallback.onComplete(true);
} catch (IOException e) {
workerCallback.onFailure(e);
}
});
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
worker.run();
}
public static void unzipDocumentFileToDirectory(DocumentFile zipFile,
ContentResolver resolver,
File targetDirectory,
boolean overwriteNotSkip) throws IOException {
try (ZipInputStream zis = new ZipInputStream(resolver.openInputStream(zipFile.getUri()))) {
unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis);
}
}
private static void unzipStreamToDirectory(File targetDirectory,
boolean overwriteNotSkip,
ZipInputStream zis) throws IOException {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
File file = new File(targetDirectory, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
if (file.exists() && !overwriteNotSkip) {
continue;
}
try (FileOutputStream fos = new FileOutputStream(file)) {
copyStream(zis, fos);
}
}
}
}
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
ContentResolver resolver,
DocumentFile targetFolder) throws IOException {
copyDocumentFileToNewOrExistingFile(sourceFile,
resolver,
targetFolder,
Constants.NO_FILE_EXTENSION_MIME_TYPE);
}
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
ContentResolver resolver,
DocumentFile targetFolder,
String mimeType) throws IOException {
String fileName = sourceFile.getName();
DocumentFile file = targetFolder.findFile(fileName);
if (file == null)
if (file == null) {
file = targetFolder.createFile(mimeType, fileName);
if (file == null)
}
if (file == null) {
return;
}
AndroidStorage.copyDocumentFile(sourceFile, resolver, file);
}
public static void copyDocumentFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFile) throws IOException {
public static void copyDocumentFile(DocumentFile sourceFile,
ContentResolver resolver,
DocumentFile targetFile) throws IOException {
try (OutputStream outputStream = resolver.openOutputStream(targetFile.getUri());
InputStream inputStream = resolver.openInputStream(sourceFile.getUri())) {
copyStream(inputStream, outputStream);
}
}
/**
* Gets the MIME-Type for a file.<p/>
* Fallback value is '* / *' (without spaces) <p/>
* Mostly copied together from: <a href="https://stackoverflow.com/q/8589645/17292289">StackOverflow</a>
*/
@NonNull
public static String getMimeType(ContentResolver resolver, Uri uri) {
String type = null;
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
type = resolver.getType(uri);
return type;
}
final String extension = MimeTypeMap.getFileExtensionFromUrl(uri.getPath());
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
}
if (type == null) {
type = "*/*"; // fallback type.
}
return type;
}
public static String getUrlForFile(Context context, File worldmap) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Uri uri = FileProvider.getUriForFile(context, "com.gpl.rpg.AndorsTrail_beta2.fileprovider", worldmap);
String applicationId = context.getPackageName();
Uri uri = FileProvider.getUriForFile(context, applicationId + ".fileprovider", worldmap);
return uri.toString();
} else {
return "file://" + worldmap.getAbsolutePath();
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static Intent getNewOpenDirectoryIntent() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
return intent;
return new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@@ -168,4 +297,176 @@ public final class AndroidStorage {
intent.setType(Constants.SAVEGAME_FILE_MIME_TYPE);
return intent;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static Intent getNewSelectZipIntent() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/zip");
return intent;
}
@RequiresApi(api = Build.VERSION_CODES.P)
public static void copyDocumentFilesFromToAsync(DocumentFile[] sources,
Context context,
DocumentFile[] targets,
String loadingMessage,
Consumer<Boolean> callback) {
if (sources.length != targets.length) {
throw new IllegalArgumentException("Both arrays, target & source have to have the same size");
}
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
progressDialog.setOnCancelListener(dialog -> worker.cancel());
ContentResolver resolver = context.getContentResolver();
Handler handler = Handler.createAsync(Looper.getMainLooper());
worker.setTask(workerCallback -> {
try {
workerCallback.onInitialize();
for (int i = 0; i < sources.length; i++) {
if (worker.isCancelled()) {
workerCallback.onFailure(new CancellationException("Cancelled"));
return;
}
DocumentFile source = sources[i];
DocumentFile target = targets[i];
if (source == null || target == null) {
continue;
}
copyDocumentFile(source, resolver, target);
float progress = i / (float) sources.length;
workerCallback.onProgress(progress);
}
workerCallback.onComplete(true);
} catch (NullPointerException e) {
if (worker.isCancelled()) {
workerCallback.onFailure(new CancellationException("Cancelled"));
return;
}
} catch (Exception e) {
workerCallback.onFailure(e);
}
});
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
worker.run();
}
@RequiresApi(api = Build.VERSION_CODES.P)
public static void copyDocumentFilesToDirAsync(DocumentFile[] files,
Context context,
DocumentFile targetDirectory,
String loadingMessage,
Consumer<Boolean> callback) {
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
progressDialog.setOnCancelListener(dialog -> worker.cancel());
ContentResolver resolver = context.getContentResolver();
Handler handler = Handler.createAsync(Looper.getMainLooper());
worker.setTask(workerCallback -> {
try {
workerCallback.onInitialize();
for (int i = 0; i < files.length; i++) {
if (worker.isCancelled()) {
workerCallback.onFailure(new CancellationException("Cancelled"));
return;
}
DocumentFile file = files[i];
if (file == null) {
continue;
}
copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory);
float progress = i / (float) files.length;
workerCallback.onProgress(progress);
}
workerCallback.onComplete(true);
} catch (NullPointerException e) {
if (worker.isCancelled()) {
workerCallback.onFailure(new CancellationException("Cancelled"));
}
} catch (Exception e) {
workerCallback.onFailure(e);
}
});
worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
worker.run();
}
private static BackgroundWorkerCallback<Boolean> getDefaultBackgroundWorkerCallback(Handler handler,
CustomDialogFactory.CustomDialog progressDialog,
Consumer<Boolean> callback) {
return new BackgroundWorkerCallback<Boolean>() {
private int progress = -1;
@Override
public void onInitialize() {
handler.post(() -> {
CustomDialogFactory.show(progressDialog);
});
}
@Override
public void onProgress(float progress) {
handler.post(() -> {
int intProgress = (int) (progress * 100);
if (this.progress == intProgress) {
return;
}
this.progress = intProgress;
if (progress == -1) {
CustomDialogFactory.setDesc(progressDialog, null);
return;
}
CustomDialogFactory.setDesc(progressDialog, intProgress + "%");
});
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onFailure(Exception e) {
this.onComplete(false);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onComplete(Boolean result) {
handler.post(() -> {
progressDialog.dismiss();
callback.accept(result);
});
}
};
}
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) {
return getLoadingDialog(context, null);
}
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context, String message) {
if (message == null) {
message = context.getResources().getString(R.string.dialog_loading_message);
}
CustomDialogFactory.CustomDialog dialog = CustomDialogFactory.createDialog(context,
message,
context.getResources()
.getDrawable(R.drawable.loading_anim),
null,
null,
true,
false);
CustomDialogFactory.addCancelButton(dialog, android.R.string.no);
return dialog;
}
}

View File

@@ -0,0 +1,46 @@
package com.gpl.rpg.AndorsTrail.util;
import java.util.concurrent.Executors;
public final class BackgroundWorker<T> {
boolean cancelled = false;
worker<T> task;
BackgroundWorkerCallback<T> callback;
public void setTask(worker<T> task) {
this.task = task;
}
public void setCallback(BackgroundWorkerCallback<T> callback) {
this.callback = callback;
}
public void cancel() {
cancelled = true;
}
interface worker<T> {
void doWork(BackgroundWorkerCallback<T> callback);
}
interface BackgroundWorkerCallback<T> {
void onInitialize();
default void onProgress(float progress) {
}
void onFailure(Exception e);
void onComplete(T result);
}
public void run() {
Executors.newSingleThreadExecutor().execute(() -> {
task.doWork(callback);
});
}
public boolean isCancelled() {
return cancelled;
}
}

View File

@@ -0,0 +1,16 @@
package com.gpl.rpg.AndorsTrail.util;
import java.util.HashMap;
public final class HashMapHelper {
public static <K,V> V getOrDefault(HashMap<K,V> map, K key, V defaultValue) {
V v = map.get(key);
return v == null ? defaultValue : v;
}
public static <K> Integer sumIntegerValues(HashMap<K,Integer> map) {
int sum = 0;
for (Integer v : map.values()) sum += v;
return sum;
}
}

View File

@@ -1,8 +1,8 @@
package com.gpl.rpg.AndorsTrail.view;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnCancelListener;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
@@ -23,166 +23,225 @@ import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
public class CustomDialogFactory {
public static class CustomDialog extends Dialog {
public CustomDialog(Context context) {
super(context);
}
public static class CustomDialog extends android.app.Dialog {
public CustomDialog(Context context) {
super(context);
}
boolean verticalButtons = false;
}
}
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
String desc, View content, boolean hasButtons, boolean canDismiss) {
return createDialog(context, title, icon, desc, content, hasButtons, canDismiss, false);
}
public static CustomDialog createDialog(final Context context, String title, Drawable icon, String desc, View content, boolean hasButtons) {
return createDialog(context, title, icon, desc, content, hasButtons, true);
}
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
String desc, View content, boolean hasButtons) {
return createDialog(context, title, icon, desc, content, hasButtons, true);
}
public static CustomDialog createDialog(final Context context, String title, Drawable icon, String desc, View content, boolean hasButtons, final boolean canDismiss) {
final CustomDialog dialog = new CustomDialog(new ContextThemeWrapper(context, ThemeHelper.getDialogTheme())) {
@Override
public boolean onTouchEvent(MotionEvent event) {
Rect r = new Rect();
this.getWindow().getDecorView().findViewById(R.id.dialog_hitrect).getHitRect(r);
public static CustomDialog createDialog(final Context context, String title, Drawable icon,
String desc, View content, boolean hasButtons,
final boolean canDismiss, final boolean verticalButtons) {
final CustomDialog dialog = new CustomDialog(new ContextThemeWrapper(context, ThemeHelper.getDialogTheme())) {
@Override
public boolean onTouchEvent(MotionEvent event) {
Rect r = new Rect();
this.getWindow().getDecorView().findViewById(R.id.dialog_hitrect).getHitRect(r);
if (r.contains((int) event.getX(), (int) event.getY())) {
return super.onTouchEvent(event);
} else {
if (canDismiss) {
this.dismiss();
return true;
}
return false;
}
}
if (r.contains((int)event.getX(), (int)event.getY())) {
return super.onTouchEvent(event);
} else {
if (canDismiss) {
this.dismiss();
return true;
}
return false;
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
TextView title = (TextView) this.getWindow().getDecorView().findViewById(R.id.dialog_title);
if (title != null && title.getCompoundDrawables() != null && title.getCompoundDrawables()[0] != null) {
if (title.getCompoundDrawables()[0] instanceof AnimationDrawable) {
((AnimationDrawable) title.getCompoundDrawables()[0]).start();
}
}
}
};
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
TextView title = (TextView) this.getWindow().getDecorView().findViewById(R.id.dialog_title);
if (title != null && title.getCompoundDrawables() != null && title.getCompoundDrawables()[0] != null) {
if (title.getCompoundDrawables()[0] instanceof AnimationDrawable) {
((AnimationDrawable)title.getCompoundDrawables()[0]).start();
}
}
}
};
dialog.verticalButtons = verticalButtons;
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.custom_dialog_title_icon);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
if (((AndorsTrailApplication) context.getApplicationContext()).getPreferences().fullscreen) {
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.custom_dialog_title_icon);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
if (((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen) {
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
setTitle(dialog, title, icon);
setTitle(dialog, title, icon);
setDesc(dialog, desc);
setDesc(dialog, desc);
setContent(dialog, content);
setContent(dialog, content);
ViewGroup buttonsHolder = (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
if (hasButtons) {
buttonsHolder.setVisibility(View.VISIBLE);
} else {
buttonsHolder.setVisibility(View.GONE);
}
ViewGroup buttonsHolder = getButtonContainer(dialog);
ViewGroup unusedButtonsHolder = getUnusedButtonContainer(dialog);
return dialog;
}
unusedButtonsHolder.setVisibility(View.GONE);
if (hasButtons) {
buttonsHolder.setVisibility(View.VISIBLE);
} else {
buttonsHolder.setVisibility(View.GONE);
}
public static CustomDialog createErrorDialog(final Context context, String title, String description) {
final CustomDialog d = createDialog(context,
title,
context.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
description,
null,
true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
return d;
}
return dialog;
}
public static CustomDialog setTitle(final CustomDialog dialog, String title, Drawable icon) {
TextView titleView = (TextView) dialog.findViewById(R.id.dialog_title);
if (title != null || icon != null) {
titleView.setText(title);
titleView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
titleView.setVisibility(View.VISIBLE);
} else {
titleView.setVisibility(View.GONE);
}
return dialog;
}
public static CustomDialog createErrorDialog(final Context context, String title, String description) {
final CustomDialog d = createDialog(context,
title,
context.getResources().getDrawable(android.R.drawable.ic_dialog_alert),
description,
null,
true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
return d;
}
public static CustomDialog setDesc(final CustomDialog dialog, String desc) {
TextView descView = (TextView) dialog.findViewById(R.id.dialog_description);
ViewGroup descHolder = (ViewGroup) dialog.findViewById(R.id.dialog_description_container);
if (desc != null) {
descView.setText(desc);
descHolder.setVisibility(View.VISIBLE);
descView.setVisibility(View.VISIBLE);
} else {
descHolder.setVisibility(View.GONE);
}
return dialog;
}
public static CustomDialog setTitle(final CustomDialog dialog, String title, Drawable icon) {
TextView titleView = (TextView) dialog.findViewById(R.id.dialog_title);
if (title != null || icon != null) {
titleView.setText(title);
titleView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
titleView.setVisibility(View.VISIBLE);
} else {
titleView.setVisibility(View.GONE);
}
return dialog;
}
public static CustomDialog setContent(final CustomDialog dialog, View content) {
ViewGroup contentHolder = (ViewGroup) dialog.findViewById(R.id.dialog_content_container);
if (content != null) {
contentHolder.addView(content);
contentHolder.setVisibility(View.VISIBLE);
} else {
contentHolder.setVisibility(View.GONE);
}
return dialog;
}
public static CustomDialog setDesc(final CustomDialog dialog, String desc) {
TextView descView = (TextView) dialog.findViewById(R.id.dialog_description);
ViewGroup descHolder = (ViewGroup) dialog.findViewById(R.id.dialog_description_container);
if (desc != null) {
descView.setText(desc);
descHolder.setVisibility(View.VISIBLE);
descView.setVisibility(View.VISIBLE);
} else {
descHolder.setVisibility(View.GONE);
}
return dialog;
}
public static Dialog addButton(final Dialog dialog, int textId, final OnClickListener listener) {
public static CustomDialog setContent(final CustomDialog dialog, View content) {
ViewGroup contentHolder = (ViewGroup) dialog.findViewById(R.id.dialog_content_container);
if (content != null) {
contentHolder.addView(content);
contentHolder.setVisibility(View.VISIBLE);
} else {
contentHolder.setVisibility(View.GONE);
}
return dialog;
}
Button template = (Button) dialog.findViewById(R.id.dialog_template_button);
LayoutParams params = template.getLayoutParams();
ViewGroup buttonsHolder = (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
public static CustomDialog addButton(final CustomDialog dialog, String text, final OnClickListener listener) {
return addButton(dialog, -1, text, listener);
}
public static CustomDialog addButton(final CustomDialog dialog, int textId, final OnClickListener listener) {
return addButton(dialog, textId, null, listener);
}
public static CustomDialog addButton(final CustomDialog dialog, int textId, String text, final OnClickListener listener) {
Button template = getButtonTemplate(dialog);
LayoutParams params = template.getLayoutParams();
ViewGroup buttonsHolder = getButtonContainer(dialog);
Button b = new Button(dialog.getContext());
b.setLayoutParams(params);
//Old android versions need this "reminder"
b.setBackgroundDrawable(ThemeHelper.getThemeDrawable(dialog.getContext(), R.attr.ui_theme_textbutton_drawable));
b.setTextColor(ThemeHelper.getThemeColor(dialog.getContext(), R.attr.ui_theme_dialogue_light_color));
Button b = new Button(dialog.getContext());
b.setLayoutParams(params);
//Old android versions need this "reminder"
b.setBackgroundDrawable(ThemeHelper.getThemeDrawable(dialog.getContext(), R.attr.ui_theme_textbutton_drawable));
b.setTextColor(ThemeHelper.getThemeColor(dialog.getContext(), R.attr.ui_theme_dialogue_light_color));
b.setText(textId);
b.setOnClickListener(new OnClickListener() {
if(textId != -1) {
b.setText(textId);
} else {
b.setText(text);
}
@Override
public void onClick(View v) {
listener.onClick(v);
dialog.dismiss();
}
});
b.setOnClickListener(new OnClickListener() {
buttonsHolder.addView(b, params);
return dialog;
}
@Override
public void onClick(View v) {
listener.onClick(v);
dialog.dismiss();
}
});
public static Dialog addDismissButton(final Dialog dialog, int textId) {
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
buttonsHolder.addView(b, params);
return dialog;
}
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
public static CustomDialog addDismissButton(final CustomDialog dialog, int textId) {
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
public static Dialog setDismissListener(Dialog dialog, OnDismissListener listener) {
dialog.setOnDismissListener(listener);
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
public static CustomDialog addCancelButton(final CustomDialog dialog, int textId) {
return CustomDialogFactory.addButton(dialog, textId, new OnClickListener() {
return dialog;
}
@Override
public void onClick(View v) {
dialog.cancel();
}
});
}
public static void show(Dialog dialog) {
public static CustomDialog setDismissListener(CustomDialog dialog, OnDismissListener listener) {
dialog.setOnDismissListener(listener);
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
dialog.show();
return dialog;
}
}
public static CustomDialog setCancelListener(CustomDialog dialog, OnCancelListener listener) {
dialog.setOnCancelListener(listener);
return dialog;
}
public static void show(CustomDialog dialog) {
dialog.findViewById(R.id.dialog_template_button).setVisibility(View.GONE);
dialog.findViewById(R.id.dialog_template_button_vertical).setVisibility(View.GONE);
dialog.show();
}
private static ViewGroup getUnusedButtonContainer(CustomDialog dialog) {
if (dialog.verticalButtons)
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
else
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
}
private static ViewGroup getButtonContainer(CustomDialog dialog) {
if (dialog.verticalButtons)
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container_vertical);
else
return (ViewGroup) dialog.findViewById(R.id.dialog_button_container);
}
private static Button getButtonTemplate(CustomDialog dialog) {
if (dialog.verticalButtons)
return (Button) dialog.findViewById(R.id.dialog_template_button_vertical);
else
return (Button) dialog.findViewById(R.id.dialog_template_button);
}
}

View File

@@ -9,13 +9,15 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory.CustomDialog;
/**
* Simply instantiate this class, implement abstract methods in an anonymous type, and tada, your Button is a Spinner!
*/
public abstract class SpinnerEmulator {
private Button spinnerButton;
private Dialog spinnerDialog = null;
private CustomDialog spinnerDialog = null;
private ListView choicesList;
private Context context;

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More