Compare commits

..

451 Commits

Author SHA1 Message Date
Auxilor
dfe2f1361b Updated to 6.41.0 2022-09-14 13:58:10 +01:00
Auxilor
3826f9f713 Added item price API 2022-09-14 13:57:01 +01:00
Auxilor
c2d2303c91 Added scyther integration and BigDecimal economy support 2022-09-14 13:45:32 +01:00
Auxilor
b1158ceb3d Added configurable host to Paste 2022-09-12 14:39:15 +01:00
Auxilor
af4048afbe Updated to 6.40.2 2022-09-12 13:53:51 +01:00
Auxilor
fce12020d5 Fixed bug with old MySQL versions 2022-09-12 13:53:35 +01:00
Auxilor
7e37332b64 Updated to 6.40.1 2022-09-11 10:47:23 +01:00
Auxilor
52dbf9ff52 Codestyle 2022-09-11 10:47:00 +01:00
Auxilor
78b6292367 Merge remote-tracking branch 'origin/master' 2022-09-11 10:46:43 +01:00
Will FP
09705e787b Merge pull request #193
Fix DeluxeCombat and FabledSkyBlock integration
2022-09-11 10:46:44 +01:00
Auxilor
9c86069a85 Added option to disable the update checker 2022-09-11 10:45:40 +01:00
Auxilor
0a7acceb83 Updated to 6.40.0 2022-09-10 19:59:07 +01:00
Auxilor
40aa8b17dd Fixed MySQL changes 2022-09-10 19:58:57 +01:00
Auxilor
71eb386a19 Reworked MySQL data handler and data migration 2022-09-10 19:22:29 +01:00
Kapitowa
c857df2360 fix FabledSkyBlock integration for proper check 2022-09-09 14:45:33 +03:00
Kapitowa
f4fc611f3b Fix when damager with DeluxeCombat protection can cause damage 2022-09-09 05:31:54 +03:00
Auxilor
0d91324d47 Updated crunch 2022-09-06 15:26:46 +01:00
Auxilor
e9dbc3ec73 Updated crunch 2022-09-06 15:11:42 +01:00
Auxilor
493d1b1b6d Updated crunch 2022-09-06 15:11:14 +01:00
Auxilor
68221d5912 Updated crunch 2022-09-06 15:07:29 +01:00
Auxilor
7f2ef4e038 Updated to 6.39.1 2022-09-06 15:06:11 +01:00
Auxilor
be0a19175b Added additional players to config expression getters 2022-09-06 15:05:52 +01:00
Auxilor
5afdcd75f7 Added min and max functions to crunch 2022-09-06 14:49:40 +01:00
Auxilor
a1c0b8c857 Fixed FUUID 2022-09-06 13:25:17 +01:00
Auxilor
0442ccf58f Fixed FactionsUUID jar 2022-09-06 13:23:59 +01:00
Auxilor
1c1a796610 FactionsUUID to local jar 2022-09-06 13:19:49 +01:00
Auxilor
eacb243493 Fixed FactionsUUID 2022-09-06 13:17:55 +01:00
Auxilor
7bbed31d4e Fixed FactionsUUID 2022-09-06 13:17:43 +01:00
Auxilor
58bccf3cd7 Added songoda repo for FabledSkyblock 2022-09-06 13:15:36 +01:00
Auxilor
4502e1e311 Removed ender.zone, using JitPack build instead 2022-09-06 13:14:27 +01:00
Auxilor
054a8d5a5e Updated to 6.39.0 2022-09-06 13:04:55 +01:00
Auxilor
dbdd4785ba Added AdditionalPlayer support to placeholders 2022-09-06 13:04:00 +01:00
Will FP
35f800b62a Merge pull request #178
Added FabledSkyBlock integration in AntigriefManager
2022-09-06 12:50:56 +01:00
Auxilor
591800dba8 Updated to 6.38.3 2022-08-22 14:16:20 +02:00
Auxilor
46673e8d24 Fixed SNBT 2022-08-22 14:16:07 +02:00
Kapitowa
bb7c300074 fix space and fill softdepend 2022-08-02 18:46:09 +03:00
Kapitowa
b003ec96f7 Added FabledSkyBlock integration in AntigriefManager 2022-08-02 18:33:18 +03:00
Will FP
a526f51780 Update README.md 2022-07-28 16:07:08 +01:00
Auxilor
dd14fc666a Updated to 6.38.2 2022-07-27 19:42:19 +01:00
Auxilor
ae0150f012 Bumped ShopGUI+ 2022-07-27 19:42:06 +01:00
Auxilor
04418fa038 Updated ProtocolLib for compatibility 2022-07-27 19:40:08 +01:00
Auxilor
bcb9523315 Updated to 6.38.1 2022-07-25 16:51:55 +01:00
Auxilor
43e7972ca3 Improved menu re-renders 2022-07-25 16:51:38 +01:00
Auxilor
7ea61eb393 Removed source/target compatibility no longer required by kotlin 1.7.x 2022-07-22 14:08:33 +01:00
Auxilor
5245a9b1d8 Updated to 6.38.0 2022-07-22 14:05:53 +01:00
Auxilor
195932463c Added DisplayProperties to DisplayModule 2022-07-22 14:04:42 +01:00
Auxilor
3cf60a7e2c Added MenuUtils#getOpenMenu 2022-07-22 13:54:45 +01:00
Auxilor
0f9f57fca2 Merge remote-tracking branch 'origin/master' 2022-07-22 13:47:03 +01:00
Will FP
fe21616dd5 Merge pull request #161 from Syrent/master
Add MythicMobs 5.X support.
2022-07-22 13:46:53 +01:00
Auxilor
396144abaa Added Vector#isSafeVelocity 2022-07-22 13:46:08 +01:00
Auxilor
50b4fa59ab Added onOpen to menu 2022-07-22 13:42:48 +01:00
Auxilor
a6754379e8 Updated to 6.37.3 2022-07-07 22:55:03 +01:00
Auxilor
bbd0182c2a Fixed weird bug 2022-07-07 22:54:54 +01:00
Auxilor
0370e9f454 Fixed startup order 2022-07-03 16:49:26 +01:00
Auxilor
8d585b58cb Fixed initializing text 2022-07-03 16:45:44 +01:00
Auxilor
0bfbd4c036 Updated to 6.37.2 2022-07-03 16:38:32 +01:00
Auxilor
881839955e Added player health fixer 2022-07-03 16:38:21 +01:00
Syrent
8ffc5f9c0f Add MythicMobs 5.X support. 2022-06-28 08:07:05 +04:30
Auxilor
709de3bb5f Updated to 6.37.1 2022-06-14 12:43:11 +01:00
Auxilor
f2aa2ffd9b Removed ExactTestableItem 2022-06-14 12:43:04 +01:00
Auxilor
5ce70399f0 Improved SNBT lookups 2022-06-14 12:42:49 +01:00
Auxilor
3f8759b08a Updated to 6.37.0 2022-06-14 12:14:33 +01:00
Auxilor
abecaa6e9f Added SNBT parsing 2022-06-14 12:13:48 +01:00
Auxilor
4744bfc78b Updated to 6.36.5 2022-06-09 19:24:49 +01:00
Auxilor
487e68221a Added 1.19 support 2022-06-09 19:24:37 +01:00
Auxilor
1c68992a8e Updated to 6.36.4 2022-05-29 17:46:52 +01:00
Auxilor
c5b7d0b644 Fixed conflict finder breaking the polymart autoupdater 2022-05-29 17:46:24 +01:00
Auxilor
0f91aec3b7 Slots can now be not captive for some players 2022-05-29 11:34:32 +01:00
Auxilor
d2bf38c5c9 Updated to 6.36.3 2022-05-29 11:11:33 +01:00
Auxilor
2c96b79aba Improved slots 2022-05-29 11:11:16 +01:00
Auxilor
d539b9e59e Improvements to captive items 2022-05-28 17:33:06 +01:00
Auxilor
b0b06ef402 Updated to 6.36.2 2022-05-28 17:20:35 +01:00
Auxilor
7a84c3de3b Captive from empty, take 2 2022-05-28 17:20:23 +01:00
Auxilor
9431321e1c Revert "Added captive defaults"
This reverts commit 7adcdd572d.
2022-05-28 17:08:36 +01:00
Auxilor
4816284fba Revert "Added captive default kotlin extension"
This reverts commit 2bcbf181a9.
2022-05-28 17:08:01 +01:00
Auxilor
a9874c9386 Revert "Updated to 6.37.0"
This reverts commit fc3c80f633.
2022-05-28 17:08:01 +01:00
Auxilor
fe68760184 Revert "Fixed backwards compatibility"
This reverts commit 1f7cf78491.
2022-05-28 17:08:01 +01:00
Auxilor
5ae8e72a98 Revert "Fixed captive default"
This reverts commit 15fc6053c8.
2022-05-28 17:08:01 +01:00
Auxilor
15fc6053c8 Fixed captive default 2022-05-28 16:54:58 +01:00
Auxilor
1f7cf78491 Fixed backwards compatibility 2022-05-28 16:43:35 +01:00
Auxilor
fc3c80f633 Updated to 6.37.0 2022-05-28 16:41:30 +01:00
Auxilor
2bcbf181a9 Added captive default kotlin extension 2022-05-28 16:41:20 +01:00
Auxilor
7adcdd572d Added captive defaults 2022-05-28 16:40:14 +01:00
Auxilor
f6eba21006 Updated to 6.36.1 2022-05-28 16:10:40 +01:00
Auxilor
cc02f26807 Fixed key registry 2022-05-28 16:10:30 +01:00
Auxilor
60f552ce65 KDoc Formatting 2022-05-28 14:38:59 +01:00
Auxilor
9fe8d4ad15 Added more slot builders 2022-05-28 14:36:48 +01:00
Auxilor
b835988eec Added toSingletonList 2022-05-28 14:32:35 +01:00
Auxilor
22366835de Added additional MaskItems constructor 2022-05-28 14:31:20 +01:00
Auxilor
cdd1baec6c Fixed codemc 2022-05-28 14:28:24 +01:00
Auxilor
1ea0da365a Removed villager-display-fix 2022-05-28 13:59:38 +01:00
Auxilor
852d40372d Added option to toggle displayed recipes 2022-05-28 13:59:03 +01:00
Auxilor
999c831dd7 Removed non-functional packet splitting 2022-05-28 13:47:44 +01:00
Auxilor
80fa5d346a Fixed recipe packet fixer 2022-05-28 12:37:47 +01:00
Auxilor
336cdc3716 Added recipe packet splitting 2022-05-28 12:31:55 +01:00
Auxilor
a49a9e92b4 Updated villager trade 2022-05-28 12:23:47 +01:00
Auxilor
1c6e64832e Minor changes 2022-05-28 12:12:35 +01:00
Auxilor
44a141cddc Improved economy helpers 2022-05-27 19:03:53 +01:00
Auxilor
ea4956870e Added more GUI kotlin utils 2022-05-27 19:02:47 +01:00
Auxilor
9207d1782b Various changes 2022-05-27 17:09:00 +01:00
Auxilor
9debcb7089 Server will no longer restart after data migration 2022-05-27 16:25:11 +01:00
Auxilor
ef53ee2ed3 Fixed constrained types 2022-05-27 16:17:31 +01:00
Auxilor
4c90360038 More MySQL fixes 2022-05-27 16:07:24 +01:00
Auxilor
d4b5102913 Fixed MySQL 2022-05-27 16:01:44 +01:00
Auxilor
f4553c544a Fixed MySQL 2022-05-27 15:57:15 +01:00
Auxilor
5ad1db72fc Fixed minimize 2022-05-27 15:52:36 +01:00
Auxilor
c761df9ee6 Data Handler changes 2022-05-27 15:48:13 +01:00
Auxilor
b6d79da4e1 Improved config.yml header 2022-05-27 15:43:02 +01:00
Auxilor
42f41618ca Added warning for MySQL users 2022-05-27 15:38:28 +01:00
Auxilor
de878fd423 Codestyle 2022-05-27 15:29:39 +01:00
Auxilor
7782657d57 Improved DataHandlers again 2022-05-27 15:29:03 +01:00
Auxilor
7778425936 Improved DataHandler 2022-05-27 15:12:05 +01:00
Auxilor
6446cef255 OOps 2022-05-27 15:06:18 +01:00
Auxilor
8dacecbcba Added big ominous comment to the MySQL Data Handler 2022-05-27 15:06:00 +01:00
Auxilor
5f8ec4f94a Added PersistentDataKeyType#STRING_LIST 2022-05-27 14:56:53 +01:00
Auxilor
d7847e9efc Optimized writes mongo 2022-05-27 14:17:17 +01:00
Auxilor
930ecd4896 Improved conflict finder 2022-05-27 14:03:54 +01:00
Auxilor
af8d6a4167 Added OfflinePlayer#balance kotlin extensions 2022-05-27 14:02:52 +01:00
Auxilor
361f0a0103 Added unused suppression 2022-05-27 13:58:45 +01:00
Auxilor
eb545a7d9e Fixed relocations 2022-05-27 13:53:28 +01:00
Auxilor
d3c64deef4 Fixed minimize / exclude 2022-05-27 13:51:20 +01:00
Auxilor
31db9dcb95 Minimzed plugin module 2022-05-27 13:24:35 +01:00
Auxilor
4938ad84bc Added clarifying comment 2022-05-27 13:02:51 +01:00
Auxilor
06b2301da1 Janky fix for mongo logging 2022-05-27 13:00:59 +01:00
Auxilor
c307878c09 More migration improvements 2022-05-26 20:40:57 +01:00
Auxilor
3b10ff01ec Updated to 6.36.0 2022-05-26 20:17:47 +01:00
Auxilor
e042754f5d Mongo improvements / Added data migration 2022-05-26 20:17:31 +01:00
Auxilor
c2b8a80560 Improved MongoDB 2022-05-25 20:21:50 +01:00
Auxilor
07c0e72564 Added MongoDB data handler 2022-05-25 20:08:24 +01:00
Auxilor
de9b961d83 Revert "Added LONG_STRING column type"
This reverts commit 83958c719c.
2022-05-25 19:20:47 +01:00
Auxilor
83958c719c Added LONG_STRING column type 2022-05-21 19:35:05 +01:00
Auxilor
9c3dfaeb01 Updated to 6.35.12 2022-05-19 17:13:00 +01:00
Auxilor
7e61340285 Fixed static placeholder string formatting 2022-05-19 17:12:51 +01:00
Auxilor
78b76cb453 Updated to 6.35.11 2022-05-18 16:02:56 +01:00
Auxilor
bb1da29704 Added placeholder injections to strings 2022-05-18 16:02:36 +01:00
Auxilor
cf152215d3 Cleaned up internal 2022-05-18 15:00:23 +01:00
Auxilor
e6a59fbc91 Updated to 6.35.10 2022-05-18 10:53:06 +01:00
Will FP
b787f8b76a Merge pull request #133
Bump io.papermc.paperweight.userdev from 1.3.5 to 1.3.6
2022-05-18 10:52:43 +01:00
Will FP
ccc83da5b0 Merge pull request #135
Bump caffeine from 3.0.6 to 3.1.0
2022-05-18 10:52:30 +01:00
Will FP
f11068f2f1 Merge pull request #145
add CMI gradient format
2022-05-18 10:52:18 +01:00
Will FP
a5cc1a5d32 Merge pull request #146
Add an exception for armorstand in interact flag of WG
2022-05-18 10:52:10 +01:00
Kapitowa
7440749ba5 Add an exception for armorstand in interact flag of WG 2022-05-18 01:28:10 +03:00
Kapitowa
75010d25fa add CMI gradient format 2022-05-18 01:01:07 +03:00
Auxilor
bb95376b93 Removed async-display 2022-05-17 19:55:13 +01:00
Auxilor
ab6d4c7aa2 Updated to 6.35.9 2022-05-17 16:53:57 +01:00
Auxilor
9ab8827e55 Fixed non-applied FIS Flags 2022-05-17 16:45:37 +01:00
Auxilor
991290095b Updated to 6.35.8 2022-05-17 10:19:48 +01:00
Auxilor
8735478fc3 More bit manip 2022-05-17 10:19:36 +01:00
Auxilor
6e44f09621 Fixed ItemFlags in FastItemStack 2022-05-17 10:11:04 +01:00
Auxilor
060106881e Updated to 6.35.7 2022-05-13 12:07:26 +01:00
Auxilor
96cc9706b3 Placeholder injection fixes 2022-05-13 12:07:15 +01:00
Auxilor
3d87b1eb73 Revert "Fixed placeholder injection bugs"
This reverts commit 06bcb10958.
2022-05-13 11:46:57 +01:00
Auxilor
4c4247b4ec Revert "Updated to 6.35.7"
This reverts commit b94dc4ac3a.
2022-05-13 11:46:57 +01:00
Auxilor
b94dc4ac3a Updated to 6.35.7 2022-05-13 11:34:58 +01:00
Auxilor
06bcb10958 Fixed placeholder injection bugs 2022-05-13 11:34:42 +01:00
Auxilor
295095e9ce Fixed spelling 2022-05-09 12:34:14 +01:00
Auxilor
ba9c5865e3 Updated to 6.35.6 2022-05-09 12:30:22 +01:00
Auxilor
d24be4121f Added conflict finder 2022-05-09 12:30:14 +01:00
Auxilor
bcc5e4ef08 Skull improvements 2022-05-09 10:23:35 +01:00
Auxilor
bf8609666a Codestyle 2022-05-09 10:20:05 +01:00
Auxilor
1a02335825 Fixed dumbest error of all time 2022-05-09 10:14:18 +01:00
Auxilor
f5ef98ec5c Improved custom item lookup 2022-05-09 10:11:06 +01:00
Auxilor
45135e2b55 Updated to 6.35.5 2022-05-08 17:27:14 +01:00
Auxilor
758b42ff8e Fixed ItemsAdder integration 2022-05-08 17:26:50 +01:00
Auxilor
4a134402da Fixed Prerequisite#HAS_PAPER 2022-05-06 09:09:54 +01:00
Auxilor
e6ad4c9268 Updated to 6.35.4 2022-05-06 09:08:38 +01:00
Auxilor
809dcbae85 Improved NaturalExpGainListeners for paper 2022-05-06 09:07:57 +01:00
Auxilor
d7fce6834c Updated to 6.35.3 2022-05-03 13:05:41 +01:00
Auxilor
ac807a991b Players can no longer tab-complete commands they don't have permission for 2022-05-03 13:05:32 +01:00
Auxilor
ba315ced3c Updated to 6.35.2 2022-04-29 22:45:42 +01:00
Auxilor
f2e65174f9 Reverted to old block vein code 2022-04-29 22:45:02 +01:00
dependabot[bot]
bd5555ff01 Bump caffeine from 3.0.6 to 3.1.0
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.0.6 to 3.1.0.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.0.6...v3.1.0)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-28 21:41:30 +00:00
Auxilor
d5584e863b Updated to 6.35.1 2022-04-27 18:52:39 +01:00
Auxilor
d9c0e8e763 Fixed overload resolution ambiguity 2022-04-27 18:52:27 +01:00
Auxilor
b223f8457d Removed unused param 2022-04-27 18:23:36 +01:00
Auxilor
694d57edf4 Changing state will no longer re-render 2022-04-27 18:20:36 +01:00
Auxilor
02afe7d788 Fixed state-render infinite loops 2022-04-27 16:20:48 +01:00
Auxilor
0593e631ea Improved reactive state 2022-04-27 16:16:00 +01:00
Auxilor
2f22e02ff1 Added MenuBuilder#onRender to add reactive state 2022-04-27 16:14:28 +01:00
Auxilor
fb240bfd0a Replaced Menu data with Menu state 2022-04-27 16:07:38 +01:00
Auxilor
11c49a543f Improved config DSL 2022-04-27 14:17:13 +01:00
Auxilor
c565f5248d Fixed ShopWrapper deprecation comment 2022-04-27 13:44:51 +01:00
Auxilor
fac4f40430 Fixed codestyle 2022-04-27 13:28:04 +01:00
Auxilor
a20cb63755 Improved integration API 2022-04-27 13:18:57 +01:00
Auxilor
f17f67227f Commented CustomItem 2022-04-27 13:16:53 +01:00
Auxilor
106c9b37fc Removed unneeded test 2022-04-27 13:11:25 +01:00
Auxilor
f7cfcd5cbb Fixed redundant method 2022-04-27 13:06:35 +01:00
Auxilor
44d9581222 Cleanup 2022-04-27 13:04:57 +01:00
Auxilor
0fa30a5f62 Finally removed Display#callDisplayModule 2022-04-27 13:04:24 +01:00
Auxilor
84f439976c Fixed refactoring bugs 2022-04-27 12:51:45 +01:00
Auxilor
01bcb62b31 Refactored -Wrapper suffix to -Integration 2022-04-27 12:42:20 +01:00
Auxilor
47c8ea3341 Switched from DisplayPriority to weight 2022-04-27 12:31:27 +01:00
Auxilor
e28c4288a3 Removed ItemMeta usage in EcoDisplayHandler 2022-04-27 12:22:58 +01:00
Auxilor
386792d7ca Reworked PersistentDataContainer 2022-04-27 12:15:37 +01:00
Auxilor
8c6d98a666 Added string progress bars 2022-04-26 11:17:24 +01:00
Auxilor
6f42224593 Various codestyle improvements 2022-04-25 20:24:52 +01:00
Auxilor
36c857086b Fixed KDoc 2022-04-25 20:17:46 +01:00
Auxilor
014bcddc0a Fixed problem with extension functinos 2022-04-25 20:16:36 +01:00
Auxilor
96c56b0291 Codestyle 2022-04-25 20:03:09 +01:00
Auxilor
c1fe633e72 Improved config DSL 2022-04-25 20:02:28 +01:00
Auxilor
c9a9d86160 Added ConfigHelpers.kt 2022-04-25 19:44:01 +01:00
Auxilor
e79c7e9881 Codestyle 2022-04-25 13:40:26 +01:00
Auxilor
be617241e7 Removed ScriptUtils 2022-04-25 13:39:18 +01:00
Auxilor
cb9b59ae01 Added ScriptUtils 2022-04-25 11:32:47 +01:00
Auxilor
a993acae72 Fixed deprecated method use 2022-04-25 10:20:49 +01:00
Auxilor
e6cdc7d2ba Added PlayerUtils#tryAsPlayer 2022-04-25 10:14:24 +01:00
Auxilor
94534b2f61 Refactoring 2022-04-25 10:09:09 +01:00
Auxilor
fe6b7805c7 Added ShopSellEvent as well as integrations for zShop, EconomyShopGUI, and DeluxeSellwands 2022-04-25 10:03:23 +01:00
Auxilor
be25f2f4fc Added startup message in constructor 2022-04-25 09:42:03 +01:00
Auxilor
a19cc7df1e Added ExtendedPersistentDataContainer.create 2022-04-23 15:54:40 +01:00
Auxilor
13dbd08dcc Removed debug and now-unused API 2022-04-23 14:14:43 +01:00
dependabot[bot]
5f80b6052d Bump io.papermc.paperweight.userdev from 1.3.5 to 1.3.6
Bumps [io.papermc.paperweight.userdev](https://github.com/PaperMC/paperweight) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/PaperMC/paperweight/releases)
- [Commits](https://github.com/PaperMC/paperweight/compare/v1.3.5...v1.3.6)

---
updated-dependencies:
- dependency-name: io.papermc.paperweight.userdev
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-22 21:29:44 +00:00
Auxilor
a48885b79a Added kotlin extensions to ExtendedPersistentDataContainer 2022-04-22 21:18:14 +01:00
Auxilor
350c2d8775 Added ExtendedPersistentDataContainer#getBase 2022-04-22 20:53:26 +01:00
Auxilor
5988dfb1fd Fixed ExtendedPersistentDataContainer 2022-04-22 20:47:21 +01:00
Auxilor
57687859e4 Updated to 6.35.0 2022-04-22 20:45:16 +01:00
Auxilor
ef42e689ae Added ExtendedPersistentDataContainer 2022-04-22 20:44:59 +01:00
Auxilor
9a3aac9a66 Stripped out current mining speed check 2022-04-22 20:15:02 +01:00
Auxilor
7be5fbfbc4 Debug changes 2022-04-22 16:35:15 +01:00
Auxilor
4b344ccd18 More changes 2022-04-22 16:31:44 +01:00
Auxilor
3f50ae0a44 Began javassisting 2022-04-22 11:36:44 +01:00
Auxilor
afb498b4bf Added more mappings to FastItemStack 2022-04-22 10:48:33 +01:00
Auxilor
6b18b06763 Fixed placeholder equality 2022-04-22 09:55:55 +01:00
Auxilor
033e334877 Codestyle and reduced memory garbage 2022-04-22 09:53:40 +01:00
Auxilor
eb9112e480 Updated placeholder injection 2022-04-22 09:48:11 +01:00
Auxilor
b75e4d59e4 Changed getNearbyBlocks 2022-04-21 10:04:16 +01:00
Auxilor
c69bb6904f Minor fixes 2022-04-20 11:31:37 +01:00
Auxilor
9f193b7206 Fixed val using annotations 2022-04-20 11:28:55 +01:00
Auxilor
6fce2c13fe Updated to 6.34.0 2022-04-20 11:25:19 +01:00
Auxilor
02342c11a6 Added utility methods for base NBT 2022-04-20 11:25:00 +01:00
Auxilor
2fde56df0d Added ability to modify full item NBT via PersistentDataContainers and FastItemStack 2022-04-20 11:19:24 +01:00
Auxilor
cb64dedd74 Updated to kotlin 1.6.21 2022-04-20 10:57:27 +01:00
Auxilor
a7c489413e Moved IridiumSkyblock to use jar 2022-04-20 10:56:47 +01:00
Auxilor
f9ed174e31 Added PersistentDataHolder to FastItemStack 2022-04-13 13:21:37 +01:00
Auxilor
496d878a14 Added missing FIS method 2022-04-13 12:55:48 +01:00
Auxilor
00853d4a92 Fixed getSkullTexture 2022-04-13 12:39:32 +01:00
Auxilor
5eb0d2380a Updated to 6.33.0 2022-04-13 12:37:19 +01:00
Auxilor
d19cff9a42 Added component methods to FastItemStack 2022-04-13 12:36:49 +01:00
Auxilor
234b5fdd8e Fixed newbiehelper and bentobox 2022-04-11 15:02:29 +01:00
Auxilor
2dbe6c7fe4 Updated to 6.32.2 2022-04-11 14:55:48 +01:00
Auxilor
9d4d1ace08 Fixed use_spell and tempt 2022-04-11 14:55:35 +01:00
Auxilor
364550d228 Pain 2022-04-06 13:47:01 +01:00
Auxilor
d5e8cbaf33 Updated to 6.32.1 2022-04-06 13:35:34 +01:00
Auxilor
c4d532fda9 Removed MySQL relocation 2022-04-06 13:34:33 +01:00
Auxilor
aa097cf7e2 Fixed wrong MySQL driver class 2022-04-06 13:08:29 +01:00
Auxilor
6f4ca40a94 Changed load order for custom items 2022-04-05 16:29:13 +01:00
Auxilor
2ef9b4033c Updated to 6.32.0 2022-04-05 15:38:44 +01:00
Auxilor
9aa22ffc86 Added Items#mergeFrom 2022-04-05 15:38:34 +01:00
Auxilor
d81c1e6fcb Added comment 2022-04-05 13:22:13 +01:00
Auxilor
ac72e0770a Undid last commit 2022-04-05 13:17:29 +01:00
Auxilor
5e3e09c4bc Moved adventure api to api configuration 2022-04-05 13:17:07 +01:00
Auxilor
ee945d5901 Updated to 6.31.4 2022-04-05 13:14:48 +01:00
Auxilor
7f747f3afc Fixed & color code 2022-04-05 13:12:49 +01:00
Auxilor
2d47593f51 More build changes 2022-04-05 13:12:29 +01:00
Auxilor
df529ba239 Minimized use of the lib-loader 2022-04-05 13:01:05 +01:00
Auxilor
2fea736631 Updated to 6.31.3 2022-04-02 14:36:23 +01:00
Auxilor
9df4fae2dc Fixed colors in console on new versions of paper 2022-04-02 14:36:14 +01:00
Auxilor
ca964a1a40 Updated to 6.31.2 and fixed default key values 2022-03-29 16:17:59 +01:00
Auxilor
ada2832839 Fixed data.yml 2022-03-28 21:24:34 +01:00
Auxilor
4d92cbb7ff Fixed PersistentDataKeyType equality 2022-03-28 14:33:28 +01:00
Auxilor
d6ab36929b Changed data reading 2022-03-28 14:29:56 +01:00
Auxilor
e06623d3fe Fixed some config constructors 2022-03-28 14:23:27 +01:00
Auxilor
8b70a37459 Updated to 6.31.1 2022-03-28 14:21:19 +01:00
Auxilor
daab3829bc Config changes 2022-03-28 14:21:09 +01:00
Auxilor
d09021707b Fixed name arg parser 2022-03-27 13:20:53 +01:00
Auxilor
bea8cb5757 Updated to 6.31.0 2022-03-27 13:20:21 +01:00
Auxilor
bde546efcb Added Items#toLookupString 2022-03-27 13:19:48 +01:00
Auxilor
e1ffc851a3 Updated to 6.30.2 2022-03-26 16:02:09 +00:00
Auxilor
828229b3e5 Updated to 6.30.1 2022-03-26 15:43:34 +00:00
Auxilor
f36e2f5349 Fixed config header duplication bug 2022-03-26 15:43:24 +00:00
Auxilor
cdbe5b141a Fixed yaml printing 2022-03-24 18:13:11 +00:00
Auxilor
08c3fc0cfa Fixed config removing 2022-03-24 15:53:12 +00:00
Auxilor
8f758fb100 Changed bukkit -> eco config mapping 2022-03-24 12:21:15 +00:00
Auxilor
ec339b0ecd Removed debug println 2022-03-24 12:13:49 +00:00
Auxilor
9dedfb86a5 Fixed more config things 2022-03-24 12:13:02 +00:00
Auxilor
0146cff8d3 More config work 2022-03-24 11:26:41 +00:00
Auxilor
2454d99d84 Reworked getKeys 2022-03-24 10:50:35 +00:00
Auxilor
7d9b1bc266 Removed debug toggle 2022-03-24 10:46:52 +00:00
Auxilor
77c56c46a8 Keep the reworks coming 2022-03-24 10:41:09 +00:00
Auxilor
85303098a7 Reworked configs (again) 2022-03-24 09:46:27 +00:00
Auxilor
821dc62d56 More anti-anchor prevention 2022-03-23 19:44:23 +00:00
Auxilor
f9af4a9e66 Removed debug 2022-03-23 16:26:51 +00:00
Auxilor
41b9d6b01d Config cleanup 2022-03-23 16:24:17 +00:00
Auxilor
7a521acccf More config improvements (and codestyle) 2022-03-23 15:50:25 +00:00
Auxilor
49233aef88 Comment headers are now preserved 2022-03-23 15:32:43 +00:00
Auxilor
c5b47ed073 And they dont stop coming 2022-03-23 14:21:25 +00:00
Auxilor
ddcef7cf0c The config rewrites never stop 2022-03-23 13:53:56 +00:00
Auxilor
0f86e1c1c1 More config rewrites 2022-03-23 12:59:53 +00:00
Auxilor
f0f7e229ea Began complete config rewrite 2022-03-23 12:28:34 +00:00
Auxilor
ea674a3757 Merge remote-tracking branch 'origin/develop' into develop 2022-03-23 10:51:50 +00:00
Auxilor
b7c51eba5e Fixed more config bugs 2022-03-22 19:55:19 +00:00
Auxilor
1127bf1700 Renamed ConfigBuilder to BuildableConfig 2022-03-22 16:59:20 +00:00
Auxilor
376e3284fb Fixed config bugs 2022-03-22 16:53:16 +00:00
Auxilor
12f355b205 Fixed GUI and rendering bugs 2022-03-22 16:46:32 +00:00
Auxilor
f4b02591e8 Clarified javadoc 2022-03-22 16:25:18 +00:00
Auxilor
f843725cf5 Fixed missing method 2022-03-22 16:16:58 +00:00
Auxilor
ed0536c188 Fixed stupidity 2022-03-22 14:14:45 +00:00
Auxilor
849e005095 More oraxen tweaks 2022-03-22 14:12:39 +00:00
Auxilor
927d61dd6b Marked ConfigUpdater as @Documented 2022-03-22 14:09:36 +00:00
Auxilor
9285cffc56 Updated ConfigUpdater javadoc 2022-03-22 14:08:25 +00:00
Auxilor
1b6c90e87d Updated to 6.30.0 2022-03-22 14:07:14 +00:00
Auxilor
c79de6fbc1 Marked more deprecated things as for removal 2022-03-22 14:06:59 +00:00
Auxilor
fc83ebbb34 Removed all long-deprecated config methods 2022-03-22 14:03:02 +00:00
Auxilor
f330cc954c Added ConfigBuilder and more TransientConfig constructors 2022-03-22 14:01:18 +00:00
Auxilor
df4f98251c Improved setting with JSON configs 2022-03-22 12:58:20 +00:00
Auxilor
74861e9c01 Improved config setters 2022-03-22 11:36:16 +00:00
Auxilor
7dad9d7875 Fixed config setters 2022-03-22 11:24:27 +00:00
Auxilor
338b9b2d4e Fixed configs 2022-03-22 11:02:01 +00:00
Auxilor
f6d83867f3 Updated to 6.29.3 2022-03-22 10:41:52 +00:00
Auxilor
bb632ac849 Codestyle 2022-03-22 10:40:02 +00:00
Auxilor
793f946b44 Removed long-deprecated, for-removal configs 2022-03-22 10:39:20 +00:00
Auxilor
519a59cc88 Reworked configs, marked all deprecated configs for removal 2022-03-22 10:35:44 +00:00
Auxilor
79b1bff547 Recoded GUI internals 2022-03-22 09:55:10 +00:00
Auxilor
17ee1ac2ff Updated to 6.29.2 2022-03-20 15:44:06 +00:00
Auxilor
a6fa446d95 Fixed Head Database integration 2022-03-20 15:43:55 +00:00
Auxilor
2f98c0ace5 Updated to 6.29.1 2022-03-18 09:40:35 +00:00
Auxilor
60d7abcda8 Fixed oraxen integration 2022-03-18 09:40:26 +00:00
Auxilor
69a5fa81b4 Updated MythicMobs 2022-03-16 20:48:42 +00:00
Auxilor
0316e627e1 Updated to 6.29.0 2022-03-16 13:22:17 +00:00
Auxilor
5bc5b47bf8 Added Menu#refresh 2022-03-16 13:22:05 +00:00
Auxilor
a9c906843d Updated to 6.28.3 2022-03-13 16:59:14 +00:00
Auxilor
85861971d3 Added wildcard material testable items 2022-03-13 16:59:02 +00:00
Auxilor
bdb24e5a14 Updated to 6.28.2 2022-03-12 21:03:59 +00:00
Auxilor
cb481d4532 Fixed 1.17.1 and 1.18.1 errors 2022-03-12 21:03:45 +00:00
Auxilor
97fba3e243 Updated to 6.28.1 2022-03-11 16:29:15 +00:00
Auxilor
e47c6387a2 Injecting placeholders now clears config cache 2022-03-11 16:29:05 +00:00
Auxilor
00df39097c Fixed statics in expressions 2022-03-11 16:28:21 +00:00
Auxilor
efcb406e9a Revert "Updated to 6.28.1"
This reverts commit 9e92ea6062.
2022-03-11 10:52:36 +00:00
Auxilor
9e92ea6062 Updated to 6.28.1 2022-03-11 10:41:43 +00:00
Auxilor
9dbc25df6f Added PlaceholderInjectable#clearInjectedPlaceholders 2022-03-11 09:01:57 +00:00
Auxilor
bc85c5232e Fixed more placeholder injection stuff 2022-03-11 09:00:24 +00:00
Auxilor
2f4783f13e Fixed placeholder equality 2022-03-11 08:58:58 +00:00
Auxilor
614241a058 Fixed placeholder injection on config wrappers 2022-03-11 08:47:50 +00:00
Auxilor
c541adb557 Improved PlaceholderInjectable 2022-03-10 20:42:06 +00:00
Auxilor
a484eecc8f Reworked placeholder system 2022-03-10 20:38:09 +00:00
Auxilor
3933e38891 Updated to 6.28.0 2022-03-10 19:54:58 +00:00
Auxilor
1d5345b367 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	gradle.properties
2022-03-10 19:54:25 +00:00
Auxilor
f8513ff1e9 Updated to 6.27.4 2022-03-09 11:21:14 +00:00
Auxilor
ca9c940b2b Updated/fixed crunch 2022-03-09 11:20:54 +00:00
Auxilor
af198d30f7 Updated to 6.27.3 2022-03-08 08:25:45 +00:00
Auxilor
637b239c66 Fixed MiniMessage on 1.18.2 2022-03-08 08:25:25 +00:00
Auxilor
124c059294 Fixed MiniMessage on 1.18.2 2022-03-07 12:32:52 +00:00
Auxilor
f1d0bd901d Updated to 6.28.0 2022-03-07 12:29:02 +00:00
Auxilor
20f4bf4e78 Improved shapeless recipe support 2022-03-07 12:27:21 +00:00
Auxilor
595bc76294 Added shapeless recipe support 2022-03-07 11:32:18 +00:00
Auxilor
9a66e78dcd Merge remote-tracking branch 'origin/master' 2022-03-07 10:29:15 +00:00
Auxilor
0fcf229bfb Fixed missing javadoc jar 2022-03-07 10:28:59 +00:00
Will FP
d2ffc43b17 Update README.md 2022-03-07 10:25:50 +00:00
Auxilor
c50f69b372 Fixed javadoc 2022-03-07 10:16:52 +00:00
Will FP
f5eafafc4c Update README.md 2022-03-06 15:50:39 +00:00
Auxilor
39372c9b1a Updated to 6.27.2 2022-03-06 13:59:51 +00:00
Auxilor
4c64f03aa1 Fixed isCustomItem 2022-03-06 13:59:42 +00:00
Auxilor
6bb4e301bc Merge remote-tracking branch 'origin/master' 2022-03-05 12:59:51 +00:00
Auxilor
827e9fd98a Cleanup 2022-03-05 12:56:32 +00:00
Auxilor
c3e9bbbc50 Updated to 6.27.1 2022-03-05 12:53:43 +00:00
Auxilor
7328881977 Cleaned up MythicMobs drop support PR 2022-03-05 12:53:11 +00:00
Auxilor
00531d0a04 Merge branch '0ft3n_master' into develop 2022-03-05 12:39:44 +00:00
Auxilor
5d4a2b4633 Updated guava 2022-03-05 12:37:33 +00:00
Auxilor
28c86460fc Merge remote-tracking branch 'origin/master' into develop 2022-03-05 12:37:27 +00:00
Will FP
4a1d714b71 Merge pull request #101
Bump guava from 31.0.1-jre to 31.1-jre
2022-03-05 12:37:02 +00:00
Will FP
4ef16530d3 Merge pull request #106
Bump io.papermc.paperweight.userdev from 1.3.4 to 1.3.5
2022-03-05 12:36:47 +00:00
Auxilor
a22ad1b22d Optimized custom item cache 2022-03-05 12:34:39 +00:00
dependabot[bot]
623c3589a3 Bump io.papermc.paperweight.userdev from 1.3.4 to 1.3.5
Bumps [io.papermc.paperweight.userdev](https://github.com/PaperMC/paperweight) from 1.3.4 to 1.3.5.
- [Release notes](https://github.com/PaperMC/paperweight/releases)
- [Commits](https://github.com/PaperMC/paperweight/compare/v1.3.4...v1.3.5)

---
updated-dependencies:
- dependency-name: io.papermc.paperweight.userdev
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 21:21:12 +00:00
Auxilor
44924cdf83 MiniMessage safety checks 2022-03-04 11:00:36 +00:00
Auxilor
75363181e4 MiniMessage is an endless source of suffering 2022-03-04 10:56:27 +00:00
Auxilor
1fc9d66457 Even more minimessage pain 2022-03-04 10:50:02 +00:00
Auxilor
2fdbe0da28 More minimessage pain 2022-03-04 10:40:56 +00:00
Auxilor
a1922cb195 MiniMessage pain 2022-03-04 10:36:35 +00:00
Auxilor
725e950092 Updated MiniMessage and adventure-platform 2022-03-04 09:21:44 +00:00
Auxilor
bf123d3105 Fixed init order bug 2022-03-04 09:16:30 +00:00
dependabot[bot]
83b6721484 Bump guava from 31.0.1-jre to 31.1-jre
Bumps [guava](https://github.com/google/guava) from 31.0.1-jre to 31.1-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 09:13:02 +00:00
Auxilor
dca952c10a Fixed deprecated adventure api usage 2022-03-04 09:11:10 +00:00
Auxilor
b2e5896885 Updated MiniMessage 2022-03-04 09:08:48 +00:00
Auxilor
38542dad5e Added utility methods to EntityGoals and TargetGoals 2022-03-04 09:07:21 +00:00
Auxilor
852a9c5fb1 Updated v1_18_R2 module, updated adventure 2022-03-04 09:02:12 +00:00
Auxilor
12aa0e349e Updated paper to 1.18.2 2022-03-04 08:53:09 +00:00
Auxilor
351f5d8c16 Updated KingdomsX 2022-03-03 17:29:43 +00:00
Auxilor
7e4b3075ed Added maxmimum size to recipes cache 2022-03-03 14:52:29 +00:00
Auxilor
cf0d725189 Improved removing entity goals 2022-03-03 14:50:26 +00:00
Auxilor
a9f33fb846 Refactoring delegated spellcasters 2022-03-03 14:19:18 +00:00
Auxilor
4a9ab7a0eb Added EntityGoalIllusionerBlindnessSpell and EntityGoalIllusionerMirrorSpell 2022-03-03 14:16:25 +00:00
Auxilor
3982ab99a6 Added some entity goals 2022-03-03 13:32:26 +00:00
Auxilor
1fb39e55d2 Removed redundant suppression 2022-03-03 11:58:25 +00:00
Auxilor
56d32b532d Move improvements to CustomGoal 2022-03-03 10:12:02 +00:00
Auxilor
0d0800dfb5 Improved CustomGoal 2022-03-03 10:07:40 +00:00
Auxilor
f32110687f Added missing nullability parameter 2022-03-03 09:47:36 +00:00
Auxilor
dbf39f3621 Added more helpful utility methods 2022-03-03 09:46:14 +00:00
Auxilor
9a2f0e3df8 Switched from com.willfp.libs.shaded to com.willfp.eco.libs 2022-03-03 08:31:47 +00:00
Auxilor
56fb9b40b9 Added Goal<T>, which EntityGoal<T> and TargetGoal<T> extend from, giving them a shared parent class 2022-03-02 20:17:06 +00:00
Auxilor
fbc7bb6f07 Tempt now uses TestableItem 2022-03-02 19:12:59 +00:00
Auxilor
2294c3758d Fixed ItemStack.mergeIfNeeded 2022-03-02 18:52:12 +00:00
Auxilor
c573da6e31 Suppressed warning 2022-03-02 18:51:07 +00:00
Auxilor
6362931e6b Stopped using percentages in goals 2022-03-02 18:48:44 +00:00
Auxilor
0be1f45edc Fixed refactoring bugs 2022-03-02 18:45:34 +00:00
Auxilor
9700aa7eac Added secondary constructors without predicates 2022-03-02 18:39:32 +00:00
Auxilor
75eaf58aa2 NMS Refactoring 2022-03-02 18:29:11 +00:00
Auxilor
63352989b1 Switched interact and hurt_by to use TestableEntity 2022-03-02 18:05:03 +00:00
Auxilor
dd5e0e3847 Switched class-based entity restrictions to TestableEntity where possible 2022-03-02 17:52:00 +00:00
Auxilor
4f009c6d57 EntityGoalAvoidEntity now functions using TestableEntity 2022-03-02 17:45:40 +00:00
Auxilor
09d4db816e Renaming goals, second pass 2022-03-02 16:22:18 +00:00
Auxilor
fb7799e931 Renaming goals, first pass 2022-03-02 16:01:16 +00:00
Auxilor
13a1965f03 Added EntityController#clearAllGoals 2022-03-02 15:06:53 +00:00
Auxilor
3abefb73f9 Added deserializers for all entity goals 2022-03-02 14:38:46 +00:00
Auxilor
a35f5bb405 Added deserializers for all target goals 2022-03-02 14:13:49 +00:00
Auxilor
88a7fb53a3 Added ConfigSerializer, ConfigDeserializer, made Testable extend Predicate 2022-03-02 13:48:05 +00:00
Auxilor
866ba8440d Refactored EntityController.of to EntityController.getFor 2022-03-02 13:10:39 +00:00
Auxilor
61896bbddd Commons refactoring 2022-03-02 12:53:21 +00:00
Auxilor
7a4891d4e3 Fixed refactoring bugs 2022-03-02 12:48:13 +00:00
Auxilor
dbd5cd341e Moved FastItemStack into commons 2022-03-02 12:42:41 +00:00
Auxilor
7df707a59d Updated goal javadoc 2022-03-02 12:33:35 +00:00
Auxilor
92dfa32d07 CustomGoal inheritance fixes 2022-03-02 12:22:37 +00:00
Auxilor
5cad1d31e3 Added v1_18_R2 Module (to be updated when papermc updates) 2022-03-02 12:18:41 +00:00
Auxilor
e4c0418fd4 Removed requirement system 2022-03-02 12:14:21 +00:00
Auxilor
54c74d0138 Added more goals, added shorthand goal syntax, added kotlin extension for entity controllers 2022-03-02 12:14:03 +00:00
Auxilor
6e21bdeb5b Updated/Added some goals 2022-03-02 12:03:28 +00:00
Auxilor
00439a1b04 Began refactoring NMS 2022-03-02 11:52:49 +00:00
Auxilor
87684abbbb Fixed NMS buildscripts some more 2022-03-02 11:28:16 +00:00
Auxilor
0cbf78733e Changed NMS Commons relocation 2022-03-02 11:24:37 +00:00
Auxilor
ecf0e7c356 NMS Buildscript changes 2022-03-02 11:22:49 +00:00
Auxilor
f20d9884b5 NMS Commons changes 2022-03-02 11:18:55 +00:00
Auxilor
61d713ad4d Moved NMS AI implementations into craftbukkit-less commons 2022-03-02 11:15:44 +00:00
Auxilor
ca5cce3f40 Fixed shadow relocations 2022-03-01 22:28:33 +00:00
Auxilor
1c8edac807 Finally fixed intersection generics 2022-03-01 22:26:47 +00:00
Auxilor
98b465f8f3 Take 3 at fixing generic issues 2022-03-01 22:20:12 +00:00
Auxilor
3c3e34eda3 Take 2 at fixing generic issues 2022-03-01 22:16:09 +00:00
Auxilor
02ad6f7810 Fixed issues with generics 2022-03-01 22:14:25 +00:00
Auxilor
5369ee7d42 Improved CustomGoal 2022-03-01 22:06:39 +00:00
Auxilor
c441e0761f Updated to 6.27.0 2022-03-01 21:10:42 +00:00
Auxilor
a02dd06c20 Added entity goals in for 1_18_R1, minor refactoring 2022-03-01 21:10:02 +00:00
Auxilor
957af5c5bf Continued work on entity controllers 2022-03-01 21:01:00 +00:00
Auxilor
2c51a6900f Added remaining entity goals 2022-03-01 20:40:45 +00:00
Auxilor
e09e9b4e8d Added more entity goals 2022-03-01 20:20:02 +00:00
Auxilor
02497d485b Added more entity goals 2022-03-01 20:04:04 +00:00
Auxilor
bd32f3bc8d Continued implementing entity goals 2022-03-01 19:58:05 +00:00
Auxilor
7176342e15 Continued goal implementation 2022-03-01 19:44:27 +00:00
Auxilor
32ef8d8c5c Began entity controller system 2022-03-01 18:04:27 +00:00
Auxilor
92f8787eb9 Updated to 6.26.3 2022-03-01 13:03:56 +00:00
Auxilor
5403f7a9ed Fixed multiple option display 2022-03-01 11:29:51 +00:00
Auxilor
2924d6f560 All options are now shown to players in crafting 2022-03-01 11:22:31 +00:00
Auxilor
36c0708c17 (Narrator voice) It wasn't 2022-03-01 10:56:54 +00:00
Auxilor
b9fe54e883 This isn't going to be the last commit, is it 2022-03-01 10:49:09 +00:00
Auxilor
5cc2f23547 Removed debug messages 2022-03-01 10:40:07 +00:00
Auxilor
30514ba780 Suffering 2022-03-01 10:39:24 +00:00
Auxilor
02e6c5e8f3 More working around how broken spigot is 2022-03-01 10:35:49 +00:00
Auxilor
fac97329aa Working around how broken spigot is 2022-03-01 10:31:19 +00:00
Auxilor
cdf5cc3abe Suppressed warnings 2022-03-01 10:25:43 +00:00
Auxilor
4cb630d201 Fixed crafting, deprecated now-unneeded API 2022-03-01 10:24:38 +00:00
Auxilor
79d6277d94 Updated to 6.26.2 2022-03-01 08:33:24 +00:00
Auxilor
1a90fa6707 Fixed ComplexInEco 2022-03-01 08:33:14 +00:00
0ft3n
d0d64b3e58 Merge branch 'Auxilor:master' into master 2022-02-23 11:43:39 +03:00
often
49273abbfc Added Items lookup system support to mythicmobs drops 2022-02-23 11:32:46 +03:00
451 changed files with 13922 additions and 4598 deletions

View File

@@ -39,7 +39,7 @@ and many more.
# For developers
## Javadoc
The 6.13.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.13.0/javadoc/)
The 6.38.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.38.2/javadoc/)
## Plugin Information
@@ -68,7 +68,7 @@ dependencies {
}
```
Replace `Tag` with a release tag for eco, eg `6.13.0`.
Replace `Tag` with a release tag for eco, eg `6.27.2`.
Maven:
@@ -88,7 +88,7 @@ Maven:
</dependency>
```
Replace `Tag` with a release tag for eco, eg `6.13.0`.
Replace `Tag` with a release tag for eco, eg `6.27.2`.
## Build locally:

View File

@@ -4,7 +4,7 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
}
}
@@ -13,16 +13,18 @@ plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
id("maven-publish")
id("java")
kotlin("jvm") version "1.6.10"
kotlin("jvm") version "1.7.10"
}
dependencies {
implementation(project(":eco-api"))
implementation(project(":eco-core:core-plugin"))
implementation(project(path = ":eco-core:core-plugin", configuration = "shadow"))
implementation(project(":eco-core:core-proxy"))
implementation(project(":eco-core:core-backend"))
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
}
allprojects {
@@ -43,11 +45,8 @@ allprojects {
// SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/")
// NMS (for jitpack compilation)
maven("https://repo.codemc.org/repository/nms/")
// mcMMO, BentoBox
maven("https://repo.codemc.org/repository/maven-public/")
maven("https://repo.codemc.io/repository/maven-public/")
// Spigot API, Bungee API
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
@@ -62,7 +61,7 @@ allprojects {
maven("https://maven.enginehub.org/repo/")
// FactionsUUID
maven("https://ci.ender.zone/plugin/repository/everything/")
//maven("https://ci.ender.zone/plugin/repository/everything/")
// NoCheatPlus
maven("https://repo.md-5.net/content/repositories/snapshots/")
@@ -70,9 +69,6 @@ allprojects {
// CombatLogX
maven("https://nexus.sirblobman.xyz/repository/public/")
// IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// MythicMobs
maven("https://mvn.lumine.io/repository/maven-public/")
@@ -81,24 +77,34 @@ allprojects {
// LibsDisguises
maven("https://repo.md-5.net/content/groups/public/")
// FabledSkyblock
maven("https://repo.songoda.com/repository/public/")
}
dependencies {
compileOnly(kotlin("stdlib", version = "1.6.10"))
// Kotlin
implementation(kotlin("stdlib", version = "1.7.10"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
// Included in spigot jar, no need to move to implementation
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.google.guava:guava:31.1-jre")
// Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
// Adventure
compileOnly("net.kyori:adventure-api:4.9.3")
compileOnly("net.kyori:adventure-text-serializer-gson:4.9.3")
compileOnly("net.kyori:adventure-text-serializer-legacy:4.9.3")
implementation("net.kyori:adventure-api:4.10.1")
implementation("net.kyori:adventure-text-serializer-gson:4.10.1") {
exclude("com.google.code.gson", "gson") // Prevent shading into the jar
}
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
// Other
compileOnly("com.google.guava:guava:31.0.1-jre")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5")
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
implementation("org.apache.maven:maven-artifact:3.8.5")
}
tasks.withType<JavaCompile> {
@@ -113,10 +119,12 @@ allprojects {
exclude(group = "org.spongepowered", module = "configurate-hocon")
exclude(group = "com.darkblade12", module = "particleeffect")
exclude(group = "com.github.cryptomorin", module = "XSeries")
exclude(group = "net.wesjd", module = "anvilgui")
exclude(group = "org.slf4j", module = "slf4j-api")
}
configurations.testImplementation {
setExtendsFrom(listOf(configurations.compileOnly.get()))
setExtendsFrom(listOf(configurations.compileOnly.get(), configurations.implementation.get()))
}
tasks {
@@ -124,13 +132,40 @@ allprojects {
kotlinOptions {
jvmTarget = "17"
}
targetCompatibility = "17"
sourceCompatibility = "17"
}
shadowJar {
relocate("org.bstats", "com.willfp.eco.shaded.bstats")
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage")
relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
}
compileJava {

View File

@@ -1,11 +1,9 @@
dependencies {
// Adventure
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
// Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.8'
}
@@ -13,6 +11,10 @@ dependencies {
group 'com.willfp'
version rootProject.version
java {
withJavadocJar()
}
build.dependsOn publishToMavenLocal
publishing {

View File

@@ -304,6 +304,11 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.logger = Eco.getHandler().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName());
this.scheduler = Eco.getHandler().createScheduler(this);
this.eventManager = Eco.getHandler().createEventManager(this);
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
@@ -311,8 +316,6 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
this.extensionLoader = Eco.getHandler().createExtensionLoader(this);
this.configHandler = Eco.getHandler().createConfigHandler(this);
this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.langYml = this.createLangYml();
this.configYml = this.createConfigYml();
@@ -347,15 +350,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0) {
if (this.getResourceId() != 0 && !Eco.getHandler().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true;
this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
this.getLogger().warning("&cThe newest version is &f" + version);
this.getLogger().warning("&cDownload the new version!");
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
this.getLogger().warning("The newest version is " + version);
this.getLogger().warning("Download the new version!");
}
});
}
@@ -374,12 +377,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
}
this.loadIntegrationLoaders().forEach((integrationLoader -> {
this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName());
integrationLoader.load();
}
}));
});
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
@@ -489,9 +492,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void reload() {
this.getConfigHandler().updateConfigs();
this.getScheduler().cancelAll();
this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.getScheduler().cancelAll();
this.handleReload();
@@ -694,7 +697,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final FileConfiguration getConfig() {
this.getLogger().warning("Call to default config method in eco plugin!");
return Objects.requireNonNull(this.getConfigYml().getBukkitHandle());
return Objects.requireNonNull(this.getConfigYml().toBukkit());
}
/**

View File

@@ -2,9 +2,11 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
@@ -13,6 +15,7 @@ import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.items.SNBTHandler;
import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
@@ -20,7 +23,9 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,7 +37,6 @@ import java.util.logging.Logger;
* @see Eco#getHandler()
*/
@ApiStatus.Internal
@SuppressWarnings("removal")
public interface Handler {
/**
* Create a scheduler.
@@ -262,4 +266,47 @@ public interface Handler {
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
/**
* Adapt base PDC to extended PDC.
*
* @param container The container.
* @return The extended container.
*/
@NotNull
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
/**
* Get SNBT handler.
*
* @return The SNBT handler.
*/
@NotNull
SNBTHandler getSNBTHandler();
}

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -234,7 +233,6 @@ public final class PluginProps {
* @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props.
*/
@ApiStatus.Internal
static PluginProps createSimple(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,

View File

@@ -26,7 +26,7 @@ public class Prerequisite {
* Requires the server to be running an implementation of paper.
*/
public static final Prerequisite HAS_PAPER = new Prerequisite(
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
() -> ClassUtils.exists("com.destroystokyo.paper.event.block.BeaconEffectEvent"),
"Requires server to be running paper (or a fork)"
);
@@ -35,17 +35,25 @@ public class Prerequisite {
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/
@Deprecated
@Deprecated(forRemoval = true)
public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault"
);
/**
* Requires the server to be running 1.19.
*/
public static final Prerequisite HAS_1_19 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19"),
"Requires server to be running 1.19+"
);
/**
* Requires the server to be running 1.18.
*/
public static final Prerequisite HAS_1_18 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("18"),
() -> ProxyConstants.NMS_VERSION.contains("18") || HAS_1_19.isMet(),
"Requires server to be running 1.18+"
);
@@ -54,7 +62,7 @@ public class Prerequisite {
*
* @deprecated eco no longer supports versions before 1.17.
*/
@Deprecated(since = "6.25.2")
@Deprecated(since = "6.25.2", forRemoval = true)
public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
"Requires server to be running 1.17+"

View File

@@ -10,6 +10,7 @@ import java.util.List;
/**
* Interface for all command implementations.
*/
@SuppressWarnings("removal")
public interface CommandBase {
/**
* Get command name.
@@ -81,7 +82,7 @@ public interface CommandBase {
* @see CommandHandler
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
*/
@Deprecated
@Deprecated(forRemoval = true)
CommandHandler getHandler();
/**
@@ -91,7 +92,7 @@ public interface CommandBase {
* @see CommandHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated
@Deprecated(forRemoval = true)
void setHandler(@NotNull CommandHandler handler);
/**
@@ -101,7 +102,7 @@ public interface CommandBase {
* @see TabCompleteHandler
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
*/
@Deprecated
@Deprecated(forRemoval = true)
TabCompleteHandler getTabCompleter();
/**
@@ -111,6 +112,6 @@ public interface CommandBase {
* @see TabCompleteHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated
@Deprecated(forRemoval = true)
void setTabCompleter(@NotNull TabCompleteHandler handler);
}

View File

@@ -16,7 +16,7 @@ import java.util.List;
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
*/
@FunctionalInterface
@Deprecated(since = "6.17.0")
@Deprecated(since = "6.17.0", forRemoval = true)
public interface CommandHandler {
/**
* The code to be called on execution.

View File

@@ -16,7 +16,7 @@ import java.util.List;
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
*/
@FunctionalInterface
@Deprecated(since = "6.17.0")
@Deprecated(since = "6.17.0", forRemoval = true)
public interface TabCompleteHandler {
/**
* Handle Tab Completion.

View File

@@ -2,8 +2,6 @@ package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandBase;
import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.TabCompleteHandler;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
@@ -23,7 +21,7 @@ import java.util.stream.Collectors;
* in order to execute the command-specific code. It's essentially an internal
* layer, hence why it's a package-private class.
*/
@SuppressWarnings({"DeprecatedIsStillUsed"})
@SuppressWarnings({"DeprecatedIsStillUsed", "removal"})
abstract class HandledCommand implements CommandBase {
/**
* The plugin.
@@ -54,14 +52,14 @@ abstract class HandledCommand implements CommandBase {
*/
@Deprecated
@Nullable
private CommandHandler handler = null;
private com.willfp.eco.core.command.CommandHandler handler = null;
/**
* The tab completion code to be executed in the command.
*/
@Deprecated
@Nullable
private TabCompleteHandler tabCompleter = null;
private com.willfp.eco.core.command.TabCompleteHandler tabCompleter = null;
/**
* All subcommands for the command.
@@ -169,7 +167,10 @@ abstract class HandledCommand implements CommandBase {
StringUtil.copyPartialMatches(
args[0],
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
this.getSubcommands().stream()
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
.map(CommandBase::getName)
.collect(Collectors.toList()),
completions
);
@@ -184,6 +185,10 @@ abstract class HandledCommand implements CommandBase {
HandledCommand command = null;
for (CommandBase subcommand : this.getSubcommands()) {
if (!sender.hasPermission(subcommand.getPermission())) {
continue;
}
if (args[0].equalsIgnoreCase(subcommand.getName())) {
command = (HandledCommand) subcommand;
}
@@ -256,27 +261,27 @@ abstract class HandledCommand implements CommandBase {
return this.subcommands;
}
@Deprecated
@Deprecated(forRemoval = true)
@Override
public @Nullable CommandHandler getHandler() {
public @Nullable com.willfp.eco.core.command.CommandHandler getHandler() {
return this.handler;
}
@Deprecated
@Deprecated(forRemoval = true)
@Override
public @Nullable TabCompleteHandler getTabCompleter() {
public @Nullable com.willfp.eco.core.command.TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
@Deprecated
@Deprecated(forRemoval = true)
@Override
public void setHandler(@Nullable final CommandHandler handler) {
public void setHandler(@Nullable final com.willfp.eco.core.command.CommandHandler handler) {
this.handler = handler;
}
@Deprecated
@Deprecated(forRemoval = true)
@Override
public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) {
public void setTabCompleter(@Nullable final com.willfp.eco.core.command.TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter;
}
}

View File

@@ -23,13 +23,31 @@ public abstract class BaseConfig extends LoadableConfigWrapper {
@NotNull final PluginLike plugin,
final boolean removeUnused,
@NotNull final ConfigType type) {
this(configName, plugin, removeUnused, type, true);
}
/**
* Create new Base Config.
*
* @param plugin The plugin or extension.
* @param configName The config name (excluding extension).
* @param removeUnused If unused sections should be removed.
* @param type The config type.
* @param requiresChangeToSave If changes must be applied to save the config.
*/
protected BaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
final boolean removeUnused,
@NotNull final ConfigType type,
final boolean requiresChangeToSave) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
type
type,
requiresChangeToSave
));
}
}

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core.config;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Builder for configs to create them programmatically.
*/
public class BuildableConfig extends TransientConfig {
/**
* Create a new empty config builder.
*/
public BuildableConfig() {
super();
}
/**
* Add to the config builder.
*
* @param path The path.
* @param object The object.
* @return The builder.
*/
public BuildableConfig add(@NotNull final String path,
@Nullable final Object object) {
set(path, object);
return this;
}
}

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.config;
import org.jetbrains.annotations.NotNull;
/**
* Config types, classified by file extension.
*/
@@ -7,10 +9,28 @@ public enum ConfigType {
/**
* .json config.
*/
JSON,
JSON("json"),
/**
* .yml config.
*/
YAML
YAML("yml");
/**
* The file extension.
*/
private final String extension;
ConfigType(@NotNull final String extension) {
this.extension = extension;
}
/**
* Get the file extension.
*
* @return The extension.
*/
public String getExtension() {
return extension;
}
}

View File

@@ -38,6 +38,7 @@ public abstract class ExtendableConfig extends LoadableConfigWrapper {
source,
removeUnused,
type,
true,
updateBlacklist
));
}

View File

@@ -26,7 +26,8 @@ public abstract class StaticBaseConfig extends LoadableConfigWrapper {
plugin,
"",
plugin.getClass(),
type
type,
true
));
}
}

