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".
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.
This project is owned and maintained by PhoenixDvpt and is distributed with "All Right's Reserved".
Things can you CANNOT do:
- 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.
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.

View File

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

View File

@ -2,15 +2,14 @@ package net.Indyuce.mmocore;
import io.lumine.mythic.lib.MythicLib;
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 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.profess.resource.PlayerResource;
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
import net.Indyuce.mmocore.command.api.ToggleableCommand;
import net.Indyuce.mmocore.command.*;
import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener;
import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader;
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.WorldGuardMMOLoader;
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.VaultMMOLoader;
import net.Indyuce.mmocore.guild.GuildModule;
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.MMOCoreGuildModule;
import net.Indyuce.mmocore.guild.provided.YAMLGuildDataManager;
import net.Indyuce.mmocore.manager.*;
import net.Indyuce.mmocore.manager.data.DataProvider;
import net.Indyuce.mmocore.manager.data.GuildDataManager;
import net.Indyuce.mmocore.manager.data.LegacyDataProvider;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
import net.Indyuce.mmocore.manager.data.yaml.YAMLDataProvider;
import net.Indyuce.mmocore.manager.profession.*;
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.party.MMOCoreTargetRestriction;
import net.Indyuce.mmocore.party.PartyModule;
import net.Indyuce.mmocore.party.PartyModuleType;
import net.Indyuce.mmocore.party.PartyRelationHandler;
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.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.bukkit.Bukkit;
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.jetbrains.annotations.NotNull;
import java.io.File;
import java.lang.reflect.Field;
import java.util.logging.Level;
public class MMOCore extends MMOPlugin {
public class MMOCore extends JavaPlugin {
public static MMOCore plugin;
public final WaypointManager waypointManager = new WaypointManager();
public final SoundManager soundManager = new SoundManager();
public final RequestManager requestManager = new RequestManager();
@ -82,10 +79,6 @@ public class MMOCore extends MMOPlugin {
public final RestrictionManager restrictionManager = new RestrictionManager();
public final SkillTreeManager skillTreeManager = new SkillTreeManager();
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
public final CustomBlockManager mineManager = new CustomBlockManager();
@ -99,11 +92,13 @@ public class MMOCore extends MMOPlugin {
public VaultEconomy economy;
public RegionHandler regionHandler = new DefaultRegionHandler();
public PlaceholderParser placeholderParser = new DefaultParser();
public DataProvider dataProvider = new YAMLDataProvider();
// Modules
@NotNull
public PartyModule partyModule;
public GuildModule guildModule;
public boolean shouldDebugSQL = false;
public MMOCore() {
plugin = this;
@ -111,13 +106,10 @@ public class MMOCore extends MMOPlugin {
@Override
public void onLoad() {
getLogger().log(Level.INFO, "Plugin file is called '" + getFile().getName() + "'");
// Register MMOCore-specific objects
MythicLib.plugin.getEntities().registerRelationHandler(new PartyRelationHandler());
MythicLib.plugin.getEntities().registerRelationHandler(new GuildRelationHandler());
MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction());
MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject));
MMOCoreTriggerType.registerAll();
// Custom scripts
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 + "')");
}
if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled")) {
final SQLDataSource dataSource = new SQLDataSource(this);
playerDataManager.setDataHandler(new SQLDataHandler(dataSource));
}
if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled"))
dataProvider = new MySQLDataProvider(getConfig());
shouldDebugSQL = getConfig().getBoolean("mysql.debug");
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();
@ -173,8 +164,6 @@ public class MMOCore extends MMOPlugin {
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
regionHandler = new WorldGuardRegionHandler();
if (getConfig().getBoolean("pvp_mode.enabled"))
Bukkit.getPluginManager().registerEvents(new PvPModeListener(), this);
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
* will make the 'respawn' button glitched plus HURT entity effect bug
* Resource regeneration. Must check if entity is dead otherwise regen will make
* the 'respawn' button glitched plus HURT entity effect bug
*/
new BukkitRunnable() {
public void run() {
@ -207,6 +196,8 @@ public class MMOCore extends MMOPlugin {
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 + "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;
}
@ -216,10 +207,9 @@ public class MMOCore extends MMOPlugin {
try {
String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin"));
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();
getLogger().log(Level.INFO, "Hooked parties onto " + moduleType.getPluginName());
} catch (Throwable exception) {
} catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage());
partyModule = new MMOCorePartyModule();
}
@ -230,7 +220,6 @@ public class MMOCore extends MMOPlugin {
GuildModuleType moduleType = GuildModuleType.valueOf(pluginName);
Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
guildModule = moduleType.provideModule();
getLogger().log(Level.INFO, "Hooked guilds onto " + moduleType.getPluginName());
} catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not initialize guild module: " + exception.getMessage());
guildModule = new MMOCoreGuildModule();
@ -238,8 +227,8 @@ public class MMOCore extends MMOPlugin {
// Skill casting
try {
final SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
mode.setCurrent(getConfig().getConfigurationSection("skill-casting"));
SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
Bukkit.getPluginManager().registerEvents(mode.loadFromConfig(getConfig().getConfigurationSection("skill-casting")), this);
} catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage());
}
@ -248,7 +237,6 @@ public class MMOCore extends MMOPlugin {
try {
Class.forName("net.Indyuce.mmocore.MMOCoreBukkit").getConstructor(MMOCore.class).newInstance(this);
} catch (Throwable exception) {
exception.printStackTrace();
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
* 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
nativeGuildManager.load();
dataProvider.getGuildManager().load();
// Toggleable Commands
ToggleableCommand.register();
// Command
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();
getCommand("mmocore").setExecutor(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
public void onDisable() {
// Save guild info
for (Guild guild : nativeGuildManager.getAll())
nativeGuildManager.save(guild);
//Executes all the pending asynchronous task (like saving the playerData)
Bukkit.getScheduler().getPendingTasks().forEach(worker -> {
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
playerDataManager.close();
// Save guild info
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
mineManager.resetRemainingBlocks();
@ -303,6 +357,8 @@ public class MMOCore extends MMOPlugin {
configManager = new ConfigManager();
if (clearBefore)
MythicLib.plugin.getSkills().initialize(true);
skillManager.initialize(clearBefore);
mineManager.initialize(clearBefore);
partyManager.initialize(clearBefore);
@ -316,6 +372,7 @@ public class MMOCore extends MMOPlugin {
statManager.initialize(clearBefore);
professionManager.initialize(clearBefore);
InventoryManager.load();
skillTreeManager.initialize(clearBefore);
classManager.initialize(clearBefore);
questManager.initialize(clearBefore);
@ -325,14 +382,12 @@ public class MMOCore extends MMOPlugin {
requestManager.initialize(clearBefore);
soundManager.initialize(clearBefore);
configItems.initialize(clearBefore);
//Needs to be loaded after the class manager.
InventoryManager.load();
if (getConfig().isConfigurationSection("action-bar"))
actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));
if (clearBefore)
PlayerData.getAll().forEach(PlayerData::reload);
PlayerData.getAll().forEach(PlayerData::update);
}
public static void log(String message) {
@ -350,4 +405,9 @@ public class MMOCore extends MMOPlugin {
public boolean hasEconomy() {
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 net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.Validate;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
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.List;
public class ConfigMessage {
private final String key;
private final List<String> lines = new ArrayList<>();
private final boolean papiPlaceholders, actionbar, raw;
private final List<String> messages;
private ConfigMessage(@NotNull String key) {
this.key = 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
boolean hasPlaceholders = false;
for (String str : lines)
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("["));
public ConfigMessage(String key) {
messages = MMOCore.plugin.configManager.getMessage(key);
}
/**
* 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
public ConfigMessage addPlaceholders(String... placeholders) {
for (int n = 0; n < messages.size(); n++) {
String line = messages.get(n);
for (int j = 0; j < placeholders.length - 1; j += 2) {
final String placeholder = String.valueOf(placeholders[j]);
line = line.replace("{" + placeholder + "}", String.valueOf(placeholders[j + 1]));
String placeholder = placeholders[j];
if (line.contains("{" + placeholder + "}"))
line = line.replace("{" + placeholder + "}", placeholders[j + 1]);
}
lines.set(n, line);
messages.set(n, line);
}
return this;
}
@Deprecated
public void sendAsJSon(Player player) {
send(player);
}
public void send(Player player) {
for (String line : lines) send(player, line);
public void send(CommandSender sender) {
messages.forEach(line -> sender.sendMessage(format(sender, line)));
}
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))));
}
/**
* Sends a line of text to a target player
*
* @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
if (this.raw) {
if (actionbar) MythicLib.plugin.getVersion().getWrapper().sendActionBarRaw(player, rawMessage);
else MythicLib.plugin.getVersion().getWrapper().sendJson(player, rawMessage);
} else {
if (actionbar)
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(rawMessage));
else player.sendMessage(rawMessage);
}
public void sendAsJSon(Player player) {
messages.forEach(line -> MythicLib.plugin.getVersion().getWrapper().sendJson(player, format(player, line)));
}
@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;
private String format(CommandSender sender, String input) {
String str = MythicLib.plugin.parseColors(input);
return sender instanceof Player ? MMOCore.plugin.placeholderParser.parse((OfflinePlayer) sender, str) : str;
}
}

View File

@ -25,7 +25,7 @@ public class MMOCoreAPI {
}
public PlayerData getPlayerData(OfflinePlayer player) {
return PlayerData.get(player);
return PlayerData.get(player.getUniqueId());
}
public boolean isInSameParty(Player player1, Player player2) {
@ -65,7 +65,7 @@ public class MMOCoreAPI {
public SkillResult cast(PlayerData playerData, ClassSkill skill) {
PlayerMetadata casterMeta = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
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_CHARGE,
WARP_UNLOCK,
HOTBAR_SWAP,
SPELL_CAST_BEGIN,
SPELL_CAST_END,
CANT_SELECT_CLASS,
SELECT_CLASS,
LEVEL_ATTRIBUTE,
RESET_ATTRIBUTES,
RESET_SKILLS,
NOT_ENOUGH_POINTS,
RESET_SKILLS
,NOT_ENOUGH_POINTS,
CANCEL_QUEST,
START_QUEST,
CLOSE_LOOT_CHEST,

View File

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

View File

@ -43,7 +43,7 @@ public class BlockInfo {
options.put(option, config.getBoolean("options." + key));
} catch (IllegalArgumentException exception) {
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")) {
@ -55,7 +55,7 @@ public class BlockInfo {
triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) {
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)
conditions.add((BlockCondition) condition);
}
}
public boolean getOption(BlockInfoOption option) {
return options.getOrDefault(option, option.getDefault());
}
@NotNull
public BlockType getBlock() {
return block;
}
@ -85,7 +85,6 @@ public class BlockInfo {
return table != null;
}
@Deprecated
public List<ItemStack> collectDrops(LootBuilder builder) {
return table != null ? table.collect(builder) : new ArrayList<>();
}

View File

@ -1,31 +1,29 @@
package net.Indyuce.mmocore.api.block;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface BlockType {
/**
* Called when placing temporary blocks
*/
void place(@NotNull BlockInfo.RegeneratingBlock placed);
/**
* Called when placing temporary blocks
*/
void place(BlockInfo.RegeneratingBlock placed);
/**
* Called when regenerating an older block with block regen
*/
void regenerate(@NotNull BlockInfo.RegeneratingBlock regenerating);
/**
* Called when regenerating an older block with block regen
*/
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
* broken. This method is used to prevent non mature crops from being broken
* for example
*/
boolean breakRestrictions(@NotNull Block block);
int hashCode();
boolean equals(@Nullable Object obj);
/**
* 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
* for example
*/
boolean breakRestrictions(Block block);
}

View File

@ -1,73 +1,59 @@
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 org.bukkit.Location;
import org.bukkit.Material;
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 {
private final String value;
private final String value;
public SkullBlockType(MMOLineConfig config) {
config.validate("value");
public SkullBlockType(MMOLineConfig config) {
config.validate("value");
value = config.getString("value");
}
value = config.getString("value");
}
public SkullBlockType(Block block) {
value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
}
public SkullBlockType(Block block) {
value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
}
public String getValue() {
return value;
}
public String getValue() {
return value;
}
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(Material.PLAYER_HEAD);
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(VersionMaterial.PLAYER_HEAD.toMaterial());
// save skull orientation if replaced block is a player head
if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
loc.getBlock().setBlockData(block.getBlockData());
// save skull orientation if replaced block is a player head
if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
// This makes sure that if a skull loses its original rotation
// it can revert back to it when the base block is regenerated
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
// This makes sure that if a skull loses its original rotation
// it can revert back to it when the base block is regenerated
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public String display() {
return "Skull{" + value + "}";
}
@Override
public String generateKey() {
return "vanilla-skull-" + value;
}
@Override
public boolean breakRestrictions(Block block) {
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);
}
@Override
public boolean breakRestrictions(Block block) {
return true;
}
}

View File

@ -1,7 +1,5 @@
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.bukkit.Location;
import org.bukkit.Material;
@ -9,75 +7,63 @@ import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
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 {
private final Material type;
private final Material type;
/*
* allows to plant back crops with a custom age so that it does not always
* have to full grow again-
*/
private final int age;
/*
* allows to plant back crops with a custom age so that it does not always
* have to full grow again-
*/
private final int age;
public VanillaBlockType(MMOLineConfig config) {
config.validate("type");
public VanillaBlockType(MMOLineConfig config) {
config.validate("type");
type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
age = config.getInt("age", 0);
type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
age = config.getInt("age", 0);
Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
}
Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
}
public VanillaBlockType(Block block) {
type = block.getType();
age = 0;
}
public VanillaBlockType(Block block) {
type = block.getType();
age = 0;
}
public Material getType() {
return type;
}
public Material getType() {
return type;
}
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
block.getLocation().getBlock().setType(type);
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
block.getLocation().getBlock().setType(type);
BlockData state = block.getLocation().getBlock().getBlockData();
if (age > 0 && state instanceof Ageable) {
((Ageable) state).setAge(age);
loc.getBlock().setBlockData(state);
}
}
BlockData state = block.getLocation().getBlock().getBlockData();
if (age > 0 && state instanceof Ageable) {
((Ageable) state).setAge(age);
loc.getBlock().setBlockData(state);
}
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(type);
// Sets the original blocks old data (only when regenerating)
loc.getBlock().setBlockData(block.getBlockData());
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(type);
// Sets the original blocks old data (only when regenerating)
loc.getBlock().setBlockData(block.getBlockData());
}
@Override
public String display() {
return "Vanilla{" + type.name() + "}";
}
@Override
public String generateKey() {
return "vanilla-block-" + type.name();
}
@Override
public boolean breakRestrictions(Block block) {
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);
}
@Override
public boolean breakRestrictions(Block block) {
return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
}
}

View File

@ -5,7 +5,6 @@ import java.util.Set;
import java.util.UUID;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
@ -29,7 +28,7 @@ public class Withdraw implements Listener {
public Withdraw(Player player) {
this.player = player;
}
public Player getPlayer() {
return player;
}
@ -39,7 +38,7 @@ public class Withdraw implements Listener {
return;
withdrawing.add(player.getUniqueId());
ConfigMessage.fromKey("withdrawing").send(player);
MMOCore.plugin.configManager.getSimpleMessage("withdrawing").send(player);
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, 20 * 20);
}
@ -61,7 +60,7 @@ public class Withdraw implements Listener {
if (!event.getPlayer().equals(player))
return;
ConfigMessage.fromKey("withdraw-cancel").send(player);
MMOCore.plugin.configManager.getSimpleMessage("withdraw-cancel").send(player);
close();
}
@ -76,13 +75,13 @@ public class Withdraw implements Listener {
try {
worth = Integer.parseInt(event.getMessage());
} 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;
}
int left = (int) (MMOCore.plugin.economy.getEconomy().getBalance(player) - worth);
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;
}
@ -92,7 +91,7 @@ public class Withdraw implements Listener {
MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, worth);
withdrawAlgorythm(worth);
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;
/**
* @deprecated Use {@link io.lumine.mythic.lib.api.event.SynchronizedDataLoadEvent} instead
* @deprecated Use {@link AsyncPlayerDataLoadEvent} instead
*/
@Deprecated
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;
}
public UpdateReason getReason() {
return reason;
}
/**
* 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) {
if (config.getKey().equals("from"))
return new FromTrigger(config);
if (config.getKey().equals("stat"))
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"))
return new MessageTrigger(config);
if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
return new SoundTrigger(config);
@ -119,12 +101,6 @@ public class DefaultMMOLoader extends MMOLoader {
if (config.getKey().equals("permission"))
return new PermissionCondition(config);
if (config.getKey().equals("weather"))
return new WeatherCondition(config);
if (config.getKey().equals("time"))
return new TimeCondition(config);
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;
/**
* Used by MMOCore when it has to store the last time a player
* did some action. This also features a time out function which
* can be used for cooldowns.
*
* @deprecated Merge with {@link io.lumine.mythic.lib.player.cooldown.CooldownMap}
* Used by MMOCore when it has to store the last time
* a player did some action.
* <p>
* This also features a time out function which can
* be used for cooldowns
*/
public enum PlayerActivity {
USE_WAYPOINT(() -> 5 * 1000L),
@ -21,9 +21,7 @@ public enum PlayerActivity {
LOOT_CHEST_SPAWN(() -> MMOCore.plugin.configManager.lootChestPlayerCooldown),
CAST_SKILL(() -> MMOCore.plugin.configManager.globalSkillCooldown),
;
CAST_SKILL(() -> MMOCore.plugin.configManager.globalSkillCooldown);
private final Provider<Long> timeout;

View File

@ -1,30 +1,36 @@
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.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.ModifierType;
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
import io.lumine.mythic.lib.util.configobject.ConfigObject;
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 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)
*/
public AttributeModifier(String key, String attribute, double value) {
super(key, value);
this.attribute = attribute;
this(key, attribute, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER);
}
/**
* Attribute modifier given by an external mechanic, like a party buff, item
* set bonuses, skills or abilities... Anything apart from items and armor.
* Attribute modifier given by an external mecanic, like a party buff, item set bonuses,
* skills or abilities... Anything apart from items and armor.
*/
public AttributeModifier(String key, String attribute, double value, ModifierType type) {
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
*/
public AttributeModifier(String key, String attribute, double value, ModifierType type, EquipmentSlot slot, ModifierSource source) {
this(UUID.randomUUID(), key, attribute, value, type, 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);
super(key, slot, source);
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
*/
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;
}
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");
}
@ -83,6 +85,14 @@ public class AttributeModifier extends InstanceModifier {
return attribute;
}
public ModifierType getType() {
return type;
}
public double getValue() {
return value;
}
/**
* Used to multiply some existing stat modifier by a constant, usually an
* integer, for instance when MMOCore party modifiers scale with the
@ -91,19 +101,24 @@ public class AttributeModifier extends InstanceModifier {
* @param coef The multiplicative constant
* @return A new instance of StatModifier with modified value
*/
public AttributeModifier multiply(double coef) {
return new AttributeModifier(getUniqueId(), getKey(), attribute, value * coef, type, getSlot(), getSource());
public StatModifier multiply(double coef) {
return new StatModifier(getKey(), attribute, value * coef, type, getSlot(), getSource());
}
@Override
public void register(MMOPlayerData mmoPlayerData) {
PlayerData playerData = PlayerData.get(mmoPlayerData);
PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
playerData.getAttributes().getInstance(attribute).addModifier(this);
}
@Override
public void unregister(MMOPlayerData mmoPlayerData) {
PlayerData playerData = PlayerData.get(mmoPlayerData);
PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
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;
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 net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.configuration.ConfigurationSection;
/**
* 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
* 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 String statName;
public MMOCoreAttributeStatHandler(ConfigurationSection config, PlayerAttribute attr) {
super(config, "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_"));
public MMOCoreAttributeStatHandler(PlayerAttribute 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
*/
@Override
public void runUpdate(StatInstance instance) {
public void runUpdate(StatMap statMap) {
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();
} catch (NullPointerException exception) {
// 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
@Override
public ExperienceTable getExperienceTable() {
return Objects.requireNonNull(expTable, "Attribute has no exp table");
return Objects.requireNonNull(expTable);
}
@Override

View File

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

View File

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

View File

@ -1,35 +1,29 @@
package net.Indyuce.mmocore.api.player.profess;
import io.lumine.mythic.lib.gson.JsonElement;
import io.lumine.mythic.lib.gson.JsonObject;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.Indyuce.mmocore.MMOCore;
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.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.player.ClassDataContainer;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
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 double experience, health, mana, stellium, stamina;
private final double experience;
private final Map<String, Integer> attributeLevels = new HashMap<>();
private final Map<String, Integer> skillLevels = new HashMap<>();
private final Map<String, Integer> skillTreePoints = new HashMap<>();
private final Map<String, Integer> nodeLevels = new HashMap<>();
private final Map<String, Integer> nodeTimesClaimed = new HashMap<>();
private final Map<Integer, String> boundSkills = new HashMap<>();
private final Set<String> unlockedItems = new HashSet<>();
private final List<String> boundSkills = new ArrayList<>();
/**
* Used by YAML storage
@ -42,34 +36,18 @@ public class SavedClassInformation implements ClassDataContainer {
attributeReallocationPoints = config.getInt("attribute-realloc-points");
skillReallocationPoints = config.getInt("skill-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"))
config.getConfigurationSection("attribute").getKeys(false)
.forEach(key -> attributeLevels.put(key, config.getInt("attribute." + key)));
config.getConfigurationSection("attribute").getKeys(false).forEach(key -> attributeLevels.put(key, config.getInt("attribute." + key)));
if (config.contains("skill"))
config.getConfigurationSection("skill").getKeys(false)
.forEach(key -> skillLevels.put(key, config.getInt("skill." + key)));
config.getConfigurationSection("skill").getKeys(false).forEach(key -> skillLevels.put(key, config.getInt("skill." + key)));
if (config.contains("skill-tree-points"))
config.getConfigurationSection("skill-tree-points").getKeys(false)
.forEach(key -> skillTreePoints.put(key, config.getInt("skill-tree-points." + key)));
config.getConfigurationSection("skill-tree-points").getKeys(false).forEach(key -> skillTreePoints.put(key, config.getInt("skill-tree-points." + key)));
if (config.contains("node-levels"))
config.getConfigurationSection("node-levels").getKeys(false)
.forEach(key -> nodeLevels.put(key, config.getInt("node-levels." + key)));
config.getConfigurationSection("node-levels").getKeys(false).forEach(key -> nodeLevels.put(key, config.getInt("node-levels." + key)));
if (config.contains("node-times-claimed"))
config.getConfigurationSection("node-times-claimed").getKeys(false)
.forEach(key -> nodeTimesClaimed.put(key, config.getInt("node-times-claimed." + key)));
/**
* '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"));
config.getConfigurationSection("node-times-claimed").getKeys(false).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));
}
/**
@ -83,11 +61,6 @@ public class SavedClassInformation implements ClassDataContainer {
attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt();
skillReallocationPoints = json.get("skill-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"))
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
attributeLevels.put(entry.getKey(), entry.getValue().getAsInt());
@ -103,13 +76,8 @@ public class SavedClassInformation implements ClassDataContainer {
if (json.has("node-times-claimed"))
for (Entry<String, JsonElement> entry : json.getAsJsonObject("node-times-claimed").entrySet())
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") && json.get("bound-skills").isJsonObject())
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());
if (json.has("bound-skills"))
json.getAsJsonArray("bound-skills").forEach(id -> boundSkills.add(id.getAsString()));
}
public SavedClassInformation(ClassDataContainer data) {
@ -120,65 +88,37 @@ public class SavedClassInformation implements ClassDataContainer {
this.skillTreeReallocationPoints = data.getSkillTreeReallocationPoints();
this.skillReallocationPoints = data.getSkillReallocationPoints();
this.experience = data.getExperience();
this.health = data.getHealth();
this.mana = data.getMana();
this.stellium = data.getStellium();
this.stamina = data.getStamina();
attributeLevels.putAll(data.mapAttributeLevels());
skillLevels.putAll(data.mapSkillLevels());
skillTreePoints.putAll(data.mapSkillTreePoints());
nodeLevels.putAll(data.getNodeLevels());
nodeTimesClaimed.putAll(data.getNodeTimesClaimed());
boundSkills.putAll(data.mapBoundSkills());
unlockedItems.addAll(data.getUnlockedItems());
data.mapAttributeLevels().forEach((key, val) -> this.attributeLevels.put(key, val));
data.mapSkillLevels().forEach((key, val) -> skillLevels.put(key, val));
data.mapSkillTreePoints().forEach((key, val) -> skillTreePoints.put(key, val));
data.getNodeLevels().forEach((node, level) -> nodeLevels.put(node.getFullId(), level));
data.getNodeTimesClaimed().forEach((key, val) -> nodeTimesClaimed.put(key, val));
data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getTriggeredSkill().getHandler().getId()));
data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
}
@Override
public int getLevel() {
return level;
}
@Override
public double getExperience() {
return experience;
}
@Override
public int getSkillPoints() {
return skillPoints;
}
@Override
public int getAttributePoints() {
return attributePoints;
}
@Override
public int getAttributeReallocationPoints() {
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() {
return skillLevels.keySet();
}
@ -195,27 +135,10 @@ public class SavedClassInformation implements ClassDataContainer {
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() {
return skillTreeReallocationPoints;
}
@Override
public int getSkillReallocationPoints() {
return skillReallocationPoints;
}
@ -232,26 +155,6 @@ public class SavedClassInformation implements ClassDataContainer {
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() {
return skillTreePoints.keySet();
}
@ -276,11 +179,6 @@ public class SavedClassInformation implements ClassDataContainer {
attributeLevels.put(attribute, level);
}
@Override
public Set<String> getUnlockedItems() {
return unlockedItems;
}
/**
* @param profess Target player 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)
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.
*/
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) {
attribute.resetAdvancement(player, false);
player.getAttributes().getInstance(attribute).setBase(0);
}
player.resetSkillTrees();
player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
player.clearSkillTreePoints();
player.clearNodeLevels();
player.clearNodeStates();
// 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
* 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.setExperience(experience);
@ -318,13 +226,16 @@ public class SavedClassInformation implements ClassDataContainer {
player.setAttributeReallocationPoints(attributeReallocationPoints);
player.setSkillTreeReallocationPoints(skillTreeReallocationPoints);
player.setSkillReallocationPoints(skillReallocationPoints);
player.setUnlockedItems(unlockedItems);
player.setClass(profess);
for (int slot : boundSkills.keySet())
player.bindSkill(slot, profess.getSkill(boundSkills.get(slot)));
for (String id : boundSkills) {
ClassSkill skill = profess.getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
player.bindPassiveSkill(-1, skill.toPassive(player));
else
player.getBoundSkills().add(skill);
}
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.
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.
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);
// This needs to be done at the end to make sure the MAX_HEALTH/MAX_MANA/... stats are loaded.
player.getPlayer().setHealth(MMOCoreUtils.fixResource(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
player.setHealth(health);
player.setMana(mana);
player.setStellium(stellium);
player.setStamina(stamina);
player.applyTemporaryTriggers();
player.getStats().updateStats();
// Updates level on exp bar
player.refreshVanillaExp();
}
}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
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.PlayerData;
import org.bukkit.Sound;
@ -21,8 +21,8 @@ public class FriendRequest extends Request {
getCreator().addFriend(getTarget().getUniqueId());
getTarget().addFriend(getCreator().getUniqueId());
if (getCreator().isOnline()) {
ConfigMessage.fromKey("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", getTarget().getPlayer().getName()).send(getCreator().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.skill.PassiveSkill;
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.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
@ -46,7 +45,7 @@ public class PlayerStats {
}
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));
}
public void updateStats() {
updateStats(false);
}
/**
* 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
* when the plugin reloads.
* MythicLib. Must be ran everytime the player levels up or changes class.
* <p>
* Login scripts are a pretty special case of scripts/skills since they are
* not loaded yet when MythicLib triggers them naturally. Therefore, they
* need to be cast as soon as they are loaded into the MMOCore player data.
*
* @param castLoginScripts Should login scripts be cast
* This is also called when reloading the plugin to make class setup easier,
* see {@link PlayerData#update()} for more info
*/
public synchronized void updateStats(boolean castLoginScripts) {
// Update player stats
public synchronized void updateStats() {
for (String stat : MMOCore.plugin.statManager.getRegistered()) {
final StatInstance instance = getMap().getInstance(stat);
final StatInstance.ModifierPacket packet = instance.newPacket();
@ -101,32 +90,25 @@ public class PlayerStats {
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();
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");
for (PassiveSkill script : data.getProfess().getScripts())
if (script.getType() != TriggerType.LOGIN) 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());
}
skillMap.addModifier(script);
}
}

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmocore.api.quest;
import io.lumine.mythic.lib.util.Closeable;
import net.Indyuce.mmocore.MMOCore;
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.event.HandlerList;
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 QuestProgress questProgress;

View File

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

View File

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

View File

@ -5,63 +5,61 @@ import net.Indyuce.mmocore.api.quest.objective.Objective;
import io.lumine.mythic.lib.MythicLib;
public class QuestProgress {
private final Quest quest;
private final PlayerData player;
private final Quest quest;
private final PlayerData player;
private int objective;
private ObjectiveProgress objectiveProgress;
private int objective;
private ObjectiveProgress objectiveProgress;
public QuestProgress(Quest quest, PlayerData player) {
this(quest, player, 0);
}
public QuestProgress(Quest quest, PlayerData player) {
this(quest, player, 0);
}
public QuestProgress(Quest quest, PlayerData player, int objective) {
this.quest = quest;
this.player = player;
public QuestProgress(Quest quest, PlayerData player, int objective) {
this.quest = quest;
this.player = player;
this.objective = objective;
objectiveProgress = nextObjective().newProgress(this);
}
this.objective = objective;
objectiveProgress = nextObjective().newProgress(this);
}
public Quest getQuest() {
return quest;
}
public Quest getQuest() {
return quest;
}
public PlayerData getPlayer() {
return player;
}
public PlayerData getPlayer() {
return player;
}
public int getObjectiveNumber() {
return objective;
}
public int getObjectiveNumber() {
return objective;
}
public ObjectiveProgress getProgress() {
return objectiveProgress;
}
public ObjectiveProgress getProgress() {
return objectiveProgress;
}
private Objective nextObjective() {
return quest.getObjectives().get(objective);
}
private Objective nextObjective() {
return quest.getObjectives().get(objective);
}
public void completeObjective() {
objective++;
objectiveProgress.close();
public void completeObjective() {
objective++;
objectiveProgress.close();
final ObjectiveProgress finishedObjectiveProgress = objectiveProgress;
// apply triggers
objectiveProgress.getObjective().getTriggers().forEach(trigger -> trigger.schedule(getPlayer()));
// Start next objective, or end quest.
if (objective >= quest.getObjectives().size()) player.getQuestData().finishCurrent();
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() {
return MythicLib.plugin.parseColors(objectiveProgress.formatLore(objectiveProgress.getObjective().getDefaultLore()));
}
public String getFormattedLore() {
return MythicLib.plugin.parseColors(objectiveProgress.formatLore(objectiveProgress.getObjective().getDefaultLore()));
}
}

View File

@ -1,6 +1,5 @@
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.event.CustomBlockMineEvent;
import net.Indyuce.mmocore.api.quest.QuestProgress;
@ -43,8 +42,6 @@ public class MineBlockObjective extends Objective {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void a(BlockBreakEvent event) {
if(!getQuestProgress().getPlayer().isOnline()) return;
if (UtilityMethods.isFake(event)) return;
if ((!playerPlaced) && event.getBlock().hasMetadata("player_placed"))
return;
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;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
@ -24,9 +23,7 @@ public class CommandTrigger extends Trigger {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), format(player.getPlayer()));
}
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
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()));
}
}

View File

@ -36,6 +36,6 @@ public class ExperienceTrigger extends Trigger {
@Override
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;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.entity.Player;
@ -23,9 +22,7 @@ public class MessageTrigger extends Trigger {
player.getPlayer().sendMessage(format(player.getPlayer()));
}
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
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()));
}
}

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.player.modifier.ModifierType;
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;
public class StatTrigger extends Trigger implements Removable, Temporary {
private final StatModifier modifier;
import java.util.UUID;
public class StatTrigger extends Trigger {
private final String stat;
private final double amount;
private final ModifierType type;
private double totalAmount;
private final UUID uuid =UUID.randomUUID();
public StatTrigger(MMOLineConfig config) {
super(config);
@ -23,18 +25,23 @@ public class StatTrigger extends Trigger implements Removable, Temporary {
Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE"));
stat = config.getString("stat");
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
public void apply(PlayerData player) {
StatModifier prevModifier = player.getMMOPlayerData().getStatMap().getInstance(stat).getModifier(modifier.getUniqueId());
if (prevModifier == null) modifier.register(player.getMMOPlayerData());
else prevModifier.add(amount).register(player.getMMOPlayerData());
totalAmount+=amount;
new StatModifier("trigger."+uuid.toString(),stat,totalAmount,type).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) {
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;
public abstract class Trigger {
public static String STAT_MODIFIER_KEY = "mmocore_trigger";
private final long delay;
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;
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.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.version.VEnchantment;
import io.lumine.mythic.lib.version.VersionMaterial;
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.entity.Entity;
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.player.PlayerItemDamageEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.jetbrains.annotations.NotNull;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream;
@ -35,37 +34,11 @@ public class MMOCoreUtils {
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) {
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) {
StringBuilder builder = new StringBuilder(s);
boolean isLastSpace = true;
@ -80,26 +53,44 @@ public class MMOCoreUtils {
return builder.toString();
}
public static String ymlName(String str) {
return str.toLowerCase().replace("_", "-").replace(" ", "-");
}
@Deprecated
/**
*
* @param value an integer you want to convert
* @return the string representing the integer but with roman letters
*/
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) {
if (s == null) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
/**
* Displays an in game indicator using a hologram. This uses
* LumineUtils hologramFactory to summon holograms
@ -110,38 +101,18 @@ public class MMOCoreUtils {
* @param message Message to display
*/
public static void displayIndicator(Location loc, String message) {
Hologram holo = Hologram.create(loc, MythicLib.plugin.parseColors(Collections.singletonList(message)));
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, holo::despawn, 20);
Hologram holo = Hologram.create(loc, Arrays.asList(message));
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> holo.despawn(), 20);
}
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) {
meta.addItemFlags(ItemFlag.values());
// Fix 1.20.6+ Paper bug that sucks. HIDE_ATTRIBUTES no longer works when item attribute list is empty
// 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 ItemStack readIcon(String string) throws IllegalArgumentException {
String[] split = string.split(":");
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
}
public static int getWorth(ItemStack[] items) {
@ -257,7 +228,6 @@ public class MMOCoreUtils {
return entities;
}
@Deprecated
public static void heal(LivingEntity target, double value) {
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double gain = Math.min(max, target.getHealth() + value) - target.getHealth();
@ -268,8 +238,6 @@ public class MMOCoreUtils {
target.setHealth(target.getHealth() + gain);
}
private static final Random RANDOM = new Random();
/**
* Method used when mining a custom block or fishing, as the corresponding
* 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
*/
public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) {
ItemStack item = UtilityMethods.getHandItem(player, slot);
if (item == null || item.getType().getMaxDurability() == 0 || item.getItemMeta().isUnbreakable())
ItemStack item = player.getInventory().getItem(slot);
if (item == null || item.getType().getMaxDurability() == 0 || !item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable())
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);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
final int newDamage = event.getDamage() + ((Damageable) meta).getDamage();
if (newDamage >= item.getType().getMaxDurability()) {
ItemMeta meta = item.getItemMeta();
if (event.getDamage() + ((Damageable) meta).getDamage() >= item.getType().getMaxDurability()) {
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
player.getInventory().setItem(slot, null);
} else {
((Damageable) meta).setDamage(newDamage);
((Damageable) meta).setDamage(((Damageable) meta).getDamage() + event.getDamage());
item.setItemMeta(meta);
}
}
@ -315,11 +277,4 @@ public class MMOCoreUtils {
public static Location getCenterLocation(Entity entity) {
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;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -13,6 +12,8 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Consumer;
import io.lumine.mythic.lib.MythicLib;
@Deprecated
public class AnvilGUI extends PlayerInput {
private final int containerId;
@ -23,7 +24,7 @@ public class AnvilGUI extends PlayerInput {
ItemStack paper = new ItemStack(Material.PAPER);
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);
MythicLib.plugin.getVersion().getWrapper().handleInventoryCloseEvent(player);

View File

@ -1,7 +1,6 @@
package net.Indyuce.mmocore.api.util.input;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.gui.api.PluginInventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -38,7 +37,8 @@ public class ChatInput extends PlayerInput {
this.lastOpened = lastOpened;
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
@ -56,7 +56,7 @@ public class ChatInput extends PlayerInput {
if (event.getMessage().equals("cancel")) {
if (lastOpened != null)
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
// Run sync
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> output(event.getMessage()));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,8 +3,6 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
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.api.event.MMOCommandEvent;
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.ChatColor;
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.Nullable;
import java.util.UUID;
public class FriendsCommand extends RegisteredCommand {
public class FriendsCommand extends BukkitCommand {
public FriendsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.FRIENDS);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the friends menu.");
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.friends"))
return false;
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true;

View File

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

View File

@ -2,8 +2,6 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore;
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.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.social.Request;
@ -14,29 +12,28 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
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.Nullable;
import java.util.UUID;
public class PartyCommand extends RegisteredCommand {
public class PartyCommand extends BukkitCommand {
public PartyCommand(ConfigurationSection config) {
super(config, ToggleableCommand.PARTY);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the party menu.");
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.party"))
return false;
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only.");
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);
MMOCommandEvent event = new MMOCommandEvent(data, "party");

View File

@ -1,34 +1,34 @@
package net.Indyuce.mmocore.command;
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 net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
public class PlayerStatsCommand extends RegisteredCommand {
public PlayerStatsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.PLAYER);
}
public class PlayerStatsCommand extends BukkitCommand {
public PlayerStatsCommand(ConfigurationSection config) {
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Show player stats.");
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.profile"))
return false;
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is for players only.");
return true;
}
PlayerData data = PlayerData.get((Player) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "profile");
Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) InventoryManager.PLAYER_STATS.newInventory(data).open();
return true;
}
@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 true;
}
PlayerData data = PlayerData.get((Player) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "profile");
Bukkit.getServer().getPluginManager().callEvent(event);
if(!event.isCancelled()) InventoryManager.PLAYER_STATS.newInventory(data).open();
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;
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.api.event.MMOCommandEvent;
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;
public class QuestsCommand extends RegisteredCommand {
public class QuestsCommand extends BukkitCommand {
public QuestsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.QUESTS);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the quests menu.");
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.quests"))
return false;
if (sender instanceof Player) {
PlayerData data = PlayerData.get((Player) sender);
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;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.MMOCore;
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.api.event.MMOCommandEvent;
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;
public class SkillsCommand extends RegisteredCommand {
public class SkillsCommand extends BukkitCommand {
public SkillsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.SKILLS);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Opens the skills menu.");
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (!sender.hasPermission("mmocore.skills"))
return false;
if (sender instanceof Player) {
PlayerData data = PlayerData.get((Player) sender);
MMOCommandEvent event = new MMOCommandEvent(data, "skills");
Bukkit.getServer().getPluginManager().callEvent(event);
if(event.isCancelled()) return true;
if (data.getUnlockedSkills().isEmpty()) {
ConfigMessage.fromKey("no-class-skill").send((Player) sender);
if (data.getProfess().getSkills().size() < 1) {
MMOCore.plugin.configManager.getSimpleMessage("no-class-skill").send((Player) sender);
return true;
}

View File

@ -1,18 +1,20 @@
package net.Indyuce.mmocore.command;
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.api.event.MMOCommandEvent;
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;
public class WaypointsCommand extends RegisteredCommand {
public class WaypointsCommand extends BukkitCommand {
public WaypointsCommand(ConfigurationSection config) {
super(config, ToggleableCommand.WAYPOINTS);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Open the waypoints menu.");
}
@Override

View File

@ -1,21 +1,23 @@
package net.Indyuce.mmocore.command;
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.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
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) {
super(config, ToggleableCommand.WITHDRAW);
super(config.getString("main"));
setAliases(config.getStringList("aliases"));
setDescription("Creates a withdraw request.");
}
@Override
@ -37,7 +39,7 @@ public class WithdrawCommand extends RegisteredCommand {
amount = Integer.parseInt(amountArgument);
Validate.isTrue(amount >= 0);
} 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;
}
@ -50,14 +52,14 @@ public class WithdrawCommand extends RegisteredCommand {
int left = (int) MMOCore.plugin.economy.getEconomy().getBalance(player) - amount;
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;
}
MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, amount);
request.withdrawAlgorythm(amount);
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;
}
}

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 AttributeCommandTreeNode(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("class", this, PlayerData::setClassPoints, PlayerData::giveClassPoints, PlayerData::getClassPoints));
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("skill-realloc", this, PlayerData::setSkillReallocationPoints, PlayerData::giveSkillReallocationPoints, PlayerData::getSkillReallocationPoints));
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())
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.attribute.PlayerAttribute;
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.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -1,20 +1,20 @@
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.ConfigMessage;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
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.SavedClassInformation;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
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 ClassCommandTreeNode(CommandTreeNode parent) {
super(parent, "class");
@ -52,9 +52,9 @@ public class ClassCommandTreeNode extends CommandTreeNode {
return CommandResult.SUCCESS;
(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()) {
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);
}

View File

@ -8,7 +8,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.PlayerProfessions;
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.util.TriConsumer;
import org.apache.commons.lang.Validate;

View File

@ -1,13 +1,21 @@
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.data.DataExport;
import io.lumine.mythic.lib.data.sql.SQLDataSource;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
import net.Indyuce.mmocore.manager.data.yaml.YAMLPlayerDataHandler;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
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
@ -18,15 +26,82 @@ public class ExportDataTreeNode extends CommandTreeNode {
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
@NotNull
public CommandResult execute(CommandSender sender, String[] strings) {
// Export YAML to SQL
final boolean result = new DataExport<>(MMOCore.plugin.playerDataManager, sender).start(
() -> new YAMLPlayerDataHandler(MMOCore.plugin),
() -> new SQLDataHandler(new SQLDataSource(MMOCore.plugin)));
if (!MMOCore.plugin.dataProvider.getDataManager().getLoaded().isEmpty()) {
sender.sendMessage("Please make sure no players are logged in when using this command. " +
"If you are still seeing this message, restart your server and execute this command before any player logs in.");
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.api.player.PlayerData;
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.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -36,7 +36,7 @@ public class HideActionBarCommandTreeNode extends CommandTreeNode {
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);
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.PlayerProfessions;
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 org.bukkit.Bukkit;
import org.bukkit.ChatColor;

View File

@ -1,7 +1,7 @@
package net.Indyuce.mmocore.command.rpg.admin;
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.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -4,7 +4,7 @@ import java.util.function.BiConsumer;
import java.util.function.Function;
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.ChatColor;
import org.bukkit.command.CommandSender;

View File

@ -1,33 +1,29 @@
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.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.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
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 ResetCommandTreeNode(CommandTreeNode parent) {
super(parent, "reset");
addChild(new ResetClassesCommandTreeNode(this));
addChild(new ResetLevelsCommandTreeNode(this));
addChild(new ResetSkillsCommandTreeNode(this));
addChild(new ResetQuestsCommandTreeNode(this));
addChild(new ResetAllCommandTreeNode(this));
addChild(new ResetAttributesCommandTreeNode(this));
addChild(new ResetWaypointsCommandTreeNode(this));
addChild(new ResetSkillTreesCommandTreeNode(this));
addChild(new ResetAllCommandTreeNode(this));
}
@Override
@ -44,7 +40,8 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
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]);
if (player == null) {
@ -52,245 +49,216 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate");
PlayerData data = PlayerData.get(player);
MMOCore.plugin.dataProvider.getDataManager().getDefaultData().apply(data);
data.setExperience(0);
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0);
}
MMOCore.plugin.classManager.getAll().forEach(data::unloadClassInfo);
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
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;
}
}
public static class ResetWaypointsCommandTreeNode extends CommandTreeNode {
public ResetWaypointsCommandTreeNode(CommandTreeNode parent) {
super(parent, "waypoints");
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;
}
PlayerData data = PlayerData.get(player);
ResetClassesCommandTreeNode.resetClasses(data);
ResetLevelsCommandTreeNode.resetLevels(data);
ResetSkillsCommandTreeNode.resetSkills(data);
ResetQuestsCommandTreeNode.resetQuests(data);
ResetAttributesCommandTreeNode.resetAttributes(data, givePoints);
ResetWaypointsCommandTreeNode.resetWaypoints(data);
ResetSkillTreesCommandTreeNode.resetSkillTrees(data);
// Reset times-claimed not being properly emptied otherwise
data.getItemClaims().clear();
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s data was successfully reset.");
data.getWaypoints().clear();
return CommandResult.SUCCESS;
}
}
public static class ResetQuestsCommandTreeNode extends CommandTreeNode {
public ResetQuestsCommandTreeNode(CommandTreeNode parent) {
super(parent, "quests");
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;
}
PlayerData data = PlayerData.get(player);
data.getQuestData().resetFinishedQuests();
data.getQuestData().start(null);
return CommandResult.SUCCESS;
}
}
public static class ResetSkillsCommandTreeNode extends CommandTreeNode {
public ResetSkillsCommandTreeNode(CommandTreeNode parent) {
super(parent, "skills");
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;
}
PlayerData data = PlayerData.get(player);
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;
}
}
public static class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
public ResetSkillTreesCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill-trees");
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;
}
PlayerData data = PlayerData.get(player);
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;
}
}
public class ResetAttributesCommandTreeNode extends CommandTreeNode {
public ResetAttributesCommandTreeNode(CommandTreeNode parent) {
super(parent, "attributes");
addParameter(Parameter.PLAYER);
addParameter(new Parameter("(-reallocate)", (explore, list) -> list.add("-reallocate")));
}
@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;
}
PlayerData data = PlayerData.get(player);
/*
* force reallocating of player attribute points
*/
if (args.length > 4 && args[4].equalsIgnoreCase("-reallocate")) {
int points = 0;
for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) {
points += ins.getBase();
ins.setBase(0);
}
data.giveAttributePoints(points);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attribute points spendings were successfully reset.");
return CommandResult.SUCCESS;
}
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were succesfully reset.");
return CommandResult.SUCCESS;
}
}
public static class ResetLevelsCommandTreeNode extends CommandTreeNode {
public ResetLevelsCommandTreeNode(CommandTreeNode parent) {
super(parent, "levels");
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;
}
PlayerData data = PlayerData.get(player);
data.setLevel(MMOCore.plugin.dataProvider.getDataManager().getDefaultData().getLevel());
data.setExperience(0);
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0);
profession.getExperienceTable().reset(data, profession);
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were succesfully reset.");
return CommandResult.SUCCESS;
}
}
}
class ResetWaypointsCommandTreeNode extends CommandTreeNode {
public ResetWaypointsCommandTreeNode(CommandTreeNode parent) {
super(parent, "waypoints");
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;
}
resetWaypoints(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s waypoints were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetWaypoints(@NotNull PlayerData playerData) {
playerData.getWaypoints().clear();
}
}
class ResetQuestsCommandTreeNode extends CommandTreeNode {
public ResetQuestsCommandTreeNode(CommandTreeNode parent) {
super(parent, "quests");
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;
}
resetQuests(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().start(null);
}
}
class ResetSkillsCommandTreeNode extends CommandTreeNode {
public ResetSkillsCommandTreeNode(CommandTreeNode parent) {
super(parent, "skills");
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;
}
resetSkills(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was successfully reset.");
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 ResetSkillTreesCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill-trees");
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;
}
resetSkillTrees(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill-tree data was successfully reset.");
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 ResetAttributesCommandTreeNode(CommandTreeNode parent) {
super(parent, "attributes");
addParameter(Parameter.PLAYER);
addParameter(new Parameter("(-reallocate)", (explore, list) -> list.add("-reallocate")));
}
@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;
}
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate");
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) {
// Give back attribute points
if (givePoints) {
int points = 0;
for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) {
points += ins.getBase();
ins.setBase(0);
}
data.giveAttributePoints(points);
return;
}
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) {
attribute.resetAdvancement(data, true);
data.getAttributes().getInstance(attribute).setBase(0);
}
}
}
class ResetLevelsCommandTreeNode extends CommandTreeNode {
public ResetLevelsCommandTreeNode(CommandTreeNode parent) {
super(parent, "levels");
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;
}
resetLevels(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetLevels(@NotNull PlayerData data) {
// Class
data.setLevel(MMOCore.plugin.playerDataManager.getDefaultData().getLevel());
data.setExperience(0);
data.getProfess().resetAdvancement(data, true);
// Professions
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0);
profession.resetAdvancement(data, true);
}
}
}
class ResetClassesCommandTreeNode extends CommandTreeNode {
public ResetClassesCommandTreeNode(CommandTreeNode parent) {
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;
}
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.quest.trigger.ManaTrigger;
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.ChatColor;
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.api.player.PlayerData;
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 org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -19,21 +19,19 @@ public class SkillCommandTreeNode extends CommandTreeNode {
public SkillCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill");
addChild(new LockSkillCommandTreeNode(this, "lock", true));
addChild(new LockSkillCommandTreeNode(this, "unlock", false));
addChild(new LevelCommandTreeNode(this, "give", (old, amount) -> old + amount));
addChild(new LevelCommandTreeNode(this, "set", (old, amount) -> amount));
addChild(new ActionCommandTreeNode(this, "give", (old, amount) -> old + amount));
addChild(new ActionCommandTreeNode(this, "set", (old, amount) -> amount));
}
public class LevelCommandTreeNode extends CommandTreeNode {
public class ActionCommandTreeNode extends CommandTreeNode {
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);
this.change = change;
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()))));
addParameter(Parameter.AMOUNT);
}
@ -57,17 +55,19 @@ public class SkillCommandTreeNode extends CommandTreeNode {
}
ClassSkill classSkill = null;
for (ClassSkill var : playerData.getProfess().getSkills()) {
if (var.getSkill().equals(skill))
classSkill = var;
ClassSkill classSkill=null;
for(ClassSkill var:playerData.getProfess().getSkills()) {
if(var.getSkill().equals(skill))
classSkill=var;
}
if (classSkill == null || classSkill.getUnlockLevel() > playerData.getLevel()) {
sender.sendMessage(ChatColor.RED + skill.getName() + " is not unlockable for " + player.getName() + ".");
if(classSkill==null||classSkill.getUnlockLevel() > playerData.getLevel()) {
sender.sendMessage(ChatColor.RED+ skill.getName()+" is not unlockable for "+player.getName()+".");
return CommandResult.FAILURE;
}
int amount;
try {
amount = Integer.parseInt(args[5]);
@ -77,59 +77,12 @@ public class SkillCommandTreeNode extends CommandTreeNode {
}
int value = change.apply(playerData.getSkillLevel(skill), amount);
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() + ".");
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
public CommandResult execute(CommandSender sender, String[] args) {
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 net.Indyuce.mmocore.MMOCore;
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 org.bukkit.Bukkit;
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")) {
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));
return CommandResult.SUCCESS;
}
@ -62,7 +62,7 @@ public class CreateCommandTreeNode extends CommandTreeNode {
Profession profession = MMOCore.plugin.professionManager.get(format);
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());
Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1));
return CommandResult.SUCCESS;

