Compare commits

..

536 Commits

Author SHA1 Message Date
Taner
b479af0f8c New translations messages.yml (Lao) 2024-08-13 08:07:12 +00:00
Taner
81787c4327 New translations messages.yml (Burmese) 2024-08-13 08:07:10 +00:00
Taner
facf7e8038 New translations messages.yml (Thai) 2024-08-13 08:07:08 +00:00
Taner
5eeda8bea3 New translations messages.yml (Portuguese, Brazilian) 2024-08-13 08:07:07 +00:00
Taner
dfc33a3d84 New translations messages.yml (Vietnamese) 2024-08-13 08:07:05 +00:00
Taner
0f3225c339 New translations messages.yml (Chinese Traditional) 2024-08-13 08:07:04 +00:00
Taner
2794d47d7e New translations messages.yml (Chinese Simplified) 2024-08-13 08:07:02 +00:00
Taner
5d207e2e24 New translations messages.yml (Turkish) 2024-08-13 08:07:01 +00:00
Taner
8ab7256bb0 New translations messages.yml (Russian) 2024-08-13 08:06:59 +00:00
Taner
df890243fc New translations messages.yml (Polish) 2024-08-13 08:06:58 +00:00
Taner
d01c7e09a5 New translations messages.yml (Japanese) 2024-08-13 08:06:56 +00:00
Taner
99e3e07a41 New translations messages.yml (Italian) 2024-08-13 08:06:55 +00:00
Taner
fce8e75531 New translations messages.yml (German) 2024-08-13 08:06:53 +00:00
Taner
f13b3132f5 New translations messages.yml (Czech) 2024-08-13 08:06:52 +00:00
Taner
eaca04b22c New translations messages.yml (Spanish) 2024-08-13 08:06:50 +00:00
Taner
09250a4894 New translations messages.yml (French) 2024-08-13 08:06:49 +00:00
Taner
c6e4131bdf New translations skill-tree.yml (Lao) 2024-08-13 08:06:29 +00:00
Taner
601c37cef5 New translations skill-tree.yml (Burmese) 2024-08-13 08:06:27 +00:00
Taner
47dfb28ed5 New translations skill-tree.yml (Thai) 2024-08-13 08:06:26 +00:00
Taner
707c083812 New translations skill-tree.yml (Portuguese, Brazilian) 2024-08-13 08:06:24 +00:00
Taner
14eebaa28b New translations skill-tree.yml (Vietnamese) 2024-08-13 08:06:23 +00:00
Taner
1fdebee983 New translations skill-tree.yml (Chinese Traditional) 2024-08-13 08:06:21 +00:00
Taner
7254c69b98 New translations skill-tree.yml (Chinese Simplified) 2024-08-13 08:06:19 +00:00
Taner
085bcbdb49 New translations skill-tree.yml (Turkish) 2024-08-13 08:06:18 +00:00
Taner
16c4c9f8cb New translations skill-tree.yml (Russian) 2024-08-13 08:06:16 +00:00
Taner
b08c5dfd48 New translations skill-tree.yml (Polish) 2024-08-13 08:06:15 +00:00
Taner
2b48dbddc3 New translations skill-tree.yml (Japanese) 2024-08-13 08:06:13 +00:00
Taner
7931808913 New translations skill-tree.yml (Italian) 2024-08-13 08:06:11 +00:00
Taner
0c6b059cef New translations skill-tree.yml (German) 2024-08-13 08:06:10 +00:00
Taner
fce111a604 New translations skill-tree.yml (Czech) 2024-08-13 08:06:08 +00:00
Taner
4127083c2f New translations skill-tree.yml (Spanish) 2024-08-13 08:06:06 +00:00
Taner
230afc54e1 New translations skill-tree.yml (French) 2024-08-13 08:06:05 +00:00
Taner
72fd3cc29e New translations skill-list.yml (Lao) 2024-08-13 08:06:03 +00:00
Taner
7f5cd4a179 New translations skill-list.yml (Burmese) 2024-08-13 08:06:01 +00:00
Taner
9c28d30109 New translations skill-list.yml (Thai) 2024-08-13 08:06:00 +00:00
Taner
8c998eda6d New translations skill-list.yml (Portuguese, Brazilian) 2024-08-13 08:05:58 +00:00
Taner
0c11a625f3 New translations skill-list.yml (Vietnamese) 2024-08-13 08:05:56 +00:00
Taner
1efdea1fe1 New translations skill-list.yml (Chinese Traditional) 2024-08-13 08:05:54 +00:00
Taner
9d5e655f3f New translations skill-list.yml (Chinese Simplified) 2024-08-13 08:05:53 +00:00
Taner
4390a46b35 New translations skill-list.yml (Turkish) 2024-08-13 08:05:51 +00:00
Taner
e04bfb266d New translations skill-list.yml (Russian) 2024-08-13 08:05:50 +00:00
Taner
1d9042fcef New translations skill-list.yml (Polish) 2024-08-13 08:05:48 +00:00
Taner
41d105b0ef New translations skill-list.yml (Japanese) 2024-08-13 08:05:47 +00:00
Taner
7e0a429c30 New translations skill-list.yml (Italian) 2024-08-13 08:05:45 +00:00
Taner
0416fd4e4f New translations skill-list.yml (German) 2024-08-13 08:05:44 +00:00
Taner
659234e3cd New translations skill-list.yml (Czech) 2024-08-13 08:05:42 +00:00
Taner
084cf08ca7 New translations skill-list.yml (Spanish) 2024-08-13 08:05:41 +00:00
Taner
d957144938 New translations skill-list.yml (French) 2024-08-13 08:05:37 +00:00
Taner
9c2940b2ff New translations player-stats.yml (Lao) 2024-08-13 08:05:27 +00:00
Taner
2c3c25d6d7 New translations player-stats.yml (Burmese) 2024-08-13 08:05:26 +00:00
Taner
166938ca31 New translations player-stats.yml (Thai) 2024-08-13 08:05:24 +00:00
Taner
d013735c14 New translations player-stats.yml (Portuguese, Brazilian) 2024-08-13 08:05:23 +00:00
Taner
d2ee42c5fc New translations player-stats.yml (Vietnamese) 2024-08-13 08:05:21 +00:00
Taner
baa00252ab New translations player-stats.yml (Chinese Traditional) 2024-08-13 08:05:20 +00:00
Taner
02c977be18 New translations player-stats.yml (Chinese Simplified) 2024-08-13 08:05:17 +00:00
Taner
72f69a0f6d New translations player-stats.yml (Turkish) 2024-08-13 08:05:16 +00:00
Taner
26fd02af0d New translations player-stats.yml (Russian) 2024-08-13 08:05:14 +00:00
Taner
93acb45f41 New translations player-stats.yml (Polish) 2024-08-13 08:05:12 +00:00
Taner
30f6752d35 New translations player-stats.yml (Japanese) 2024-08-13 08:05:11 +00:00
Taner
122d97f84b New translations player-stats.yml (Italian) 2024-08-13 08:05:10 +00:00
Taner
4775c9265d New translations player-stats.yml (German) 2024-08-13 08:05:08 +00:00
Taner
335867baf9 New translations player-stats.yml (Czech) 2024-08-13 08:05:07 +00:00
Taner
4da254527c New translations player-stats.yml (Spanish) 2024-08-13 08:05:05 +00:00
Taner
91e7753bc8 New translations player-stats.yml (French) 2024-08-13 08:05:03 +00:00
Taner
7fd401fe9d New translations attribute-view.yml (Lao) 2024-08-13 08:04:05 +00:00
Taner
d5ed20523b New translations attribute-view.yml (Burmese) 2024-08-13 08:04:03 +00:00
Taner
6205a2ef97 New translations attribute-view.yml (Thai) 2024-08-13 08:04:02 +00:00
Taner
3b20c17c64 New translations attribute-view.yml (Portuguese, Brazilian) 2024-08-13 08:04:00 +00:00
Taner
e57ce9fd80 New translations attribute-view.yml (Vietnamese) 2024-08-13 08:03:59 +00:00
Taner
57b1b68a5e New translations attribute-view.yml (Chinese Traditional) 2024-08-13 08:03:57 +00:00
Taner
5421167fdf New translations attribute-view.yml (Chinese Simplified) 2024-08-13 08:03:56 +00:00
Taner
cf8c940cb0 New translations attribute-view.yml (Turkish) 2024-08-13 08:03:53 +00:00
Taner
37d9fcb335 New translations attribute-view.yml (Russian) 2024-08-13 08:03:52 +00:00
Taner
b6fe7f1fcb New translations attribute-view.yml (Polish) 2024-08-13 08:03:50 +00:00
Taner
7383039e94 New translations attribute-view.yml (Japanese) 2024-08-13 08:03:49 +00:00
Taner
97c744dfe5 New translations attribute-view.yml (Italian) 2024-08-13 08:03:47 +00:00
Taner
089128593d New translations attribute-view.yml (German) 2024-08-13 08:03:46 +00:00
Taner
13d037964b New translations attribute-view.yml (Czech) 2024-08-13 08:03:44 +00:00
Taner
70deea538a New translations attribute-view.yml (Spanish) 2024-08-13 08:03:43 +00:00
Taner
4893f7f8d2 New translations attribute-view.yml (French) 2024-08-13 08:03:39 +00:00
Taner
8ea7c694f1 New translations class-confirm-default.yml (Russian) 2024-08-13 07:46:51 +00:00
Taner
5c8fc159bc New translations class-confirm-default.yml (Italian) 2024-08-13 07:46:48 +00:00
Taner
79a03e7d1c New translations class-confirm-default.yml (French) 2024-08-13 07:46:45 +00:00
Taner
74840ba77f New translations messages.yml (Vietnamese) 2024-08-13 07:46:40 +00:00
Taner
89bd59dc66 New translations messages.yml (Chinese Simplified) 2024-08-13 07:46:38 +00:00
Taner
ba91246701 New translations messages.yml (Russian) 2024-08-13 07:46:36 +00:00
Taner
9edd2b8b60 New translations messages.yml (Polish) 2024-08-13 07:46:35 +00:00
Taner
6f4b6f8fc6 New translations messages.yml (Italian) 2024-08-13 07:46:33 +00:00
Taner
fe7bc16f3c New translations messages.yml (Spanish) 2024-08-13 07:46:30 +00:00
Taner
bf3c5001a7 New translations messages.yml (French) 2024-08-13 07:46:28 +00:00
Taner
447795c35f New translations waypoints.yml (Chinese Traditional) 2024-08-13 07:46:23 +00:00
Taner
0ba49ba147 New translations waypoints.yml (Chinese Simplified) 2024-08-13 07:46:22 +00:00
Taner
215fe49f01 New translations waypoints.yml (Russian) 2024-08-13 07:46:20 +00:00
Taner
0b08edcdb2 New translations waypoints.yml (Italian) 2024-08-13 07:46:17 +00:00
Taner
f867361f11 New translations waypoints.yml (Spanish) 2024-08-13 07:46:14 +00:00
Taner
62bb206e53 New translations waypoints.yml (French) 2024-08-13 07:46:13 +00:00
Taner
92c341d556 New translations subclass-select.yml (Russian) 2024-08-13 07:46:06 +00:00
Taner
4c6c3bc1ad New translations subclass-select.yml (Italian) 2024-08-13 07:46:02 +00:00
Taner
450e8a4d0d New translations subclass-select.yml (French) 2024-08-13 07:45:59 +00:00
Taner
d264fa4f68 New translations skill-tree.yml (Chinese Simplified) 2024-08-13 07:45:53 +00:00
Taner
f5d2939e52 New translations skill-tree.yml (Russian) 2024-08-13 07:45:50 +00:00
Taner
f3eff7d452 New translations skill-tree.yml (Italian) 2024-08-13 07:45:47 +00:00
Taner
44bc2684af New translations skill-tree.yml (Spanish) 2024-08-13 07:45:45 +00:00
Taner
faea8fe5a8 New translations skill-tree.yml (French) 2024-08-13 07:45:43 +00:00
Taner
fb5c63f588 New translations skill-list.yml (Chinese Simplified) 2024-08-13 07:45:37 +00:00
Taner
9e7a45f64d New translations skill-list.yml (Russian) 2024-08-13 07:45:35 +00:00
Taner
c782c34bbf New translations skill-list.yml (Italian) 2024-08-13 07:45:32 +00:00
Taner
823a7cb994 New translations skill-list.yml (French) 2024-08-13 07:45:29 +00:00
Taner
65f2916daf New translations quest-list.yml (French) 2024-08-13 07:45:18 +00:00
Taner
193ed55160 New translations player-stats.yml (Russian) 2024-08-13 07:45:09 +00:00
Taner
5a4941fe22 New translations player-stats.yml (Italian) 2024-08-13 07:45:07 +00:00
Taner
daca2533fc New translations player-stats.yml (French) 2024-08-13 07:45:03 +00:00
Taner
6f10e71da1 New translations class-select.yml (Russian) 2024-08-13 07:43:52 +00:00
Taner
da95c1ffc7 New translations class-select.yml (Italian) 2024-08-13 07:43:50 +00:00
Taner
663c393b9b New translations class-select.yml (French) 2024-08-13 07:43:46 +00:00
Taner
22fd4e94e7
New translations class-confirm-default.yml (Lao) 2023-09-10 11:04:16 +00:00
Taner
b9423cbc2a
New translations class-confirm-default.yml (Burmese) 2023-09-10 11:04:14 +00:00
Taner
c0ac350124
New translations class-confirm-default.yml (Thai) 2023-09-10 11:04:13 +00:00
Taner
a829e183b4
New translations class-confirm-default.yml (Portuguese, Brazilian) 2023-09-10 11:04:12 +00:00
Taner
25d6a30e5b
New translations class-confirm-default.yml (Vietnamese) 2023-09-10 11:04:10 +00:00
Taner
8c0ddd4a49
New translations class-confirm-default.yml (Chinese Traditional) 2023-09-10 11:04:09 +00:00
Taner
1ce6379d18
New translations class-confirm-default.yml (Chinese Simplified) 2023-09-10 11:04:07 +00:00
Taner
1c4bafcc3b
New translations class-confirm-default.yml (Turkish) 2023-09-10 11:04:06 +00:00
Taner
be7800e815
New translations class-confirm-default.yml (Russian) 2023-09-10 11:04:05 +00:00
Taner
7da25e0579
New translations class-confirm-default.yml (Polish) 2023-09-10 11:04:03 +00:00
Taner
1d37e0e58a
New translations class-confirm-default.yml (Japanese) 2023-09-10 11:04:02 +00:00
Taner
2fa3cde927
New translations class-confirm-default.yml (Italian) 2023-09-10 11:04:00 +00:00
Taner
54e806c516
New translations class-confirm-default.yml (German) 2023-09-10 11:03:59 +00:00
Taner
289191d52d
New translations class-confirm-default.yml (Czech) 2023-09-10 11:03:57 +00:00
Taner
16ee35f6f0
New translations class-confirm-default.yml (Spanish) 2023-09-10 11:03:56 +00:00
Taner
71b01a23f0
New translations class-confirm-default.yml (French) 2023-09-10 11:03:54 +00:00
Taner
d292641c22
New translations messages.yml (Lao) 2023-09-10 11:03:53 +00:00
Taner
f3106512ca
New translations messages.yml (Burmese) 2023-09-10 11:03:52 +00:00
Taner
dcabc26be2
New translations messages.yml (Thai) 2023-09-10 11:03:50 +00:00
Taner
1cee4f8927
New translations messages.yml (Portuguese, Brazilian) 2023-09-10 11:03:49 +00:00
Taner
c2eaa21674
New translations messages.yml (Vietnamese) 2023-09-10 11:03:47 +00:00
Taner
5ca2b27ef6
New translations messages.yml (Chinese Traditional) 2023-09-10 11:03:46 +00:00
Taner
c1fdcc58d8
New translations messages.yml (Chinese Simplified) 2023-09-10 11:03:44 +00:00
Taner
a1b54882ec
New translations messages.yml (Turkish) 2023-09-10 11:03:42 +00:00
Taner
16cfaec71f
New translations messages.yml (Russian) 2023-09-10 11:03:41 +00:00
Taner
08a236bd2d
New translations messages.yml (Polish) 2023-09-10 11:03:40 +00:00
Taner
ae213508c7
New translations messages.yml (Japanese) 2023-09-10 11:03:38 +00:00
Taner
2baa149b7d
New translations messages.yml (Italian) 2023-09-10 11:03:37 +00:00
Taner
068cf040ad
New translations messages.yml (German) 2023-09-10 11:03:35 +00:00
Taner
ce8a60bea3
New translations messages.yml (Czech) 2023-09-10 11:03:34 +00:00
Taner
03321276ce
New translations messages.yml (Spanish) 2023-09-10 11:03:33 +00:00
Taner
979ef97127
New translations messages.yml (French) 2023-09-10 11:03:31 +00:00
Taner
8f6b494e73
New translations waypoints.yml (Lao) 2023-09-10 11:03:29 +00:00
Taner
1cdeaef039
New translations waypoints.yml (Burmese) 2023-09-10 11:03:28 +00:00
Taner
1f03463be4
New translations waypoints.yml (Thai) 2023-09-10 11:03:27 +00:00
Taner
28fa452a5b
New translations waypoints.yml (Portuguese, Brazilian) 2023-09-10 11:03:25 +00:00
Taner
ef151da6bf
New translations waypoints.yml (Vietnamese) 2023-09-10 11:03:24 +00:00
Taner
9e783ce71c
New translations waypoints.yml (Chinese Traditional) 2023-09-10 11:03:22 +00:00
Taner
020bc5a3a8
New translations waypoints.yml (Chinese Simplified) 2023-09-10 11:03:20 +00:00
Taner
368ba1831c
New translations waypoints.yml (Turkish) 2023-09-10 11:03:18 +00:00
Taner
e961ac9625
New translations waypoints.yml (Russian) 2023-09-10 11:03:17 +00:00
Taner
eafb8dfb74
New translations waypoints.yml (Polish) 2023-09-10 11:03:15 +00:00
Taner
0c88b6f454
New translations waypoints.yml (Japanese) 2023-09-10 11:03:14 +00:00
Taner
fe496932b7
New translations waypoints.yml (Italian) 2023-09-10 11:03:12 +00:00
Taner
666a4bbe2e
New translations waypoints.yml (German) 2023-09-10 11:03:11 +00:00
Taner
3d85df7bfb
New translations waypoints.yml (Czech) 2023-09-10 11:03:09 +00:00
Taner
1a175bd68f
New translations waypoints.yml (Spanish) 2023-09-10 11:03:07 +00:00
Taner
165d4699a5
New translations waypoints.yml (French) 2023-09-10 11:03:06 +00:00
Taner
c8d32f63c2
New translations subclass-select.yml (Lao) 2023-09-10 11:03:05 +00:00
Taner
b80c0f3f5e
New translations subclass-select.yml (Burmese) 2023-09-10 11:03:03 +00:00
Taner
a41ddf9067
New translations subclass-select.yml (Thai) 2023-09-10 11:03:01 +00:00
Taner
153a51f3fd
New translations subclass-select.yml (Portuguese, Brazilian) 2023-09-10 11:03:00 +00:00
Taner
b292d7b273
New translations subclass-select.yml (Vietnamese) 2023-09-10 11:02:58 +00:00
Taner
af76c5056d
New translations subclass-select.yml (Chinese Traditional) 2023-09-10 11:02:57 +00:00
Taner
10d1d3af97
New translations subclass-select.yml (Chinese Simplified) 2023-09-10 11:02:56 +00:00
Taner
327f29ad5a
New translations subclass-select.yml (Turkish) 2023-09-10 11:02:54 +00:00
Taner
4a69378d27
New translations subclass-select.yml (Russian) 2023-09-10 11:02:53 +00:00
Taner
0c410ac5fb
New translations subclass-select.yml (Polish) 2023-09-10 11:02:51 +00:00
Taner
a8837616c7
New translations subclass-select.yml (Japanese) 2023-09-10 11:02:50 +00:00
Taner
910822099b
New translations subclass-select.yml (Italian) 2023-09-10 11:02:48 +00:00
Taner
649dbcfaf4
New translations subclass-select.yml (German) 2023-09-10 11:02:47 +00:00
Taner
71989a7680
New translations subclass-select.yml (Czech) 2023-09-10 11:02:45 +00:00
Taner
7ce63ba733
New translations subclass-select.yml (Spanish) 2023-09-10 11:02:44 +00:00
Taner
ffd2c67311
New translations subclass-select.yml (French) 2023-09-10 11:02:42 +00:00
Taner
ad57e0565c
New translations skill-tree.yml (Lao) 2023-09-10 11:02:41 +00:00
Taner
c6ea927bb1
New translations skill-tree.yml (Burmese) 2023-09-10 11:02:37 +00:00
Taner
5b655a8b7c
New translations skill-tree.yml (Thai) 2023-09-10 11:02:33 +00:00
Taner
0b05ea74f6
New translations skill-tree.yml (Portuguese, Brazilian) 2023-09-10 11:02:30 +00:00
Taner
d5e08f51e0
New translations skill-tree.yml (Vietnamese) 2023-09-10 11:02:28 +00:00
Taner
6222328b73
New translations skill-tree.yml (Chinese Traditional) 2023-09-10 11:02:27 +00:00
Taner
0296cc10db
New translations skill-tree.yml (Chinese Simplified) 2023-09-10 11:02:25 +00:00
Taner
bb48c2c438
New translations skill-tree.yml (Turkish) 2023-09-10 11:02:24 +00:00
Taner
d062de6baf
New translations skill-tree.yml (Russian) 2023-09-10 11:02:22 +00:00
Taner
ed88388657
New translations skill-tree.yml (Polish) 2023-09-10 11:02:18 +00:00
Taner
13f3e05c0c
New translations skill-tree.yml (Japanese) 2023-09-10 11:02:17 +00:00
Taner
133748ae33
New translations skill-tree.yml (Italian) 2023-09-10 11:02:15 +00:00
Taner
500175cd33
New translations skill-tree.yml (German) 2023-09-10 11:02:13 +00:00
Taner
921530c068
New translations skill-tree.yml (Czech) 2023-09-10 11:02:10 +00:00
Taner
4145e28ec4
New translations skill-tree.yml (Spanish) 2023-09-10 11:02:09 +00:00
Taner
5300ef6ffa
New translations skill-tree.yml (French) 2023-09-10 11:02:06 +00:00
Taner
7a91bccd18
New translations skill-list.yml (Lao) 2023-09-10 11:02:04 +00:00
Taner
89879d705a
New translations skill-list.yml (Burmese) 2023-09-10 11:02:03 +00:00
Taner
aca89babc0
New translations skill-list.yml (Thai) 2023-09-10 11:02:01 +00:00
Taner
b984e72d73
New translations skill-list.yml (Portuguese, Brazilian) 2023-09-10 11:01:59 +00:00
Taner
0cd906c790
New translations skill-list.yml (Vietnamese) 2023-09-10 11:01:56 +00:00
Taner
518aa66182
New translations skill-list.yml (Chinese Traditional) 2023-09-10 11:01:52 +00:00
Taner
acb0192849
New translations skill-list.yml (Chinese Simplified) 2023-09-10 11:01:51 +00:00
Taner
4f0b582929
New translations skill-list.yml (Turkish) 2023-09-10 11:01:49 +00:00
Taner
d1a70091dc
New translations skill-list.yml (Russian) 2023-09-10 11:01:47 +00:00
Taner
d93a619649
New translations skill-list.yml (Polish) 2023-09-10 11:01:46 +00:00
Taner
8a07a3d0c8
New translations skill-list.yml (Japanese) 2023-09-10 11:01:44 +00:00
Taner
e5b6b711bc
New translations skill-list.yml (Italian) 2023-09-10 11:01:43 +00:00
Taner
ed68c3d50e
New translations skill-list.yml (German) 2023-09-10 11:01:41 +00:00
Taner
aeaf7e072f
New translations skill-list.yml (Czech) 2023-09-10 11:01:40 +00:00
Taner
dd2862ba3e
New translations skill-list.yml (Spanish) 2023-09-10 11:01:39 +00:00
Taner
65997648ea
New translations skill-list.yml (French) 2023-09-10 11:01:37 +00:00
Taner
9630b9ae38
New translations quest-list.yml (Lao) 2023-09-10 11:01:35 +00:00
Taner
2c88a89872
New translations quest-list.yml (Burmese) 2023-09-10 11:01:33 +00:00
Taner
22c5526c98
New translations quest-list.yml (Thai) 2023-09-10 11:01:32 +00:00
Taner
3aa8b74fe6
New translations quest-list.yml (Portuguese, Brazilian) 2023-09-10 11:01:31 +00:00
Taner
b23c28a157
New translations quest-list.yml (Vietnamese) 2023-09-10 11:01:29 +00:00
Taner
e6f50e5549
New translations quest-list.yml (Chinese Traditional) 2023-09-10 11:01:28 +00:00
Taner
817d807a72
New translations quest-list.yml (Turkish) 2023-09-10 11:01:25 +00:00
Taner
782a31a7b6
New translations quest-list.yml (Polish) 2023-09-10 11:01:22 +00:00
Taner
492bc03f0d
New translations quest-list.yml (Japanese) 2023-09-10 11:01:20 +00:00
Taner
9032b40e30
New translations quest-list.yml (Italian) 2023-09-10 11:01:18 +00:00
Taner
67003c1be8
New translations quest-list.yml (German) 2023-09-10 11:01:17 +00:00
Taner
9ed974f4a3
New translations quest-list.yml (Czech) 2023-09-10 11:01:15 +00:00
Taner
299ad3167e
New translations quest-list.yml (Spanish) 2023-09-10 11:01:14 +00:00
Taner
1c713820e4
New translations quest-list.yml (French) 2023-09-10 11:01:12 +00:00
Taner
98da330bfb
New translations player-stats.yml (Lao) 2023-09-10 11:01:11 +00:00
Taner
8acc88b5b5
New translations player-stats.yml (Burmese) 2023-09-10 11:01:09 +00:00
Taner
95a7299dc8
New translations player-stats.yml (Thai) 2023-09-10 11:01:07 +00:00
Taner
43d97ada52
New translations player-stats.yml (Portuguese, Brazilian) 2023-09-10 11:01:06 +00:00
Taner
f37832b3d9
New translations player-stats.yml (Vietnamese) 2023-09-10 11:01:04 +00:00
Taner
889ba274b2
New translations player-stats.yml (Chinese Traditional) 2023-09-10 11:01:02 +00:00
Taner
2f7e95118b
New translations player-stats.yml (Chinese Simplified) 2023-09-10 11:01:00 +00:00
Taner
d0e9d33eb4
New translations player-stats.yml (Turkish) 2023-09-10 11:00:58 +00:00
Taner
d1f95db9f8
New translations player-stats.yml (Russian) 2023-09-10 11:00:57 +00:00
Taner
79a7a2bccc
New translations player-stats.yml (Polish) 2023-09-10 11:00:55 +00:00
Taner
1ee9fcc895
New translations player-stats.yml (Japanese) 2023-09-10 11:00:53 +00:00
Taner
fb00a5a94a
New translations player-stats.yml (Italian) 2023-09-10 11:00:52 +00:00
Taner
5a7ec19941
New translations player-stats.yml (German) 2023-09-10 11:00:50 +00:00
Taner
c706e4320b
New translations player-stats.yml (Czech) 2023-09-10 11:00:48 +00:00
Taner
cfeaf2ab9d
New translations player-stats.yml (Spanish) 2023-09-10 11:00:47 +00:00
Taner
f669dd13e2
New translations player-stats.yml (French) 2023-09-10 11:00:44 +00:00
Taner
5e692e9840
New translations party-view.yml (Lao) 2023-09-10 11:00:43 +00:00
Taner
1dbc213f7f
New translations party-view.yml (Burmese) 2023-09-10 11:00:41 +00:00
Taner
7b69ab5041
New translations party-view.yml (Thai) 2023-09-10 11:00:40 +00:00
Taner
69323ca394
New translations party-view.yml (Portuguese, Brazilian) 2023-09-10 11:00:39 +00:00
Taner
fb4147b8c7
New translations party-view.yml (Chinese Traditional) 2023-09-10 11:00:36 +00:00
Taner
dab199b983
New translations party-view.yml (Turkish) 2023-09-10 11:00:34 +00:00
Taner
3e0f4b8a7a
New translations party-view.yml (Polish) 2023-09-10 11:00:32 +00:00
Taner
fbb6d069fe
New translations party-view.yml (Japanese) 2023-09-10 11:00:30 +00:00
Taner
8ac432769b
New translations party-view.yml (Italian) 2023-09-10 11:00:29 +00:00
Taner
5f948720f1
New translations party-view.yml (German) 2023-09-10 11:00:27 +00:00
Taner
ae6b5f0c32
New translations party-view.yml (Czech) 2023-09-10 11:00:26 +00:00
Taner
1bd9a2982b
New translations party-view.yml (French) 2023-09-10 11:00:23 +00:00
Taner
ff44d1a4a3
New translations party-creation.yml (Lao) 2023-09-10 11:00:22 +00:00
Taner
82d64bc889
New translations party-creation.yml (Burmese) 2023-09-10 11:00:20 +00:00
Taner
c6c5c75e2b
New translations party-creation.yml (Thai) 2023-09-10 11:00:19 +00:00
Taner
5e41adb51f
New translations party-creation.yml (Portuguese, Brazilian) 2023-09-10 11:00:17 +00:00
Taner
3a4c02af50
New translations party-creation.yml (Chinese Traditional) 2023-09-10 11:00:15 +00:00
Taner
9b1c1aceed
New translations party-creation.yml (Turkish) 2023-09-10 11:00:13 +00:00
Taner
7b6a555dba
New translations party-creation.yml (Polish) 2023-09-10 11:00:11 +00:00
Taner
05f37a797c
New translations party-creation.yml (Japanese) 2023-09-10 11:00:09 +00:00
Taner
a66053b22e
New translations party-creation.yml (Italian) 2023-09-10 11:00:07 +00:00
Taner
0d6d3703b2
New translations party-creation.yml (German) 2023-09-10 11:00:06 +00:00
Taner
39b028f75e
New translations party-creation.yml (Czech) 2023-09-10 11:00:04 +00:00
Taner
4b9a8b5d6f
New translations party-creation.yml (French) 2023-09-10 11:00:01 +00:00
Taner
5c67e32759
New translations guild-view.yml (Lao) 2023-09-10 11:00:00 +00:00
Taner
550c68506b
New translations guild-view.yml (Burmese) 2023-09-10 10:59:58 +00:00
Taner
cbe25cf390
New translations guild-view.yml (Thai) 2023-09-10 10:59:57 +00:00
Taner
34521fdac3
New translations guild-view.yml (Portuguese, Brazilian) 2023-09-10 10:59:55 +00:00
Taner
0cdd498e78
New translations guild-view.yml (Chinese Traditional) 2023-09-10 10:59:53 +00:00
Taner
de0d1a6be8
New translations guild-view.yml (Turkish) 2023-09-10 10:59:51 +00:00
Taner
b597994ed7
New translations guild-view.yml (Polish) 2023-09-10 10:59:49 +00:00
Taner
10c1f0baec
New translations guild-view.yml (Japanese) 2023-09-10 10:59:48 +00:00
Taner
e95b61e93f
New translations guild-view.yml (Italian) 2023-09-10 10:59:46 +00:00
Taner
8cc0200796
New translations guild-view.yml (German) 2023-09-10 10:59:45 +00:00
Taner
ef3149b3d6
New translations guild-view.yml (Czech) 2023-09-10 10:59:44 +00:00
Taner
aec315c149
New translations guild-view.yml (French) 2023-09-10 10:59:42 +00:00
Taner
895ad97f37
New translations guild-creation.yml (Lao) 2023-09-10 10:59:40 +00:00
Taner
772aaaa9bc
New translations guild-creation.yml (Burmese) 2023-09-10 10:59:39 +00:00
Taner
90afccc139
New translations guild-creation.yml (Thai) 2023-09-10 10:59:37 +00:00
Taner
a2244f6c06
New translations guild-creation.yml (Portuguese, Brazilian) 2023-09-10 10:59:36 +00:00
Taner
7414f53119
New translations guild-creation.yml (Chinese Traditional) 2023-09-10 10:59:33 +00:00
Taner
f444384bd2
New translations guild-creation.yml (Turkish) 2023-09-10 10:59:32 +00:00
Taner
26f562a7f2
New translations guild-creation.yml (Polish) 2023-09-10 10:59:29 +00:00
Taner
14beb59efb
New translations guild-creation.yml (Japanese) 2023-09-10 10:59:28 +00:00
Taner
dea5f4fea7
New translations guild-creation.yml (Italian) 2023-09-10 10:59:26 +00:00
Taner
6e152f871e
New translations guild-creation.yml (German) 2023-09-10 10:59:25 +00:00
Taner
492e6ac6dd
New translations guild-creation.yml (Czech) 2023-09-10 10:59:24 +00:00
Taner
0e5c79aefb
New translations guild-creation.yml (French) 2023-09-10 10:59:21 +00:00
Taner
6c07fe3699
New translations friend-removal.yml (Lao) 2023-09-10 10:59:19 +00:00
Taner
be54b2f800
New translations friend-removal.yml (Burmese) 2023-09-10 10:59:18 +00:00
Taner
2fc6b74d75
New translations friend-removal.yml (Thai) 2023-09-10 10:59:17 +00:00
Taner
42a0e045a1
New translations friend-removal.yml (Portuguese, Brazilian) 2023-09-10 10:59:16 +00:00
Taner
208b423c30
New translations friend-removal.yml (Chinese Traditional) 2023-09-10 10:59:12 +00:00
Taner
b1a13527a6
New translations friend-removal.yml (Turkish) 2023-09-10 10:59:10 +00:00
Taner
1b52cb0d13
New translations friend-removal.yml (Polish) 2023-09-10 10:59:08 +00:00
Taner
6136ae47e8
New translations friend-removal.yml (Japanese) 2023-09-10 10:59:06 +00:00
Taner
86dd9720bb
New translations friend-removal.yml (Italian) 2023-09-10 10:59:05 +00:00
Taner
38c3db2901
New translations friend-removal.yml (German) 2023-09-10 10:59:03 +00:00
Taner
9e2163affc
New translations friend-removal.yml (Czech) 2023-09-10 10:59:02 +00:00
Taner
5a2b38970b
New translations friend-removal.yml (French) 2023-09-10 10:59:00 +00:00
Taner
c0acb4901e
New translations friend-list.yml (Lao) 2023-09-10 10:58:58 +00:00
Taner
fd7b7b6206
New translations friend-list.yml (Burmese) 2023-09-10 10:58:57 +00:00
Taner
587025b312
New translations friend-list.yml (Thai) 2023-09-10 10:58:56 +00:00
Taner
3eb9541ab6
New translations friend-list.yml (Portuguese, Brazilian) 2023-09-10 10:58:54 +00:00
Taner
1b29291c43
New translations friend-list.yml (Chinese Traditional) 2023-09-10 10:58:52 +00:00
Taner
a5879ef356
New translations friend-list.yml (Turkish) 2023-09-10 10:58:50 +00:00
Taner
75086881c1
New translations friend-list.yml (Polish) 2023-09-10 10:58:48 +00:00
Taner
defea24460
New translations friend-list.yml (Japanese) 2023-09-10 10:58:46 +00:00
Taner
f574e7ce26
New translations friend-list.yml (Italian) 2023-09-10 10:58:45 +00:00
Taner
e5738fb9c0
New translations friend-list.yml (German) 2023-09-10 10:58:44 +00:00
Taner
3cd11b91db
New translations friend-list.yml (Czech) 2023-09-10 10:58:42 +00:00
Taner
f80c52062f
New translations friend-list.yml (French) 2023-09-10 10:58:40 +00:00
Taner
9cedcf8aec
New translations class-select.yml (Lao) 2023-09-10 10:58:39 +00:00
Taner
0b3a2a26cb
New translations class-select.yml (Burmese) 2023-09-10 10:58:38 +00:00
Taner
6aa66b4a9f
New translations class-select.yml (Thai) 2023-09-10 10:58:36 +00:00
Taner
c4516bb27e
New translations class-select.yml (Portuguese, Brazilian) 2023-09-10 10:58:35 +00:00
Taner
86a5bc326e
New translations class-select.yml (Vietnamese) 2023-09-10 10:58:33 +00:00
Taner
0875776149
New translations class-select.yml (Chinese Traditional) 2023-09-10 10:58:31 +00:00
Taner
6c293c2c00
New translations class-select.yml (Chinese Simplified) 2023-09-10 10:58:30 +00:00
Taner
e6171c374c
New translations class-select.yml (Turkish) 2023-09-10 10:58:29 +00:00
Taner
345b9e5f87
New translations class-select.yml (Russian) 2023-09-10 10:58:27 +00:00
Taner
82cb6f035e
New translations class-select.yml (Polish) 2023-09-10 10:58:26 +00:00
Taner
e0c25c930c
New translations class-select.yml (Japanese) 2023-09-10 10:58:24 +00:00
Taner
55fa1c79a5
New translations class-select.yml (Italian) 2023-09-10 10:58:22 +00:00
Taner
c6617952da
New translations class-select.yml (German) 2023-09-10 10:58:21 +00:00
Taner
b60b628654
New translations class-select.yml (Czech) 2023-09-10 10:58:20 +00:00
Taner
51e390e849
New translations class-select.yml (Spanish) 2023-09-10 10:58:18 +00:00
Taner
548e181ffc
New translations class-select.yml (French) 2023-09-10 10:58:17 +00:00
Taner
579a2228f5
New translations attribute-view.yml (Lao) 2023-09-10 10:58:16 +00:00
Taner
44d00402c8
New translations attribute-view.yml (Burmese) 2023-09-10 10:58:14 +00:00
Taner
99569efa96
New translations attribute-view.yml (Thai) 2023-09-10 10:58:13 +00:00
Taner
3fbba4cea3
New translations attribute-view.yml (Portuguese, Brazilian) 2023-09-10 10:58:11 +00:00
Taner
4af025e5f9
New translations attribute-view.yml (Vietnamese) 2023-09-10 10:58:10 +00:00
Taner
5e43ced423
New translations attribute-view.yml (Chinese Traditional) 2023-09-10 10:58:08 +00:00
Taner
1247ff5a83
New translations attribute-view.yml (Turkish) 2023-09-10 10:58:06 +00:00
Taner
645f201593
New translations attribute-view.yml (Polish) 2023-09-10 10:58:03 +00:00
Taner
20663a2ffd
New translations attribute-view.yml (Japanese) 2023-09-10 10:58:02 +00:00
Taner
1659fd1200
New translations attribute-view.yml (Italian) 2023-09-10 10:58:01 +00:00
Taner
4ccd492175
New translations attribute-view.yml (German) 2023-09-10 10:57:59 +00:00
Taner
05d069dcb1
New translations attribute-view.yml (Czech) 2023-09-10 10:57:58 +00:00
Taner
db6905bf7e
New translations attribute-view.yml (French) 2023-09-10 10:57:56 +00:00
Taner
363f74cdec New translations messages.yml (German) 2023-01-24 09:05:05 +00:00
Taner
bf40faf96e New translations waypoints.yml (German) 2023-01-24 09:05:03 +00:00
Taner
7bd9db0d33 New translations subclass-select.yml (German) 2023-01-24 09:05:02 +00:00
Taner
73f18d0cbd New translations subclass-confirm.yml (German) 2023-01-24 09:05:00 +00:00
Taner
b2979fa307 New translations skill-tree.yml (German) 2023-01-24 09:04:59 +00:00
Taner
303fea1b91 New translations skill-list.yml (German) 2023-01-24 09:04:58 +00:00
Taner
5792158094 New translations quest-list.yml (German) 2023-01-24 09:04:56 +00:00
Taner
baf9d86b36 New translations player-stats.yml (German) 2023-01-24 09:04:55 +00:00
Taner
8d7e7c6fe3 New translations party-view.yml (German) 2023-01-24 09:04:54 +00:00
Taner
941f4fc538 New translations party-creation.yml (German) 2023-01-24 09:04:53 +00:00
Taner
db3483fc34 New translations guild-view.yml (German) 2023-01-24 09:04:51 +00:00
Taner
b56c04bee9 New translations guild-creation.yml (German) 2023-01-24 09:04:50 +00:00
Taner
2f1aa74522 New translations friend-removal.yml (German) 2023-01-24 09:04:49 +00:00
Taner
404e9a5126 New translations friend-list.yml (German) 2023-01-24 09:04:47 +00:00
Taner
29e09d0710 New translations class-select.yml (German) 2023-01-24 09:04:46 +00:00
Taner
b23a137a5a New translations class-confirm.yml (German) 2023-01-24 09:04:45 +00:00
Taner
4ca736ada4 New translations attribute-view.yml (German) 2023-01-24 09:04:44 +00:00
Taner
d644b0791a New translations messages.yml (Vietnamese) 2023-01-24 09:04:42 +00:00
Taner
a6f391b756 New translations messages.yml (Chinese Simplified) 2023-01-24 09:04:41 +00:00
Taner
6d2085f6c7 New translations messages.yml (Turkish) 2023-01-24 09:04:39 +00:00
Taner
1b01214c2a New translations messages.yml (Russian) 2023-01-24 09:04:38 +00:00
Taner
ed8126d8cd New translations messages.yml (Polish) 2023-01-24 09:04:36 +00:00
Taner
a76801fce6 New translations messages.yml (Spanish) 2023-01-24 09:04:35 +00:00
Taner
f5d9c8bf42 New translations messages.yml (French) 2023-01-24 09:04:34 +00:00
Taner
fe6911ef3a New translations waypoints.yml (Chinese Simplified) 2023-01-24 09:04:31 +00:00
Taner
7bec9c1a63 New translations subclass-select.yml (Chinese Simplified) 2023-01-24 09:04:26 +00:00
Taner
b170c0e2ca New translations subclass-select.yml (Russian) 2023-01-24 09:04:23 +00:00
Taner
0118a4205c New translations subclass-confirm.yml (Chinese Simplified) 2023-01-24 09:04:19 +00:00
Taner
26c1f2ba0a New translations subclass-confirm.yml (Russian) 2023-01-24 09:04:17 +00:00
Taner
05ac4f7e3d New translations skill-tree.yml (Chinese Simplified) 2023-01-24 09:04:12 +00:00
Taner
75d8c12d9e New translations skill-list.yml (Chinese Simplified) 2023-01-24 09:04:06 +00:00
Taner
f3dabde01b New translations skill-list.yml (Russian) 2023-01-24 09:04:03 +00:00
Taner
43faddcbe5 New translations quest-list.yml (Chinese Simplified) 2023-01-24 09:03:59 +00:00
Taner
927648796c New translations quest-list.yml (Russian) 2023-01-24 09:03:57 +00:00
Taner
b07b7c4485 New translations player-stats.yml (Chinese Simplified) 2023-01-24 09:03:52 +00:00
Taner
b76b766b09 New translations player-stats.yml (Russian) 2023-01-24 09:03:50 +00:00
Taner
ef3ba20f1d New translations player-stats.yml (Spanish) 2023-01-24 09:03:47 +00:00
Taner
76344dc68a New translations party-view.yml (Vietnamese) 2023-01-24 09:03:45 +00:00
Taner
32562958ed New translations party-view.yml (Chinese Simplified) 2023-01-24 09:03:43 +00:00
Taner
9e71e62b40 New translations party-view.yml (Russian) 2023-01-24 09:03:41 +00:00
Taner
e694ea70a9 New translations party-view.yml (Spanish) 2023-01-24 09:03:39 +00:00
Taner
f85e81c878 New translations party-creation.yml (Vietnamese) 2023-01-24 09:03:37 +00:00
Taner
e975736f8b New translations party-creation.yml (Chinese Simplified) 2023-01-24 09:03:36 +00:00
Taner
1d3494a829 New translations party-creation.yml (Russian) 2023-01-24 09:03:33 +00:00
Taner
8361d25387 New translations party-creation.yml (Spanish) 2023-01-24 09:03:31 +00:00
Taner
76029dbfbd New translations guild-view.yml (Vietnamese) 2023-01-24 09:03:29 +00:00
Taner
b1153aefc3 New translations guild-view.yml (Chinese Simplified) 2023-01-24 09:03:28 +00:00
Taner
4e4a383e04 New translations guild-view.yml (Russian) 2023-01-24 09:03:26 +00:00
Taner
b3a597bdd1 New translations guild-view.yml (Spanish) 2023-01-24 09:03:23 +00:00
Taner
c5f96e485f New translations guild-creation.yml (Vietnamese) 2023-01-24 09:03:21 +00:00
Taner
a759033051 New translations guild-creation.yml (Chinese Simplified) 2023-01-24 09:03:20 +00:00
Taner
b622b311bb New translations guild-creation.yml (Russian) 2023-01-24 09:03:17 +00:00
Taner
b6e185608d New translations guild-creation.yml (Spanish) 2023-01-24 09:03:14 +00:00
Taner
2e618223ed New translations friend-removal.yml (Vietnamese) 2023-01-24 09:03:12 +00:00
Taner
673908ceba New translations friend-removal.yml (Chinese Simplified) 2023-01-24 09:03:11 +00:00
Taner
5f6cd1f44b New translations friend-removal.yml (Russian) 2023-01-24 09:03:08 +00:00
Taner
6d2991992f New translations friend-removal.yml (Spanish) 2023-01-24 09:03:06 +00:00
Taner
424e760d5f New translations friend-list.yml (Vietnamese) 2023-01-24 09:03:04 +00:00
Taner
e4430c5d51 New translations friend-list.yml (Chinese Simplified) 2023-01-24 09:03:03 +00:00
Taner
6fb3d79974 New translations friend-list.yml (Russian) 2023-01-24 09:03:00 +00:00
Taner
463da924ac New translations friend-list.yml (Spanish) 2023-01-24 09:02:58 +00:00
Taner
a271a5258c New translations class-select.yml (Vietnamese) 2023-01-24 09:02:56 +00:00
Taner
43eb8ca615 New translations class-select.yml (Chinese Simplified) 2023-01-24 09:02:54 +00:00
Taner
6c7e3a9d77 New translations class-select.yml (Russian) 2023-01-24 09:02:51 +00:00
Taner
0c9f0ce608 New translations class-select.yml (Spanish) 2023-01-24 09:02:47 +00:00
Taner
8e7521f06b New translations class-confirm.yml (Vietnamese) 2023-01-24 09:02:45 +00:00
Taner
3e4e8f1d99 New translations class-confirm.yml (Chinese Simplified) 2023-01-24 09:02:44 +00:00
Taner
3430b852c5 New translations class-confirm.yml (Russian) 2023-01-24 09:02:42 +00:00
Taner
7b8f328ca5 New translations class-confirm.yml (Spanish) 2023-01-24 09:02:40 +00:00
Taner
4949918ba5 New translations attribute-view.yml (Vietnamese) 2023-01-24 09:02:38 +00:00
Taner
14eb121812 New translations attribute-view.yml (Chinese Simplified) 2023-01-24 09:02:36 +00:00
Taner
98a3c14dbf New translations attribute-view.yml (Russian) 2023-01-24 09:02:34 +00:00
Taner
601ea7b1ec New translations attribute-view.yml (Polish) 2023-01-24 09:02:33 +00:00
Taner
b1994613fa New translations attribute-view.yml (Spanish) 2023-01-24 09:02:32 +00:00
Taner
6dc60e553c Update file README.md 2023-01-23 17:54:30 +00:00
Taner
faaa416cd3 New translations messages.yml (Vietnamese) 2023-01-23 17:50:18 +00:00
Taner
6dbda38906 New translations messages.yml (Chinese Simplified) 2023-01-23 17:50:16 +00:00
Taner
9ec851e8c0 New translations messages.yml (Turkish) 2023-01-23 17:50:15 +00:00
Taner
6ac28beae1 New translations messages.yml (Russian) 2023-01-23 17:50:14 +00:00
Taner
5f785c83b4 New translations messages.yml (Polish) 2023-01-23 17:50:13 +00:00
Taner
2267bc9dc9 New translations messages.yml (Spanish) 2023-01-23 17:50:11 +00:00
Taner
31389e5013 New translations messages.yml (French) 2023-01-23 17:50:10 +00:00
Taner
565d698678 New translations waypoints.yml (Vietnamese) 2023-01-23 17:50:09 +00:00
Taner
c18334ac2f New translations waypoints.yml (Chinese Simplified) 2023-01-23 17:50:08 +00:00
Taner
2e518fb108 New translations waypoints.yml (Turkish) 2023-01-23 17:50:06 +00:00
Taner
41ef88a436 New translations waypoints.yml (Russian) 2023-01-23 17:50:05 +00:00
Taner
6a259b3642 New translations waypoints.yml (Polish) 2023-01-23 17:50:03 +00:00
Taner
f55479baea New translations waypoints.yml (Spanish) 2023-01-23 17:50:02 +00:00
Taner
85afbde15c New translations waypoints.yml (French) 2023-01-23 17:50:00 +00:00
Taner
1f9998d673 New translations subclass-select.yml (Vietnamese) 2023-01-23 17:49:59 +00:00
Taner
1e07a7e8b9 New translations subclass-select.yml (Chinese Simplified) 2023-01-23 17:49:57 +00:00
Taner
0f17ea56c0 New translations subclass-select.yml (Turkish) 2023-01-23 17:49:56 +00:00
Taner
06d481b156 New translations subclass-select.yml (Russian) 2023-01-23 17:49:53 +00:00
Taner
1feb9009e8 New translations subclass-select.yml (Polish) 2023-01-23 17:49:51 +00:00
Taner
ab4354de9d New translations subclass-select.yml (Spanish) 2023-01-23 17:49:50 +00:00
Taner
d0906c2fcd New translations subclass-select.yml (French) 2023-01-23 17:49:48 +00:00
Taner
2c684d0824 New translations subclass-confirm.yml (Vietnamese) 2023-01-23 17:49:47 +00:00
Taner
b7eb2318ac New translations subclass-confirm.yml (Chinese Simplified) 2023-01-23 17:49:46 +00:00
Taner
2898123ab1 New translations subclass-confirm.yml (Turkish) 2023-01-23 17:49:45 +00:00
Taner
120c8ab291 New translations subclass-confirm.yml (Russian) 2023-01-23 17:49:43 +00:00
Taner
8524f15308 New translations subclass-confirm.yml (Polish) 2023-01-23 17:49:42 +00:00
Taner
009de2929b New translations subclass-confirm.yml (Spanish) 2023-01-23 17:49:41 +00:00
Taner
d5ace90cc4 New translations subclass-confirm.yml (French) 2023-01-23 17:49:39 +00:00
Taner
89350e69c6 New translations skill-tree.yml (Vietnamese) 2023-01-23 17:49:38 +00:00
Taner
6604303bab New translations skill-tree.yml (Chinese Simplified) 2023-01-23 17:49:36 +00:00
Taner
17925e6582 New translations skill-tree.yml (Turkish) 2023-01-23 17:49:35 +00:00
Taner
b1ac87303f New translations skill-tree.yml (Russian) 2023-01-23 17:49:34 +00:00
Taner
6675506bec New translations skill-tree.yml (Polish) 2023-01-23 17:49:32 +00:00
Taner
a23292dc52 New translations skill-tree.yml (Spanish) 2023-01-23 17:49:31 +00:00
Taner
50f0d00512 New translations skill-tree.yml (French) 2023-01-23 17:49:29 +00:00
Taner
df5637b097 New translations skill-list.yml (Vietnamese) 2023-01-23 17:49:28 +00:00
Taner
aca884ac7e New translations skill-list.yml (Chinese Simplified) 2023-01-23 17:49:27 +00:00
Taner
4182b01b43 New translations skill-list.yml (Turkish) 2023-01-23 17:49:25 +00:00
Taner
18ce43c8b5 New translations skill-list.yml (Russian) 2023-01-23 17:49:24 +00:00
Taner
993a8d672d New translations skill-list.yml (Polish) 2023-01-23 17:49:22 +00:00
Taner
7ae887b892 New translations skill-list.yml (Spanish) 2023-01-23 17:49:21 +00:00
Taner
1ede7b1c9a New translations skill-list.yml (French) 2023-01-23 17:49:20 +00:00
Taner
6583557a12 New translations quest-list.yml (Vietnamese) 2023-01-23 17:49:18 +00:00
Taner
a7f7324f24 New translations quest-list.yml (Chinese Simplified) 2023-01-23 17:49:17 +00:00
Taner
4c214bddfb New translations quest-list.yml (Turkish) 2023-01-23 17:49:16 +00:00
Taner
86f00881a4 New translations quest-list.yml (Russian) 2023-01-23 17:49:14 +00:00
Taner
add5470402 New translations quest-list.yml (Polish) 2023-01-23 17:49:13 +00:00
Taner
48f11467b9 New translations quest-list.yml (Spanish) 2023-01-23 17:49:11 +00:00
Taner
941cf16df6 New translations quest-list.yml (French) 2023-01-23 17:49:10 +00:00
Taner
3471a74cf8 New translations player-stats.yml (Vietnamese) 2023-01-23 17:49:09 +00:00
Taner
1761008016 New translations player-stats.yml (Chinese Simplified) 2023-01-23 17:49:07 +00:00
Taner
3b0a4d7a95 New translations player-stats.yml (Turkish) 2023-01-23 17:49:05 +00:00
Taner
6b638a844d New translations player-stats.yml (Russian) 2023-01-23 17:49:04 +00:00
Taner
6f59834afb New translations player-stats.yml (Polish) 2023-01-23 17:49:03 +00:00
Taner
ac33645cad New translations player-stats.yml (Spanish) 2023-01-23 17:49:01 +00:00
Taner
b43f9e90fa New translations player-stats.yml (French) 2023-01-23 17:49:00 +00:00
Taner
ce32ee868b New translations party-view.yml (Vietnamese) 2023-01-23 17:48:58 +00:00
Taner
0f0954d8fb New translations party-view.yml (Chinese Simplified) 2023-01-23 17:48:57 +00:00
Taner
35a5a93828 New translations party-view.yml (Turkish) 2023-01-23 17:48:56 +00:00
Taner
7f3b94d596 New translations party-view.yml (Russian) 2023-01-23 17:48:54 +00:00
Taner
8dda69e8cc New translations party-view.yml (Polish) 2023-01-23 17:48:53 +00:00
Taner
a040a5898e New translations party-view.yml (Spanish) 2023-01-23 17:48:52 +00:00
Taner
58ba640839 New translations party-view.yml (French) 2023-01-23 17:48:51 +00:00
Taner
beeb88bac9 New translations party-creation.yml (Vietnamese) 2023-01-23 17:48:49 +00:00
Taner
708af42b1b New translations party-creation.yml (Chinese Simplified) 2023-01-23 17:48:48 +00:00
Taner
0e26a2d38b New translations party-creation.yml (Turkish) 2023-01-23 17:48:46 +00:00
Taner
a8111a3498 New translations party-creation.yml (Russian) 2023-01-23 17:48:45 +00:00
Taner
abd04e623a New translations party-creation.yml (Polish) 2023-01-23 17:48:44 +00:00
Taner
570a0dab82 New translations party-creation.yml (Spanish) 2023-01-23 17:48:43 +00:00
Taner
e66ea2090d New translations party-creation.yml (French) 2023-01-23 17:48:41 +00:00
Taner
9f53211ed9 New translations guild-view.yml (Vietnamese) 2023-01-23 17:48:40 +00:00
Taner
78f857fc60 New translations guild-view.yml (Chinese Simplified) 2023-01-23 17:48:39 +00:00
Taner
af90d7f28d New translations guild-view.yml (Turkish) 2023-01-23 17:48:37 +00:00
Taner
44d42c11d5 New translations guild-view.yml (Russian) 2023-01-23 17:48:36 +00:00
Taner
eab296eae0 New translations guild-view.yml (Polish) 2023-01-23 17:48:35 +00:00
Taner
dc4ab4296b New translations guild-view.yml (Spanish) 2023-01-23 17:48:33 +00:00
Taner
b054d3d8b2 New translations guild-view.yml (French) 2023-01-23 17:48:32 +00:00
Taner
91f2606291 New translations guild-creation.yml (Vietnamese) 2023-01-23 17:48:30 +00:00
Taner
f856b837fe New translations guild-creation.yml (Chinese Simplified) 2023-01-23 17:48:29 +00:00
Taner
735af257f6 New translations guild-creation.yml (Turkish) 2023-01-23 17:48:28 +00:00
Taner
17a720a150 New translations guild-creation.yml (Russian) 2023-01-23 17:48:27 +00:00
Taner
21d5a0ee44 New translations guild-creation.yml (Polish) 2023-01-23 17:48:25 +00:00
Taner
aeb36790ea New translations guild-creation.yml (Spanish) 2023-01-23 17:48:24 +00:00
Taner
59324e0d6d New translations guild-creation.yml (French) 2023-01-23 17:48:23 +00:00
Taner
02c339464b New translations friend-removal.yml (Vietnamese) 2023-01-23 17:48:22 +00:00
Taner
cf2dcc88fb New translations friend-removal.yml (Chinese Simplified) 2023-01-23 17:48:20 +00:00
Taner
acb95d7f7c New translations friend-removal.yml (Turkish) 2023-01-23 17:48:19 +00:00
Taner
6f6e16ffee New translations friend-removal.yml (Russian) 2023-01-23 17:48:17 +00:00
Taner
e8387b893b New translations friend-removal.yml (Polish) 2023-01-23 17:48:16 +00:00
Taner
89010a9867 New translations friend-removal.yml (Spanish) 2023-01-23 17:48:15 +00:00
Taner
b9cd04f310 New translations friend-removal.yml (French) 2023-01-23 17:48:14 +00:00
Taner
568bed78ba New translations friend-list.yml (Vietnamese) 2023-01-23 17:48:12 +00:00
Taner
c71accaabc New translations friend-list.yml (Chinese Simplified) 2023-01-23 17:48:11 +00:00
Taner
412c8d425e New translations friend-list.yml (Turkish) 2023-01-23 17:48:09 +00:00
Taner
ca6a3426c3 New translations friend-list.yml (Russian) 2023-01-23 17:48:08 +00:00
Taner
51dc5f44bb New translations friend-list.yml (Polish) 2023-01-23 17:48:07 +00:00
Taner
1b724fcf3c New translations friend-list.yml (Spanish) 2023-01-23 17:48:05 +00:00
Taner
7cace251f0 New translations friend-list.yml (French) 2023-01-23 17:48:04 +00:00
Taner
387726ef68 New translations class-select.yml (Vietnamese) 2023-01-23 17:48:02 +00:00
Taner
b399229b59 New translations class-select.yml (Chinese Simplified) 2023-01-23 17:48:01 +00:00
Taner
9a76892901 New translations class-select.yml (Turkish) 2023-01-23 17:47:59 +00:00
Taner
70aca34df6 New translations class-select.yml (Russian) 2023-01-23 17:47:58 +00:00
Taner
8466c532bc New translations class-select.yml (Polish) 2023-01-23 17:47:57 +00:00
Taner
f3cffd0e71 New translations class-select.yml (Spanish) 2023-01-23 17:47:56 +00:00
Taner
3d39e21433 New translations class-select.yml (French) 2023-01-23 17:47:54 +00:00
Taner
0445dc7e6c New translations class-confirm.yml (Vietnamese) 2023-01-23 17:47:53 +00:00
Taner
c4392eadff New translations class-confirm.yml (Chinese Simplified) 2023-01-23 17:47:52 +00:00
Taner
952ef1b89e New translations class-confirm.yml (Turkish) 2023-01-23 17:47:50 +00:00
Taner
c071abdda4 New translations class-confirm.yml (Russian) 2023-01-23 17:47:49 +00:00
Taner
5041651fae New translations class-confirm.yml (Polish) 2023-01-23 17:47:48 +00:00
Taner
5041169c43 New translations class-confirm.yml (Spanish) 2023-01-23 17:47:47 +00:00
Taner
9bf1842a5f New translations class-confirm.yml (French) 2023-01-23 17:47:45 +00:00
Taner
72554b546c New translations attribute-view.yml (Vietnamese) 2023-01-23 17:47:44 +00:00
Taner
d0d595caac New translations attribute-view.yml (Chinese Simplified) 2023-01-23 17:47:43 +00:00
Taner
f7bc366f4c New translations attribute-view.yml (Turkish) 2023-01-23 17:47:41 +00:00
Taner
174f85827a New translations attribute-view.yml (Russian) 2023-01-23 17:47:40 +00:00
Taner
ed5178730a New translations attribute-view.yml (Polish) 2023-01-23 17:47:38 +00:00
Taner
c0d2bae51c New translations attribute-view.yml (Spanish) 2023-01-23 17:47:37 +00:00
Taner
5cc8a9166d New translations attribute-view.yml (French) 2023-01-23 17:47:36 +00:00
716 changed files with 33994 additions and 16210 deletions