View File

@@ -3,12 +3,17 @@ package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
/**
@@ -18,10 +23,19 @@ import java.util.Map;
*/
public class TransientConfig extends ConfigWrapper<Config> {
/**
* @param config The ConfigurationSection handle.
*/
public TransientConfig(@NotNull final ConfigurationSection config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
}
/**
* Exists for backwards compatibility, YamlConfigurations are ConfigurationSections.
*
* @param config The YamlConfiguration handle.
*/
public TransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
this((ConfigurationSection) config);
}
/**
@@ -33,20 +47,50 @@ public class TransientConfig extends ConfigWrapper<Config> {
)) : new TransientConfig());
}
/**
* @param file The File.
* @deprecated Specify the config type to prevent bugs.
*/
@Deprecated(since = "6.30.0", forRemoval = true)
public TransientConfig(@Nullable final File file) {
this(file, ConfigType.YAML);
}
/**
* @param file The file.
* @param type The config type to try read from.
*/
public TransientConfig(@Nullable final File file,
@NotNull final ConfigType type) {
super(file != null ? Eco.getHandler().getConfigFactory().createConfig(readFile(file), type)
: new TransientConfig());
}
/**
* Create a new empty transient config.
*
* @param values The values.
*/
public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values));
super(Eco.getHandler().getConfigFactory().createConfig(values, ConfigType.YAML));
}
/**
* Create a new empty transient config.
*
* @param values The values.
* @param type The type.
*/
public TransientConfig(@NotNull final Map<String, Object> values,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(values, type));
}
/**
* Create a new empty transient config.
*/
public TransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML));
this(new HashMap<>(), ConfigType.JSON);
}
/**
@@ -57,4 +101,22 @@ public class TransientConfig extends ConfigWrapper<Config> {
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
}
/**
* Read a file to a string.
*
* @param file The file.
* @return The string.
*/
private static String readFile(@Nullable final File file) {
if (file == null) {
return "";
}
try {
return Files.readString(file.toPath());
} catch (IOException e) {
return "";
}
}
}