View File

@ -12,30 +12,30 @@ import org.bukkit.entity.Player;
public class StatModifiersCommandTreeNode extends CommandTreeNode {
public StatModifiersCommandTreeNode(CommandTreeNode parent) {
super(parent, "statmods");
public StatModifiersCommandTreeNode(CommandTreeNode parent) {
super(parent, "statmods");
addParameter(new Parameter("<stat>", (explorer, list) -> list.add("STAT_ID")));
}
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 3)
return CommandResult.THROW_USAGE;
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 3)
return CommandResult.THROW_USAGE;
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command can only be used by a player.");
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get((Player) sender);
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command can only be used by a player.");
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get((Player) sender);
StatInstance instance = data.getMMOPlayerData().getStatMap().getInstance(UtilityMethods.enumName(args[2]));
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key);
sender.sendMessage("-> '" + key + "' " + mod.getValue() + " " + mod.getType().name() + " " + mod.getSlot() + " " + mod.getSource());
}
StatInstance instance = data.getMMOPlayerData().getStatMap().getInstance(UtilityMethods.enumName(args[2]));
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key);
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 net.Indyuce.mmocore.MMOCore;
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 org.bukkit.Bukkit;
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.drops.DropMetadata;
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 net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
@ -27,8 +27,7 @@ public class CurrencyItemDrop extends Drop implements IItemDrop {
@Override
public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
// Not great wrt to performance. Should build the item like MM does
return BukkitAdapter.adapt(new CurrencyItemBuilder(key, random(minw, maxw)).build());
return new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build());
}
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.drops.DropMetadata;
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.lib.api.item.ItemTag;
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)));
// Not great wrt to performance. Should build the item like MM does
return BukkitAdapter.adapt(nbt.toItem());
return new BukkitItemStack(nbt.toItem());
}
private ItemStack setAmount(ItemStack item, int amount) {

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.comp.placeholder;
import io.lumine.mythic.lib.util.annotation.BackwardsCompatibility;
import org.bukkit.OfflinePlayer;
import io.lumine.mythic.lib.MythicLib;
@ -8,9 +7,7 @@ import io.lumine.mythic.lib.MythicLib;
public class DefaultParser implements PlaceholderParser {
@Override
@BackwardsCompatibility(version = "1.12-SNAPSHOT")
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()));
}
}