15
.m2/settings.xml Normal file
View File

@ -0,0 +1,15 @@
<settings>
<servers>
<server>
<id>nexus</id>
<username>${env.M2_REPO_USER}</username>
<password>${env.M2_REPO_PASS}</password>
<blocked>false</blocked>
</server>
<server>
<id>lumine</id>
<username>${env.M2_REPO_USER}</username>
<password>${env.M2_REPO_PASS}</password>
</server>
</servers>
</settings>

19
LICENSE
View File

@ -1,18 +1,3 @@
This project is owned and maintained by "Phoenix Development" and is distributed with "All Rights Reserved". This project is owned and maintained by PhoenixDvpt and is distributed with "All Right's Reserved".
PhoenixDevt reserves the right to change these terms at any time, you have to comply with the most recent version.
We do NOT provide support to servers involved with piracy in any form, or owners who have downloaded ANY of our plugins from an unofficial/illegal source.
Things can you CANNOT do: You can fork and modify the source code of this project as you wish to meet your server's needs, and merge requests are accepted under the terms that you grant full rights to us using any pushed code. However, you may not distribute the plugin for any purpose other than providing cross-compatibility with other Minecraft plugins, and may not bypass any anti-piracy protection.
- Issue a refund on PayPal without our explicit permission, as this is a digital good.
- Redistribute, sell or give an official/modified version of the plugin (with or without any type of counterpart) to anyone else.
- Modify and compile the project source code to bypass an anti-piracy protection.
- Download, compile, decompile or use the plugin on any server without purchasing a license.
Things can you CAN do when purchasing the plugin:
- Download and decompile the plugin file.
- Fork and modify the project source code to meet your production server's needs.
- Use it on ONE production server or network (= proxy-connected servers) and one private test server at a time.
You may propose a merge request, under the terms that you grant full rights to us using any pushed code.
If you are a developer and have not purchased a license, you have the permission to download, fork, edit and compile the project source code, and sell code modifications to your client ONLY IF they have already purchased a license. This only applies to one-time comission works and does NOT apply to public sales.