View File

@@ -1,16 +1,27 @@
package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.BuildableConfig;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.TransientConfig;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
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.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* All configs implement this interface.
@@ -18,11 +29,16 @@ import java.util.Objects;
* Contains all methods that must exist in yaml and json configurations.
*/
@SuppressWarnings("unused")
public interface Config extends Cloneable {
public interface Config extends Cloneable, PlaceholderInjectable {
/**
* Clears cache.
* <p>
* Configs no longer have caches as they have in previous versions.
*/
void clearCache();
@Deprecated(since = "6.31.1", forRemoval = true)
default void clearCache() {
// Do nothing.
}
/**
* Convert the config into readable text.
@@ -48,9 +64,21 @@ public interface Config extends Cloneable {
@NotNull
List<String> getKeys(boolean deep);
/**
* Recurse config keys.
*
* @param found The found keys.
* @param root The root.
* @return The keys.
*/
@NotNull
default List<String> recurseKeys(@NotNull Set<String> found,
@NotNull String root) {
return new ArrayList<>();
}
/**
* Get an object from config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#get(String)}.
*
* @param path The path.
* @return The object.
@@ -60,7 +88,6 @@ public interface Config extends Cloneable {
/**
* Set an object in config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#set(String, Object)}
*
* @param path The path.
* @param object The object.
@@ -132,6 +159,20 @@ public interface Config extends Cloneable {
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path,
@Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
}
/**
* Get an integer from config.
@@ -238,35 +279,6 @@ public interface Config extends Cloneable {
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @return The found value, or an empty string if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Deprecated(since = "6.18.0")
default String getString(@NotNull String path,
boolean format) {
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or an empty string if not found.
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
*/
@NotNull
@Deprecated
default String getString(@NotNull String path,
@NotNull final StringUtils.FormatOption option) {
return this.getString(path, true, option);
}
/**
* Get a string from config.
*
@@ -319,36 +331,6 @@ public interface Config extends Cloneable {
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Nullable
@Deprecated(since = "6.18.0")
default String getStringOrNull(@NotNull String path,
boolean format) {
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
*/
@Nullable
@Deprecated
default String getStringOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return this.getStringOrNull(path, true, option);
}
/**
* Get a string from config.
*
@@ -403,36 +385,6 @@ public interface Config extends Cloneable {
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@NotNull
@Deprecated(since = "6.18.0")
default List<String> getStrings(@NotNull String path,
boolean format) {
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
* @deprecated Use {@link Config#getFormattedStrings(String, StringUtils.FormatOption)} instead.
*/
@NotNull
@Deprecated
default List<String> getStrings(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStrings(path, false, option);
}
/**
* Get a list of strings from config.
*
@@ -491,36 +443,6 @@ public interface Config extends Cloneable {
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Nullable
@Deprecated(since = "6.18.0")
default List<String> getStringsOrNull(@NotNull String path,
boolean format) {
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
* @deprecated Use {@link Config#getFormattedStringsOrNull(String, StringUtils.FormatOption)} instead.
*/
@Nullable
@Deprecated
default List<String> getStringsOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStringsOrNull(path, false, option);
}
/**
* Get a list of strings from config.
*
@@ -563,7 +485,21 @@ public interface Config extends Cloneable {
*/
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player);
return NumberUtils.evaluateExpression(this.getString(path), player, this);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers);
}
/**
@@ -629,4 +565,48 @@ public interface Config extends Cloneable {
* @return The clone.
*/
Config clone();
@Override
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override
default @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
@Override
default void clearInjectedPlaceholders() {
// Do nothing.
}
/**
* Convert the config to a map of values.
*
* @return The values.
*/
default Map<String, Object> toMap() {
return new HashMap<>();
}
/**
* Convert the config to a map of values.
*
* @return The values.
*/
default ConfigurationSection toBukkit() {
YamlConfiguration empty = new YamlConfiguration();
empty.createSection("temp", this.toMap());
return empty.getConfigurationSection("temp");
}
/**
* Create a new config builder.
*
* @return The builder.
*/
static BuildableConfig builder() {
return new BuildableConfig();
}
}

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.interfaces;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* JSON config.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface JSONConfig extends Config {
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
default List<JSONConfig> getSubsections(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
}
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<JSONConfig> getSubsectionsOrNull(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection. Throws NPE if not found.
*/
@Override
@NotNull
JSONConfig getSubsection(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection, or null if not found.
*/
@Override
@Nullable
JSONConfig getSubsectionOrNull(@NotNull String path);
@Override
JSONConfig clone();
}

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -47,14 +47,21 @@ public interface LoadableConfig extends Config {
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This method is not recommended unless absolutely required as it
* only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML},
* and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals
* and the implementation, and so may cause problems - it exists mostly for parity with
* {@link JavaPlugin#getConfig()}.
* This used to represent the underlying config, but since 6.30.0 configs use
* their own implementations internally, without relying on bukkit.
*
* @return The config, or null if config is not yaml-based.
* @deprecated Use toBukkit() instead.
*/
@Nullable
YamlConfiguration getBukkitHandle();
@Deprecated(since = "6.30.0", forRemoval = true)
default YamlConfiguration getBukkitHandle() {
return this.toBukkit();
}
/**
* Convert the config to a bukkit {@link YamlConfiguration}.
*/
@NotNull
YamlConfiguration toBukkit();
}

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
/**
* Interface for configs that wrap an {@link YamlConfiguration}.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface WrappedYamlConfiguration {
/**
* Get the ConfigurationSection handle.
*
* @return The handle.
*/
YamlConfiguration getBukkitHandle();
}

View File

@@ -1,90 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.json).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -1,70 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -1,45 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable JSON config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super((JSONConfig) Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.JSON));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -1,37 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* Raw JSON config with a map of values at its core.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public class JSONTransientConfig extends JSONConfigWrapper {
/**
* Config implementation for passing maps.
* <p>
* Does not automatically update.
*
* @param values The map of values.
*/
public JSONTransientConfig(@NotNull final Map<String, Object> values) {
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(values));
}
/**
* Empty JSON config.
*/
public JSONTransientConfig() {
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(new HashMap<>()));
}
}

