mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2026-02-20 02:33:15 +01:00
Compare commits
148 Commits
1.12
...
1.13-suppo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b41637fbf8 | ||
|
|
7506646862 | ||
|
|
227fb49dec | ||
|
|
78fdfc1c35 | ||
|
|
0b26d6c72c | ||
|
|
cae722e8c7 | ||
|
|
0eed1a6c5a | ||
|
|
bbf7ce9c57 | ||
|
|
1fa21823a4 | ||
|
|
4b34299648 | ||
|
|
45841218e6 | ||
|
|
c509daff9f | ||
|
|
ce92329705 | ||
|
|
817b5364cf | ||
|
|
820c3260c8 | ||
|
|
54a1475fef | ||
|
|
bd0204a09e | ||
|
|
31c1bd52bc | ||
|
|
0f8c0f97d9 | ||
|
|
5a56b27ea8 | ||
|
|
273dfbbdce | ||
|
|
138b109ff5 | ||
|
|
908ac7c541 | ||
|
|
e7e13d990a | ||
|
|
ea9f79291e | ||
|
|
4b13cbeb43 | ||
|
|
d542098f8a | ||
|
|
f6e01ea910 | ||
|
|
2a053a0be2 | ||
|
|
b5cbfc7f66 | ||
|
|
8c0076ff80 | ||
|
|
6e3c2fcb76 | ||
|
|
33a68daa9c | ||
|
|
00cc5f0845 | ||
|
|
8b0a580505 | ||
|
|
87bf3a5b40 | ||
|
|
426b1304e2 | ||
|
|
f1204f8a2a | ||
|
|
f7b07899c1 | ||
|
|
e5de240eb4 | ||
|
|
0ba3d7bd68 | ||
|
|
79d5c6192f | ||
|
|
b8ae8438de | ||
|
|
974106f983 | ||
|
|
d599db2897 | ||
|
|
3f89f91f42 | ||
|
|
2fca0963d7 | ||
|
|
b63db1981c | ||
|
|
af744fa088 | ||
|
|
8538ac4e50 | ||
|
|
cabc5977d9 | ||
|
|
43dd382541 | ||
|
|
cdb81e961e | ||
|
|
51ced83301 | ||
|
|
09bca96af3 | ||
|
|
f1d9f787f4 | ||
|
|
b8b0be71b1 | ||
|
|
ac10261803 | ||
|
|
dc018be6bb | ||
|
|
832b653a88 | ||
|
|
1fddaf15cc | ||
|
|
b68feb6992 | ||
|
|
f3837265db | ||
|
|
ae551e17cd | ||
|
|
c6d055cb48 | ||
|
|
68e34d682c | ||
|
|
b125600dac | ||
|
|
57b31b60b3 | ||
|
|
7757e187be | ||
|
|
5ce360d443 | ||
|
|
d44b6e0afb | ||
|
|
629d882831 | ||
|
|
947018c0f1 | ||
|
|
ca2e1c11e6 | ||
|
|
69e5d3e1b5 | ||
|
|
b7d33f0227 | ||
|
|
28c7fdd4e2 | ||
|
|
53534e0f1d | ||
|
|
8d477a5cf5 | ||
|
|
74908cdcf5 | ||
|
|
39b22d0ee8 | ||
|
|
74e62ab08c | ||
|
|
f1cc745de8 | ||
|
|
7654e78fbe | ||
|
|
558c727136 | ||
|
|
18097fa1a5 | ||
|
|
e2b8d940d3 | ||
|
|
5093c37efb | ||
|
|
610e1a6bf4 | ||
|
|
99843f2735 | ||
|
|
732726bbd3 | ||
|
|
65687ca603 | ||
|
|
658382dba2 | ||
|
|
404a876d6b | ||
|
|
c4a383c4fb | ||
|
|
e0341f7ae7 | ||
|
|
018c6fc96b | ||
|
|
d324aa9589 | ||
|
|
cc1c73cb17 | ||
|
|
d6dc8bb04c | ||
|
|
88ef6b0984 | ||
|
|
624299602d | ||
|
|
8fe8db2353 | ||
|
|
159cf7c0d4 | ||
|
|
947cdc91a4 | ||
|
|
ff55cbb946 | ||
|
|
fdb151083d | ||
|
|
7a3d608f36 | ||
|
|
719283177e | ||
|
|
55fb3ed74f | ||
|
|
363ea66335 | ||
|
|
7ee65a7e65 | ||
|
|
aa25ba6338 | ||
|
|
b68bbad766 | ||
|
|
6d19239db7 | ||
|
|
faab64864a | ||
|
|
b1f4ea8cba | ||
|
|
df6315dd62 | ||
|
|
255f7bf335 | ||
|
|
ce6553d857 | ||
|
|
df1497924c | ||
|
|
aeed0cf6ad | ||
|
|
e40a7bb4e1 | ||
|
|
d59dbe7630 | ||
|
|
dece43429d | ||
|
|
14f900aa83 | ||
|
|
53848d3fd3 | ||
|
|
c8d95dc711 | ||
|
|
bb118607ce | ||
|
|
2d849f55e5 | ||
|
|
fef9058e16 | ||
|
|
e3d2526939 | ||
|
|
2f0a58b968 | ||
|
|
8994594ed4 | ||
|
|
bb46b2a6ac | ||
|
|
7296deb149 | ||
|
|
ef5cd3ec60 | ||
|
|
f9f6d1550e | ||
|
|
68e43e3641 | ||
|
|
93458aa355 | ||
|
|
e80e771e9d | ||
|
|
af9b631ee2 | ||
|
|
ca5a46508d | ||
|
|
7703cafa34 | ||
|
|
437fe29112 | ||
|
|
28b71804a2 | ||
|
|
6f15cd4005 | ||
|
|
ba88831c88 |
257
Changelog.txt
257
Changelog.txt
@@ -7,7 +7,262 @@ Key:
|
||||
! Change
|
||||
- Removal
|
||||
|
||||
Version 2.2.0
|
||||
Version 2.1.47
|
||||
Fix NPE when party leader is offline and players grab a party list
|
||||
|
||||
Version 2.1.46
|
||||
Party member lists now show the whole party, including offline players again.
|
||||
Party lists now have special markers for players who are in shared XP range
|
||||
Party lists now have special markers for players who are offline
|
||||
Party lists now have special markers for the party leader
|
||||
Fixed an error where bleed was setting health outside minimum values
|
||||
[See NOTE] Fixed a bug where Creepers and Zombies were not dropping the correct heads from Shake (thanks Zed-I)
|
||||
[See NOTE] Fixed a bug where salvage was not returning the correct amount of materials for AXE items (thanks Zed-I)
|
||||
[See NOTE] Added missing STRIPPED_WOOD entries to experience.yml for Woodcutting
|
||||
[See NOTE] Added about 15-20 missing entries to experience.yml for coral to Herbalism
|
||||
Fixed a bug where admin chat from console would fail to send (thanks OverCrave)
|
||||
Reduced default XP values for DEAD_* coral plants from 30 -> 10
|
||||
Updated hu_HU locale (thanks andris155)
|
||||
|
||||
NOTE: These bugfixes were related to default config values, to receive these changes you can either delete experience.yml, treasures.yml and salvage.vanilla.yml to generate new ones or make the necessary edits.
|
||||
This is what the files should look like after being edited.
|
||||
Experience Correct Default Config - https://paste.gg/p/anonymous/ff695df1417e4232957a3d176fd14ed4
|
||||
Salvage Correct Default Config - https://paste.gg/p/anonymous/c4eb2f4e66ed444e872021051760f3be
|
||||
Treasures Correct Default Config - https://paste.gg/p/anonymous/b0120210f8c149958ca0303c68c19ebd
|
||||
|
||||
Version 2.1.45
|
||||
mcMMO will now check to see if the server version is incompatible and inform server admins on how to fix the problem.
|
||||
|
||||
Version 2.1.44
|
||||
Fixed a NPE with Alchemy brewing
|
||||
|
||||
Version 2.1.43
|
||||
Fixed a bug that would result in players being told they they failed to salvage enchantments when in reality they succeeded.
|
||||
|
||||
Version 2.1.42
|
||||
Fixed McMMOPlayerNotFoundException being thrown instead of null
|
||||
(API) UserManager.getPlayer() returns null again (oopsie)
|
||||
Added new perk permission node `mcmmo.perks.bypass.salvageenchant` - guarantees full enchantment return for Salvage
|
||||
Added alternative permission node `mcmmo.perks.bypass.repairenchant` - guarantees full enchantment return for Repair
|
||||
Added new wildcard perk `mcmmo.perks.bypass.*` and `mcmmo.perks.bypass.all` (either of these will grant all new mcmmo.perks.bypass perk permissions)
|
||||
|
||||
NOTE: Sorry about that, when trying to improve Bungee Cord compatibility I made a big oopsie!
|
||||
NOTE: Repair's new perk permission works in the exact same way as mcmmo.bypass.arcanebypass, bypass perk permissions will all eventually be moved to `mcmmo.perks.bypass`
|
||||
NOTE: Expect perk permissions to all be moved to `mcmmo.perks.X` in the near future
|
||||
|
||||
Version 2.1.41
|
||||
Fixed NullPointerException errors when trying to grab PlayerProfiles for players who have not loaded
|
||||
Added new locale string Profile.PendingLoad
|
||||
Added new locale string Commands.Database.CooldownMS
|
||||
Fixed a display error preventing the remaining time on /mcrank from being shown if it was on cooldown
|
||||
|
||||
Version 2.1.40
|
||||
(API) mcMMO will now return null in all cases for UserManager.getPlayerProfile() if they have not been loaded yet
|
||||
(API) Roll stores exploit data in AcrobaticsManager now
|
||||
Added new locale string "Profile.Loading.FailureNotice"
|
||||
Added new locale string "Profile.Loading.FailurePlayer"
|
||||
mcMMO no longer gives up forever if a player profile fails to load and the player is still online
|
||||
mcMMO will attempt to save a profile up to 10 times now, previously it would only try one time.
|
||||
Fixed an ArrayIndexOutOfBounds error with Party Chat
|
||||
Player data for mcMMO is now loaded 3 seconds after a player connects in order to give any ongoing save tasks from other servers a small grace period to finish. This will mostly be useful to Bungee servers.
|
||||
|
||||
NOTES: I received reports from some users saying that saving and loading was failing could fail and not recover, I have implemented some fail safes to greatly reduce the the odds of that happening.
|
||||
|
||||
Version 2.1.39
|
||||
Salvaging an item should now only play the item break sound (was playing the anvil sound simultaneously before)
|
||||
Fixed bug where Tall_Grass was not giving full XP
|
||||
Added Tall_Seagrass and Seagrass to experience.yml under Herbalism (update your configs)
|
||||
|
||||
NOTE: This is what your herbalism section in experience.yml should look like - https://paste.gg/p/anonymous/d5b03bd56e8442f2836f8a954d2974de
|
||||
Version 2.1.38
|
||||
Roll XP cooldown down from 60 seconds to 10
|
||||
Updated pt_BR localization (thanks FabioZumbi12)
|
||||
NOTE: The XP Cooldown will be configurable in 2.2 which is nearing the finish line
|
||||
|
||||
Version 2.1.37
|
||||
Fixed a potential IndexOutOfBoundsException when informing a disconnected player that their Blast Mining was off CD
|
||||
Updated hu_HU locale (thanks andris)
|
||||
|
||||
Version 2.1.36
|
||||
Updated German locale (Thanks OverCrave)
|
||||
Fixed a bug preventing Villagers from giving combat XP
|
||||
The /mcnotify command will now squelch almost all chat messages or action bar notifications sent to the player from mcMMO
|
||||
mcMMO will now remind players on an hourly basis that they are are not receiving notifications from mcMMO if they have run the mcnotify command and toggled squelch mode
|
||||
Added a new setting to advanced.yml "Feedback.PlayerTips", when set to true this will allow mcMMO to send periodic helpful messages to players, currently this only affects mcnotify reminders.
|
||||
|
||||
Version 2.1.35
|
||||
Readded the detonator config option
|
||||
|
||||
NOTE: I decided to make the detonator configurable again because 2.2 is some ways off. Sorry for the inconvenience.
|
||||
NOTE: Pickaxes are now usable for blast mining, this is in addition to the detonator that you can specify in the config. This will be more configurable in the upcoming 2.2 update.
|
||||
|
||||
Version 2.1.34
|
||||
Added Llama to taming XP tables
|
||||
Added Parrot to taming XP tables
|
||||
Pickaxes are now used to activate Blast Mining instead of Flint
|
||||
The detonator for Blast Mining is no longer configurable
|
||||
Fixed a bug where Blast Mining did not show cooldown length correctly
|
||||
|
||||
NOTE: You'll have to add these entries in yourself, this is what it should look like: https://paste.gg/p/anonymous/aadbcfde3eb3470fb13caebde4065a03
|
||||
Alternatively you can delete the experience config file to generate a new one
|
||||
|
||||
Version 2.1.33
|
||||
Renamed "Skills.Acrobatics.Prevent_AFK_Leveling" to "ExploitFix.Acrobatics"
|
||||
ExploitFix.Acrobatics when set to false allows gaining XP in Acrobatics freely with no anti-grind measures
|
||||
NOTE: The anti-grinding/exploit stuff is fully configurable in update 2.2 coming soon, this hotfix is to hold you over until that update comes out.
|
||||
|
||||
Version 2.1.32
|
||||
Completely removed Fireworks from mcMMO because they lag
|
||||
Added 'General.AprilFoolsEvent' setting to config.yml to turn off April Fools
|
||||
NOTE: April Fools event has been in mcMMO for a long time, I did not write it so I didn't know it spawned fireworks like crazy.
|
||||
|
||||
Version 2.1.31
|
||||
Fixed a bug where certain SubSkills did not properly send unlock or rank up notifications
|
||||
Fixed a bug where unlock notifications would send simultaneously for a specific skill (still happens if mmoedit changes all skill levels on a player at once)
|
||||
Fixed a bug where mmoedit triggered notifications for skills already gained
|
||||
Fixed NPE with grabbing offline player skill ranks through certain API methods (thanks Ineusia)
|
||||
Updated German language locale (thanks OverCrave)
|
||||
|
||||
Version 2.1.30
|
||||
Fixed double drops behaving oddly
|
||||
Double_Drop config table has been renamed to Bonus_Drops, this is to jankily auto-update everyones config
|
||||
DoubleDrop config tables now must contain all things that can possibly be doubled, such as the Ore block, the ore itself, etc.
|
||||
Added the following items to the Bonus_Drops tables for Mining: Coal, Diamond, Emerald, Glowstone_Dust, Iron_Ingot, Lapis_Lazuli, Nether_Quartz, Redstone, Cobblestone
|
||||
Added the following items to the Bonus_Drops tables for Herbalism: Beetroot, Carrot, Cocoa_Beans, Melon_Slice, Potatoe
|
||||
Added the following items to the Bonus_Drops tables for Woodcutting: Birch_Wood, Spruce_Wood, Jungle_Wood, Dark_Oak_Wood, Oak_Wood, Acacia_Wood
|
||||
|
||||
NOTE: You don't need to update your configs for this one unless you had custom entries in the Double_Drop tables, the renaming of the key will auto-insert default values and give everyone correct defaults
|
||||
NOTE: I'm gonna have to blame Bukkit on this one, several API methods I used are actually unfinished and kind of janky. So I hacked something together to make them work.
|
||||
|
||||
Version 2.1.29
|
||||
Fixed a bug where double drops and triple drops were not activating
|
||||
|
||||
Version 2.1.28
|
||||
Fixed a bug where Archery could not gain XP
|
||||
|
||||
Version 2.1.27
|
||||
Fixed an exploit that allowed players to duplicate torches, and rails
|
||||
|
||||
Version 2.1.26
|
||||
Added new scaling damage buffs to all existing Combat Skills
|
||||
Added a new subskill named Stab to Swords
|
||||
Fixed a bug where Berserk was not adding 50% damage to attacks
|
||||
Changed how Iron Arm damage is calculated (Rank 1 now effectively gives twice the damage bonus it used to, higher ranks have more damage)
|
||||
|
||||
NOTE: Combat skills will be completely configurable in the upcoming 2.2 update, be patient <3
|
||||
|
||||
New Permissions
|
||||
- mcmmo.ability.unarmed.unarmedlimitbreak
|
||||
- mcmmo.ability.axes.axeslimitbreak
|
||||
- mcmmo.ability.archery.archerylimitbreak
|
||||
- mcmmo.ability.swords.swordslimitbreak
|
||||
- mcmmo.ability.swords.stab
|
||||
|
||||
Notes:
|
||||
The new Limit Break subskills are intended to make Prot IV players less tanky and for you to feel more powerful for having high skill level.
|
||||
Limit Break has 10 ranks, each rank gives 1 extra RAW damage, this is damage before reductions from armor and enchantments. The net result is you deal about 50% more damage with an end game skill compared to before.
|
||||
With these new changes, most skills can 2 shot normal diamond armor, and it takes about 5 hits to kill someone in Prot IV Diamond Armor.
|
||||
I'm not sure everyone will like these changes, the net result is players are a lot easier to kill now, whereas before you could take quite a beating before getting killed.
|
||||
I collected several sets of data before making these changes, including damage to player with and without prot 4 diamond armor, damage to those players with and without enchanted weapons, damage with and without leveling your skills, and combinations of the previously mentioned things.
|
||||
|
||||
Version 2.1.25
|
||||
Shake now has an upper limit of damage (10) - Will be configurable in 2.2 which is coming in the near future
|
||||
Rank 1 of Catalysis & Concoctions are now available at level 0 by default (update skillranks.yml or delete it to regen a new one)
|
||||
NOTE: The change to shake was to make mcMMO more compatible with plugins that spawn entities with large amounts of HP
|
||||
|
||||
Version 2.1.24
|
||||
Fixed an exploit where you could clone inventories
|
||||
|
||||
Version 2.1.23
|
||||
Fixed a bug with Double Drops for Mining (Update your configs instructions below)
|
||||
Fixed a 7 year old bug where damage in mcMMO from SkillBs was potentially getting reduced by damage reduction TWICE
|
||||
Fixed a bug where killing entities with Rupture would not properly credit you as the killer
|
||||
Fixed a bug where Serrated Strikes was applying Rupture twice
|
||||
Players will now be ejected from Minecarts if they cast their fishing rod (anti-afk)
|
||||
Many nerfs to Rupture, its now much more reasonable and not very useful against Protection IV opponents
|
||||
Rupture's strength is now related to your equipped Sword
|
||||
Rupture will no longer be applied if the target is blocking, this doesn't prevent existing bleed damage from occurring though.
|
||||
Wolf's Rupture has strength equivalent to a Stone Sword
|
||||
Only Diamond swords will have bonus rupture damage at Rank 4
|
||||
Rupture damage is cut in half for weapons below Diamond in quality, if the weapon is wooden, the damage is cut in half again.
|
||||
Swords below Diamond quality will have their tick duration drastically reduced
|
||||
Rupture damage is reduced by 25% on players if they are wearing Full Armor (can be any type)
|
||||
Note: You'll need to add these entries to your config.yml manually, or wait for the upcoming config update where this will be fixed for you automatically.
|
||||
NOTE: Here's what your Double_Drop entries in Config.yml for Mining should look like
|
||||
https://paste.gg/p/anonymous/dcd06f1215844311b4f2225f200090d1
|
||||
IMPORTANT: Version 2.1.22 which came before this had a similar fix for Herbalism, instructions on how to fix your Herbalism Double Drops can be found here
|
||||
https://www.spigotmc.org/resources/official-mcmmo.64348/update?update=269868
|
||||
NOTE: Due to the nature of these fixes, Fortune enchants now work with Double/Triple drops
|
||||
|
||||
Version 2.1.22
|
||||
Less aggressive spam click protection on Fishing
|
||||
Updated Hungarian file for missing entries related to Fishing messages (credit: andris155)
|
||||
Added all missing flowers to Double Drop tables for Herbalism
|
||||
Fixed bug where Repair Mastery was calculating player skill level incorrectly when determining bonuses
|
||||
Fixed Double Drop entries for all farming crops for Herbalism
|
||||
It no longer requires seeds to replant crops if you are harvesting crops with a hoe (will still consume seeds if you aren't)
|
||||
NOTE: You'll need to add these entries to your config.yml manually, or wait for the upcoming config update where this will be fixed for you automatically.
|
||||
NOTE: Here's what your Double_Drop entries in Config.yml for Herbalism should look like: https://paste.gg/p/anonymous/8d8db4ac69bd495fa48a7f5190484c5e
|
||||
|
||||
Version 2.1.21
|
||||
Improved anti-farm/anti-grinding mechanics for Rolling
|
||||
When you gain XP from Rolling there is a cooldown period (60~ seconds) for gaining XP again
|
||||
This XP cooldown period extends if players are taking fall damage within the cooldown period
|
||||
NOTE: Roll already has a few built in measures to prevent XP grinding / abuse, those are still the same.
|
||||
NOTE: Rolls still happen in the cooldown period, you just won't gain XP.
|
||||
|
||||
Version 2.1.20
|
||||
Added Hungarian localization (Locale code: hu_HU) (thanks andris155)
|
||||
Players can now fish in the same spot about 3 times before mcMMO will mark the area as being over-fished (over-fishing is to prevent abuse)
|
||||
Added a toggle to turn off the fishing exploit detection to experience.yml "ExploitFix.Fishing"
|
||||
Note: The new config update is coming soon and will use a different setting, putting this out as a band-aid fix for people that don't like the new fishing exploit prevention stuff
|
||||
Added a message to warn players that their next fishing attempt will result in over-fishing (Locale: Fishing.LowResources)
|
||||
|
||||
Version 2.1.19
|
||||
Greatly Improved Fishing AFK/Exploit Detection
|
||||
Fixed a bug where Fishing AFK detection did not work on a new exploit
|
||||
Certain exploits for Fishing now result in players losing small amounts of hunger and durability
|
||||
Players who get detected by Fishing's anti-exploit measures will no longer get vanilla rewards from Minecraft
|
||||
**Note: Previously if mcMMO detected you abusing Fishing it just switched you over to vanilla Minecraft fishing rewards, this change is to help server admins who don't want players to get any kind of reward from AFK fishing
|
||||
Fishing now drops several hints to players if they are triggering the exploit detection
|
||||
**Note: Not all types of exploit detection will warn players, this is just to prevent legitimate fishers from being confused by the aggressive exploit detection.
|
||||
Added messages to warn players about fishing in the same spot (Locale: Fishing.Scarcity)
|
||||
Added messages to warn players who exploit in order to catch fish unusually fast (Locale: Fishing.Scared)
|
||||
Added messages to warn players about casting the fishing rod too often (Locale: Fishing.Exhausting)
|
||||
|
||||
Version 2.1.18
|
||||
You will need to add Kelp to your experience.yml file for this fix to be fully functional
|
||||
Breaking Kelp will now properly count its XP
|
||||
Added "Kelp" to experience.yml (Kelp is actually made up of two blocks mixed together)
|
||||
It is recommended that Kelp and Kelp_Plant have the same XP value in experience.yml
|
||||
mcMMO will now calculate XP for plants that are taller than naturally allowed (Cactus above 3 block height, etc)
|
||||
|
||||
Version 2.1.17
|
||||
Fixed a logic error that resulted in Drowned giving no XP
|
||||
Fixed a bug that resulted in mob spawner entities to not be marked for no xp after being transforming into Drowned
|
||||
|
||||
Version 2.1.16
|
||||
Breaking Kelp should now count the whole plant for XP
|
||||
Spawned Mobs that are not supposed to award XP will no longer reward XP once transformed (ie: drowned)
|
||||
|
||||
Version 2.1.15
|
||||
Fixed a bug where a max rank of Fuel Efficiency would cause its benefits to be lost
|
||||
|
||||
Version 2.1.14
|
||||
Added a config option to toggle double drops for Silk Touch pickaxes (advanced.yml "Skills.Mining.DoubleDrops.SilkTouch"
|
||||
Mycelium removed from Woodcutting XP tables (because its soil!)
|
||||
Kelp added to Herbalism XP tables
|
||||
mcMMO now flags blocks moved by piston as not natural to prevent automated XP farms
|
||||
Fixed a bug where Fuel Efficiency was way too good
|
||||
Fixed a display issue with Fisherman's Diet
|
||||
Fuel Efficiency now uses the rank system
|
||||
Removed Fuel Efficiency config options in advanced.yml
|
||||
Added Tropical Fish, Raw Cod, Raw Salmon to the list of foods that benefit from Fisherman's Diet
|
||||
|
||||
Version 2.1.13
|
||||
Fixed a bug where Archery's Arrow Retrieval was using the wrong permission node
|
||||
|
||||
Version 2.1.12
|
||||
Salvage config entries are no longer case sensitive
|
||||
Fixed a bug where Fishing was not rewarding vanilla XP orbs
|
||||
|
||||
|
||||
29
README.md
29
README.md
@@ -5,37 +5,43 @@
|
||||
I'm working on a brand new website for mcMMO
|
||||
|
||||
You can check it out here http://www.mcmmo.org
|
||||
Spigot Resource: https://www.spigotmc.org/resources/official-mcmmo-original-author-returns.64348/
|
||||
|
||||
I plan to post links to our new wiki (its still under development), downloads, and dev blogs there.
|
||||
|
||||
|
||||
### Builds
|
||||
Currently, you can obtain our builds via the Spigot resource page: https://spigot.mcmmo.org
|
||||
Currently, you can obtain our builds via the Spigot resource page: http://spigot.mcmmo.org
|
||||
|
||||
### Brief Description
|
||||
The goal of mcMMO is to take core Minecraft game mechanics and expand them into add an extensive and quality RPG experience. Everything in mcMMO has been carefully thought out and is constantly being improved upon. Currently, mcMMO adds fourteen unique skills to train and level in. Each of these skills is highly customizable through our configuration files, allowing server admins to tweak mcMMO to best suit the needs of his or her server. Know that the mcMMO team is dedicated to providing an ever-evolving experience, and that we carefully read all feedback and bug reports in order to evaluate and balance the mechanics of mcMMO in every update.
|
||||
|
||||
## About the Team
|
||||
mcMMO is currently developed by a team of individuals from all over the world.
|
||||
In December 2018 nossr50 returned as project lead for mcMMO once again to develop and improve mcMMO.
|
||||
The mcMMO team currently has two members, nossr50 (lead) and t00thpick1 (classic maintainer).
|
||||
mcMMO is currently developed almost entirely by nossr50, many thanks go out to the many developers who have worked on the project over the years.
|
||||
|
||||
### Project Lead & Founder
|
||||
[](https://github.com/nossr50)
|
||||
|
||||
### Former Lead
|
||||
Other mcMMO Projects
|
||||
|
||||
### Classic Maintainer
|
||||
[](https://github.com/t00thpick1)
|
||||
|
||||
## Former Team Members
|
||||
|
||||
### Former Lead & Awesome guy
|
||||
[](https://github.com/gmcferrin)
|
||||
|
||||
### Developers
|
||||
### Former team members
|
||||
[](https://github.com/bm01)
|
||||
[](https://github.com/Glitchfinder)
|
||||
[](https://github.com/NuclearW)
|
||||
[](https://github.com/shatteredbeam)
|
||||
[](https://github.com/TfT-02)
|
||||
[](https://github.com/t00thpick1)
|
||||
[](https://github.com/riking)
|
||||
|
||||
### Special thanks
|
||||
[](https://github.com/EasyMFnE)
|
||||
Added the Alchemy skill
|
||||
[](https://github.com/TheYeti)
|
||||
|
||||
## Compiling
|
||||
|
||||
@@ -46,5 +52,8 @@ The typical command used to build mcMMO is: `mvn clean package install`
|
||||
Required Libraries:
|
||||
* Bukkit
|
||||
* JUnit
|
||||
* WorldGuard 7
|
||||
* bStats Bukkit
|
||||
|
||||
https://spigot.mcmmo.org for more up to date information.
|
||||
http://spigot.mcmmo.org for more up to date information.
|
||||
https://www.spigotmc.org/resources/official-mcmmo-original-author-returns.64348/
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||
<artifactId>mcMMO</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.1.47</version>
|
||||
<name>mcMMO</name>
|
||||
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
||||
<scm>
|
||||
|
||||
@@ -783,7 +783,7 @@ public final class ExperienceAPI {
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getPlayerRankSkill(String playerName, String skillType) {
|
||||
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(playerName).getPlayerName()).get(getNonChildSkillType(skillType));
|
||||
return mcMMO.getDatabaseManager().readRank(mcMMO.p.getServer().getOfflinePlayer(playerName).getName()).get(getNonChildSkillType(skillType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -801,7 +801,7 @@ public final class ExperienceAPI {
|
||||
* @return the position on the leaderboard
|
||||
*/
|
||||
public static int getPlayerRankSkill(UUID uuid, String skillType) {
|
||||
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(uuid).getPlayerName()).get(getNonChildSkillType(skillType));
|
||||
return mcMMO.getDatabaseManager().readRank(mcMMO.p.getServer().getOfflinePlayer(uuid).getName()).get(getNonChildSkillType(skillType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -817,7 +817,7 @@ public final class ExperienceAPI {
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getPlayerRankOverall(String playerName) {
|
||||
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(playerName).getPlayerName()).get(null);
|
||||
return mcMMO.getDatabaseManager().readRank(mcMMO.p.getServer().getOfflinePlayer(playerName).getName()).get(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -832,7 +832,7 @@ public final class ExperienceAPI {
|
||||
* @return the position on the power level leaderboard
|
||||
*/
|
||||
public static int getPlayerRankOverall(UUID uuid) {
|
||||
return mcMMO.getDatabaseManager().readRank(getOfflineProfile(uuid).getPlayerName()).get(null);
|
||||
return mcMMO.getDatabaseManager().readRank(mcMMO.p.getServer().getOfflinePlayer(uuid).getName()).get(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1158,6 +1158,13 @@ public final class ExperienceAPI {
|
||||
return formulaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use UserManager::getPlayer(Player player) instead
|
||||
* @param player target player
|
||||
* @return McMMOPlayer for that player if the profile is loaded, otherwise null
|
||||
* @throws McMMOPlayerNotFoundException
|
||||
*/
|
||||
@Deprecated
|
||||
private static McMMOPlayer getPlayer(Player player) throws McMMOPlayerNotFoundException {
|
||||
if (!UserManager.hasPlayerDataKey(player)) {
|
||||
throw new McMMOPlayerNotFoundException(player);
|
||||
|
||||
@@ -41,6 +41,9 @@ public final class PartyAPI {
|
||||
* @return true if the player is in a party, false otherwise
|
||||
*/
|
||||
public static boolean inParty(Player player) {
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return false;
|
||||
|
||||
return UserManager.getPlayer(player).inParty();
|
||||
}
|
||||
|
||||
@@ -79,6 +82,10 @@ public final class PartyAPI {
|
||||
*/
|
||||
@Deprecated
|
||||
public static void addToParty(Player player, String partyName) {
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return;
|
||||
|
||||
Party party = PartyManager.getParty(partyName);
|
||||
|
||||
if (party == null) {
|
||||
@@ -113,7 +120,12 @@ public final class PartyAPI {
|
||||
* @param partyName The party to add the player to
|
||||
* @param bypassLimit if true bypasses party size limits
|
||||
*/
|
||||
//TODO: bypasslimit not used?
|
||||
public static void addToParty(Player player, String partyName, boolean bypassLimit) {
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return;
|
||||
|
||||
Party party = PartyManager.getParty(partyName);
|
||||
|
||||
if (party == null) {
|
||||
@@ -131,6 +143,10 @@ public final class PartyAPI {
|
||||
* @param player The player to remove
|
||||
*/
|
||||
public static void removeFromParty(Player player) {
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return;
|
||||
|
||||
PartyManager.removeFromParty(UserManager.getPlayer(player));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ public class McMMOPlayerNotFoundException extends RuntimeException {
|
||||
private static final long serialVersionUID = 761917904993202836L;
|
||||
|
||||
public McMMOPlayerNotFoundException(Player player) {
|
||||
super("McMMOPlayer object was not found for: " + player.getName() + " " + player.getUniqueId());
|
||||
super("McMMOPlayer object was not found for [NOTE: This can mean the profile is not loaded yet!] : " + player.getName() + " " + player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gmail.nossr50.chat;
|
||||
|
||||
import com.gmail.nossr50.datatypes.party.Party;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.events.chat.McMMOChatEvent;
|
||||
import com.gmail.nossr50.events.chat.McMMOPartyChatEvent;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
@@ -46,12 +47,14 @@ public abstract class ChatManager {
|
||||
McMMOPartyChatEvent partyChatEvent = (McMMOPartyChatEvent) event;
|
||||
|
||||
//Find the people with permissions
|
||||
for(Player player : event.getPlugin().getServer().getOnlinePlayers())
|
||||
for(McMMOPlayer mcMMOPlayer : UserManager.getPlayers())
|
||||
{
|
||||
Player player = mcMMOPlayer.getPlayer();
|
||||
|
||||
//Check for toggled players
|
||||
if(UserManager.getPlayer(player).isPartyChatSpying())
|
||||
if(mcMMOPlayer.isPartyChatSpying())
|
||||
{
|
||||
Party adminParty = UserManager.getPlayer(player).getParty();
|
||||
Party adminParty = mcMMOPlayer.getParty();
|
||||
|
||||
//Only message admins not part of this party
|
||||
if(adminParty != null)
|
||||
|
||||
@@ -18,6 +18,10 @@ public class McnotifyCommand implements TabExecutor {
|
||||
case 0:
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer((Player) sender);
|
||||
|
||||
//Not Loaded yet
|
||||
if(mcMMOPlayer == null)
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.Notifications." + (mcMMOPlayer.useChatNotifications() ? "Off" : "On")));
|
||||
mcMMOPlayer.toggleChatNotifications();
|
||||
return true;
|
||||
|
||||
@@ -55,14 +55,13 @@ public abstract class ChatCommand implements TabExecutor {
|
||||
return true;
|
||||
|
||||
case 1:
|
||||
if (!CommandUtils.hasPlayerDataKey(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CommandUtils.shouldEnableToggle(args[0])) {
|
||||
if (CommandUtils.noConsoleUsage(sender)) {
|
||||
return true;
|
||||
}
|
||||
if (!CommandUtils.hasPlayerDataKey(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
enableChatMode(UserManager.getPlayer(sender.getName()), sender);
|
||||
return true;
|
||||
@@ -72,6 +71,9 @@ public abstract class ChatCommand implements TabExecutor {
|
||||
if (CommandUtils.noConsoleUsage(sender)) {
|
||||
return true;
|
||||
}
|
||||
if (!CommandUtils.hasPlayerDataKey(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
disableChatMode(UserManager.getPlayer(sender.getName()), sender);
|
||||
return true;
|
||||
|
||||
@@ -22,6 +22,10 @@ public class PartyChatCommand extends ChatCommand {
|
||||
String message;
|
||||
|
||||
if (sender instanceof Player) {
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
return;
|
||||
|
||||
party = UserManager.getPlayer((Player) sender).getParty();
|
||||
|
||||
if (party == null) {
|
||||
|
||||
@@ -24,6 +24,10 @@ public class AddxpCommand extends ExperienceCommand {
|
||||
@Override
|
||||
protected void handleCommand(Player player, PlayerProfile profile, PrimarySkillType skill, int value) {
|
||||
if (player != null) {
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return;
|
||||
|
||||
UserManager.getPlayer(player).applyXpGain(skill, value, XPGainReason.COMMAND, XPGainSource.COMMAND);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -51,6 +51,14 @@ public abstract class ExperienceCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(sender.getName()) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
editValues((Player) sender, UserManager.getPlayer(sender.getName()).getProfile(), skill, Integer.parseInt(args[1]));
|
||||
return true;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class MmoeditCommand extends ExperienceCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND);
|
||||
EventUtils.handleLevelChangeEventEdit(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,8 +15,17 @@ public class PartyAcceptCommand implements CommandExecutor {
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
Player player = (Player) sender;
|
||||
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
|
||||
if (!mcMMOPlayer.hasPartyInvite()) {
|
||||
sender.sendMessage(LocaleLoader.getString("mcMMO.NoInvites"));
|
||||
return true;
|
||||
|
||||
@@ -17,6 +17,13 @@ public class PartyChangeOwnerCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
//Check if player profile is loaded
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
|
||||
String targetName = CommandUtils.getMatchedPlayerName(args[1]);
|
||||
OfflinePlayer target = mcMMO.p.getServer().getOfflinePlayer(targetName);
|
||||
|
||||
@@ -11,6 +11,12 @@ import org.bukkit.entity.Player;
|
||||
public class PartyChangePasswordCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party party = UserManager.getPlayer((Player) sender).getParty();
|
||||
|
||||
switch (args.length) {
|
||||
|
||||
@@ -74,6 +74,12 @@ public class PartyCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
if (args.length < 1) {
|
||||
@@ -197,6 +203,14 @@ public class PartyCommand implements TabExecutor {
|
||||
|
||||
if (matches.size() == 0) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
//Not Loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
Party party = UserManager.getPlayer(player).getParty();
|
||||
|
||||
playerNames = party.getOnlinePlayerNames(player);
|
||||
|
||||
@@ -18,6 +18,12 @@ public class PartyCreateCommand implements CommandExecutor {
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check to see if the party exists, and if it does cancel creating a new party
|
||||
if (PartyManager.checkPartyExistence(player, args[1])) {
|
||||
return true;
|
||||
|
||||
@@ -15,6 +15,12 @@ public class PartyDisbandCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
|
||||
String partyName = playerParty.getName();
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ public class PartyInfoCommand implements CommandExecutor {
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
case 1:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
Party party = mcMMOPlayer.getParty();
|
||||
|
||||
@@ -25,6 +25,13 @@ public class PartyInviteCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
Player target = mcMMOTarget.getPlayer();
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
String playerName = player.getName();
|
||||
|
||||
@@ -17,6 +17,12 @@ import org.bukkit.entity.Player;
|
||||
public class PartyItemShareCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party party = UserManager.getPlayer((Player) sender).getParty();
|
||||
|
||||
if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ITEM_SHARE)) {
|
||||
|
||||
@@ -32,6 +32,13 @@ public class PartyJoinCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
Party targetParty = mcMMOTarget.getParty();
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ public class PartyKickCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
|
||||
String targetName = CommandUtils.getMatchedPlayerName(args[1]);
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ public class PartyLockCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
private void togglePartyLock(CommandSender sender, boolean lock) {
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return;
|
||||
}
|
||||
|
||||
Party party = UserManager.getPlayer((Player) sender).getParty();
|
||||
|
||||
if (!Permissions.partySubcommand(sender, lock ? PartySubcommandType.LOCK : PartySubcommandType.UNLOCK)) {
|
||||
|
||||
@@ -17,6 +17,13 @@ public class PartyQuitCommand implements CommandExecutor {
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
Player player = (Player) sender;
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
Party playerParty = mcMMOPlayer.getParty();
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@ public class PartyRenameCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer((Player) sender);
|
||||
Party playerParty = mcMMOPlayer.getParty();
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@ import org.bukkit.entity.Player;
|
||||
public class PartyXpShareCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Party party = UserManager.getPlayer((Player) sender).getParty();
|
||||
|
||||
if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.XP_SHARE)) {
|
||||
|
||||
@@ -14,6 +14,11 @@ public class PartyAllianceAcceptCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
|
||||
@@ -37,6 +37,12 @@ public class PartyAllianceCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@ public class PartyAllianceDisbandCommand implements CommandExecutor {
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
Party party = mcMMOPlayer.getParty();
|
||||
|
||||
@@ -24,6 +24,13 @@ public class PartyAllianceInviteCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
Player target = mcMMOTarget.getPlayer();
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
String playerName = player.getName();
|
||||
|
||||
@@ -20,6 +20,12 @@ public class PtpAcceptCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
PartyTeleportRecord ptpRecord = UserManager.getPlayer(player).getPartyTeleportRecord();
|
||||
|
||||
|
||||
@@ -59,6 +59,12 @@ public class PtpCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
if (!mcMMOPlayer.inParty()) {
|
||||
@@ -131,6 +137,12 @@ public class PtpCommand implements TabExecutor {
|
||||
List<String> matches = StringUtil.copyPartialMatches(args[0], TELEPORT_SUBCOMMANDS, new ArrayList<String>(TELEPORT_SUBCOMMANDS.size()));
|
||||
|
||||
if (matches.size() == 0) {
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
@@ -205,6 +217,18 @@ public class PtpCommand implements TabExecutor {
|
||||
}
|
||||
|
||||
protected static void handleTeleportWarmup(Player teleportingPlayer, Player targetPlayer) {
|
||||
if(UserManager.getPlayer(targetPlayer) == null)
|
||||
{
|
||||
targetPlayer.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer(teleportingPlayer) == null)
|
||||
{
|
||||
teleportingPlayer.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
|
||||
McMMOPlayer mcMMOTarget = UserManager.getPlayer(targetPlayer);
|
||||
|
||||
|
||||
@@ -38,6 +38,12 @@ public class MccooldownCommand implements TabExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
player.sendMessage(LocaleLoader.getString("Commands.Cooldowns.Header"));
|
||||
|
||||
@@ -88,10 +88,17 @@ public class McrankCommand implements TabExecutor {
|
||||
private void display(CommandSender sender, String playerName) {
|
||||
if (sender instanceof Player) {
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
|
||||
long cooldownMillis = Math.max(Config.getInstance().getDatabasePlayerCooldown(), 1750);
|
||||
|
||||
if(mcMMOPlayer == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return;
|
||||
}
|
||||
|
||||
long cooldownMillis = Math.min(Config.getInstance().getDatabasePlayerCooldown(), 1750);
|
||||
|
||||
if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.Database.Cooldown"));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.Database.CooldownMS", getCDSeconds(mcMMOPlayer, cooldownMillis)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,4 +117,8 @@ public class McrankCommand implements TabExecutor {
|
||||
|
||||
new McrankCommandAsyncTask(playerName, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
|
||||
}
|
||||
|
||||
private long getCDSeconds(McMMOPlayer mcMMOPlayer, long cooldownMillis) {
|
||||
return ((mcMMOPlayer.getDatabaseATS() + cooldownMillis) - System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ public class McstatsCommand implements TabExecutor {
|
||||
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
|
||||
if (Config.getInstance().getStatsUseBoard() && Config.getInstance().getScoreboardsEnabled()) {
|
||||
|
||||
@@ -30,6 +30,13 @@ public class AlchemyCommand extends SkillCommand {
|
||||
}
|
||||
|
||||
protected String[] calculateAbilityDisplayValues(Player player) {
|
||||
//TODO: Needed?
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return new String[] {"DATA NOT LOADED", "DATA NOT LOADED"};
|
||||
}
|
||||
|
||||
AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
|
||||
String[] displayValues = new String[2];
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.skills.archery.Archery;
|
||||
import com.gmail.nossr50.util.TextComponentFactory;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -74,6 +75,11 @@ public class ArcheryCommand extends SkillCommand {
|
||||
messages.add(getStatMessage(SubSkillType.ARCHERY_SKILL_SHOT, skillShotBonus));
|
||||
}
|
||||
|
||||
if(canUseSubskill(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK)) {
|
||||
messages.add(getStatMessage(SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK,
|
||||
String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK))));
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.gmail.nossr50.skills.axes.Axes;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.TextComponentFactory;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@@ -95,6 +96,11 @@ public class AxesCommand extends SkillCommand {
|
||||
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", skullSplitterLengthEndurance) : ""));
|
||||
}
|
||||
|
||||
if(canUseSubskill(player, SubSkillType.AXES_AXES_LIMIT_BREAK)) {
|
||||
messages.add(getStatMessage(SubSkillType.AXES_AXES_LIMIT_BREAK,
|
||||
String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.AXES_AXES_LIMIT_BREAK))));
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public class FishingCommand extends SkillCommand {
|
||||
|
||||
// FISHERMAN'S DIET
|
||||
if (canFishermansDiet) {
|
||||
fishermansDietRank = calculateRank(skillValue, Fishing.fishermansDietMaxLevel, Fishing.fishermansDietRankLevel1);
|
||||
fishermansDietRank = RankUtils.getRank(player, SubSkillType.FISHING_FISHERMANS_DIET);
|
||||
}
|
||||
|
||||
// MASTER ANGLER
|
||||
|
||||
@@ -86,7 +86,7 @@ public class RepairCommand extends SkillCommand {
|
||||
canRepairString = Permissions.repairMaterialType(player, MaterialType.STRING);
|
||||
canRepairLeather = Permissions.repairMaterialType(player, MaterialType.LEATHER);
|
||||
canRepairWood = Permissions.repairMaterialType(player, MaterialType.WOOD);
|
||||
arcaneBypass = Permissions.arcaneBypass(player);
|
||||
arcaneBypass = (Permissions.arcaneBypass(player) || Permissions.hasRepairEnchantBypassPerk(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,6 +56,12 @@ public abstract class SkillCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer((Player) sender) == null)
|
||||
{
|
||||
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
Player player = (Player) sender;
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.skills;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.skills.smelting.Smelting;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.TextComponentFactory;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
@@ -35,7 +34,7 @@ public class SmeltingCommand extends SkillCommand {
|
||||
protected void dataCalculations(Player player, float skillValue) {
|
||||
// FUEL EFFICIENCY
|
||||
if (canFuelEfficiency) {
|
||||
burnTimeModifier = decimal.format(1 + ((skillValue / Smelting.burnModifierMaxLevel) * Smelting.burnTimeMultiplier));
|
||||
burnTimeModifier = String.valueOf(UserManager.getPlayer(player).getSmeltingManager().getFuelEfficiencyMultiplier());
|
||||
}
|
||||
|
||||
// FLUX MINING
|
||||
@@ -57,7 +56,7 @@ public class SmeltingCommand extends SkillCommand {
|
||||
protected void permissionsCheck(Player player) {
|
||||
canFuelEfficiency = canUseSubskill(player, SubSkillType.SMELTING_FUEL_EFFICIENCY);
|
||||
canSecondSmelt = canUseSubskill(player, SubSkillType.SMELTING_SECOND_SMELT);
|
||||
canFluxMine = canUseSubskill(player, SubSkillType.SMELTING_FLUX_MINING);
|
||||
//canFluxMine = canUseSubskill(player, SubSkillType.SMELTING_FLUX_MINING);
|
||||
canUnderstandTheArt = Permissions.vanillaXpBoost(player, skill) && RankUtils.hasUnlockedSubskill(player, SubSkillType.SMELTING_UNDERSTANDING_THE_ART);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.TextComponentFactory;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@@ -94,6 +95,17 @@ public class SwordsCommand extends SkillCommand {
|
||||
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", serratedStrikesLengthEndurance) : ""));
|
||||
}
|
||||
|
||||
if(canUseSubskill(player, SubSkillType.SWORDS_STAB))
|
||||
{
|
||||
messages.add(getStatMessage(SubSkillType.SWORDS_STAB,
|
||||
String.valueOf(UserManager.getPlayer(player).getSwordsManager().getStabDamage())));
|
||||
}
|
||||
|
||||
if(canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
|
||||
messages.add(getStatMessage(SubSkillType.SWORDS_SWORDS_LIMIT_BREAK,
|
||||
String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK))));
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.TextComponentFactory;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@@ -113,6 +114,11 @@ public class UnarmedCommand extends SkillCommand {
|
||||
//messages.add(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance) + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", ironGripChanceLucky) : ""));
|
||||
}
|
||||
|
||||
if(canUseSubskill(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) {
|
||||
messages.add(getStatMessage(SubSkillType.UNARMED_UNARMED_LIMIT_BREAK,
|
||||
String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK))));
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
@@ -438,10 +438,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
reason.add("Skills.Smelting.FuelEfficiency.MaxBonusLevel should be at least 1!");
|
||||
}
|
||||
|
||||
if (getBurnTimeMultiplier() < 1) {
|
||||
reason.add("Skills.Smelting.FuelEfficiency.Multiplier should be at least 1!");
|
||||
}
|
||||
|
||||
if (getMaxBonusLevel(SubSkillType.SMELTING_SECOND_SMELT) < 1) {
|
||||
reason.add("Skills.Smelting.SecondSmelt.MaxBonusLevel should be at least 1!");
|
||||
}
|
||||
@@ -650,6 +646,10 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
/* GENERAL */
|
||||
public int getStartingLevel() { return config.getInt("Skills.General.StartingLevel", 1); }
|
||||
|
||||
public boolean allowPlayerTips() {
|
||||
return config.getBoolean("Feedback.PlayerTips", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the maximum level at which superabilities will stop lengthening from scaling alongside skill level.
|
||||
* It returns a different value depending on whether or not the server is in retro mode
|
||||
@@ -907,6 +907,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public int getGreenThumbStageChange() { return config.getInt("Skills.Herbalism.GreenThumb.StageChange", 200); }
|
||||
|
||||
/* MINING */
|
||||
public boolean getDoubleDropSilkTouchEnabled() { return config.getBoolean("Skills.Mining.DoubleDrops.SilkTouch", true); }
|
||||
public int getBlastMiningRankLevel(int rank) { return config.getInt("Skills.Mining.BlastMining.Rank_Levels.Rank_" + rank); }
|
||||
public double getBlastDamageDecrease(int rank) { return config.getDouble("Skills.Mining.BlastMining.BlastDamageDecrease.Rank_" + rank); }
|
||||
public double getOreBonus(int rank) { return config.getDouble("Skills.Mining.BlastMining.OreBonus.Rank_" + rank); }
|
||||
@@ -939,8 +940,12 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public double getArcaneSalvageExtractPartialEnchantsChance(int rank) { return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractPartialEnchant.Rank_" + rank); }
|
||||
|
||||
/* SMELTING */
|
||||
public int getBurnModifierMaxLevel() { return config.getInt("Skills.Smelting.FuelEfficiency.MaxBonusLevel", 100); }
|
||||
public double getBurnTimeMultiplier() { return config.getDouble("Skills.Smelting.FuelEfficiency.Multiplier", 3.0D); }
|
||||
public int getBurnModifierMaxLevel() {
|
||||
if(mcMMO.isRetroModeEnabled())
|
||||
return config.getInt("Skills.Smelting.FuelEfficiency.RetroMode.MaxBonusLevel", 1000);
|
||||
else
|
||||
return config.getInt("Skills.Smelting.FuelEfficiency.Standard.MaxBonusLevel", 100);
|
||||
}
|
||||
|
||||
/*public int getFluxMiningUnlockLevel() { return config.getInt("Skills.Smelting.FluxMining.UnlockLevel", 250); }*/
|
||||
public double getFluxMiningChance() { return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D); }
|
||||
|
||||
@@ -186,10 +186,6 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
reason.add("Abilities.Fishing.Lure_Modifier should be at least 0!");
|
||||
}
|
||||
|
||||
if (getDetonatorItem() == null) {
|
||||
reason.add("Skills.Mining.Detonator_Item is invalid!");
|
||||
}
|
||||
|
||||
if (getRepairAnvilMaterial() == null) {
|
||||
reason.add("Skills.Repair.Anvil_Type is invalid!!");
|
||||
}
|
||||
@@ -245,6 +241,8 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
* GENERAL SETTINGS
|
||||
*/
|
||||
|
||||
public boolean isAprilFoolsAllowed() { return config.getBoolean("General.AprilFoolsEvent", true); }
|
||||
|
||||
/* General Settings */
|
||||
public boolean getIsMetricsEnabled() { return config.getBoolean("Metrics.bstats", true); }
|
||||
|
||||
@@ -405,7 +403,7 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
public boolean getCallOfTheWildEffectEnabled() { return config.getBoolean("Particles.Call_of_the_Wild", true); }
|
||||
public boolean getLevelUpEffectsEnabled() { return config.getBoolean("Particles.LevelUp_Enabled", true); }
|
||||
public int getLevelUpEffectsTier() { return config.getInt("Particles.LevelUp_Tier", 100); }
|
||||
public boolean getLargeFireworks() { return config.getBoolean("Particles.LargeFireworks", true); }
|
||||
// public boolean getLargeFireworks() { return config.getBoolean("Particles.LargeFireworks", true); }
|
||||
|
||||
/* PARTY SETTINGS */
|
||||
public boolean getPartyFriendlyFire() { return config.getBoolean("Party.FriendlyFire", false);}
|
||||
@@ -463,18 +461,18 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
/*
|
||||
* SKILL SETTINGS
|
||||
*/
|
||||
public boolean getDoubleDropsEnabled(PrimarySkillType skill, Material material) { return config.getBoolean("Double_Drops." + StringUtils.getCapitalized(skill.toString()) + "." + StringUtils.getPrettyItemString(material).replace(" ", "_")); }
|
||||
public boolean getDoubleDropsEnabled(PrimarySkillType skill, Material material) { return config.getBoolean("Bonus_Drops." + StringUtils.getCapitalized(skill.toString()) + "." + StringUtils.getPrettyItemString(material).replace(" ", "_")); }
|
||||
|
||||
public boolean getDoubleDropsDisabled(PrimarySkillType skill) {
|
||||
String skillName = StringUtils.getCapitalized(skill.toString());
|
||||
ConfigurationSection section = config.getConfigurationSection("Double_Drops." + skillName);
|
||||
ConfigurationSection section = config.getConfigurationSection("Bonus_Drops." + skillName);
|
||||
if (section == null)
|
||||
return false;
|
||||
Set<String> keys = section.getKeys(false);
|
||||
boolean disabled = true;
|
||||
|
||||
for (String key : keys) {
|
||||
if (config.getBoolean("Double_Drops." + skillName + "." + key)) {
|
||||
if (config.getBoolean("Bonus_Drops." + skillName + "." + key)) {
|
||||
disabled = false;
|
||||
break;
|
||||
}
|
||||
@@ -503,7 +501,6 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
|
||||
/* Mining */
|
||||
public Material getDetonatorItem() { return Material.matchMaterial(config.getString("Skills.Mining.Detonator_Name", "FLINT_AND_STEEL")); }
|
||||
public int getMiningGate() { return config.getInt("Skills.Mining.Ability_Activation_Level_Gate", 10); }
|
||||
|
||||
/* Excavation */
|
||||
public int getExcavationGate() { return config.getInt("Skills.Excavation.Ability_Activation_Level_Gate", 10); }
|
||||
@@ -540,13 +537,11 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
public double getTamingCOTWRange() { return config.getDouble("Skills.Taming.Call_Of_The_Wild.Range", 40.0D); }
|
||||
|
||||
/* Woodcutting */
|
||||
public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) { return config.getBoolean("Double_Drops.Woodcutting." + StringUtils.getFriendlyConfigBlockDataString(material)); }
|
||||
public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) { return config.getBoolean("Bonus_Drops.Woodcutting." + StringUtils.getFriendlyConfigBlockDataString(material)); }
|
||||
public boolean getTreeFellerSoundsEnabled() { return config.getBoolean("Skills.Woodcutting.Tree_Feller_Sounds", true); }
|
||||
public int getWoodcuttingGate() { return config.getInt("Skills.Woodcutting.Ability_Activation_Level_Gate", 10); }
|
||||
|
||||
/* AFK Leveling */
|
||||
public boolean getAcrobaticsPreventAFK() { return config.getBoolean("Skills.Acrobatics.Prevent_AFK_Leveling", true); }
|
||||
public int getAcrobaticsAFKMaxTries() { return config.getInt("Skills.Acrobatics.Max_Tries_At_Same_Location", 3); }
|
||||
public boolean getHerbalismPreventAFK() { return config.getBoolean("Skills.Herbalism.Prevent_AFK_Leveling", true); }
|
||||
|
||||
/* Level Caps */
|
||||
|
||||
@@ -144,6 +144,9 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
|
||||
/* EXPLOIT TOGGLES */
|
||||
public boolean isEndermanEndermiteFarmingPrevented() { return config.getBoolean("ExploitFix.EndermanEndermiteFarms", true); }
|
||||
|
||||
public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); }
|
||||
public boolean isAcrobaticsExploitingPrevented() { return config.getBoolean("ExploitFix.Acrobatics", true); }
|
||||
|
||||
/* Curve settings */
|
||||
public FormulaType getFormulaType() { return FormulaType.getFormulaType(config.getString("Experience_Formula.Curve")); }
|
||||
public boolean getCumulativeCurveEnabled() { return config.getBoolean("Experience_Formula.Cumulative_Curve", false); }
|
||||
|
||||
@@ -3,12 +3,16 @@ package com.gmail.nossr50.datatypes.party;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.experience.FormulaType;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.util.EventUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -18,8 +22,15 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Party {
|
||||
// private static final String ONLINE_PLAYER_PREFIX = "★";
|
||||
// private static final String ONLINE_PLAYER_PREFIX = "●" + ChatColor.RESET;
|
||||
private static final String ONLINE_PLAYER_PREFIX = "⬤";
|
||||
// private static final String OFFLINE_PLAYER_PREFIX = "☆";
|
||||
private static final String OFFLINE_PLAYER_PREFIX = "○";
|
||||
// private static final String OFFLINE_PLAYER_PREFIX = "⭕" + ChatColor.RESET;
|
||||
private final LinkedHashMap<UUID, String> members = new LinkedHashMap<UUID, String>();
|
||||
private final List<Player> onlineMembers = new ArrayList<Player>();
|
||||
|
||||
@@ -324,36 +335,203 @@ public class Party {
|
||||
return this.getMembers().keySet().contains(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a formatted list of party members based on the perspective of a target player
|
||||
* Players that are hidden will be shown as offline (formatted in the same way)
|
||||
* Party leader will be formatted a specific way as well
|
||||
* @param player target player to use as POV
|
||||
* @return formatted list of party members from the POV of a player
|
||||
*/
|
||||
public String createMembersList(Player player) {
|
||||
StringBuilder memberList = new StringBuilder();
|
||||
|
||||
for (Player otherPlayer : this.getVisibleMembers(player)) {
|
||||
String memberName = otherPlayer.getName();
|
||||
List<UUID> onlineMembers = members.keySet().stream()
|
||||
.filter(x -> Bukkit.getOfflinePlayer(x).isOnline())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (this.getLeader().getUniqueId().equals(otherPlayer.getUniqueId())) {
|
||||
memberList.append(ChatColor.GOLD);
|
||||
List<UUID> offlineMembers = members.keySet().stream()
|
||||
.filter(x -> !Bukkit.getOfflinePlayer(x).isOnline())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (otherPlayer == null) {
|
||||
memberName = memberName.substring(0, 1) + ChatColor.GRAY + ChatColor.ITALIC + "" + memberName.substring(1);
|
||||
}
|
||||
}
|
||||
else if (otherPlayer != null) {
|
||||
memberList.append(ChatColor.WHITE);
|
||||
}
|
||||
else {
|
||||
memberList.append(ChatColor.GRAY);
|
||||
}
|
||||
ArrayList<UUID> visiblePartyList = new ArrayList<>();
|
||||
boolean isPartyLeaderOfflineOrHidden = false;
|
||||
ArrayList<UUID> offlineOrHiddenPartyList = new ArrayList<>();
|
||||
|
||||
if (player.getName().equalsIgnoreCase(otherPlayer.getName())) {
|
||||
memberList.append(ChatColor.ITALIC);
|
||||
}
|
||||
for(UUID onlineMember : onlineMembers)
|
||||
{
|
||||
Player onlinePlayer = Bukkit.getPlayer(onlineMember);
|
||||
|
||||
memberList.append(memberName).append(ChatColor.RESET).append(" ");
|
||||
if(!isNotSamePerson(player.getUniqueId(), onlineMember) || player.canSee(onlinePlayer))
|
||||
{
|
||||
visiblePartyList.add(onlineMember);
|
||||
} else {
|
||||
//Party leader and cannot be seen by this player
|
||||
if(isNotSamePerson(leader.getUniqueId(), player.getUniqueId()) && onlineMember == leader.getUniqueId())
|
||||
isPartyLeaderOfflineOrHidden = true;
|
||||
|
||||
offlineOrHiddenPartyList.add(onlineMember);
|
||||
}
|
||||
}
|
||||
|
||||
if(offlineMembers.contains(leader.getUniqueId()))
|
||||
isPartyLeaderOfflineOrHidden = true;
|
||||
|
||||
//Add all the actually offline members
|
||||
offlineOrHiddenPartyList.addAll(offlineMembers);
|
||||
|
||||
/* BUILD THE PARTY LIST WITH FORMATTING */
|
||||
|
||||
String partyLeaderPrefix =
|
||||
/*ChatColor.WHITE
|
||||
+ "["
|
||||
+*/ ChatColor.GOLD
|
||||
+ "♕"
|
||||
/*+ ChatColor.WHITE
|
||||
+ "]"*/
|
||||
+ ChatColor.RESET;
|
||||
|
||||
//First add the party leader
|
||||
memberList.append(partyLeaderPrefix);
|
||||
|
||||
List<Player> nearbyPlayerList = getNearMembers(UserManager.getPlayer(player));
|
||||
|
||||
boolean useDisplayNames = Config.getInstance().getPartyDisplayNames();
|
||||
|
||||
if(isPartyLeaderOfflineOrHidden)
|
||||
{
|
||||
if(isNotSamePerson(player.getUniqueId(), leader.getUniqueId()))
|
||||
applyOnlineAndRangeFormatting(memberList, false, false);
|
||||
|
||||
memberList.append(ChatColor.GRAY)
|
||||
.append(leader.getPlayerName());
|
||||
}
|
||||
else {
|
||||
if(isNotSamePerson(leader.getUniqueId(), player.getUniqueId()))
|
||||
applyOnlineAndRangeFormatting(memberList, true, nearbyPlayerList.contains(Bukkit.getPlayer(leader.getUniqueId())));
|
||||
|
||||
if(useDisplayNames) {
|
||||
memberList.append(leader.getPlayerName());
|
||||
} else {
|
||||
memberList.append(ChatColor.GOLD)
|
||||
.append(Bukkit.getOfflinePlayer(leader.getUniqueId()));
|
||||
}
|
||||
}
|
||||
|
||||
//Space
|
||||
memberList.append(" ");
|
||||
|
||||
//Now do online members
|
||||
for(UUID onlinePlayerUUID : visiblePartyList)
|
||||
{
|
||||
if(onlinePlayerUUID == leader.getUniqueId())
|
||||
continue;
|
||||
|
||||
if(isNotSamePerson(onlinePlayerUUID, player.getUniqueId()))
|
||||
applyOnlineAndRangeFormatting(memberList, true, nearbyPlayerList.contains(Bukkit.getPlayer(onlinePlayerUUID)));
|
||||
|
||||
if(useDisplayNames)
|
||||
{
|
||||
memberList.append(Bukkit.getPlayer(onlinePlayerUUID).getDisplayName());
|
||||
}
|
||||
else
|
||||
{
|
||||
//Color allies green, players dark aqua
|
||||
memberList.append(ChatColor.GREEN)
|
||||
.append(Bukkit.getPlayer(onlinePlayerUUID).getName());
|
||||
}
|
||||
|
||||
memberList.append(" ").append(ChatColor.RESET);
|
||||
}
|
||||
|
||||
for(UUID offlineOrHiddenPlayer : offlineOrHiddenPartyList)
|
||||
{
|
||||
if(offlineOrHiddenPlayer == leader.getUniqueId())
|
||||
continue;
|
||||
|
||||
applyOnlineAndRangeFormatting(memberList, false, false);
|
||||
|
||||
memberList.append(ChatColor.GRAY)
|
||||
.append(Bukkit.getOfflinePlayer(offlineOrHiddenPlayer).getName())
|
||||
.append(" ").append(ChatColor.RESET);
|
||||
}
|
||||
|
||||
|
||||
// for (Player otherPlayer : this.getVisibleMembers(player)) {
|
||||
// String memberName = otherPlayer.getName();
|
||||
//
|
||||
// if (this.getLeader().getUniqueId().equals(otherPlayer.getUniqueId())) {
|
||||
// memberList.append(ChatColor.GOLD);
|
||||
//
|
||||
// if (otherPlayer == null) {
|
||||
// memberName = memberName.substring(0, 1) + ChatColor.GRAY + ChatColor.ITALIC + "" + memberName.substring(1);
|
||||
// }
|
||||
// }
|
||||
// else if (otherPlayer != null) {
|
||||
// memberList.append(ChatColor.WHITE);
|
||||
// }
|
||||
// else {
|
||||
// memberList.append(ChatColor.GRAY);
|
||||
// }
|
||||
//
|
||||
// if (player.getName().equalsIgnoreCase(otherPlayer.getName())) {
|
||||
// memberList.append(ChatColor.ITALIC);
|
||||
// }
|
||||
//
|
||||
// memberList.append(memberName).append(ChatColor.RESET).append(" ");
|
||||
// }
|
||||
|
||||
return memberList.toString();
|
||||
}
|
||||
|
||||
private boolean isNotSamePerson(UUID onlinePlayerUUID, UUID uniqueId) {
|
||||
return onlinePlayerUUID != uniqueId;
|
||||
}
|
||||
|
||||
private void applyOnlineAndRangeFormatting(StringBuilder stringBuilder, boolean isVisibleOrOnline, boolean isNear)
|
||||
{
|
||||
if(isVisibleOrOnline)
|
||||
{
|
||||
if(isNear)
|
||||
{
|
||||
stringBuilder.append(ChatColor.GREEN);
|
||||
} else {
|
||||
stringBuilder.append(ChatColor.GRAY);
|
||||
}
|
||||
|
||||
// stringBuilder.append(ChatColor.BOLD);
|
||||
stringBuilder.append(ONLINE_PLAYER_PREFIX);
|
||||
} else {
|
||||
stringBuilder.append(ChatColor.GRAY);
|
||||
stringBuilder.append(OFFLINE_PLAYER_PREFIX);
|
||||
}
|
||||
|
||||
stringBuilder.append(ChatColor.RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the near party members.
|
||||
*
|
||||
* @param mcMMOPlayer The player to check
|
||||
* @return the near party members
|
||||
*/
|
||||
public List<Player> getNearMembers(McMMOPlayer mcMMOPlayer) {
|
||||
List<Player> nearMembers = new ArrayList<Player>();
|
||||
Party party = mcMMOPlayer.getParty();
|
||||
|
||||
if (party != null) {
|
||||
Player player = mcMMOPlayer.getPlayer();
|
||||
double range = Config.getInstance().getPartyShareRange();
|
||||
|
||||
for (Player member : party.getOnlineMembers()) {
|
||||
if (!player.equals(member) && member.isValid() && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
|
||||
nearMembers.add(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nearMembers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
|
||||
@@ -542,7 +542,7 @@ public class McMMOPlayer {
|
||||
*/
|
||||
private void checkXp(PrimarySkillType primarySkillType, XPGainReason xpGainReason, XPGainSource xpGainSource) {
|
||||
if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) {
|
||||
UserManager.getPlayer(player).processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -560,7 +560,7 @@ public class McMMOPlayer {
|
||||
}
|
||||
|
||||
if (!EventUtils.handleLevelChangeEvent(player, primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) {
|
||||
UserManager.getPlayer(player).processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -572,10 +572,10 @@ public class McMMOPlayer {
|
||||
* Check to see if the player unlocked any new skills
|
||||
*/
|
||||
|
||||
NotificationManager.sendPlayerLevelUpNotification(UserManager.getPlayer(player), primarySkillType, levelsGained, profile.getSkillLevel(primarySkillType));
|
||||
NotificationManager.sendPlayerLevelUpNotification(this, primarySkillType, levelsGained, profile.getSkillLevel(primarySkillType));
|
||||
|
||||
//UPDATE XP BARS
|
||||
UserManager.getPlayer(player).processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,6 +29,7 @@ public class PlayerProfile {
|
||||
/* HUDs */
|
||||
private MobHealthbarType mobHealthbarType;
|
||||
private int scoreboardTipsShown;
|
||||
private int saveAttempts = 0;
|
||||
|
||||
/* Skill Data */
|
||||
private final Map<PrimarySkillType, Integer> skills = new HashMap<PrimarySkillType, Integer>(); // Skill & Level
|
||||
@@ -36,7 +37,7 @@ public class PlayerProfile {
|
||||
private final Map<SuperAbilityType, Integer> abilityDATS = new HashMap<SuperAbilityType, Integer>(); // Ability & Cooldown
|
||||
private final Map<UniqueDataType, Integer> uniquePlayerData = new HashMap<>(); //Misc data that doesn't fit into other categories (chimaera wing, etc..)
|
||||
|
||||
// Store previous XP gains for deminished returns
|
||||
// Store previous XP gains for diminished returns
|
||||
private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<SkillXpGain>();
|
||||
private HashMap<PrimarySkillType, Float> rollingSkillsXp = new HashMap<PrimarySkillType, Float>();
|
||||
|
||||
@@ -94,8 +95,13 @@ public class PlayerProfile {
|
||||
new PlayerProfileSaveTask(this).runTaskAsynchronously(mcMMO.p);
|
||||
}
|
||||
|
||||
public void scheduleAsyncSaveDelay() {
|
||||
new PlayerProfileSaveTask(this).runTaskLaterAsynchronously(mcMMO.p, 20);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (!changed || !loaded) {
|
||||
saveAttempts = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,8 +110,29 @@ public class PlayerProfile {
|
||||
changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
|
||||
|
||||
if (changed) {
|
||||
mcMMO.p.getLogger().warning("PlayerProfile saving failed for player: " + playerName + " " + uuid);
|
||||
mcMMO.p.getLogger().severe("PlayerProfile saving failed for player: " + playerName + " " + uuid);
|
||||
|
||||
if(saveAttempts > 0)
|
||||
{
|
||||
mcMMO.p.getLogger().severe("Attempted to save profile for player "+getPlayerName()
|
||||
+ " resulted in failure. "+saveAttempts+" have been made so far.");
|
||||
}
|
||||
|
||||
if(saveAttempts < 10)
|
||||
{
|
||||
saveAttempts++;
|
||||
scheduleAsyncSaveDelay();
|
||||
return;
|
||||
} else {
|
||||
mcMMO.p.getLogger().severe("mcMMO has failed to save the profile for "
|
||||
+getPlayerName()+" numerous times." +
|
||||
" mcMMO will now stop attempting to save this profile." +
|
||||
" Check your console for errors and inspect your DB for issues.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
saveAttempts = 0;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
||||
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.StringUtils;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bukkit.Color;
|
||||
@@ -35,21 +34,36 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public enum PrimarySkillType {
|
||||
ACROBATICS(AcrobaticsManager.class, Color.WHITE, ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL)),
|
||||
ALCHEMY(AlchemyManager.class, Color.FUCHSIA, ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS)),
|
||||
ARCHERY(ArcheryManager.class, Color.MAROON, ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT)),
|
||||
AXES(AxesManager.class, Color.AQUA, SuperAbilityType.SKULL_SPLITTER, ToolType.AXE, ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT)),
|
||||
EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), SuperAbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL, ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY)),
|
||||
FISHING(FishingManager.class, Color.NAVY, ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE)),
|
||||
HERBALISM(HerbalismManager.class, Color.GREEN, SuperAbilityType.GREEN_TERRA, ToolType.HOE, ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB)),
|
||||
MINING(MiningManager.class, Color.GRAY, SuperAbilityType.SUPER_BREAKER, ToolType.PICKAXE, ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS)),
|
||||
REPAIR(RepairManager.class, Color.SILVER, ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR)),
|
||||
SALVAGE(SalvageManager.class, Color.ORANGE, ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE)),
|
||||
SMELTING(SmeltingManager.class, Color.YELLOW, ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, SubSkillType.SMELTING_FLUX_MINING, SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT)),
|
||||
SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD, ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK)),
|
||||
TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL)),
|
||||
UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS, ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)),
|
||||
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE, ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER));
|
||||
ACROBATICS(AcrobaticsManager.class, Color.WHITE,
|
||||
ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL)),
|
||||
ALCHEMY(AlchemyManager.class, Color.FUCHSIA,
|
||||
ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS)),
|
||||
ARCHERY(ArcheryManager.class, Color.MAROON,
|
||||
ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT)),
|
||||
AXES(AxesManager.class, Color.AQUA, SuperAbilityType.SKULL_SPLITTER, ToolType.AXE,
|
||||
ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_AXES_LIMIT_BREAK, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT)),
|
||||
EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), SuperAbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL,
|
||||
ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY)),
|
||||
FISHING(FishingManager.class, Color.NAVY,
|
||||
ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE)),
|
||||
HERBALISM(HerbalismManager.class, Color.GREEN, SuperAbilityType.GREEN_TERRA, ToolType.HOE,
|
||||
ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB)),
|
||||
MINING(MiningManager.class, Color.GRAY, SuperAbilityType.SUPER_BREAKER, ToolType.PICKAXE,
|
||||
ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS)),
|
||||
REPAIR(RepairManager.class, Color.SILVER,
|
||||
ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR)),
|
||||
SALVAGE(SalvageManager.class, Color.ORANGE,
|
||||
ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE)),
|
||||
SMELTING(SmeltingManager.class, Color.YELLOW,
|
||||
ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT)),
|
||||
SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD,
|
||||
ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK, SubSkillType.SWORDS_STAB, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK)),
|
||||
TAMING(TamingManager.class, Color.PURPLE,
|
||||
ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL)),
|
||||
UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS,
|
||||
ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)),
|
||||
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE,
|
||||
ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER));
|
||||
|
||||
private Class<? extends SkillManager> managerClass;
|
||||
private Color runescapeColor;
|
||||
@@ -228,9 +242,9 @@ public enum PrimarySkillType {
|
||||
return Permissions.skillEnabled(player, this);
|
||||
}
|
||||
|
||||
public void celebrateLevelUp(Player player) {
|
||||
/* public void celebrateLevelUp(Player player) {
|
||||
ParticleEffectUtils.fireworkParticleShower(player, runescapeColor);
|
||||
}
|
||||
}*/
|
||||
|
||||
public boolean shouldProcess(Entity target) {
|
||||
return (target instanceof Player || (target instanceof Tameable && ((Tameable) target).isTamed())) ? getPVPEnabled() : getPVEEnabled();
|
||||
|
||||
@@ -18,10 +18,12 @@ public enum SubSkillType {
|
||||
ARCHERY_ARROW_RETRIEVAL(1),
|
||||
ARCHERY_DAZE,
|
||||
ARCHERY_SKILL_SHOT(20),
|
||||
ARCHERY_ARCHERY_LIMIT_BREAK(10),
|
||||
|
||||
/* Axes */
|
||||
AXES_ARMOR_IMPACT(20),
|
||||
AXES_AXE_MASTERY(4),
|
||||
AXES_AXES_LIMIT_BREAK(10),
|
||||
AXES_CRITICAL_STRIKES(1),
|
||||
AXES_GREATER_IMPACT(1),
|
||||
AXES_SKULL_SPLITTER(1),
|
||||
@@ -63,8 +65,7 @@ public enum SubSkillType {
|
||||
SALVAGE_ARCANE_SALVAGE(8),
|
||||
|
||||
/* Smelting */
|
||||
SMELTING_FLUX_MINING(1),
|
||||
SMELTING_FUEL_EFFICIENCY,
|
||||
SMELTING_FUEL_EFFICIENCY(3),
|
||||
SMELTING_SECOND_SMELT,
|
||||
SMELTING_UNDERSTANDING_THE_ART(8),
|
||||
|
||||
@@ -72,6 +73,8 @@ public enum SubSkillType {
|
||||
SWORDS_COUNTER_ATTACK(1),
|
||||
SWORDS_RUPTURE(4),
|
||||
SWORDS_SERRATED_STRIKES(1),
|
||||
SWORDS_STAB(2),
|
||||
SWORDS_SWORDS_LIMIT_BREAK(10),
|
||||
|
||||
/* Taming */
|
||||
TAMING_BEAST_LORE(1),
|
||||
@@ -92,6 +95,7 @@ public enum SubSkillType {
|
||||
UNARMED_DISARM(1),
|
||||
UNARMED_IRON_ARM_STYLE(5),
|
||||
UNARMED_IRON_GRIP(1),
|
||||
UNARMED_UNARMED_LIMIT_BREAK(10),
|
||||
|
||||
/* Woodcutting */
|
||||
/* WOODCUTTING_BARK_SURGEON(3),*/
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.LimitedSizeList;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
@@ -34,14 +32,11 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Roll extends AcrobaticsSubSkill {
|
||||
protected HashMap<Player, LimitedSizeList> fallLocationMap;
|
||||
|
||||
|
||||
public Roll() {
|
||||
super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL);
|
||||
fallLocationMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,6 +68,9 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
//Grab the player
|
||||
McMMOPlayer mcMMOPlayer = EventUtils.getMcMMOPlayer(entityDamageEvent.getEntity());
|
||||
|
||||
if(mcMMOPlayer == null)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check for success
|
||||
*/
|
||||
@@ -210,7 +208,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
//player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
|
||||
|
||||
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
|
||||
if(!isExploiting(player))
|
||||
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
|
||||
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
|
||||
//}
|
||||
|
||||
@@ -219,7 +217,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
}
|
||||
else if (!isFatal(player, damage)) {
|
||||
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
|
||||
if(!isExploiting(player))
|
||||
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
|
||||
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
|
||||
//}
|
||||
}
|
||||
@@ -249,14 +247,14 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
{
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc");
|
||||
SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F);
|
||||
if(!isExploiting(player))
|
||||
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
|
||||
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
|
||||
|
||||
addFallLocation(player);
|
||||
return modifiedDamage;
|
||||
}
|
||||
else if (!isFatal(player, damage)) {
|
||||
if(!isExploiting(player))
|
||||
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
|
||||
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
|
||||
|
||||
addFallLocation(player);
|
||||
@@ -272,7 +270,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
* @return true if exploits are detected, false otherwise
|
||||
*/
|
||||
private boolean isExploiting(Player player) {
|
||||
if (!Config.getInstance().getAcrobaticsPreventAFK()) {
|
||||
if (!ExperienceConfig.getInstance().isAcrobaticsExploitingPrevented()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -280,25 +278,10 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(fallLocationMap.get(player) == null)
|
||||
fallLocationMap.put(player, new LimitedSizeList(50));
|
||||
|
||||
LimitedSizeList fallLocations = fallLocationMap.get(player);
|
||||
|
||||
if(fallLocations.contains(getBlockLocation(player)))
|
||||
if(UserManager.getPlayer(player).getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(player)))
|
||||
return true;
|
||||
|
||||
return false; //NOT EXPLOITING
|
||||
/*
|
||||
Location fallLocation = player.getLocation();
|
||||
int maxTries = Config.getInstance().getAcrobaticsAFKMaxTries();
|
||||
|
||||
boolean sameLocation = (lastFallLocation != null && Misc.isNear(lastFallLocation, fallLocation, 2));
|
||||
|
||||
fallTries = sameLocation ? Math.min(fallTries + 1, maxTries) : Math.max(fallTries - 1, 0);
|
||||
lastFallLocation = fallLocation;
|
||||
|
||||
return fallTries + 1 > maxTries;*/
|
||||
}
|
||||
|
||||
private float calculateRollXP(Player player, double damage, boolean isRoll) {
|
||||
@@ -426,13 +409,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
|
||||
public void addFallLocation(Player player)
|
||||
{
|
||||
if(fallLocationMap.get(player) == null)
|
||||
fallLocationMap.put(player, new LimitedSizeList(50));
|
||||
|
||||
LimitedSizeList fallLocations = fallLocationMap.get(player);
|
||||
|
||||
Location loc = getBlockLocation(player);
|
||||
fallLocations.add(loc);
|
||||
UserManager.getPlayer(player).getAcrobaticsManager().addLocationToFallMap(getBlockLocation(player));
|
||||
}
|
||||
|
||||
public Location getBlockLocation(Player player)
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.*;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -54,6 +55,75 @@ public class BlockListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockDropItemEvent(BlockDropItemEvent event)
|
||||
{
|
||||
for(Item item : event.getItems())
|
||||
{
|
||||
ItemStack is = new ItemStack(item.getItemStack());
|
||||
|
||||
if(is.getAmount() <= 0)
|
||||
continue;
|
||||
|
||||
//TODO: Ignore this abomination its rewritten in 2.2
|
||||
if(!Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, is.getType())
|
||||
&& !Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.HERBALISM, is.getType())
|
||||
&& !Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, is.getType()))
|
||||
continue;
|
||||
|
||||
//TODO: Should just store the amount of drops in the metadata itself and use a loop
|
||||
if(event.getBlock().getState().getMetadata(mcMMO.doubleDrops).size() > 0)
|
||||
{
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
event.getBlock().getState().removeMetadata(mcMMO.doubleDrops, plugin);
|
||||
}
|
||||
else if(event.getBlock().getState().getMetadata(mcMMO.tripleDrops).size() > 0)
|
||||
{
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
event.getBlock().getState().removeMetadata(mcMMO.tripleDrops, plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockDropItemEvent(BlockDropItemEvent event)
|
||||
{
|
||||
for(Item item : event.getItems())
|
||||
{
|
||||
ItemStack is = new ItemStack(item.getItemStack());
|
||||
|
||||
if(event.getBlock().getMetadata(mcMMO.doubleDrops).size() > 0)
|
||||
{
|
||||
List<MetadataValue> metadataValue = event.getBlock().getMetadata(mcMMO.doubleDrops);
|
||||
|
||||
BonusDrops bonusDrops = (BonusDrops) metadataValue.get(0);
|
||||
Collection<ItemStack> potentialDrops = (Collection<ItemStack>) bonusDrops.value();
|
||||
|
||||
if(potentialDrops.contains(is))
|
||||
{
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
}
|
||||
|
||||
event.getBlock().removeMetadata(mcMMO.doubleDrops, plugin);
|
||||
} else {
|
||||
if(event.getBlock().getMetadata(mcMMO.tripleDrops).size() > 0) {
|
||||
List<MetadataValue> metadataValue = event.getBlock().getMetadata(mcMMO.tripleDrops);
|
||||
|
||||
BonusDrops bonusDrops = (BonusDrops) metadataValue.get(0);
|
||||
Collection<ItemStack> potentialDrops = (Collection<ItemStack>) bonusDrops.value();
|
||||
|
||||
if (potentialDrops.contains(is)) {
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
|
||||
}
|
||||
|
||||
event.getBlock().removeMetadata(mcMMO.tripleDrops, plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Monitor BlockPistonExtend events.
|
||||
*
|
||||
@@ -70,7 +140,7 @@ public class BlockListener implements Listener {
|
||||
movedBlock = movedBlock.getRelative(direction, 2);
|
||||
|
||||
for (Block b : event.getBlocks()) {
|
||||
if (BlockUtils.shouldBeWatched(b.getState()) && mcMMO.getPlaceStore().isTrue(b)) {
|
||||
if (BlockUtils.shouldBeWatched(b.getState())) {
|
||||
movedBlock = b.getRelative(direction);
|
||||
mcMMO.getPlaceStore().setTrue(movedBlock);
|
||||
}
|
||||
@@ -176,6 +246,9 @@ public class BlockListener implements Listener {
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
if(mcMMOPlayer == null)
|
||||
return;
|
||||
|
||||
if (blockState.getType() == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player)) {
|
||||
mcMMOPlayer.getRepairManager().placedAnvilCheck();
|
||||
}
|
||||
@@ -269,6 +342,11 @@ public class BlockListener implements Listener {
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Check if profile is loaded
|
||||
if(mcMMOPlayer == null)
|
||||
return;
|
||||
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
|
||||
/* HERBALISM */
|
||||
@@ -348,6 +426,12 @@ public class BlockListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BlockState blockState = event.getBlock().getState();
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
|
||||
@@ -413,6 +497,12 @@ public class BlockListener implements Listener {
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Profile not loaded
|
||||
if(mcMMOPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ABILITY PREPARATION CHECKS
|
||||
*
|
||||
@@ -487,6 +577,13 @@ public class BlockListener implements Listener {
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
Block block = event.getBlock();
|
||||
BlockState blockState = block.getState();
|
||||
@@ -522,6 +619,14 @@ public class BlockListener implements Listener {
|
||||
public void onBlockDamageCleanup(BlockDamageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BlockState blockState = event.getBlock().getState();
|
||||
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
@@ -532,6 +637,12 @@ public class BlockListener implements Listener {
|
||||
}
|
||||
|
||||
public void debugStickDump(Player player, BlockState blockState) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(player.getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK)
|
||||
{
|
||||
if(mcMMO.getPlaceStore().isTrue(blockState))
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.gmail.nossr50.events.fake.FakeEntityTameEvent;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.skills.archery.Archery;
|
||||
import com.gmail.nossr50.skills.fishing.Fishing;
|
||||
import com.gmail.nossr50.skills.mining.BlastMining;
|
||||
import com.gmail.nossr50.skills.mining.MiningManager;
|
||||
import com.gmail.nossr50.skills.taming.Taming;
|
||||
@@ -54,6 +53,19 @@ public class EntityListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onEntityTransform(EntityTransformEvent event)
|
||||
{
|
||||
//Transfer metadata keys from mob-spawned mobs to new mobs
|
||||
if(event.getEntity().getMetadata(mcMMO.entityMetadataKey) != null || event.getEntity().getMetadata(mcMMO.entityMetadataKey).size() >= 1)
|
||||
{
|
||||
for(Entity entity : event.getTransformedEntities())
|
||||
{
|
||||
entity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityTargetEntity(EntityTargetLivingEntityEvent event)
|
||||
{
|
||||
@@ -173,6 +185,75 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/*@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onEntityDamageDebugLowest(EntityDamageEvent event)
|
||||
{
|
||||
if(event instanceof FakeEntityDamageByEntityEvent)
|
||||
return;
|
||||
|
||||
if(event instanceof FakeEntityDamageEvent)
|
||||
return;
|
||||
|
||||
Bukkit.broadcastMessage(ChatColor.DARK_AQUA+"DMG Before Events: "
|
||||
+ChatColor.RESET+event.getDamage());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDamageDebugMonitor(EntityDamageEvent event)
|
||||
{
|
||||
if(event instanceof FakeEntityDamageByEntityEvent)
|
||||
return;
|
||||
|
||||
if(event instanceof FakeEntityDamageEvent)
|
||||
return;
|
||||
|
||||
if(!(event.getEntity() instanceof LivingEntity))
|
||||
return;
|
||||
|
||||
LivingEntity entity = (LivingEntity) event.getEntity();
|
||||
|
||||
double rawDamage = event.getDamage();
|
||||
double dmgAfterReduction = event.getFinalDamage();
|
||||
|
||||
Bukkit.broadcastMessage(ChatColor.GOLD+"DMG After Events: "
|
||||
+ event.getEntity().getName()+ChatColor.RESET
|
||||
+"RawDMG["+rawDamage+"], "
|
||||
+"FinalDMG=["+dmgAfterReduction+"]");
|
||||
|
||||
Bukkit.broadcastMessage(
|
||||
event.getEntity().getName()
|
||||
+ChatColor.GREEN
|
||||
+" HP "
|
||||
+ChatColor.RESET
|
||||
+entity.getHealth()
|
||||
+ChatColor.YELLOW
|
||||
+" -> "
|
||||
+ChatColor.RESET
|
||||
+(entity.getHealth()-event.getFinalDamage()));
|
||||
|
||||
Bukkit.broadcastMessage("");
|
||||
}*/
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onEntityDamageLowest(EntityDamageByEntityEvent event)
|
||||
{
|
||||
Entity defender = event.getEntity();
|
||||
|
||||
if(defender.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() > 0)
|
||||
{
|
||||
defender.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, plugin);
|
||||
|
||||
if(defender instanceof Player)
|
||||
{
|
||||
LivingEntity defLive = (LivingEntity) defender;
|
||||
defLive.setHealth(Math.max(0, (defLive.getHealth() - event.getFinalDamage())));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle EntityDamageByEntity events that involve modifying the event.
|
||||
*
|
||||
@@ -181,6 +262,10 @@ public class EntityListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
|
||||
double damage = event.getFinalDamage();
|
||||
Entity defender = event.getEntity();
|
||||
Entity attacker = event.getDamager();
|
||||
|
||||
/* WORLD BLACKLIST CHECK */
|
||||
if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
||||
return;
|
||||
@@ -199,10 +284,6 @@ public class EntityListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
double damage = event.getFinalDamage();
|
||||
Entity defender = event.getEntity();
|
||||
Entity attacker = event.getDamager();
|
||||
|
||||
if(attacker instanceof Player)
|
||||
{
|
||||
Player player = (Player) attacker;
|
||||
@@ -251,8 +332,6 @@ public class EntityListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Misc.isNPCEntity(attacker)) {
|
||||
return;
|
||||
}
|
||||
@@ -322,6 +401,8 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,6 +479,10 @@ public class EntityListener implements Listener {
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Profile not loaded
|
||||
if(mcMMOPlayer == null)
|
||||
return;
|
||||
|
||||
/* Check for invincibility */
|
||||
if (mcMMOPlayer.getGodMode()) {
|
||||
event.setCancelled(true);
|
||||
@@ -429,6 +514,12 @@ public class EntityListener implements Listener {
|
||||
Player player = (Player) owner;
|
||||
Wolf wolf = (Wolf) pet;
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TamingManager tamingManager = UserManager.getPlayer(player).getTamingManager();
|
||||
|
||||
switch (cause) {
|
||||
@@ -606,6 +697,12 @@ public class EntityListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* WORLD GUARD MAIN FLAG CHECK */
|
||||
if(WorldGuardUtils.isWorldGuardLoaded())
|
||||
{
|
||||
@@ -653,6 +750,12 @@ public class EntityListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MiningManager miningManager = UserManager.getPlayer(player).getMiningManager();
|
||||
|
||||
if (miningManager.canUseBlastMining()) {
|
||||
@@ -702,6 +805,12 @@ public class EntityListener implements Listener {
|
||||
|
||||
Player player = (Player) entity;
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* WORLD GUARD MAIN FLAG CHECK */
|
||||
if(WorldGuardUtils.isWorldGuardLoaded())
|
||||
{
|
||||
@@ -765,19 +874,14 @@ public class EntityListener implements Listener {
|
||||
event.setFoodLevel(UserManager.getPlayer(player).getHerbalismManager().farmersDiet(newFoodLevel));
|
||||
}
|
||||
return;
|
||||
case COD:
|
||||
case SALMON:
|
||||
case TROPICAL_FISH:
|
||||
case COOKED_COD:
|
||||
case COOKED_SALMON:
|
||||
|
||||
case COOKED_SALMON: /*
|
||||
* RESTORES 2 1/2 HUNGER - RESTORES 5 HUNGER @
|
||||
* 1000
|
||||
*/
|
||||
if (Permissions.isSubSkillEnabled(player, SubSkillType.FISHING_FISHERMANS_DIET)) {
|
||||
event.setFoodLevel(UserManager.getPlayer(player).getFishingManager().handleFishermanDiet(Fishing.fishermansDietRankLevel1, newFoodLevel));
|
||||
}
|
||||
return;
|
||||
|
||||
case SALMON: /* RESTORES 1 HUNGER - RESTORES 2 1/2 HUNGER @ 1000 */
|
||||
if (Permissions.isSubSkillEnabled(player, SubSkillType.FISHING_FISHERMANS_DIET)) {
|
||||
event.setFoodLevel(UserManager.getPlayer(player).getFishingManager().handleFishermanDiet(Fishing.fishermansDietRankLevel2, newFoodLevel));
|
||||
event.setFoodLevel(UserManager.getPlayer(player).getFishingManager().handleFishermanDiet(newFoodLevel));
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -818,6 +922,13 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
|
||||
entity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).getTamingManager().awardTamingXP(entity);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,12 @@ public class InventoryListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer((Player) player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!furnaceBlock.hasMetadata(mcMMO.furnaceMetadataKey) && furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey).size() == 0)
|
||||
furnaceBlock.setMetadata(mcMMO.furnaceMetadataKey, UserManager.getPlayer((Player) player).getPlayerMetadata());
|
||||
}
|
||||
@@ -109,6 +115,12 @@ public class InventoryListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.setBurnTime(UserManager.getPlayer(player).getSmeltingManager().fuelEfficiency(event.getBurnTime()));
|
||||
}
|
||||
|
||||
@@ -138,6 +150,12 @@ public class InventoryListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.setResult(UserManager.getPlayer(player).getSmeltingManager().smeltProcessing(smelting, event.getResult()));
|
||||
}
|
||||
|
||||
@@ -166,6 +184,12 @@ public class InventoryListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int exp = UserManager.getPlayer(player).getSmeltingManager().vanillaXPBoost(event.getExpToDrop());
|
||||
event.setExpToDrop(exp);
|
||||
}
|
||||
@@ -188,6 +212,12 @@ public class InventoryListener implements Listener {
|
||||
if (furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey).size() > 0)
|
||||
furnaceBlock.removeMetadata(mcMMO.furnaceMetadataKey, mcMMO.p);
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
furnaceBlock.setMetadata(mcMMO.furnaceMetadataKey, UserManager.getPlayer(player).getPlayerMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,11 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.minecart.PoweredMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
@@ -78,6 +80,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).actualizeTeleportATS();
|
||||
}
|
||||
|
||||
@@ -183,6 +191,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
mcMMOPlayer.checkGodMode();
|
||||
@@ -248,6 +262,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager();
|
||||
|
||||
switch (event.getState()) {
|
||||
@@ -319,10 +339,37 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager();
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entity caught = event.getCaught();
|
||||
//event.setExpToDrop(event.getExpToDrop()); //Redundant?
|
||||
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager();
|
||||
|
||||
//Track the hook
|
||||
if(ExperienceConfig.getInstance().isFishingExploitingPrevented())
|
||||
{
|
||||
if(event.getHook().getMetadata(mcMMO.FISH_HOOK_REF_METAKEY).size() == 0)
|
||||
{
|
||||
fishingManager.setFishHookReference(event.getHook());
|
||||
}
|
||||
|
||||
//Spam Fishing
|
||||
if(event.getState() == PlayerFishEvent.State.CAUGHT_FISH && fishingManager.isFishingTooOften())
|
||||
{
|
||||
event.setExpToDrop(0);
|
||||
|
||||
if(caught instanceof Item)
|
||||
{
|
||||
Item caughtItem = (Item) caught;
|
||||
caughtItem.remove();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.getState()) {
|
||||
case FISHING:
|
||||
@@ -331,21 +378,29 @@ public class PlayerListener implements Listener {
|
||||
fishingManager.setFishingTarget();
|
||||
}
|
||||
return;
|
||||
|
||||
case CAUGHT_FISH:
|
||||
if(fishingManager.exploitPrevention(event.getHook().getBoundingBox()))
|
||||
return;
|
||||
if(ExperienceConfig.getInstance().isFishingExploitingPrevented())
|
||||
{
|
||||
if(fishingManager.isExploitingFishing(event.getHook().getLocation().toVector()))
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Fishing.Scarcity"));
|
||||
event.setExpToDrop(0);
|
||||
Item caughtItem = (Item) caught;
|
||||
caughtItem.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fishingManager.handleFishing((Item) caught);
|
||||
fishingManager.setFishingTarget();
|
||||
//fishingManager.setFishHookReference(null);
|
||||
return;
|
||||
|
||||
case CAUGHT_ENTITY:
|
||||
if (fishingManager.canShake(caught)) {
|
||||
fishingManager.shakeCheck((LivingEntity) caught);
|
||||
fishingManager.setFishingTarget();
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -380,6 +435,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
Item drop = event.getItem();
|
||||
@@ -432,6 +493,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
mcMMOPlayer.logout(false);
|
||||
}
|
||||
@@ -453,7 +520,8 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||
//Delay loading for 3 seconds in case the player has a save task running, its hacky but it should do the trick
|
||||
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 60);
|
||||
|
||||
if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
|
||||
Motd.displayAll(player);
|
||||
@@ -481,6 +549,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).actualizeRespawnATS();
|
||||
}
|
||||
|
||||
@@ -508,6 +582,12 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
MiningManager miningManager = mcMMOPlayer.getMiningManager();
|
||||
Block block = event.getClickedBlock();
|
||||
@@ -611,9 +691,30 @@ public class PlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
|
||||
//Spam Fishing Detection
|
||||
if(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR)
|
||||
{
|
||||
if(heldItem.getType() == Material.FISHING_ROD || player.getInventory().getItemInOffHand().getType() == Material.FISHING_ROD)
|
||||
{
|
||||
if(player.isInsideVehicle() && (player.getVehicle() instanceof Minecart || player.getVehicle() instanceof PoweredMinecart))
|
||||
{
|
||||
player.getVehicle().eject();
|
||||
player.setVelocity(player.getEyeLocation().getDirection().multiply(10));
|
||||
}
|
||||
|
||||
mcMMOPlayer.getFishingManager().setFishingRodCastTimestamp();
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
if(player.getInventory().getItemInOffHand().getType() != Material.AIR && !player.isInsideVehicle() && !player.isSneaking()) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.gmail.nossr50.events.skills.abilities.McMMOPlayerAbilityActivateEvent
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.worldguard.WorldGuardManager;
|
||||
import com.gmail.nossr50.worldguard.WorldGuardUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -40,6 +41,9 @@ public class SelfListener implements Listener {
|
||||
UserManager.getPlayer(player).processUnlockNotifications(plugin, event.getSkill(), previousLevelGained);
|
||||
}
|
||||
|
||||
//Reset the delay timer
|
||||
RankUtils.resetUnlockDelayTimer();
|
||||
|
||||
if(Config.getInstance().getScoreboardsEnabled())
|
||||
ScoreboardManager.handleLevelUp(player, skill);
|
||||
|
||||
@@ -47,9 +51,9 @@ public class SelfListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((event.getSkillLevel() % Config.getInstance().getLevelUpEffectsTier()) == 0) {
|
||||
/*if ((event.getSkillLevel() % Config.getInstance().getLevelUpEffectsTier()) == 0) {
|
||||
skill.celebrateLevelUp(player);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.gmail.nossr50.listeners;
|
||||
|
||||
import com.gmail.nossr50.config.WorldBlacklist;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.blockmeta.conversion.BlockStoreConversionMain;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockState;
|
||||
@@ -62,7 +61,7 @@ public class WorldListener implements Listener {
|
||||
|
||||
plugin.getLogger().info("Converting block storage for " + world.getName() + " to a new format.");
|
||||
|
||||
new BlockStoreConversionMain(world).run();
|
||||
//new BlockStoreConversionMain(world).run();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.runnables.CheckDateTask;
|
||||
import com.gmail.nossr50.runnables.SaveTimerTask;
|
||||
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
|
||||
import com.gmail.nossr50.runnables.commands.NotifySquelchReminderTask;
|
||||
import com.gmail.nossr50.runnables.database.UserPurgeTask;
|
||||
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
|
||||
import com.gmail.nossr50.runnables.player.ClearRegisteredXPGainTask;
|
||||
@@ -46,6 +47,7 @@ import com.gmail.nossr50.worldguard.WorldGuardManager;
|
||||
import com.google.common.base.Charsets;
|
||||
import net.shatteredlands.shatt.backup.ZipLibrary;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
@@ -56,6 +58,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -87,6 +90,9 @@ public class mcMMO extends JavaPlugin {
|
||||
/* Plugin Checks */
|
||||
private static boolean healthBarPluginEnabled;
|
||||
|
||||
// API checks
|
||||
private static boolean serverAPIOutdated = false;
|
||||
|
||||
// Config Validation Check
|
||||
public boolean noErrorsInConfigFiles = true;
|
||||
|
||||
@@ -96,6 +102,8 @@ public class mcMMO extends JavaPlugin {
|
||||
private static boolean isRetroModeEnabled;
|
||||
|
||||
/* Metadata Values */
|
||||
public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
|
||||
public static final String CUSTOM_DAMAGE_METAKEY = "mcMMO: Custom Damage";
|
||||
public final static String entityMetadataKey = "mcMMO: Spawned Entity";
|
||||
public final static String blockMetadataKey = "mcMMO: Piston Tracking";
|
||||
public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace";
|
||||
@@ -108,6 +116,8 @@ public class mcMMO extends JavaPlugin {
|
||||
public final static String infiniteArrowKey = "mcMMO: Infinite Arrow";
|
||||
public final static String bowForceKey = "mcMMO: Bow Force";
|
||||
public final static String arrowDistanceKey = "mcMMO: Arrow Distance";
|
||||
public final static String doubleDrops = "mcMMO: Double Drops";
|
||||
public final static String tripleDrops = "mcMMO: Triple Drops";
|
||||
//public final static String customDamageKey = "mcMMO: Custom Damage";
|
||||
public final static String disarmedItemKey = "mcMMO: Disarmed Item";
|
||||
public final static String playerDataKey = "mcMMO: Player Data";
|
||||
@@ -160,35 +170,54 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
databaseManager = DatabaseManagerFactory.getDatabaseManager();
|
||||
|
||||
registerEvents();
|
||||
registerCoreSkills();
|
||||
registerCustomRecipes();
|
||||
//Check for the newer API and tell them what to do if its missing
|
||||
checkForOutdatedAPI();
|
||||
|
||||
PartyManager.loadParties();
|
||||
if(serverAPIOutdated)
|
||||
{
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.scheduleSyncRepeatingTask(this,
|
||||
() -> getLogger().severe("You are running an outdated version of "+getServerSoftware()+", mcMMO will not work unless you update to a newer version!"),
|
||||
20, 20*60*30);
|
||||
|
||||
formulaManager = new FormulaManager();
|
||||
holidayManager = new HolidayManager();
|
||||
if(getServerSoftware() == ServerSoftwareType.CRAFTBUKKIT)
|
||||
{
|
||||
Bukkit.getScheduler()
|
||||
.scheduleSyncRepeatingTask(this,
|
||||
() -> getLogger().severe("We have detected you are using incompatible server software, our best guess is that you are using CraftBukkit. mcMMO requires Spigot or Paper, if you are not using CraftBukkit, you will still need to update your custom server software before mcMMO will work."),
|
||||
20, 20*60*30);
|
||||
}
|
||||
} else {
|
||||
registerEvents();
|
||||
registerCoreSkills();
|
||||
registerCustomRecipes();
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||
PartyManager.loadParties();
|
||||
|
||||
formulaManager = new FormulaManager();
|
||||
holidayManager = new HolidayManager();
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||
}
|
||||
|
||||
debug("Version " + getDescription().getVersion() + " is enabled!");
|
||||
|
||||
scheduleTasks();
|
||||
CommandRegistrationManager.registerCommands();
|
||||
|
||||
placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
|
||||
|
||||
if (Config.getInstance().getPTPCommandWorldPermissions()) {
|
||||
Permissions.generateWorldTeleportPermissions();
|
||||
}
|
||||
|
||||
//Populate Ranked Skill Maps (DO THIS LAST)
|
||||
RankUtils.populateRanks();
|
||||
}
|
||||
|
||||
debug("Version " + getDescription().getVersion() + " is enabled!");
|
||||
|
||||
scheduleTasks();
|
||||
CommandRegistrationManager.registerCommands();
|
||||
|
||||
placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
|
||||
|
||||
if (Config.getInstance().getPTPCommandWorldPermissions()) {
|
||||
Permissions.generateWorldTeleportPermissions();
|
||||
}
|
||||
|
||||
//Populate Ranked Skill Maps (DO THIS LAST)
|
||||
RankUtils.populateRanks();
|
||||
|
||||
//If anonymous statistics are enabled then use them
|
||||
|
||||
Metrics metrics;
|
||||
|
||||
if(Config.getInstance().getIsMetricsEnabled()) {
|
||||
@@ -218,6 +247,47 @@ public class mcMMO extends JavaPlugin {
|
||||
worldBlacklist = new WorldBlacklist(this);
|
||||
}
|
||||
|
||||
private void checkForOutdatedAPI() {
|
||||
try {
|
||||
Class<?> checkForClass = Class.forName("org.bukkit.event.block.BlockDropItemEvent");
|
||||
Method newerAPIMethod = checkForClass.getMethod("getItems");
|
||||
Class<?> checkForClassBaseComponent = Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
serverAPIOutdated = true;
|
||||
String software = getServerSoftwareStr();
|
||||
getLogger().severe("You are running an older version of " + software + " that is not compatible with mcMMO, update your server software!");
|
||||
}
|
||||
}
|
||||
|
||||
private enum ServerSoftwareType {
|
||||
PAPER,
|
||||
SPIGOT,
|
||||
CRAFTBUKKIT
|
||||
}
|
||||
|
||||
private ServerSoftwareType getServerSoftware()
|
||||
{
|
||||
if(Bukkit.getVersion().toLowerCase().contains("paper"))
|
||||
return ServerSoftwareType.PAPER;
|
||||
else if(Bukkit.getVersion().toLowerCase().contains("spigot"))
|
||||
return ServerSoftwareType.SPIGOT;
|
||||
else
|
||||
return ServerSoftwareType.CRAFTBUKKIT;
|
||||
}
|
||||
|
||||
private String getServerSoftwareStr()
|
||||
{
|
||||
switch(getServerSoftware())
|
||||
{
|
||||
case PAPER:
|
||||
return "Paper";
|
||||
case SPIGOT:
|
||||
return "Spigot";
|
||||
default:
|
||||
return "CraftBukkit";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad()
|
||||
{
|
||||
@@ -535,6 +605,11 @@ public class mcMMO extends JavaPlugin {
|
||||
if (ExperienceConfig.getInstance().getDiminishedReturnsEnabled()) {
|
||||
new ClearRegisteredXPGainTask().runTaskTimer(this, 60, 60);
|
||||
}
|
||||
|
||||
if(AdvancedConfig.getInstance().allowPlayerTips())
|
||||
{
|
||||
new NotifySquelchReminderTask().runTaskTimer(this, 60, ((20 * 60) * 60));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModConfigs() {
|
||||
|
||||
@@ -98,6 +98,18 @@ public final class PartyManager {
|
||||
* @return true if they are in the same party, false otherwise
|
||||
*/
|
||||
public static boolean inSameParty(Player firstPlayer, Player secondPlayer) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(firstPlayer) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(secondPlayer) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Party firstParty = UserManager.getPlayer(firstPlayer).getParty();
|
||||
Party secondParty = UserManager.getPlayer(secondPlayer).getParty();
|
||||
|
||||
@@ -109,6 +121,18 @@ public final class PartyManager {
|
||||
}
|
||||
|
||||
public static boolean areAllies(Player firstPlayer, Player secondPlayer) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(firstPlayer) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(secondPlayer) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Party firstParty = UserManager.getPlayer(firstPlayer).getParty();
|
||||
Party secondParty = UserManager.getPlayer(secondPlayer).getParty();
|
||||
|
||||
@@ -263,6 +287,12 @@ public final class PartyManager {
|
||||
* @return the existing party, null otherwise
|
||||
*/
|
||||
public static Party getParty(Player player) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
return mcMMOPlayer.getParty();
|
||||
@@ -322,7 +352,14 @@ public final class PartyManager {
|
||||
* @param party The party to remove
|
||||
*/
|
||||
public static void disbandParty(Party party) {
|
||||
//TODO: Potential issues with unloaded profile?
|
||||
for (Player member : party.getOnlineMembers()) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(member) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
processPartyLeaving(UserManager.getPlayer(member));
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,12 @@ public final class ShareHandler {
|
||||
float splitXp = (float) (xp / partySize * shareBonus);
|
||||
|
||||
for (Player member : nearMembers) {
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(member) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UserManager.getPlayer(member).beginUnsharedXpGain(primarySkillType, splitXp, xpGainReason, XPGainSource.PARTY_MEMBERS);
|
||||
}
|
||||
|
||||
@@ -105,6 +111,13 @@ public final class ShareHandler {
|
||||
|
||||
for (Player member : nearMembers) {
|
||||
McMMOPlayer mcMMOMember = UserManager.getPlayer(member);
|
||||
|
||||
//Profile not loaded
|
||||
if(UserManager.getPlayer(member) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int itemShareModifier = mcMMOMember.getItemShareModifier();
|
||||
int diceRoll = Misc.getRandom().nextInt(itemShareModifier);
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.gmail.nossr50.runnables.commands;
|
||||
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class NotifySquelchReminderTask extends BukkitRunnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if(UserManager.getPlayer(player) != null)
|
||||
{
|
||||
if(!UserManager.getPlayer(player).useChatNotifications())
|
||||
{
|
||||
player.sendMessage(LocaleLoader.getString("Reminder.Squelched"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||
private static final int MAX_TRIES = 5;
|
||||
private final Player player;
|
||||
private int attempt = 0;
|
||||
|
||||
@@ -37,9 +36,6 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment attempt counter and try
|
||||
attempt++;
|
||||
|
||||
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getName(), player.getUniqueId(), true);
|
||||
// If successful, schedule the apply
|
||||
if (profile.isLoaded()) {
|
||||
@@ -47,14 +43,24 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we've failed five times, give up
|
||||
if (attempt >= MAX_TRIES) {
|
||||
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + player.getName());
|
||||
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.AdminFailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||
player.sendMessage(LocaleLoader.getString("Profile.Loading.Failure").split("\n"));
|
||||
return;
|
||||
// Print errors to console/logs if we're failing at least 2 times in a row to load the profile
|
||||
if (attempt >= 3)
|
||||
{
|
||||
//Log the error
|
||||
mcMMO.p.getLogger().severe(LocaleLoader.getString("Profile.Loading.FailureNotice",
|
||||
player.getName(), String.valueOf(attempt)));
|
||||
|
||||
//Notify the admins
|
||||
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.FailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||
|
||||
//Notify the player
|
||||
player.sendMessage(LocaleLoader.getString("Profile.Loading.FailurePlayer", String.valueOf(attempt)).split("\n"));
|
||||
}
|
||||
new PlayerProfileLoadingTask(player, attempt).runTaskLaterAsynchronously(mcMMO.p, 100 * attempt);
|
||||
|
||||
// Increment attempt counter and try
|
||||
attempt++;
|
||||
|
||||
new PlayerProfileLoadingTask(player, attempt).runTaskLaterAsynchronously(mcMMO.p, 100);
|
||||
}
|
||||
|
||||
private class ApplySuccessfulProfile extends BukkitRunnable {
|
||||
@@ -90,7 +96,6 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class AbilityCooldownTask extends BukkitRunnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mcMMOPlayer.getAbilityInformed(ability)) {
|
||||
if (!mcMMOPlayer.getPlayer().isOnline() || mcMMOPlayer.getAbilityInformed(ability)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,11 @@ public class AlchemyBrewTask extends BukkitRunnable {
|
||||
brewSpeed = DEFAULT_BREW_SPEED;
|
||||
brewTimer = DEFAULT_BREW_TICKS;
|
||||
|
||||
if (player != null && !Misc.isNPCEntity(player) && Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS)) {
|
||||
if (player != null
|
||||
&& !Misc.isNPCEntity(player)
|
||||
&& Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS)
|
||||
&& UserManager.getPlayer(player) != null) {
|
||||
|
||||
double catalysis = UserManager.getPlayer(player).getAlchemyManager().calculateBrewSpeed(Permissions.lucky(player, PrimarySkillType.ALCHEMY));
|
||||
|
||||
McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(player, catalysis);
|
||||
|
||||
@@ -25,7 +25,7 @@ public class AprilTask extends BukkitRunnable {
|
||||
if (betterRandom == 0) {
|
||||
SoundManager.sendSound(player, player.getLocation(), SoundType.LEVEL_UP);
|
||||
player.sendMessage(unknown("superskill") + " skill increased by 1. Total (" + unknown("12") + ")");
|
||||
fireworksShow(player);
|
||||
// fireworksShow(player);
|
||||
}
|
||||
|
||||
for (Statistic statistic : mcMMO.getHolidayManager().movementStatistics) {
|
||||
@@ -37,7 +37,7 @@ public class AprilTask extends BukkitRunnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void fireworksShow(final Player player) {
|
||||
/*private void fireworksShow(final Player player) {
|
||||
final int firework_amount = 10;
|
||||
for (int i = 0; i < firework_amount; i++) {
|
||||
int delay = (int) (Misc.getRandom().nextDouble() * 3 * Misc.TICK_CONVERSION_FACTOR) + 4;
|
||||
@@ -48,7 +48,7 @@ public class AprilTask extends BukkitRunnable {
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
private String unknown(String string) {
|
||||
return ChatColor.MAGIC + string + ChatColor.RESET + ChatColor.YELLOW;
|
||||
|
||||
@@ -5,14 +5,16 @@ import org.bukkit.entity.LivingEntity;
|
||||
public class BleedContainer {
|
||||
public int bleedTicks;
|
||||
public int bleedRank;
|
||||
public int toolTier;
|
||||
public LivingEntity target;
|
||||
public LivingEntity damageSource;
|
||||
|
||||
public BleedContainer(LivingEntity target, int bleedTicks, int bleedRank, LivingEntity damageSource)
|
||||
public BleedContainer(LivingEntity target, int bleedTicks, int bleedRank, int toolTier, LivingEntity damageSource)
|
||||
{
|
||||
this.target = target;
|
||||
this.bleedTicks = bleedTicks;
|
||||
this.bleedRank = bleedRank;
|
||||
this.toolTier = toolTier;
|
||||
this.damageSource = damageSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -28,21 +29,32 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
while (bleedIterator.hasNext()) {
|
||||
Entry<LivingEntity, BleedContainer> containerEntry = bleedIterator.next();
|
||||
LivingEntity target = containerEntry.getKey();
|
||||
int toolTier = containerEntry.getValue().toolTier;
|
||||
|
||||
int bleedTicks = containerEntry.getValue().bleedTicks;
|
||||
// String debugMessage = "";
|
||||
// debugMessage += ChatColor.GOLD + "Target ["+target.getName()+"]: " + ChatColor.RESET;
|
||||
|
||||
// debugMessage+="RemainingTicks=["+containerEntry.getValue().bleedTicks+"], ";
|
||||
|
||||
if (containerEntry.getValue().bleedTicks <= 0 || !target.isValid()) {
|
||||
if(target instanceof Player)
|
||||
{
|
||||
NotificationManager.sendPlayerInformation((Player) target, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Stopped");
|
||||
}
|
||||
|
||||
bleedIterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
int armorCount = 0;
|
||||
|
||||
double damage;
|
||||
|
||||
if (target instanceof Player) {
|
||||
damage = AdvancedConfig.getInstance().getRuptureDamagePlayer();
|
||||
|
||||
//Above Bleed Rank 3 deals 50% more damage
|
||||
if (containerEntry.getValue().bleedRank >= 3)
|
||||
if (containerEntry.getValue().toolTier >= 4 && containerEntry.getValue().bleedRank >= 3)
|
||||
damage = damage * 1.5;
|
||||
|
||||
Player player = (Player) target;
|
||||
@@ -51,28 +63,77 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
continue;
|
||||
}
|
||||
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Stopped");
|
||||
//Count Armor
|
||||
for(ItemStack armorPiece : ((Player) target).getInventory().getArmorContents())
|
||||
{
|
||||
if(armorPiece != null)
|
||||
armorCount++;
|
||||
}
|
||||
|
||||
} else {
|
||||
damage = AdvancedConfig.getInstance().getRuptureDamageMobs();
|
||||
|
||||
// debugMessage+="BaseDMG=["+damage+"], ";
|
||||
|
||||
//Above Bleed Rank 3 deals 50% more damage
|
||||
if (containerEntry.getValue().bleedRank >= 3)
|
||||
{
|
||||
damage = damage * 1.5;
|
||||
}
|
||||
|
||||
// debugMessage+="Rank4Bonus=["+String.valueOf(containerEntry.getValue().bleedRank >= 3)+"], ";
|
||||
|
||||
|
||||
MobHealthbarUtils.handleMobHealthbars(target, damage, mcMMO.p); //Update health bars
|
||||
}
|
||||
|
||||
CombatUtils.dealNoInvulnerabilityTickDamage(target, damage, containerEntry.getValue().damageSource);
|
||||
//Play Bleed Sound
|
||||
SoundManager.worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED);
|
||||
// debugMessage+="FullArmor=["+String.valueOf(armorCount > 3)+"], ";
|
||||
|
||||
ParticleEffectUtils.playBleedEffect(target);
|
||||
if(armorCount > 3)
|
||||
{
|
||||
damage = damage * .75;
|
||||
}
|
||||
|
||||
// debugMessage+="AfterRankAndArmorChecks["+damage+"], ";
|
||||
|
||||
//Weapons below Diamond get damage cut in half
|
||||
if(toolTier < 4)
|
||||
damage = damage / 2;
|
||||
|
||||
// debugMessage+="AfterDiamondCheck=["+String.valueOf(damage)+"], ";
|
||||
|
||||
//Wood weapons get damage cut in half again
|
||||
if(toolTier < 2)
|
||||
damage = damage / 2;
|
||||
|
||||
// debugMessage+="AfterWoodenCheck=["+String.valueOf(damage)+"], ";
|
||||
|
||||
double victimHealth = target.getHealth();
|
||||
|
||||
// debugMessage+="TargetHealthBeforeDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
|
||||
CombatUtils.dealNoInvulnerabilityTickDamageRupture(target, damage, containerEntry.getValue().damageSource, toolTier);
|
||||
|
||||
double victimHealthAftermath = target.getHealth();
|
||||
|
||||
// debugMessage+="TargetHealthAfterDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
|
||||
if(victimHealthAftermath <= 0 || victimHealth != victimHealthAftermath)
|
||||
{
|
||||
//Play Bleed Sound
|
||||
SoundManager.worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED);
|
||||
|
||||
ParticleEffectUtils.playBleedEffect(target);
|
||||
}
|
||||
|
||||
//Lower Bleed Ticks
|
||||
BleedContainer loweredBleedContainer = copyContainer(containerEntry.getValue());
|
||||
loweredBleedContainer.bleedTicks -= 1;
|
||||
|
||||
// debugMessage+="RemainingTicks=["+loweredBleedContainer.bleedTicks+"]";
|
||||
containerEntry.setValue(loweredBleedContainer);
|
||||
|
||||
// Bukkit.broadcastMessage(debugMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +143,9 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
LivingEntity source = container.damageSource;
|
||||
int bleedTicks = container.bleedTicks;
|
||||
int bleedRank = container.bleedRank;
|
||||
int toolTier = container.toolTier;
|
||||
|
||||
BleedContainer newContainer = new BleedContainer(target, bleedTicks, bleedRank, source);
|
||||
BleedContainer newContainer = new BleedContainer(target, bleedTicks, bleedRank, toolTier, source);
|
||||
return newContainer;
|
||||
}
|
||||
|
||||
@@ -108,8 +170,11 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
* @param entity LivingEntity to add
|
||||
* @param ticks Number of bleeding ticks
|
||||
*/
|
||||
public static void add(LivingEntity entity, LivingEntity attacker, int ticks, int bleedRank) {
|
||||
BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, attacker);
|
||||
public static void add(LivingEntity entity, LivingEntity attacker, int ticks, int bleedRank, int toolTier) {
|
||||
if(toolTier < 4)
|
||||
ticks = Math.max(1, (ticks / 3));
|
||||
|
||||
BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, toolTier, attacker);
|
||||
bleedList.put(entity, newBleedContainer);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.gmail.nossr50.skills.acrobatics;
|
||||
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.LimitedSizeList;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
@@ -14,6 +16,7 @@ import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -22,6 +25,39 @@ public class AcrobaticsManager extends SkillManager {
|
||||
|
||||
public AcrobaticsManager(McMMOPlayer mcMMOPlayer) {
|
||||
super(mcMMOPlayer, PrimarySkillType.ACROBATICS);
|
||||
fallLocationMap = new LimitedSizeList(50);
|
||||
}
|
||||
|
||||
private long rollXPCooldown = 0;
|
||||
private long rollXPInterval = (1000 * 10); //1 Minute
|
||||
private long rollXPIntervalLengthen = (1000 * 10); //10 Seconds
|
||||
private LimitedSizeList fallLocationMap;
|
||||
|
||||
public boolean hasFallenInLocationBefore(Location location)
|
||||
{
|
||||
return fallLocationMap.contains(location);
|
||||
}
|
||||
|
||||
public void addLocationToFallMap(Location location)
|
||||
{
|
||||
fallLocationMap.add(location);
|
||||
}
|
||||
|
||||
public boolean canGainRollXP()
|
||||
{
|
||||
if(!ExperienceConfig.getInstance().isAcrobaticsExploitingPrevented())
|
||||
return true;
|
||||
|
||||
if(System.currentTimeMillis() >= rollXPCooldown)
|
||||
{
|
||||
rollXPCooldown = System.currentTimeMillis() + rollXPInterval;
|
||||
rollXPIntervalLengthen = (1000 * 10); //5 Seconds
|
||||
return true;
|
||||
} else {
|
||||
rollXPCooldown += rollXPIntervalLengthen;
|
||||
rollXPIntervalLengthen += 1000; //Add another second to the next penalty
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canDodge(Entity damager) {
|
||||
|
||||
@@ -93,7 +93,12 @@ public final class AlchemyPotionBrewer {
|
||||
}
|
||||
|
||||
private static List<ItemStack> getValidIngredients(Player player) {
|
||||
return PotionConfig.getInstance().getIngredients((player == null || !Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS)) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
if(player == null || UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return PotionConfig.getInstance().getIngredients(1);
|
||||
}
|
||||
|
||||
return PotionConfig.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
}
|
||||
|
||||
public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
|
||||
@@ -142,6 +147,7 @@ public final class AlchemyPotionBrewer {
|
||||
if (output != null && player != null) {
|
||||
PotionStage potionStage = PotionStage.getPotionStage(input, output);
|
||||
|
||||
//TODO: hmm
|
||||
if (UserManager.hasPlayerDataKey(player)) {
|
||||
UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(potionStage, 1);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
@@ -90,7 +89,8 @@ public class ArcheryManager extends SkillManager {
|
||||
defender.teleport(dazedLocation);
|
||||
defender.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20 * 10, 10));
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Combat.TouchedFuzzy");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.ItemUtils;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.*;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
@@ -95,7 +94,7 @@ public class AxesManager extends SkillManager {
|
||||
if (target instanceof Player) {
|
||||
Player defender = (Player) target;
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Axes.Combat.CritStruck");
|
||||
}
|
||||
|
||||
@@ -152,7 +151,7 @@ public class AxesManager extends SkillManager {
|
||||
if (target instanceof Player) {
|
||||
Player defender = (Player) target;
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Axes.Combat.GI.Struck");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.gmail.nossr50.skills.fishing;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.treasure.TreasureConfig;
|
||||
import com.gmail.nossr50.datatypes.treasure.ShakeTreasure;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
@@ -19,10 +18,6 @@ public final class Fishing {
|
||||
|
||||
protected static final HashMap<Material, List<Enchantment>> ENCHANTABLE_CACHE = new HashMap<Material, List<Enchantment>>();
|
||||
|
||||
public static int fishermansDietRankLevel1 = AdvancedConfig.getInstance().getFishermanDietRankChange();
|
||||
public static int fishermansDietRankLevel2 = fishermansDietRankLevel1 * 2;
|
||||
public static int fishermansDietMaxLevel = fishermansDietRankLevel1 * 5;
|
||||
|
||||
public static Set<Biome> masterAnglerBiomes = BiomeAdapter.WATER_BIOMES;
|
||||
public static Set<Biome> iceFishingBiomes = BiomeAdapter.ICE_BIOMES;
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ import com.gmail.nossr50.datatypes.treasure.Rarity;
|
||||
import com.gmail.nossr50.datatypes.treasure.ShakeTreasure;
|
||||
import com.gmail.nossr50.events.skills.fishing.McMMOPlayerFishingTreasureEvent;
|
||||
import com.gmail.nossr50.events.skills.fishing.McMMOPlayerShakeEvent;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.*;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
@@ -23,6 +25,8 @@ import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -34,16 +38,24 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class FishingManager extends SkillManager {
|
||||
public static final int FISHING_ROD_CAST_CD_MILLISECONDS = 100;
|
||||
public static final int OVERFISH_LIMIT = 4;
|
||||
private final long FISHING_COOLDOWN_SECONDS = 1000L;
|
||||
|
||||
private long fishingTimestamp = 0L;
|
||||
private long fishingRodCastTimestamp = 0L;
|
||||
private long fishHookSpawnTimestamp = 0L;
|
||||
private long lastWarned = 0L;
|
||||
private long lastWarnedExhaust = 0L;
|
||||
private FishHook fishHookReference;
|
||||
private BoundingBox lastFishingBoundingBox;
|
||||
private Item fishingCatch;
|
||||
private Location hookLocation;
|
||||
private int fishCaughtCounter = 1;
|
||||
|
||||
public FishingManager(McMMOPlayer mcMMOPlayer) {
|
||||
super(mcMMOPlayer, PrimarySkillType.FISHING);
|
||||
@@ -57,25 +69,88 @@ public class FishingManager extends SkillManager {
|
||||
return getSkillLevel() >= RankUtils.getUnlockLevel(SubSkillType.FISHING_MASTER_ANGLER) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_MASTER_ANGLER);
|
||||
}
|
||||
|
||||
public boolean exploitPrevention(BoundingBox boundingBox) {
|
||||
public void setFishingRodCastTimestamp()
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
//Only track spam casting if the fishing hook is fresh
|
||||
if(currentTime > fishHookSpawnTimestamp + 1000)
|
||||
return;
|
||||
|
||||
Block targetBlock = getPlayer().getTargetBlock(BlockUtils.getTransparentBlocks(), 100);
|
||||
if(currentTime < fishingRodCastTimestamp + FISHING_ROD_CAST_CD_MILLISECONDS)
|
||||
{
|
||||
getPlayer().setFoodLevel(Math.max(getPlayer().getFoodLevel() - 1, 0));
|
||||
getPlayer().getInventory().getItemInMainHand().setDurability((short) (getPlayer().getInventory().getItemInMainHand().getDurability() + 5));
|
||||
getPlayer().updateInventory();
|
||||
|
||||
if(lastWarnedExhaust + (1000 * 1) < currentTime)
|
||||
{
|
||||
getPlayer().sendMessage(LocaleLoader.getString("Fishing.Exhausting"));
|
||||
lastWarnedExhaust = currentTime;
|
||||
SoundManager.sendSound(getPlayer(), getPlayer().getLocation(), SoundType.TIRED);
|
||||
}
|
||||
}
|
||||
|
||||
fishingRodCastTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setFishHookReference(FishHook fishHook)
|
||||
{
|
||||
if(fishHook.getMetadata(mcMMO.FISH_HOOK_REF_METAKEY).size() > 0)
|
||||
return;
|
||||
|
||||
fishHook.setMetadata(mcMMO.FISH_HOOK_REF_METAKEY, mcMMO.metadataValue);
|
||||
this.fishHookReference = fishHook;
|
||||
fishHookSpawnTimestamp = System.currentTimeMillis();
|
||||
fishingRodCastTimestamp = System.currentTimeMillis();
|
||||
|
||||
}
|
||||
|
||||
public boolean isFishingTooOften()
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long fishHookSpawnCD = fishHookSpawnTimestamp + 1000;
|
||||
boolean hasFished = (currentTime < fishHookSpawnCD);
|
||||
|
||||
if(hasFished && (lastWarned + (1000 * 1) < currentTime))
|
||||
{
|
||||
getPlayer().sendMessage(LocaleLoader.getString("Fishing.Scared"));
|
||||
lastWarned = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
return hasFished;
|
||||
}
|
||||
|
||||
public boolean isExploitingFishing(Vector centerOfCastVector) {
|
||||
|
||||
/*Block targetBlock = getPlayer().getTargetBlock(BlockUtils.getTransparentBlocks(), 100);
|
||||
|
||||
if (!targetBlock.isLiquid()) {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
BoundingBox newCastBoundingBox = makeBoundingBox(centerOfCastVector);
|
||||
|
||||
boolean sameTarget = lastFishingBoundingBox != null && lastFishingBoundingBox.overlaps(newCastBoundingBox);
|
||||
|
||||
if(sameTarget)
|
||||
fishCaughtCounter++;
|
||||
else
|
||||
fishCaughtCounter = 1;
|
||||
|
||||
if(fishCaughtCounter + 1 == OVERFISH_LIMIT)
|
||||
{
|
||||
getPlayer().sendMessage(LocaleLoader.getString("Fishing.LowResources"));
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
boolean hasFished = (currentTime < fishingTimestamp + (FISHING_COOLDOWN_SECONDS * 10));
|
||||
//If the new bounding box does not intersect with the old one, then update our bounding box reference
|
||||
if(!sameTarget)
|
||||
lastFishingBoundingBox = newCastBoundingBox;
|
||||
|
||||
if(hasFished)
|
||||
fishingTimestamp = currentTime;
|
||||
return sameTarget && fishCaughtCounter >= OVERFISH_LIMIT;
|
||||
}
|
||||
|
||||
boolean sameTarget = (lastFishingBoundingBox != null && lastFishingBoundingBox.overlaps(boundingBox));
|
||||
|
||||
lastFishingBoundingBox = boundingBox;
|
||||
|
||||
return hasFished || sameTarget;
|
||||
public static BoundingBox makeBoundingBox(Vector centerOfCastVector) {
|
||||
return BoundingBox.of(centerOfCastVector, 1, 1, 1);
|
||||
}
|
||||
|
||||
public void setFishingTarget() {
|
||||
@@ -134,12 +209,11 @@ public class FishingManager extends SkillManager {
|
||||
/**
|
||||
* Handle the Fisherman's Diet ability
|
||||
*
|
||||
* @param rankChange The # of levels to change rank for the food
|
||||
* @param eventFoodLevel The initial change in hunger from the event
|
||||
*
|
||||
* @return the modified change in hunger for the event
|
||||
*/
|
||||
public int handleFishermanDiet(int rankChange, int eventFoodLevel) {
|
||||
public int handleFishermanDiet(int eventFoodLevel) {
|
||||
return SkillUtils.handleFoodSkills(getPlayer(), eventFoodLevel, SubSkillType.FISHING_FISHERMANS_DIET);
|
||||
}
|
||||
|
||||
@@ -346,7 +420,7 @@ public class FishingManager extends SkillManager {
|
||||
}
|
||||
|
||||
Misc.dropItem(target.getLocation(), drop);
|
||||
CombatUtils.dealDamage(target, Math.max(target.getMaxHealth() / 4, 1), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times.
|
||||
CombatUtils.dealDamage(target, Math.min(Math.max(target.getMaxHealth() / 4, 1), 10), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times.
|
||||
applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP(), XPGainReason.PVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gmail.nossr50.skills.herbalism;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -42,11 +43,11 @@ public class Herbalism {
|
||||
}
|
||||
}
|
||||
|
||||
private static int calculateChorusPlantDrops(Block target) {
|
||||
return calculateChorusPlantDropsRecursive(target, new HashSet<>());
|
||||
private static int calculateChorusPlantDrops(Block target, boolean triple, HerbalismManager herbalismManager) {
|
||||
return calculateChorusPlantDropsRecursive(target, new HashSet<>(), triple, herbalismManager);
|
||||
}
|
||||
|
||||
private static int calculateChorusPlantDropsRecursive(Block target, HashSet<Block> traversed) {
|
||||
private static int calculateChorusPlantDropsRecursive(Block target, HashSet<Block> traversed, boolean triple, HerbalismManager herbalismManager) {
|
||||
if (target.getType() != Material.CHORUS_PLANT)
|
||||
return 0;
|
||||
|
||||
@@ -62,10 +63,15 @@ public class Herbalism {
|
||||
if (mcMMO.getPlaceStore().isTrue(target))
|
||||
mcMMO.getPlaceStore().setFalse(target);
|
||||
else
|
||||
{
|
||||
dropAmount++;
|
||||
|
||||
if(herbalismManager.checkDoubleDrop(target.getState()))
|
||||
BlockUtils.markDropsAsBonus(target.getState(), triple);
|
||||
}
|
||||
|
||||
for (BlockFace blockFace : new BlockFace[] { BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST ,BlockFace.WEST})
|
||||
dropAmount += calculateChorusPlantDropsRecursive(target.getRelative(blockFace, 1), traversed);
|
||||
dropAmount += calculateChorusPlantDropsRecursive(target.getRelative(blockFace, 1), traversed, triple, herbalismManager);
|
||||
|
||||
return dropAmount;
|
||||
}
|
||||
@@ -78,7 +84,7 @@ public class Herbalism {
|
||||
* The {@link BlockState} of the bottom block of the plant
|
||||
* @return the number of bonus drops to award from the blocks in this plant
|
||||
*/
|
||||
protected static int calculateMultiBlockPlantDrops(BlockState blockState) {
|
||||
protected static int countAndMarkDoubleDropsMultiBlockPlant(BlockState blockState, boolean triple, HerbalismManager herbalismManager) {
|
||||
Block block = blockState.getBlock();
|
||||
Material blockType = blockState.getType();
|
||||
int dropAmount = mcMMO.getPlaceStore().isTrue(block) ? 0 : 1;
|
||||
@@ -87,11 +93,11 @@ public class Herbalism {
|
||||
dropAmount = 1;
|
||||
|
||||
if (block.getRelative(BlockFace.DOWN, 1).getType() == Material.END_STONE) {
|
||||
dropAmount = calculateChorusPlantDrops(block);
|
||||
dropAmount = calculateChorusPlantDrops(block, triple, herbalismManager);
|
||||
}
|
||||
} else {
|
||||
// Handle the two blocks above it - cacti & sugar cane can only grow 3 high naturally
|
||||
for (int y = 1; y < 3; y++) {
|
||||
for (int y = 1; y < 255; y++) {
|
||||
Block relativeBlock = block.getRelative(BlockFace.UP, y);
|
||||
|
||||
if (relativeBlock.getType() != blockType) {
|
||||
@@ -102,6 +108,9 @@ public class Herbalism {
|
||||
mcMMO.getPlaceStore().setFalse(relativeBlock);
|
||||
} else {
|
||||
dropAmount++;
|
||||
|
||||
if(herbalismManager.checkDoubleDrop(relativeBlock.getState()))
|
||||
BlockUtils.markDropsAsBonus(relativeBlock.getState(), triple);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,6 +118,54 @@ public class Herbalism {
|
||||
return dropAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the drop amounts for kelp plants based on the blocks
|
||||
* relative to them.
|
||||
*
|
||||
* @param blockState
|
||||
* The {@link BlockState} of the bottom block of the plant
|
||||
* @return the number of bonus drops to award from the blocks in this plant
|
||||
*/
|
||||
protected static int countAndMarkDoubleDropsKelp(BlockState blockState, boolean triple, HerbalismManager herbalismManager) {
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
int kelpMaxHeight = 255;
|
||||
int amount = 1;
|
||||
|
||||
// Handle the two blocks above it - cacti & sugar cane can only grow 3 high naturally
|
||||
for (int y = 1; y < kelpMaxHeight; y++) {
|
||||
Block relativeUpBlock = block.getRelative(BlockFace.UP, y);
|
||||
|
||||
if(!isKelp(relativeUpBlock))
|
||||
break;
|
||||
|
||||
amount += 1;
|
||||
|
||||
if(herbalismManager.checkDoubleDrop(relativeUpBlock.getState()))
|
||||
BlockUtils.markDropsAsBonus(relativeUpBlock.getState(), triple);
|
||||
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
private static int addKelpDrops(int dropAmount, Block relativeBlock) {
|
||||
if (isKelp(relativeBlock) && !mcMMO.getPlaceStore().isTrue(relativeBlock)) {
|
||||
dropAmount++;
|
||||
} else {
|
||||
mcMMO.getPlaceStore().setFalse(relativeBlock);
|
||||
}
|
||||
|
||||
return dropAmount;
|
||||
}
|
||||
|
||||
private static boolean isKelp(Block relativeBlock) {
|
||||
Material kelptype_1 = Material.KELP_PLANT;
|
||||
Material kelptype_2 = Material.KELP;
|
||||
|
||||
return relativeBlock.getType() == kelptype_1 || relativeBlock.getType() == kelptype_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert blocks affected by the Green Thumb & Green Terra abilities.
|
||||
*
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class HerbalismManager extends SkillManager {
|
||||
@@ -126,7 +125,7 @@ public class HerbalismManager extends SkillManager {
|
||||
public void herbalismBlockCheck(BlockState blockState) {
|
||||
Player player = getPlayer();
|
||||
Material material = blockState.getType();
|
||||
boolean oneBlockPlant = !(material == Material.CACTUS || material == Material.CHORUS_PLANT || material == Material.SUGAR_CANE);
|
||||
boolean oneBlockPlant = isOneBlockPlant(material);
|
||||
|
||||
// Prevents placing and immediately breaking blocks for exp
|
||||
if (oneBlockPlant && mcMMO.getPlaceStore().isTrue(blockState)) {
|
||||
@@ -137,8 +136,7 @@ public class HerbalismManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<ItemStack> drops = null;
|
||||
int amount = 1;
|
||||
int amount;
|
||||
int xp;
|
||||
boolean greenTerra = mcMMOPlayer.getAbilityMode(skill.getAbility());
|
||||
|
||||
@@ -147,39 +145,50 @@ public class HerbalismManager extends SkillManager {
|
||||
xp = customBlock.getXpGain();
|
||||
|
||||
if (Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && customBlock.isDoubleDropEnabled()) {
|
||||
drops = blockState.getBlock().getDrops();
|
||||
if(checkDoubleDrop(blockState))
|
||||
BlockUtils.markDropsAsBonus(blockState, greenTerra);
|
||||
}
|
||||
}
|
||||
else {
|
||||
xp = ExperienceConfig.getInstance().getXp(skill, blockState.getBlockData());
|
||||
|
||||
if (Config.getInstance().getDoubleDropsEnabled(skill, material) && Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_DOUBLE_DROPS)) {
|
||||
drops = blockState.getBlock().getDrops();
|
||||
if (!oneBlockPlant) {
|
||||
//Kelp is actually two blocks mixed together
|
||||
if(material == Material.KELP_PLANT || material == Material.KELP) {
|
||||
amount = Herbalism.countAndMarkDoubleDropsKelp(blockState, greenTerra,this);
|
||||
} else {
|
||||
amount = Herbalism.countAndMarkDoubleDropsMultiBlockPlant(blockState, greenTerra, this);
|
||||
}
|
||||
|
||||
xp *= amount;
|
||||
} else {
|
||||
/* MARK SINGLE BLOCK CROP FOR DOUBLE DROP */
|
||||
if(checkDoubleDrop(blockState))
|
||||
BlockUtils.markDropsAsBonus(blockState, greenTerra);
|
||||
}
|
||||
|
||||
if (!oneBlockPlant) {
|
||||
amount = Herbalism.calculateMultiBlockPlantDrops(blockState);
|
||||
xp *= amount;
|
||||
}
|
||||
|
||||
if (Permissions.greenThumbPlant(player, material)) {
|
||||
processGreenThumbPlants(blockState, greenTerra);
|
||||
}
|
||||
}
|
||||
|
||||
applyXpGain(xp, XPGainReason.PVE);
|
||||
}
|
||||
|
||||
if (drops == null) {
|
||||
return;
|
||||
}
|
||||
public boolean isOneBlockPlant(Material material) {
|
||||
return !(material == Material.CACTUS || material == Material.CHORUS_PLANT
|
||||
|| material == Material.SUGAR_CANE || material == Material.KELP_PLANT || material == Material.KELP
|
||||
|| material == Material.TALL_SEAGRASS || material == Material.TALL_GRASS);
|
||||
}
|
||||
|
||||
for (int i = greenTerra ? 2 : 1; i != 0; i--) {
|
||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.HERBALISM_DOUBLE_DROPS, player)) {
|
||||
for (ItemStack item : drops) {
|
||||
Misc.dropItems(Misc.getBlockCenter(blockState), item, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check for success on herbalism double drops
|
||||
* @param blockState target block state
|
||||
* @return true if double drop succeeds
|
||||
*/
|
||||
public boolean checkDoubleDrop(BlockState blockState)
|
||||
{
|
||||
return BlockUtils.checkDoubleDrops(getPlayer(), blockState, skill, SubSkillType.HERBALISM_DOUBLE_DROPS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,11 +322,7 @@ public class HerbalismManager extends SkillManager {
|
||||
|
||||
ItemStack seedStack = new ItemStack(seed);
|
||||
|
||||
if (!playerInventory.containsAtLeast(seedStack, 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!greenTerra && !RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.HERBALISM_GREEN_THUMB, player)) {
|
||||
if (!greenTerra && !RandomChanceUtil.checkRandomChanceExecutionSuccess(player, SubSkillType.HERBALISM_GREEN_THUMB, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -325,8 +330,16 @@ public class HerbalismManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
playerInventory.removeItem(seedStack);
|
||||
player.updateInventory(); // Needed until replacement available
|
||||
if(!ItemUtils.isHoe(getPlayer().getInventory().getItemInMainHand()))
|
||||
{
|
||||
if (!playerInventory.containsAtLeast(seedStack, 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
playerInventory.removeItem(seedStack);
|
||||
player.updateInventory(); // Needed until replacement available
|
||||
}
|
||||
|
||||
new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.gmail.nossr50.skills.mining;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
@@ -41,8 +39,6 @@ public class BlastMining {
|
||||
|
||||
}*/
|
||||
|
||||
public static Material detonator = Config.getInstance().getDetonatorItem();
|
||||
|
||||
public final static int MAXIMUM_REMOTE_DETONATION_DISTANCE = 100;
|
||||
|
||||
public static double getBlastRadiusModifier(int rank) {
|
||||
@@ -107,6 +103,11 @@ public class BlastMining {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer(defender) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MiningManager miningManager = UserManager.getPlayer(defender).getMiningManager();
|
||||
|
||||
if (!miningManager.canUseDemolitionsExpertise()) {
|
||||
|
||||
@@ -34,6 +34,9 @@ public class Mining {
|
||||
Material blockType = blockState.getType();
|
||||
|
||||
switch (blockType) {
|
||||
case ANDESITE:
|
||||
case DIORITE:
|
||||
case GRANITE:
|
||||
case END_STONE:
|
||||
case TERRACOTTA:
|
||||
case CLAY:
|
||||
|
||||
@@ -11,14 +11,10 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.EventUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.*;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -46,7 +42,9 @@ public class MiningManager extends SkillManager {
|
||||
public boolean canDetonate() {
|
||||
Player player = getPlayer();
|
||||
|
||||
return canUseBlastMining() && player.isSneaking() && player.getInventory().getItemInMainHand().getType() == BlastMining.detonator && Permissions.remoteDetonation(player);
|
||||
return canUseBlastMining() && player.isSneaking()
|
||||
&& (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == Config.getInstance().getDetonatorItem())
|
||||
&& Permissions.remoteDetonation(player);
|
||||
}
|
||||
|
||||
public boolean canUseBlastMining() {
|
||||
@@ -81,22 +79,18 @@ public class MiningManager extends SkillManager {
|
||||
SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), Config.getInstance().getAbilityToolDamage());
|
||||
}
|
||||
|
||||
if ((mcMMO.getModManager().isCustomMiningBlock(blockState) && !mcMMO.getModManager().getBlock(blockState).isDoubleDropEnabled()) || !Config.getInstance().getDoubleDropsEnabled(skill, material)) {
|
||||
if ((mcMMO.getModManager().isCustomMiningBlock(blockState) && !mcMMO.getModManager().getBlock(blockState).isDoubleDropEnabled())) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
|
||||
|
||||
if(silkTouch && !AdvancedConfig.getInstance().getDoubleDropSilkTouchEnabled())
|
||||
return;
|
||||
|
||||
//TODO: Make this readable
|
||||
for (int i = mcMMOPlayer.getAbilityMode(skill.getAbility()) ? 2 : 1; i != 0; i--) {
|
||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.MINING_DOUBLE_DROPS, player)) {
|
||||
if (silkTouch) {
|
||||
Mining.handleSilkTouchDrops(blockState);
|
||||
}
|
||||
else {
|
||||
Mining.handleMiningDrops(blockState);
|
||||
}
|
||||
}
|
||||
if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS, true)) {
|
||||
BlockUtils.markDropsAsBonus(blockState, mcMMOPlayer.getAbilityMode(skill.getAbility()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +118,7 @@ public class MiningManager extends SkillManager {
|
||||
|
||||
mcMMOPlayer.setAbilityDATS(SuperAbilityType.BLAST_MINING, System.currentTimeMillis());
|
||||
mcMMOPlayer.setAbilityInformed(SuperAbilityType.BLAST_MINING, false);
|
||||
new AbilityCooldownTask(mcMMOPlayer, SuperAbilityType.BLAST_MINING).runTaskLaterAsynchronously(mcMMO.p, SuperAbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
|
||||
new AbilityCooldownTask(mcMMOPlayer, SuperAbilityType.BLAST_MINING).runTaskLater(mcMMO.p, SuperAbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +261,7 @@ public class MiningManager extends SkillManager {
|
||||
|
||||
if (timeRemaining > 0) {
|
||||
//getPlayer().sendMessage(LocaleLoader.getString("Skills.TooTired", timeRemaining));
|
||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf("timeRemaining"));
|
||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.gmail.nossr50.skills.repair;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class Repair {
|
||||
public static int repairMasteryMaxBonusLevel = AdvancedConfig.getInstance().getRepairMasteryMaxLevel();
|
||||
public static int repairMasteryMaxBonusLevel = AdvancedConfig.getInstance().getMaxBonusLevel(SubSkillType.REPAIR_REPAIR_MASTERY);
|
||||
public static double repairMasteryMaxBonus = AdvancedConfig.getInstance().getRepairMasteryMaxBonus();
|
||||
|
||||
public static Material anvilMaterial = Config.getInstance().getRepairAnvilMaterial();
|
||||
|
||||
@@ -139,7 +139,7 @@ public class RepairManager extends SkillManager {
|
||||
}
|
||||
|
||||
// Handle the enchants
|
||||
if (ArcaneForging.arcaneForgingEnchantLoss) {
|
||||
if (ArcaneForging.arcaneForgingEnchantLoss && !Permissions.hasRepairEnchantBypassPerk(player)) {
|
||||
addEnchants(item);
|
||||
}
|
||||
|
||||
@@ -262,8 +262,14 @@ public class RepairManager extends SkillManager {
|
||||
private short repairCalculate(short durability, int repairAmount) {
|
||||
Player player = getPlayer();
|
||||
|
||||
if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_REPAIR_MASTERY) && RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_REPAIR_MASTERY)) {
|
||||
double bonus = repairAmount * Math.min((((Repair.repairMasteryMaxBonus / Repair.repairMasteryMaxBonusLevel) * getSkillLevel()) / 100.0D), Repair.repairMasteryMaxBonus / 100.0D);
|
||||
if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_REPAIR_MASTERY)
|
||||
&& RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_REPAIR_MASTERY)) {
|
||||
|
||||
double maxBonusCalc = Repair.repairMasteryMaxBonus / 100.0D;
|
||||
double skillLevelBonusCalc = (Repair.repairMasteryMaxBonus / Repair.repairMasteryMaxBonusLevel) * (getSkillLevel() / 100.0D);
|
||||
double bonus = repairAmount * Math.min(skillLevelBonusCalc, maxBonusCalc);
|
||||
|
||||
|
||||
repairAmount += bonus;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ public class SalvageManager extends SkillManager {
|
||||
|
||||
// BWONG BWONG BWONG - CLUNK!
|
||||
if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) {
|
||||
SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
|
||||
// SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
|
||||
SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
|
||||
|
||||
//player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0F, 1.0F);
|
||||
@@ -182,6 +182,9 @@ public class SalvageManager extends SkillManager {
|
||||
}*/
|
||||
|
||||
public double getExtractFullEnchantChance() {
|
||||
if(Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
|
||||
return 100.0D;
|
||||
|
||||
return AdvancedConfig.getInstance().getArcaneSalvageExtractFullEnchantsChance(getArcaneSalvageRank());
|
||||
}
|
||||
|
||||
@@ -201,10 +204,11 @@ public class SalvageManager extends SkillManager {
|
||||
EnchantmentStorageMeta enchantMeta = (EnchantmentStorageMeta) book.getItemMeta();
|
||||
|
||||
boolean downgraded = false;
|
||||
boolean arcaneFailure = false;
|
||||
int arcaneFailureCount = 0;
|
||||
|
||||
for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
|
||||
if (!Salvage.arcaneSalvageEnchantLoss
|
||||
|| Permissions.hasSalvageEnchantBypassPerk(player)
|
||||
|| RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
|
||||
enchantMeta.addStoredEnchant(enchant.getKey(), enchant.getValue(), true);
|
||||
}
|
||||
@@ -213,36 +217,28 @@ public class SalvageManager extends SkillManager {
|
||||
&& RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
|
||||
enchantMeta.addStoredEnchant(enchant.getKey(), enchant.getValue() - 1, true);
|
||||
downgraded = true;
|
||||
}
|
||||
else {
|
||||
arcaneFailure = true;
|
||||
downgraded = true;
|
||||
} else {
|
||||
arcaneFailureCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!arcaneFailure)
|
||||
if(failedAllEnchants(arcaneFailureCount, enchants.entrySet().size()))
|
||||
{
|
||||
Map<Enchantment, Integer> newEnchants = enchantMeta.getStoredEnchants();
|
||||
|
||||
if (downgraded || newEnchants.size() < enchants.size()) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcanePartial");
|
||||
}
|
||||
else {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcanePartial");
|
||||
}
|
||||
|
||||
book.setItemMeta(enchantMeta);
|
||||
} else {
|
||||
if(enchantMeta.getStoredEnchants().size() > 0)
|
||||
{
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcaneFailed");
|
||||
}
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcaneFailed");
|
||||
return null;
|
||||
} else if(downgraded)
|
||||
{
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.ArcanePartial");
|
||||
}
|
||||
|
||||
book.setItemMeta(enchantMeta);
|
||||
return book;
|
||||
}
|
||||
|
||||
private boolean failedAllEnchants(int arcaneFailureCount, int size) {
|
||||
return arcaneFailureCount == size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player has tried to use an Anvil before.
|
||||
* @param actualize
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.gmail.nossr50.skills.smelting;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
@@ -16,11 +15,7 @@ public class Smelting {
|
||||
return RankUtils.getRank(player, SubSkillType.SMELTING_UNDERSTANDING_THE_ART);
|
||||
}
|
||||
|
||||
public static int burnModifierMaxLevel = AdvancedConfig.getInstance().getBurnModifierMaxLevel();
|
||||
public static double burnTimeMultiplier = AdvancedConfig.getInstance().getBurnTimeMultiplier();
|
||||
|
||||
public static int fluxMiningUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.SMELTING_FLUX_MINING);
|
||||
public static double fluxMiningChance = AdvancedConfig.getInstance().getFluxMiningChance();
|
||||
//public static int fluxMiningUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.SMELTING_FLUX_MINING);
|
||||
|
||||
protected static int getResourceXp(ItemStack smelting) {
|
||||
return mcMMO.getModManager().isCustomOre(smelting.getType()) ? mcMMO.getModManager().getBlock(smelting.getType()).getSmeltingXpGain() : ExperienceConfig.getInstance().getXp(PrimarySkillType.SMELTING, smelting.getType());
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
package com.gmail.nossr50.skills.smelting;
|
||||
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.skills.mining.Mining;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.EventUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.FurnaceBurnEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -31,12 +19,12 @@ public class SmeltingManager extends SkillManager {
|
||||
super(mcMMOPlayer, PrimarySkillType.SMELTING);
|
||||
}
|
||||
|
||||
public boolean canUseFluxMining(BlockState blockState) {
|
||||
/*public boolean canUseFluxMining(BlockState blockState) {
|
||||
return getSkillLevel() >= Smelting.fluxMiningUnlockLevel
|
||||
&& BlockUtils.affectedByFluxMining(blockState)
|
||||
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_FLUX_MINING)
|
||||
&& !mcMMO.getPlaceStore().isTrue(blockState);
|
||||
}
|
||||
}*/
|
||||
|
||||
public boolean isSecondSmeltSuccessful() {
|
||||
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_SECOND_SMELT)
|
||||
@@ -49,7 +37,7 @@ public class SmeltingManager extends SkillManager {
|
||||
* @param blockState The {@link BlockState} to check ability activation for
|
||||
* @return true if the ability was successful, false otherwise
|
||||
*/
|
||||
public boolean processFluxMining(BlockState blockState) {
|
||||
/*public boolean processFluxMining(BlockState blockState) {
|
||||
Player player = getPlayer();
|
||||
|
||||
if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.SMELTING_FLUX_MINING, true)) {
|
||||
@@ -94,7 +82,7 @@ public class SmeltingManager extends SkillManager {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Increases burn time for furnace fuel.
|
||||
@@ -102,9 +90,22 @@ public class SmeltingManager extends SkillManager {
|
||||
* @param burnTime The initial burn time from the {@link FurnaceBurnEvent}
|
||||
*/
|
||||
public int fuelEfficiency(int burnTime) {
|
||||
double burnModifier = 1 + (((double) getSkillLevel() / Smelting.burnModifierMaxLevel) * Smelting.burnTimeMultiplier);
|
||||
return burnTime * getFuelEfficiencyMultiplier();
|
||||
}
|
||||
|
||||
return (int) (burnTime * burnModifier);
|
||||
public int getFuelEfficiencyMultiplier()
|
||||
{
|
||||
switch(RankUtils.getRank(getPlayer(), SubSkillType.SMELTING_FUEL_EFFICIENCY))
|
||||
{
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 3;
|
||||
case 3:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack smeltProcessing(ItemStack smelting, ItemStack result) {
|
||||
|
||||
@@ -4,10 +4,8 @@ import com.gmail.nossr50.config.AdvancedConfig;
|
||||
|
||||
public class Swords {
|
||||
public static int bleedMaxTicks = AdvancedConfig.getInstance().getRuptureMaxTicks();
|
||||
public static int bleedBaseTicks = AdvancedConfig.getInstance().getRuptureBaseTicks();
|
||||
|
||||
public static double counterAttackModifier = AdvancedConfig.getInstance().getCounterModifier();
|
||||
|
||||
public static double serratedStrikesModifier = AdvancedConfig.getInstance().getSerratedStrikesModifier();
|
||||
public static int serratedStrikesBleedTicks = AdvancedConfig.getInstance().getSerratedStrikesTicks();
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
||||
import com.gmail.nossr50.datatypes.skills.ToolType;
|
||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.ItemUtils;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
@@ -19,6 +19,7 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -31,6 +32,10 @@ public class SwordsManager extends SkillManager {
|
||||
return mcMMOPlayer.getToolPreparationMode(ToolType.SWORD) && Permissions.serratedStrikes(getPlayer());
|
||||
}
|
||||
|
||||
public boolean canUseStab() {
|
||||
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_STAB) && RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_STAB);
|
||||
}
|
||||
|
||||
public boolean canUseRupture() {
|
||||
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_RUPTURE) && RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_RUPTURE);
|
||||
}
|
||||
@@ -60,13 +65,17 @@ public class SwordsManager extends SkillManager {
|
||||
if (target instanceof Player) {
|
||||
Player defender = (Player) target;
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
//Don't start or add to a bleed if they are blocking
|
||||
if(defender.isBlocking())
|
||||
return;
|
||||
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
if(!BleedTimerTask.isBleeding(defender))
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Started");
|
||||
}
|
||||
}
|
||||
|
||||
BleedTimerTask.add(target, getPlayer(), getRuptureBleedTicks(), RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE));
|
||||
BleedTimerTask.add(target, getPlayer(), getRuptureBleedTicks(), RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE), getToolTier(getPlayer().getInventory().getItemInMainHand()));
|
||||
|
||||
if (mcMMOPlayer.useChatNotifications()) {
|
||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding");
|
||||
@@ -74,6 +83,31 @@ public class SwordsManager extends SkillManager {
|
||||
}
|
||||
}
|
||||
|
||||
public double getStabDamage()
|
||||
{
|
||||
int rank = RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_STAB);
|
||||
|
||||
if(rank > 0)
|
||||
{
|
||||
double stabDamage = 1.0D + (rank * 1.5);
|
||||
return stabDamage;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getToolTier(ItemStack itemStack)
|
||||
{
|
||||
if(ItemUtils.isDiamondTool(itemStack))
|
||||
return 4;
|
||||
else if(ItemUtils.isIronTool(itemStack) || ItemUtils.isGoldTool(itemStack))
|
||||
return 3;
|
||||
else if(ItemUtils.isStoneTool(itemStack))
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getRuptureBleedTicks()
|
||||
{
|
||||
int bleedTicks = 2 * RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE);
|
||||
@@ -110,6 +144,5 @@ public class SwordsManager extends SkillManager {
|
||||
*/
|
||||
public void serratedStrikes(LivingEntity target, double damage, Map<DamageModifier, Double> modifiers) {
|
||||
CombatUtils.applyAbilityAoE(getPlayer(), target, damage / Swords.serratedStrikesModifier, modifiers, skill);
|
||||
BleedTimerTask.add(target, getPlayer(), getRuptureBleedTicks(), RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_RUPTURE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.StringUtils;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
@@ -124,7 +123,7 @@ public class TamingManager extends SkillManager {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BleedTimerTask.add(target, getPlayer(), Taming.goreBleedTicks, 1);
|
||||
BleedTimerTask.add(target, getPlayer(), Taming.goreBleedTicks, 1, 2);
|
||||
|
||||
if (target instanceof Player) {
|
||||
NotificationManager.sendPlayerInformation((Player)target, NotificationType.SUBSKILL_MESSAGE, "Combat.StruckByGore");
|
||||
@@ -225,7 +224,7 @@ public class TamingManager extends SkillManager {
|
||||
if (target instanceof Player) {
|
||||
Player defender = (Player) target;
|
||||
|
||||
if (UserManager.getPlayer(defender).useChatNotifications()) {
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Taming.SubSkill.Pummel.TargetMessage");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,9 @@ public class UnarmedManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if(UserManager.getPlayer(defender) == null)
|
||||
return;
|
||||
|
||||
Item item = Misc.dropItem(defender.getLocation(), defender.getInventory().getItemInMainHand());
|
||||
|
||||
if (item != null && AdvancedConfig.getInstance().getDisarmProtected()) {
|
||||
@@ -151,7 +154,14 @@ public class UnarmedManager extends SkillManager {
|
||||
}
|
||||
|
||||
public double getIronArmDamage() {
|
||||
return RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE) * 2;
|
||||
int rank = RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
|
||||
|
||||
if(rank == 1)
|
||||
{
|
||||
return 4;
|
||||
} else {
|
||||
return 3 + (rank * 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.repair.Repair;
|
||||
import com.gmail.nossr50.skills.salvage.Salvage;
|
||||
import com.gmail.nossr50.util.random.RandomChanceSkill;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.Ageable;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -16,6 +21,34 @@ public final class BlockUtils {
|
||||
|
||||
private BlockUtils() {}
|
||||
|
||||
/**
|
||||
* Mark a block for giving bonus drops, double drops are used if triple is false
|
||||
* @param blockState target blockstate
|
||||
* @param triple marks the block to give triple drops
|
||||
*/
|
||||
public static void markDropsAsBonus(BlockState blockState, boolean triple)
|
||||
{
|
||||
if(triple)
|
||||
blockState.setMetadata(mcMMO.tripleDrops, mcMMO.metadataValue);
|
||||
else
|
||||
blockState.setMetadata(mcMMO.doubleDrops, mcMMO.metadataValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player successfully passed the double drop check
|
||||
* @param blockState the blockstate
|
||||
* @return true if the player succeeded in the check
|
||||
*/
|
||||
public static boolean checkDoubleDrops(Player player, BlockState blockState, PrimarySkillType skillType, SubSkillType subSkillType)
|
||||
{
|
||||
if(Config.getInstance().getDoubleDropsEnabled(skillType, blockState.getType()) && Permissions.isSubSkillEnabled(player, subSkillType))
|
||||
{
|
||||
return RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType, true));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a given block awards XP.
|
||||
*
|
||||
|
||||
@@ -54,6 +54,10 @@ public final class ChimaeraWing {
|
||||
|
||||
mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Not loaded
|
||||
if(mcMMOPlayer == null)
|
||||
return;
|
||||
|
||||
if (mcMMOPlayer.getTeleportCommenceLocation() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -120,11 +120,16 @@ public class EventUtils {
|
||||
Player player = (Player) entity;
|
||||
|
||||
if (!UserManager.hasPlayerDataKey(player)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
if(mcMMOPlayer == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check for invincibility */
|
||||
if (mcMMOPlayer.getGodMode()) {
|
||||
entityDamageEvent.setCancelled(true);
|
||||
@@ -198,6 +203,22 @@ public class EventUtils {
|
||||
return !isCancelled;
|
||||
}
|
||||
|
||||
public static boolean handleLevelChangeEventEdit(Player player, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason, int oldLevel) {
|
||||
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged - oldLevel, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
boolean isCancelled = event.isCancelled();
|
||||
|
||||
if (isCancelled) {
|
||||
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
|
||||
|
||||
profile.modifySkill(skill, profile.getSkillLevel(skill) - (isLevelUp ? levelsChanged : -levelsChanged));
|
||||
profile.addXp(skill, xpRemoved);
|
||||
}
|
||||
|
||||
return !isCancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a block break event.
|
||||
*
|
||||
@@ -226,6 +247,9 @@ public class EventUtils {
|
||||
public static void handlePartyTeleportEvent(Player teleportingPlayer, Player targetPlayer) {
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
|
||||
|
||||
if(mcMMOPlayer == null)
|
||||
return;
|
||||
|
||||
McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(teleportingPlayer, targetPlayer, mcMMOPlayer.getParty().getName());
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
@@ -284,6 +308,9 @@ public class EventUtils {
|
||||
}
|
||||
|
||||
public static boolean handleStatsLossEvent(Player player, HashMap<String, Integer> levelChanged, HashMap<String, Float> experienceChanged) {
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return true;
|
||||
|
||||
McMMOPlayerStatLossEvent event = new McMMOPlayerStatLossEvent(player, levelChanged, experienceChanged);
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
@@ -330,6 +357,15 @@ public class EventUtils {
|
||||
HashMap<String, Float> experienceChangedVictim = eventVictim.getExperienceChanged();
|
||||
|
||||
McMMOPlayer killerPlayer = UserManager.getPlayer(killer);
|
||||
|
||||
//Not loaded
|
||||
if(killerPlayer == null)
|
||||
return true;
|
||||
|
||||
//Not loaded
|
||||
if(UserManager.getPlayer(victim) == null)
|
||||
return true;
|
||||
|
||||
PlayerProfile victimProfile = UserManager.getPlayer(victim).getProfile();
|
||||
|
||||
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
|
||||
|
||||
@@ -17,6 +17,9 @@ public final class HardcoreManager {
|
||||
double statLossPercentage = Config.getInstance().getHardcoreDeathStatPenaltyPercentage();
|
||||
int levelThreshold = Config.getInstance().getHardcoreDeathStatPenaltyLevelThreshold();
|
||||
|
||||
if(UserManager.getPlayer(player) == null)
|
||||
return;
|
||||
|
||||
PlayerProfile playerProfile = UserManager.getPlayer(player).getProfile();
|
||||
int totalLevelsLost = 0;
|
||||
|
||||
@@ -59,6 +62,9 @@ public final class HardcoreManager {
|
||||
double vampirismStatLeechPercentage = Config.getInstance().getHardcoreVampirismStatLeechPercentage();
|
||||
int levelThreshold = Config.getInstance().getHardcoreVampirismLevelThreshold();
|
||||
|
||||
if(UserManager.getPlayer(killer) == null || UserManager.getPlayer(victim) == null)
|
||||
return;
|
||||
|
||||
PlayerProfile killerProfile = UserManager.getPlayer(killer).getProfile();
|
||||
PlayerProfile victimProfile = UserManager.getPlayer(victim).getProfile();
|
||||
int totalLevelsStolen = 0;
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.commands.skills.AprilCommand;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.FireworkEffect.Type;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerStatisticIncrementEvent;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@@ -110,9 +108,9 @@ public final class HolidayManager {
|
||||
}
|
||||
}
|
||||
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
colors.add(color.getFireworkColor());
|
||||
}
|
||||
// for (DyeColor color : DyeColor.values()) {
|
||||
// colors.add(color.getFireworkColor());
|
||||
// }
|
||||
|
||||
Collections.shuffle(chatColors, Misc.getRandom());
|
||||
Collections.shuffle(colors, Misc.getRandom());
|
||||
@@ -224,7 +222,7 @@ public final class HolidayManager {
|
||||
}
|
||||
|
||||
sender.sendMessage(LocaleLoader.getString("Holiday.Anniversary", (currentYear - START_YEAR)));
|
||||
if (sender instanceof Player) {
|
||||
/*if (sender instanceof Player) {
|
||||
final int firework_amount = 10;
|
||||
for (int i = 0; i < firework_amount; i++) {
|
||||
int delay = (int) (Misc.getRandom().nextDouble() * 3 * Misc.TICK_CONVERSION_FACTOR) + 4;
|
||||
@@ -235,8 +233,8 @@ public final class HolidayManager {
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
}*/
|
||||
// else {
|
||||
/*
|
||||
* Credit: http://www.geocities.com/spunk1111/
|
||||
* (good luck finding that in 3 years heh)
|
||||
@@ -273,7 +271,7 @@ public final class HolidayManager {
|
||||
sender.sendMessage(String.format(" %2$s* %6$s*..* %9$s: %11$s*", colorParams));
|
||||
sender.sendMessage(String.format(" %2$s* %9$s* %11$s*", colorParams));
|
||||
sender.sendMessage(String.format(" %2$s* %9$s* %11$s*", colorParams));
|
||||
}
|
||||
// }
|
||||
|
||||
hasCelebrated.add(sender.getName());
|
||||
}
|
||||
@@ -282,19 +280,19 @@ public final class HolidayManager {
|
||||
return !(date.before(start) || date.after(end));
|
||||
}
|
||||
|
||||
public void spawnFireworks(Player player) {
|
||||
int power = Misc.getRandom().nextInt(3) + 1;
|
||||
Type fireworkType = Type.values()[Misc.getRandom().nextInt(Type.values().length)];
|
||||
double varX = Misc.getRandom().nextGaussian() * 3;
|
||||
double varZ = Misc.getRandom().nextGaussian() * 3;
|
||||
|
||||
Firework fireworks = (Firework) player.getWorld().spawnEntity(player.getLocation().add(varX, 0, varZ), EntityType.FIREWORK);
|
||||
FireworkMeta fireworkmeta = fireworks.getFireworkMeta();
|
||||
FireworkEffect effect = FireworkEffect.builder().flicker(Misc.getRandom().nextBoolean()).withColor(colorChoose()).withFade(colorChoose()).with(fireworkType).trail(Misc.getRandom().nextBoolean()).build();
|
||||
fireworkmeta.addEffect(effect);
|
||||
fireworkmeta.setPower(power);
|
||||
fireworks.setFireworkMeta(fireworkmeta);
|
||||
}
|
||||
// public void spawnFireworks(Player player) {
|
||||
// int power = Misc.getRandom().nextInt(3) + 1;
|
||||
// Type fireworkType = Type.values()[Misc.getRandom().nextInt(Type.values().length)];
|
||||
// double varX = Misc.getRandom().nextGaussian() * 3;
|
||||
// double varZ = Misc.getRandom().nextGaussian() * 3;
|
||||
//
|
||||
// Firework fireworks = (Firework) player.getWorld().spawnEntity(player.getLocation().add(varX, 0, varZ), EntityType.FIREWORK);
|
||||
// FireworkMeta fireworkmeta = fireworks.getFireworkMeta();
|
||||
// FireworkEffect effect = FireworkEffect.builder().flicker(Misc.getRandom().nextBoolean()).withColor(colorChoose()).withFade(colorChoose()).with(fireworkType).trail(Misc.getRandom().nextBoolean()).build();
|
||||
// fireworkmeta.addEffect(effect);
|
||||
// fireworkmeta.setPower(power);
|
||||
// fireworks.setFireworkMeta(fireworkmeta);
|
||||
// }
|
||||
|
||||
private static List<Color> colorChoose() {
|
||||
return ALL_COLORS.subList(0, Math.max(Misc.getRandom().nextInt(ALL_COLORS.size() + 1), 1));
|
||||
@@ -313,6 +311,9 @@ public final class HolidayManager {
|
||||
}
|
||||
|
||||
public boolean isAprilFirst() {
|
||||
if(!Config.getInstance().isAprilFoolsAllowed())
|
||||
return false;
|
||||
|
||||
GregorianCalendar aprilFirst = new GregorianCalendar(currentYear, Calendar.APRIL, 1);
|
||||
GregorianCalendar aprilSecond = new GregorianCalendar(currentYear, Calendar.APRIL, 2);
|
||||
GregorianCalendar day = new GregorianCalendar();
|
||||
@@ -320,6 +321,9 @@ public final class HolidayManager {
|
||||
}
|
||||
|
||||
public boolean nearingAprilFirst() {
|
||||
if(!Config.getInstance().isAprilFoolsAllowed())
|
||||
return false;
|
||||
|
||||
GregorianCalendar start = new GregorianCalendar(Calendar.getInstance().get(Calendar.YEAR), Calendar.MARCH, 28);
|
||||
GregorianCalendar end = new GregorianCalendar(Calendar.getInstance().get(Calendar.YEAR), Calendar.APRIL, 2);
|
||||
GregorianCalendar day = new GregorianCalendar();
|
||||
@@ -360,13 +364,19 @@ public final class HolidayManager {
|
||||
}
|
||||
|
||||
public void levelUpApril(Player player, FakeSkillType fakeSkillType) {
|
||||
if(!Config.getInstance().isAprilFoolsAllowed())
|
||||
return;
|
||||
|
||||
int levelTotal = Misc.getRandom().nextInt(1 + UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.MINING)) + 1;
|
||||
SoundManager.sendSound(player, player.getLocation(), SoundType.LEVEL_UP);
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.HOLIDAY, "Holiday.AprilFools.Levelup", StringUtils.getCapitalized(fakeSkillType.toString()), String.valueOf(levelTotal));
|
||||
ParticleEffectUtils.fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size())));
|
||||
// ParticleEffectUtils.fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size())));
|
||||
}
|
||||
|
||||
public void registerAprilCommand() {
|
||||
if(!Config.getInstance().isAprilFoolsAllowed())
|
||||
return;
|
||||
|
||||
PluginCommand command = mcMMO.p.getCommand("mcfools");
|
||||
command.setExecutor(new AprilCommand());
|
||||
}
|
||||
|
||||
@@ -8,10 +8,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.NPC;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -43,7 +40,10 @@ public final class Misc {
|
||||
private Misc() {};
|
||||
|
||||
public static boolean isNPCEntity(Entity entity) {
|
||||
return (entity == null || entity.hasMetadata("NPC") || entity instanceof NPC || entity.getClass().getName().equalsIgnoreCase("cofh.entity.PlayerFake"));
|
||||
return (entity == null
|
||||
|| (entity.hasMetadata("NPC") && !(entity instanceof Villager))
|
||||
|| (entity instanceof NPC && !(entity instanceof Villager))
|
||||
|| entity.getClass().getName().equalsIgnoreCase("cofh.entity.PlayerFake"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,6 +106,11 @@ public final class Permissions {
|
||||
* PERKS
|
||||
*/
|
||||
|
||||
/* BYPASS PERKS */
|
||||
|
||||
public static boolean hasRepairEnchantBypassPerk(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.bypass.repairenchant"); }
|
||||
public static boolean hasSalvageEnchantBypassPerk(Permissible permissible) { return permissible.hasPermission("mcmmo.perks.bypass.salvageenchant"); }
|
||||
|
||||
public static boolean lucky(Permissible permissible, PrimarySkillType skill) { return permissible.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase()); }
|
||||
|
||||
/* XP PERKS */
|
||||
|
||||
@@ -48,11 +48,13 @@ public class HashChunkManager implements ChunkManager {
|
||||
throw new RuntimeException("Wrong class type read for chunk meta data for " + x + ", " + z);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Assume the format changed
|
||||
return null;
|
||||
//throw new RuntimeException("Unable to process chunk meta data for " + x + ", " + z, e);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
// Assume the format changed
|
||||
//System.out.println("[SpoutPlugin] is Unable to find serialized class for " + x + ", " + z + ", " + e.getMessage());
|
||||
return null;
|
||||
|
||||
@@ -223,6 +223,9 @@ public final class CommandUtils {
|
||||
}
|
||||
|
||||
private static void printGroupedSkillData(Player inspect, CommandSender display, String header, List<PrimarySkillType> skillGroup) {
|
||||
if(UserManager.getPlayer(inspect) == null)
|
||||
return;
|
||||
|
||||
PlayerProfile profile = UserManager.getPlayer(inspect).getProfile();
|
||||
|
||||
List<String> displayData = new ArrayList<String>();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user