View File

@ -5,18 +5,35 @@
<parent> <parent>
<artifactId>MMOCore</artifactId> <artifactId>MMOCore</artifactId>
<groupId>net.Indyuce</groupId> <groupId>net.Indyuce</groupId>
<version>1.12.1-SNAPSHOT</version> <version>${revision}</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>MMOCore-API</artifactId> <artifactId>MMOCore-API</artifactId>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build> <build>
<finalName>${project.name}-${project.version}</finalName> <finalName>${project.name}-${project.version}</finalName>
<sourceDirectory>src/main/java</sourceDirectory> <sourceDirectory>src/main/java</sourceDirectory>
<defaultGoal>clean package install</defaultGoal> <defaultGoal>clean package install</defaultGoal>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>16</source>
<target>16</target>
<encoding>UTF-8</encoding>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
@ -80,13 +97,8 @@
</repository> </repository>
<repository> <repository>
<id>lumine</id> <id>spigot-repo</id>
<url>https://mvn.lumine.io/repository/maven/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository> </repository>
<repository> <repository>
@ -94,6 +106,11 @@
<url>https://maven.enginehub.org/repo/</url> <url>https://maven.enginehub.org/repo/</url>
</repository> </repository>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository> <repository>
<id>dmulloy2-repo</id> <id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url> <url>https://repo.dmulloy2.net/repository/public/</url>
@ -104,39 +121,16 @@
<id>simonsators Repo</id> <id>simonsators Repo</id>
<url>https://simonsator.de/repo</url> <url>https://simonsator.de/repo</url>
</repository> </repository>
<!-- Heroes Repository
<repository>
<id>herocraft</id>
<url>https://nexus.hc.to/content/repositories/pub_releases</url>
</repository> -->
</repositories> </repositories>
<dependencies> <dependencies>
<!-- Paper API --> <!-- Spigot API -->
<dependency> <dependency>
<groupId>io.papermc.paper</groupId> <groupId>org.spigotmc</groupId>
<artifactId>paper-api</artifactId> <artifactId>spigot-1.17.1</artifactId>
<version>1.20.6-R0.1-SNAPSHOT</version> <version>dev</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<!-- Extra libs --> <!-- Extra libs -->
@ -152,32 +146,14 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.20</version> <version>1.18.20</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<!-- Plugin dependencies --> <!-- Plugin dependencies -->
<dependency> <dependency>
<groupId>io.lumine</groupId> <groupId>io.lumine</groupId>
<artifactId>Mythic-Dist</artifactId> <artifactId>Mythic-Dist</artifactId>
<version>5.7.1</version> <version>5.0.1</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.playavalon</groupId>
<artifactId>MythicDungeons</artifactId>
<version>1.4.1-SNAPSHOT-CUSTOM</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>fr.phoenixdevt</groupId>
<artifactId>Profile-API</artifactId>
<version>1.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -185,7 +161,6 @@
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>
<version>2.9.2</version> <version>2.9.2</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -193,7 +168,6 @@
<artifactId>VaultAPI</artifactId> <artifactId>VaultAPI</artifactId>
<version>1.7.1</version> <version>1.7.1</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -201,18 +175,6 @@
<artifactId>worldguard-bukkit</artifactId> <artifactId>worldguard-bukkit</artifactId>
<version>7.0.2-SNAPSHOT</version> <version>7.0.2-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
@ -220,7 +182,6 @@
<artifactId>ProtocolLib</artifactId> <artifactId>ProtocolLib</artifactId>
<version>4.8.0</version> <version>4.8.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -228,7 +189,6 @@
<artifactId>Citizens</artifactId> <artifactId>Citizens</artifactId>
<version>2.0.30</version> <version>2.0.30</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<!-- Party plugins --> <!-- Party plugins -->
@ -237,7 +197,6 @@
<artifactId>DevelopmentPAFSpigot</artifactId> <artifactId>DevelopmentPAFSpigot</artifactId>
<version>1.0.65</version> <version>1.0.65</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -245,7 +204,6 @@
<artifactId>Party-and-Friends-MySQL-Edition-Spigot-API</artifactId> <artifactId>Party-and-Friends-MySQL-Edition-Spigot-API</artifactId>
<version>1.5.4-RELEASE</version> <version>1.5.4-RELEASE</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -253,15 +211,6 @@
<artifactId>spigot-party-api-for-party-and-friends</artifactId> <artifactId>spigot-party-api-for-party-and-friends</artifactId>
<version>1.0.4-RELEASE</version> <version>1.0.4-RELEASE</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.civious</groupId>
<artifactId>OBTeam</artifactId>
<version>1.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -269,7 +218,6 @@
<artifactId>Parties</artifactId> <artifactId>Parties</artifactId>
<version>3.1.14</version> <version>3.1.14</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -277,31 +225,13 @@
<artifactId>mcMMO</artifactId> <artifactId>mcMMO</artifactId>
<version>2.1.209</version> <version>2.1.209</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.erethon</groupId> <groupId>de.erethon</groupId>
<artifactId>DungeonsXL</artifactId> <artifactId>DungeonsXL</artifactId>
<version>0.18-SNAPSHOT-1149</version> <version>0.18-PRE-02</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.herocraftonline</groupId>
<artifactId>Heroes</artifactId>
<version>1.9.22</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>de.erethon</groupId>
<artifactId>Bedrock</artifactId>
<version>1.2.5</version>
<scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -309,7 +239,6 @@
<artifactId>Dungeons</artifactId> <artifactId>Dungeons</artifactId>
<version>1.0</version> <version>1.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<!-- Quest Plugins --> <!-- Quest Plugins -->
@ -318,45 +247,39 @@
<artifactId>Quests</artifactId> <artifactId>Quests</artifactId>
<version>4.4.1-b340</version> <version>4.4.1-b340</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>fr.skytasul.quests</groupId> <groupId>fr.skytasul.quests</groupId>
<artifactId>BeautyQuests</artifactId> <artifactId>BeautyQuests</artifactId>
<version>0.19.5</version> <version>0.19.5</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.guillaumevdn</groupId> <groupId>com.guillaumevdn</groupId>
<artifactId>QuestCreator</artifactId> <artifactId>QuestCreator</artifactId>
<version>6.39.0</version> <version>6.39.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.guillaumevdn</groupId> <groupId>com.guillaumevdn</groupId>
<artifactId>GCore</artifactId> <artifactId>GCore</artifactId>
<version>8.39.0</version> <version>8.39.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<!-- Guild plugins --> <!-- Guild plugins -->
<dependency> <dependency>
<groupId>cc.javajobs</groupId> <groupId>com.massivecraft</groupId>
<artifactId>FactionsBridge</artifactId> <artifactId>Factions</artifactId>
<version>1.3.6</version> <version>1.6.9.5-2.9.8-RC</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.UlrichBR</groupId> <groupId>me.ulrich</groupId>
<artifactId>UClansV7-API</artifactId> <artifactId>UltimateClans</artifactId>
<version>7.1.0</version> <version>4.2.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
@ -364,15 +287,13 @@
<artifactId>Guilds</artifactId> <artifactId>Guilds</artifactId>
<version>3.5.6.0</version> <version>3.5.6.0</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.kingdoms.main</groupId> <groupId>org.kingdoms.main</groupId>
<artifactId>Kingdoms</artifactId> <artifactId>Kingdoms</artifactId>
<version>1.15.5</version> <version>1.11.15.0.0.0.1.1</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -2,15 +2,14 @@ package net.Indyuce.mmocore;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.data.sql.SQLDataSource;
import io.lumine.mythic.lib.metrics.bukkit.Metrics;
import io.lumine.mythic.lib.util.MMOPlugin;
import io.lumine.mythic.lib.version.SpigotPlugin; import io.lumine.mythic.lib.version.SpigotPlugin;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.social.PartyManager;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.manager.ActionBarManager;
import net.Indyuce.mmocore.api.player.attribute.AttributeModifier; import net.Indyuce.mmocore.api.player.attribute.AttributeModifier;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot; import net.Indyuce.mmocore.command.*;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener; import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener;
import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader; import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader;
import net.Indyuce.mmocore.comp.mythicmobs.MythicHook; import net.Indyuce.mmocore.comp.mythicmobs.MythicHook;
@ -22,47 +21,45 @@ import net.Indyuce.mmocore.comp.region.DefaultRegionHandler;
import net.Indyuce.mmocore.comp.region.RegionHandler; import net.Indyuce.mmocore.comp.region.RegionHandler;
import net.Indyuce.mmocore.comp.region.WorldGuardMMOLoader; import net.Indyuce.mmocore.comp.region.WorldGuardMMOLoader;
import net.Indyuce.mmocore.comp.region.WorldGuardRegionHandler; import net.Indyuce.mmocore.comp.region.WorldGuardRegionHandler;
import net.Indyuce.mmocore.comp.region.pvpmode.PvPModeListener;
import net.Indyuce.mmocore.comp.vault.VaultEconomy; import net.Indyuce.mmocore.comp.vault.VaultEconomy;
import net.Indyuce.mmocore.comp.vault.VaultMMOLoader; import net.Indyuce.mmocore.comp.vault.VaultMMOLoader;
import net.Indyuce.mmocore.guild.GuildModule; import net.Indyuce.mmocore.guild.GuildModule;
import net.Indyuce.mmocore.guild.GuildModuleType; import net.Indyuce.mmocore.guild.GuildModuleType;
import net.Indyuce.mmocore.guild.GuildRelationHandler;
import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule; import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule;
import net.Indyuce.mmocore.guild.provided.YAMLGuildDataManager;
import net.Indyuce.mmocore.manager.*; import net.Indyuce.mmocore.manager.*;
import net.Indyuce.mmocore.manager.data.DataProvider; import net.Indyuce.mmocore.manager.data.DataProvider;
import net.Indyuce.mmocore.manager.data.GuildDataManager; import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
import net.Indyuce.mmocore.manager.data.LegacyDataProvider; import net.Indyuce.mmocore.manager.data.yaml.YAMLDataProvider;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
import net.Indyuce.mmocore.manager.profession.*; import net.Indyuce.mmocore.manager.profession.*;
import net.Indyuce.mmocore.manager.social.BoosterManager; import net.Indyuce.mmocore.manager.social.BoosterManager;
import net.Indyuce.mmocore.manager.social.PartyManager;
import net.Indyuce.mmocore.manager.social.RequestManager; import net.Indyuce.mmocore.manager.social.RequestManager;
import net.Indyuce.mmocore.party.MMOCoreTargetRestriction;
import net.Indyuce.mmocore.party.PartyModule; import net.Indyuce.mmocore.party.PartyModule;
import net.Indyuce.mmocore.party.PartyModuleType; import net.Indyuce.mmocore.party.PartyModuleType;
import net.Indyuce.mmocore.party.PartyRelationHandler;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.script.mechanic.ExperienceMechanic;
import net.Indyuce.mmocore.script.mechanic.ManaMechanic;
import net.Indyuce.mmocore.script.mechanic.StaminaMechanic;
import net.Indyuce.mmocore.script.mechanic.StelliumMechanic;
import net.Indyuce.mmocore.skill.cast.SkillCastingMode; import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
import net.Indyuce.mmocore.skill.trigger.MMOCoreTriggerType; import net.Indyuce.mmocore.script.mechanic.ExperienceMechanic;
import net.Indyuce.mmocore.script.mechanic.StaminaMechanic;
import net.Indyuce.mmocore.script.mechanic.ManaMechanic;
import net.Indyuce.mmocore.script.mechanic.StelliumMechanic;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.event.EventPriority; import io.lumine.mythic.lib.metrics.bukkit.Metrics;
import org.bukkit.command.CommandMap;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.lang.reflect.Field;
import java.util.logging.Level; import java.util.logging.Level;
public class MMOCore extends MMOPlugin { public class MMOCore extends JavaPlugin {
public static MMOCore plugin; public static MMOCore plugin;
public final WaypointManager waypointManager = new WaypointManager(); public final WaypointManager waypointManager = new WaypointManager();
public final SoundManager soundManager = new SoundManager(); public final SoundManager soundManager = new SoundManager();
public final RequestManager requestManager = new RequestManager(); public final RequestManager requestManager = new RequestManager();
@ -82,10 +79,6 @@ public class MMOCore extends MMOPlugin {
public final RestrictionManager restrictionManager = new RestrictionManager(); public final RestrictionManager restrictionManager = new RestrictionManager();
public final SkillTreeManager skillTreeManager = new SkillTreeManager(); public final SkillTreeManager skillTreeManager = new SkillTreeManager();
public final StatManager statManager = new StatManager(); public final StatManager statManager = new StatManager();
public final GuildDataManager nativeGuildManager = new YAMLGuildDataManager();
public final PlayerDataManager playerDataManager = new PlayerDataManager(this);
@Deprecated
public final DataProvider dataProvider = new LegacyDataProvider();
// Profession managers // Profession managers
public final CustomBlockManager mineManager = new CustomBlockManager(); public final CustomBlockManager mineManager = new CustomBlockManager();
@ -99,11 +92,13 @@ public class MMOCore extends MMOPlugin {
public VaultEconomy economy; public VaultEconomy economy;
public RegionHandler regionHandler = new DefaultRegionHandler(); public RegionHandler regionHandler = new DefaultRegionHandler();
public PlaceholderParser placeholderParser = new DefaultParser(); public PlaceholderParser placeholderParser = new DefaultParser();
public DataProvider dataProvider = new YAMLDataProvider();
// Modules // Modules
@NotNull @NotNull
public PartyModule partyModule; public PartyModule partyModule;
public GuildModule guildModule; public GuildModule guildModule;
public boolean shouldDebugSQL = false;
public MMOCore() { public MMOCore() {
plugin = this; plugin = this;
@ -111,13 +106,10 @@ public class MMOCore extends MMOPlugin {
@Override @Override
public void onLoad() { public void onLoad() {
getLogger().log(Level.INFO, "Plugin file is called '" + getFile().getName() + "'");
// Register MMOCore-specific objects // Register MMOCore-specific objects
MythicLib.plugin.getEntities().registerRelationHandler(new PartyRelationHandler()); MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction());
MythicLib.plugin.getEntities().registerRelationHandler(new GuildRelationHandler());
MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject)); MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject));
MMOCoreTriggerType.registerAll();
// Custom scripts // Custom scripts
MythicLib.plugin.getSkills().registerMechanic("mana", config -> new ManaMechanic(config)); MythicLib.plugin.getSkills().registerMechanic("mana", config -> new ManaMechanic(config));
@ -151,13 +143,12 @@ public class MMOCore extends MMOPlugin {
getLogger().warning("(Your config version: '" + configVersion + "' | Expected config version: '" + defConfigVersion + "')"); getLogger().warning("(Your config version: '" + configVersion + "' | Expected config version: '" + defConfigVersion + "')");
} }
if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled")) { if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled"))
final SQLDataSource dataSource = new SQLDataSource(this); dataProvider = new MySQLDataProvider(getConfig());
playerDataManager.setDataHandler(new SQLDataHandler(dataSource)); shouldDebugSQL = getConfig().getBoolean("mysql.debug");
}
if (getConfig().isConfigurationSection("default-playerdata")) if (getConfig().isConfigurationSection("default-playerdata"))
playerDataManager.loadDefaultData(getConfig().getConfigurationSection("default-playerdata")); dataProvider.getDataManager().loadDefaultData(getConfig().getConfigurationSection("default-playerdata"));
if (Bukkit.getPluginManager().getPlugin("Vault") != null) economy = new VaultEconomy(); if (Bukkit.getPluginManager().getPlugin("Vault") != null) economy = new VaultEconomy();
@ -173,8 +164,6 @@ public class MMOCore extends MMOPlugin {
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) { if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
regionHandler = new WorldGuardRegionHandler(); regionHandler = new WorldGuardRegionHandler();
if (getConfig().getBoolean("pvp_mode.enabled"))
Bukkit.getPluginManager().registerEvents(new PvPModeListener(), this);
getLogger().log(Level.INFO, "Hooked onto WorldGuard"); getLogger().log(Level.INFO, "Hooked onto WorldGuard");
} }
@ -184,8 +173,8 @@ public class MMOCore extends MMOPlugin {
} }
/* /*
* Resource regeneration. Must check if entity is dead otherwise regen * Resource regeneration. Must check if entity is dead otherwise regen will make
* will make the 'respawn' button glitched plus HURT entity effect bug * the 'respawn' button glitched plus HURT entity effect bug
*/ */
new BukkitRunnable() { new BukkitRunnable() {
public void run() { public void run() {
@ -207,6 +196,8 @@ public class MMOCore extends MMOPlugin {
if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) { if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) {
getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "MMOCore is not meant to be used with MMOItems ManaAndStamina"); getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "MMOCore is not meant to be used with MMOItems ManaAndStamina");
getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!"); getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!");
Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] MMOCore is not meant to be used with MMOItems ManaAndStamina");
Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] Please read the installation guide!");
return; return;
} }
@ -216,10 +207,9 @@ public class MMOCore extends MMOPlugin {
try { try {
String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin")); String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin"));
PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName); PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName);
Validate.isTrue(moduleType.isValid(), "Plugin " + moduleType.getPluginName() + " is not installed"); Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
partyModule = moduleType.provideModule(); partyModule = moduleType.provideModule();
getLogger().log(Level.INFO, "Hooked parties onto " + moduleType.getPluginName()); } catch (RuntimeException exception) {
} catch (Throwable exception) {
getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage()); getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage());
partyModule = new MMOCorePartyModule(); partyModule = new MMOCorePartyModule();
} }
@ -230,7 +220,6 @@ public class MMOCore extends MMOPlugin {
GuildModuleType moduleType = GuildModuleType.valueOf(pluginName); GuildModuleType moduleType = GuildModuleType.valueOf(pluginName);
Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed"); Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
guildModule = moduleType.provideModule(); guildModule = moduleType.provideModule();
getLogger().log(Level.INFO, "Hooked guilds onto " + moduleType.getPluginName());
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not initialize guild module: " + exception.getMessage()); getLogger().log(Level.WARNING, "Could not initialize guild module: " + exception.getMessage());
guildModule = new MMOCoreGuildModule(); guildModule = new MMOCoreGuildModule();
@ -238,8 +227,8 @@ public class MMOCore extends MMOPlugin {
// Skill casting // Skill casting
try { try {
final SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode"))); SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
mode.setCurrent(getConfig().getConfigurationSection("skill-casting")); Bukkit.getPluginManager().registerEvents(mode.loadFromConfig(getConfig().getConfigurationSection("skill-casting")), this);
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage()); getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage());
} }
@ -248,7 +237,6 @@ public class MMOCore extends MMOPlugin {
try { try {
Class.forName("net.Indyuce.mmocore.MMOCoreBukkit").getConstructor(MMOCore.class).newInstance(this); Class.forName("net.Indyuce.mmocore.MMOCoreBukkit").getConstructor(MMOCore.class).newInstance(this);
} catch (Throwable exception) { } catch (Throwable exception) {
exception.printStackTrace();
throw new RuntimeException("Cannot run an API build on Spigot!"); throw new RuntimeException("Cannot run an API build on Spigot!");
} }
@ -257,29 +245,95 @@ public class MMOCore extends MMOPlugin {
* that after registering all the professses otherwise the player datas can't * that after registering all the professses otherwise the player datas can't
* recognize what profess the player has and professes will be lost * recognize what profess the player has and professes will be lost
*/ */
playerDataManager.initialize(EventPriority.LOW, EventPriority.NORMAL); Bukkit.getOnlinePlayers().forEach(player -> dataProvider.getDataManager().setup(player.getUniqueId()));
// load guild data after loading player data // load guild data after loading player data
nativeGuildManager.load(); dataProvider.getGuildManager().load();
// Toggleable Commands // Command
ToggleableCommand.register(); try {
final Field bukkitCommandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
bukkitCommandMap.setAccessible(true);
CommandMap commandMap = (CommandMap) bukkitCommandMap.get(Bukkit.getServer());
FileConfiguration config = new ConfigFile("commands").getConfig();
if (config.contains("player"))
commandMap.register("mmocore", new PlayerStatsCommand(config.getConfigurationSection("player")));
if (config.contains("attributes"))
commandMap.register("mmocore", new AttributesCommand(config.getConfigurationSection("attributes")));
if (config.contains("class"))
commandMap.register("mmocore", new ClassCommand(config.getConfigurationSection("class")));
if (config.contains("waypoints"))
commandMap.register("mmocore", new WaypointsCommand(config.getConfigurationSection("waypoints")));
if (config.contains("quests"))
commandMap.register("mmocore", new QuestsCommand(config.getConfigurationSection("quests")));
if (config.contains("skills"))
commandMap.register("mmocore", new SkillsCommand(config.getConfigurationSection("skills")));
if (config.contains("friends"))
commandMap.register("mmocore", new FriendsCommand(config.getConfigurationSection("friends")));
if (config.contains("party"))
commandMap.register("mmocore", new PartyCommand(config.getConfigurationSection("party")));
if (config.contains("guild"))
commandMap.register("mmocore", new GuildCommand(config.getConfigurationSection("guild")));
if (config.contains("skill-trees"))
commandMap.register("mmocore", new SkillTreeCommand(config.getConfigurationSection("skill-trees")));
if (hasEconomy() && economy.isValid()) {
if (config.contains("withdraw"))
commandMap.register("mmocore", new WithdrawCommand(config.getConfigurationSection("withdraw")));
if (config.contains("deposit"))
commandMap.register("mmocore", new DepositCommand(config.getConfigurationSection("deposit")));
}
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) {
ex.printStackTrace();
}
// Register MMOCore command what soever
MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot(); MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot();
getCommand("mmocore").setExecutor(mmoCoreCommand); getCommand("mmocore").setExecutor(mmoCoreCommand);
getCommand("mmocore").setTabCompleter(mmoCoreCommand); getCommand("mmocore").setTabCompleter(mmoCoreCommand);
if (getConfig().getBoolean("auto-save.enabled")) {
int autosave = getConfig().getInt("auto-save.interval") * 20;
new BukkitRunnable() {
public void run() {
// Save player data
for (PlayerData data : PlayerData.getAll())
if (data.isFullyLoaded())
dataProvider.getDataManager().saveData(data);
// Save guild info
for (Guild guild : dataProvider.getGuildManager().getAll())
dataProvider.getGuildManager().save(guild);
}
}.runTaskTimerAsynchronously(MMOCore.plugin, autosave, autosave);
}
} }
@Override @Override
public void onDisable() { public void onDisable() {
// Save guild info //Executes all the pending asynchronous task (like saving the playerData)
for (Guild guild : nativeGuildManager.getAll()) Bukkit.getScheduler().getPendingTasks().forEach(worker -> {
nativeGuildManager.save(guild); if (worker.getOwner().equals(this)) {
((Runnable) worker).run();
}
});
// Save player data
for (PlayerData data : PlayerData.getAll())
if (data.isFullyLoaded()) {
data.close();
dataProvider.getDataManager().saveData(data);
}
// Close player data manager // Save guild info
playerDataManager.close(); for (Guild guild : dataProvider.getGuildManager().getAll())
dataProvider.getGuildManager().save(guild);
// Close MySQL data provider (memory leaks)
if (dataProvider instanceof MySQLDataProvider)
((MySQLDataProvider) dataProvider).close();
// Reset active blocks // Reset active blocks
mineManager.resetRemainingBlocks(); mineManager.resetRemainingBlocks();
@ -303,6 +357,8 @@ public class MMOCore extends MMOPlugin {
configManager = new ConfigManager(); configManager = new ConfigManager();
if (clearBefore)
MythicLib.plugin.getSkills().initialize(true);
skillManager.initialize(clearBefore); skillManager.initialize(clearBefore);
mineManager.initialize(clearBefore); mineManager.initialize(clearBefore);
partyManager.initialize(clearBefore); partyManager.initialize(clearBefore);
@ -316,6 +372,7 @@ public class MMOCore extends MMOPlugin {
statManager.initialize(clearBefore); statManager.initialize(clearBefore);
professionManager.initialize(clearBefore); professionManager.initialize(clearBefore);
InventoryManager.load();
skillTreeManager.initialize(clearBefore); skillTreeManager.initialize(clearBefore);
classManager.initialize(clearBefore); classManager.initialize(clearBefore);
questManager.initialize(clearBefore); questManager.initialize(clearBefore);
@ -325,14 +382,12 @@ public class MMOCore extends MMOPlugin {
requestManager.initialize(clearBefore); requestManager.initialize(clearBefore);
soundManager.initialize(clearBefore); soundManager.initialize(clearBefore);
configItems.initialize(clearBefore); configItems.initialize(clearBefore);
//Needs to be loaded after the class manager.
InventoryManager.load();
if (getConfig().isConfigurationSection("action-bar")) if (getConfig().isConfigurationSection("action-bar"))
actionBarManager.reload(getConfig().getConfigurationSection("action-bar")); actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));
if (clearBefore) if (clearBefore)
PlayerData.getAll().forEach(PlayerData::reload); PlayerData.getAll().forEach(PlayerData::update);
} }
public static void log(String message) { public static void log(String message) {
@ -350,4 +405,9 @@ public class MMOCore extends MMOPlugin {
public boolean hasEconomy() { public boolean hasEconomy() {
return economy != null && economy.isValid(); return economy != null && economy.isValid();
} }
public static void sqlDebug(String s) {
if (!MMOCore.plugin.shouldDebugSQL) return;
MMOCore.plugin.getLogger().warning("- [SQL Debug] " + s);
}
} }

View File

@ -2,143 +2,47 @@ package net.Indyuce.mmocore.api;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.OfflinePlayer;
import net.md_5.bungee.api.ChatMessageType; import org.bukkit.command.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
public class ConfigMessage { public class ConfigMessage {
private final String key; private final List<String> messages;
private final List<String> lines = new ArrayList<>();
private final boolean papiPlaceholders, actionbar, raw;
private ConfigMessage(@NotNull String key) { public ConfigMessage(String key) {
this.key = key; messages = MMOCore.plugin.configManager.getMessage(key);
// Initialize message list
final Object obj = MMOCore.plugin.configManager.getMessageObject(key);
if (obj == null) lines.add("<message_not_found:'" + key + "'>");
else if (obj instanceof List<?>) lines.addAll((List<String>) obj);
else {
final String tostr = obj.toString();
if (!tostr.isEmpty()) lines.add(tostr);
} }
// Does message include placeholders public ConfigMessage addPlaceholders(String... placeholders) {
boolean hasPlaceholders = false; for (int n = 0; n < messages.size(); n++) {
for (String str : lines) String line = messages.get(n);
if (str.contains("%")) {
hasPlaceholders = true;
break;
}
this.papiPlaceholders = hasPlaceholders;
// Is message for action bar
actionbar = !lines.isEmpty() && lines.get(0).startsWith("%");
if (actionbar) lines.set(0, lines.get(0).substring(1));
// Are messages raw (JSON format)
raw = !lines.isEmpty() && (lines.get(0).startsWith("{") || lines.get(0).startsWith("["));
}
/**
* Useful for things like indicators or specific lore lines
* which are string tags not requiring more than one string
* object. An empty return value is accepted as some features
* do require the ability to fully remove text.
*
* @return First line of message, if it exists.
*/
@NotNull
public String asLine() {
return lines.isEmpty() ? "" : lines.get(0);
}
@NotNull
public List<String> getLines() {
return lines;
}
@NotNull
public ConfigMessage addPlaceholders(@NotNull Object... placeholders) {
for (int n = 0; n < lines.size(); n++) {
String line = lines.get(n);
// Apply placeholders to string
for (int j = 0; j < placeholders.length - 1; j += 2) { for (int j = 0; j < placeholders.length - 1; j += 2) {
final String placeholder = String.valueOf(placeholders[j]); String placeholder = placeholders[j];
line = line.replace("{" + placeholder + "}", String.valueOf(placeholders[j + 1])); if (line.contains("{" + placeholder + "}"))
line = line.replace("{" + placeholder + "}", placeholders[j + 1]);
} }
messages.set(n, line);
lines.set(n, line);
} }
return this; return this;
} }
@Deprecated public void send(CommandSender sender) {
public void sendAsJSon(Player player) { messages.forEach(line -> sender.sendMessage(format(sender, line)));
send(player);
}
public void send(Player player) {
for (String line : lines) send(player, line);
} }
public void send(Collection<? extends Player> players) { public void send(Collection<? extends Player> players) {
for (Player player : players) for (String line : lines) send(player, line); players.forEach(player -> messages.forEach(line -> player.sendMessage(format(player, line))));
} }
/** public void sendAsJSon(Player player) {
* Sends a line of text to a target player messages.forEach(line -> MythicLib.plugin.getVersion().getWrapper().sendJson(player, format(player, line)));
*
* @param player Player to send message to. His player
* data is not necessarily fully loaded
* @param messageFormat Raw/normal message to send
*/
private void send(@NotNull Player player, String messageFormat) {
Validate.notNull(player, "Player cannot be null");
final String rawMessage = format(player, messageFormat);
final PlayerData playerData = PlayerData.has(player) ? PlayerData.get(player) : null;
// Handle special case with player data + action bar
if (playerData != null && playerData.isOnline() && actionbar) {
playerData.displayActionBar(rawMessage, raw);
return;
} }
// Normal sender private String format(CommandSender sender, String input) {
if (this.raw) { String str = MythicLib.plugin.parseColors(input);
if (actionbar) MythicLib.plugin.getVersion().getWrapper().sendActionBarRaw(player, rawMessage); return sender instanceof Player ? MMOCore.plugin.placeholderParser.parse((OfflinePlayer) sender, str) : str;
else MythicLib.plugin.getVersion().getWrapper().sendJson(player, rawMessage);
} else {
if (actionbar)
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(rawMessage));
else player.sendMessage(rawMessage);
}
}
@NotNull
private String format(@Nullable Player player, String input) {
input = MythicLib.plugin.parseColors(input);
if (!papiPlaceholders || player == null) return input; // Optimization
return MMOCore.plugin.placeholderParser.parse(player, input);
}
@NotNull
public static ConfigMessage fromKey(@NotNull String key, Object... placeholders) {
Validate.notNull(MMOCore.plugin.configManager, "MMOCore has not finished enabling");
final ConfigMessage message = new ConfigMessage(key);
if (placeholders.length != 0) message.addPlaceholders(placeholders);
return message;
} }
} }

View File