View File

@@ -1,53 +0,0 @@
package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Wrapper to handle the backend JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected JSONConfigWrapper(@NotNull final JSONConfig handle) {
super(handle);
}
@Override
public @NotNull List<JSONConfig> getSubsections(@NotNull final String path) {
return this.getHandle().getSubsections(path);
}
@Override
public @Nullable List<JSONConfig> getSubsectionsOrNull(@NotNull final String path) {
return this.getHandle().getSubsectionsOrNull(path);
}
@Override
public @NotNull JSONConfig getSubsection(@NotNull final String path) {
return this.getHandle().getSubsection(path);
}
@Override
public @Nullable JSONConfig getSubsectionOrNull(@NotNull final String path) {
return this.getHandle().getSubsectionOrNull(path);
}
@Override
public JSONConfig clone() {
return this.getHandle().clone();
}
}

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableJSONConfigWrapper(@NotNull final JSONConfig handle) {
super(handle);
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
}
@Override
public void createFile() {
((LoadableConfig) this.getHandle()).createFile();
}
@Override
public String getResourcePath() {
return ((LoadableConfig) this.getHandle()).getResourcePath();
}
@Override
public void save() throws IOException {
((LoadableConfig) this.getHandle()).save();
}
@Override
public File getConfigFile() {
return ((LoadableConfig) this.getHandle()).getConfigFile();
}
@Override
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return null;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.updating;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -29,7 +30,8 @@ import java.lang.annotation.Target;
* }</pre>
* <p>
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
* in order to prevent null pointer exceptions.
* in order to prevent null pointer exceptions - this also means that you cannot
* have config updater methods in companion objects.
* <p>
* Config update methods in all classes in a plugin jar will be called
* on reload.
@@ -39,5 +41,6 @@ import java.lang.annotation.Target;
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ConfigUpdater {
}