View File

@ -1,316 +1,234 @@
package net.Indyuce.mmocore.comp.placeholder;
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.manager.StatManager;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.Indyuce.mmocore.MMOCore;
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.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession;
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 org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.UUID;
public class RPGPlaceholders extends PlaceholderExpansion {
@Override
public boolean persist() {
return true;
}
@Override
public boolean persist() {
return true;
}
@Override
public boolean canRegister() {
return true;
}
@Override
public boolean canRegister() {
return true;
}
@Override
public String getAuthor() {
return "Indyuce";
}
@Override
public String getAuthor() {
return "Indyuce";
}
@Override
public String getIdentifier() {
return "mmocore";
}
@Override
public String getIdentifier() {
return "mmocore";
}
@Override
public String getVersion() {
return MMOCore.plugin.getDescription().getVersion();
}
@Override
public String getVersion() {
return MMOCore.plugin.getDescription().getVersion();
}
private static final String ERROR_PLACEHOLDER = " ";
@SuppressWarnings("DuplicateExpressions")
@Override
public String onRequest(OfflinePlayer player, String identifier) {
if (!PlayerData.has(player.getUniqueId()))
return null;
@SuppressWarnings("DuplicateExpressions")
@Override
public String onRequest(OfflinePlayer player, String identifier) {
if (!PlayerData.has(player.getUniqueId()))
return null;
final PlayerData playerData = PlayerData.get(player);
PlayerData playerData = PlayerData.get(player);
if (identifier.equals("mana_icon"))
return playerData.getProfess().getManaDisplay().getIcon();
if (identifier.equals("mana_name"))
return playerData.getProfess().getManaDisplay().getName();
if (identifier.equals("mana_icon"))
return playerData.getProfess().getManaDisplay().getIcon();
if (identifier.equals("level"))
return "" + playerData.getLevel();
if (identifier.equals("mana_name"))
return playerData.getProfess().getManaDisplay().getName();
else if (identifier.startsWith("skill_level_")) {
String id = identifier.substring(12);
RegisteredSkill skill = Objects.requireNonNull(MMOCore.plugin.skillManager.getSkill(id), "Could not find skill with ID '" + id + "'");
return String.valueOf(playerData.getSkillLevel(skill));
}
if (identifier.equals("level"))
return String.valueOf(playerData.getLevel());
else if (identifier.equals("level_percent")) {
double current = playerData.getExperience(), next = playerData.getLevelUpExperience();
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
}
else if (identifier.startsWith("skill_level_")) {
String id = identifier.substring(12);
RegisteredSkill skill = MMOCore.plugin.skillManager.getSkillOrThrow(id);
return String.valueOf(playerData.getSkillLevel(skill));
}
else if (identifier.equals("health"))
return StatManager.format("MAX_HEALTH", player.getPlayer().getHealth());
/*
* 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);
}
else if (identifier.equals("max_health"))
return StatManager.format("MAX_HEALTH", player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
// 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.equals("health_bar") && player.isOnline()) {
StringBuilder format = new StringBuilder();
double ratio = 20 * player.getPlayer().getHealth() / player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
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);
return format.toString();
}
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("class"))
return playerData.getProfess().getName();
else if (identifier.equals("level_percent")) {
double current = playerData.getExperience(), next = playerData.getLevelUpExperience();
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
}
else if (identifier.startsWith("profession_percent_")) {
PlayerProfessions professions = playerData.getCollectionSkills();
String name = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase();
Profession profession = MMOCore.plugin.professionManager.get(name);
double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession);
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
}
else if (identifier.equals("health"))
return StatManager.format("MAX_HEALTH", player.getPlayer().getHealth());
else if (identifier.startsWith("is_casting")) {
return String.valueOf(playerData.isCasting());
} else if (identifier.startsWith("in_combat")) {
return String.valueOf(playerData.isInCombat());
}
else if (identifier.equals("max_health"))
return StatManager.format("MAX_HEALTH", player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
else if (identifier.startsWith("bound_")) {
int slot = Math.max(0, Integer.parseInt(identifier.substring(6)) - 1);
return playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getName()
: MMOCore.plugin.configManager.noSkillBoundPlaceholder;
}
else if (identifier.equals("health_bar") && player.isOnline()) {
StringBuilder format = new StringBuilder();
double ratio = 20 * player.getPlayer().getHealth() / player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
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);
return format.toString();
} else if (identifier.equals("class"))
return playerData.getProfess().getName();
else if (identifier.startsWith("profession_experience_"))
return MythicLib.plugin.getMMOConfig().decimal.format(
playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.startsWith("profession_percent_")) {
PlayerProfessions professions = playerData.getCollectionSkills();
String name = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase();
Profession profession = MMOCore.plugin.professionManager.get(name);
double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession);
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
else if (identifier.startsWith("profession_next_level_"))
return "" + PlayerData.get(player).getCollectionSkills()
.getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase());
} else if (identifier.equals("is_casting"))
return String.valueOf(playerData.isCasting());
else if (identifier.startsWith("party_count")) {
AbstractParty party = playerData.getParty();
return party == null ? "0" : String.valueOf(party.countMembers());
}
else if (identifier.equals("in_combat"))
return String.valueOf(playerData.isInCombat());
else if (identifier.startsWith("profession_"))
return String
.valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.equals("pvp_mode"))
return String.valueOf(playerData.getCombat().isInPvpMode());
else if (identifier.equals("experience"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getExperience());
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.equals("next_level"))
return String.valueOf(playerData.getLevelUpExperience());
else if (identifier.startsWith("invulnerability_left"))
return MythicLib.plugin.getMMOConfig().decimal.format(Math.max(0, (playerData.getCombat().getInvulnerableTill() - System.currentTimeMillis()) / 1000.));
else if (identifier.equals("class_points"))
return String.valueOf(playerData.getClassPoints());
else if (identifier.startsWith("since_last_hit"))
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastHit()) / 1000.) : "-1";
else if (identifier.equals("skill_points"))
return String.valueOf(playerData.getSkillPoints());
// 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();
}
else if (identifier.equals("attribute_points"))
return String.valueOf(playerData.getAttributePoints());
// 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));
}
else if (identifier.equals("attribute_reallocation_points"))
return String.valueOf(playerData.getAttributeReallocationPoints());
// 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());
}
else if (identifier.startsWith("attribute_"))
return String.valueOf(playerData.getAttributes()
.getAttribute(MMOCore.plugin.attributeManager.get(identifier.substring(10).toLowerCase().replace("_", "-"))));
// Returns the bound skill name
else if (identifier.startsWith("bound_")) {
final int slot = Math.max(1, Integer.parseInt(identifier.substring(6)));
final ClassSkill skill = playerData.getBoundSkill(slot);
if (skill == null) return MMOCore.plugin.configManager.noSkillBoundPlaceholder;
return (playerData.getCooldownMap().isOnCooldown(skill) ? ChatColor.RED : ChatColor.GREEN) + skill.getSkill().getName();
}
else if (identifier.equals("mana"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
// Returns cooldown of skill bound at given slot
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(
playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.equals("mana_bar")) {
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
}
else if (identifier.startsWith("profession_next_level_"))
return String.valueOf(PlayerData.get(player).getCollectionSkills()
.getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.startsWith("exp_multiplier_")) {
String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100);
}
else if (identifier.startsWith("party_count")) {
final @Nullable AbstractParty party = playerData.getParty();
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();
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
.valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase()));
else if (identifier.startsWith("exp_boost_")) {
String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100);
}
else if (identifier.equals("experience"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getExperience());
else if (identifier.equals("stamina"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina());
else if (identifier.equals("next_level"))
return String.valueOf(playerData.getLevelUpExperience());
else if (identifier.equals("stamina_bar")) {
StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA");
for (double j = 1; j < 20; j++)
format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
.append(AltChar.listSquare);
return format.toString();
}
else if (identifier.equals("class_points"))
return String.valueOf(playerData.getClassPoints());
else if (identifier.startsWith("stat_")) {
final String stat = identifier.substring(5).toUpperCase();
return StatManager.format(identifier.substring(5), playerData.getStats().getStat(stat));
}
else if (identifier.equals("skill_points"))
return String.valueOf(playerData.getSkillPoints());
else if (identifier.equals("stellium"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium());
else if (identifier.equals("attribute_points"))
return String.valueOf(playerData.getAttributePoints());
else if (identifier.equals("stellium_bar")) {
StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
return format.toString();
}
else if (identifier.equals("attribute_reallocation_points"))
return String.valueOf(playerData.getAttributeReallocationPoints());
else if (identifier.equals("quest")) {
PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None";
}
else if (identifier.startsWith("attribute_"))
return String.valueOf(playerData.getAttributes()
.getAttribute(MMOCore.plugin.attributeManager.get(identifier.substring(10).toLowerCase().replace("_", "-"))));
else if (identifier.equals("quest_progress")) {
PlayerQuests data = playerData.getQuestData();
else if (identifier.equals("mana"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal
.format( (double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0";
}
else if (identifier.equals("mana_bar"))
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
else if (identifier.equals("quest_objective")) {
PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None";
}
else if (identifier.startsWith("exp_multiplier_")) {
String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100);
} else if (identifier.startsWith("exp_boost_")) {
String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-");
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100);
} else if (identifier.equals("stamina"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina());
else if (identifier.startsWith("guild_")) {
String placeholder = identifier.substring(6);
if (playerData.getGuild() == null)
return "";
else if (identifier.equals("stamina_bar")) {
StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA");
for (double j = 1; j < 20; j++)
format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
.append(AltChar.listSquare);
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.equals("stellium"))
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium());
if (placeholder.equalsIgnoreCase("name"))
return playerData.getGuild().getName();
else if (placeholder.equalsIgnoreCase("tag"))
return playerData.getGuild().getTag();
else if (placeholder.equalsIgnoreCase("leader"))
return Bukkit.getOfflinePlayer(playerData.getGuild().getOwner()).getName();
else if (placeholder.equalsIgnoreCase("members"))
return String.valueOf(playerData.getGuild().countMembers());
else if (placeholder.equalsIgnoreCase("online_members"))
return String.valueOf(playerData.getGuild().countOnlineMembers());
}
else if (identifier.equals("stellium_bar")) {
StringBuilder format = new StringBuilder();
double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
return format.toString();
} else if (identifier.equals("quest")) {
PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None";
} else if (identifier.equals("quest_progress")) {
PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal
.format((double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0";
} else if (identifier.equals("quest_objective")) {
PlayerQuests data = playerData.getQuestData();
return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None";
} else if (identifier.startsWith("guild_")) {
String placeholder = identifier.substring(6);
if (playerData.getGuild() == null)
return "";
if (placeholder.equalsIgnoreCase("name"))
return playerData.getGuild().getName();
else if (placeholder.equalsIgnoreCase("tag"))
return playerData.getGuild().getTag();
else if (placeholder.equalsIgnoreCase("leader"))
return Bukkit.getOfflinePlayer(playerData.getGuild().getOwner()).getName();
else if (placeholder.equalsIgnoreCase("members"))
return String.valueOf(playerData.getGuild().countMembers());
else if (placeholder.equalsIgnoreCase("online_members"))
return String.valueOf(playerData.getGuild().countOnlineMembers());
}
return null;
}
return null;
}
}

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