@ -25,7 +25,7 @@ public class MMOCoreAPI {
} }
public PlayerData getPlayerData(OfflinePlayer player) { public PlayerData getPlayerData(OfflinePlayer player) {
return PlayerData.get(player); return PlayerData.get(player.getUniqueId());
} }
public boolean isInSameParty(Player player1, Player player2) { public boolean isInSameParty(Player player1, Player player2) {
@ -65,7 +65,7 @@ public class MMOCoreAPI {
public SkillResult cast(PlayerData playerData, ClassSkill skill) { public SkillResult cast(PlayerData playerData, ClassSkill skill) {
PlayerMetadata casterMeta = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); PlayerMetadata casterMeta = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
TriggerMetadata triggerMeta = new TriggerMetadata(casterMeta, null, null); TriggerMetadata triggerMeta = new TriggerMetadata(casterMeta, null, null);
return new CastableSkill(skill, playerData).cast(triggerMeta); return new CastableSkill(skill, playerData.getSkillLevel(skill.getSkill())).cast(triggerMeta);
} }
/** /**

View File

@ -6,14 +6,15 @@ public enum SoundEvent {
WARP_CANCELLED, WARP_CANCELLED,
WARP_CHARGE, WARP_CHARGE,
WARP_UNLOCK, WARP_UNLOCK,
HOTBAR_SWAP,
SPELL_CAST_BEGIN, SPELL_CAST_BEGIN,
SPELL_CAST_END, SPELL_CAST_END,
CANT_SELECT_CLASS, CANT_SELECT_CLASS,
SELECT_CLASS, SELECT_CLASS,
LEVEL_ATTRIBUTE, LEVEL_ATTRIBUTE,
RESET_ATTRIBUTES, RESET_ATTRIBUTES,
RESET_SKILLS, RESET_SKILLS
NOT_ENOUGH_POINTS, ,NOT_ENOUGH_POINTS,
CANCEL_QUEST, CANCEL_QUEST,
START_QUEST, START_QUEST,
CLOSE_LOOT_CHEST, CLOSE_LOOT_CHEST,

View File

@ -24,7 +24,6 @@ public class SoundObject {
private final float volume; private final float volume;
private final float pitch; private final float pitch;
@Deprecated
public SoundObject(String input) { public SoundObject(String input) {
String[] split = input.split(","); String[] split = input.split(",");
@ -37,14 +36,12 @@ public class SoundObject {
} }
this.sound = sound; this.sound = sound;
this.key = key != null ? key.toLowerCase() : null; this.key = key;
volume = split.length > 1 ? Float.parseFloat(split[1]) : 1; volume = split.length > 1 ? Float.parseFloat(split[1]) : 1;
pitch = split.length > 2 ? Float.parseFloat(split[2]) : 1; pitch = split.length > 2 ? Float.parseFloat(split[2]) : 1;
} }
@Deprecated
public SoundObject(ConfigurationSection config) { public SoundObject(ConfigurationSection config) {
String input = config.getString("sound"); String input = config.getString("sound");
@ -57,7 +54,7 @@ public class SoundObject {
} }
this.sound = sound; this.sound = sound;
this.key = key != null ? key.toLowerCase() : null; this.key = key;
volume = (float) config.getDouble("volume", 1); volume = (float) config.getDouble("volume", 1);
pitch = (float) config.getDouble("pitch", 1); pitch = (float) config.getDouble("pitch", 1);
@ -67,39 +64,32 @@ public class SoundObject {
* @return If this object is custom a custom sound, potentially * @return If this object is custom a custom sound, potentially
* from a resource pack * from a resource pack
*/ */
@Deprecated
public boolean isCustom() { public boolean isCustom() {
return sound == null; return sound == null;
} }
@Nullable @Nullable
@Deprecated
public Sound getSound() { public Sound getSound() {
return sound; return sound;
} }
@Nullable @Nullable
@Deprecated
public String getKey() { public String getKey() {
return key; return key;
} }
@Deprecated
public float getVolume() { public float getVolume() {
return volume; return volume;
} }
@Deprecated
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
@Deprecated
public void playTo(Player player) { public void playTo(Player player) {
playTo(player, volume, pitch); playTo(player, volume, pitch);
} }
@Deprecated
public void playTo(Player player, float volume, float pitch) { public void playTo(Player player, float volume, float pitch) {
if (isCustom()) if (isCustom())
player.playSound(player.getLocation(), key, volume, pitch); player.playSound(player.getLocation(), key, volume, pitch);
@ -107,12 +97,10 @@ public class SoundObject {
player.playSound(player.getLocation(), sound, volume, pitch); player.playSound(player.getLocation(), sound, volume, pitch);
} }
@Deprecated
public void playAt(Location loc) { public void playAt(Location loc) {
playAt(loc, volume, pitch); playAt(loc, volume, pitch);
} }
@Deprecated
public void playAt(Location loc, float volume, float pitch) { public void playAt(Location loc, float volume, float pitch) {
if (isCustom()) if (isCustom())
loc.getWorld().playSound(loc, key, volume, pitch); loc.getWorld().playSound(loc, key, volume, pitch);

View File

@ -43,7 +43,7 @@ public class BlockInfo {
options.put(option, config.getBoolean("options." + key)); options.put(option, config.getBoolean("options." + key));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load option '" + key + "' from block info '" + block.display() + "': " + exception.getMessage()); "Could not load option '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
} }
if (config.contains("triggers")) { if (config.contains("triggers")) {
@ -55,7 +55,7 @@ public class BlockInfo {
triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key))); triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load trigger '" + key + "' from block info '" + block.display() + "': " + exception.getMessage()); "Could not load trigger '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
} }
} }
@ -65,13 +65,13 @@ public class BlockInfo {
if (condition instanceof BlockCondition) if (condition instanceof BlockCondition)
conditions.add((BlockCondition) condition); conditions.add((BlockCondition) condition);
} }
} }
public boolean getOption(BlockInfoOption option) { public boolean getOption(BlockInfoOption option) {
return options.getOrDefault(option, option.getDefault()); return options.getOrDefault(option, option.getDefault());
} }
@NotNull
public BlockType getBlock() { public BlockType getBlock() {
return block; return block;
} }
@ -85,7 +85,6 @@ public class BlockInfo {
return table != null; return table != null;
} }
@Deprecated
public List<ItemStack> collectDrops(LootBuilder builder) { public List<ItemStack> collectDrops(LootBuilder builder) {
return table != null ? table.collect(builder) : new ArrayList<>(); return table != null ? table.collect(builder) : new ArrayList<>();
} }

View File

@ -1,31 +1,29 @@
package net.Indyuce.mmocore.api.block; package net.Indyuce.mmocore.api.block;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface BlockType { public interface BlockType {
/** /**
* Called when placing temporary blocks * Called when placing temporary blocks
*/ */
void place(@NotNull BlockInfo.RegeneratingBlock placed); void place(BlockInfo.RegeneratingBlock placed);
/** /**
* Called when regenerating an older block with block regen * Called when regenerating an older block with block regen
*/ */
void regenerate(@NotNull BlockInfo.RegeneratingBlock regenerating); void regenerate(BlockInfo.RegeneratingBlock regenerating);
@NotNull String display(); /**
* Generates a key used to store the BlockInfo instance in the manager map,
* the key depends on the block type to make sure there is no interference
*/
String generateKey();
/** /**
* Applies some extra break restrictions; returns TRUE if the block can be * Applies some extra break restrictions; returns TRUE if the block can be
* broken. This method is used to prevent non mature crops from being broken * broken. This method is used to prevent non mature crops from being broken
* for example * for example
*/ */
boolean breakRestrictions(@NotNull Block block); boolean breakRestrictions(Block block);
int hashCode();
boolean equals(@Nullable Object obj);
} }

View File

@ -1,14 +1,13 @@
package net.Indyuce.mmocore.api.block; package net.Indyuce.mmocore.api.block;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import java.util.Objects; import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.version.VersionMaterial;
public class SkullBlockType implements BlockType { public class SkullBlockType implements BlockType {
private final String value; private final String value;
@ -30,7 +29,7 @@ public class SkullBlockType implements BlockType {
@Override @Override
public void place(RegeneratingBlock block) { public void place(RegeneratingBlock block) {
Location loc = block.getLocation(); Location loc = block.getLocation();
loc.getBlock().setType(Material.PLAYER_HEAD); loc.getBlock().setType(VersionMaterial.PLAYER_HEAD.toMaterial());
// save skull orientation if replaced block is a player head // save skull orientation if replaced block is a player head
if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial())) if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
@ -49,25 +48,12 @@ public class SkullBlockType implements BlockType {
} }
@Override @Override
public String display() { public String generateKey() {
return "Skull{" + value + "}"; return "vanilla-skull-" + value;
} }
@Override @Override
public boolean breakRestrictions(Block block) { public boolean breakRestrictions(Block block) {
return true; return true;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SkullBlockType that = (SkullBlockType) o;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
} }

View File

@ -1,7 +1,5 @@
package net.Indyuce.mmocore.api.block; package net.Indyuce.mmocore.api.block;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -9,7 +7,8 @@ import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import java.util.Objects; import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class VanillaBlockType implements BlockType { public class VanillaBlockType implements BlockType {
private final Material type; private final Material type;
@ -59,25 +58,12 @@ public class VanillaBlockType implements BlockType {
} }
@Override @Override
public String display() { public String generateKey() {
return "Vanilla{" + type.name() + "}"; return "vanilla-block-" + type.name();
} }
@Override @Override
public boolean breakRestrictions(Block block) { public boolean breakRestrictions(Block block) {
return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age); return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VanillaBlockType that = (VanillaBlockType) o;
return type == that.type;
}
@Override
public int hashCode() {
return Objects.hash(type);
}
} }

View File

@ -5,7 +5,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder; import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -39,7 +38,7 @@ public class Withdraw implements Listener {
return; return;
withdrawing.add(player.getUniqueId()); withdrawing.add(player.getUniqueId());
ConfigMessage.fromKey("withdrawing").send(player); MMOCore.plugin.configManager.getSimpleMessage("withdrawing").send(player);
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, 20 * 20); Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, 20 * 20);
} }
@ -61,7 +60,7 @@ public class Withdraw implements Listener {
if (!event.getPlayer().equals(player)) if (!event.getPlayer().equals(player))
return; return;
ConfigMessage.fromKey("withdraw-cancel").send(player); MMOCore.plugin.configManager.getSimpleMessage("withdraw-cancel").send(player);
close(); close();
} }
@ -76,13 +75,13 @@ public class Withdraw implements Listener {
try { try {
worth = Integer.parseInt(event.getMessage()); worth = Integer.parseInt(event.getMessage());
} catch (Exception e) { } catch (Exception e) {
ConfigMessage.fromKey("wrong-number").addPlaceholders("arg", event.getMessage()).send(player); MMOCore.plugin.configManager.getSimpleMessage("wrong-number", "arg", event.getMessage()).send(player);
return; return;
} }
int left = (int) (MMOCore.plugin.economy.getEconomy().getBalance(player) - worth); int left = (int) (MMOCore.plugin.economy.getEconomy().getBalance(player) - worth);
if (left < 0) { if (left < 0) {
ConfigMessage.fromKey("not-enough-money").addPlaceholders("left", -left).send(player); MMOCore.plugin.configManager.getSimpleMessage("not-enough-money", "left", "" + -left).send(player);
return; return;
} }
@ -92,7 +91,7 @@ public class Withdraw implements Listener {
MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, worth); MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, worth);
withdrawAlgorythm(worth); withdrawAlgorythm(worth);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
ConfigMessage.fromKey("withdrew").addPlaceholders("worth", worth).send(player); MMOCore.plugin.configManager.getSimpleMessage("withdrew", "worth", "" + worth).send(player);
}); });
} }

View File

@ -0,0 +1,29 @@
package net.Indyuce.mmocore.api.event;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
/**
* In order to create bukkit async events we must call
* the right constructor:
* <p>
* {@link Event#Event(boolean)} and have the boolean set to true
*/
public abstract class AsyncPlayerDataEvent extends Event {
private final PlayerData playerData;
public AsyncPlayerDataEvent(PlayerData playerData) {
super(true);
this.playerData = playerData;
}
public PlayerData getData() {
return playerData;
}
public Player getPlayer() {
return playerData.getPlayer();
}
}

View File