View File

@@ -5,7 +5,7 @@ import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -27,6 +27,7 @@ public interface ConfigFactory {
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createUpdatableConfig(@NotNull String configName,
@@ -35,6 +36,7 @@ public interface ConfigFactory {
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
boolean requiresChangesToSave,
@NotNull String... updateBlacklist);
/**
@@ -45,13 +47,15 @@ public interface ConfigFactory {
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
@NotNull ConfigType type);
@NotNull ConfigType type,
boolean requiresChangesToSave);
/**
* Create config.
@@ -59,15 +63,17 @@ public interface ConfigFactory {
* @param config The handle.
* @return The config implementation.
*/
Config createConfig(@NotNull YamlConfiguration config);
Config createConfig(@NotNull ConfigurationSection config);
/**
* Create config.
*
* @param values The values.
* @param type The config type.
* @return The config implementation.
*/
Config createConfig(@NotNull Map<String, Object> values);
Config createConfig(@NotNull Map<String, Object> values,
@NotNull ConfigType type);
/**
* Create config.

View File

@@ -2,11 +2,14 @@ package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Configs from eco have an internal implementation,
@@ -16,7 +19,7 @@ import java.util.List;
*
* @param <T> The type of the handle.
*/
@SuppressWarnings("MethodDoesntCallSuperMethod")
@SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"})
public abstract class ConfigWrapper<T extends Config> implements Config {
/**
* Configs from eco have an internal implementation,
@@ -40,6 +43,7 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
}
@Override
@Deprecated(since = "6.31.1", forRemoval = true)
public void clearCache() {
handle.clearCache();
}
@@ -59,6 +63,12 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getKeys(deep);
}
@Override
public @NotNull List<String> recurseKeys(@NotNull final Set<String> found,
@NotNull final String root) {
return handle.recurseKeys(found, root);
}
@Override
public @Nullable Object get(@NotNull final String path) {
return handle.get(path);
@@ -134,6 +144,26 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getType();
}
@Override
public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
handle.addInjectablePlaceholder(placeholders);
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return handle.getPlaceholderInjections();
}
@Override
public void clearInjectedPlaceholders() {
handle.clearInjectedPlaceholders();
}
@Override
public Map<String, Object> toMap() {
return this.handle.toMap();
}
/**
* Get the handle.
*

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -47,7 +46,7 @@ public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return this.getHandle().getBukkitHandle();
public @NotNull YamlConfiguration toBukkit() {
return this.getHandle().toBukkit();
}
}

View File

@@ -1,87 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.YAML
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -1,68 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -1,44 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable yaml config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.YAML));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -1,42 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.StringReader;
/**
* Config implementation for passing YamlConfigurations.
* <p>
* Does not automatically update.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public class YamlTransientConfig extends YamlConfigWrapper {
/**
* @param config The YamlConfiguration handle.
*/
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
}
/**
* @param contents The contents of the config.
*/
public YamlTransientConfig(@NotNull final String contents) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, ConfigType.YAML));
}
/**
* Create a new empty transient config.
*/
public YamlTransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
}
}

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableYamlConfigWrapper(@NotNull final Config handle) {
super(handle);
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
}
@Override
public void createFile() {
((LoadableConfig) this.getHandle()).createFile();
}
@Override
public String getResourcePath() {
return ((LoadableConfig) this.getHandle()).getResourcePath();
}
@Override
public void save() throws IOException {
((LoadableConfig) this.getHandle()).save();
}
@Override
public File getConfigFile() {
return ((LoadableConfig) this.getHandle()).getConfigFile();
}
@Override
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
}
}

View File