@ -0,0 +1,27 @@
package net.Indyuce.mmocore.api.event;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.event.HandlerList;
public class AsyncPlayerDataLoadEvent extends AsyncPlayerDataEvent {
private static final HandlerList handlers = new HandlerList();
/**
* Called when a player data is being loaded into the game.
* This event is called async.
*
* @param playerData Player data being loaded
*/
public AsyncPlayerDataLoadEvent(PlayerData playerData) {
super(playerData);
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -4,7 +4,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
/** /**
* @deprecated Use {@link io.lumine.mythic.lib.api.event.SynchronizedDataLoadEvent} instead * @deprecated Use {@link AsyncPlayerDataLoadEvent} instead
*/ */
@Deprecated @Deprecated
public class PlayerDataLoadEvent extends PlayerDataEvent { public class PlayerDataLoadEvent extends PlayerDataEvent {

View File

@ -1,42 +0,0 @@
package net.Indyuce.mmocore.api.event;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerEnterCastingModeEvent extends PlayerDataEvent implements Cancellable {
private boolean cancelled = false;
private static final HandlerList HANDLERS = new HandlerList();
@Deprecated
public PlayerEnterCastingModeEvent(@NotNull Player who) {
super(PlayerData.get(who));
}
public PlayerEnterCastingModeEvent(@NotNull PlayerData playerData) {
super(playerData);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@ -1,43 +0,0 @@
package net.Indyuce.mmocore.api.event;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerExitCastingModeEvent extends PlayerDataEvent implements Cancellable {
private boolean cancelled = false;
private static final HandlerList HANDLERS = new HandlerList();
@Deprecated
public PlayerExitCastingModeEvent(@NotNull Player who) {
super(PlayerData.get(who));
}
public PlayerExitCastingModeEvent(@NotNull PlayerData who) {
super(who);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@ -56,10 +56,6 @@ public class PlayerResourceUpdateEvent extends PlayerDataEvent implements Cancel
return amount; return amount;
} }
public UpdateReason getReason() {
return reason;
}
/** /**
* Changes the amount of resource given/taken away * Changes the amount of resource given/taken away
* *

View File

@ -1,36 +0,0 @@
package net.Indyuce.mmocore.api.event.unlocking;
import net.Indyuce.mmocore.api.event.PlayerDataEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
public abstract class ItemChangeEvent extends PlayerDataEvent {
private final String itemKey;
public ItemChangeEvent(PlayerData playerData, String itemKey) {
super(playerData);
this.itemKey = itemKey;
}
/**
* @return The full item key in the format <plugin-id>:<item-type-id>:<item-id>.
*/
public String getItemKey() {
return itemKey;
}
/**
* @return The item-type-id which is the first parameter in the key format <item-type-id>:<item-id>.
*/
public String getItemTypeId() {
return itemKey.split(":")[0];
}
/**
* @return The item--id which is the last parameter in the key format <item-type-id>:<item-id>.
*/
public String getItemId() {
return itemKey.split(":")[1];
}
}

View File

@ -1,24 +0,0 @@
package net.Indyuce.mmocore.api.event.unlocking;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class ItemLockedEvent extends ItemChangeEvent {
private static final HandlerList handlers = new HandlerList();
public ItemLockedEvent(PlayerData playerData, String itemKey) {
super(playerData, itemKey);
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -1,22 +0,0 @@
package net.Indyuce.mmocore.api.event.unlocking;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class ItemUnlockedEvent extends ItemChangeEvent {
private static final HandlerList handlers = new HandlerList();
public ItemUnlockedEvent(PlayerData playerData, String itemKey) {
super(playerData, itemKey);
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -19,28 +19,10 @@ public class DefaultMMOLoader extends MMOLoader {
public Trigger loadTrigger(MMOLineConfig config) { public Trigger loadTrigger(MMOLineConfig config) {
if (config.getKey().equals("from")) if (config.getKey().equals("from"))
return new FromTrigger(config); return new FromTrigger(config);
if (config.getKey().equals("stat")) if (config.getKey().equals("stat"))
return new StatTrigger(config); return new StatTrigger(config);
if(config.getKey().equals("unlock_slot"))
return new UnlockSlotTrigger(config);
if (config.getKey().equals("unlock_skill"))
return new UnlockSkillTrigger(config);
if (config.getKey().equals("bind_skill"))
return new BindSkillTrigger(config);
if (config.getKey().equals("levelup_skill"))
return new LevelUpSkillTrigger(config);
if (config.getKey().equals("skill_buff")||config.getKey().equals("skill_modifier"))
return new SkillModifierTrigger(config);
if (config.getKey().equals("message")) if (config.getKey().equals("message"))
return new MessageTrigger(config); return new MessageTrigger(config);
if (config.getKey().equals("sound") || config.getKey().equals("playsound")) if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
return new SoundTrigger(config); return new SoundTrigger(config);
@ -119,12 +101,6 @@ public class DefaultMMOLoader extends MMOLoader {
if (config.getKey().equals("permission")) if (config.getKey().equals("permission"))
return new PermissionCondition(config); return new PermissionCondition(config);
if (config.getKey().equals("weather"))
return new WeatherCondition(config);
if (config.getKey().equals("time"))
return new TimeCondition(config);
return null; return null;
} }

View File

@ -0,0 +1,49 @@
package net.Indyuce.mmocore.api.player;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerCombatEvent;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
public class CombatRunnable extends BukkitRunnable {
private final PlayerData player;
private long lastHit = System.currentTimeMillis();
private boolean open = true;
public CombatRunnable(PlayerData player) {
this.player = player;
if (player.isOnline()) {
MMOCore.plugin.configManager.getSimpleMessage("now-in-combat").send(player.getPlayer());
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, true));
runTaskTimer(MMOCore.plugin, 20, 20);
}
}
public void update() {
lastHit = System.currentTimeMillis();
}
@Override
public void run() {
if (!player.isOnline()) {
close();
return;
}
if (lastHit + MMOCore.plugin.configManager.combatLogTimer < System.currentTimeMillis()) {
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, false));
MMOCore.plugin.configManager.getSimpleMessage("leave-combat").send(player.getPlayer());
close();
}
}
private void close() {
Validate.isTrue(open, "Combat runnable has already been closed");
player.combat = null;
cancel();
open = false;
}
}

View File

@ -0,0 +1,32 @@
package net.Indyuce.mmocore.api.player;
import java.util.UUID;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
public abstract class OfflinePlayerData {
private final UUID uuid;
public OfflinePlayerData(UUID uuid) {
this.uuid = uuid;
}
public UUID getUniqueId() {
return uuid;
}
public abstract void removeFriend(UUID uuid);
public abstract boolean hasFriend(UUID uuid);
public abstract PlayerClass getProfess();
public abstract int getLevel();
public abstract long getLastLogin();
public static OfflinePlayerData get(UUID uuid) {
return MMOCore.plugin.dataProvider.getDataManager().getOffline(uuid);
}
}

View File

@ -6,11 +6,11 @@ import javax.inject.Provider;
import java.util.Objects; import java.util.Objects;
/** /**
* Used by MMOCore when it has to store the last time a player * Used by MMOCore when it has to store the last time
* did some action. This also features a time out function which * a player did some action.
* can be used for cooldowns. * <p>
* * This also features a time out function which can
* @deprecated Merge with {@link io.lumine.mythic.lib.player.cooldown.CooldownMap} * be used for cooldowns
*/ */
public enum PlayerActivity { public enum PlayerActivity {
USE_WAYPOINT(() -> 5 * 1000L), USE_WAYPOINT(() -> 5 * 1000L),
@ -21,9 +21,7 @@ public enum PlayerActivity {
LOOT_CHEST_SPAWN(() -> MMOCore.plugin.configManager.lootChestPlayerCooldown), LOOT_CHEST_SPAWN(() -> MMOCore.plugin.configManager.lootChestPlayerCooldown),
CAST_SKILL(() -> MMOCore.plugin.configManager.globalSkillCooldown), CAST_SKILL(() -> MMOCore.plugin.configManager.globalSkillCooldown);
;
private final Provider<Long> timeout; private final Provider<Long> timeout;

View File

@ -1,30 +1,36 @@
package net.Indyuce.mmocore.api.player.attribute; package net.Indyuce.mmocore.api.player.attribute;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.api.stat.api.InstanceModifier; import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
import io.lumine.mythic.lib.util.configobject.ConfigObject; import io.lumine.mythic.lib.util.configobject.ConfigObject;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import java.util.UUID; import java.text.DecimalFormat;
import java.util.Objects;
public class AttributeModifier extends InstanceModifier { public class AttributeModifier extends PlayerModifier {
private final String attribute; private final String attribute;
private final double value;
private final ModifierType type;
private static final DecimalFormat oneDigit = MythicLib.plugin.getMMOConfig().newDecimalFormat("0.#");
/** /**
* Flat attribute modifier (simplest modifier you can think about) * Flat attribute modifier (simplest modifier you can think about)
*/ */
public AttributeModifier(String key, String attribute, double value) { public AttributeModifier(String key, String attribute, double value) {
super(key, value); this(key, attribute, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER);
this.attribute = attribute;
} }
/** /**
* Attribute modifier given by an external mechanic, like a party buff, item * Attribute modifier given by an external mecanic, like a party buff, item set bonuses,
* set bonuses, skills or abilities... Anything apart from items and armor. * skills or abilities... Anything apart from items and armor.
*/ */
public AttributeModifier(String key, String attribute, double value, ModifierType type) { public AttributeModifier(String key, String attribute, double value, ModifierType type) {
this(key, attribute, value, type, EquipmentSlot.OTHER, ModifierSource.OTHER); this(key, attribute, value, type, EquipmentSlot.OTHER, ModifierSource.OTHER);
@ -41,23 +47,11 @@ public class AttributeModifier extends InstanceModifier {
* @param source Type of the item granting the stat modifier * @param source Type of the item granting the stat modifier
*/ */
public AttributeModifier(String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) { public AttributeModifier(String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
this(UUID.randomUUID(), key, attribute, value, type, slot, source); super(key, slot, source);
}
/**
* Attribute modifier given by an item, either a weapon or an armor piece.
*
* @param key Player modifier key
* @param attribute Attribute being modified
* @param value Value of stat modifier
* @param type Is the modifier flat or multiplicative
* @param slot Slot of the item granting the stat modifier
* @param source Type of the item granting the stat modifier
*/
public AttributeModifier(UUID uniqueId, String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
super(uniqueId, key, slot, source, value, type);
this.attribute = attribute; this.attribute = attribute;
this.value = value;
this.type = type;
} }
/** /**
@ -68,14 +62,22 @@ public class AttributeModifier extends InstanceModifier {
* @param str The string to be parsed * @param str The string to be parsed
*/ */
public AttributeModifier(String key, String attribute, String str) { public AttributeModifier(String key, String attribute, String str) {
super(key, EquipmentSlot.OTHER, ModifierSource.OTHER, str); super(key, EquipmentSlot.OTHER, ModifierSource.OTHER);
Validate.notNull(str, "String cannot be null");
Validate.notEmpty(str, "String cannot be empty");
type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
this.attribute = attribute; this.attribute = attribute;
} }
public AttributeModifier(ConfigObject object) { public AttributeModifier(ConfigObject object) {
super(object); super(object.getString("key"), EquipmentSlot.OTHER, ModifierSource.OTHER);
String str = Objects.requireNonNull(object.getString("value"));
type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
this.attribute = object.getString("attribute"); this.attribute = object.getString("attribute");
} }
@ -83,6 +85,14 @@ public class AttributeModifier extends InstanceModifier {
return attribute; return attribute;
} }
public ModifierType getType() {
return type;
}
public double getValue() {
return value;
}
/** /**
* Used to multiply some existing stat modifier by a constant, usually an * Used to multiply some existing stat modifier by a constant, usually an
* integer, for instance when MMOCore party modifiers scale with the * integer, for instance when MMOCore party modifiers scale with the
@ -91,19 +101,24 @@ public class AttributeModifier extends InstanceModifier {
* @param coef The multiplicative constant * @param coef The multiplicative constant
* @return A new instance of StatModifier with modified value * @return A new instance of StatModifier with modified value
*/ */
public AttributeModifier multiply(double coef) { public StatModifier multiply(double coef) {
return new AttributeModifier(getUniqueId(), getKey(), attribute, value * coef, type, getSlot(), getSource()); return new StatModifier(getKey(), attribute, value * coef, type, getSlot(), getSource());
} }
@Override @Override
public void register(MMOPlayerData mmoPlayerData) { public void register(MMOPlayerData mmoPlayerData) {
PlayerData playerData = PlayerData.get(mmoPlayerData); PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
playerData.getAttributes().getInstance(attribute).addModifier(this); playerData.getAttributes().getInstance(attribute).addModifier(this);
} }
@Override @Override
public void unregister(MMOPlayerData mmoPlayerData) { public void unregister(MMOPlayerData mmoPlayerData) {
PlayerData playerData = PlayerData.get(mmoPlayerData); PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
playerData.getAttributes().getInstance(attribute).removeModifier(getKey()); playerData.getAttributes().getInstance(attribute).removeModifier(getKey());
} }
@Override
public String toString() {
return oneDigit.format(value) + (type == io.lumine.mythic.lib.player.modifier.ModifierType.RELATIVE ? "%" : "");
}
} }

View File

@ -1,10 +1,9 @@
package net.Indyuce.mmocore.api.player.attribute; package net.Indyuce.mmocore.api.player.attribute;
import io.lumine.mythic.lib.api.stat.StatInstance; import io.lumine.mythic.lib.api.stat.StatMap;
import io.lumine.mythic.lib.api.stat.handler.StatHandler; import io.lumine.mythic.lib.api.stat.handler.StatHandler;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.configuration.ConfigurationSection;
/** /**
* This fixes an issue where registering new stat modifiers in ML * This fixes an issue where registering new stat modifiers in ML
@ -14,13 +13,17 @@ import org.bukkit.configuration.ConfigurationSection;
* This stat handler MAY call subsequent stat handlers. There might * This stat handler MAY call subsequent stat handlers. There might
* be infinite recursion problems if another attr. grants extra attribute pts. * be infinite recursion problems if another attr. grants extra attribute pts.
*/ */
public class MMOCoreAttributeStatHandler extends StatHandler { public class MMOCoreAttributeStatHandler implements StatHandler {
private final PlayerAttribute attr; private final PlayerAttribute attr;
private final String statName;
public MMOCoreAttributeStatHandler(ConfigurationSection config, PlayerAttribute attr) { public MMOCoreAttributeStatHandler(PlayerAttribute attr) {
super(config, "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_"));
this.attr = attr; this.attr = attr;
this.statName = "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_");
}
public String getStat() {
return statName;
} }
/** /**
@ -28,12 +31,22 @@ public class MMOCoreAttributeStatHandler extends StatHandler {
* is not loaded yet, hence the try/catch clause * is not loaded yet, hence the try/catch clause
*/ */
@Override @Override
public void runUpdate(StatInstance instance) { public void runUpdate(StatMap statMap) {
try { try {
final PlayerData playerData = PlayerData.get(instance.getMap().getPlayerData()); final PlayerData playerData = MMOCore.plugin.dataProvider.getDataManager().get(statMap.getPlayerData().getUniqueId());
playerData.getAttributes().getInstance(attr).updateStats(); playerData.getAttributes().getInstance(attr).updateStats();
} catch (NullPointerException exception) { } catch (NullPointerException exception) {
// Player data is not loaded yet so there's nothing to update. // Player data is not loaded yet so there's nothing to update.
} }
} }
@Override
public double getBaseValue(StatMap statMap) {
return 0;
}
@Override
public double getTotalValue(StatMap statMap) {
return statMap.getStat(statName);
}
} }

View File

@ -85,7 +85,7 @@ public class PlayerAttribute implements ExperienceObject {
@NotNull @NotNull
@Override @Override
public ExperienceTable getExperienceTable() { public ExperienceTable getExperienceTable() {
return Objects.requireNonNull(expTable, "Attribute has no exp table"); return Objects.requireNonNull(expTable);
} }
@Override @Override

View File

@ -1,14 +1,13 @@
package net.Indyuce.mmocore.api.player.attribute; package net.Indyuce.mmocore.api.player.attribute;
import io.lumine.mythic.lib.MythicLib; import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.stat.StatInstance; import io.lumine.mythic.lib.player.modifier.Closeable;
import io.lumine.mythic.lib.gson.JsonElement;
import io.lumine.mythic.lib.gson.JsonObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.util.Closeable;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -33,9 +32,11 @@ public class PlayerAttributes {
public void load(ConfigurationSection config) { public void load(ConfigurationSection config) {
for (String key : config.getKeys(false)) for (String key : config.getKeys(false))
try { try {
final String id = key.toLowerCase().replace("_", "-").replace(" ", "-"); String id = key.toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute called '" + id + "'"); Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
final AttributeInstance ins = new AttributeInstance(id);
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute.getId());
ins.setBase(config.getInt(key)); ins.setBase(config.getInt(key));
instances.put(id, ins); instances.put(id, ins);
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
@ -55,12 +56,15 @@ public class PlayerAttributes {
} }
public void load(String json) { public void load(String json) {
JsonObject jo = MythicLib.plugin.getGson().fromJson(json, JsonObject.class); Gson parser = new Gson();
JsonObject jo = parser.fromJson(json, JsonObject.class);
for (Entry<String, JsonElement> entry : jo.entrySet()) { for (Entry<String, JsonElement> entry : jo.entrySet()) {
try { try {
final String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-"); String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute called '" + id + "'"); Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
final AttributeInstance ins = new AttributeInstance(id);
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute.getId());
ins.setBase(entry.getValue().getAsInt()); ins.setBase(entry.getValue().getAsInt());
instances.put(id, ins); instances.put(id, ins);
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
@ -109,14 +113,13 @@ public class PlayerAttributes {
return n; return n;
} }
// TODO have it extend ModifiedInstance
public class AttributeInstance { public class AttributeInstance {
private int spent; private int spent;
private final String id, enumName; private final String id, enumName;
private final Map<String, AttributeModifier> map = new HashMap<>(); private final Map<String, AttributeModifier> map = new HashMap<>();
public AttributeInstance(@NotNull String id) { public AttributeInstance(String id) {
this.id = id; this.id = id;
this.enumName = UtilityMethods.enumName(this.id); this.enumName = UtilityMethods.enumName(this.id);
} }
@ -125,11 +128,6 @@ public class PlayerAttributes {
return spent; return spent;
} }
@Deprecated
public int getSpent() {
return getBase();
}
public void setBase(int value) { public void setBase(int value) {
spent = Math.max(0, value); spent = Math.max(0, value);
@ -138,7 +136,7 @@ public class PlayerAttributes {
} }
public void addBase(int value) { public void addBase(int value) {
setBase(getBase() + value); setBase(spent + value);
} }
/* /*
@ -178,7 +176,8 @@ public class PlayerAttributes {
public AttributeModifier addModifier(AttributeModifier modifier) { public AttributeModifier addModifier(AttributeModifier modifier) {
final AttributeModifier current = map.put(modifier.getKey(), modifier); final AttributeModifier current = map.put(modifier.getKey(), modifier);
if (current instanceof Closeable) ((Closeable) current).close(); if (current != null && current instanceof Closeable)
((Closeable) current).close();
updateStats(); updateStats();
return current; return current;
@ -211,12 +210,6 @@ public class PlayerAttributes {
public void updateStats() { public void updateStats() {
final PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id); final PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
final int total = getTotal(); final int total = getTotal();
// Remove ALL stat modifiers
for (StatInstance ins : data.getMMOPlayerData().getStatMap().getInstances())
ins.removeIf(str -> str.equals("attribute." + id));
// Register new stat modifiers
attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData())); attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
} }
@ -225,9 +218,10 @@ public class PlayerAttributes {
} }
} }
@Deprecated
public void setBaseAttribute(String id, int value) { public void setBaseAttribute(String id, int value) {
AttributeInstance ins = instances.get(id); getInstances().forEach(ins -> {
if (ins != null) ins.setBase(value); if (ins.getId().equals(id))
ins.setBase(value);
});
} }
} }

View File

@ -1,9 +1,12 @@
package net.Indyuce.mmocore.api.player.profess; package net.Indyuce.mmocore.api.player.profess;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.skill.PassiveSkill; import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.script.Script; import io.lumine.mythic.lib.script.Script;
@ -11,10 +14,7 @@ import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill; import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler; import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.util.FileUtils; import io.lumine.mythic.lib.version.VersionMaterial;
import io.lumine.mythic.lib.util.PostLoadAction;
import io.lumine.mythic.lib.util.PreloadedObject;
import io.lumine.mythic.lib.version.VParticle;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger; import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
@ -25,29 +25,30 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.ExpCurve; import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle; import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.skill.cast.ComboMap; import net.Indyuce.mmocore.skill.cast.ComboMap;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.skilltree.tree.SkillTree; import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
public class PlayerClass implements ExperienceObject, PreloadedObject { public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final String name, id, actionBarFormat; private final String name, id, actionBarFormat;
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>(); private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
private final ItemStack icon; private final ItemStack icon;
@ -66,7 +67,8 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
@Nullable @Nullable
private final CastingParticle castParticle; private final CastingParticle castParticle;
private final List<SkillSlot> skillSlots = new ArrayList<>(); private final int maxBoundActiveSkills, maxBoundPassiveSkills;
private final List<SkillTree> skillTrees = new ArrayList<>(); private final List<SkillTree> skillTrees = new ArrayList<>();
private final List<PassiveSkill> classScripts = new LinkedList(); private final List<PassiveSkill> classScripts = new LinkedList();
private final Map<String, LinearValue> stats = new HashMap<>(); private final Map<String, LinearValue> stats = new HashMap<>();
@ -80,32 +82,26 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
@Deprecated @Deprecated
private final Map<String, EventTrigger> eventTriggers = new HashMap<>(); private final Map<String, EventTrigger> eventTriggers = new HashMap<>();
private final PostLoadAction postLoadAction = new PostLoadAction(config -> { public PlayerClass(String id, FileConfiguration config) {
if (config.contains("subclasses")) super(config);
for (String key : config.getConfigurationSection("subclasses").getKeys(false))
try {
subclasses.add(new Subclass(
MMOCore.plugin.classManager
.getOrThrow(key.toUpperCase().replace("-", "_").replace(" ", "_")),
config.getInt("subclasses." + key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load subclass '" + key + "' from class '"
+ getId() + "': " + exception.getMessage());
}
});
public PlayerClass(String id, ConfigurationSection config) {
postLoadAction.cacheConfig(config);
this.id = id.toUpperCase().replace("-", "_").replace(" ", "_"); this.id = id.toUpperCase().replace("-", "_").replace(" ", "_");
name = MythicLib.plugin.parseColors(config.getString("display.name", "INVALID DISPLAY NAME")); name = MythicLib.plugin.parseColors(config.getString("display.name", "INVALID DISPLAY NAME"));
icon = MMOCoreUtils.readIcon(config.getString("display.item", "BARRIER")); icon = MMOCoreUtils.readIcon(config.getString("display.item", "BARRIER"));
if (config.contains("display.texture") && icon.getType() == Material.PLAYER_HEAD) { if (config.contains("display.texture") && icon.getType() == VersionMaterial.PLAYER_HEAD.toMaterial())
try {
ItemMeta meta = icon.getItemMeta(); ItemMeta meta = icon.getItemMeta();
UtilityMethods.setTextureValue((SkullMeta) meta, config.getString("display.texture")); Field profileField = meta.getClass().getDeclaredField("profile");
profileField.setAccessible(true);
GameProfile gp = new GameProfile(UUID.randomUUID(), null);
gp.getProperties().put("textures", new Property("textures", config.getString("display.texture")));
profileField.set(meta, gp);
icon.setItemMeta(meta); icon.setItemMeta(meta);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
| SecurityException exception) {
throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage());
} }
for (String string : config.getStringList("display.lore")) for (String string : config.getStringList("display.lore"))
@ -118,13 +114,12 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
displayOrder = config.getInt("display.order"); displayOrder = config.getInt("display.order");
actionBarFormat = config.contains("action-bar", true) ? config.getString("action-bar") : null; actionBarFormat = config.contains("action-bar", true) ? config.getString("action-bar") : null;
// Exp curve
expCurve = config.contains("exp-curve") expCurve = config.contains("exp-curve")
? MMOCore.plugin.experience.getCurveOrThrow( ? MMOCore.plugin.experience.getCurveOrThrow(
config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-")) config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
: ExpCurve.DEFAULT; : ExpCurve.DEFAULT;
maxBoundActiveSkills = config.getInt("max-bound-active-skills", MMOCore.plugin.configManager.maxBoundActiveSkills);
// Main exp table maxBoundPassiveSkills = config.getInt("max-bound-passive-skills", MMOCore.plugin.configManager.maxBoundPassiveSkills);
ExperienceTable expTable = null; ExperienceTable expTable = null;
if (config.contains("exp-table")) if (config.contains("exp-table"))
try { try {
@ -133,8 +128,6 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage()); MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage());
} }
this.expTable = expTable; this.expTable = expTable;
// Skill trees
if (config.contains("skill-trees")) if (config.contains("skill-trees"))
for (String str : config.getStringList("skill-trees")) for (String str : config.getStringList("skill-trees"))
try { try {
@ -143,7 +136,6 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
MMOCore.log(Level.WARNING, "Could not find skill tree with ID: " + str); MMOCore.log(Level.WARNING, "Could not find skill tree with ID: " + str);
} }
// Class-specific scripts
if (config.contains("scripts")) if (config.contains("scripts"))
for (String key : config.getConfigurationSection("scripts").getKeys(false)) for (String key : config.getConfigurationSection("scripts").getKeys(false))
try { try {
@ -166,7 +158,6 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
} }
this.comboMap = comboMap; this.comboMap = comboMap;
// Triggers (DEPRECATED)
if (config.contains("triggers")) if (config.contains("triggers"))
for (String key : config.getConfigurationSection("triggers").getKeys(false)) for (String key : config.getConfigurationSection("triggers").getKeys(false))
try { try {
@ -176,7 +167,6 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
MMOCore.log(Level.WARNING, "Could not load trigger '" + key + "' from class '" + id + "':" + exception.getMessage()); MMOCore.log(Level.WARNING, "Could not load trigger '" + key + "' from class '" + id + "':" + exception.getMessage());
} }
// Class STATS, not attributes (historic reasons)
if (config.contains("attributes")) if (config.contains("attributes"))
for (String key : config.getConfigurationSection("attributes").getKeys(false)) for (String key : config.getConfigurationSection("attributes").getKeys(false))
try { try {
@ -187,28 +177,18 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
+ id + "': " + exception.getMessage()); + id + "': " + exception.getMessage());
} }
// Skill slots if (config.contains("skills"))
if (config.isConfigurationSection("skill-slots")) for (String key : config.getConfigurationSection("skills").getKeys(false))
FileUtils.iterateConfigSectionList( try {
config.getConfigurationSection("skill-slots"), RegisteredSkill registered = MMOCore.plugin.skillManager.getSkillOrThrow(UtilityMethods.enumName(key));
skillSlots, skills.put(registered.getHandler().getId(), new ClassSkill(registered, config.getConfigurationSection("skills." + key)));
SkillSlot::new, } catch (RuntimeException exception) {
index -> new SkillSlot(index, 0, "true", "&eUnconfigured Skill Slot " + MMOCoreUtils.intToRoman(index), new ArrayList<>(), false, true, new ArrayList<>()), MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill info '" + key + "' from class '"
(key, exception) -> MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill slot '" + key + "' from class '" + getId() + "': " + exception.getMessage())); + id + "': " + exception.getMessage());
// Class skills
for (RegisteredSkill registered : MMOCore.plugin.skillManager.getAll()) {
final String key = registered.getHandler().getId();
if (config.contains("skills." + key))
skills.put(key, new ClassSkill(registered, config.getConfigurationSection("skills." + key)));
else
skills.put(key, new ClassSkill(registered, 1, 1, false));
} }
// Casting particle
castParticle = config.contains("cast-particle") ? new CastingParticle(config.getConfigurationSection("cast-particle")) : null; castParticle = config.contains("cast-particle") ? new CastingParticle(config.getConfigurationSection("cast-particle")) : null;
// Other class options
if (config.contains("options")) if (config.contains("options"))
for (String key : config.getConfigurationSection("options").getKeys(false)) for (String key : config.getConfigurationSection("options").getKeys(false))
try { try {
@ -219,12 +199,11 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
"Could not load option '" + key + "' from class '" + key + "': " + exception.getMessage()); "Could not load option '" + key + "' from class '" + key + "': " + exception.getMessage());
} }
// Experience sources
if (config.contains("main-exp-sources")) { if (config.contains("main-exp-sources")) {
for (String key : config.getStringList("main-exp-sources")) for (String key : config.getStringList("main-exp-sources"))
try { try {
MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this)); MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this));
} catch (RuntimeException exception) { } catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '" MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '"
+ id + "': " + exception.getMessage()); + id + "': " + exception.getMessage());
} }
@ -258,6 +237,8 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
* option was not provided. * option was not provided.
*/ */
public PlayerClass(String id, String name, Material material) { public PlayerClass(String id, String name, Material material) {
super(null);
this.id = id; this.id = id;
this.name = name; this.name = name;
manaDisplay = ManaDisplayOptions.DEFAULT; manaDisplay = ManaDisplayOptions.DEFAULT;
@ -266,15 +247,32 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
expCurve = ExpCurve.DEFAULT; expCurve = ExpCurve.DEFAULT;
expTable = null; expTable = null;
comboMap = null; comboMap = null;
castParticle = new CastingParticle(VParticle.INSTANT_EFFECT.get()); castParticle = new CastingParticle(Particle.SPELL_INSTANT);
actionBarFormat = ""; actionBarFormat = "";
this.icon = new ItemStack(material); this.icon = new ItemStack(material);
setOption(ClassOption.DISPLAY, false); setOption(ClassOption.DISPLAY, false);
setOption(ClassOption.DEFAULT, false); setOption(ClassOption.DEFAULT, false);
maxBoundActiveSkills = 6;
maxBoundPassiveSkills = 3;
for (PlayerResource resource : PlayerResource.values()) for (PlayerResource resource : PlayerResource.values())
resourceHandlers.put(resource, new ResourceRegeneration(resource)); resourceHandlers.put(resource, new ResourceRegeneration(resource));
} }
@Override
protected void whenPostLoaded(ConfigurationSection config) {
if (config.contains("subclasses"))
for (String key : config.getConfigurationSection("subclasses").getKeys(false))
try {
subclasses.add(new Subclass(
MMOCore.plugin.classManager
.getOrThrow(key.toUpperCase().replace("-", "_").replace(" ", "_")),
config.getInt("subclasses." + key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load subclass '" + key + "' from class '"
+ getId() + "': " + exception.getMessage());
}
}
public String getId() { public String getId() {
return id; return id;
} }
@ -285,7 +283,7 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
@Override @Override
public String getKey() { public String getKey() {
return "class_" + getId(); return "class." + getId();
} }
@NotNull @NotNull
@ -306,17 +304,18 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
return displayOrder; return displayOrder;
} }
@NotNull
@Override
public PostLoadAction getPostLoadAction() {
return postLoadAction;
}
@Override @Override
public ExpCurve getExpCurve() { public ExpCurve getExpCurve() {
return expCurve; return expCurve;
} }
public int getMaxBoundActiveSkills() {
return maxBoundActiveSkills;
}
public int getMaxBoundPassiveSkills() {
return maxBoundPassiveSkills;
}
@NotNull @NotNull
public ExperienceTable getExperienceTable() { public ExperienceTable getExperienceTable() {
@ -355,7 +354,8 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
@Override @Override
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null : hologramLocation; hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
: hologramLocation;
playerData.giveExperience(experience, source, hologramLocation, true); playerData.giveExperience(experience, source, hologramLocation, true);
} }
@ -416,35 +416,18 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
return false; return false;
} }
@Deprecated
public boolean hasSkill(RegisteredSkill skill) { public boolean hasSkill(RegisteredSkill skill) {
return hasSkill(skill.getHandler().getId()); return hasSkill(skill.getHandler().getId());
} }
@Deprecated
public boolean hasSkill(String id) { public boolean hasSkill(String id) {
return skills.containsKey(id); return skills.containsKey(id);
} }
public boolean hasSlot(int slot) {
return 1 <= slot && slot <= skillSlots.size();
}
public List<SkillTree> getSkillTrees() { public List<SkillTree> getSkillTrees() {
return skillTrees; return skillTrees;
} }
@Nullable
public SkillSlot getSkillSlot(int slot) {
return hasSlot(slot) ? skillSlots.get(slot - 1) : null;
}
@NotNull
public List<SkillSlot> getSlots() {
return skillSlots;
}
@NotNull
public ClassSkill getSkill(RegisteredSkill skill) { public ClassSkill getSkill(RegisteredSkill skill) {
return getSkill(skill.getHandler().getId()); return getSkill(skill.getHandler().getId());
} }
@ -454,7 +437,6 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
return skills.get(id); return skills.get(id);
} }
@Deprecated
public Collection<ClassSkill> getSkills() { public Collection<ClassSkill> getSkills() {
return skills.values(); return skills.values();
} }

View File

@ -1,35 +1,29 @@
package net.Indyuce.mmocore.api.player.profess; package net.Indyuce.mmocore.api.player.profess;
import io.lumine.mythic.lib.gson.JsonElement; import com.google.gson.JsonElement;
import io.lumine.mythic.lib.gson.JsonObject; import com.google.gson.JsonObject;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.player.ClassDataContainer; import net.Indyuce.mmocore.player.ClassDataContainer;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode; import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree; import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import java.util.HashMap; import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
public class SavedClassInformation implements ClassDataContainer { public class SavedClassInformation {
private final int level, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints; private final int level, skillPoints, attributePoints, attributeReallocationPoints, skillTreeReallocationPoints, skillReallocationPoints;
private final double experience, health, mana, stellium, stamina; private final double experience;
private final Map<String, Integer> attributeLevels = new HashMap<>(); private final Map<String, Integer> attributeLevels = new HashMap<>();
private final Map<String, Integer> skillLevels = new HashMap<>(); private final Map<String, Integer> skillLevels = new HashMap<>();
private final Map<String, Integer> skillTreePoints = new HashMap<>(); private final Map<String, Integer> skillTreePoints = new HashMap<>();
private final Map<String, Integer> nodeLevels = new HashMap<>(); private final Map<String, Integer> nodeLevels = new HashMap<>();
private final Map<String, Integer> nodeTimesClaimed = new HashMap<>(); private final Map<String, Integer> nodeTimesClaimed = new HashMap<>();
private final Map<Integer, String> boundSkills = new HashMap<>(); private final List<String> boundSkills = new ArrayList<>();
private final Set<String> unlockedItems = new HashSet<>();
/** /**
* Used by YAML storage * Used by YAML storage
@ -42,34 +36,18 @@ public class SavedClassInformation implements ClassDataContainer {
attributeReallocationPoints = config.getInt("attribute-realloc-points"); attributeReallocationPoints = config.getInt("attribute-realloc-points");
skillReallocationPoints = config.getInt("skill-reallocation-points"); skillReallocationPoints = config.getInt("skill-reallocation-points");
skillTreeReallocationPoints = config.getInt("skill-tree-reallocation-points"); skillTreeReallocationPoints = config.getInt("skill-tree-reallocation-points");
health = config.getDouble("health", 20);
mana = config.getDouble("mana", 0);
stamina = config.getDouble("stamina", 0);
stellium = config.getDouble("stellium", 0);
if (config.contains("attribute")) if (config.contains("attribute"))
config.getConfigurationSection("attribute").getKeys(false) config.getConfigurationSection("attribute").getKeys(false).forEach(key -> attributeLevels.put(key, config.getInt("attribute." + key)));
.forEach(key -> attributeLevels.put(key, config.getInt("attribute." + key)));
if (config.contains("skill")) if (config.contains("skill"))
config.getConfigurationSection("skill").getKeys(false) config.getConfigurationSection("skill").getKeys(false).forEach(key -> skillLevels.put(key, config.getInt("skill." + key)));
.forEach(key -> skillLevels.put(key, config.getInt("skill." + key)));
if (config.contains("skill-tree-points")) if (config.contains("skill-tree-points"))
config.getConfigurationSection("skill-tree-points").getKeys(false) config.getConfigurationSection("skill-tree-points").getKeys(false).forEach(key -> skillTreePoints.put(key, config.getInt("skill-tree-points." + key)));
.forEach(key -> skillTreePoints.put(key, config.getInt("skill-tree-points." + key)));
if (config.contains("node-levels")) if (config.contains("node-levels"))
config.getConfigurationSection("node-levels").getKeys(false) config.getConfigurationSection("node-levels").getKeys(false).forEach(key -> nodeLevels.put(key, config.getInt("node-levels." + key)));
.forEach(key -> nodeLevels.put(key, config.getInt("node-levels." + key)));
if (config.contains("node-times-claimed")) if (config.contains("node-times-claimed"))
config.getConfigurationSection("node-times-claimed").getKeys(false) config.getConfigurationSection("node-times-claimed").getKeys(false).forEach(key -> nodeTimesClaimed.put(key, config.getInt("node-times-claimed." + key)));
.forEach(key -> nodeTimesClaimed.put(key, config.getInt("node-times-claimed." + key))); if (config.contains("bound-skills"))
config.getStringList("bound-skills").forEach(id -> boundSkills.add(id));
/**
* 'bound-skills' used to be a list. This condition makes
* sure that the config is using the newest format.
*/
if (config.isConfigurationSection("bound-skills"))
config.getConfigurationSection("bound-skills").getKeys(false)
.forEach(key -> boundSkills.put(Integer.parseInt(key), config.getString("bound-skills." + key)));
unlockedItems.addAll(config.getStringList("unlocked-items"));
} }
/** /**
@ -83,11 +61,6 @@ public class SavedClassInformation implements ClassDataContainer {
attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt(); attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt();
skillReallocationPoints = json.get("skill-reallocation-points").getAsInt(); skillReallocationPoints = json.get("skill-reallocation-points").getAsInt();
skillTreeReallocationPoints = json.get("skill-tree-reallocation-points").getAsInt(); skillTreeReallocationPoints = json.get("skill-tree-reallocation-points").getAsInt();
health = json.has("health") ? json.get("health").getAsDouble() : 20;
mana = json.has("mana") ? json.get("mana").getAsDouble() : 0;
stamina = json.has("stamina") ? json.get("stamina").getAsDouble() : 0;
stellium = json.has("stellium") ? json.get("stellium").getAsDouble() : 0;
if (json.has("attribute")) if (json.has("attribute"))
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet()) for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
attributeLevels.put(entry.getKey(), entry.getValue().getAsInt()); attributeLevels.put(entry.getKey(), entry.getValue().getAsInt());
@ -103,13 +76,8 @@ public class SavedClassInformation implements ClassDataContainer {
if (json.has("node-times-claimed")) if (json.has("node-times-claimed"))
for (Entry<String, JsonElement> entry : json.getAsJsonObject("node-times-claimed").entrySet()) for (Entry<String, JsonElement> entry : json.getAsJsonObject("node-times-claimed").entrySet())
nodeTimesClaimed.put(entry.getKey(), entry.getValue().getAsInt()); nodeTimesClaimed.put(entry.getKey(), entry.getValue().getAsInt());
//Old system was using a JsonArray. If it saved with the old system the if condition won't be respected. if (json.has("bound-skills"))
if (json.has("bound-skills") && json.get("bound-skills").isJsonObject()) json.getAsJsonArray("bound-skills").forEach(id -> boundSkills.add(id.getAsString()));
for (Entry<String, JsonElement> entry : json.getAsJsonObject("bound-skills").entrySet())
boundSkills.put(Integer.parseInt(entry.getKey()), entry.getValue().getAsString());
if (json.has("unlocked-items"))
for (JsonElement unlockedItem : json.get("unlocked-items").getAsJsonArray())
unlockedItems.add(unlockedItem.getAsString());
} }
public SavedClassInformation(ClassDataContainer data) { public SavedClassInformation(ClassDataContainer data) {
@ -120,65 +88,37 @@ public class SavedClassInformation implements ClassDataContainer {
this.skillTreeReallocationPoints = data.getSkillTreeReallocationPoints(); this.skillTreeReallocationPoints = data.getSkillTreeReallocationPoints();
this.skillReallocationPoints = data.getSkillReallocationPoints(); this.skillReallocationPoints = data.getSkillReallocationPoints();
this.experience = data.getExperience(); this.experience = data.getExperience();
this.health = data.getHealth();
this.mana = data.getMana();
this.stellium = data.getStellium();
this.stamina = data.getStamina();
attributeLevels.putAll(data.mapAttributeLevels()); data.mapAttributeLevels().forEach((key, val) -> this.attributeLevels.put(key, val));
skillLevels.putAll(data.mapSkillLevels()); data.mapSkillLevels().forEach((key, val) -> skillLevels.put(key, val));
skillTreePoints.putAll(data.mapSkillTreePoints()); data.mapSkillTreePoints().forEach((key, val) -> skillTreePoints.put(key, val));
nodeLevels.putAll(data.getNodeLevels()); data.getNodeLevels().forEach((node, level) -> nodeLevels.put(node.getFullId(), level));
nodeTimesClaimed.putAll(data.getNodeTimesClaimed()); data.getNodeTimesClaimed().forEach((key, val) -> nodeTimesClaimed.put(key, val));
boundSkills.putAll(data.mapBoundSkills());
unlockedItems.addAll(data.getUnlockedItems()); data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getTriggeredSkill().getHandler().getId()));
data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
} }
@Override
public int getLevel() { public int getLevel() {
return level; return level;
} }
@Override
public double getExperience() { public double getExperience() {
return experience; return experience;
} }
@Override
public int getSkillPoints() { public int getSkillPoints() {
return skillPoints; return skillPoints;
} }
@Override
public int getAttributePoints() { public int getAttributePoints() {
return attributePoints; return attributePoints;
} }
@Override
public int getAttributeReallocationPoints() { public int getAttributeReallocationPoints() {
return attributeReallocationPoints; return attributeReallocationPoints;
} }
@Override
public double getHealth() {
return health;
}
@Override
public double getMana() {
return mana;
}
@Override
public double getStellium() {
return stellium;
}
@Override
public double getStamina() {
return stamina;
}
public Set<String> getSkillKeys() { public Set<String> getSkillKeys() {
return skillLevels.keySet(); return skillLevels.keySet();
} }
@ -195,27 +135,10 @@ public class SavedClassInformation implements ClassDataContainer {
registerSkillLevel(skill.getHandler().getId(), level); registerSkillLevel(skill.getHandler().getId(), level);
} }
@Override
public Map<String, Integer> mapSkillLevels() {
return skillLevels;
}
@Override
public Map<String, Integer> mapSkillTreePoints() {
return skillTreePoints;
}
@Deprecated
public Map<Integer, String> getBoundSkills() {
return mapBoundSkills();
}
@Override
public int getSkillTreeReallocationPoints() { public int getSkillTreeReallocationPoints() {
return skillTreeReallocationPoints; return skillTreeReallocationPoints;
} }
@Override
public int getSkillReallocationPoints() { public int getSkillReallocationPoints() {
return skillReallocationPoints; return skillReallocationPoints;
} }
@ -232,26 +155,6 @@ public class SavedClassInformation implements ClassDataContainer {
return nodeLevels.get(node); return nodeLevels.get(node);
} }
@Override
public Map<String, Integer> mapAttributeLevels() {
return attributeLevels;
}
@Override
public Map<Integer, String> mapBoundSkills() {
return boundSkills;
}
@Override
public Map<String, Integer> getNodeLevels() {
return nodeLevels;
}
@Override
public Map<String, Integer> getNodeTimesClaimed() {
return nodeTimesClaimed;
}
public Set<String> getSkillTreePointsKeys() { public Set<String> getSkillTreePointsKeys() {
return skillTreePoints.keySet(); return skillTreePoints.keySet();
} }
@ -276,11 +179,6 @@ public class SavedClassInformation implements ClassDataContainer {
attributeLevels.put(attribute, level); attributeLevels.put(attribute, level);
} }
@Override
public Set<String> getUnlockedItems() {
return unlockedItems;
}
/** /**
* @param profess Target player class * @param profess Target player class
* @param player Player changing class * @param player Player changing class
@ -294,22 +192,32 @@ public class SavedClassInformation implements ClassDataContainer {
if (!player.getProfess().hasOption(ClassOption.DEFAULT) || MMOCore.plugin.configManager.saveDefaultClassInfo) if (!player.getProfess().hasOption(ClassOption.DEFAULT) || MMOCore.plugin.configManager.saveDefaultClassInfo)
player.applyClassInfo(player.getProfess(), new SavedClassInformation(player)); player.applyClassInfo(player.getProfess(), new SavedClassInformation(player));
// Remove class permanent buffs
player.getProfess().resetAdvancement(player, false);
/* /*
* Resets information which much be reset after everything is saved. * Resets information which much be reset after everything is saved.
*/ */
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill)); player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) { player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
attribute.resetAdvancement(player, false); player.clearSkillTreePoints();
player.getAttributes().getInstance(attribute).setBase(0); player.clearNodeLevels();
} player.clearNodeStates();
player.resetSkillTrees();
// We remove perm stats for nodes and class.
for (SkillTree skillTree : player.getProfess().getSkillTrees())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().removePermStats(player, node);
if (player.getProfess().hasExperienceTable())
player.getProfess().getExperienceTable().removePermStats(player, player.getProfess());
while (player.hasPassiveSkillBound(0))
player.unbindPassiveSkill(0);
while (player.hasSkillBound(0))
player.unbindSkill(0);
/* /*
* Reads this class info, applies it to the player. set class after * Reads this class info, applies it to the player. set class after
* changing level so the player stats can be calculated based on new level * changing level so the player stats can be calculated based on new
* level.
*/ */
player.setLevel(level); player.setLevel(level);
player.setExperience(experience); player.setExperience(experience);
@ -318,13 +226,16 @@ public class SavedClassInformation implements ClassDataContainer {
player.setAttributeReallocationPoints(attributeReallocationPoints); player.setAttributeReallocationPoints(attributeReallocationPoints);
player.setSkillTreeReallocationPoints(skillTreeReallocationPoints); player.setSkillTreeReallocationPoints(skillTreeReallocationPoints);
player.setSkillReallocationPoints(skillReallocationPoints); player.setSkillReallocationPoints(skillReallocationPoints);
player.setUnlockedItems(unlockedItems); for (String id : boundSkills) {
player.setClass(profess); ClassSkill skill = profess.getSkill(id);
for (int slot : boundSkills.keySet()) if (skill.getSkill().getTrigger().isPassive())
player.bindSkill(slot, profess.getSkill(boundSkills.get(slot))); player.bindPassiveSkill(-1, skill.toPassive(player));
else
player.getBoundSkills().add(skill);
}
skillLevels.forEach(player::setSkillLevel); skillLevels.forEach(player::setSkillLevel);
attributeLevels.forEach((id, pts) -> player.getAttributes().getInstance(id).setBase(pts)); attributeLevels.forEach((id, pts) -> player.getAttributes().setBaseAttribute(id, pts));
// Careful, the global points must not be forgotten. // Careful, the global points must not be forgotten.
player.setSkillTreePoints("global", skillTreePoints.getOrDefault("global", 0)); player.setSkillTreePoints("global", skillTreePoints.getOrDefault("global", 0));
@ -339,17 +250,21 @@ public class SavedClassInformation implements ClassDataContainer {
// Add the values to the times claimed table and claims the corresponding stat triggers. // Add the values to the times claimed table and claims the corresponding stat triggers.
nodeTimesClaimed.forEach((str, val) -> player.setClaims(str, val)); nodeTimesClaimed.forEach((str, val) -> player.setClaims(str, val));
// Unload current class information // We claim back the stats triggers for all the skill tree nodes of the new class.
for (SkillTree skillTree : profess.getSkillTrees())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().claimStatTriggers(player, node);
profess.getExperienceTable().claimStatTriggers(player, profess);
/*
* Unload current class information and set
* the new profess once everything is changed
*/
player.setClass(profess);
player.unloadClassInfo(profess); player.unloadClassInfo(profess);
// This needs to be done at the end to make sure the MAX_HEALTH/MAX_MANA/... stats are loaded. // Updates level on exp bar
player.getPlayer().setHealth(MMOCoreUtils.fixResource(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())); player.refreshVanillaExp();
player.setHealth(health);
player.setMana(mana);
player.setStellium(stellium);
player.setStamina(stamina);
player.applyTemporaryTriggers();
player.getStats().updateStats();
} }
} }

View File

@ -21,7 +21,7 @@ public class AttackEventTrigger implements EventTriggerHandler {
// We don't want players dying by themselves when using an enderpearl. // We don't want players dying by themselves when using an enderpearl.
if (event.getPlayer().equals(event.getEntity())) return; if (event.getPlayer().equals(event.getEntity())) return;
PlayerData player = PlayerData.get(event.getData()); PlayerData player = PlayerData.get(event.getData().getUniqueId());
PlayerClass profess = player.getProfess(); PlayerClass profess = player.getProfess();
for (DamageType type : event.getAttack().getDamage().collectTypes()) { for (DamageType type : event.getAttack().getDamage().collectTypes()) {

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger; package net.Indyuce.mmocore.api.player.profess.event.trigger;
import io.lumine.mythic.lib.UtilityMethods;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
@ -18,8 +17,6 @@ public class BlockBrokenTrigger implements EventTriggerHandler {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(BlockBreakEvent event) { public void a(BlockBreakEvent event) {
if (UtilityMethods.isFake(event)) return;
PlayerData player = PlayerData.get(event.getPlayer()); PlayerData player = PlayerData.get(event.getPlayer());
if (player.getProfess().hasEventTriggers("break-block")) if (player.getProfess().hasEventTriggers("break-block"))
player.getProfess().getEventTriggers("break-block").getTriggers().forEach(trigger -> trigger.apply(player)); player.getProfess().getEventTriggers("break-block").getTriggers().forEach(trigger -> trigger.apply(player));

View File

@ -1,6 +1,6 @@
package net.Indyuce.mmocore.api.player.social; package net.Indyuce.mmocore.api.player.social;
import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -21,8 +21,8 @@ public class FriendRequest extends Request {
getCreator().addFriend(getTarget().getUniqueId()); getCreator().addFriend(getTarget().getUniqueId());
getTarget().addFriend(getCreator().getUniqueId()); getTarget().addFriend(getCreator().getUniqueId());
if (getCreator().isOnline()) { if (getCreator().isOnline()) {
ConfigMessage.fromKey("now-friends", "player", getTarget().getPlayer().getName()).send(getCreator().getPlayer()); MMOCore.plugin.configManager.getSimpleMessage("now-friends", "player", getTarget().getPlayer().getName()).send(getCreator().getPlayer());
ConfigMessage.fromKey("now-friends", "player", getCreator().getPlayer().getName()).send(getTarget().getPlayer()); MMOCore.plugin.configManager.getSimpleMessage("now-friends", "player", getCreator().getPlayer().getName()).send(getTarget().getPlayer());
} }
} }
} }

View File

@ -8,7 +8,6 @@ import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.player.skill.PassiveSkill; import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.player.skill.PassiveSkillMap; import io.lumine.mythic.lib.player.skill.PassiveSkillMap;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
@ -46,7 +45,7 @@ public class PlayerStats {
} }
public double getStat(String stat) { public double getStat(String stat) {
return getMap().getStat(stat); return getMap().getInstance(stat).getTotal();
} }
/** /**
@ -67,24 +66,14 @@ public class PlayerStats {
return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession)); return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession));
} }
public void updateStats() {
updateStats(false);
}
/** /**
* Used to update MMOCore stat modifiers due to class and send them over to * Used to update MMOCore stat modifiers due to class and send them over to
* MythicLib. Must be ran everytime the player levels up, changes class or * MythicLib. Must be ran everytime the player levels up or changes class.
* when the plugin reloads.
* <p> * <p>
* Login scripts are a pretty special case of scripts/skills since they are * This is also called when reloading the plugin to make class setup easier,
* not loaded yet when MythicLib triggers them naturally. Therefore, they * see {@link PlayerData#update()} for more info
* need to be cast as soon as they are loaded into the MMOCore player data.
*
* @param castLoginScripts Should login scripts be cast
*/ */
public synchronized void updateStats(boolean castLoginScripts) { public synchronized void updateStats() {
// Update player stats
for (String stat : MMOCore.plugin.statManager.getRegistered()) { for (String stat : MMOCore.plugin.statManager.getRegistered()) {
final StatInstance instance = getMap().getInstance(stat); final StatInstance instance = getMap().getInstance(stat);
final StatInstance.ModifierPacket packet = instance.newPacket(); final StatInstance.ModifierPacket packet = instance.newPacket();
@ -101,32 +90,25 @@ public class PlayerStats {
packet.runUpdate(); packet.runUpdate();
} }
// Updates the player's unbindable CLASS passive skills /*
* This is here because it requires updates for the same reasons
* as statistics (when the player level changes, when his class
* changes, when he logs on..)
*
* This updates the player's PASSIVE skills
*/
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap(); final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
skillMap.removeModifiers("MMOCorePermanentSkill");
for (ClassSkill skill : data.getProfess().getSkills())
if (skill.isPermanent()
&& skill.getSkill().getTrigger() != TriggerType.LOGIN
&& data.hasUnlocked(skill)
&& data.hasUnlockedLevel(skill))
skillMap.addModifier(skill.toPassive(data));
// Updates the player's CLASS scripts if (!MMOCore.plugin.configManager.passiveSkillNeedBound) {
skillMap.removeModifiers("MMOCorePassiveSkill");
for (ClassSkill skill : data.getProfess().getSkills())
if (skill.getSkill().getTrigger().isPassive())
skillMap.addModifier(skill.toPassive(data));
}
// This updates the player's class SCRIPTS
skillMap.removeModifiers("MMOCoreClassScript"); skillMap.removeModifiers("MMOCoreClassScript");
for (PassiveSkill script : data.getProfess().getScripts()) for (PassiveSkill script : data.getProfess().getScripts())
if (script.getType() != TriggerType.LOGIN) skillMap.addModifier(script); skillMap.addModifier(script);
// If data hasn't been synchronized yet, cast LOGIN scripts
if (castLoginScripts) {
// Call class login skills
for (ClassSkill skill : data.getProfess().getSkills())
if (skill.getSkill().getTrigger() == TriggerType.LOGIN)
skill.toCastable(data).cast(data.getMMOPlayerData());
// Call class login scripts
for (PassiveSkill skill : data.getProfess().getScripts())
if (skill.getType() == TriggerType.LOGIN) skill.getTriggeredSkill().cast(data.getMMOPlayerData());
}
} }
} }

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmocore.api.quest; package net.Indyuce.mmocore.api.quest;
import io.lumine.mythic.lib.util.Closeable;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.objective.Objective; import net.Indyuce.mmocore.api.util.Closable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
public abstract class ObjectiveProgress implements Closeable { import net.Indyuce.mmocore.api.quest.objective.Objective;
public abstract class ObjectiveProgress implements Closable {
private final Objective objective; private final Objective objective;
private final QuestProgress questProgress; private final QuestProgress questProgress;

View File

@ -1,11 +1,11 @@
package net.Indyuce.mmocore.api.quest; package net.Indyuce.mmocore.api.quest;
import io.lumine.mythic.lib.MythicLib; import com.google.gson.Gson;
import io.lumine.mythic.lib.gson.JsonElement; import com.google.gson.JsonElement;
import io.lumine.mythic.lib.gson.JsonObject; import com.google.gson.JsonObject;
import io.lumine.mythic.lib.util.Closeable;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.Closable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.boss.BarColor; import org.bukkit.boss.BarColor;
@ -21,7 +21,7 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
public class PlayerQuests implements Closeable { public class PlayerQuests implements Closable {
private final PlayerData playerData; private final PlayerData playerData;
private final Map<String, Long> finished = new HashMap<>(); private final Map<String, Long> finished = new HashMap<>();
@ -38,7 +38,6 @@ public class PlayerQuests implements Closeable {
bossbarNamespacedKey = new NamespacedKey(MMOCore.plugin, "mmocore_quest_progress_" + playerData.getUniqueId().toString()); bossbarNamespacedKey = new NamespacedKey(MMOCore.plugin, "mmocore_quest_progress_" + playerData.getUniqueId().toString());
bossbar = Bukkit.createBossBar(bossbarNamespacedKey, "", BarColor.PURPLE, BarStyle.SEGMENTED_20); bossbar = Bukkit.createBossBar(bossbarNamespacedKey, "", BarColor.PURPLE, BarStyle.SEGMENTED_20);
bossbar.addPlayer(playerData.getPlayer()); bossbar.addPlayer(playerData.getPlayer());
bossbar.setVisible(false); // Safety
// Bossbar is disabled // Bossbar is disabled
} else { } else {
@ -99,7 +98,8 @@ public class PlayerQuests implements Closeable {
} }
public void load(String json) { public void load(String json) {
JsonObject jo = MythicLib.plugin.getGson().fromJson(json, JsonObject.class); Gson parser = new Gson();
JsonObject jo = parser.fromJson(json, JsonObject.class);
if (jo.has("current")) { if (jo.has("current")) {
JsonObject cur = jo.getAsJsonObject("current"); JsonObject cur = jo.getAsJsonObject("current");
try { try {
@ -173,9 +173,6 @@ public class PlayerQuests implements Closeable {
bossbar.removeAll(); bossbar.removeAll();
Bukkit.removeBossBar(bossbarNamespacedKey); Bukkit.removeBossBar(bossbarNamespacedKey);
} }
// Close current objective progress
closeCurrentQuest();
} }
public boolean checkCooldownAvailability(Quest quest) { public boolean checkCooldownAvailability(Quest quest) {

View File

@ -1,8 +1,12 @@
package net.Indyuce.mmocore.api.quest; package net.Indyuce.mmocore.api.quest;
import io.lumine.mythic.lib.api.MMOLineConfig; import java.util.ArrayList;
import io.lumine.mythic.lib.util.PostLoadAction; import java.util.HashMap;
import io.lumine.mythic.lib.util.PreloadedObject; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.objective.Objective; import net.Indyuce.mmocore.api.quest.objective.Objective;
@ -10,32 +14,26 @@ import net.Indyuce.mmocore.experience.Profession;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import java.util.*; import io.lumine.mythic.lib.api.MMOLineConfig;
import java.util.logging.Level; import io.lumine.mythic.lib.api.util.PostLoadObject;
public class Quest implements PreloadedObject { public class Quest extends PostLoadObject {
private final String id, name; private final String id;
private final String name;
private final List<Quest> parents = new ArrayList<>(); private final List<Quest> parents = new ArrayList<>();
private final List<Objective> objectives = new ArrayList<>(); private final List<Objective> objectives = new ArrayList<>();
private final List<String> lore; private final List<String> lore;
private final int mainLevelRestriction; private final int mainLevelRestriction;
private final Map<Profession, Integer> levelRestrictions = new HashMap<>(); private final Map<Profession, Integer> levelRestrictions = new HashMap<>();
// Cooldown in millis // cooldown in millis
private final long cooldown; private final long cooldown;
private final PostLoadAction postLoadAction = new PostLoadAction(config -> { public Quest(String id, FileConfiguration config) {
super(config);
// Load parent quests
if (config.contains("parent"))
for (String parent : config.getStringList("parent"))
parents.add(MMOCore.plugin.questManager.getOrThrow(parent.toLowerCase().replace(" ", "-").replace("_", "-")));
});
public Quest(String id, ConfigurationSection config) {
postLoadAction.cacheConfig(config);
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-"); this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");
cooldown = (long) (config.contains("delay") ? config.getDouble("delay") * 60 * 60 * 1000 : -1); cooldown = (long) (config.contains("delay") ? config.getDouble("delay") * 60 * 60 * 1000 : -1);
@ -71,10 +69,11 @@ public class Quest implements PreloadedObject {
} }
} }
@NotNull
@Override @Override
public PostLoadAction getPostLoadAction() { protected void whenPostLoaded(ConfigurationSection config) {
return postLoadAction; if (config.contains("parent"))
for (String parent : config.getStringList("parent"))
parents.add(MMOCore.plugin.questManager.getOrThrow(parent.toLowerCase().replace(" ", "-").replace("_", "-")));
} }
public String getId() { public String getId() {

View File

@ -46,19 +46,17 @@ public class QuestProgress {
public void completeObjective() { public void completeObjective() {
objective++; objective++;
objectiveProgress.close(); objectiveProgress.close();
final ObjectiveProgress finishedObjectiveProgress = objectiveProgress;
// Start next objective, or end quest. // apply triggers
if (objective >= quest.getObjectives().size()) player.getQuestData().finishCurrent(); objectiveProgress.getObjective().getTriggers().forEach(trigger -> trigger.schedule(getPlayer()));
else objectiveProgress = nextObjective().newProgress(this);
// end quest
if (objective >= quest.getObjectives().size())
player.getQuestData().finishCurrent();
else
objectiveProgress = nextObjective().newProgress(this);
player.getQuestData().updateBossBar(); player.getQuestData().updateBossBar();
/*
* Apply triggers only at the end! It comes handy when starting another
* quest in some storyline using triggers from the previous quest.
*/
finishedObjectiveProgress.getObjective().getTriggers().forEach(trigger -> trigger.schedule(getPlayer()));
} }
public String getFormattedLore() { public String getFormattedLore() {

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.api.quest.objective; package net.Indyuce.mmocore.api.quest.objective;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.api.quest.ObjectiveProgress; import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent; import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
import net.Indyuce.mmocore.api.quest.QuestProgress; import net.Indyuce.mmocore.api.quest.QuestProgress;
@ -43,8 +42,6 @@ public class MineBlockObjective extends Objective {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void a(BlockBreakEvent event) { public void a(BlockBreakEvent event) {
if(!getQuestProgress().getPlayer().isOnline()) return; if(!getQuestProgress().getPlayer().isOnline()) return;
if (UtilityMethods.isFake(event)) return;
if ((!playerPlaced) && event.getBlock().hasMetadata("player_placed")) if ((!playerPlaced) && event.getBlock().hasMetadata("player_placed"))
return; return;
if (event.getPlayer().equals(getQuestProgress().getPlayer().getPlayer()) && event.getBlock().getType() == block) { if (event.getPlayer().equals(getQuestProgress().getPlayer().getPlayer()) && event.getBlock().getType() == block) {

View File

@ -1,34 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import javax.annotation.Nullable;
public class BindSkillTrigger extends Trigger implements Removable {
private final RegisteredSkill skill;
private final int slot;
public BindSkillTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("skill", "slot");
slot = config.getInt("slot");
skill = MMOCore.plugin.skillManager.getSkillOrThrow(config.getString("skill"));
}
@Override
public void apply(PlayerData playerData) {
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null) playerData.bindSkill(slot, found);
}
@Override
public void remove(PlayerData playerData) {
playerData.unbindSkill(slot);
}
}

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.api.quest.trigger; package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -24,9 +23,7 @@ public class CommandTrigger extends Trigger {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), format(player.getPlayer())); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), format(player.getPlayer()));
} }
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
private String format(Player player) { private String format(Player player) {
// TODO remove use of confusing non-PAPI %player% placeholder
return MMOCore.plugin.placeholderParser.parse(player, command.replace("%player%", player.getName())); return MMOCore.plugin.placeholderParser.parse(player, command.replace("%player%", player.getName()));
} }
} }

View File

@ -36,6 +36,6 @@ public class ExperienceTrigger extends Trigger {
@Override @Override
public void apply(PlayerData player) { public void apply(PlayerData player) {
dispenser.giveExperience(player, amount.calculate(), null, source); dispenser.giveExperience(player, amount.calculateInt(), null, source);
} }
} }

View File

@ -1,30 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.skill.RegisteredSkill;
public class LevelUpSkillTrigger extends Trigger implements Removable {
private final RegisteredSkill skill;
private final int amount;
public LevelUpSkillTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("skill", "amount");
amount = config.getInt("amount");
skill = MMOCore.plugin.skillManager.getSkillOrThrow(config.getString("skill"));
}
@Override
public void apply(PlayerData playerData) {
playerData.setSkillLevel(skill, playerData.getSkillLevel(skill) + amount);
}
@Override
public void remove(PlayerData playerData) {
playerData.setSkillLevel(skill, Math.max(0, playerData.getSkillLevel(skill) - amount));
}
}

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.api.quest.trigger; package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -23,9 +22,7 @@ public class MessageTrigger extends Trigger {
player.getPlayer().sendMessage(format(player.getPlayer())); player.getPlayer().sendMessage(format(player.getPlayer()));
} }
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
private String format(Player player) { private String format(Player player) {
// TODO remove use of confusing non-PAPI %player% placeholder
return MMOCore.plugin.placeholderParser.parse(player, message.replace("%player%", player.getName())); return MMOCore.plugin.placeholderParser.parse(player, message.replace("%player%", player.getName()));
} }
} }

View File

@ -1,73 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.player.skillmod.SkillModifier;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.api.quest.trigger.api.Temporary;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public class SkillModifierTrigger extends Trigger implements Removable, Temporary {
private SkillModifier mod;
private boolean mutable = true;
public SkillModifierTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("modifier");
config.validateKeys("amount");
final double amount = config.getDouble("amount");
final String parameter = config.getString("modifier");
final String formula = config.getString("formula", "true");
final ModifierType type = config.contains("type") ? ModifierType.valueOf(UtilityMethods.enumName(config.getString("type"))) : ModifierType.FLAT;
final List<SkillHandler<?>> targetSkills = MMOCore.plugin.skillManager.getAll().stream().filter(skill -> skill.matchesFormula(formula)).map(RegisteredSkill::getHandler).collect(Collectors.toList());
mod = new SkillModifier(Trigger.STAT_MODIFIER_KEY, parameter, targetSkills, amount, type);
}
public void updateKey(@NotNull String key) {
Validate.isTrue(mutable, "No longer mutable");
this.mod = new SkillModifier(key, mod.getParameter(), mod.getSkills(), mod.getValue(), mod.getType());
}
public List<SkillHandler<?>> getTargetSkills() {
return mod.getSkills();
}
@Override
public void apply(PlayerData player) {
mod.register(player.getMMOPlayerData());
}
@Override
public void remove(PlayerData playerData) {
mod.unregister(playerData.getMMOPlayerData());
}
/**
* Used by skill slots to apply a skill modifier.
* to a dynamically chosen skill handler.
*/
public void apply(PlayerData playerData, SkillHandler<?> skill) {
mutable = false;
mod.register(playerData.getMMOPlayerData(), skill);
}
/**
* Used by skill slots to remove a skillBuff
* from a dynamically chosen skill handler.
*/
public void remove(PlayerData playerData, SkillHandler<?> skill) {
mod.unregister(playerData.getMMOPlayerData(), skill);
}
}

View File

@ -4,14 +4,16 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.api.quest.trigger.api.Temporary;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
public class StatTrigger extends Trigger implements Removable, Temporary { import java.util.UUID;
private final StatModifier modifier;
public class StatTrigger extends Trigger {
private final String stat; private final String stat;
private final double amount; private final double amount;
private final ModifierType type;
private double totalAmount;
private final UUID uuid =UUID.randomUUID();
public StatTrigger(MMOLineConfig config) { public StatTrigger(MMOLineConfig config) {
super(config); super(config);
@ -23,18 +25,23 @@ public class StatTrigger extends Trigger implements Removable, Temporary {
Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE")); Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE"));
stat = config.getString("stat"); stat = config.getString("stat");
amount = config.getDouble("amount"); amount = config.getDouble("amount");
modifier = new StatModifier(Trigger.STAT_MODIFIER_KEY, stat, amount, ModifierType.valueOf(type)); this.type = ModifierType.valueOf(type);
this.totalAmount = 0;
} }
@Override @Override
public void apply(PlayerData player) { public void apply(PlayerData player) {
StatModifier prevModifier = player.getMMOPlayerData().getStatMap().getInstance(stat).getModifier(modifier.getUniqueId()); totalAmount+=amount;
if (prevModifier == null) modifier.register(player.getMMOPlayerData()); new StatModifier("trigger."+uuid.toString(),stat,totalAmount,type).register(player.getMMOPlayerData());
else prevModifier.add(amount).register(player.getMMOPlayerData());
} }
@Override /**
* Removes the effect of the trigger to the player by registering the
* opposite amount. (Little corrective term for the relative to have the inverse.
* Not a problem to store twice the stat modifiers are there only remain in the RAM.
*/
public void remove(PlayerData playerData) { public void remove(PlayerData playerData) {
modifier.unregister(playerData.getMMOPlayerData()); totalAmount-=amount;
new StatModifier("trigger."+uuid.toString(), stat, totalAmount, type).register(playerData.getMMOPlayerData());
} }
} }

View File

@ -6,8 +6,6 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public abstract class Trigger { public abstract class Trigger {
public static String STAT_MODIFIER_KEY = "mmocore_trigger";
private final long delay; private final long delay;
public Trigger(MMOLineConfig config) { public Trigger(MMOLineConfig config) {

View File

@ -1,33 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import javax.annotation.Nullable;
public class UnlockSkillTrigger extends Trigger implements Removable {
private final RegisteredSkill skill;
public UnlockSkillTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("skill");
skill = MMOCore.plugin.skillManager.getSkillOrThrow(config.getString("skill"));
}
@Override
public void apply(PlayerData playerData) {
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null) playerData.unlock(found);
}
@Override
public void remove(PlayerData playerData) {
final @Nullable ClassSkill found = playerData.getProfess().getSkill(skill);
if (found != null) playerData.lock(found);
}
}

View File

@ -1,35 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
import org.apache.commons.lang.Validate;
public class UnlockSlotTrigger extends Trigger implements Removable {
private final int slot;
public UnlockSlotTrigger(MMOLineConfig config) {
super(config);
config.validateKeys("slot");
try {
slot = Integer.parseInt(config.getString("slot"));
} catch (NumberFormatException exception) {
throw new IllegalArgumentException("Slot should be a number");
}
Validate.isTrue(slot > 0, "Slot number must be positive");
}
@Override
public void apply(PlayerData player) {
player.unlock(player.getProfess().getSkillSlot(slot));
}
@Override
public void remove(PlayerData player) {
player.lock(player.getProfess().getSkillSlot(slot));
}
}

View File

@ -1,13 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger.api;
import net.Indyuce.mmocore.api.player.PlayerData;
/**
* Cancelable triggers cause problems when letting the player reset
* their advancement on things they can spend points in/level up.
* If you give access to some resource to the player via a trigger,
* you must take it away when resetting their progression.
*/
public interface Removable {
public void remove(PlayerData playerData);
}

View File

@ -1,12 +0,0 @@
package net.Indyuce.mmocore.api.quest.trigger.api;
/**
* Non-permanent triggers are triggers which are not saved
* by the player and taken off when the player logs off,
* for instance temporary player modifiers. They need to
* be re-applied everytime the player logs back.
*
* @author jules
*/
public interface Temporary extends Removable {
}

View File

@ -0,0 +1,15 @@
package net.Indyuce.mmocore.api.util;
/**
* Indicates that a class temporarily registers something
* such as a Bukkit event, which needs to be unregistered
* when the class is finally garbage collected.
*/
public interface Closable {
/**
* Method that must be called before the class
* is garbage collected
*/
void close();
}

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmocore.api.util; package net.Indyuce.mmocore.api.util;
import com.google.common.collect.MultimapBuilder; import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.gson.JsonArray;
import io.lumine.mythic.lib.gson.JsonObject;
import io.lumine.mythic.lib.hologram.Hologram; import io.lumine.mythic.lib.hologram.Hologram;
import io.lumine.mythic.lib.version.VEnchantment; import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import org.bukkit.*; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@ -17,13 +18,11 @@ import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.io.BukkitObjectInputStream; import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream; import org.bukkit.util.io.BukkitObjectOutputStream;
import org.jetbrains.annotations.NotNull;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -35,37 +34,11 @@ public class MMOCoreUtils {
return item != null && item.hasItemMeta() && item.getItemMeta().hasDisplayName(); return item != null && item.hasItemMeta() && item.getItemMeta().hasDisplayName();
} }
/**
* If a given player is not in the server cache, no information
* cannot be retrieved from that player (without using requests
* to MC servers obviously). In that case, the instance of
* OfflinePlayer is pretty much useless and it only wraps its
* UUID which was already known beforehand.
*
* @param player Offline player instance to test
* @return Is the instance valid
*/
public static boolean isInvalid(OfflinePlayer player) {
return player.getName() == null;
}
@Deprecated
public static String displayName(ItemStack item) { public static String displayName(ItemStack item) {
return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName()
: UtilityMethods.caseOnWords(item.getType().name().replace("_", " ")); : caseOnWords(item.getType().name().replace("_", " "));
} }
/**
* @param current Current value of resource
* @param maxStat Maximum value of resource
* @return Clamped resource value. If the provided current value is 0,
* this function will return the maximum resource value.
*/
public static double fixResource(double current, double maxStat) {
return current == 0 ? maxStat : Math.max(0, Math.min(current, maxStat));
}
@Deprecated
public static String caseOnWords(String s) { public static String caseOnWords(String s) {
StringBuilder builder = new StringBuilder(s); StringBuilder builder = new StringBuilder(s);
boolean isLastSpace = true; boolean isLastSpace = true;
@ -80,15 +53,34 @@ public class MMOCoreUtils {
return builder.toString(); return builder.toString();
} }
public static String ymlName(String str) { /**
return str.toLowerCase().replace("_", "-").replace(" ", "-"); *
} * @param value an integer you want to convert
* @return the string representing the integer but with roman letters
@Deprecated */
public static String toRomanNumerals(int value) { public static String toRomanNumerals(int value) {
return intToRoman(value); LinkedHashMap<String, Integer> roman_numerals = new LinkedHashMap<String, Integer>();
roman_numerals.put("M", 1000);
roman_numerals.put("CM", 900);
roman_numerals.put("D", 500);
roman_numerals.put("CD", 400);
roman_numerals.put("C", 100);
roman_numerals.put("XC", 90);
roman_numerals.put("L", 50);
roman_numerals.put("XL", 40);
roman_numerals.put("X", 10);
roman_numerals.put("IX", 9);
roman_numerals.put("V", 5);
roman_numerals.put("IV", 4);
roman_numerals.put("I", 1);
String res = "";
for(Map.Entry<String, Integer> entry : roman_numerals.entrySet()){
int matches = value/entry.getValue();
res += repeat(entry.getKey(), matches);
value = value % entry.getValue();
}
return res;
} }
private static String repeat(String s, int n) { private static String repeat(String s, int n) {
if(s == null) { if(s == null) {
return null; return null;
@ -99,7 +91,6 @@ public class MMOCoreUtils {
} }
return sb.toString(); return sb.toString();
} }
/** /**
* Displays an in game indicator using a hologram. This uses * Displays an in game indicator using a hologram. This uses
* LumineUtils hologramFactory to summon holograms * LumineUtils hologramFactory to summon holograms
@ -110,38 +101,18 @@ public class MMOCoreUtils {
* @param message Message to display * @param message Message to display
*/ */
public static void displayIndicator(Location loc, String message) { public static void displayIndicator(Location loc, String message) {
Hologram holo = Hologram.create(loc, MythicLib.plugin.parseColors(Collections.singletonList(message))); Hologram holo = Hologram.create(loc, Arrays.asList(message));
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, holo::despawn, 20); Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> holo.despawn(), 20);
} }
public static boolean isPlayerHead(Material material) { public static boolean isPlayerHead(Material material) {
return material == Material.PLAYER_HEAD || material == Material.PLAYER_WALL_HEAD; return material == VersionMaterial.PLAYER_HEAD.toMaterial() || material == VersionMaterial.PLAYER_WALL_HEAD.toMaterial();
} }
public static void addAllItemFlags(@NotNull ItemMeta meta) { public static ItemStack readIcon(String string) throws IllegalArgumentException {
meta.addItemFlags(ItemFlag.values()); String[] split = string.split(":");
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
// Fix 1.20.6+ Paper bug that sucks. HIDE_ATTRIBUTES no longer works when item attribute list is empty return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
// TODO refactor with GUI update.
try {
meta.setAttributeModifiers(MultimapBuilder.hashKeys(0).hashSetValues(0).build());
} catch (Exception exception) {
// Not needed
}
}
@NotNull
public static ItemStack readIcon(String string) {
final String[] split = string.split(":");
final ItemStack item = new ItemStack(Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_")));
if (split.length > 1) {
final ItemMeta meta = item.getItemMeta();
meta.setCustomModelData(Integer.parseInt(split[1]));
item.setItemMeta(meta);
}
return item;
} }
public static int getWorth(ItemStack[] items) { public static int getWorth(ItemStack[] items) {
@ -257,7 +228,6 @@ public class MMOCoreUtils {
return entities; return entities;
} }
@Deprecated
public static void heal(LivingEntity target, double value) { public static void heal(LivingEntity target, double value) {
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double gain = Math.min(max, target.getHealth() + value) - target.getHealth(); double gain = Math.min(max, target.getHealth() + value) - target.getHealth();
@ -268,8 +238,6 @@ public class MMOCoreUtils {
target.setHealth(target.getHealth() + gain); target.setHealth(target.getHealth() + gain);
} }
private static final Random RANDOM = new Random();
/** /**
* Method used when mining a custom block or fishing, as the corresponding * Method used when mining a custom block or fishing, as the corresponding
* interaction event is cancelled durability is not handled. This method is * interaction event is cancelled durability is not handled. This method is
@ -284,27 +252,21 @@ public class MMOCoreUtils {
* @param damage Damage that needs to be applied * @param damage Damage that needs to be applied
*/ */
public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) { public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) {
ItemStack item = player.getInventory().getItem(slot);
ItemStack item = UtilityMethods.getHandItem(player, slot); if (item == null || item.getType().getMaxDurability() == 0 || !item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable())
if (item == null || item.getType().getMaxDurability() == 0 || item.getItemMeta().isUnbreakable())
return; return;
// Check unbreakable, ignore if necessary
final ItemMeta meta = item.getItemMeta();
final int unbreakingLevel = meta.getEnchantLevel(VEnchantment.UNBREAKING.get());
if (unbreakingLevel > 0 && RANDOM.nextInt(unbreakingLevel + 1) != 0) return;
PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, item, damage); PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled())
return; return;
final int newDamage = event.getDamage() + ((Damageable) meta).getDamage(); ItemMeta meta = item.getItemMeta();
if (newDamage >= item.getType().getMaxDurability()) { if (event.getDamage() + ((Damageable) meta).getDamage() >= item.getType().getMaxDurability()) {
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F); player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
player.getInventory().setItem(slot, null); player.getInventory().setItem(slot, null);
} else { } else {
((Damageable) meta).setDamage(newDamage); ((Damageable) meta).setDamage(((Damageable) meta).getDamage() + event.getDamage());
item.setItemMeta(meta); item.setItemMeta(meta);
} }
} }
@ -315,11 +277,4 @@ public class MMOCoreUtils {
public static Location getCenterLocation(Entity entity) { public static Location getCenterLocation(Entity entity) {
return entity.getBoundingBox().getCenter().toLocation(entity.getWorld()); return entity.getBoundingBox().getCenter().toLocation(entity.getWorld());
} }
public static void debug(String message) {
message = ChatColor.YELLOW + "Debug> " + ChatColor.WHITE + message;
for (Player player : Bukkit.getOnlinePlayers())
player.sendMessage(message);
Bukkit.getConsoleSender().sendMessage(message);
}
} }

View File

@ -1,7 +1,6 @@
package net.Indyuce.mmocore.api.util.input; package net.Indyuce.mmocore.api.util.input;
import io.lumine.mythic.lib.MythicLib; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -13,6 +12,8 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Consumer; import org.bukkit.util.Consumer;
import io.lumine.mythic.lib.MythicLib;
@Deprecated @Deprecated
public class AnvilGUI extends PlayerInput { public class AnvilGUI extends PlayerInput {
private final int containerId; private final int containerId;
@ -23,7 +24,7 @@ public class AnvilGUI extends PlayerInput {
ItemStack paper = new ItemStack(Material.PAPER); ItemStack paper = new ItemStack(Material.PAPER);
ItemMeta paperMeta = paper.getItemMeta(); ItemMeta paperMeta = paper.getItemMeta();
paperMeta.setDisplayName(ConfigMessage.fromKey("player-input.anvil." + type.getLowerCaseName()).asLine()); paperMeta.setDisplayName(MMOCore.plugin.configManager.getSimpleMessage("player-input.anvil." + type.getLowerCaseName()).message());
paper.setItemMeta(paperMeta); paper.setItemMeta(paperMeta);
MythicLib.plugin.getVersion().getWrapper().handleInventoryCloseEvent(player); MythicLib.plugin.getVersion().getWrapper().handleInventoryCloseEvent(player);

View File

@ -1,7 +1,6 @@
package net.Indyuce.mmocore.api.util.input; package net.Indyuce.mmocore.api.util.input;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.gui.api.PluginInventory; import net.Indyuce.mmocore.gui.api.PluginInventory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -38,7 +37,8 @@ public class ChatInput extends PlayerInput {
this.lastOpened = lastOpened; this.lastOpened = lastOpened;
player.closeInventory(); player.closeInventory();
ConfigMessage.fromKey("player-input.chat." + inputType.getLowerCaseName()).send(player); MMOCore.plugin.configManager.getSimpleMessage("player-input.chat." + inputType.getLowerCaseName()).send(player);
MMOCore.plugin.configManager.getSimpleMessage("player-input.chat.cancel").send(player);
} }
@Override @Override
@ -56,7 +56,7 @@ public class ChatInput extends PlayerInput {
if (event.getMessage().equals("cancel")) { if (event.getMessage().equals("cancel")) {
if (lastOpened != null) if (lastOpened != null)
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> lastOpened.open()); Bukkit.getScheduler().runTask(MMOCore.plugin, () -> lastOpened.open());
ConfigMessage.fromKey("player-input.chat." + inputType.getLowerCaseName() + "-cancel").send(getPlayer()); MMOCore.plugin.configManager.getSimpleMessage("player-input.chat." + inputType.getLowerCaseName() + "-cancel").send(getPlayer());
} else } else
// Run sync // Run sync
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> output(event.getMessage())); Bukkit.getScheduler().runTask(MMOCore.plugin, () -> output(event.getMessage()));

View File

@ -29,6 +29,7 @@ public abstract class PlayerInput implements Listener {
public enum InputType { public enum InputType {
FRIEND_REQUEST, FRIEND_REQUEST,
PARTY_INVITE, PARTY_INVITE,
GUILD_INVITE, GUILD_INVITE,
GUILD_CREATION_TAG, GUILD_CREATION_TAG,

View File

@ -2,13 +2,7 @@ package net.Indyuce.mmocore.api.util.math.formula;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
/**
* Bounded linear formula.
*
* @author Jules
*/
public class LinearValue { public class LinearValue {
private final double base, perLevel, min, max; private final double base, perLevel, min, max;
private final boolean hasMin, hasMax; private final boolean hasMin, hasMax;
@ -103,7 +97,6 @@ public class LinearValue {
return hasMin; return hasMin;
} }
@NotNull
public String getDisplay(int level) { public String getDisplay(int level) {
return MythicLib.plugin.getMMOConfig().decimals.format(calculate(level)); return MythicLib.plugin.getMMOConfig().decimals.format(calculate(level));
} }

View File

@ -1,26 +1,25 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class AttributesCommand extends RegisteredCommand { public class AttributesCommand extends BukkitCommand {
public AttributesCommand(ConfigurationSection config) { public AttributesCommand(ConfigurationSection config) {
super(config, ToggleableCommand.ATTRIBUTES); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the attribute menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.attributes"))
return false;
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only."); sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true; return true;

View File

@ -1,19 +1,21 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class ClassCommand extends RegisteredCommand { public class ClassCommand extends BukkitCommand {
public ClassCommand(ConfigurationSection config) { public ClassCommand(ConfigurationSection config) {
super(config, ToggleableCommand.CLASS); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Select a new class.");
} }
@Override @Override

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.command.api; package net.Indyuce.mmocore.command;
import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;

View File

@ -1,17 +1,19 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.gui.eco.DepositMenu; import net.Indyuce.mmocore.gui.eco.DepositMenu;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class DepositCommand extends RegisteredCommand { public class DepositCommand extends BukkitCommand {
public DepositCommand(ConfigurationSection config) { public DepositCommand(ConfigurationSection config) {
super(config, ToggleableCommand.DEPOSIT); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the currency deposit menu.");
} }
@Override @Override
@ -27,7 +29,7 @@ public class DepositCommand extends RegisteredCommand {
// if (sender instanceof Player) // if (sender instanceof Player)
// if (!isNearEnderchest(((Player) sender).getLocation())) { // if (!isNearEnderchest(((Player) sender).getLocation())) {
// sender.sendMessage(ConfigMessage.fromKey("stand-near-enderchest")); // sender.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("stand-near-enderchest"));
// return true; // return true;
// } // }

View File

@ -3,8 +3,6 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.FriendRequest; import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.api.player.social.Request;
@ -12,21 +10,23 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.UUID; import java.util.UUID;
public class FriendsCommand extends RegisteredCommand { public class FriendsCommand extends BukkitCommand {
public FriendsCommand(ConfigurationSection config) { public FriendsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.FRIENDS); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the friends menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.friends"))
return false;
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only."); sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true; return true;

View File

@ -2,8 +2,6 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.api.player.social.Request;
@ -13,21 +11,24 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.UUID; import java.util.UUID;
public class GuildCommand extends RegisteredCommand { public class GuildCommand extends BukkitCommand {
public GuildCommand(ConfigurationSection config) { public GuildCommand(ConfigurationSection config) {
super(config, ToggleableCommand.GUILD); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the guilds menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.guild"))
return false;
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only."); sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true; return true;
@ -49,7 +50,7 @@ public class GuildCommand extends RegisteredCommand {
final Request req = MMOCore.plugin.requestManager.getRequest(uuid); final Request req = MMOCore.plugin.requestManager.getRequest(uuid);
Validate.isTrue(!req.isTimedOut() && req instanceof GuildInvite); Validate.isTrue(!req.isTimedOut() && req instanceof GuildInvite);
invite = (GuildInvite) req; invite = (GuildInvite) req;
Validate.isTrue(MMOCore.plugin.nativeGuildManager.isRegistered(invite.getGuild())); Validate.isTrue(MMOCore.plugin.dataProvider.getGuildManager().isRegistered(invite.getGuild()));
} catch (Exception exception) { } catch (Exception exception) {
return true; return true;
} }

View File

@ -2,8 +2,6 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.api.player.social.Request;
@ -14,29 +12,28 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.UUID; import java.util.UUID;
public class PartyCommand extends RegisteredCommand { public class PartyCommand extends BukkitCommand {
public PartyCommand(ConfigurationSection config) { public PartyCommand(ConfigurationSection config) {
super(config, ToggleableCommand.PARTY); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the party menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.party"))
return false;
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only."); sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true; return true;
} }
if(!(MMOCore.plugin.partyModule instanceof MMOCorePartyModule)){
sender.sendMessage(ChatColor.RED+"You can't use MMOCore party system as you delegated the party system to another plugin.");
return true;
}
PlayerData data = PlayerData.get((OfflinePlayer) sender); PlayerData data = PlayerData.get((OfflinePlayer) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "party"); MMOCommandEvent event = new MMOCommandEvent(data, "party");

View File

@ -1,25 +1,25 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class PlayerStatsCommand extends RegisteredCommand { public class PlayerStatsCommand extends BukkitCommand {
public PlayerStatsCommand(ConfigurationSection config) { public PlayerStatsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.PLAYER); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Show player stats.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.profile"))
return false;
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only."); sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true; return true;

View File

@ -1,57 +0,0 @@
package net.Indyuce.mmocore.command;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.comp.flags.CustomFlag;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
public class PvpModeCommand extends RegisteredCommand {
public PvpModeCommand(ConfigurationSection config) {
super(config, ToggleableCommand.PVP_MODE);
}
public static final String COOLDOWN_KEY = "PvpMode";
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only.");
return false;
}
if (!sender.hasPermission("mmocore.pvpmode")) {
ConfigMessage.fromKey("not-enough-perms").send((Player) sender);
return false;
}
final PlayerData playerData = PlayerData.get((Player) sender);
// Command cooldown
if (playerData.getCooldownMap().isOnCooldown(COOLDOWN_KEY)) {
ConfigMessage.fromKey("pvp-mode.cooldown", "remaining", MythicLib.plugin.getMMOConfig().decimal.format(playerData.getCooldownMap().getCooldown(COOLDOWN_KEY))).send((Player) sender);
return true;
}
playerData.getCombat().setPvpMode(!playerData.getCombat().isInPvpMode());
playerData.getCooldownMap().applyCooldown(COOLDOWN_KEY, playerData.getCombat().isInPvpMode() ? MMOCore.plugin.configManager.pvpModeToggleOnCooldown : MMOCore.plugin.configManager.pvpModeToggleOffCooldown);
// Toggling on when in PVP region
if (playerData.getCombat().isInPvpMode() &&
MythicLib.plugin.getFlags().isFlagAllowed(playerData.getPlayer(), CustomFlag.PVP_MODE)) {
playerData.getCombat().setInvulnerable(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeCommand);
ConfigMessage.fromKey("pvp-mode.toggle.on-invulnerable", "time",
MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeCommand)).send(playerData.getPlayer());
// Just send message otherwise
} else
ConfigMessage.fromKey("pvp-mode.toggle." + (playerData.getCombat().isInPvpMode() ? "on" : "off") + "-safe").send((Player) sender);
return true;
}
}

View File

@ -1,24 +1,24 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class QuestsCommand extends RegisteredCommand { public class QuestsCommand extends BukkitCommand {
public QuestsCommand(ConfigurationSection config) { public QuestsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.QUESTS); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the quests menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.quests"))
return false;
if (sender instanceof Player) { if (sender instanceof Player) {
PlayerData data = PlayerData.get((Player) sender); PlayerData data = PlayerData.get((Player) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "quests"); MMOCommandEvent event = new MMOCommandEvent(data, "quests");

View File

@ -0,0 +1,44 @@
package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SkillTreeCommand extends BukkitCommand {
public SkillTreeCommand(ConfigurationSection config) {
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the skills menu.");
}
@Override
public boolean execute(@NotNull CommandSender sender, String s, String[] args) {
if (!(sender instanceof Player player))
return false;
PlayerData data = PlayerData.get(player);
MMOCommandEvent event = new MMOCommandEvent(data, "skilltrees");
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled())
return true;
if (data.getProfess().getSkillTrees().size() != 0) {
InventoryManager.TREE_VIEW.newInventory(data).open();
return false;
}
else {
MMOCore.plugin.configManager.getSimpleMessage("no-skill-tree").send(player);
return true;
}
}
}

View File

@ -1,77 +0,0 @@
package net.Indyuce.mmocore.command;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Collectors;
public class SkillTreesCommand extends RegisteredCommand {
public SkillTreesCommand(ConfigurationSection config) {
super(config, ToggleableCommand.SKILL_TREES);
}
@Override
public boolean execute(@NotNull CommandSender sender, String s, String[] args) {
if (!sender.hasPermission("mmocore.skilltrees"))
return false;
if (!(sender instanceof Player))
return false;
final Player player = (Player) sender;
PlayerData data = PlayerData.get(player);
MMOCommandEvent event = new MMOCommandEvent(data, "skilltrees");
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled())
return false;
// Default skilltree command
if (args.length == 0) {
if (!MMOCore.plugin.configManager.enableGlobalSkillTreeGUI) {
sender.sendMessage(ChatColor.RED + "Usage: /skilltrees <skilltree_id>");
return false;
}
if (data.getProfess().getSkillTrees().size() != 0) {
InventoryManager.TREE_VIEW.newInventory(data).open();
return true;
} else {
ConfigMessage.fromKey("no-skill-tree").send(player);
return false;
}
}
if (args.length == 1) {
if (!MMOCore.plugin.configManager.enableSpecificSkillTreeGUI) {
sender.sendMessage(ChatColor.RED + "Usage: /skilltrees <skilltree-id>");
return false;
}
if (data.getProfess().getSkillTrees()
.stream()
.filter(skillTree -> UtilityMethods.ymlName(skillTree.getId()).equals(UtilityMethods.ymlName(args[0])))
.collect(Collectors.toList())
.size() != 0) {
InventoryManager.SPECIFIC_TREE_VIEW.get(UtilityMethods.ymlName(args[0])).newInventory(data).open();
return true;
} else {
sender.sendMessage(ChatColor.RED + "Your class does not have a skill tree with id: " + args[0]);
return false;
}
} else {
if (MMOCore.plugin.configManager.enableSpecificSkillTreeGUI)
sender.sendMessage(ChatColor.RED + "Usage: /skilltrees <skilltree-id>");
else
sender.sendMessage(ChatColor.RED + "Usage: /skilltrees");
return false;
}
}
}

View File

@ -1,33 +1,33 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class SkillsCommand extends RegisteredCommand { public class SkillsCommand extends BukkitCommand {
public SkillsCommand(ConfigurationSection config) { public SkillsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.SKILLS); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the skills menu.");
} }
@Override @Override
public boolean execute(CommandSender sender, String label, String[] args) { public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.skills"))
return false;
if (sender instanceof Player) { if (sender instanceof Player) {
PlayerData data = PlayerData.get((Player) sender); PlayerData data = PlayerData.get((Player) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "skills"); MMOCommandEvent event = new MMOCommandEvent(data, "skills");
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if(event.isCancelled()) return true; if(event.isCancelled()) return true;
if (data.getUnlockedSkills().isEmpty()) { if (data.getProfess().getSkills().size() < 1) {
ConfigMessage.fromKey("no-class-skill").send((Player) sender); MMOCore.plugin.configManager.getSimpleMessage("no-class-skill").send((Player) sender);
return true; return true;
} }

View File

@ -1,18 +1,20 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.manager.InventoryManager; import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class WaypointsCommand extends RegisteredCommand { public class WaypointsCommand extends BukkitCommand {
public WaypointsCommand(ConfigurationSection config) { public WaypointsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.WAYPOINTS); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Open the waypoints menu.");
} }
@Override @Override

View File

@ -1,21 +1,23 @@
package net.Indyuce.mmocore.command; package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.eco.Withdraw;
import net.Indyuce.mmocore.command.api.RegisteredCommand;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class WithdrawCommand extends RegisteredCommand { import net.Indyuce.mmocore.api.eco.Withdraw;
public class WithdrawCommand extends BukkitCommand {
public WithdrawCommand(ConfigurationSection config) { public WithdrawCommand(ConfigurationSection config) {
super(config, ToggleableCommand.WITHDRAW); super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Creates a withdraw request.");
} }
@Override @Override
@ -37,7 +39,7 @@ public class WithdrawCommand extends RegisteredCommand {
amount = Integer.parseInt(amountArgument); amount = Integer.parseInt(amountArgument);
Validate.isTrue(amount >= 0); Validate.isTrue(amount >= 0);
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
sender.sendMessage(ConfigMessage.fromKey("wrong-number", "arg", "" + args[0]).asLine()); sender.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("wrong-number", "arg", "" + args[0]).message());
return true; return true;
} }
@ -50,14 +52,14 @@ public class WithdrawCommand extends RegisteredCommand {
int left = (int) MMOCore.plugin.economy.getEconomy().getBalance(player) - amount; int left = (int) MMOCore.plugin.economy.getEconomy().getBalance(player) - amount;
if (left < 0) { if (left < 0) {
ConfigMessage.fromKey("not-enough-money", "left", "" + -left).send(player); MMOCore.plugin.configManager.getSimpleMessage("not-enough-money", "left", "" + -left).send(player);
return true; return true;
} }
MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, amount); MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, amount);
request.withdrawAlgorythm(amount); request.withdrawAlgorythm(amount);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
ConfigMessage.fromKey("withdrew", "worth", amount).send(player); MMOCore.plugin.configManager.getSimpleMessage("withdrew", "worth", "" + amount).send(player);
return true; return true;
} }
} }

View File

@ -1,14 +0,0 @@
package net.Indyuce.mmocore.command.api;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
public abstract class RegisteredCommand extends BukkitCommand {
public RegisteredCommand(@NotNull ConfigurationSection config, ToggleableCommand command) {
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription(config.getString("description", command.getDescription()));
}
}

View File

@ -1,112 +0,0 @@
package net.Indyuce.mmocore.command.api;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.command.*;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Level;
/**
* Commands which can be disabled using commands.yml
*/
public enum ToggleableCommand {
PLAYER("player", "Displays player stats", config -> new PlayerStatsCommand(config), "p", "profile"),
ATTRIBUTES("attributes", "Display and manage attributes", config -> new AttributesCommand(config), "att", "stats"),
CLASS("class", "Select a new class", config -> new ClassCommand(config), "c"),
WAYPOINTS("waypoints", "Display discovered waypoints", config -> new WaypointsCommand(config), "wp"),
QUESTS("quests", "Display available quests", config -> new QuestsCommand(config), "q", "journal"),
SKILLS("skills", "Spend skill points to unlock new skills", config -> new SkillsCommand(config), "s"),
FRIENDS("friends", "Show online/offline friends", config -> new FriendsCommand(config), "f"),
PARTY("party", "Invite players in a party to split exp", config -> new PartyCommand(config)),
GUILD("guild", "Show players in current guild", config -> new GuildCommand(config)),
WITHDRAW("withdraw", "Withdraw money into coins and notes", config -> new WithdrawCommand(config), v -> MMOCore.plugin.hasEconomy() && MMOCore.plugin.economy.isValid(), "w"),
SKILL_TREES("skilltrees", "Open up the skill tree menu", config -> new SkillTreesCommand(config), "st", "trees", "tree"),
DEPOSIT("deposit", "Open the currency deposit menu", config -> new DepositCommand(config), "d"),
PVP_MODE("pvpmode", "Toggle on/off PVP mode.", config -> new PvpModeCommand(config), "pvp");
private final String mainLabel;
private final String description;
private final Function<ConfigurationSection, RegisteredCommand> generator;
private final List<String> aliases;
private final Predicate<Void> enabled;
ToggleableCommand(@NotNull String mainLabel, @NotNull String description, @NotNull Function<ConfigurationSection, RegisteredCommand> generator, @NotNull String... aliases) {
this(mainLabel, description, generator, null, aliases);
}
ToggleableCommand(@NotNull String mainLabel, @NotNull String description, @NotNull Function<ConfigurationSection, RegisteredCommand> generator, @Nullable Predicate<Void> enabled, @NotNull String... aliases) {
this.mainLabel = mainLabel;
this.description = description;
this.generator = generator;
this.aliases = Arrays.asList(aliases);
this.enabled = enabled == null ? v -> true : enabled;
}
public String getMainLabel() {
return mainLabel;
}
public String getDescription() {
return description;
}
public List<String> getAliases() {
return aliases;
}
public String getConfigPath() {
return name().toLowerCase().replace("_", "-");
}
public boolean isEnabled() {
return enabled.test(null);
}
public static void register() {
// Load default config file
if (!new File(MMOCore.plugin.getDataFolder(), "commands.yml").exists()) {
final ConfigFile config = new ConfigFile("commands");
for (ToggleableCommand cmd : values()) {
final String path = cmd.getConfigPath();
config.getConfig().set(path + ".main", cmd.mainLabel);
config.getConfig().set(path + ".aliases", cmd.aliases);
config.getConfig().set(path + ".description", cmd.description);
}
config.save();
}
try {
// Find command map
final Field commandMapField = Bukkit.getServer().getClass().getDeclaredField("commandMap");
commandMapField.setAccessible(true);
final CommandMap commandMap = (CommandMap) commandMapField.get(Bukkit.getServer());
// Enable commands individually
final FileConfiguration config = new ConfigFile("commands").getConfig();
for (ToggleableCommand cmd : values())
if (cmd.isEnabled() && config.contains(cmd.getConfigPath()))
commandMap.register("mmocore", cmd.generator.apply(config.getConfigurationSection(cmd.getConfigPath())));
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Unable to register custom commands:");
exception.printStackTrace();
}
}
}

View File

@ -21,15 +21,14 @@ public class AdminCommandTreeNode extends CommandTreeNode {
addChild(new LevelCommandTreeNode(this)); addChild(new LevelCommandTreeNode(this));
addChild(new AttributeCommandTreeNode(this)); addChild(new AttributeCommandTreeNode(this));
addChild(new SkillCommandTreeNode(this)); addChild(new SkillCommandTreeNode(this));
addChild(new SaveDataTreeNode(this));
addChild(new SlotCommandTreeNode(this));
addChild(new PointsCommandTreeNode("skill", this, PlayerData::setSkillPoints, PlayerData::giveSkillPoints, PlayerData::getSkillPoints)); addChild(new PointsCommandTreeNode("skill", this, PlayerData::setSkillPoints, PlayerData::giveSkillPoints, PlayerData::getSkillPoints));
addChild(new PointsCommandTreeNode("class", this, PlayerData::setClassPoints, PlayerData::giveClassPoints, PlayerData::getClassPoints)); addChild(new PointsCommandTreeNode("class", this, PlayerData::setClassPoints, PlayerData::giveClassPoints, PlayerData::getClassPoints));
addChild(new PointsCommandTreeNode("attribute", this, PlayerData::setAttributePoints, PlayerData::giveAttributePoints, PlayerData::getAttributePoints)); addChild(new PointsCommandTreeNode("attribute", this, PlayerData::setAttributePoints, PlayerData::giveAttributePoints, PlayerData::getAttributePoints));
addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints)); addChild(new PointsCommandTreeNode("attr-realloc", this, PlayerData::setAttributeReallocationPoints, PlayerData::giveAttributeReallocationPoints, PlayerData::getAttributeReallocationPoints));
addChild(new PointsCommandTreeNode("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints)); addChild(new PointsCommandTreeNode("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints));
addChild(new PointsCommandTreeNode("skill-tree-realloc", this, PlayerData::setSkillTreeReallocationPoints, PlayerData::giveSkillTreeReallocationPoints, PlayerData::getSkillTreeReallocationPoints)); addChild(new PointsCommandTreeNode("skill-tree-realloc", this, PlayerData::setSkillTreeReallocationPoints, PlayerData::giveSkillTreeReallocationPoints, PlayerData::getSkillTreeReallocationPoints));
addChild(new SkillTreePointsCommandTreeNode(this, (playerData, integer, s) -> playerData.setSkillTreePoints(s, integer), (playerData, integer, s) -> playerData.giveSkillTreePoints(s, integer), PlayerData::getSkillTreePoints)); addChild(new SkillTreePointsCommandTreeNode(this,(playerData, integer, s) -> playerData.setSkillTreePoints(s,integer),(playerData, integer, s) -> playerData.giveSkillTreePoints(s,integer),((playerData, s) -> playerData.getSkillTreePoint(s))));
for (PlayerResource res : PlayerResource.values()) for (PlayerResource res : PlayerResource.values())
addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res)); addChild(new ResourceCommandTreeNode(res.name().toLowerCase(), this, res));
} }

View File

@ -4,7 +4,7 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes; import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -1,20 +1,20 @@
package net.Indyuce.mmocore.command.rpg.admin; package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.command.CommandVerbose;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
public class ClassCommandTreeNode extends CommandTreeNode { public class ClassCommandTreeNode extends CommandTreeNode {
public ClassCommandTreeNode(CommandTreeNode parent) { public ClassCommandTreeNode(CommandTreeNode parent) {
super(parent, "class"); super(parent, "class");
@ -52,9 +52,9 @@ public class ClassCommandTreeNode extends CommandTreeNode {
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
(data.hasSavedClass(profess) ? data.getClassInfo(profess) (data.hasSavedClass(profess) ? data.getClassInfo(profess)
: new SavedClassInformation(MMOCore.plugin.playerDataManager.getDefaultData())).load(profess, data); : new SavedClassInformation(MMOCore.plugin.dataProvider.getDataManager().getDefaultData())).load(profess, data);
if (data.isOnline()) { if (data.isOnline()) {
ConfigMessage.fromKey("class-select", "class", profess.getName()).send(data.getPlayer()); MMOCore.plugin.configManager.getSimpleMessage("class-select", "class", profess.getName()).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1, 1); data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1, 1);
} }

View File

@ -8,7 +8,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot; import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
import net.Indyuce.mmocore.util.TriConsumer; import net.Indyuce.mmocore.util.TriConsumer;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;

View File

@ -1,13 +1,21 @@
package net.Indyuce.mmocore.command.rpg.admin; package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.command.api.CommandTreeNode; import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.data.DataExport;
import io.lumine.mythic.lib.data.sql.SQLDataSource;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.data.yaml.YAMLPlayerDataHandler; import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.stream.Collectors;
/** /**
* This command allows to transfer data from your actual storage type * This command allows to transfer data from your actual storage type
@ -18,15 +26,82 @@ public class ExportDataTreeNode extends CommandTreeNode {
super(parent, "exportdata"); super(parent, "exportdata");
} }
/**
* Amount of requests generated every batch
*/
private static final int BATCH_AMOUNT = 50;
/**
* Period in ticks
*/
private static final int BATCH_PERIOD = 20;
private static final DecimalFormat decFormat = new DecimalFormat("0.#");
@Override @Override
@NotNull
public CommandResult execute(CommandSender sender, String[] strings) { public CommandResult execute(CommandSender sender, String[] strings) {
// Export YAML to SQL if (!MMOCore.plugin.dataProvider.getDataManager().getLoaded().isEmpty()) {
final boolean result = new DataExport<>(MMOCore.plugin.playerDataManager, sender).start( sender.sendMessage("Please make sure no players are logged in when using this command. " +
() -> new YAMLPlayerDataHandler(MMOCore.plugin), "If you are still seeing this message, restart your server and execute this command before any player logs in.");
() -> new SQLDataHandler(new SQLDataSource(MMOCore.plugin))); return CommandResult.FAILURE;
}
return result ? CommandResult.SUCCESS : CommandResult.FAILURE; final List<UUID> playerIds = Arrays.stream(new File(MMOCore.plugin.getDataFolder() + "/userdata").listFiles())
.map(file -> UUID.fromString(file.getName().replace(".yml", ""))).collect(Collectors.toList());
// Initialize fake SQL data provider
final MySQLDataProvider sqlProvider;
try {
sqlProvider = new MySQLDataProvider(MMOCore.plugin.getConfig());
} catch (RuntimeException exception) {
sender.sendMessage("Could not initialize SQL provider (see console for stack trace): " + exception.getMessage());
return CommandResult.FAILURE;
}
final double timeEstimation = (double) playerIds.size() / BATCH_AMOUNT * BATCH_PERIOD / 20;
sender.sendMessage("Exporting " + playerIds.size() + " player data(s).. See console for details");
sender.sendMessage("Minimum expected time: " + decFormat.format(timeEstimation) + "s");
// Save player data
new BukkitRunnable() {
int errorCount = 0;
int batchCounter = 0;
@Override
public void run() {
for (int i = 0; i < BATCH_AMOUNT; i++) {
final int index = BATCH_AMOUNT * batchCounter + i;
/*
* Saving is done. Close connection to avoid memory
* leaks and ouput the results to the command executor
*/
if (index >= playerIds.size()) {
cancel();
sqlProvider.close();
MMOCore.plugin.getLogger().log(Level.WARNING, "Exported " + playerIds.size() + " player datas to SQL database. Total errors: " + errorCount);
return;
}
final UUID playerId = playerIds.get(index);
try {
final PlayerData offlinePlayerData = new PlayerData(new MMOPlayerData(playerId));
MMOCore.plugin.dataProvider.getDataManager().loadData(offlinePlayerData);
// Player data is loaded, now it gets saved through SQL
sqlProvider.getDataManager().saveData(offlinePlayerData);
} catch (RuntimeException exception) {
errorCount++;
exception.printStackTrace();
}
}
batchCounter++;
}
}.runTaskTimerAsynchronously(MMOCore.plugin, 0, BATCH_PERIOD);
return CommandResult.SUCCESS;
} }
} }

View File

@ -3,7 +3,7 @@ package net.Indyuce.mmocore.command.rpg.admin;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -36,7 +36,7 @@ public class HideActionBarCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
final long lastUsed = System.currentTimeMillis() - PlayerActivity.ACTION_BAR_MESSAGE.getTimeOut() + amount * 50; long lastUsed = System.currentTimeMillis() - PlayerActivity.ACTION_BAR_MESSAGE.getTimeOut() + amount * 50;
PlayerData.get(player).setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, lastUsed); PlayerData.get(player).setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, lastUsed);
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }

View File

@ -7,7 +7,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.util.TriConsumer; import net.Indyuce.mmocore.util.TriConsumer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;

View File

@ -1,7 +1,7 @@
package net.Indyuce.mmocore.command.rpg.admin; package net.Indyuce.mmocore.command.rpg.admin;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -4,7 +4,7 @@ import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -1,33 +1,29 @@
package net.Indyuce.mmocore.command.rpg.admin; package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import net.Indyuce.mmocore.command.CommandVerbose;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
public class ResetCommandTreeNode extends CommandTreeNode { public class ResetCommandTreeNode extends CommandTreeNode {
public ResetCommandTreeNode(CommandTreeNode parent) { public ResetCommandTreeNode(CommandTreeNode parent) {
super(parent, "reset"); super(parent, "reset");
addChild(new ResetClassesCommandTreeNode(this));
addChild(new ResetLevelsCommandTreeNode(this)); addChild(new ResetLevelsCommandTreeNode(this));
addChild(new ResetSkillsCommandTreeNode(this)); addChild(new ResetSkillsCommandTreeNode(this));
addChild(new ResetQuestsCommandTreeNode(this)); addChild(new ResetAllCommandTreeNode(this));
addChild(new ResetAttributesCommandTreeNode(this)); addChild(new ResetAttributesCommandTreeNode(this));
addChild(new ResetWaypointsCommandTreeNode(this)); addChild(new ResetWaypointsCommandTreeNode(this));
addChild(new ResetSkillTreesCommandTreeNode(this)); addChild(new ResetSkillTreesCommandTreeNode(this));
addChild(new ResetAllCommandTreeNode(this));
} }
@Override @Override
@ -44,7 +40,8 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -52,25 +49,36 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate");
PlayerData data = PlayerData.get(player); PlayerData data = PlayerData.get(player);
ResetClassesCommandTreeNode.resetClasses(data); MMOCore.plugin.dataProvider.getDataManager().getDefaultData().apply(data);
ResetLevelsCommandTreeNode.resetLevels(data); data.setExperience(0);
ResetSkillsCommandTreeNode.resetSkills(data); for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
ResetQuestsCommandTreeNode.resetQuests(data); data.getCollectionSkills().setExperience(profession, 0);
ResetAttributesCommandTreeNode.resetAttributes(data, givePoints); data.getCollectionSkills().setLevel(profession, 0);
ResetWaypointsCommandTreeNode.resetWaypoints(data); }
ResetSkillTreesCommandTreeNode.resetSkillTrees(data); MMOCore.plugin.classManager.getAll().forEach(data::unloadClassInfo);
// Reset times-claimed not being properly emptied otherwise data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
data.getItemClaims().clear(); data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s data was successfully reset."); data.setSkillTreePoints("global", 0);
for (SkillTree skillTree : data.getProfess().getSkillTrees()) {
data.resetSkillTree(skillTree);
data.setSkillTreePoints(skillTree.getId(), 0);
}
data.resetTimesClaimed();
while (data.hasSkillBound(0))
data.unbindSkill(0);
while (data.hasPassiveSkillBound(0))
data.unbindPassiveSkill(0);
data.getQuestData().resetFinishedQuests();
data.getQuestData().start(null);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s data was succesfully reset.");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
} }
}
class ResetWaypointsCommandTreeNode extends CommandTreeNode { public static class ResetWaypointsCommandTreeNode extends CommandTreeNode {
public ResetWaypointsCommandTreeNode(CommandTreeNode parent) { public ResetWaypointsCommandTreeNode(CommandTreeNode parent) {
super(parent, "waypoints"); super(parent, "waypoints");
@ -79,7 +87,8 @@ class ResetWaypointsCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -87,17 +96,13 @@ class ResetWaypointsCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
resetWaypoints(PlayerData.get(player)); PlayerData data = PlayerData.get(player);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s waypoints were successfully reset."); data.getWaypoints().clear();
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
static void resetWaypoints(@NotNull PlayerData playerData) {
playerData.getWaypoints().clear();
}
} }
class ResetQuestsCommandTreeNode extends CommandTreeNode { public static class ResetQuestsCommandTreeNode extends CommandTreeNode {
public ResetQuestsCommandTreeNode(CommandTreeNode parent) { public ResetQuestsCommandTreeNode(CommandTreeNode parent) {
super(parent, "quests"); super(parent, "quests");
@ -106,7 +111,8 @@ class ResetQuestsCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -114,18 +120,14 @@ class ResetQuestsCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
resetQuests(PlayerData.get(player)); PlayerData data = PlayerData.get(player);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s quests were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetQuests(@NotNull PlayerData data) {
data.getQuestData().resetFinishedQuests(); data.getQuestData().resetFinishedQuests();
data.getQuestData().start(null); data.getQuestData().start(null);
return CommandResult.SUCCESS;
} }
} }
class ResetSkillsCommandTreeNode extends CommandTreeNode { public static class ResetSkillsCommandTreeNode extends CommandTreeNode {
public ResetSkillsCommandTreeNode(CommandTreeNode parent) { public ResetSkillsCommandTreeNode(CommandTreeNode parent) {
super(parent, "skills"); super(parent, "skills");
@ -134,7 +136,8 @@ class ResetSkillsCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -142,19 +145,18 @@ class ResetSkillsCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
resetSkills(PlayerData.get(player)); PlayerData data = PlayerData.get(player);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was successfully reset."); data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0))
data.unbindSkill(0);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was succesfully reset.");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
static void resetSkills(@NotNull PlayerData data) {
data.mapSkillLevels().forEach((skill, ignored) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0)) data.unbindSkill(0);
data.setUnlockedItems(new HashSet<>()); // TODO class-specific unlockables etc.
}
} }
class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
public static class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
public ResetSkillTreesCommandTreeNode(CommandTreeNode parent) { public ResetSkillTreesCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill-trees"); super(parent, "skill-trees");
@ -163,7 +165,8 @@ class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -171,18 +174,16 @@ class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
resetSkillTrees(PlayerData.get(player)); PlayerData data = PlayerData.get(player);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill-tree data was successfully reset."); for (SkillTree skillTree : data.getProfess().getSkillTrees())
data.resetSkillTree(skillTree);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill-tree data was succesfully reset.");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
// TODO option to reallocate skill tree points instead of not giving any back
static void resetSkillTrees(@NotNull PlayerData data) {
data.resetSkillTrees();
}
} }
class ResetAttributesCommandTreeNode extends CommandTreeNode { public class ResetAttributesCommandTreeNode extends CommandTreeNode {
public ResetAttributesCommandTreeNode(CommandTreeNode parent) { public ResetAttributesCommandTreeNode(CommandTreeNode parent) {
super(parent, "attributes"); super(parent, "attributes");
@ -192,7 +193,8 @@ class ResetAttributesCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -200,16 +202,12 @@ class ResetAttributesCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate"); PlayerData data = PlayerData.get(player);
resetAttributes(PlayerData.get(player), givePoints);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetAttributes(@NotNull PlayerData data, boolean givePoints) { /*
* force reallocating of player attribute points
// Give back attribute points */
if (givePoints) { if (args.length > 4 && args[4].equalsIgnoreCase("-reallocate")) {
int points = 0; int points = 0;
for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) { for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) {
@ -218,17 +216,19 @@ class ResetAttributesCommandTreeNode extends CommandTreeNode {
} }
data.giveAttributePoints(points); data.giveAttributePoints(points);
return; CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attribute points spendings were successfully reset.");
return CommandResult.SUCCESS;
} }
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) { data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
attribute.resetAdvancement(data, true); CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
data.getAttributes().getInstance(attribute).setBase(0); ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were succesfully reset.");
} return CommandResult.SUCCESS;
} }
} }
class ResetLevelsCommandTreeNode extends CommandTreeNode { public static class ResetLevelsCommandTreeNode extends CommandTreeNode {
public ResetLevelsCommandTreeNode(CommandTreeNode parent) { public ResetLevelsCommandTreeNode(CommandTreeNode parent) {
super(parent, "levels"); super(parent, "levels");
@ -237,7 +237,8 @@ class ResetLevelsCommandTreeNode extends CommandTreeNode {
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE; if (args.length < 4)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]); Player player = Bukkit.getPlayer(args[3]);
if (player == null) { if (player == null) {
@ -245,52 +246,19 @@ class ResetLevelsCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
resetLevels(PlayerData.get(player)); PlayerData data = PlayerData.get(player);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were successfully reset."); data.setLevel(MMOCore.plugin.dataProvider.getDataManager().getDefaultData().getLevel());
return CommandResult.SUCCESS;
}
static void resetLevels(@NotNull PlayerData data) {
// Class
data.setLevel(MMOCore.plugin.playerDataManager.getDefaultData().getLevel());
data.setExperience(0); data.setExperience(0);
data.getProfess().resetAdvancement(data, true);
// Professions
for (Profession profession : MMOCore.plugin.professionManager.getAll()) { for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0); data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0); data.getCollectionSkills().setLevel(profession, 0);
profession.resetAdvancement(data, true); profession.getExperienceTable().reset(data, profession);
}
}
} }
class ResetClassesCommandTreeNode extends CommandTreeNode { CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
public ResetClassesCommandTreeNode(CommandTreeNode parent) { ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were succesfully reset.");
super(parent, "classes");
addParameter(Parameter.PLAYER);
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
return CommandResult.FAILURE;
}
resetClasses(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s classes were successfully reset.");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
static void resetClasses(@NotNull PlayerData data) {
MMOCore.plugin.classManager.getAll().forEach(data::unloadClassInfo);
MMOCore.plugin.playerDataManager.getDefaultData().apply(data);
data.setClass(MMOCore.plugin.classManager.getDefaultClass());
} }
} }

View File

@ -5,7 +5,7 @@ import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger; import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -1,37 +0,0 @@
package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* Saves player data
*/
public class SaveDataTreeNode extends CommandTreeNode {
public SaveDataTreeNode(CommandTreeNode parent) {
super(parent, "savedata");
addParameter(Parameter.PLAYER);
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 3)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[2]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[2] + ".");
return CommandResult.FAILURE;
}
MMOCore.plugin.playerDataManager.getDataHandler().saveData(PlayerData.get(player), false);
return CommandResult.SUCCESS;
}
}

View File

@ -5,7 +5,7 @@ import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.ClassSkill;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -19,21 +19,19 @@ public class SkillCommandTreeNode extends CommandTreeNode {
public SkillCommandTreeNode(CommandTreeNode parent) { public SkillCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill"); super(parent, "skill");
addChild(new LockSkillCommandTreeNode(this, "lock", true)); addChild(new ActionCommandTreeNode(this, "give", (old, amount) -> old + amount));
addChild(new LockSkillCommandTreeNode(this, "unlock", false)); addChild(new ActionCommandTreeNode(this, "set", (old, amount) -> amount));
addChild(new LevelCommandTreeNode(this, "give", (old, amount) -> old + amount));
addChild(new LevelCommandTreeNode(this, "set", (old, amount) -> amount));
} }
public class LevelCommandTreeNode extends CommandTreeNode {
public class ActionCommandTreeNode extends CommandTreeNode {
private final BiFunction<Integer, Integer, Integer> change; private final BiFunction<Integer, Integer, Integer> change;
public LevelCommandTreeNode(CommandTreeNode parent, String type, BiFunction<Integer, Integer, Integer> change) { public ActionCommandTreeNode(CommandTreeNode parent, String type, BiFunction<Integer, Integer, Integer> change) {
super(parent, type); super(parent, type);
this.change = change; this.change = change;
addParameter(Parameter.PLAYER); addParameter(Parameter.PLAYER);
addParameter(new Parameter("<skill>", addParameter(new Parameter("<attribute>",
(explorer, list) -> MMOCore.plugin.skillManager.getAll().forEach(skill -> list.add(skill.getHandler().getId().toUpperCase())))); (explorer, list) -> MMOCore.plugin.skillManager.getAll().forEach(skill -> list.add(skill.getHandler().getId().toUpperCase()))));
addParameter(Parameter.AMOUNT); addParameter(Parameter.AMOUNT);
} }
@ -57,6 +55,7 @@ public class SkillCommandTreeNode extends CommandTreeNode {
} }
ClassSkill classSkill=null; ClassSkill classSkill=null;
for(ClassSkill var:playerData.getProfess().getSkills()) { for(ClassSkill var:playerData.getProfess().getSkills()) {
if(var.getSkill().equals(skill)) if(var.getSkill().equals(skill))
@ -68,6 +67,7 @@ public class SkillCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; return CommandResult.FAILURE;
} }
int amount; int amount;
try { try {
amount = Integer.parseInt(args[5]); amount = Integer.parseInt(args[5]);
@ -77,59 +77,12 @@ public class SkillCommandTreeNode extends CommandTreeNode {
} }
int value = change.apply(playerData.getSkillLevel(skill), amount); int value = change.apply(playerData.getSkillLevel(skill), amount);
playerData.setSkillLevel(skill, value); playerData.setSkillLevel(skill, value);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + player.getName() + ChatColor.YELLOW CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + player.getName() + ChatColor.YELLOW
+ " is now level " + ChatColor.GOLD + value + ChatColor.YELLOW + " for " + skill.getName() + "."); + " is now level " + ChatColor.GOLD + value + ChatColor.YELLOW + " for " + skill.getName() + ".");
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
} }
public class LockSkillCommandTreeNode extends CommandTreeNode {
private final boolean lock;
public LockSkillCommandTreeNode(CommandTreeNode parent, String id, boolean lock) {
super(parent, id);
this.lock = lock;
addParameter(Parameter.PLAYER);
addParameter(new Parameter("<skill>",
(explorer, list) -> MMOCore.plugin.skillManager.getAll().forEach(skill -> list.add(skill.getHandler().getId().toUpperCase()))));
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 5)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find player called " + args[3] + ".");
return CommandResult.FAILURE;
}
PlayerData playerData = PlayerData.get(player);
ClassSkill skill = playerData.getProfess().getSkill(args[4]);
if (skill == null) {
sender.sendMessage(ChatColor.RED + "Class doesn't have a skill called " + args[4] + ".");
return CommandResult.FAILURE;
}
if (lock) {
if (!playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "Skill " + skill.getSkill().getName() + " already locked for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.lock(skill);
} else {
if (playerData.hasUnlocked(skill)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "Skill " + skill.getSkill().getName() + " already unlocked for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.unlock(skill);
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "Skill " + ChatColor.GOLD + skill.getSkill().getName() + ChatColor.YELLOW + " now " + (lock ? "locked" : "unlocked") + " for " + ChatColor.GOLD + player.getName());
return CommandResult.SUCCESS;
}
}
@Override @Override
public CommandResult execute(CommandSender sender, String[] args) { public CommandResult execute(CommandSender sender, String[] args) {
return CommandResult.THROW_USAGE; return CommandResult.THROW_USAGE;

View File

@ -4,7 +4,7 @@ import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter; import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.util.TriConsumer; import net.Indyuce.mmocore.util.TriConsumer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;

View File

@ -1,159 +0,0 @@
package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.binding.BoundSkillInfo;
import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import net.Indyuce.mmocore.skill.ClassSkill;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class SlotCommandTreeNode extends CommandTreeNode {
public SlotCommandTreeNode(CommandTreeNode parent) {
super(parent, "slot");
addChild(new LockSlotCommandTreeNode(this, "lock", true));
addChild(new LockSlotCommandTreeNode(this, "unlock", false));
addChild(new UnbindSlotCommandTreeNode(this, "unbind"));
addChild(new BindSlotCommandTreeNode(this, "bind"));
}
public class LockSlotCommandTreeNode extends CommandTreeNode {
private final boolean lock;
public LockSlotCommandTreeNode(CommandTreeNode parent, String id, boolean lock) {
super(parent, id);
this.lock = lock;
addParameter(Parameter.PLAYER);
addParameter(Parameter.AMOUNT);
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 5)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
return CommandResult.FAILURE;
}
PlayerData playerData = PlayerData.get(player);
int slot;
try {
slot = Integer.parseInt(args[4]);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
return CommandResult.FAILURE;
}
if (slot <= 0) {
sender.sendMessage(ChatColor.RED + "The slot can't be negative.");
return CommandResult.FAILURE;
}
SkillSlot skillSlot = playerData.getProfess().getSkillSlot(slot);
if (skillSlot.isUnlockedByDefault()) {
sender.sendMessage(ChatColor.RED + "You can't lock a skill that is unlocked by default.");
return CommandResult.FAILURE;
}
if (lock) {
if (!playerData.hasUnlocked(skillSlot)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already locked" + " for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.lock(skillSlot);
} else {
if (playerData.hasUnlocked(skillSlot)) {
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already unlocked" + " for " + player.getName());
return CommandResult.SUCCESS;
}
playerData.unlock(skillSlot);
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "The skill slot " + skillSlot.getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
return CommandResult.SUCCESS;
}
}
public class BindSlotCommandTreeNode extends CommandTreeNode {
public BindSlotCommandTreeNode(CommandTreeNode parent, String id) {
super(parent, id);
addParameter(Parameter.PLAYER);
addParameter(Parameter.AMOUNT);
addParameter(new Parameter("<skill>",
(explorer, list) -> MMOCore.plugin.skillManager.getAll().forEach(skill -> list.add(skill.getHandler().getId().toUpperCase()))));
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 6)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
return CommandResult.FAILURE;
}
PlayerData playerData = PlayerData.get(player);
int slot;
try {
slot = Integer.parseInt(args[4]);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
return CommandResult.FAILURE;
}
ClassSkill skill = playerData.getProfess().getSkill(args[5]);
if (skill == null) {
sender.sendMessage(ChatColor.RED + "The player's class doesn't have a skill called " + args[5] + ".");
return CommandResult.FAILURE;
}
playerData.bindSkill(slot, skill);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + "Skill " + ChatColor.GOLD + skill.getSkill().getHandler().getId() + ChatColor.YELLOW + " now bound to slot " + ChatColor.GOLD + slot);
return CommandResult.SUCCESS;
}
}
public class UnbindSlotCommandTreeNode extends CommandTreeNode {
public UnbindSlotCommandTreeNode(CommandTreeNode parent, String id) {
super(parent, id);
addParameter(Parameter.PLAYER);
addParameter(Parameter.AMOUNT);
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 5)
return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
return CommandResult.FAILURE;
}
PlayerData playerData = PlayerData.get(player);
int slot;
try {
slot = Integer.parseInt(args[4]);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
return CommandResult.FAILURE;
}
final BoundSkillInfo found = playerData.unbindSkill(slot);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.YELLOW + (found != null ?
"Skill " + ChatColor.GOLD + found.getClassSkill().getSkill().getName() + ChatColor.YELLOW + " was taken off the slot " + ChatColor.GOLD + slot :
"Could not find skill at slot " + ChatColor.GOLD + slot));
return CommandResult.SUCCESS;
}
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
return CommandResult.THROW_USAGE;
}
}

View File

@ -49,7 +49,7 @@ public class CreateCommandTreeNode extends CommandTreeNode {
if (args[2].equalsIgnoreCase("main")) { if (args[2].equalsIgnoreCase("main")) {
MMOCore.plugin.boosterManager.register(new Booster(args.length > 5 ? args[5] : null, extra, length)); MMOCore.plugin.boosterManager.register(new Booster(args.length > 5 ? args[5] : null, extra, length));
ConfigMessage.fromKey("booster-main").addPlaceholders("multiplier", "" + (1 + extra)).send(Bukkit.getOnlinePlayers()); new ConfigMessage("booster-main").addPlaceholders("multiplier", "" + (1 + extra)).send(Bukkit.getOnlinePlayers());
Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1)); Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1));
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
@ -62,7 +62,7 @@ public class CreateCommandTreeNode extends CommandTreeNode {
Profession profession = MMOCore.plugin.professionManager.get(format); Profession profession = MMOCore.plugin.professionManager.get(format);
MMOCore.plugin.boosterManager.register(new Booster(args.length > 5 ? args[5] : null, profession, extra, length)); MMOCore.plugin.boosterManager.register(new Booster(args.length > 5 ? args[5] : null, profession, extra, length));
ConfigMessage.fromKey("booster-skill").addPlaceholders("multiplier", "" + (1 + extra), "profession", profession.getName()) new ConfigMessage("booster-skill").addPlaceholders("multiplier", "" + (1 + extra), "profession", profession.getName())
.send(Bukkit.getOnlinePlayers()); .send(Bukkit.getOnlinePlayers());
Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1)); Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1));
return CommandResult.SUCCESS; return CommandResult.SUCCESS;

View File

@ -33,7 +33,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):"); sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) { for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key); StatModifier mod = instance.getModifier(key);
sender.sendMessage("-> '" + key + "' " + mod.getValue() + " " + mod.getType().name() + " " + mod.getSlot() + " " + mod.getSource()); sender.sendMessage("- " + key + ": " + mod.getValue() + " " + mod.getType().name());
} }
return CommandResult.SUCCESS; return CommandResult.SUCCESS;

View File

@ -4,7 +4,7 @@ import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter; import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.api.CommandVerbose; import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.Waypoint;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;

View File

@ -4,7 +4,7 @@ import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig; import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata; import io.lumine.mythic.api.drops.DropMetadata;
import io.lumine.mythic.api.drops.IItemDrop; import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.BukkitAdapter; import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop; import io.lumine.mythic.core.drops.Drop;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder; import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
@ -27,8 +27,7 @@ public class CurrencyItemDrop extends Drop implements IItemDrop {
@Override @Override
public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) { public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
// Not great wrt to performance. Should build the item like MM does return new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build());
return BukkitAdapter.adapt(new CurrencyItemBuilder(key, random(minw, maxw)).build());
} }
private int random(int a, int b) { private int random(int a, int b) {

View File

@ -4,7 +4,7 @@ import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig; import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata; import io.lumine.mythic.api.drops.DropMetadata;
import io.lumine.mythic.api.drops.IItemDrop; import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.BukkitAdapter; import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop; import io.lumine.mythic.core.drops.Drop;
import io.lumine.mythic.lib.api.item.ItemTag; import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.item.NBTItem;
@ -49,8 +49,7 @@ public class GoldPouchDrop extends Drop implements IItemDrop {
} }
nbt.addTag(new ItemTag("RpgPouchSize", 18), new ItemTag("RpgPouchMob", true), new ItemTag("RpgPouchInventory", MMOCoreUtils.toBase64(content))); nbt.addTag(new ItemTag("RpgPouchSize", 18), new ItemTag("RpgPouchMob", true), new ItemTag("RpgPouchInventory", MMOCoreUtils.toBase64(content)));
// Not great wrt to performance. Should build the item like MM does return new BukkitItemStack(nbt.toItem());
return BukkitAdapter.adapt(nbt.toItem());
} }
private ItemStack setAmount(ItemStack item, int amount) { private ItemStack setAmount(ItemStack item, int amount) {

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.comp.placeholder; package net.Indyuce.mmocore.comp.placeholder;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
@ -8,9 +7,7 @@ import io.lumine.mythic.lib.MythicLib;
public class DefaultParser implements PlaceholderParser { public class DefaultParser implements PlaceholderParser {
@Override @Override
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
public String parse(OfflinePlayer player, String string) { public String parse(OfflinePlayer player, String string) {
// TODO remove use of confusing non-PAPI %player% placeholder
return MythicLib.plugin.parseColors(string.replace("%player%", player.getName())); return MythicLib.plugin.parseColors(string.replace("%player%", player.getName()));
} }
} }

View File

@ -1,30 +1,22 @@
package net.Indyuce.mmocore.comp.placeholder; package net.Indyuce.mmocore.comp.placeholder;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.util.AltChar; import io.lumine.mythic.lib.api.util.AltChar;
import io.lumine.mythic.lib.manager.StatManager; import io.lumine.mythic.lib.manager.StatManager;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.api.quest.PlayerQuests;
import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.party.AbstractParty; import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.skill.CastableSkill;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
import java.util.UUID;
public class RPGPlaceholders extends PlaceholderExpansion { public class RPGPlaceholders extends PlaceholderExpansion {
@ -53,63 +45,27 @@ public class RPGPlaceholders extends PlaceholderExpansion {
return MMOCore.plugin.getDescription().getVersion(); return MMOCore.plugin.getDescription().getVersion();
} }
private static final String ERROR_PLACEHOLDER = " ";
@SuppressWarnings("DuplicateExpressions") @SuppressWarnings("DuplicateExpressions")
@Override @Override
public String onRequest(OfflinePlayer player, String identifier) { public String onRequest(OfflinePlayer player, String identifier) {
if (!PlayerData.has(player.getUniqueId())) if (!PlayerData.has(player.getUniqueId()))
return null; return null;
final PlayerData playerData = PlayerData.get(player);
PlayerData playerData = PlayerData.get(player);
if (identifier.equals("mana_icon")) if (identifier.equals("mana_icon"))
return playerData.getProfess().getManaDisplay().getIcon(); return playerData.getProfess().getManaDisplay().getIcon();
if (identifier.equals("mana_name")) if (identifier.equals("mana_name"))
return playerData.getProfess().getManaDisplay().getName(); return playerData.getProfess().getManaDisplay().getName();
if (identifier.equals("level")) if (identifier.equals("level"))
return String.valueOf(playerData.getLevel()); return "" + playerData.getLevel();
else if (identifier.startsWith("skill_level_")) { else if (identifier.startsWith("skill_level_")) {
String id = identifier.substring(12); String id = identifier.substring(12);
RegisteredSkill skill = MMOCore.plugin.skillManager.getSkillOrThrow(id); RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(id), "Could not find skill with ID '" + id + "'");
return String.valueOf(playerData.getSkillLevel(skill)); return String.valueOf(playerData.getSkillLevel(skill));
} }
/*
* Given a skill slot number (integer) and a parameter name,
* return the player's value of that skill parameter from that
* specific skill slot.
*/
else if (identifier.startsWith("bound_skill_parameter_")) {
final String[] ids = identifier.substring(22).split(":");
final String parameterId = ids[0];
final int skillSlot = Integer.parseInt(ids[1]);
final ClassSkill found = playerData.getBoundSkill(skillSlot);
if (found == null) return "";
final CastableSkill castable = found.toCastable(playerData);
final double value = playerData.getMMOPlayerData().getSkillModifierMap().calculateValue(castable, parameterId);
return MythicLib.plugin.getMMOConfig().decimal.format(value);
}
// Returns a player's value of a skill parameter.
else if (identifier.startsWith("skill_modifier_") || identifier.startsWith("skill_parameter_")) {
final String[] ids = identifier.substring(identifier.startsWith("skill_modifier_") ? 15 : 16).split(":");
final String parameterId = ids[0];
final String skillId = ids[1];
final RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(skillId), "Could not find skill with ID '" + skillId + "'");
final CastableSkill castable = playerData.getProfess().getSkill(skill).toCastable(playerData);
final double value = playerData.getMMOPlayerData().getSkillModifierMap().calculateValue(castable, parameterId);
return MythicLib.plugin.getMMOConfig().decimal.format(value);
}
else if (identifier.startsWith("attribute_points_spent_")) {
final String attributeId = identifier.substring(23);
final PlayerAttributes.AttributeInstance attributeInstance = Objects.requireNonNull(playerData.getAttributes().getInstance(attributeId), "Could not find attribute with ID '" + attributeId + "'");
return String.valueOf(attributeInstance.getBase());
}
else if (identifier.equals("level_percent")) { else if (identifier.equals("level_percent")) {
double current = playerData.getExperience(), next = playerData.getLevelUpExperience(); double current = playerData.getExperience(), next = playerData.getLevelUpExperience();
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100); return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
@ -127,7 +83,9 @@ public class RPGPlaceholders extends PlaceholderExpansion {
for (double j = 1; j < 20; j++) for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.RED : ratio >= j - .5 ? ChatColor.DARK_RED : ChatColor.DARK_GRAY).append(AltChar.listSquare); format.append(ratio >= j ? ChatColor.RED : ratio >= j - .5 ? ChatColor.DARK_RED : ChatColor.DARK_GRAY).append(AltChar.listSquare);
return format.toString(); return format.toString();
} else if (identifier.equals("class")) }
else if (identifier.equals("class"))
return playerData.getProfess().getName(); return playerData.getProfess().getName();
else if (identifier.startsWith("profession_percent_")) { else if (identifier.startsWith("profession_percent_")) {
@ -136,92 +94,34 @@ public class RPGPlaceholders extends PlaceholderExpansion {
Profession profession = MMOCore.plugin.professionManager.get(name); Profession profession = MMOCore.plugin.professionManager.get(name);
double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession); double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession);
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100); return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
}
} else if (identifier.equals("is_casting")) else if (identifier.startsWith("is_casting")) {
return String.valueOf(playerData.isCasting()); return String.valueOf(playerData.isCasting());
} else if (identifier.startsWith("in_combat")) {
else if (identifier.equals("in_combat"))
return String.valueOf(playerData.isInCombat()); return String.valueOf(playerData.isInCombat());
else if (identifier.equals("pvp_mode"))
return String.valueOf(playerData.getCombat().isInPvpMode());
else if (identifier.startsWith("since_enter_combat"))
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastEntry()) / 1000.) : "-1";
else if (identifier.startsWith("invulnerability_left"))
return MythicLib.plugin.getMMOConfig().decimal.format(Math.max(0, (playerData.getCombat().getInvulnerableTill() - System.currentTimeMillis()) / 1000.));
else if (identifier.startsWith("since_last_hit"))
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastHit()) / 1000.) : "-1";
// Returns the bound skill ID
else if (identifier.startsWith("id_bound_")) {
final int slot = Math.max(1, Integer.parseInt(identifier.substring(9)));
final ClassSkill info = playerData.getBoundSkill(slot);
return info == null ? "" : info.getSkill().getHandler().getId();
} }
// Returns the casting slot taking into account the skill slot offset
else if (identifier.startsWith("cast_slot_offset_")) {
final Player online = player.getPlayer();
Validate.notNull(online, "Player is offline");
final int slot = Integer.parseInt(identifier.substring(17));
return String.valueOf(slot + (online.getInventory().getHeldItemSlot() < slot ? 1 : 0));
}
// Is there a passive skill bound to given slot
else if (identifier.startsWith("passive_bound_")) {
final int slot = Integer.parseInt(identifier.substring(14));
final ClassSkill skill = playerData.getBoundSkill(slot);
return String.valueOf(skill != null && skill.getSkill().getTrigger().isPassive());
}
// Returns the bound skill name
else if (identifier.startsWith("bound_")) { else if (identifier.startsWith("bound_")) {
final int slot = Math.max(1, Integer.parseInt(identifier.substring(6))); int slot = Math.max(0, Integer.parseInt(identifier.substring(6)) - 1);
final ClassSkill skill = playerData.getBoundSkill(slot); return playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getName()
if (skill == null) return MMOCore.plugin.configManager.noSkillBoundPlaceholder; : MMOCore.plugin.configManager.noSkillBoundPlaceholder;
return (playerData.getCooldownMap().isOnCooldown(skill) ? ChatColor.RED : ChatColor.GREEN) + skill.getSkill().getName();
} }
// Returns cooldown of skill bound at given slot else if (identifier.startsWith("profession_experience_"))
else if (identifier.startsWith("cooldown_bound_")) {
int slot = Math.max(0, Integer.parseInt(identifier.substring(15)));
if (playerData.hasSkillBound(slot))
return Double.toString(playerData.getCooldownMap().getCooldown(playerData.getBoundSkill(slot)));
else return MMOCore.plugin.configManager.noSkillBoundPlaceholder;
} else if (identifier.startsWith("profession_experience_"))
return MythicLib.plugin.getMMOConfig().decimal.format( return MythicLib.plugin.getMMOConfig().decimal.format(
playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase())); playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.startsWith("profession_next_level_")) else if (identifier.startsWith("profession_next_level_"))
return String.valueOf(PlayerData.get(player).getCollectionSkills() return "" + PlayerData.get(player).getCollectionSkills()
.getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase())); .getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase());
else if (identifier.startsWith("party_count")) { else if (identifier.startsWith("party_count")) {
final @Nullable AbstractParty party = playerData.getParty(); AbstractParty party = playerData.getParty();
return party == null ? "0" : String.valueOf(party.countMembers()); return party == null ? "0" : String.valueOf(party.countMembers());
} else if (identifier.startsWith("party_member_")) { }
final int n = Integer.parseInt(identifier.substring(13)) - 1;
final @Nullable AbstractParty party = playerData.getParty(); else if (identifier.startsWith("profession_"))
if (party == null) return ERROR_PLACEHOLDER;
if (n >= party.countMembers()) return ERROR_PLACEHOLDER;
final @Nullable PlayerData member = party.getMember(n);
if (member == null) return ERROR_PLACEHOLDER;
return member.getPlayer().getName();
} else if (identifier.equals("online_friends")) {
int count = 0;
for (UUID friendId : playerData.getFriends())
if (Bukkit.getPlayer(friendId) != null) count++;
return String.valueOf(count);
} else if (identifier.startsWith("online_friend_")) {
final int n = Integer.parseInt(identifier.substring(14)) - 1;
if (n >= playerData.getFriends().size()) return ERROR_PLACEHOLDER;
final @Nullable Player friend = Bukkit.getPlayer(playerData.getFriends().get(n));
if (friend == null) return ERROR_PLACEHOLDER;
return friend.getName();
} else if (identifier.startsWith("profession_"))
return String return String
.valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase())); .valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase()));
@ -250,18 +150,23 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (identifier.equals("mana")) else if (identifier.equals("mana"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana()); return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
else if (identifier.equals("mana_bar")) else if (identifier.equals("mana_bar")) {
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA")); return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
}
else if (identifier.startsWith("exp_multiplier_")) { else if (identifier.startsWith("exp_multiplier_")) {
String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-"); String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format); Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100); return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100);
} else if (identifier.startsWith("exp_boost_")) { }
else if (identifier.startsWith("exp_boost_")) {
String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-"); String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format); Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100); return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100);
} else if (identifier.equals("stamina")) }
else if (identifier.equals("stamina"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina()); return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina());
else if (identifier.equals("stamina_bar")) { else if (identifier.equals("stamina_bar")) {
@ -272,10 +177,14 @@ public class RPGPlaceholders extends PlaceholderExpansion {
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty) : ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
.append(AltChar.listSquare); .append(AltChar.listSquare);
return format.toString(); return format.toString();
} else if (identifier.startsWith("stat_")) { }
final String stat = UtilityMethods.enumName(identifier.substring(5));
return StatManager.format(stat, playerData.getMMOPlayerData()); else if (identifier.startsWith("stat_")) {
} else if (identifier.equals("stellium")) final String stat = identifier.substring(5).toUpperCase();
return StatManager.format(identifier.substring(5), playerData.getStats().getStat(stat));
}
else if (identifier.equals("stellium"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium()); return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium());
else if (identifier.equals("stellium_bar")) { else if (identifier.equals("stellium_bar")) {
@ -284,17 +193,26 @@ public class RPGPlaceholders extends PlaceholderExpansion {
for (double j = 1; j < 20; j++) for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare); format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
return format.toString(); return format.toString();
} else if (identifier.equals("quest")) { }
else if (identifier.equals("quest")) {
PlayerQuests data = playerData.getQuestData(); PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None"; return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None";
} else if (identifier.equals("quest_progress")) { }
else if (identifier.equals("quest_progress")) {
PlayerQuests data = playerData.getQuestData(); PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal
.format( (double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0"; .format( (double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0";
} else if (identifier.equals("quest_objective")) { }
else if (identifier.equals("quest_objective")) {
PlayerQuests data = playerData.getQuestData(); PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None"; return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None";
} else if (identifier.startsWith("guild_")) { }
else if (identifier.startsWith("guild_")) {
String placeholder = identifier.substring(6); String placeholder = identifier.substring(6);
if (playerData.getGuild() == null) if (playerData.getGuild() == null)
return ""; return "";

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