@@ -1,31 +0,0 @@
package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper to handle the backend yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected YamlConfigWrapper(@NotNull final Config handle) {
super(handle);
}
@Override
public YamlConfiguration getBukkitHandle() {
return ((WrappedYamlConfiguration) this.getHandle()).getBukkitHandle();
}
}

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* Persistent data container wrapper that allows for full string (non-namespaced) keys.
*/
public interface ExtendedPersistentDataContainer {
/**
* Set a key.
*
* @param key The key.
* @param dataType The data type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
*/
<T, Z> void set(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z value);
/**
* Get if there is a key.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return If the key is present.
*/
<T, Z> boolean has(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or null if not found.
*/
@Nullable <T, Z> Z get(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value or default if not present.
*
* @param key The key.
* @param dataType The data type.
* @param defaultValue The default value.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or the default if not found.
*/
@NotNull <T, Z> Z getOrDefault(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z defaultValue);
/**
* Get all keys, including namespaced keys.
*
* @return The keys.
*/
@NotNull
Set<String> getAllKeys();
/**
* Remove a key.
*
* @param key The key.
*/
void remove(@NotNull String key);
/**
* Get the base PDC.
*
* @return The base.
*/
@NotNull
PersistentDataContainer getBase();
/**
* Get extension for PersistentDataContainers to add non-namespaced keys.
*
* @param base The base container.
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
return Eco.getHandler().adaptPdc(base);
}
/**
* Create a new extended container.
*
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.getHandler().newPdc());
}
}

View File

@@ -68,7 +68,7 @@ public interface ProfileHandler {
* @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation.
*/
@Deprecated
@Deprecated(forRemoval = true)
default void saveAll(boolean async) {
saveAll();
}
@@ -77,8 +77,13 @@ public interface ProfileHandler {
* Save all player data.
* <p>
* Can run async if using MySQL.
*
* @deprecated Never used.
*/
void saveAll();
@Deprecated(since = "6.36.0", forRemoval = true)
default void saveAll() {
// Do nothing.
}
/**
* Commit all changes to the file.

View File

@@ -28,15 +28,6 @@ public interface KeyRegistry {
*/
Set<PersistentDataKey<?>> getRegisteredKeys();
/**
* Mark key as category.
*
* @param key The key.
* @param category The category.
*/
void markKeyAs(@NotNull PersistentDataKey<?> key,
@NotNull KeyRegistry.KeyCategory category);
/**
* Get persistent data key from namespaced key.
*
@@ -45,19 +36,4 @@ public interface KeyRegistry {
*/
@Nullable
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
/**
* Locations for key categorization.
*/
enum KeyCategory {
/**
* Player keys.
*/
PLAYER,
/**
* Server keys.
*/
SERVER
}
}

View File

@@ -83,28 +83,40 @@ public final class PersistentDataKey<T> {
}
/**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a server key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> server() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
return this;
}
/**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a player key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> player() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
return this;
}

View File

@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* All storable data key types.
@@ -37,6 +38,11 @@ public final class PersistentDataKeyType<T> {
*/
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
/**
* String List.
*/
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST");
/**
* The class of the type.
*/
@@ -51,7 +57,10 @@ public final class PersistentDataKeyType<T> {
* Get the class of the type.
*
* @return The class.
* @deprecated String list type will return null.
*/
@Deprecated(since = "6.36.0", forRemoval = true)
@Nullable
public Class<T> getTypeClass() {
return typeClass;
}
@@ -71,7 +80,7 @@ public final class PersistentDataKeyType<T> {
* @param typeClass The type class.
* @param name The name.
*/
private PersistentDataKeyType(@NotNull final Class<T> typeClass,
private PersistentDataKeyType(@Nullable final Class<T> typeClass,
@NotNull final String name) {
VALUES.add(this);
@@ -79,6 +88,22 @@ public final class PersistentDataKeyType<T> {
this.name = name;
}
@Override
public boolean equals(@Nullable final Object that) {
if (this == that) {
return true;
}
if (!(that instanceof PersistentDataKeyType type)) {
return false;
}
return Objects.equals(this.name, type.name);
}
@Override
public int hashCode() {
return Objects.hash(this.name);
}
/**
* Get all registered {@link PersistentDataKeyType}s.
*

View File

@@ -113,52 +113,6 @@ public final class Display {
handler.registerDisplayModule(module);
}
/**
* Initialize the display system.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void init(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalArgumentException("Already Initialized!");
}
Display.handler = handler;
}
/**
* Extremely janky method - also internal, so don't use it. <b>This method is
* NOT part of the API and may be removed at any time!</b>
* <p>
* This calls a display module with the specified parameters, now
* you might ask why I need a static java method when the DisplayHandler
* implementation could just call it itself? Well, kotlin doesn't really
* like dealing with vararg ambiguity, and so while kotlin can't figure out
* what is and isn't a vararg when I call display with a player, java can.
* <p>
* Because of this, I need to have this part of the code in java.
*
* <b>Don't call this method as part of your plugins!</b>
* <p>
* No, seriously - don't. This skips a bunch of checks and you'll almost
* definitely break something.
*
* @param module The display module.
* @param itemStack The ItemStack.
* @param player The player.
* @param args The args.
*/
@ApiStatus.Internal
public static void callDisplayModule(@NotNull final DisplayModule module,
@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final Object... args) {
module.display(itemStack, args);
if (player != null) {
module.display(itemStack, player, args);
}
}
/**
* Set the display handler.
* <p>

View File

@@ -14,7 +14,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
/**
* The priority of the module.
*/
private final DisplayPriority priority;
private final int weight;
/**
* Create a new display module.
@@ -25,7 +25,19 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
protected DisplayModule(@NotNull final EcoPlugin plugin,
@NotNull final DisplayPriority priority) {
super(plugin);
this.priority = priority;
this.weight = priority.getWeight();
}
/**
* Create a new display module.
*
* @param plugin The plugin that the display is for.
* @param weight The weight/priority of the module.
*/
protected DisplayModule(@NotNull final EcoPlugin plugin,
final int weight) {
super(plugin);
this.weight = weight;
}
/**
@@ -52,6 +64,21 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
// Technically optional.
}
/**
* Display an item.
*
* @param itemStack The item.
* @param player The player.
* @param properties The properties.
* @param args Optional args for display.
*/
public void display(@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final DisplayProperties properties,
@NotNull final Object... args) {
// Technically optional.
}
/**
* Revert an item.
*
@@ -84,8 +111,25 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* Get the display priority.
*
* @return The priority.
* @deprecated Use getWeight instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public DisplayPriority getPriority() {
return this.priority;
return switch (this.weight) {
case 100 -> DisplayPriority.LOWEST;
case 200 -> DisplayPriority.LOW;
case 300 -> DisplayPriority.HIGH;
case 400 -> DisplayPriority.HIGHEST;
default -> DisplayPriority.CUSTOM;
};
}
/**
* Get the display weight.
*
* @return The weight.
*/
public int getWeight() {
return this.weight;
}
}

View File

@@ -4,23 +4,51 @@ package com.willfp.eco.core.display;
* The priority (order) of display modules.
*/
public enum DisplayPriority {
/**
* Custom weight.
*/
CUSTOM(250),
/**
* Ran first.
*/
LOWEST,
LOWEST(100),
/**
* Ran second.
*/
LOW,
LOW(200),
/**
* Ran third.
*/
HIGH,
HIGH(300),
/**
* Ran last.
*/
HIGHEST
HIGHEST(400);
/**
* The display priority weight.
*/
private final int weight;
/**
* Create new display priority.
*
* @param weight The weight.
*/
DisplayPriority(final int weight) {
this.weight = weight;
}
/**
* Get the weight.
*
* @return The weight.
*/
public int getWeight() {
return weight;
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.display;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Extra properties passed into {@link DisplayModule}.
*
* @param inInventory If the item was in an inventory.
* @param inGui If the item is assumed to be in a gui. (Not perfectly accurate).
* @param originalItem The original item, not to be modified.
*/
public record DisplayProperties(
boolean inInventory,
boolean inGui,
@NotNull ItemStack originalItem
) {
}

View File

@@ -0,0 +1,122 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
/**
* Base interface for all custom goals.
* <p>
* Can be used both for entity goals and target goals.
*
* @param <T> The type of mob that this goal can be applied to.
*/
public abstract class CustomGoal<T extends Mob> implements EntityGoal<T>, TargetGoal<T> {
/**
* The flags for the goal.
*/
private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class);
/**
* Initialize the goal with a mob.
* <p>
* This will be run before any implementation code, treat this as the constructor.
*
* @param mob The mob.
*/
public abstract void initialize(@NotNull T mob);
/**
* Get if the goal can be used.
* Will start the goal if this returns true.
*
* @return If the goal can be used.
*/
public abstract boolean canUse();
/**
* Tick the goal.
* <p>
* Runs ever tick as long as canUse returns true.
* <p>
* Runs after start().
*/
public void tick() {
// Override when needed.
}
/**
* Start the goal.
* <p>
* Runs once canUse() returns true.
*/
public void start() {
// Override when needed.
}
/**
* Stop the goal.
* <p>
* Runs once canUse() returns false.
*/
public void stop() {
// Override when needed.
}
/**
* Get if the goal can continue to be used.
*
* @return If the goal can continue to be used.
*/
public boolean canContinueToUse() {
return this.canUse();
}
/**
* Get if the goal is interruptable.
*
* @return If interruptable.
*/
public boolean isInterruptable() {
return true;
}
/**
* Get the goal flags.
*
* @return The flags.
*/
public EnumSet<GoalFlag> getFlags() {
return EnumSet.copyOf(this.flags);
}
/**
* Set the flags for the goal.
*
* @param flags The flags.
*/
public final void setFlags(@NotNull final GoalFlag... flags) {
this.setFlags(EnumSet.copyOf(List.of(flags)));
}
/**
* Set the flags for the goal.
*
* @param flags The flags.
*/
public void setFlags(@NotNull final EnumSet<GoalFlag> flags) {
this.flags.clear();
this.flags.addAll(flags);
}
@Override
public T addToEntity(@NotNull final T entity,
final int priority) {
throw new UnsupportedOperationException(
"Shorthand syntax is not supported for custom goals by default as they can be both entity and target goals."
);
}
}

View File

@@ -0,0 +1,106 @@
package com.willfp.eco.core.entities.ai;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* An entity controller allows for adding targets and goals to entities.
*
* @param <T> The wrapped mob.
*/
public interface EntityController<T extends Mob> {
/**
* Add a target goal to the entity.
* <p>
* Mutates the instance.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> addTargetGoal(int priority,
@NotNull TargetGoal<? super T> goal);
/**
* Remove all target goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
EntityController<T> clearTargetGoals();
/**
* Remove a target goal from the entity.
* <p>
* Mutates the instance.
*
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> removeTargetGoal(@NotNull TargetGoal<? super T> goal);
/**
* Add an entity goal to the entity.
* <p>
* Mutates the instance.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> addEntityGoal(int priority,
@NotNull EntityGoal<? super T> goal);
/**
* Remove an entity goal from the entity.
* <p>
* Mutates the instance.
*
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> removeEntityGoal(@NotNull EntityGoal<? super T> goal);
/**
* Remove all entity goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
EntityController<T> clearEntityGoals();
/**
* Remove all goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
default EntityController<T> clearAllGoals() {
this.clearTargetGoals();
return this.clearEntityGoals();
}
/**
* Get the mob back from the controlled entity.
* <p>
* Not required to apply changes, as the mob instance will be altered.
*
* @return The mob.
*/
T getEntity();
/**
* Create an entity controller for an entity in order to modify targets and goals.
*
* @param entity The entity.
* @param <T> The mob type.
* @return The entity controller.
*/
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
return Eco.getHandler().createEntityController(entity);
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A goal for entity AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface EntityGoal<T extends Mob> extends Goal<T> {
@Override
default T addToEntity(@NotNull T entity, int priority) {
return EntityController.getFor(entity)
.addEntityGoal(priority, this)
.getEntity();
}
}

View File

@@ -0,0 +1,175 @@
package com.willfp.eco.core.entities.ai;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.entity.EntityGoalAvoidEntity;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreakDoors;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreatheAir;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatLieOnBed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatSitOnBed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalEatGrass;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFleeSun;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFloat;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowBoats;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowMobs;
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerBlindnessSpell;
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerMirrorSpell;
import com.willfp.eco.core.entities.ai.entity.EntityGoalInteract;
import com.willfp.eco.core.entities.ai.entity.EntityGoalLeapAtTarget;
import com.willfp.eco.core.entities.ai.entity.EntityGoalLookAtPlayer;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMeleeAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveBackToVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveThroughVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsRestriction;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsTarget;
import com.willfp.eco.core.entities.ai.entity.EntityGoalOcelotAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalOpenDoors;
import com.willfp.eco.core.entities.ai.entity.EntityGoalPanic;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomLookAround;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomStroll;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomSwimming;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedBowAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedCrossbowAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRestrictSun;
import com.willfp.eco.core.entities.ai.entity.EntityGoalStrollThroughVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalTempt;
import com.willfp.eco.core.entities.ai.entity.EntityGoalTryFindWater;
import com.willfp.eco.core.entities.ai.entity.EntityGoalUseItem;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomFlying;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomStroll;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWolfBeg;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Class to manage entity goals.
*/
public final class EntityGoals {
/**
* All registered deserializers.
*/
private static final Map<NamespacedKey, KeyedDeserializer<? extends EntityGoal<?>>> BY_KEY = HashBiMap.create();
static {
register(EntityGoalAvoidEntity.DESERIALIZER);
register(EntityGoalBreakDoors.DESERIALIZER);
register(EntityGoalBreatheAir.DESERIALIZER);
register(EntityGoalEatGrass.DESERIALIZER);
register(EntityGoalFleeSun.DESERIALIZER);
register(EntityGoalFloat.DESERIALIZER);
register(EntityGoalFollowBoats.DESERIALIZER);
register(EntityGoalFollowMobs.DESERIALIZER);
register(EntityGoalInteract.DESERIALIZER);
register(EntityGoalLeapAtTarget.DESERIALIZER);
register(EntityGoalLookAtPlayer.DESERIALIZER);
register(EntityGoalMeleeAttack.DESERIALIZER);
register(EntityGoalMoveBackToVillage.DESERIALIZER);
register(EntityGoalMoveThroughVillage.DESERIALIZER);
register(EntityGoalMoveTowardsRestriction.DESERIALIZER);
register(EntityGoalMoveTowardsTarget.DESERIALIZER);
register(EntityGoalOcelotAttack.DESERIALIZER);
register(EntityGoalOpenDoors.DESERIALIZER);
register(EntityGoalPanic.DESERIALIZER);
register(EntityGoalRandomLookAround.DESERIALIZER);
register(EntityGoalRandomStroll.DESERIALIZER);
register(EntityGoalRandomSwimming.DESERIALIZER);
register(EntityGoalRangedAttack.DESERIALIZER);
register(EntityGoalRangedBowAttack.DESERIALIZER);
register(EntityGoalRangedCrossbowAttack.DESERIALIZER);
register(EntityGoalRestrictSun.DESERIALIZER);
register(EntityGoalStrollThroughVillage.DESERIALIZER);
register(EntityGoalTempt.DESERIALIZER);
register(EntityGoalTryFindWater.DESERIALIZER);
register(EntityGoalUseItem.DESERIALIZER);
register(EntityGoalWaterAvoidingRandomFlying.DESERIALIZER);
register(EntityGoalWaterAvoidingRandomStroll.DESERIALIZER);
register(EntityGoalWolfBeg.DESERIALIZER);
register(EntityGoalBreed.DESERIALIZER);
register(EntityGoalCatSitOnBed.DESERIALIZER);
register(EntityGoalCatLieOnBed.DESERIALIZER);
register(EntityGoalIllusionerBlindnessSpell.DESERIALIZER);
register(EntityGoalIllusionerMirrorSpell.DESERIALIZER);
}
/**
* Get deserializer by key.
*
* @param key The key.
* @return The deserializer, or null if not found.
*/
@Nullable
public static KeyedDeserializer<? extends EntityGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
return BY_KEY.get(key);
}
/**
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
*
* @param key The key.
* @param clazz The type of target goal.
* @param <T> The type of mob the goal can be applied to.
* @return The deserializer, or null if not found.
*/
@Nullable
@SuppressWarnings({"unchecked", "unused"})
public static <T extends Mob> KeyedDeserializer<EntityGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
@NotNull final Class<T> clazz) {
return (KeyedDeserializer<EntityGoal<T>>) BY_KEY.get(key);
}
/**
* Apply goal to entity given key and config.
* <p>
* If the key or config are invalid, the goal will not be applied.
*
* @param entity The entity.
* @param key The key.
* @param config The config.
* @param priority The priority.
* @param <T> The entity type.
* @return The entity.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
@NotNull final NamespacedKey key,
@NotNull final Config config,
final int priority) {
KeyedDeserializer<EntityGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
if (deserializer == null) {
return entity;
}
EntityGoal<T> goal = deserializer.deserialize(config);
if (goal == null) {
return entity;
}
return goal.addToEntity(entity, priority);
}
/**
* Register a deserializer for an entity goal.
*
* @param toRegister The entity goal to register.
* @param <T> The type of deserializer.
* @return The deserializer.
*/
@NotNull
public static <T extends KeyedDeserializer<? extends EntityGoal<?>>> T register(@NotNull final T toRegister) {
BY_KEY.put(toRegister.getKey(), toRegister);
return toRegister;
}
private EntityGoals() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A generic goal for entity AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface Goal<T extends Mob> {
/**
* Add the entity goal to an entity.
* <p>
* The lower the priority, the higher up the execution order; so
* priority 0 will execute first. Lower priority (higher number) goals
* will only execute if all higher priority goals are stopped.
*
* @param entity The entity.
* @param priority The priority.
* @return The entity, modified.
*/
T addToEntity(@NotNull T entity, int priority);
}

View File

@@ -0,0 +1,26 @@
package com.willfp.eco.core.entities.ai;
/**
* Flags for ai goals.
*/
public enum GoalFlag {
/**
* Move.
*/
MOVE,
/**
* Look around.
*/
LOOK,
/**
* Jump.
*/
JUMP,
/**
* Target.
*/
TARGET
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A goal for entity target AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface TargetGoal<T extends Mob> extends Goal<T> {
@Override
default T addToEntity(@NotNull T entity, int priority) {
return EntityController.getFor(entity)
.addTargetGoal(priority, this)
.getEntity();
}
}

View File

@@ -0,0 +1,117 @@
package com.willfp.eco.core.entities.ai;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.target.TargetGoalDefendVillage;
import com.willfp.eco.core.entities.ai.target.TargetGoalHurtBy;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackable;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackableWitch;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestHealableRaider;
import com.willfp.eco.core.entities.ai.target.TargetGoalNonTameRandom;
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerHurtBy;
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerTarget;
import com.willfp.eco.core.entities.ai.target.TargetGoalResetUniversalAnger;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Class to manage target goals.
*/
public final class TargetGoals {
/**
* All registered deserializers.
*/
private static final Map<NamespacedKey, KeyedDeserializer<? extends TargetGoal<?>>> BY_KEY = HashBiMap.create();
static {
register(TargetGoalDefendVillage.DESERIALIZER);
register(TargetGoalHurtBy.DESERIALIZER);
register(TargetGoalNearestAttackable.DESERIALIZER);
register(TargetGoalNearestAttackableWitch.DESERIALIZER);
register(TargetGoalNearestHealableRaider.DESERIALIZER);
register(TargetGoalNonTameRandom.DESERIALIZER);
register(TargetGoalOwnerTarget.DESERIALIZER);
register(TargetGoalOwnerHurtBy.DESERIALIZER);
register(TargetGoalResetUniversalAnger.DESERIALIZER);
}
/**
* Get deserializer by key.
*
* @param key The key.
* @return The deserializer, or null if not found.
*/
@Nullable
public static KeyedDeserializer<? extends TargetGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
return BY_KEY.get(key);
}
/**
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
*
* @param key The key.
* @param clazz The type of target goal.
* @param <T> The type of mob the goal can be applied to.
* @return The deserializer, or null if not found.
*/
@Nullable
@SuppressWarnings({"unchecked", "unused"})
public static <T extends Mob> KeyedDeserializer<TargetGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
@NotNull final Class<T> clazz) {
return (KeyedDeserializer<TargetGoal<T>>) BY_KEY.get(key);
}
/**
* Apply goal to entity given key and config.
* <p>
* If the key or config are invalid, the goal will not be applied.
*
* @param entity The entity.
* @param key The key.
* @param config The config.
* @param priority The priority.
* @param <T> The entity type.
* @return The entity.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
@NotNull final NamespacedKey key,
@NotNull final Config config,
final int priority) {
KeyedDeserializer<TargetGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
if (deserializer == null) {
return entity;
}
TargetGoal<T> goal = deserializer.deserialize(config);
if (goal == null) {
return entity;
}
return goal.addToEntity(entity, priority);
}
/**
* Register a deserializer for a target goal.
*
* @param toRegister The target goal to register.
* @param <T> The type of deserializer.
* @return The deserializer.
*/
@NotNull
public static <T extends KeyedDeserializer<? extends TargetGoal<?>>> T register(@NotNull final T toRegister) {
BY_KEY.put(toRegister.getKey(), toRegister);
return toRegister;
}
private TargetGoals() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,73 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Avoid entities.
*
* @param entity The entity type to avoid.
* @param distance The distance to flee to.
* @param slowSpeed The slow movement speed.
* @param fastSpeed The fast movement speed.
*/
public record EntityGoalAvoidEntity(
@NotNull TestableEntity entity,
double distance,
double slowSpeed,
double fastSpeed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalAvoidEntity> DESERIALIZER = new Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalAvoidEntity> {
@Override
@Nullable
public EntityGoalAvoidEntity deserialize(@NotNull final Config config) {
if (!(
config.has("entity")
&& config.has("distance")
&& config.has("slowSpeed")
&& config.has("fastSpeed")
)) {
return null;
}
try {
TestableEntity entity = Entities.lookup(config.getString("entity"));
return new EntityGoalAvoidEntity(
entity,
config.getDouble("distance"),
config.getDouble("slowSpeed"),
config.getDouble("fastSpeed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("avoid_entity");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to break down doors.
*
* @param ticks The time taken to break the door. Minimum value is 240, as set by the game.
*/
public record EntityGoalBreakDoors(
int ticks
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreakDoors> DESERIALIZER = new EntityGoalBreakDoors.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreakDoors> {
@Override
@Nullable
public EntityGoalBreakDoors deserialize(@NotNull final Config config) {
if (!(
config.has("ticks")
)) {
return null;
}
try {
return new EntityGoalBreakDoors(
config.getInt("ticks")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("break_doors");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Breathe air.
*/
public record EntityGoalBreatheAir(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreatheAir> DESERIALIZER = new EntityGoalBreatheAir.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreatheAir> {
@Override
public EntityGoalBreatheAir deserialize(@NotNull final Config config) {
return new EntityGoalBreatheAir();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("breathe_air");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Animals;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows animals to breed.
*
* @param speed The speed at which to move to a partner.
*/
public record EntityGoalBreed(
double speed
) implements EntityGoal<Animals> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreed> DESERIALIZER = new EntityGoalBreed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreed> {
@Override
@Nullable
public EntityGoalBreed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalBreed(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("breed");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows a cat to lie on a bed.
*
* @param speed The speed at which to move to the bed.
* @param range The range at which to search for beds.
*/
public record EntityGoalCatLieOnBed(
double speed,
int range
) implements EntityGoal<Cat> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalCatLieOnBed> DESERIALIZER = new EntityGoalCatLieOnBed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatLieOnBed> {
@Override
@Nullable
public EntityGoalCatLieOnBed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("range")
)) {
return null;
}
try {
return new EntityGoalCatLieOnBed(
config.getDouble("speed"),
config.getInt("range")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("cat_lie_on_bed");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows a cat to sit on a bed.
*
* @param speed The speed at which to move to the bed.
*/
public record EntityGoalCatSitOnBed(
double speed
) implements EntityGoal<Cat> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalCatSitOnBed> DESERIALIZER = new EntityGoalCatSitOnBed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatSitOnBed> {
@Override
@Nullable
public EntityGoalCatSitOnBed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalCatSitOnBed(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("cat_sit_on_bed");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to eat the ground.
*/
public record EntityGoalEatGrass(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalEatGrass> DESERIALIZER = new EntityGoalEatGrass.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalEatGrass> {
@Override
public EntityGoalEatGrass deserialize(@NotNull final Config config) {
return new EntityGoalEatGrass();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("eat_grass");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Will make the entity actively avoid the sunlight.
*
* @param speed The speed at which to flee.
*/
public record EntityGoalFleeSun(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFleeSun> DESERIALIZER = new EntityGoalFleeSun.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFleeSun> {
@Override
@Nullable
public EntityGoalFleeSun deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalFleeSun(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("flee_sun");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to float on water.
*/
public record EntityGoalFloat(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFloat> DESERIALIZER = new EntityGoalFloat.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFloat> {
@Override
public EntityGoalFloat deserialize(@NotNull final Config config) {
return new EntityGoalFloat();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("float");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Follow boats.
*/
public record EntityGoalFollowBoats(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFollowBoats> DESERIALIZER = new EntityGoalFollowBoats.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowBoats> {
@Override
public EntityGoalFollowBoats deserialize(@NotNull final Config config) {
return new EntityGoalFollowBoats();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("follow_boats");
}
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to follow and gather around all types of mobs, both hostile and neutral mobs.
*
* @param speed The speed at which to follow.
* @param minDistance The minimum follow distance.
* @param maxDistance The maximum follow distance.
*/
public record EntityGoalFollowMobs(
double speed,
double minDistance,
double maxDistance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFollowMobs> DESERIALIZER = new EntityGoalFollowMobs.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowMobs> {
@Override
@Nullable
public EntityGoalFollowMobs deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("minDistance")
&& config.has("maxDistance")
)) {
return null;
}
try {
return new EntityGoalFollowMobs(
config.getDouble("speed"),
config.getDouble("minDistance"),
config.getDouble("maxDistance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("follow_mobs");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Illusioner;
import org.jetbrains.annotations.NotNull;
/**
* Allows an illusioner to perform the blindness spell.
*/
public record EntityGoalIllusionerBlindnessSpell(
) implements EntityGoal<Illusioner> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> DESERIALIZER = new EntityGoalIllusionerBlindnessSpell.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> {
@Override
public EntityGoalIllusionerBlindnessSpell deserialize(@NotNull final Config config) {
return new EntityGoalIllusionerBlindnessSpell();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("illusioner_blindness_spell");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Illusioner;
import org.jetbrains.annotations.NotNull;
/**
* Allows an illusioner to perform the mirror spell.
*/
public record EntityGoalIllusionerMirrorSpell(
) implements EntityGoal<Illusioner> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalIllusionerMirrorSpell> DESERIALIZER = new EntityGoalIllusionerMirrorSpell.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerMirrorSpell> {
@Override
public EntityGoalIllusionerMirrorSpell deserialize(@NotNull final Config config) {
return new EntityGoalIllusionerMirrorSpell();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("illusioner_mirror_spell");
}
}
}

View File

@@ -0,0 +1,67 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interact with other mobs.
*
* @param target The type of entity to interact with.
* @param range The range at which to interact.
* @param chance The chance for interaction, between 0 and 1.
*/
public record EntityGoalInteract(
@NotNull TestableEntity target,
double range,
double chance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalInteract> DESERIALIZER = new EntityGoalInteract.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalInteract> {
@Override
@Nullable
public EntityGoalInteract deserialize(@NotNull final Config config) {
if (!(
config.has("target")
&& config.has("range")
&& config.has("chance")
)) {
return null;
}
try {
return new EntityGoalInteract(
Entities.lookup(config.getString("target")),
config.getDouble("range"),
config.getDouble("chance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("interact");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to jump towards a target.
*
* @param velocity The leap velocity.
*/
public record EntityGoalLeapAtTarget(
double velocity
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalLeapAtTarget> DESERIALIZER = new EntityGoalLeapAtTarget.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalLeapAtTarget> {
@Override
@Nullable
public EntityGoalLeapAtTarget deserialize(@NotNull final Config config) {
if (!(
config.has("velocity")
)) {
return null;
}
try {
return new EntityGoalLeapAtTarget(
config.getDouble("velocity")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("leap_at_target");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to look at the player by rotating the head bone pose within a set limit.
*
* @param range The range at which to look at the player.
* @param chance The chance to look at the player, between 0 and 1.
*/
public record EntityGoalLookAtPlayer(
double range,
double chance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalLookAtPlayer> DESERIALIZER = new EntityGoalLookAtPlayer.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalLookAtPlayer> {
@Override
@Nullable
public EntityGoalLookAtPlayer deserialize(@NotNull final Config config) {
if (!(
config.has("range")
&& config.has("chance")
)) {
return null;
}
try {
return new EntityGoalLookAtPlayer(
config.getDouble("range"),
config.getDouble("chance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("look_at_player");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows entities to make close combat melee attacks.
*
* @param speed The speed at which to attack the target.
* @param pauseWhenMobIdle If the entity should pause attacking when the target is idle.
*/
public record EntityGoalMeleeAttack(
double speed,
boolean pauseWhenMobIdle
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMeleeAttack> DESERIALIZER = new EntityGoalMeleeAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMeleeAttack> {
@Override
@Nullable
public EntityGoalMeleeAttack deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("pauseWhenMobIdle")
)) {
return null;
}
try {
return new EntityGoalMeleeAttack(
config.getDouble("speed"),
config.getBool("pauseWhenMobIdle")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("melee_attack");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to navigate and search for a nearby village.
*
* @param speed The speed at which to move back to the village.
* @param canDespawn If the entity can despawn.
*/
public record EntityGoalMoveBackToVillage(
double speed,
boolean canDespawn
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveBackToVillage> DESERIALIZER = new EntityGoalMoveBackToVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveBackToVillage> {
@Override
@Nullable
public EntityGoalMoveBackToVillage deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("canDespawn")
)) {
return null;
}
try {
return new EntityGoalMoveBackToVillage(
config.getDouble("speed"),
config.getBool("canDespawn")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_back_to_village");
}
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows the entity to create paths around the village.
*
* @param speed The speed at which to move through the village.
* @param onlyAtNight If the entity can only move through village at night.
* @param distance The distance to move through the village.
* @param canPassThroughDoors If the entity can pass through doors.
*/
public record EntityGoalMoveThroughVillage(
double speed,
boolean onlyAtNight,
int distance,
boolean canPassThroughDoors
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveThroughVillage> DESERIALIZER = new EntityGoalMoveThroughVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveThroughVillage> {
@Override
@Nullable
public EntityGoalMoveThroughVillage deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("onlyAtNight")
&& config.has("distance")
&& config.has("canPassThroughDoors")
)) {
return null;
}
try {
return new EntityGoalMoveThroughVillage(
config.getDouble("speed"),
config.getBool("onlyAtNight"),
config.getInt("distance"),
config.getBool("canPassThroughDoors")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_through_village");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Move towards restriction.
*
* @param speed The speed at which to move towards the restriction.
*/
public record EntityGoalMoveTowardsRestriction(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveTowardsRestriction> DESERIALIZER = new EntityGoalMoveTowardsRestriction.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveTowardsRestriction> {
@Override
@Nullable
public EntityGoalMoveTowardsRestriction deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalMoveTowardsRestriction(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_towards_restriction");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to move towards a target.
*
* @param speed The speed at which to move towards the target.
* @param maxDistance The maximum distance the target can be where the entity will still move towards it.
*/
public record EntityGoalMoveTowardsTarget(
double speed,
double maxDistance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveTowardsTarget> DESERIALIZER = new EntityGoalMoveTowardsTarget.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveTowardsTarget> {
@Override
@Nullable
public EntityGoalMoveTowardsTarget deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("maxDistance")
)) {
return null;
}
try {
return new EntityGoalMoveTowardsTarget(
config.getDouble("speed"),
config.getDouble("maxDistance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_towards_target");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Attack like an ocelot.
*/
public record EntityGoalOcelotAttack(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalOcelotAttack> DESERIALIZER = new EntityGoalOcelotAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalOcelotAttack> {
@Override
public EntityGoalOcelotAttack deserialize(@NotNull final Config config) {
return new EntityGoalOcelotAttack();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("ocelot_attack");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to interact and open a door.
*
* @param delayClosing If closing the door should be delayed.
*/
public record EntityGoalOpenDoors(
boolean delayClosing
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalOpenDoors> DESERIALIZER = new EntityGoalOpenDoors.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalOpenDoors> {
@Override
@Nullable
public EntityGoalOpenDoors deserialize(@NotNull final Config config) {
if (!(
config.has("delayClosing")
)) {
return null;
}
try {
return new EntityGoalOpenDoors(
config.getBool("delayClosing")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("open_doors");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to react when it receives damage.
*
* @param speed The speed at which to panic.
*/
public record EntityGoalPanic(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalPanic> DESERIALIZER = new EntityGoalPanic.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalPanic> {
@Override
@Nullable
public EntityGoalPanic deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalPanic(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("panic");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to choose a random direction to look in for a random duration within a range.
*/
public record EntityGoalRandomLookAround(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRandomLookAround> DESERIALIZER = new EntityGoalRandomLookAround.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRandomLookAround> {
@Override
public EntityGoalRandomLookAround deserialize(@NotNull final Config config) {
return new EntityGoalRandomLookAround();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("random_look_around");
}
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to choose a random direction to walk towards.
*
* @param speed The speed at which to move around.
* @param interval The amount of ticks to wait (on average) between strolling around.
* @param canDespawn If the entity can despawn.
*/
public record EntityGoalRandomStroll(
double speed,
int interval,
boolean canDespawn
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRandomStroll> DESERIALIZER = new EntityGoalRandomStroll.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRandomStroll> {
@Override
@Nullable
public EntityGoalRandomStroll deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("interval")
&& config.has("canDespawn")
)) {
return null;
}
try {
return new EntityGoalRandomStroll(
config.getDouble("speed"),
config.getInt("interval"),
config.getBool("canDespawn")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("random_stroll");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to swim in a random point in water.
*
* @param speed The speed at which to move around.
* @param interval The amount of ticks to wait (on average) between strolling around.
*/
public record EntityGoalRandomSwimming(
double speed,
int interval
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRandomSwimming> DESERIALIZER = new EntityGoalRandomSwimming.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRandomSwimming> {
@Override
@Nullable
public EntityGoalRandomSwimming deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("interval")
)) {
return null;
}
try {
return new EntityGoalRandomSwimming(
config.getDouble("speed"),
config.getInt("interval")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("random_swimming");
}
}
}

View File

@@ -0,0 +1,71 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Ranged attack.
* <p>
* Only supports mobs that have ranged attacks.
*
* @param speed The speed.
* @param minInterval The minimum interval between attacks (in ticks).
* @param maxInterval The maximum interval between attacks (in ticks).
* @param maxRange The max range at which to attack.
*/
public record EntityGoalRangedAttack(
double speed,
int minInterval,
int maxInterval,
double maxRange
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRangedAttack> DESERIALIZER = new EntityGoalRangedAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRangedAttack> {
@Override
@Nullable
public EntityGoalRangedAttack deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("minInterval")
&& config.has("maxInterval")
&& config.has("range")
)) {
return null;
}
try {
return new EntityGoalRangedAttack(
config.getDouble("speed"),
config.getInt("minInterval"),
config.getInt("maxInterval"),
config.getDouble("range")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("ranged_attack");
}
}
}

View File

@@ -0,0 +1,67 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Monster;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Ranged attack.
* <p>
* Only supports monsters that have bow attacks.
*
* @param speed The speed.
* @param interval The interval between attacks (in ticks).
* @param range The max range at which to attack.
*/
public record EntityGoalRangedBowAttack(
double speed,
int interval,
double range
) implements EntityGoal<Monster> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRangedBowAttack> DESERIALIZER = new EntityGoalRangedBowAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRangedBowAttack> {
@Override
@Nullable
public EntityGoalRangedBowAttack deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("interval")
&& config.has("range")
)) {
return null;
}
try {
return new EntityGoalRangedBowAttack(
config.getDouble("speed"),
config.getInt("interval"),
config.getDouble("range")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("ranged_bow_attack");
}
}
}

View File

@@ -0,0 +1,63 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Monster;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Ranged attack.
* <p>
* Only supports monsters that have crossbow attacks.
*
* @param speed The speed.
* @param range The max range at which to attack.
*/
public record EntityGoalRangedCrossbowAttack(
double speed,
double range
) implements EntityGoal<Monster> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRangedCrossbowAttack> DESERIALIZER = new EntityGoalRangedCrossbowAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRangedCrossbowAttack> {
@Override
@Nullable
public EntityGoalRangedCrossbowAttack deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("range")
)) {
return null;
}
try {
return new EntityGoalRangedCrossbowAttack(
config.getDouble("speed"),
config.getDouble("range")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("ranged_crossbow_attack");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to actively avoid direct sunlight.
*/
public record EntityGoalRestrictSun(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRestrictSun> DESERIALIZER = new EntityGoalRestrictSun.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRestrictSun> {
@Override
public EntityGoalRestrictSun deserialize(@NotNull final Config config) {
return new EntityGoalRestrictSun();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("restrict_sun");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows the entity to create paths around the village.
*
* @param searchRange The search range.
*/
public record EntityGoalStrollThroughVillage(
int searchRange
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalStrollThroughVillage> DESERIALIZER = new EntityGoalStrollThroughVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalStrollThroughVillage> {
@Override
@Nullable
public EntityGoalStrollThroughVillage deserialize(@NotNull final Config config) {
if (!(
config.has("searchRange")
)) {
return null;
}
try {
return new EntityGoalStrollThroughVillage(
config.getInt("searchRange")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("stroll_through_village");
}
}
}

View File

@@ -0,0 +1,88 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* Allows an entity to be tempted by a set item.
*
* @param speed The speed at which the entity follows the item.
* @param items The items that the entity will be attracted by.
* @param canBeScared If the entity can be scared and lose track of the item.
*/
public record EntityGoalTempt(
double speed,
@NotNull Collection<TestableItem> items,
boolean canBeScared
) implements EntityGoal<Mob> {
/**
* @param speed The speed at which the entity follows the item.
* @param item The item that the entity will be attracted by.
* @param canBeScared If the entity can be scared and lose track of the item.
*/
public EntityGoalTempt(final double speed,
@NotNull final TestableItem item,
final boolean canBeScared) {
this(speed, List.of(item), canBeScared);
}
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalTempt> DESERIALIZER = new EntityGoalTempt.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalTempt> {
@Override
@Nullable
public EntityGoalTempt deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("items")
&& config.has("canBeScared")
)) {
return null;
}
try {
Collection<TestableItem> items = config.getStrings("items").stream()
.map(Items::lookup)
.filter(it -> !(it instanceof EmptyTestableItem))
.collect(Collectors.toList());
return new EntityGoalTempt(
config.getDouble("speed"),
items,
config.getBool("canBeScared")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("tempt");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to move to water when on land.
*/
public record EntityGoalTryFindWater(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalTryFindWater> DESERIALIZER = new EntityGoalTryFindWater.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalTryFindWater> {
@Override
public EntityGoalTryFindWater deserialize(@NotNull final Config config) {
return new EntityGoalTryFindWater();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("try_find_water");
}
}
}

View File

@@ -0,0 +1,75 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Use item.
*
* @param item The item.
* @param sound The sound to play on use.
* @param condition The condition when to use the item.
*/
public record EntityGoalUseItem(
@NotNull ItemStack item,
@NotNull Sound sound,
@NotNull Predicate<LivingEntity> condition
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalUseItem> DESERIALIZER = new EntityGoalUseItem.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalUseItem> {
@Override
@Nullable
public EntityGoalUseItem deserialize(@NotNull final Config config) {
if (!(
config.has("item")
&& config.has("sound")
&& config.has("condition")
)) {
return null;
}
try {
TestableEntity filter = Entities.lookup(config.getString("condition"));
return new EntityGoalUseItem(
Items.lookup(config.getString("item")).getItem(),
Sound.valueOf(config.getString("sound").toUpperCase()),
filter::matches
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("use_item");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Fly randomly while avoiding water.
*
* @param speed The speed.
*/
public record EntityGoalWaterAvoidingRandomFlying(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalWaterAvoidingRandomFlying> DESERIALIZER = new EntityGoalWaterAvoidingRandomFlying.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalWaterAvoidingRandomFlying> {
@Override
@Nullable
public EntityGoalWaterAvoidingRandomFlying deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
return null;
}
try {
return new EntityGoalWaterAvoidingRandomFlying(
config.getDouble("speed")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("water_avoiding_random_flying");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Stroll randomly while avoiding water.
*
* @param speed The speed.
* @param chance The chance to stroll every tick, between 0 and 1.
*/
public record EntityGoalWaterAvoidingRandomStroll(
double speed,
double chance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalWaterAvoidingRandomStroll> DESERIALIZER = new EntityGoalWaterAvoidingRandomStroll.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalWaterAvoidingRandomStroll> {
@Override
@Nullable
public EntityGoalWaterAvoidingRandomStroll deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("chance")
)) {
return null;
}
try {
return new EntityGoalWaterAvoidingRandomStroll(
config.getDouble("speed"),
config.getDouble("chance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("water_avoiding_random_stroll");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Wolf;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows a wolf to beg.
*
* @param distance The distance at which to beg from.
*/
public record EntityGoalWolfBeg(
double distance
) implements EntityGoal<Wolf> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalWolfBeg> DESERIALIZER = new EntityGoalWolfBeg.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalWolfBeg> {
@Override
@Nullable
public EntityGoalWolfBeg deserialize(@NotNull final Config config) {
if (!(
config.has("distance")
)) {
return null;
}
try {
return new EntityGoalWolfBeg(
config.getDouble("distance")
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("wolf_beg");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.IronGolem;
import org.jetbrains.annotations.NotNull;
/**
* Defend village.
*/
public record TargetGoalDefendVillage(
) implements TargetGoal<IronGolem> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalDefendVillage> DESERIALIZER = new TargetGoalDefendVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalDefendVillage> {
@Override
public TargetGoalDefendVillage deserialize(@NotNull final Config config) {
return new TargetGoalDefendVillage();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("defend_village");
}
}
}

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to react when hit by set target.
*
* @param blacklist The entities not to attack when hurt by.
*/
@SuppressWarnings({"varargs"})
public record TargetGoalHurtBy(
@NotNull TestableEntity blacklist
) implements TargetGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalHurtBy> DESERIALIZER = new TargetGoalHurtBy.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalHurtBy> {
@Override
@Nullable
public TargetGoalHurtBy deserialize(@NotNull final Config config) {
if (!(
config.has("blacklist")
)) {
return null;
}
try {
return new TargetGoalHurtBy(
Entities.lookup(config.getString("blacklist"))
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("hurt_by");
}
}
}

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Raider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Allows an entity to attack the closest target within a given subset of specific target types.
*
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
* @param reciprocalChance 1 in reciprocalChance chance of not activating on any tick.
* @param targetFilter The filter for targets to match.
*/
public record TargetGoalNearestAttackable(
@NotNull TestableEntity target,
boolean checkVisibility,
boolean checkCanNavigate,
int reciprocalChance,
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
* @param reciprocalChance 1 in reciprocalChance chance of not activating on any tick.
*/
public TargetGoalNearestAttackable(@NotNull final TestableEntity target,
final boolean checkVisibility,
final boolean checkCanNavigate,
final int reciprocalChance) {
this(target, checkVisibility, checkCanNavigate, reciprocalChance, it -> true);
}
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalNearestAttackable> DESERIALIZER = new TargetGoalNearestAttackable.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalNearestAttackable> {
@Override
@Nullable
public TargetGoalNearestAttackable deserialize(@NotNull final Config config) {
if (!(
config.has("target")
&& config.has("checkVisibility")
&& config.has("checkCanNavigate")
&& config.has("reciprocalChance")
)) {
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestAttackable(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance"),
filter::matches
);
} else {
return new TargetGoalNearestAttackable(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance")
);
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("nearest_attackable");
}
}
}

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Raider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Allows an entity to attack the closest target within a given subset of specific target types.
*
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
* @param reciprocalChance 1 in reciprocalChance chance of not activating on any tick.
* @param targetFilter The filter for targets to match.
*/
public record TargetGoalNearestAttackableWitch(
@NotNull TestableEntity target,
boolean checkVisibility,
boolean checkCanNavigate,
int reciprocalChance,
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
* @param reciprocalChance 1 in reciprocalChance chance of not activating on any tick.
*/
public TargetGoalNearestAttackableWitch(@NotNull final TestableEntity target,
final boolean checkVisibility,
final boolean checkCanNavigate,
final int reciprocalChance) {
this(target, checkVisibility, checkCanNavigate, reciprocalChance, it -> true);
}
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalNearestAttackableWitch> DESERIALIZER = new TargetGoalNearestAttackableWitch.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalNearestAttackableWitch> {
@Override
@Nullable
public TargetGoalNearestAttackableWitch deserialize(@NotNull final Config config) {
if (!(
config.has("target")
&& config.has("checkVisibility")
&& config.has("checkCanNavigate")
&& config.has("reciprocalChance")
)) {
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestAttackableWitch(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance"),
filter::matches
);
} else {
return new TargetGoalNearestAttackableWitch(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance")
);
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("nearest_attackable_witch");
}
}
}

View File

@@ -0,0 +1,87 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Raider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Target nearest attackable raider.
*
* @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked.
* @param targetFilter The filter for targets to match.
*/
public record TargetGoalNearestHealableRaider(
@NotNull TestableEntity target,
boolean checkVisibility,
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* @param target The target.
* @param checkVisibility If visibility should be checked.
*/
public TargetGoalNearestHealableRaider(@NotNull final TestableEntity target,
final boolean checkVisibility) {
this(target, checkVisibility, it -> true);
}
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalNearestHealableRaider> DESERIALIZER = new TargetGoalNearestHealableRaider.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalNearestHealableRaider> {
@Override
@Nullable
public TargetGoalNearestHealableRaider deserialize(@NotNull final Config config) {
if (!(
config.has("target")
&& config.has("checkVisibility")
)) {
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestHealableRaider(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
filter::matches
);
} else {
return new TargetGoalNearestHealableRaider(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility")
);
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("nearest_healable_raider");
}
}
}

View File

@@ -0,0 +1,87 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Tameable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Target random non-tame entity.
*
* @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked.
* @param targetFilter The filter for targets to match.
*/
public record TargetGoalNonTameRandom(
@NotNull TestableEntity target,
boolean checkVisibility,
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Tameable> {
/**
* @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked.
*/
public TargetGoalNonTameRandom(@NotNull final TestableEntity target,
final boolean checkVisibility) {
this(target, checkVisibility, it -> true);
}
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalNonTameRandom> DESERIALIZER = new TargetGoalNonTameRandom.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalNonTameRandom> {
@Override
@Nullable
public TargetGoalNonTameRandom deserialize(@NotNull final Config config) {
if (!(
config.has("targetClass")
&& config.has("checkVisibility")
)) {
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNonTameRandom(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"),
filter::matches
);
} else {
return new TargetGoalNonTameRandom(
Entities.lookup(config.getString("target")),
config.getBool("checkVisibility")
);
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("non_tame_random");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Tameable;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to react when the owner is hit by a target.
*/
public record TargetGoalOwnerHurtBy(
) implements TargetGoal<Tameable> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalOwnerHurtBy> DESERIALIZER = new TargetGoalOwnerHurtBy.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalOwnerHurtBy> {
@Override
public TargetGoalOwnerHurtBy deserialize(@NotNull final Config config) {
return new TargetGoalOwnerHurtBy();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("owner_hurt_by");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.target;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.TargetGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Tameable;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to react when the owner hits a target.
*/
public record TargetGoalOwnerTarget(
) implements TargetGoal<Tameable> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<TargetGoalOwnerTarget> DESERIALIZER = new TargetGoalOwnerTarget.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<TargetGoalOwnerTarget> {
@Override
public TargetGoalOwnerTarget deserialize(@NotNull final Config config) {
return new TargetGoalOwnerTarget();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("owner_target");
}
}
}

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