1
0
mirror of https://github.com/mcMMO-Dev/mcMMO.git synced 2026-02-21 19:22:59 +01:00

Compare commits

...

77 Commits

Author SHA1 Message Date
NuclearW
3eb265c5f7 1.3.08
Minor addition to changelog
2012-05-22 08:42:06 -04:00
GJ
049338e83b Remove unused variables & methods from old repair system 2012-05-22 08:37:32 -04:00
GJ
a336e9f460 Removed unused imports. 2012-05-22 08:31:32 -04:00
GJ
0294cf8c4a Implement new repairable stuff for custom tools/armor. 2012-05-22 08:21:05 -04:00
NuclearW
c5183309ae New line on the factory floor
For RepairableFactory
2012-05-22 08:10:22 -04:00
NuclearW
0a15cb1e13 Modify custom items loading to permit registering of repairables from these configs.
Move loading of the main repairables to below the custom items so that repair.*.yml will over-write any custom items when the list is processed and repairables registered.
2012-05-22 07:57:09 -04:00
nossr50
9546cc42b2 Redundant 2012-05-22 02:57:54 -07:00
NuclearW
ac01262655 Fix error in config 2012-05-22 05:46:40 -04:00
nossr50
6ea962c1fa Changing the MOTD again, modified a few messages. Now hardcore mode only
tells you about itself when motd is enabled.
2012-05-22 02:45:42 -07:00
nossr50
9e35283273 Changelog updates 2012-05-22 02:41:19 -07:00
NuclearW
9c8e1d9c9f Some changelog for @nossr50 2012-05-22 05:34:23 -04:00
NuclearW
7d324b3fd4 Changelog
and supercomment to default repair.vanilla.yml
2012-05-22 05:33:05 -04:00
NuclearW
badc5738ff Fix up repair command as best as possible given what it is... 2012-05-22 05:33:05 -04:00
NuclearW
8feaf4410f getRepairable by id 2012-05-22 05:33:04 -04:00
NuclearW
4e224d761e Cleanup Repair.java 2012-05-22 05:33:04 -04:00
NuclearW
e775abdc5a Remove all the old stuff from the config 2012-05-22 05:33:04 -04:00
NuclearW
60754c9380 Implement xp 2012-05-22 05:33:04 -04:00
NuclearW
c890ff5605 Use new system! 2012-05-22 05:33:04 -04:00
NuclearW
9f9c0059a5 Change xpHandler for new system usage
This commit marks the first breaking change for this new system
2012-05-22 05:33:03 -04:00
NuclearW
4eabd417b9 Level check 2012-05-22 05:33:03 -04:00
NuclearW
c218de9567 Change to new line in locale 2012-05-22 05:33:03 -04:00
NuclearW
4b5ca5ecf4 Logic fix 2012-05-22 05:33:02 -04:00
NuclearW
edbf46a751 Unused import 2012-05-22 05:33:02 -04:00
NuclearW
c9c90bb86a New line in locale 2012-05-22 05:33:02 -04:00
NuclearW
437a608d2b Return on this error 2012-05-22 05:33:01 -04:00
nossr50
b638eef1c6 Players are now informed about Hardcore mode when logging in 2012-05-22 02:31:01 -07:00
NuclearW
b7cec8a0c4 Most of handleRepair() done, level checking still needed
- Move Repair
- Change visibility of a few methods for repurposing Repair soon
2012-05-22 04:22:29 -04:00
NuclearW
28578bd6b0 Convenience method for RepairManager 2012-05-22 02:59:10 -04:00
nossr50
160004fa7e Hardcore mode now has some exploit prevention and much more information 2012-05-21 23:56:08 -07:00
nossr50
f4332761f9 Many changes to Hardcore / Vampirism 2012-05-21 23:30:16 -07:00
NuclearW
a4d1a18850 Example repair config for chainmail 2012-05-22 01:11:56 -04:00
NuclearW
c3e1e55e9c Fix for minimumQuantity default 2012-05-22 01:08:29 -04:00
NuclearW
e20bcd19b9 Make our RepairManager, load configs, and register them all 2012-05-22 00:57:24 -04:00
NuclearW
1fbf213ada Load message 2012-05-22 00:56:57 -04:00
NuclearW
c2d2359a8c RepairConfig loader
and small fix for RepairConfigManager
2012-05-22 00:56:14 -04:00
NuclearW
586a2a065e Shears 2012-05-22 00:00:02 -04:00
NuclearW
adf43b7e35 String 2012-05-22 00:00:02 -04:00
NuclearW
45a4cddeef Leather 2012-05-22 00:00:02 -04:00
NuclearW
69f62551c7 Your repair is now diamonds 2012-05-22 00:00:02 -04:00
NuclearW
f1bdf502be Gold
and fix for minQuantity on iron armor
2012-05-22 00:00:02 -04:00
NuclearW
e89b3795f8 Save vanilla from jar 2012-05-22 00:00:02 -04:00
NuclearW
20b169e8eb Typo 2012-05-22 00:00:01 -04:00
NuclearW
1480ee2779 Changelog 2012-05-22 00:00:01 -04:00
GJ
41c9741b72 Fixed exploit where you could gain tons of Acrobatics XP from spamming
Ender Pearls
2012-05-21 23:41:11 -04:00
GJ
f9e5096ceb Cleanup 2012-05-21 10:31:24 -04:00
NuclearW
a9b2a4940e Max_Ticks to Max_Seconds 2012-05-21 10:04:07 -04:00
GJ
f66c6ab8fc Cleanup 2012-05-21 09:33:21 -04:00
GJ
73902d5f92 Minor cleanup / refactoring 2012-05-21 09:21:26 -04:00
NuclearW
0bb5f9f297 Max ticks for abilities 2012-05-21 09:17:16 -04:00
GJ
16ad8502d2 Cleanup, changed order of some logic checks. 2012-05-21 09:04:51 -04:00
GJ
ad68e6057e More cleanup. 2012-05-21 08:45:33 -04:00
GJ
54b4faeeff Minor cleanup. 2012-05-21 08:39:27 -04:00
NuclearW
a7f69545f2 Emulate unbreaking properly 2012-05-21 08:31:29 -04:00
NuclearW
93ea558ec3 Cleanup 2012-05-21 08:27:26 -04:00
GJ
d0cdc208e3 Avoid a duplicate config call. 2012-05-21 07:53:52 -04:00
NuclearW
0d7c483bd5 Tameable not a part of combat checks at the moment, only wolves 2012-05-21 07:25:20 -04:00
NuclearW
3f211c6277 Generalize Wolf to Tameable
Also generalize Arrow to Projectile
For MCCORE-263
2012-05-21 04:44:48 -04:00
NuclearW
79e93edfef Switch order of sticky check and placeStore check.
sticky check is much less expensive than placeStore, so it's better to ensure that the piston is sticky before doing a placeStore check
2012-05-21 02:19:45 -04:00
Travis Ralston
44e8efda36 Check for sticky pistons 2012-05-19 08:00:34 -06:00
NuclearW
9726ac6f12 Send metrics information on if this server uses timings 2012-05-19 00:42:50 -04:00
NuclearW
898d8c6449 Changelog 2012-05-18 22:09:28 -04:00
NuclearW
01006ed76d Hidden config and use of NullChunkletManager
ChunkletManagerFactory now produces NullChunkletManagers if Chunklets are disabeld in the hidden.yml
2012-05-18 22:01:15 -04:00
NuclearW
2936823d03 NullChunkletManager 2012-05-18 21:44:25 -04:00
GJ
7d05d53f9e Whoops. Can't initialize something that doesn't exist. 2012-05-18 14:40:48 -04:00
GJ
f3074461ed More cleanup. 2012-05-18 14:29:53 -04:00
GJ
146f832919 Minor refactoring & cleanup. 2012-05-18 13:40:21 -04:00
GJ
a622707608 Cleanup & Silk Touch changes. 2012-05-18 11:15:30 -04:00
NuclearW
6da43b15c8 Move to a more ideal location.
Not as efficient as I would like, but certainly better than it was before
2012-05-18 03:14:19 -04:00
NuclearW
d0bb7b075e This was a bad idea 2012-05-18 03:12:40 -04:00
NuclearW
c1ecd74644 Actually remove from map on unload 2012-05-18 03:12:16 -04:00
NuclearW
a1aada0777 Iron armor 2012-05-17 23:53:25 -04:00
NuclearW
c55a8eeccd Iron tools 2012-05-17 23:40:34 -04:00
NuclearW
73cc8adcab Beginnings of repair.vanilla.yml 2012-05-17 23:16:59 -04:00
NuclearW
7bb05f7f26 Update version for development
towards a stronger nation defense system
2012-05-17 22:41:40 -04:00
NuclearW
7f0803c3f6 Add in xpMultiplier 2012-05-17 22:40:46 -04:00
NuclearW
1185ea4f96 Beginnings of RepairConfig 2012-05-17 22:40:46 -04:00
NuclearW
43db51a664 RepairConfigManager 2012-05-17 22:40:46 -04:00
67 changed files with 2083 additions and 1191 deletions

View File

@@ -7,6 +7,27 @@ Key:
! Change
- Removal
Version 1.3.08
+ Added more notifications about Vampirism and Hardcore mode on player death
+ Added information about Hardcore mode when joining a server running Hardcore mode
+ Added new hidden.yml inside the jar for very sensitive config options for advanced users
+ Added option to disable Chunklets for servers which do not have doubledrops and do not care about xp farming
+ Added new "Max_Seconds" setting in config.yml to limit the max time of abilities
+ Added new repair configs to allow customization of the repair skill
+ Added message to inform users about hardcore mode on login
= Fixed exploit where you could gain tons of Acrobatics XP from spamming Ender Pearls
= Fixed normal pistons marking a block as user-placed on retract if it wasn't a sticky piston (thanks turt2live!)
= Fixed handling of the Unbreaking enchantment so that tools are actually damaged as they should now
= Fixed hurting pet cats with serrated strikes
! Changed Hardcore Vampirism to require the victim to have at least half the skill level of the killer in order for vampirism to proc (this is to avoid exploitation)
! Changed Hardcore Vampirism to steal a minimum of 1 skill level from a player no matter the percentage
! Changed Hardcore & Vampirism to not be executed if percentages were set to zero or below
! Changed Vampirism to actually remove stats from the victim
! Changed Vampirism to inform the victim of their stat loss
! Changed Mining to allow Silk Touch to work again since the dupe exploit has been fixed.
! Changed Metrics to also report if the server uses plugin profiling
- Removed level and item settings from Repair skill in config.yml
Version 1.3.07
+ Added ability to gain XP from custom blocks. Enable custom blocks in the config file, then enter the data in the blocks.yml file.
+ Added ability to gain XP with custom tools. Enable custom tools in the config file, then enter the data in the tools.yml file.

73
extras/repair.chain.yml Normal file
View File

@@ -0,0 +1,73 @@
#
# Any file named repair.*.yml in the mcmmmo folder will be loaded as a repair config
# All repair configs have a main section titled "Repairables"
# Afterwards, all sub-items are considered a Repairable to be loaded
# The bare minimum of a Repairable is that it have an ItemId, a RepairMaterialId, and a MaximumDurability
#
# ItemId: This is the id of the item to be repairable.
## This is required to be set.
#
# ItemType: This is the type of item to be repaired, this is only important to permissions.
## Valid values are ARMOR, TOOL, and OTHER.
## This defaults to OTHER.
#
# MaterialType: This is the type of the material of the item to be repaired, this is only important for permissions.
## Valid values are STRING, LEATHER, WOOD, STONE, IRON, GOLD, DIAMOND, and OTHER
## This defaults to OTHER.
#
# RepairMaterialId: This is the id of the item used to repair this repairable.
## This is required to be set.
#
# RepairMaterialMetadata: This is the metadata of the item used to repair this repairable.
## A value of -1 means to ignore all metadata when repairing.
## This defaults to -1
#
# MaximumDurability: This is the maximum durability of the item.
## This is required to be set.
#
# MinimumLevel: This is the minimum repair level needed to repair this item.
## Valid values are > 0
## This defaults to 0
#
# MinimumQuantity: This is the minimum number of items needed to repair this item ignoring all other repair bonuses.
## This is typically the number of the repair material needed to create a new item, for example for a sword it is 2, for an axe it is 3
## This defaults to 2
#
# XpMultiplier: This is the amount to multiply the xp bonus by.
## This defaults to 1
#
#
# The following is an example of a repair.*.yml config which adds the ability to repair Chainmail armor using fire.
#
#
###
Repairables:
ChainHelmet:
ItemId: 302
ItemType: ARMOR
RepairMaterialId: 51
MaximumDurability: 165
MinimumQuantity: 5
XpMultiplier: 2
ChainChest:
ItemId: 303
ItemType: ARMOR
RepairMaterialId: 51
MaximumDurability: 240
MinimumQuantity: 8
XpMultiplier: 2
ChainLegs:
ItemId: 304
ItemType: ARMOR
RepairMaterialId: 51
MaximumDurability: 225
MinimumQuantity: 7
XpMultiplier: 2
ChainBoots:
ItemId: 305
ItemType: ARMOR
RepairMaterialId: 51
RepairMaterialMetadata: -1
MaximumDurability: 195
MinimumQuantity: 4
XpMultiplier: 2

View File

@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>1.3.07</version>
<version>1.3.08</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<issueManagement>

View File

@@ -7,12 +7,14 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.commands.CommandHelper;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.misc.Repair;
import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.util.Page;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
@@ -128,12 +130,17 @@ public class RepairCommand implements CommandExecutor {
private void dataCalculations(float skillValue) {
DecimalFormat percent = new DecimalFormat("##0.00%");
Config configInstance = Config.getInstance();
diamondLevel = configInstance.getRepairDiamondLevelRequirement();
goldLevel = configInstance.getRepairGoldLevelRequirement();
ironLevel = configInstance.getRepairIronLevelRequirement();
stoneLevel = configInstance.getRepairStoneLevelRequirement();
// We're using pickaxes here, not the best but works
Repairable diamondRepairable = mcMMO.repairManager.getRepairable(278);
Repairable goldRepairable = mcMMO.repairManager.getRepairable(285);
Repairable ironRepairable = mcMMO.repairManager.getRepairable(257);
Repairable stoneRepairable = mcMMO.repairManager.getRepairable(274);
diamondLevel = (diamondRepairable == null) ? 0 : diamondRepairable.getMinimumLevel();
goldLevel = (goldRepairable == null) ? 0 : goldRepairable.getMinimumLevel();
ironLevel = (ironRepairable == null) ? 0 : ironRepairable.getMinimumLevel();
stoneLevel = (stoneRepairable == null) ? 0 : stoneRepairable.getMinimumLevel();
repairMasteryBonus = percent.format(skillValue / 500);

View File

@@ -113,6 +113,16 @@ public class Config extends ConfigLoader {
public int getAbilityCooldownSkullSplitter() { return config.getInt("Abilities.Cooldowns.Skull_Splitter", 240); }
public int getAbilityCooldownBlastMining() { return config.getInt("Abilities.Cooldowns.Blast_Mining", 60); }
/* Max ticks */
public int getAbilityMaxTicksGreenTerra() { return config.getInt("Abilities.Max_Seconds.Green_Terra", 0); }
public int getAbilityMaxTicksSuperBreaker() { return config.getInt("Abilities.Max_Seconds.Super_Breaker", 0); }
public int getAbilityMaxTicksGigaDrillBreaker() { return config.getInt("Abilities.Max_Seconds.Giga_Drill_Breaker", 0); }
public int getAbilityMaxTicksTreeFeller() { return config.getInt("Abilities.Max_Seconds.Tree_Feller", 0); }
public int getAbilityMaxTicksBerserk() { return config.getInt("Abilities.Max_Seconds.Berserk", 0); }
public int getAbilityMaxTicksSerratedStrikes() { return config.getInt("Abilities.Max_Seconds.Serrated_Strikes", 0); }
public int getAbilityMaxTicksSkullSplitter() { return config.getInt("Abilities.Max_Seconds.Skull_Splitter", 0); }
public int getAbilityMaxTicksBlastMining() { return config.getInt("Abilities.Max_Seconds.Blast_Mining", 0); }
/* Thresholds */
public int getTreeFellerThreshold() { return config.getInt("Abilities.Limits.Tree_Feller_Threshold", 500); }
@@ -239,19 +249,6 @@ public class Config extends ConfigLoader {
public boolean getRepairAnvilMessagesEnabled() { return config.getBoolean("Skills.Repair.Anvil_Messages", true); }
public int getRepairAnvilId() { return config.getInt("Skills.Repair.Anvil_ID", 42); }
public int getRepairGoldMaterial() { return config.getInt("Skills.Repair.Gold.ID", 266); }
public int getRepairStoneMaterial() { return config.getInt("Skills.Repair.Stone.ID", 4); }
public int getRepairWoodMaterial() { return config.getInt("Skills.Repair.Wood.ID", 5); }
public int getRepairDiamondMaterial() { return config.getInt("Skills.Repair.Diamond.ID", 264); }
public int getRepairIronMaterial() { return config.getInt("Skills.Repair.Iron.ID", 265); }
public int getRepairStringMaterial() { return config.getInt("Skills.Repair.String.ID", 287); }
public int getRepairLeatherMaterial() { return config.getInt("Skills.Repair.Leather.ID", 334); }
public int getRepairDiamondLevelRequirement() { return config.getInt("Skills.Repair.Diamond.Level_Required", 50); }
public int getRepairIronLevelRequirement() { return config.getInt("Skills.Repair.Iron.Level_Required", 0); }
public int getRepairGoldLevelRequirement() { return config.getInt("Skills.Repair.Gold.Level_Required", 0); }
public int getRepairStoneLevelRequirement() { return config.getInt("Skills.Repair.Stone.Level_Required", 0); }
/* Taming */
public int getTamingXPWolf() { return config.getInt("Experience.Taming.Animal_Taming.Wolf", 250); }
public int getTamingXPOcelot() { return config.getInt("Experience.Taming.Animal_Taming.Ocelot", 500); }

View File

@@ -0,0 +1,44 @@
package com.gmail.nossr50.config;
import org.bukkit.configuration.file.YamlConfiguration;
import com.gmail.nossr50.mcMMO;
public class HiddenConfig extends ConfigLoader {
private static String fileName;
private static HiddenConfig instance;
private static YamlConfiguration config;
private static boolean chunkletsEnabled;
public HiddenConfig(mcMMO plugin, String fileName) {
super(plugin, fileName);
HiddenConfig.fileName = fileName;
}
public static HiddenConfig getInstance() {
if (instance == null) {
instance = new HiddenConfig(mcMMO.p, "hidden.yml");
instance.load();
}
return instance;
}
@Override
protected void load() {
if(plugin.isInJar(fileName)) loadKeys();
}
@Override
protected void loadKeys() {
config = YamlConfiguration.loadConfiguration(plugin.getResource(fileName));
chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
}
public boolean getChunkletsEnabled() {
return chunkletsEnabled;
}
}

View File

@@ -0,0 +1,111 @@
package com.gmail.nossr50.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.RepairItemType;
import com.gmail.nossr50.skills.repair.RepairMaterialType;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.skills.repair.RepairableFactory;
public class RepairConfig extends ConfigLoader {
private final String fileName;
private List<Repairable> repairables;
public RepairConfig(mcMMO plugin, String fileName) {
super(plugin, fileName);
this.fileName = fileName;
this.config = YamlConfiguration.loadConfiguration(this.configFile);
}
@Override
protected void load() {
loadKeys();
}
@Override
protected void loadKeys() {
repairables = new ArrayList<Repairable>();
ConfigurationSection section = config.getConfigurationSection("Repairables");
Set<String> keys = section.getKeys(false);
for(String key : keys) {
// Validate all the things!
List<String> reason = new ArrayList<String>();
if(!config.contains("Repairables." + key + ".ItemId")) {
reason.add(key + " is missing ItemId");
}
if(!config.contains("Repairables." + key + ".RepairMaterialId")) {
reason.add(key + " is missing RepairMaterialId");
}
if(!config.contains("Repairables." + key + ".MaximumDurability")) {
reason.add(key + " is missing MaximumDurability");
}
int itemId = config.getInt("Repairables." + key + ".ItemId", 0);
int repairMaterialId = config.getInt("Repairables." + key + ".RepairMaterialId", 0);
int maximumDurability = config.getInt("Repairables." + key + ".MaximumDurability", 0);
int repairMetadata = config.getInt("Repairables." + key + ".RepairMaterialMetadata", -1);
int minimumLevel = config.getInt("Repairables." + key + ".MinimumLevel", 0);
int minimumQuantity = config.getInt("Repairables." + key + ".MinimumQuantity", 2);
double xpMultiplier = config.getDouble("Repairables." + key + ".XpMultiplier", 1);
RepairItemType repairItemType = RepairItemType.OTHER;
RepairMaterialType repairMaterialType = RepairMaterialType.OTHER;
String repairItemTypeString = config.getString("Repairables." + key + ".ItemType", "OTHER");
String repairMaterialTypeString = config.getString("Repairables." + key + ".MaterialType", "OTHER");
if(minimumLevel < 0) {
reason.add(key + " has an invalid MinimumLevel of " + minimumLevel);
}
if(minimumQuantity < 0) {
reason.add(key + " has an invalid MinimumQuantity of " + minimumQuantity);
}
try {
repairItemType = RepairItemType.valueOf(repairItemTypeString);
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid ItemType of " + repairItemTypeString);
}
try {
repairMaterialType = RepairMaterialType.valueOf(repairMaterialTypeString);
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid MaterialType of " + repairMaterialTypeString);
}
if(noErrorsInRepairable(reason)) {
Repairable repairable = RepairableFactory.getRepairable(itemId, repairMaterialId, (byte) repairMetadata, minimumLevel, minimumQuantity, (short) maximumDurability, repairItemType, repairMaterialType, xpMultiplier);
repairables.add(repairable);
}
}
}
protected List<Repairable> getLoadedRepairables() {
if(repairables == null) return new ArrayList<Repairable>();
return repairables;
}
private boolean noErrorsInRepairable(List<String> issues) {
if (issues.isEmpty()) {
return true;
}
else {
for (String issue : issues) {
plugin.getLogger().warning(issue);
}
return false;
}
}
}

View File

@@ -0,0 +1,47 @@
package com.gmail.nossr50.config;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.Repairable;
public class RepairConfigManager {
private List<Repairable> repairables;
public RepairConfigManager(mcMMO plugin) {
repairables = new ArrayList<Repairable>();
Pattern pattern = Pattern.compile("repair\\.(?:.+)\\.yml");
File dataFolder = plugin.getDataFolder();
File vanilla = new File(dataFolder, "repair.vanilla.yml");
if(!vanilla.exists()) {
plugin.saveResource("repair.vanilla.yml", false);
}
for(String location : dataFolder.list()) {
if(!pattern.matcher(location).matches()) continue;
plugin.getLogger().info("Loading " + location + " repair config file...");
File file = new File(dataFolder, location);
if(file.isDirectory()) continue;
RepairConfig rConfig = new RepairConfig(plugin, location);
rConfig.load();
List<Repairable> rConfigRepairables = rConfig.getLoadedRepairables();
if(rConfigRepairables != null) {
repairables.addAll(rConfigRepairables);
}
}
}
public List<Repairable> getLoadedRepairables() {
if(repairables == null) return new ArrayList<Repairable>();
return repairables;
}
}

View File

@@ -1,15 +1,17 @@
package com.gmail.nossr50.config.mods;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.mods.CustomItem;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.skills.repair.RepairableFactory;
public class CustomArmorConfig extends ModConfigLoader{
private static CustomArmorConfig instance;
@@ -22,13 +24,16 @@ public class CustomArmorConfig extends ModConfigLoader{
return instance;
}
private List<Repairable> repairables;
public List<Integer> customBootIDs = new ArrayList<Integer>();
public List<Integer> customChestplateIDs = new ArrayList<Integer>();
public List<Integer> customHelmetIDs = new ArrayList<Integer>();
public List<Integer> customLeggingIDs = new ArrayList<Integer>();
public List<Integer> customIDs = new ArrayList<Integer>();
public List<CustomItem> customItems = new ArrayList<CustomItem>();
public List<CustomItem> customArmorList = new ArrayList<CustomItem>();
public HashMap<Integer, CustomItem> customArmor = new HashMap<Integer, CustomItem>();
public CustomArmorConfig(mcMMO plugin) {
super(plugin, "armor.yml");
@@ -49,6 +54,7 @@ public class CustomArmorConfig extends ModConfigLoader{
@Override
protected void loadKeys() {
plugin.getLogger().info("Loading mcMMO armor.yml File...");
repairables = new ArrayList<Repairable>();
loadArmor("Boots", customBootIDs);
loadArmor("Chestplates", customChestplateIDs);
@@ -84,16 +90,20 @@ public class CustomArmorConfig extends ModConfigLoader{
CustomItem armor;
if (repairable) {
ItemStack repairMaterial = new ItemStack(repairID, 1, (short) 0, repairData);
armor = new CustomItem(durability, repairMaterial, repairQuantity, repairable, id);
}
else {
armor = new CustomItem(durability, null, 0, repairable, id);
repairables.add(RepairableFactory.getRepairable(id, repairID, repairData, repairQuantity, durability));
}
armor = new CustomItem(id);
idList.add(id);
customIDs.add(id);
customItems.add(armor);
customArmorList.add(armor);
customArmor.put(id, armor);
}
}
public List<Repairable> getLoadedRepairables() {
if(repairables == null) return new ArrayList<Repairable>();
return repairables;
}
}

View File

@@ -1,16 +1,17 @@
package com.gmail.nossr50.config.mods;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.mods.CustomItem;
import com.gmail.nossr50.datatypes.mods.CustomTool;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.skills.repair.RepairableFactory;
public class CustomToolsConfig extends ModConfigLoader {
private static CustomToolsConfig instance;
@@ -23,6 +24,8 @@ public class CustomToolsConfig extends ModConfigLoader {
return instance;
}
private List<Repairable> repairables;
public List<Integer> customAxeIDs = new ArrayList<Integer>();
public List<Integer> customBowIDs = new ArrayList<Integer>();
public List<Integer> customHoeIDs = new ArrayList<Integer>();
@@ -31,7 +34,8 @@ public class CustomToolsConfig extends ModConfigLoader {
public List<Integer> customSwordIDs = new ArrayList<Integer>();
public List<Integer> customIDs = new ArrayList<Integer>();
public List<CustomItem> customItems = new ArrayList<CustomItem>();
public List<CustomTool> customToolList = new ArrayList<CustomTool>();
public HashMap<Integer, CustomTool> customTools = new HashMap<Integer, CustomTool>();
private CustomToolsConfig(mcMMO plugin) {
super(plugin, "tools.yml");
@@ -52,6 +56,7 @@ public class CustomToolsConfig extends ModConfigLoader {
@Override
protected void loadKeys() {
plugin.getLogger().info("Loading mcMMO tools.yml File...");
repairables = new ArrayList<Repairable>();
loadTool("Axes", customAxeIDs);
loadTool("Bows", customBowIDs);
@@ -92,16 +97,20 @@ public class CustomToolsConfig extends ModConfigLoader {
CustomTool tool;
if (repairable) {
ItemStack repairMaterial = new ItemStack(repairID, 1, (short) 0, repairData);
tool = new CustomTool(durability, repairMaterial, repairQuantity, repairable, tier, abilityEnabled, multiplier, id);
}
else {
tool = new CustomTool(durability, null, 0, repairable, tier, abilityEnabled, multiplier, id);
repairables.add(RepairableFactory.getRepairable(id, repairID, repairData, repairQuantity, durability));
}
tool = new CustomTool(tier, abilityEnabled, multiplier, id);
idList.add(id);
customIDs.add(id);
customItems.add(tool);
customToolList.add(tool);
customTools.put(id, tool);
}
}
public List<Repairable> getLoadedRepairables() {
if(repairables == null) return new ArrayList<Repairable>();
return repairables;
}
}

View File

@@ -12,6 +12,7 @@ import com.gmail.nossr50.util.Permissions;
public enum AbilityType {
BERSERK(
Config.getInstance().getAbilityCooldownBerserk(),
Config.getInstance().getAbilityMaxTicksBerserk(),
"Unarmed.Skills.Berserk.On",
"Unarmed.Skills.Berserk.Off",
"Unarmed.Skills.Berserk.Other.On",
@@ -20,6 +21,7 @@ public enum AbilityType {
SUPER_BREAKER(
Config.getInstance().getAbilityCooldownSuperBreaker(),
Config.getInstance().getAbilityMaxTicksSuperBreaker(),
"Mining.Skills.SuperBreaker.On",
"Mining.Skills.SuperBreaker.Off",
"Mining.Skills.SuperBreaker.Other.On",
@@ -28,6 +30,7 @@ public enum AbilityType {
GIGA_DRILL_BREAKER(
Config.getInstance().getAbilityCooldownGigaDrillBreaker(),
Config.getInstance().getAbilityMaxTicksGigaDrillBreaker(),
"Excavation.Skills.GigaDrillBreaker.On",
"Excavation.Skills.GigaDrillBreaker.Off",
"Excavation.Skills.GigaDrillBreaker.Other.On",
@@ -36,6 +39,7 @@ public enum AbilityType {
GREEN_TERRA(
Config.getInstance().getAbilityCooldownGreenTerra(),
Config.getInstance().getAbilityMaxTicksGreenTerra(),
"Herbalism.Skills.GTe.On",
"Herbalism.Skills.GTe.Off",
"Herbalism.Skills.GTe.Other.On",
@@ -44,6 +48,7 @@ public enum AbilityType {
SKULL_SPLIITER(
Config.getInstance().getAbilityCooldownSkullSplitter(),
Config.getInstance().getAbilityMaxTicksSkullSplitter(),
"Axes.Skills.SS.On",
"Axes.Skills.SS.Off",
"Axes.Skills.SS.Other.On",
@@ -52,6 +57,7 @@ public enum AbilityType {
TREE_FELLER(
Config.getInstance().getAbilityCooldownTreeFeller(),
Config.getInstance().getAbilityMaxTicksTreeFeller(),
"Woodcutting.Skills.TreeFeller.On",
"Woodcutting.Skills.TreeFeller.Off",
"Woodcutting.Skills.TreeFeller.Other.On",
@@ -60,6 +66,7 @@ public enum AbilityType {
SERRATED_STRIKES(
Config.getInstance().getAbilityCooldownSerratedStrikes(),
Config.getInstance().getAbilityMaxTicksSerratedStrikes(),
"Swords.Skills.SS.On",
"Swords.Skills.SS.Off",
"Swords.Skills.SS.Other.On",
@@ -68,6 +75,7 @@ public enum AbilityType {
BLAST_MINING(
Config.getInstance().getAbilityCooldownBlastMining(),
Config.getInstance().getAbilityMaxTicksBlastMining(),
null,
null,
"Mining.Blast.Other.On",
@@ -75,6 +83,7 @@ public enum AbilityType {
null),
LEAF_BLOWER(
0,
0,
null,
null,
@@ -83,14 +92,16 @@ public enum AbilityType {
null);
private int cooldown;
private int maxTicks;
private String abilityOn;
private String abilityOff;
private String abilityPlayer;
private String abilityRefresh;
private String abilityPlayerOff;
private AbilityType(int cooldown, String abilityOn, String abilityOff, String abilityPlayer, String abilityRefresh, String abilityPlayerOff) {
private AbilityType(int cooldown, int maxTicks, String abilityOn, String abilityOff, String abilityPlayer, String abilityRefresh, String abilityPlayerOff) {
this.cooldown = cooldown;
this.maxTicks = maxTicks;
this.abilityOn = abilityOn;
this.abilityOff = abilityOff;
this.abilityPlayer = abilityPlayer;
@@ -122,6 +133,10 @@ public enum AbilityType {
return LocaleLoader.getString(this.abilityRefresh);
}
public int getMaxTicks() {
return this.maxTicks;
}
/**
* Get the permissions for this ability.
*

View File

@@ -12,9 +12,9 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.mods.CustomTool;
import com.gmail.nossr50.events.experience.McMMOPlayerXpGainEvent;
import com.gmail.nossr50.party.Party;
import com.gmail.nossr50.util.ItemChecks;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.ModChecks;
import com.gmail.nossr50.util.Users;
@@ -1032,9 +1032,10 @@ public class PlayerProfile {
if (Config.getInstance().getToolModsEnabled()) {
ItemStack item = player.getItemInHand();
CustomTool tool = ModChecks.getToolFromItemStack(item);
if (ItemChecks.isCustomTool(item)) {
xp = (int) (xp * ModChecks.getToolFromItemStack(item).getXpMultiplier());
if (tool != null) {
xp = (int) (xp * tool.getXpMultiplier());
}
}

View File

@@ -1,20 +1,10 @@
package com.gmail.nossr50.datatypes.mods;
import org.bukkit.inventory.ItemStack;
public class CustomItem {
protected int itemID;
protected boolean repairable;
protected ItemStack repairMaterial;
protected int repairQuantity;
protected short durability;
public CustomItem(short durability, ItemStack repairMaterial, int repairQuantity, boolean repairable, int itemID) {
public CustomItem(int itemID) {
this.itemID = itemID;
this.repairable = repairable;
this.repairMaterial = repairMaterial;
this.repairQuantity = repairQuantity;
this.durability = durability;
}
public int getItemID() {
@@ -24,37 +14,4 @@ public class CustomItem {
public void setItemID(int itemID) {
this.itemID = itemID;
}
public boolean isRepairable() {
return repairable;
}
public void setRepairable(boolean repairable) {
this.repairable = repairable;
}
public ItemStack getRepairMaterial() {
return repairMaterial;
}
public void setRepairMaterial(ItemStack repairMaterial) {
this.repairMaterial = repairMaterial;
}
public int getRepairQuantity() {
return repairQuantity;
}
public void setRepairQuantity(int repairQuantity) {
this.repairQuantity = repairQuantity;
}
public short getDurability() {
return durability;
}
public void setDurability(short durability) {
this.durability = durability;
}
}

View File

@@ -1,14 +1,12 @@
package com.gmail.nossr50.datatypes.mods;
import org.bukkit.inventory.ItemStack;
public class CustomTool extends CustomItem {
private double xpMultiplier;
private boolean abilityEnabled;
private int tier;
public CustomTool(short durability, ItemStack repairMaterial, int repairQuantity, boolean repairable, int tier, boolean abilityEnabled, double xpMultiplier, int itemID) {
super(durability, repairMaterial, repairQuantity, repairable, itemID);
public CustomTool(int tier, boolean abilityEnabled, double xpMultiplier, int itemID) {
super(itemID);
this.xpMultiplier = xpMultiplier;
this.abilityEnabled = abilityEnabled;
this.tier = tier;

View File

@@ -12,7 +12,7 @@ import com.gmail.nossr50.skills.gathering.Excavation;
import com.gmail.nossr50.skills.gathering.Herbalism;
import com.gmail.nossr50.skills.gathering.Mining;
import com.gmail.nossr50.skills.gathering.WoodCutting;
import com.gmail.nossr50.skills.misc.Repair;
import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.spout.SpoutSounds;
import com.gmail.nossr50.util.BlockChecks;
import com.gmail.nossr50.util.ItemChecks;
@@ -23,11 +23,9 @@ import com.gmail.nossr50.util.Users;
import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
import org.bukkit.CropState;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -82,7 +80,7 @@ public class BlockListener implements Listener {
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
Block block = event.getRetractLocation().getBlock();
if (mcMMO.placeStore.isTrue(block)) {
if (event.isSticky() && mcMMO.placeStore.isTrue(block)) {
mcMMO.placeStore.setFalse(block);
mcMMO.placeStore.setTrue(event.getBlock().getRelative(event.getDirection()));
}
@@ -95,6 +93,8 @@ public class BlockListener implements Listener {
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
Config configInstance = Config.getInstance();
Block block = event.getBlock();
Player player = event.getPlayer();
int id = block.getTypeId();
@@ -119,7 +119,7 @@ public class BlockListener implements Listener {
mcMMO.placeStore.setTrue(block);
}
if (id == Config.getInstance().getRepairAnvilId() && Config.getInstance().getRepairAnvilMessagesEnabled()) {
if (id == configInstance.getRepairAnvilId() && configInstance.getRepairAnvilMessagesEnabled()) {
Repair.placedAnvilCheck(player, id);
}
}
@@ -134,77 +134,75 @@ public class BlockListener implements Listener {
Player player = event.getPlayer();
PlayerProfile PP = Users.getProfile(player);
Block block = event.getBlock();
Material mat = block.getType();
ItemStack inhand = player.getItemInHand();
ItemStack inHand = player.getItemInHand();
Config configInstance = Config.getInstance();
Permissions permInstance = Permissions.getInstance();
if (event instanceof FakeBlockBreakEvent) {
return;
}
/*
* HERBALISM
*/
/* Green Terra */
if (PP.getToolPreparationMode(ToolType.HOE) && Permissions.getInstance().greenTerra(player) && ((mat.equals(Material.CROPS) && block.getData() == CropState.RIPE.getData()) || BlockChecks.canBeGreenTerra(block))) {
Skills.abilityCheck(player, SkillType.HERBALISM);
}
/* Triple drops */
if (PP.getAbilityMode(AbilityType.GREEN_TERRA) && BlockChecks.canBeGreenTerra(block)) {
Herbalism.herbalismProcCheck(block, player, event, plugin);
}
if (Permissions.getInstance().herbalism(player) && BlockChecks.canBeGreenTerra(block)) {
Herbalism.herbalismProcCheck(block, player, event, plugin);
}
/*
* MINING
*/
if (Permissions.getInstance().mining(player) && BlockChecks.canBeSuperBroken(block)) {
if (Config.getInstance().getMiningRequiresTool() && ItemChecks.isPickaxe(inhand)) {
Mining.miningBlockCheck(player, block);
/* HERBALISM */
if (BlockChecks.canBeGreenTerra(block)) {
/* Green Terra */
if (PP.getToolPreparationMode(ToolType.HOE) && permInstance.greenTerra(player)) {
Skills.abilityCheck(player, SkillType.HERBALISM);
}
else if (!Config.getInstance().getMiningRequiresTool()) {
Mining.miningBlockCheck(player, block);
/* Triple drops */
if (PP.getAbilityMode(AbilityType.GREEN_TERRA)) {
Herbalism.herbalismProcCheck(block, player, event, plugin);
}
if (permInstance.herbalism(player)) {
Herbalism.herbalismProcCheck(block, player, event, plugin);
}
}
/*
* WOOD CUTTING
*/
if (Permissions.getInstance().woodcutting(player) && mat.equals(Material.LOG)) {
if (Config.getInstance().getWoodcuttingRequiresTool() && ItemChecks.isAxe(inhand)) {
WoodCutting.woodcuttingBlockCheck(player, block);
}
else if (!Config.getInstance().getWoodcuttingRequiresTool()) {
WoodCutting.woodcuttingBlockCheck(player, block);
}
}
if (PP.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.getInstance().treeFeller(player) && ItemChecks.isAxe(inhand)) {
if (Config.getInstance().getToolModsEnabled()) {
if ((ItemChecks.isCustomTool(inhand) && ModChecks.getToolFromItemStack(inhand).isAbilityEnabled()) || !ItemChecks.isCustomTool(inhand)) {
WoodCutting.treeFeller(event);
/* MINING */
else if (BlockChecks.canBeSuperBroken(block) && permInstance.mining(player)) {
if (configInstance.getMiningRequiresTool()) {
if (ItemChecks.isPickaxe(inHand)) {
Mining.miningBlockCheck(player, block);
}
}
else {
WoodCutting.treeFeller(event);
Mining.miningBlockCheck(player, block);
}
}
/*
* EXCAVATION
*/
if (BlockChecks.canBeGigaDrillBroken(block) && Permissions.getInstance().excavation(player) && !mcMMO.placeStore.isTrue(block)) {
if (Config.getInstance().getExcavationRequiresTool() && ItemChecks.isShovel(inhand)) {
Excavation.excavationProcCheck(block, player);
/* WOOD CUTTING */
else if (BlockChecks.isLog(block) && permInstance.woodcutting(player)) {
if (configInstance.getWoodcuttingRequiresTool()) {
if (ItemChecks.isAxe(inHand)) {
WoodCutting.woodcuttingBlockCheck(player, block);
}
}
else if (!Config.getInstance().getExcavationRequiresTool()) {
else {
WoodCutting.woodcuttingBlockCheck(player, block);
}
if (PP.getAbilityMode(AbilityType.TREE_FELLER) && permInstance.treeFeller(player) && ItemChecks.isAxe(inHand)) {
if (ModChecks.isCustomTool(inHand)) {
if (ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
WoodCutting.treeFeller(event);
}
}
else {
WoodCutting.treeFeller(event);
}
}
}
/* EXCAVATION */
else if (BlockChecks.canBeGigaDrillBroken(block) && permInstance.excavation(player) && !mcMMO.placeStore.isTrue(block)) {
if (configInstance.getExcavationRequiresTool()) {
if (ItemChecks.isShovel(inHand)) {
Excavation.excavationProcCheck(block, player);
}
}
else {
Excavation.excavationProcCheck(block, player);
}
}
@@ -226,9 +224,12 @@ public class BlockListener implements Listener {
Player player = event.getPlayer();
PlayerProfile PP = Users.getProfile(player);
ItemStack inhand = player.getItemInHand();
ItemStack inHand = player.getItemInHand();
Block block = event.getBlock();
Material mat = block.getType();
Material material = block.getType();
Config configInstance = Config.getInstance();
Permissions permInstance = Permissions.getInstance();
/*
* ABILITY PREPARATION CHECKS
@@ -237,7 +238,7 @@ public class BlockListener implements Listener {
if (PP.getToolPreparationMode(ToolType.HOE) && (BlockChecks.canBeGreenTerra(block) || BlockChecks.makeMossy(block))) {
Skills.abilityCheck(player, SkillType.HERBALISM);
}
else if (PP.getToolPreparationMode(ToolType.AXE) && mat.equals(Material.LOG) && Permissions.getInstance().treeFeller(player)) { //TODO: Why are we checking the permissions here?
else if (PP.getToolPreparationMode(ToolType.AXE) && BlockChecks.isLog(block) && permInstance.treeFeller(player)) { //TODO: Why are we checking the permissions here?
Skills.abilityCheck(player, SkillType.WOODCUTTING);
}
else if (PP.getToolPreparationMode(ToolType.PICKAXE) && BlockChecks.canBeSuperBroken(block)) {
@@ -246,22 +247,22 @@ public class BlockListener implements Listener {
else if (PP.getToolPreparationMode(ToolType.SHOVEL) && BlockChecks.canBeGigaDrillBroken(block)) {
Skills.abilityCheck(player, SkillType.EXCAVATION);
}
else if (PP.getToolPreparationMode(ToolType.FISTS) && (BlockChecks.canBeGigaDrillBroken(block) || mat.equals(Material.SNOW))) {
else if (PP.getToolPreparationMode(ToolType.FISTS) && (BlockChecks.canBeGigaDrillBroken(block) || material.equals(Material.SNOW))) {
Skills.abilityCheck(player, SkillType.UNARMED);
}
}
/* TREE FELLER SOUNDS */
if (Config.getInstance().spoutEnabled && mat.equals(Material.LOG) && PP.getAbilityMode(AbilityType.TREE_FELLER)) {
if (configInstance.spoutEnabled && BlockChecks.isLog(block) && PP.getAbilityMode(AbilityType.TREE_FELLER)) {
SpoutSounds.playSoundForPlayer(SoundEffect.FIZZ, player, block.getLocation());
}
/*
* ABILITY TRIGGER CHECKS
*/
if (PP.getAbilityMode(AbilityType.GREEN_TERRA) && Permissions.getInstance().greenTerra(player) && BlockChecks.makeMossy(block)) {
if (Config.getInstance().getToolModsEnabled()) {
if ((ItemChecks.isCustomTool(inhand) && ModChecks.getToolFromItemStack(inhand).isAbilityEnabled()) || !ItemChecks.isCustomTool(inhand)) {
if (PP.getAbilityMode(AbilityType.GREEN_TERRA) && permInstance.greenTerra(player) && BlockChecks.makeMossy(block)) {
if (ModChecks.isCustomTool(inHand)) {
if (ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
Herbalism.greenTerra(player, block);
}
}
@@ -270,64 +271,66 @@ public class BlockListener implements Listener {
}
}
else if (PP.getAbilityMode(AbilityType.GIGA_DRILL_BREAKER) && Skills.triggerCheck(player, block, AbilityType.GIGA_DRILL_BREAKER)) {
if (Config.getInstance().getExcavationRequiresTool() && ItemChecks.isShovel(inhand)) {
if (Config.getInstance().getToolModsEnabled()) {
if ((ItemChecks.isCustomTool(inhand) && ModChecks.getToolFromItemStack(inhand).isAbilityEnabled()) || !ItemChecks.isCustomTool(inhand)) {
if (configInstance.getExcavationRequiresTool()) {
if (ItemChecks.isShovel(inHand)) {
if (ModChecks.isCustomTool(inHand)) {
if (ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
event.setInstaBreak(true);
Excavation.gigaDrillBreaker(player, block);
}
}
else {
event.setInstaBreak(true);
Excavation.gigaDrillBreaker(player, block);
}
}
else {
event.setInstaBreak(true);
Excavation.gigaDrillBreaker(player, block);
}
}
else if (!Config.getInstance().getExcavationRequiresTool()) {
else {
event.setInstaBreak(true);
Excavation.gigaDrillBreaker(player, block);
}
}
else if (PP.getAbilityMode(AbilityType.BERSERK) && Skills.triggerCheck(player, block, AbilityType.BERSERK)) {
if (inhand.getType().equals(Material.AIR)) {
if (inHand.getType().equals(Material.AIR)) {
FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
plugin.getServer().getPluginManager().callEvent(armswing);
event.setInstaBreak(true);
}
if (Config.getInstance().spoutEnabled) {
if (configInstance.spoutEnabled) {
SpoutSounds.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
}
}
else if (PP.getAbilityMode(AbilityType.SUPER_BREAKER) && Skills.triggerCheck(player, block, AbilityType.SUPER_BREAKER)) {
if (!player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) { //TODO: Why are we checking this?
if (Config.getInstance().getMiningRequiresTool() && ItemChecks.isPickaxe(inhand)) {
if (Config.getInstance().getToolModsEnabled()) {
if ((ItemChecks.isCustomTool(inhand) && ModChecks.getToolFromItemStack(inhand).isAbilityEnabled()) || !ItemChecks.isCustomTool(inhand)) {
if (configInstance.getMiningRequiresTool()) {
if (ItemChecks.isPickaxe(inHand)) {
if (ModChecks.isCustomTool(inHand)) {
if (ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
event.setInstaBreak(true);
Mining.SuperBreakerBlockCheck(player, block);
Mining.superBreakerBlockCheck(player, block);
}
}
else {
event.setInstaBreak(true);
Mining.SuperBreakerBlockCheck(player, block);
Mining.superBreakerBlockCheck(player, block);
}
}
else if (!Config.getInstance().getMiningRequiresTool()) {
event.setInstaBreak(true);
Mining.SuperBreakerBlockCheck(player, block);
}
}
else {
event.setInstaBreak(true);
Mining.superBreakerBlockCheck(player, block);
}
}
else if (PP.getSkillLevel(SkillType.WOODCUTTING) >= LEAF_BLOWER_LEVEL && (mat.equals(Material.LEAVES) || (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLeafBlock(block)))) {
if (Config.getInstance().getWoodcuttingRequiresTool() && ItemChecks.isAxe(inhand)) {
if (Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) {
event.setInstaBreak(true);
WoodCutting.leafBlower(player, block);
else if (PP.getSkillLevel(SkillType.WOODCUTTING) >= LEAF_BLOWER_LEVEL && (material.equals(Material.LEAVES) || (configInstance.getBlockModsEnabled() && ModChecks.isCustomLeafBlock(block)))) {
if (Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) {
if (configInstance.getWoodcuttingRequiresTool()) {
if (ItemChecks.isAxe(inHand)) {
event.setInstaBreak(true);
WoodCutting.leafBlower(player, block);
}
}
}
else if (!Config.getInstance().getWoodcuttingRequiresTool() && !inhand.getType().equals(Material.SHEARS)) {
if (Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) {
else if (!inHand.getType().equals(Material.SHEARS)) {
event.setInstaBreak(true);
WoodCutting.leafBlower(player, block);
}

View File

@@ -9,7 +9,6 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Wolf;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -105,12 +104,15 @@ public class EntityListener implements Listener {
}
Entity entity = event.getEntity();
EntityType type = entity.getType();
DamageCause cause = event.getCause();
switch(type) {
case PLAYER:
if (!(entity instanceof LivingEntity)) {
return;
}
LivingEntity lEntity = (LivingEntity) entity;
if (lEntity instanceof Player) {
/* Check for invincibility */
Player player = (Player) entity;
PlayerProfile PP = Users.getProfile(player);
@@ -121,7 +123,7 @@ public class EntityListener implements Listener {
}
if (!Misc.isInvincible(player, event)) {
if (cause == DamageCause.FALL && Permissions.getInstance().acrobatics(player) && !player.isInsideVehicle()) {
if (cause == DamageCause.FALL && Permissions.getInstance().acrobatics(player) && !player.isInsideVehicle() && !player.getItemInHand().getType().equals(Material.ENDER_PEARL)) {
Acrobatics.acrobaticsCheck(player, event);
}
else if (cause == DamageCause.BLOCK_EXPLOSION && Permissions.getInstance().demolitionsExpertise(player)) {
@@ -132,18 +134,12 @@ public class EntityListener implements Listener {
PP.setRecentlyHurt(System.currentTimeMillis());
}
}
break;
} else if (lEntity instanceof Tameable) {
Tameable pet = (Tameable) lEntity;
case WOLF:
Wolf wolf = (Wolf) entity;
if ((!Misc.isInvincible(wolf, event)) && wolf.isTamed() && (wolf.getOwner() instanceof Player)) {
if ((!Misc.isInvincible(lEntity, event)) && pet.isTamed() && (pet.getOwner() instanceof Player)) {
Taming.preventDamage(event);
}
break;
default:
break;
}
}

View File

@@ -21,7 +21,6 @@ public class HardcoreListener implements Listener {
Hardcore.invokeVampirism(((Player)player.getKiller()), player);
}
}
Hardcore.invokeStatPenalty(player);
}
}

View File

@@ -41,11 +41,8 @@ import com.gmail.nossr50.skills.combat.Taming;
import com.gmail.nossr50.skills.gathering.BlastMining;
import com.gmail.nossr50.skills.gathering.Fishing;
import com.gmail.nossr50.skills.gathering.Herbalism;
import com.gmail.nossr50.skills.misc.Repair;
import com.gmail.nossr50.util.BlockChecks;
import com.gmail.nossr50.util.Item;
import com.gmail.nossr50.util.ItemChecks;
import com.gmail.nossr50.util.ModChecks;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Skills;
import com.gmail.nossr50.util.Users;
@@ -164,10 +161,23 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (Permissions.getInstance().motd(player) && Config.getInstance().getMOTDEnabled()) {
player.sendMessage(ChatColor.GOLD+"Server is running "+ChatColor.GREEN+plugin.getName()+" "+plugin.getDescription().getVersion());
player.sendMessage(ChatColor.GOLD+"http://www.mcmmo.info"+ChatColor.DARK_AQUA+" - mcMMO Website");
if (Config.getInstance().getMOTDEnabled() && Permissions.getInstance().motd(player)) {
String prefix = ChatColor.GOLD+"[mcMMO] ";
player.sendMessage(prefix+ChatColor.YELLOW+"Running version " + ChatColor.DARK_AQUA + plugin.getDescription().getVersion()); //TODO: Locale
if(Config.getInstance().getHardcoreEnabled()) {
if(Config.getInstance().getHardcoreVampirismEnabled()) {
player.sendMessage(prefix+ChatColor.DARK_RED+"Hardcore & Vampirism enabled.");
player.sendMessage(prefix+ChatColor.DARK_AQUA+"Skill Death Penalty: "+ChatColor.DARK_RED+Config.getInstance().getHardcoreDeathStatPenaltyPercentage()+"% "+ChatColor.DARK_AQUA+"Vampirism Stat Leech: "+ChatColor.DARK_RED+Config.getInstance().getHardcoreVampirismStatLeechPercentage()+"%");
} else {
player.sendMessage(prefix+ChatColor.DARK_RED+"Hardcore enabled.");
player.sendMessage(prefix+ChatColor.DARK_AQUA+"Skill Death Penalty: "+ChatColor.DARK_RED+Config.getInstance().getHardcoreDeathStatPenaltyPercentage()+"%");
}
}
player.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.GREEN+ "http://www.mcmmo.info" + ChatColor.YELLOW + " - mcMMO Website & Forums"); //TODO: Locale
//player.sendMessage(LocaleLoader.getString("mcMMO.MOTD", new Object[] {plugin.getDescription().getVersion()}));
//player.sendMessage(LocaleLoader.getString("mcMMO.Website"));
}
@@ -176,6 +186,8 @@ public class PlayerListener implements Listener {
if (XprateCommand.xpevent) {
player.sendMessage(LocaleLoader.getString("XPRate.Event", new Object[] {Config.getInstance().xpGainMultiplier}));
}
}
/**
@@ -186,18 +198,17 @@ public class PlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
Action action = event.getAction();
Block block = event.getClickedBlock();
ItemStack is = player.getItemInHand();
Material mat;
ItemStack inHand = player.getItemInHand();
Material material;
/* Fix for NPE on interacting with air */
if (block == null) {
mat = Material.AIR;
material = Material.AIR;
}
else {
mat = block.getType();
material = block.getType();
}
switch (action) {
@@ -205,18 +216,8 @@ public class PlayerListener implements Listener {
/* REPAIR CHECKS */
if (Permissions.getInstance().repair(player) && block.getTypeId() == Config.getInstance().getRepairAnvilId()) {
if (ItemChecks.isTool(is) || ItemChecks.isArmor(is)) {
Repair.repairCheck(player, is);
event.setCancelled(true);
player.updateInventory();
}
else if (Config.getInstance().getToolModsEnabled() && ItemChecks.isCustomTool(is) && ModChecks.getToolFromItemStack(is).isRepairable()) {
Repair.repairCheck(player, is);
event.setCancelled(true);
player.updateInventory();
}
else if (Config.getInstance().getArmorModsEnabled() && ItemChecks.isCustomArmor(is) && ModChecks.getArmorFromItemStack(is).isRepairable()) {
Repair.repairCheck(player, is);
if (mcMMO.repairManager.isRepairable(inHand)) {
mcMMO.repairManager.handleRepair(player, inHand);
event.setCancelled(true);
player.updateInventory();
}
@@ -224,7 +225,7 @@ public class PlayerListener implements Listener {
/* ACTIVATION CHECKS */
if (Config.getInstance().getAbilitiesEnabled() && BlockChecks.abilityBlockCheck(block)) {
if (!mat.equals(Material.DIRT) && !mat.equals(Material.GRASS) && !mat.equals(Material.SOIL)) {
if (!material.equals(Material.DIRT) && !material.equals(Material.GRASS) && !material.equals(Material.SOIL)) {
Skills.activationCheck(player, SkillType.HERBALISM);
}
@@ -237,8 +238,8 @@ public class PlayerListener implements Listener {
}
/* GREEN THUMB CHECK */
if (Permissions.getInstance().greenThumbBlocks(player) && BlockChecks.makeMossy(block) && is.getType().equals(Material.SEEDS)) {
Herbalism.greenThumbBlocks(is, player, block);
if (inHand.getType().equals(Material.SEEDS) && BlockChecks.makeMossy(block) && Permissions.getInstance().greenThumbBlocks(player)) {
Herbalism.greenThumbBlocks(inHand, player, block);
}
/* ITEM CHECKS */
@@ -247,7 +248,7 @@ public class PlayerListener implements Listener {
}
/* BLAST MINING CHECK */
if (player.isSneaking() && Permissions.getInstance().blastMining(player) && is.getTypeId() == Config.getInstance().getDetonatorItemID()) {
if (player.isSneaking() && inHand.getTypeId() == Config.getInstance().getDetonatorItemID() && Permissions.getInstance().blastMining(player)) {
BlastMining.detonate(event, player, plugin);
}
@@ -270,7 +271,7 @@ public class PlayerListener implements Listener {
Item.itemChecks(player);
/* BLAST MINING CHECK */
if (player.isSneaking() && Permissions.getInstance().blastMining(player) && is.getTypeId() == Config.getInstance().getDetonatorItemID()) {
if (player.isSneaking() && inHand.getTypeId() == Config.getInstance().getDetonatorItemID() && Permissions.getInstance().blastMining(player)) {
BlastMining.detonate(event, player, plugin);
}
@@ -281,10 +282,10 @@ public class PlayerListener implements Listener {
/* CALL OF THE WILD CHECKS */
if (player.isSneaking() && Permissions.getInstance().taming(player)) {
if (is.getType().equals(Material.RAW_FISH)) {
if (inHand.getType().equals(Material.RAW_FISH)) {
Taming.animalSummon(EntityType.OCELOT, player, plugin);
}
else if (is.getType().equals(Material.BONE)) {
else if (inHand.getType().equals(Material.BONE)) {
Taming.animalSummon(EntityType.WOLF, player, plugin);
}
}
@@ -331,7 +332,8 @@ public class PlayerListener implements Listener {
event.setFormat(bracketColor + "(" + ChatColor.WHITE + "%1$s" + bracketColor + ") %2$s");
event.getRecipients().retainAll(intendedRecipients);
} else if (PP.getAdminChatMode()) {
}
else if (PP.getAdminChatMode()) {
McMMOAdminChatEvent chatEvent = new McMMOAdminChatEvent(player.getName(), event.getMessage());
plugin.getServer().getPluginManager().callEvent(chatEvent);
@@ -365,14 +367,15 @@ public class PlayerListener implements Listener {
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
String message = event.getMessage();
String command = message.substring(1).split(" ")[0];
String lowerCaseCommand = command.toLowerCase();
if (plugin.aliasMap.containsKey(command.toLowerCase())) {
if (plugin.aliasMap.containsKey(lowerCaseCommand)) {
//We should find a better way to avoid string replacement where the alias is equals to the command
if (command.equals(plugin.aliasMap.get(command.toLowerCase()))) {
if (command.equals(plugin.aliasMap.get(lowerCaseCommand))) {
return;
}
event.setMessage(message.replace(command, plugin.aliasMap.get(command.toLowerCase())));
event.setMessage(message.replace(command, plugin.aliasMap.get(lowerCaseCommand)));
}
}
}

View File

@@ -7,14 +7,20 @@ import com.gmail.nossr50.commands.mc.*;
import com.gmail.nossr50.commands.party.*;
import com.gmail.nossr50.commands.general.*;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.config.RepairConfigManager;
import com.gmail.nossr50.config.TreasuresConfig;
import com.gmail.nossr50.config.mods.CustomBlocksConfig;
import com.gmail.nossr50.config.mods.CustomArmorConfig;
import com.gmail.nossr50.config.mods.CustomToolsConfig;
import com.gmail.nossr50.runnables.*;
import com.gmail.nossr50.skills.repair.RepairManager;
import com.gmail.nossr50.skills.repair.RepairManagerFactory;
import com.gmail.nossr50.skills.repair.Repairable;
import com.gmail.nossr50.util.Database;
import com.gmail.nossr50.util.Leaderboard;
import com.gmail.nossr50.util.Metrics;
import com.gmail.nossr50.util.Metrics.Graph;
import com.gmail.nossr50.util.Users;
import com.gmail.nossr50.util.blockmeta.ChunkletManager;
import com.gmail.nossr50.util.blockmeta.ChunkletManagerFactory;
@@ -30,7 +36,9 @@ import net.shatteredlands.shatt.backup.ZipLibrary;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.PluginDescriptionFile;
@@ -57,6 +65,7 @@ public class mcMMO extends JavaPlugin {
public static mcMMO p;
public static ChunkletManager placeStore;
public static RepairManager repairManager;
/* Jar Stuff */
public File mcmmo;
@@ -74,19 +83,30 @@ public class mcMMO extends JavaPlugin {
//Force the loading of config files
Config configInstance = Config.getInstance();
TreasuresConfig.getInstance();
HiddenConfig.getInstance();
List<Repairable> repairables = new ArrayList<Repairable>();
if (configInstance.getToolModsEnabled()) {
CustomToolsConfig.getInstance().load();
repairables.addAll(CustomToolsConfig.getInstance().getLoadedRepairables());
}
if (configInstance.getArmorModsEnabled()) {
CustomArmorConfig.getInstance().load();
repairables.addAll(CustomArmorConfig.getInstance().getLoadedRepairables());
}
if (configInstance.getBlockModsEnabled()) {
CustomBlocksConfig.getInstance().load();
}
//Load repair configs, make manager, and register them at this time
RepairConfigManager rManager = new RepairConfigManager(this);
repairables.addAll(rManager.getLoadedRepairables());
repairManager = RepairManagerFactory.getRepairManager(repairables.size());
repairManager.registerRepairables(repairables);
if (!configInstance.getUseMySQL()) {
Users.loadUsers();
}
@@ -136,6 +156,25 @@ public class mcMMO extends JavaPlugin {
if (configInstance.getStatsTrackingEnabled()) {
try {
Metrics metrics = new Metrics(this);
Graph graph = metrics.createGraph("Percentage of servers using timings");
if(pm.useTimings()) {
graph.addPlotter(new Metrics.Plotter("Enabled") {
@Override
public int getValue() {
return 1;
}
});
} else {
graph.addPlotter(new Metrics.Plotter("Disabled") {
@Override
public int getValue() {
return 1;
}
});
}
metrics.start();
}
catch (IOException e) {
@@ -146,7 +185,10 @@ public class mcMMO extends JavaPlugin {
// Get our ChunkletManager
placeStore = ChunkletManagerFactory.getChunkletManager();
}
/**
* Setup the various storage file paths
*/
public void setupFilePaths() {
mcmmo = getFile();
mainDirectory = getDataFolder().getPath() + File.separator;

View File

@@ -13,7 +13,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -21,24 +20,24 @@ import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Users;
public class Archery {
public static Map<Entity, Integer> arrowTracker = new HashMap<Entity, Integer>();
private static Random random = new Random();
public static Map<Entity, Integer> arrowTracker = new HashMap<Entity, Integer>();
/**
* Track arrows fired for later retrieval.
*
* @param plugin mcMMO plugin instance
* @param entity Entity damaged by the arrow
* @param PPa PlayerProfile of the player firing the arrow
*/
public static void trackArrows(mcMMO plugin, Entity entity, PlayerProfile PPa) {
public static void trackArrows(Entity entity, PlayerProfile PPa) {
final int MAX_BONUS_LEVEL = 1000;
int skillLevel = PPa.getSkillLevel(SkillType.ARCHERY);
if (skillLevel > MAX_BONUS_LEVEL || (random.nextInt(1000) <= skillLevel)) {
int skillLevel = PPa.getSkillLevel(SkillType.ARCHERY);
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
if (random.nextInt(1000) <= skillCheck) {
for (Entry<Entity, Integer> entry : arrowTracker.entrySet()) {
if (entry.getKey() == entity) {
if (entry.getKey() == entity) { //Shouldn't we be using .equals() here?
entry.setValue(entry.getValue() + 1);
return;
}
@@ -59,18 +58,18 @@ public class Archery {
final int MAX_BONUS_LEVEL = 1000;
int skillLevel = Users.getProfile(attacker).getSkillLevel(SkillType.ARCHERY);
Location loc = defender.getLocation();
Location location = defender.getLocation();
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
if (random.nextInt(10) > 5) {
loc.setPitch(90);
location.setPitch(90);
}
else {
loc.setPitch(-90);
location.setPitch(-90);
}
if (random.nextInt(2000) <= skillCheck) {
defender.teleport(loc);
defender.teleport(location);
event.setDamage(event.getDamage() + 4);
defender.sendMessage(LocaleLoader.getString("Combat.TouchedFuzzy"));
attacker.sendMessage(LocaleLoader.getString("Combat.TargetDazed"));
@@ -83,11 +82,11 @@ public class Archery {
* @param entity The entity hit by the arrows
*/
public static void arrowRetrievalCheck(Entity entity) {
for (Iterator<Map.Entry<Entity, Integer>> it = arrowTracker.entrySet().iterator() ; it.hasNext() ; ) {
for (Iterator<Map.Entry<Entity, Integer>> it = arrowTracker.entrySet().iterator() ; it.hasNext() ; ) { //This is a wee bit confusing...
Entry<Entity, Integer> entry = it.next();
if (entry.getKey() == entity) {
Misc.mcDropItems(entity.getLocation(), new ItemStack(Material.ARROW), entry.getValue());
if (entry.getKey() == entity) { //Shouldn't we be using .equals() here?
Misc.dropItems(entity.getLocation(), new ItemStack(Material.ARROW), entry.getValue());
it.remove();
return;
}

View File

@@ -6,7 +6,7 @@ import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Tameable;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
@@ -51,11 +51,11 @@ public class Axes {
public static void axeCriticalCheck(Player attacker, EntityDamageByEntityEvent event) {
Entity entity = event.getEntity();
if (entity instanceof Wolf) {
Wolf wolf = (Wolf) entity;
if (entity instanceof Tameable) {
Tameable pet = (Tameable) entity;
if (wolf.isTamed()) {
AnimalTamer tamer = wolf.getOwner();
if (pet.isTamed()) {
AnimalTamer tamer = pet.getOwner();
if (tamer instanceof Player) {
Player owner = (Player) tamer;
@@ -80,8 +80,7 @@ public class Axes {
if (entity instanceof Player){
event.setDamage((int) (damage * PVP_MODIFIER));
Player player = (Player) entity;
player.sendMessage(LocaleLoader.getString("Axes.Combat.CritStruck"));
((Player) entity).sendMessage(LocaleLoader.getString("Axes.Combat.CritStruck"));
}
else {
event.setDamage(damage * PVE_MODIFIER);

View File

@@ -6,10 +6,8 @@ import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.entity.Tameable;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -22,23 +20,21 @@ import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class Swords {
private static Random random = new Random();
/**
* Check for Bleed effect.
*
* @param attacker The attacking player
* @param entity The defending entity
* @param plugin mcMMO plugin instance
* @param defender The defending entity
*/
public static void bleedCheck(Player attacker, LivingEntity entity, mcMMO plugin) {
public static void bleedCheck(Player attacker, LivingEntity defender) {
if (entity instanceof Wolf) {
Wolf wolf = (Wolf) entity;
if (defender instanceof Tameable) {
Tameable pet = (Tameable) defender;
if (wolf.isTamed()) {
AnimalTamer tamer = wolf.getOwner();
if (pet.isTamed()) {
AnimalTamer tamer = pet.getOwner();
if (tamer instanceof Player) {
Player owner = (Player) tamer;
@@ -56,7 +52,7 @@ public class Swords {
int skillLevel = PPa.getSkillLevel(SkillType.SWORDS);
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
if (random.nextInt(1000) <= skillCheck && !entity.isDead()) {
if (random.nextInt(1000) <= skillCheck && !defender.isDead()) {
int bleedTicks = 0;
if (skillLevel >= 750) {
@@ -66,7 +62,7 @@ public class Swords {
bleedTicks = 2;
}
BleedTimer.add(entity, bleedTicks);
BleedTimer.add(defender, bleedTicks);
attacker.sendMessage(LocaleLoader.getString("Swords.Combat.Bleeding"));
}
}
@@ -74,35 +70,30 @@ public class Swords {
/**
* Counter-attack entities.
*
* @param event The event to modify
* @param attacker The attacking entity
* @param defender The defending player
* @param damage The amount of damage being countered
*/
public static void counterAttackChecks(EntityDamageByEntityEvent event) {
Entity attacker = event.getDamager();
public static void counterAttackChecks(Entity attacker, Player defender, int damage) {
if (!(attacker instanceof LivingEntity)) {
return;
}
Entity target = event.getEntity();
PlayerProfile PPd = Users.getProfile(defender);
if (target instanceof Player) {
Player defender = (Player) target;
PlayerProfile PPd = Users.getProfile(defender);
if (ItemChecks.isSword(defender.getItemInHand()) && Permissions.getInstance().counterAttack(defender)) {
final int MAX_BONUS_LEVEL = 600;
final int COUNTER_ATTACK_MODIFIER = 2;
if (ItemChecks.isSword(defender.getItemInHand()) && Permissions.getInstance().counterAttack(defender)) {
final int MAX_BONUS_LEVEL = 600;
final int COUNTER_ATTACK_MODIFIER = 2;
int skillLevel = PPd.getSkillLevel(SkillType.SWORDS);
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
int skillLevel = PPd.getSkillLevel(SkillType.SWORDS);
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
if (random.nextInt(2000) <= skillCheck) {
Combat.dealDamage((LivingEntity) attacker, damage / COUNTER_ATTACK_MODIFIER);
defender.sendMessage(LocaleLoader.getString("Swords.Combat.Countered"));
if (random.nextInt(2000) <= skillCheck) {
Combat.dealDamage((LivingEntity) attacker, event.getDamage() / COUNTER_ATTACK_MODIFIER);
defender.sendMessage(LocaleLoader.getString("Swords.Combat.Countered"));
if (attacker instanceof Player) {
((Player) attacker).sendMessage(LocaleLoader.getString("Swords.Combat.Counter.Hit"));
}
if (attacker instanceof Player) {
((Player) attacker).sendMessage(LocaleLoader.getString("Swords.Combat.Counter.Hit"));
}
}
}

View File

@@ -29,7 +29,6 @@ import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class Taming {
private static Random random = new Random();
/**
@@ -37,15 +36,14 @@ public class Taming {
*
* @param PPo The PlayerProfile of the wolf's owner
* @param theWolf The wolf using the ability
* @param event The event to modify
* @param damage The damage being absorbed by the wolf
*/
public static void fastFoodService (PlayerProfile PPo, Wolf theWolf, EntityDamageEvent event) {
public static void fastFoodService (PlayerProfile PPo, Wolf theWolf, int damage) {
final int SKILL_ACTIVATION_LEVEL = 50;
final int ACTIVATION_CHANCE = 50;
int health = theWolf.getHealth();
int maxHealth = theWolf.getMaxHealth();
int damage = event.getDamage();
if (PPo.getSkillLevel(SkillType.TAMING) >= SKILL_ACTIVATION_LEVEL) {
if (health < maxHealth) {
@@ -82,9 +80,8 @@ public class Taming {
* @param PPo The PlayerProfile of the wolf's owner
* @param event The event to modify
* @param master The wolf's master
* @param plugin mcMMO plugin instance
*/
public static void gore(PlayerProfile PPo, EntityDamageEvent event, Player master, mcMMO plugin) {
public static void gore(PlayerProfile PPo, EntityDamageEvent event, Player master) {
final int GORE_MULTIPLIER = 2;
if (random.nextInt(1000) <= PPo.getSkillLevel(SkillType.TAMING)) {
@@ -111,8 +108,7 @@ public class Taming {
AnimalTamer tamer = beast.getOwner();
if (tamer instanceof Player) {
Player owner = (Player) tamer;
return owner.getName();
return ((Player) tamer).getName();
}
else {
return "Offline Master";
@@ -132,6 +128,10 @@ public class Taming {
final int THICK_FUR_MODIFIER = 2;
final int SHOCK_PROOF_MODIFIER = 6;
if (!(event.getEntity() instanceof Wolf)) {
return;
}
DamageCause cause = event.getCause();
Wolf wolf = (Wolf) event.getEntity();
Player master = (Player) wolf.getOwner();
@@ -257,7 +257,7 @@ public class Taming {
player.sendMessage(LocaleLoader.getString("Taming.Summon.Complete"));
}
else {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore")+ " " + ChatColor.GRAY + Misc.prettyItemString(summonItem.getId()));
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GRAY + Misc.prettyItemString(summonItem.getId()));
}
}
}

View File

@@ -16,7 +16,6 @@ import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class Unarmed {
private static Random random = new Random();
/**
@@ -57,7 +56,7 @@ public class Unarmed {
if (random.nextInt(3000) <= skillCheck && !ironGrip(defender, attacker)) {
defender.sendMessage(LocaleLoader.getString("Skills.Disarmed"));
Misc.mcDropItem(defender.getLocation(), inHand);
Misc.dropItem(defender.getLocation(), inHand);
defender.setItemInHand(new ItemStack(Material.AIR));
}
}
@@ -81,7 +80,14 @@ public class Unarmed {
}
}
public static boolean ironGrip(Player defender, Player attacker) {
/**
* Check Iron Grip ability success
*
* @param defender The defending player
* @param attacker The attacking player
* @return true if the defender was not disarmed, false otherwise
*/
private static boolean ironGrip(Player defender, Player attacker) {
final int MAX_BONUS_LEVEL = 1000;
PlayerProfile PPd = Users.getProfile(defender);

View File

@@ -102,7 +102,7 @@ public class Excavation {
//Drop items
for (ItemStack x : is) {
if (x != null) {
Misc.mcDropItem(loc, x);
Misc.dropItem(loc, x);
}
}
}

View File

@@ -187,91 +187,91 @@ public class Fishing {
switch (type) {
case BLAZE:
Misc.mcDropItem(loc, new ItemStack(Material.BLAZE_ROD));
Misc.dropItem(loc, new ItemStack(Material.BLAZE_ROD));
break;
case CAVE_SPIDER:
if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.SPIDER_EYE));
Misc.dropItem(loc, new ItemStack(Material.SPIDER_EYE));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.STRING));
Misc.dropItem(loc, new ItemStack(Material.STRING));
}
break;
case CHICKEN:
if (DROP_NUMBER > 66) {
Misc.mcDropItem(loc, new ItemStack(Material.FEATHER));
Misc.dropItem(loc, new ItemStack(Material.FEATHER));
}
else if (DROP_NUMBER > 33) {
Misc.mcDropItem(loc, new ItemStack(Material.RAW_CHICKEN));
Misc.dropItem(loc, new ItemStack(Material.RAW_CHICKEN));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.EGG));
Misc.dropItem(loc, new ItemStack(Material.EGG));
}
break;
case COW:
if (DROP_NUMBER > 99) {
Misc.mcDropItem(loc, new ItemStack(Material.MILK_BUCKET));
Misc.dropItem(loc, new ItemStack(Material.MILK_BUCKET));
}
else if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.LEATHER));
Misc.dropItem(loc, new ItemStack(Material.LEATHER));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.RAW_BEEF));
Misc.dropItem(loc, new ItemStack(Material.RAW_BEEF));
}
break;
case CREEPER:
Misc.mcDropItem(loc, new ItemStack(Material.SULPHUR));
Misc.dropItem(loc, new ItemStack(Material.SULPHUR));
break;
case ENDERMAN:
Misc.mcDropItem(loc, new ItemStack(Material.ENDER_PEARL));
Misc.dropItem(loc, new ItemStack(Material.ENDER_PEARL));
break;
case GHAST:
if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.SULPHUR));
Misc.dropItem(loc, new ItemStack(Material.SULPHUR));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.GHAST_TEAR));
Misc.dropItem(loc, new ItemStack(Material.GHAST_TEAR));
}
break;
case MAGMA_CUBE:
Misc.mcDropItem(loc, new ItemStack(Material.MAGMA_CREAM));
Misc.dropItem(loc, new ItemStack(Material.MAGMA_CREAM));
break;
case MUSHROOM_COW:
if (DROP_NUMBER > 99) {
Misc.mcDropItem(loc, new ItemStack(Material.MILK_BUCKET));
Misc.dropItem(loc, new ItemStack(Material.MILK_BUCKET));
}
else if (DROP_NUMBER > 98) {
Misc.mcDropItem(loc, new ItemStack(Material.MUSHROOM_SOUP));
Misc.dropItem(loc, new ItemStack(Material.MUSHROOM_SOUP));
}
else if (DROP_NUMBER > 66) {
Misc.mcDropItem(loc, new ItemStack(Material.LEATHER));
Misc.dropItem(loc, new ItemStack(Material.LEATHER));
}
else if (DROP_NUMBER > 33) {
Misc.mcDropItem(loc, new ItemStack(Material.RAW_BEEF));
Misc.dropItem(loc, new ItemStack(Material.RAW_BEEF));
}
else {
Misc.mcDropItems(loc, new ItemStack(Material.RED_MUSHROOM), 3);
Misc.dropItems(loc, new ItemStack(Material.RED_MUSHROOM), 3);
}
break;
case PIG:
Misc.mcDropItem(loc, new ItemStack(Material.PORK));
Misc.dropItem(loc, new ItemStack(Material.PORK));
break;
case PIG_ZOMBIE:
if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.ROTTEN_FLESH));
Misc.dropItem(loc, new ItemStack(Material.ROTTEN_FLESH));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.GOLD_NUGGET));
Misc.dropItem(loc, new ItemStack(Material.GOLD_NUGGET));
}
break;
@@ -285,48 +285,48 @@ public class Fishing {
ItemStack theWool = wool.toItemStack();
theWool.setAmount(1 + random.nextInt(6));
Misc.mcDropItem(loc, theWool);
Misc.dropItem(loc, theWool);
sheep.setSheared(true);
}
break;
case SKELETON:
if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.BONE));
Misc.dropItem(loc, new ItemStack(Material.BONE));
}
else {
Misc.mcDropItems(loc, new ItemStack(Material.ARROW), 3);
Misc.dropItems(loc, new ItemStack(Material.ARROW), 3);
}
break;
case SLIME:
Misc.mcDropItem(loc, new ItemStack(Material.SLIME_BALL));
Misc.dropItem(loc, new ItemStack(Material.SLIME_BALL));
break;
case SNOWMAN:
if (DROP_NUMBER > 99) {
Misc.mcDropItem(loc, new ItemStack(Material.PUMPKIN));
Misc.dropItem(loc, new ItemStack(Material.PUMPKIN));
}
else {
Misc.mcDropItems(loc, new ItemStack(Material.SNOW_BALL), 5);
Misc.dropItems(loc, new ItemStack(Material.SNOW_BALL), 5);
}
break;
case SPIDER:
if (DROP_NUMBER > 50) {
Misc.mcDropItem(loc, new ItemStack(Material.SPIDER_EYE));
Misc.dropItem(loc, new ItemStack(Material.SPIDER_EYE));
}
else {
Misc.mcDropItem(loc, new ItemStack(Material.STRING));
Misc.dropItem(loc, new ItemStack(Material.STRING));
}
break;
case SQUID:
Misc.mcDropItem(loc, new ItemStack(Material.INK_SACK, 1, (short) 0, (byte) 0x0));
Misc.dropItem(loc, new ItemStack(Material.INK_SACK, 1, (short) 0, (byte) 0x0));
break;
case ZOMBIE:
Misc.mcDropItem(loc, new ItemStack(Material.ROTTEN_FLESH));
Misc.dropItem(loc, new ItemStack(Material.ROTTEN_FLESH));
break;
default:

View File

@@ -213,75 +213,75 @@ public class Herbalism {
switch (type) {
case BROWN_MUSHROOM:
if (configInstance.getBrownMushroomsDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case CACTUS:
if (configInstance.getCactiDoubleDropsEnabled()) {
Misc.mcDropItems(loc, is, catciDrops);
Misc.dropItems(loc, is, catciDrops);
}
break;
case CROPS:
if (configInstance.getWheatDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case MELON_BLOCK:
if (configInstance.getMelonsDoubleDropsEnabled()) {
Misc.mcDropItems(loc, is, 3);
Misc.mcRandomDropItems(loc, is, 50, 4);
Misc.dropItems(loc, is, 3);
Misc.randomDropItems(loc, is, 50, 4);
}
break;
case NETHER_WARTS:
if (configInstance.getNetherWartsDoubleDropsEnabled()) {
Misc.mcDropItems(loc, is, 2);
Misc.mcRandomDropItems(loc, is, 50, 3);
Misc.dropItems(loc, is, 2);
Misc.randomDropItems(loc, is, 50, 3);
}
break;
case PUMPKIN:
if (configInstance.getPumpkinsDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case RED_MUSHROOM:
if (configInstance.getRedMushroomsDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case SUGAR_CANE_BLOCK:
if (configInstance.getSugarCaneDoubleDropsEnabled()) {
Misc.mcDropItems(loc, is, caneDrops);
Misc.dropItems(loc, is, caneDrops);
}
break;
case VINE:
if (configInstance.getVinesDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case WATER_LILY:
if (configInstance.getWaterLiliesDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
case YELLOW_FLOWER:
if (configInstance.getYellowFlowersDoubleDropsEnabled()) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
default:
if (customPlant) {
Misc.mcDropItem(loc, is);
Misc.dropItem(loc, is);
}
break;
}
@@ -312,8 +312,8 @@ public class Herbalism {
if (hasSeeds && PP.getAbilityMode(AbilityType.GREEN_TERRA) || hasSeeds && (herbLevel > MAX_BONUS_LEVEL || random.nextInt(1500) <= herbLevel)) {
event.setCancelled(true);
Misc.mcDropItem(loc, new ItemStack(Material.WHEAT));
Misc.mcRandomDropItems(loc, new ItemStack(Material.SEEDS), 50, 3);
Misc.dropItem(loc, new ItemStack(Material.WHEAT));
Misc.randomDropItems(loc, new ItemStack(Material.SEEDS), 50, 3);
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new GreenThumbTimer(block, PP), 1);

View File

@@ -6,29 +6,94 @@ import org.bukkit.CoalType;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.getspout.spoutapi.sound.SoundEffect;
import org.bukkit.enchantments.Enchantment;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.spout.SpoutSounds;
import com.gmail.nossr50.util.BlockChecks;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.ModChecks;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Skills;
import com.gmail.nossr50.util.Users;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.mods.CustomBlocksConfig;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
public class Mining {
private static Random random = new Random();
/**
* Handle double drops when using Silk Touch.
*
* @param block The block to process drops for
*/
private static void silkTouchDrops(Block block) {
Location loc = block.getLocation();
Material type = block.getType();
ItemStack item = new ItemStack(type);
Config configInstance = Config.getInstance();
switch (type) {
case ENDER_STONE:
case GOLD_ORE:
case IRON_ORE:
case MOSSY_COBBLESTONE:
case NETHERRACK:
case OBSIDIAN:
case SANDSTONE:
miningDrops(block);
break;
case COAL_ORE:
if (configInstance.getCoalDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
case DIAMOND_ORE:
if (configInstance.getDiamondDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
case GLOWING_REDSTONE_ORE:
case REDSTONE_ORE:
if (configInstance.getRedstoneDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
case GLOWSTONE:
if (configInstance.getGlowstoneDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
case LAPIS_ORE:
if (configInstance.getLapisDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
case STONE:
if (configInstance.getStoneDoubleDropsEnabled()) {
Misc.dropItem(loc, item);
}
break;
default:
if (ModChecks.isCustomMiningBlock(block)) {
Misc.dropItem(loc, item);
}
break;
}
}
/**
* Drop items from Mining & Blast Mining skills.
*
@@ -44,20 +109,20 @@ public class Mining {
case COAL_ORE:
if (configInstance.getCoalDoubleDropsEnabled()) {
item = new ItemStack(Material.COAL, 1, (short) 0, CoalType.COAL.getData());
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case DIAMOND_ORE:
if (configInstance.getDiamondDoubleDropsEnabled()) {
item = new ItemStack(Material.DIAMOND);
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case ENDER_STONE:
if (configInstance.getEndStoneDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
@@ -65,74 +130,74 @@ public class Mining {
case REDSTONE_ORE:
if (configInstance.getRedstoneDoubleDropsEnabled()) {
item = new ItemStack(Material.REDSTONE);
Misc.mcDropItems(loc, item, 4);
Misc.mcRandomDropItem(loc, item, 50);
Misc.dropItems(loc, item, 4);
Misc.randomDropItem(loc, item, 50);
}
break;
case GLOWSTONE:
if (configInstance.getGlowstoneDoubleDropsEnabled()) {
item = new ItemStack(Material.GLOWSTONE_DUST);
Misc.mcDropItems(loc, item, 2);
Misc.mcRandomDropItems(loc, item, 50, 2);
Misc.dropItems(loc, item, 2);
Misc.randomDropItems(loc, item, 50, 2);
}
break;
case GOLD_ORE:
if (configInstance.getGoldDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case IRON_ORE:
if (configInstance.getIronDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case LAPIS_ORE:
if (configInstance.getLapisDoubleDropsEnabled()) {
item = new ItemStack(Material.INK_SACK, 1, (short) 0, (byte) 0x4);
Misc.mcDropItems(loc, item, 4);
Misc.mcRandomDropItems(loc, item, 50, 4);
Misc.dropItems(loc, item, 4);
Misc.randomDropItems(loc, item, 50, 4);
}
break;
case MOSSY_COBBLESTONE:
if (configInstance.getMossyCobblestoneDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case NETHERRACK:
if (configInstance.getNetherrackDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case OBSIDIAN:
if (configInstance.getObsidianDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case SANDSTONE:
if (configInstance.getSandstoneDoubleDropsEnabled()) {
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
case STONE:
if (configInstance.getStoneDoubleDropsEnabled()) {
item = new ItemStack(Material.COBBLESTONE);
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
default:
if (Config.getInstance().getBlockModsEnabled() && CustomBlocksConfig.getInstance().customMiningBlocks.contains(new ItemStack(block.getTypeId(), 1, (short) 0, block.getData()))) {
if (ModChecks.isCustomMiningBlock(block)) {
item = ModChecks.getCustomBlock(block).getItemDrop();
Misc.mcDropItem(loc, item);
Misc.dropItem(loc, item);
}
break;
}
@@ -204,7 +269,7 @@ public class Mining {
break;
default:
if (Config.getInstance().getBlockModsEnabled() && CustomBlocksConfig.getInstance().customMiningBlocks.contains(new ItemStack(block.getTypeId(), 1, (short) 0, block.getData()))) {
if (ModChecks.isCustomMiningBlock(block)) {
xp += ModChecks.getCustomBlock(block).getXpGain();
}
break;
@@ -221,18 +286,21 @@ public class Mining {
* @param block The block being broken
*/
public static void miningBlockCheck(Player player, Block block) {
if (mcMMO.placeStore.isTrue(block) || player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
if (mcMMO.placeStore.isTrue(block)) {
return;
}
miningXP(player, block);
if (BlockChecks.canBeSuperBroken(block)) {
final int MAX_BONUS_LEVEL = 1000;
final int MAX_BONUS_LEVEL = 1000;
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.MINING);
int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL);
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.MINING);
if ((skillLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= skillLevel) && Permissions.getInstance().miningDoubleDrops(player)) {
if (random.nextInt(1000) <= skillCheck && Permissions.getInstance().miningDoubleDrops(player)) {
if (player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
silkTouchDrops(block);
}
else {
miningDrops(block);
}
}
@@ -244,13 +312,13 @@ public class Mining {
* @param player The player using the ability
* @param block The block being affected
*/
public static void SuperBreakerBlockCheck(Player player, Block block) {
public static void superBreakerBlockCheck(Player player, Block block) {
Material type = block.getType();
int tier = Misc.getTier(player.getItemInHand());
int durabilityLoss = Config.getInstance().getAbilityToolDamage();
FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
if (Config.getInstance().getBlockModsEnabled() && CustomBlocksConfig.getInstance().customItems.contains(new ItemStack(block.getTypeId(), 1, (short) 0, block.getData()))) {
if (ModChecks.isCustomMiningBlock(block)) {
if (ModChecks.getCustomBlock(block).getTier() < tier) {
return;
}

View File

@@ -105,7 +105,7 @@ public class WoodCutting {
x.setData((byte) 0x0);
x.setType(Material.AIR);
Misc.mcDropItem(x.getLocation(), item);
Misc.dropItem(x.getLocation(), item);
}
else if (ModChecks.isCustomLeafBlock(x)) {
final int SAPLING_DROP_CHANCE = 10;
@@ -114,7 +114,7 @@ public class WoodCutting {
x.setData((byte) 0x0);
x.setType(Material.AIR);
Misc.mcRandomDropItem(x.getLocation(), item, SAPLING_DROP_CHANCE);
Misc.randomDropItem(x.getLocation(), item, SAPLING_DROP_CHANCE);
}
}
else if (x.getType() == Material.LOG) {
@@ -172,13 +172,13 @@ public class WoodCutting {
x.setType(Material.AIR);
/* Drop the block */
Misc.mcDropItem(x.getLocation(), item);
Misc.dropItem(x.getLocation(), item);
}
else if (x.getType() == Material.LEAVES) {
final int SAPLING_DROP_CHANCE = 10;
item = new ItemStack(Material.SAPLING, 1, (short) 0, (byte) (x.getData() & 3)); //Drop the right type of sapling
Misc.mcRandomDropItem(x.getLocation(), item, SAPLING_DROP_CHANCE);
Misc.randomDropItem(x.getLocation(), item, SAPLING_DROP_CHANCE);
//Remove the block
x.setData((byte) 0);
@@ -287,7 +287,7 @@ public class WoodCutting {
if (configInstance.getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
item = ModChecks.getCustomBlock(block).getItemDrop();
location = block.getLocation();
Misc.mcDropItem(location, item);
Misc.dropItem(location, item);
return;
}
else {
@@ -299,25 +299,25 @@ public class WoodCutting {
switch (species) {
case GENERIC:
if (configInstance.getOakDoubleDropsEnabled()) {
Misc.mcDropItem(location, item);
Misc.dropItem(location, item);
}
break;
case REDWOOD:
if (configInstance.getSpruceDoubleDropsEnabled()) {
Misc.mcDropItem(location, item);
Misc.dropItem(location, item);
}
break;
case BIRCH:
if (configInstance.getBirchDoubleDropsEnabled()) {
Misc.mcDropItem(location, item);
Misc.dropItem(location, item);
}
break;
case JUNGLE:
if (configInstance.getJungleDoubleDropsEnabled()) {
Misc.mcDropItem(location, item);
Misc.dropItem(location, item);
}
break;

View File

@@ -16,7 +16,6 @@ import com.gmail.nossr50.util.Skills;
import com.gmail.nossr50.util.Users;
public class Acrobatics {
private static Random random = new Random();
/**

View File

@@ -1,614 +0,0 @@
package com.gmail.nossr50.skills.misc;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.mods.CustomArmorConfig;
import com.gmail.nossr50.config.mods.CustomToolsConfig;
import com.gmail.nossr50.spout.SpoutSounds;
import com.gmail.nossr50.util.ItemChecks;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.ModChecks;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Skills;
import com.gmail.nossr50.util.Users;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.datatypes.mods.CustomItem;
import com.gmail.nossr50.events.skills.McMMOPlayerRepairCheckEvent;
import com.gmail.nossr50.locale.LocaleLoader;
public class Repair {
private static Random random = new Random();
private static Config configInstance = Config.getInstance();
private static Permissions permInstance = Permissions.getInstance();
/**
* Handle all the item repair checks.
*
* @param player Player repairing the item
* @param is The item being repaired
*/
public static void repairCheck(Player player, ItemStack is) {
PlayerProfile PP = Users.getProfile(player);
short durabilityBefore = is.getDurability();
PlayerInventory inventory = player.getInventory();
int skillLevel = PP.getSkillLevel(SkillType.REPAIR);
if (durabilityBefore > 0 && is.getAmount() == 1) {
/*
* REPAIR ARMOR
*/
if (ItemChecks.isArmor(is) && permInstance.armorRepair(player)) {
if (ItemChecks.isDiamondArmor(is) && inventory.contains(configInstance.getRepairDiamondMaterial()) && skillLevel >= configInstance.getRepairDiamondLevelRequirement() && permInstance.diamondRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairDiamondMaterial()));
xpHandler(player, PP, is, durabilityBefore, 6);
}
else if (ItemChecks.isIronArmor(is) && inventory.contains(configInstance.getRepairIronMaterial()) && skillLevel >= configInstance.getRepairIronLevelRequirement() && permInstance.ironRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairIronMaterial()));
xpHandler(player, PP, is, durabilityBefore, 2);
}
else if (ItemChecks.isGoldArmor(is) && inventory.contains(configInstance.getRepairGoldMaterial()) && skillLevel >= configInstance.getRepairGoldLevelRequirement() && permInstance.goldRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairGoldMaterial()));
xpHandler(player, PP, is, durabilityBefore, 4);
}
else if (ItemChecks.isLeatherArmor(is) && inventory.contains(configInstance.getRepairLeatherMaterial()) && permInstance.leatherRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairLeatherMaterial()));
xpHandler(player, PP, is, durabilityBefore, 1);
}
else {
needMoreVespeneGas(is, player); //UNABLE TO REPAIR
}
}
/*
* REPAIR TOOLS
*/
else if (ItemChecks.isTool(is) && permInstance.toolRepair(player)) {
if (ItemChecks.isStoneTool(is) && inventory.contains(configInstance.getRepairStoneMaterial()) && skillLevel >= configInstance.getRepairStoneLevelRequirement() && permInstance.stoneRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairStoneMaterial()));
xpHandler(player, PP, is, durabilityBefore, .5);
}
else if (ItemChecks.isWoodTool(is) && inventory.contains(configInstance.getRepairWoodMaterial()) && permInstance.woodRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairWoodMaterial()));
xpHandler(player, PP, is, durabilityBefore, .5);
}
else if (ItemChecks.isIronTool(is) && inventory.contains(configInstance.getRepairIronMaterial()) && skillLevel >= configInstance.getRepairIronLevelRequirement() && permInstance.ironRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairIronMaterial()));
xpHandler(player, PP, is, durabilityBefore, 1);
}
else if (ItemChecks.isDiamondTool(is) && inventory.contains(configInstance.getRepairDiamondMaterial()) && skillLevel >= configInstance.getRepairDiamondLevelRequirement() && permInstance.diamondRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairDiamondMaterial()));
xpHandler(player, PP, is, durabilityBefore, 1);
}
else if (ItemChecks.isGoldTool(is) && inventory.contains(configInstance.getRepairGoldMaterial()) && skillLevel >= configInstance.getRepairGoldLevelRequirement() && permInstance.goldRepair(player)) {
repairItem(player, is, new ItemStack(configInstance.getRepairGoldMaterial()));
xpHandler(player, PP, is, durabilityBefore, 8);
}
else if (ItemChecks.isStringTool(is) && inventory.contains(configInstance.getRepairStringMaterial()) && permInstance.stringRepair(player)){
repairItem(player, is, new ItemStack(configInstance.getRepairStringMaterial()));
xpHandler(player, PP, is, durabilityBefore, .5);
}
else {
needMoreVespeneGas(is, player); //UNABLE TO REPAIR
}
}
/*
* REPAIR CUSTOM TOOLS
*/
else if (ItemChecks.isCustomTool(is) && permInstance.toolRepair(player)) {
CustomToolsConfig toolsInstance = CustomToolsConfig.getInstance();
for (CustomItem tool : toolsInstance.customItems) {
if (tool.getItemID() == is.getTypeId()) {
ItemStack repairMaterial = tool.getRepairMaterial();
if (inventory.contains(repairMaterial)) {
repairCustomItem(player, is, repairMaterial);
xpHandler(player, PP, is, durabilityBefore, 1);
}
else {
needMoreVespeneGas(is, player);
}
break;
}
}
}
/*
* REPAIR CUSTOM ARMOR
*/
else if (ItemChecks.isCustomArmor(is) && permInstance.armorRepair(player)) {
CustomArmorConfig armorInstance = CustomArmorConfig.getInstance();
for (CustomItem armor : armorInstance.customItems) {
if (armor.getItemID() == is.getTypeId()) {
ItemStack repairMaterial = armor.getRepairMaterial();
if (inventory.contains(repairMaterial)) {
repairCustomItem(player, is, repairMaterial);
xpHandler(player, PP, is, durabilityBefore, 1);
}
else {
needMoreVespeneGas(is, player);
}
break;
}
}
}
}
else {
player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability"));
}
}
/**
* Handle the XP gain for repair events.
*
* @param player Player repairing the item
* @param PP PlayerProfile of the repairing player
* @param is Item being repaired
* @param durabilityBefore Durability of the item before repair
* @param modify Amount to modify the durability by
* @param boost True if the modifier is a boost, false if the modifier is a reduction
*/
private static void xpHandler(Player player, PlayerProfile PP, ItemStack is, short durabilityBefore, double modify) {
short durabilityAfter = is.getDurability();
short dif = (short) (durabilityBefore - durabilityAfter);
dif = (short) (dif * modify);
//TODO: What exactly is this for, and should we have it for armor as well?
if (ItemChecks.isShovel(is)) {
dif = (short) (dif / 3);
}
else if(ItemChecks.isSword(is)) {
dif = (short) (dif / 2);
}
else if(ItemChecks.isHoe(is)) {
dif = (short) (dif / 2);
}
PP.addXP(player, SkillType.REPAIR, dif * 10);
Skills.XpCheckSkill(SkillType.REPAIR, player);
//CLANG CLANG
if (configInstance.spoutEnabled) {
SpoutSounds.playRepairNoise(player, mcMMO.p);
}
}
/**
* Get current Arcane Forging rank.
*
* @param skillLevel The skill level of the player whose rank is being checked
* @return The player's current Arcane Forging rank
*/
public static int getArcaneForgingRank(PlayerProfile PP) {
int skillLevel = PP.getSkillLevel(SkillType.REPAIR);
if (skillLevel >= configInstance.getArcaneForgingRankLevels4()) {
return 4;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels3()) {
return 3;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels2()) {
return 2;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels1()) {
return 1;
}
else {
return 0;
}
}
/**
* Handles removing & downgrading enchants.
*
* @param player Player repairing the item
* @param is Item being repaired
*/
private static void addEnchants(Player player, ItemStack is) {
Map<Enchantment, Integer> enchants = is.getEnchantments();
if (enchants.size() == 0) {
return;
}
int rank = getArcaneForgingRank(Users.getProfile(player));
if (rank == 0 || !permInstance.arcaneForging(player)) {
for (Enchantment x : enchants.keySet()) {
is.removeEnchantment(x);
}
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Lost"));
return;
}
boolean downgraded = false;
for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
Enchantment enchantment = enchant.getKey();
if (random.nextInt(100) <= getEnchantChance(rank)) {
int enchantLevel = enchant.getValue();
if (configInstance.getArcaneForgingDowngradeEnabled() && enchantLevel > 1) {
if (random.nextInt(100) <= getDowngradeChance(rank)) {
is.addEnchantment(enchantment, enchantLevel--);
downgraded = true;
}
}
}
else {
is.removeEnchantment(enchantment);
}
}
Map<Enchantment, Integer> newEnchants = is.getEnchantments();
if (newEnchants.isEmpty()) {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Fail"));
}
else if (downgraded || newEnchants.size() < enchants.size()) {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Downgrade"));
}
else {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect"));
}
}
/**
* Gets chance of keeping enchantment during repair.
*
* @param rank Arcane Forging rank
* @return The chance of keeping the enchantment
*/
public static int getEnchantChance(int rank) {
switch (rank) {
case 4:
return configInstance.getArcaneForgingKeepEnchantsChanceRank4();
case 3:
return configInstance.getArcaneForgingKeepEnchantsChanceRank3();
case 2:
return configInstance.getArcaneForgingKeepEnchantsChanceRank2();
case 1:
return configInstance.getArcaneForgingKeepEnchantsChanceRank1();
default:
return 0;
}
}
/**
* Gets chance of enchantment being downgraded during repair.
*
* @param rank Arcane Forging rank
* @return The chance of the enchantment being downgraded
*/
public static int getDowngradeChance(int rank) {
switch (rank) {
case 4:
return configInstance.getArcaneForgingDowngradeChanceRank4();
case 3:
return configInstance.getArcaneForgingDowngradeChanceRank3();
case 2:
return configInstance.getArcaneForgingDowngradeChanceRank2();
case 1:
return configInstance.getArcaneForgingDowngradeChanceRank1();
default:
return 100;
}
}
/**
* Computes repair bonuses.
*
* @param player The player repairing an item
* @param durability The durability of the item being repaired
* @param repairAmount The base amount of durability repaired to the item
* @return The final amount of durability repaired to the item
*/
private static short repairCalculate(Player player, short durability, int repairAmount) {
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.REPAIR);
float bonus = (float) skillLevel / 500;
if (permInstance.repairMastery(player)) {
bonus = (repairAmount * bonus);
repairAmount += bonus;
}
if (checkPlayerProcRepair(player)) {
repairAmount = (short) (repairAmount * 2);
}
durability -= repairAmount;
if (durability < 0) {
durability = 0;
}
return durability;
}
/**
* Gets the base durability amount to repair an item.
*
* @param is The item being repaired
* @param player The player repairing the item
* @return The final amount of durability repaired to the item
*/
private static short getRepairAmount(ItemStack is, Player player){
short maxDurability = is.getType().getMaxDurability();
int repairAmount = 0;
if (ItemChecks.isShovel(is)) {
repairAmount = maxDurability;
}
else if (ItemChecks.isHoe(is) || ItemChecks.isSword(is) || is.getType().equals(Material.SHEARS) || is.getType().equals(Material.FISHING_ROD)) {
repairAmount = maxDurability / 2;
}
else if (ItemChecks.isAxe(is) || ItemChecks.isPickaxe(is) || is.getType().equals(Material.BOW)) {
repairAmount = maxDurability / 3;
}
else if (ItemChecks.isBoots(is)) {
repairAmount = maxDurability / 4;
}
else if (ItemChecks.isHelmet(is)) {
repairAmount = maxDurability / 5;
}
else if (ItemChecks.isPants(is)) {
repairAmount = maxDurability / 7;
}
else if (ItemChecks.isChestplate(is)) {
repairAmount = maxDurability / 8;
}
return repairCalculate(player, is.getDurability(), repairAmount);
}
/**
* Gets the base durability amount to repair a custom item.
*
* @param is The custom item being repaired
* @param player The player repairing the custom item
* @return The final amount of durability repaired to the custom item
*/
private static short getCustomRepairAmount(ItemStack is, Player player) {
short maxDurability = 0;
int materialsRequired = 0;
int repairAmount = 0;
CustomToolsConfig toolInstance = CustomToolsConfig.getInstance();
CustomArmorConfig armorInstance = CustomArmorConfig.getInstance();
if (ModChecks.getToolFromItemStack(is) != null) {
for (CustomItem tool : toolInstance.customItems) {
if (tool.getItemID() == is.getTypeId()) {
maxDurability = tool.getDurability();
materialsRequired = tool.getRepairQuantity();
break;
}
}
}
else if (ModChecks.getArmorFromItemStack(is) != null) {
for (CustomItem armor : armorInstance.customItems) {
if (armor.getItemID() == is.getTypeId()) {
maxDurability = armor.getDurability();
materialsRequired = armor.getRepairQuantity();
break;
}
}
}
repairAmount = maxDurability / materialsRequired;
return repairCalculate(player, is.getDurability(), repairAmount);
}
/**
* Informs a player that the repair has failed.
*
* @param is The item being repaired
* @param player The player repairing the item
*/
private static void needMoreVespeneGas(ItemStack is, Player player) {
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.REPAIR);
if (is.getAmount() != 1) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems"));
}
else {
if (ItemChecks.isDiamondTool(is) || ItemChecks.isDiamondArmor(is)) {
if (skillLevel < configInstance.getRepairDiamondLevelRequirement()) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.AdeptDiamond"));
}
else {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.BLUE + Misc.prettyItemString(configInstance.getRepairDiamondMaterial()));
}
}
else if (ItemChecks.isIronTool(is) || ItemChecks.isIronArmor(is)) {
if (skillLevel < configInstance.getRepairIronLevelRequirement()) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.AdeptIron"));
}
else {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore")+ " " + ChatColor.GRAY + Misc.prettyItemString(configInstance.getRepairIronMaterial()));
}
}
else if (ItemChecks.isGoldTool(is) || ItemChecks.isGoldArmor(is)) {
if (skillLevel < configInstance.getRepairGoldLevelRequirement()) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.AdeptGold"));
}
else {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GOLD + Misc.prettyItemString(configInstance.getRepairGoldMaterial()));
}
}
else if (ItemChecks.isStoneTool(is)) {
if (skillLevel < configInstance.getRepairStoneLevelRequirement()) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.AdeptStone"));
}
else {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GRAY + Misc.prettyItemString(configInstance.getRepairStoneMaterial()));
}
}
else if (ItemChecks.isWoodTool(is)) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.DARK_GREEN + Misc.prettyItemString(configInstance.getRepairWoodMaterial()));
}
else if (ItemChecks.isLeatherArmor(is)) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.YELLOW + Misc.prettyItemString(configInstance.getRepairLeatherMaterial()));
}
else if (ItemChecks.isStringTool(is)) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.YELLOW + Misc.prettyItemString(configInstance.getRepairStringMaterial()));
}
else {
player.sendMessage("You do not have the material needed to repair this item!"); //TODO: Use locale
}
}
}
/**
* Checks for Super Repair bonus.
*
* @param player The player repairing an item
* @return true if bonus granted, false otherwise
*/
public static boolean checkPlayerProcRepair(Player player) {
final int MAX_BONUS_LEVEL = 1000;
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.REPAIR);
if ((skillLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= skillLevel) && permInstance.repairBonus(player)) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.FeltEasy"));
return true;
}
return false;
}
/**
* Repairs an item.
*
* @param player The player repairing an item
* @param item The item being repaired
* @param repairMaterial The repair reagent
*/
private static void repairItem(Player player, ItemStack item, ItemStack repairMaterial) {
short initialDurability = item.getDurability();
short newDurability = getRepairAmount(item, player);
PlayerInventory inventory = player.getInventory();
McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (initialDurability - newDurability), repairMaterial, item);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
if (repairMaterial.getType().equals(Material.WOOD)) {
removeWood(inventory);
}
else {
inventory.removeItem(repairMaterial);
}
/* Handle the enchants */
if (configInstance.getArcaneForgingEnchantLossEnabled() && !permInstance.arcaneBypass(player)) {
addEnchants(player, item);
}
item.setDurability(newDurability);
}
/**
* Repairs a custom item.
*
* @param player The player repairing an item
* @param item The custom item being repaired
* @param repairMaterial The repair reagent
*/
private static void repairCustomItem(Player player, ItemStack item, ItemStack repairMaterial) {
short initialDurability = item.getDurability();
short newDurability = getCustomRepairAmount(item, player);
PlayerInventory inventory = player.getInventory();
McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (initialDurability - newDurability), repairMaterial, item);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
inventory.removeItem(repairMaterial);
if (configInstance.getArcaneForgingEnchantLossEnabled() && !permInstance.arcaneBypass(player)) {
addEnchants(player, item);
}
item.setDurability(newDurability);
}
/**
* Handles notifications for placing an anvil.
*
* @param player The player placing the anvil
* @param anvilID The item ID of the anvil block
*/
public static void placedAnvilCheck(Player player, int anvilID) {
PlayerProfile PP = Users.getProfile(player);
if (!PP.getPlacedAnvil()) {
if (configInstance.spoutEnabled) {
SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
if (sPlayer.isSpoutCraftEnabled()) {
sPlayer.sendNotification("[mcMMO] Anvil Placed", "Right click to repair!", Material.getMaterial(anvilID)); //TODO: Use Locale
}
}
else {
player.sendMessage(LocaleLoader.getString("Repair.Listener.Anvil"));
}
PP.togglePlacedAnvil();
}
}
/**
* Removes wood from a player's inventory on repair. Needed due to wood having multiple possible data values.
*
* @param inventory The inventory to remove wood from
*/
private static void removeWood(PlayerInventory inventory) {
//TODO: Make this less hackish once there's a better way to do it...
int slot = inventory.first(Material.WOOD);
ItemStack item = inventory.getItem(slot);
item.setAmount(item.getAmount() - 1);
inventory.setItem(slot, item);
}
}

View File

@@ -0,0 +1,259 @@
package com.gmail.nossr50.skills.repair;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.spout.SpoutSounds;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Skills;
import com.gmail.nossr50.util.Users;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.locale.LocaleLoader;
public class Repair {
private static Random random = new Random();
private static Config configInstance = Config.getInstance();
private static Permissions permInstance = Permissions.getInstance();
/**
* Handle the XP gain for repair events.
*
* @param player Player repairing the item
* @param PP PlayerProfile of the repairing player
* @param is Item being repaired
* @param durabilityBefore Durability of the item before repair
* @param modify Amount to modify the durability by
* @param boost True if the modifier is a boost, false if the modifier is a reduction
*/
protected static void xpHandler(Player player, PlayerProfile PP, short durabilityBefore, short durabilityAfter, double modify) {
short dif = (short) (durabilityBefore - durabilityAfter);
dif = (short) (dif * modify);
PP.addXP(player, SkillType.REPAIR, dif * 10);
Skills.XpCheckSkill(SkillType.REPAIR, player);
//CLANG CLANG
if (configInstance.spoutEnabled) {
SpoutSounds.playRepairNoise(player, mcMMO.p);
}
}
/**
* Get current Arcane Forging rank.
*
* @param skillLevel The skill level of the player whose rank is being checked
* @return The player's current Arcane Forging rank
*/
public static int getArcaneForgingRank(PlayerProfile PP) {
int skillLevel = PP.getSkillLevel(SkillType.REPAIR);
if (skillLevel >= configInstance.getArcaneForgingRankLevels4()) {
return 4;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels3()) {
return 3;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels2()) {
return 2;
}
else if (skillLevel >= configInstance.getArcaneForgingRankLevels1()) {
return 1;
}
else {
return 0;
}
}
/**
* Handles removing & downgrading enchants.
*
* @param player Player repairing the item
* @param is Item being repaired
*/
protected static void addEnchants(Player player, ItemStack is) {
Map<Enchantment, Integer> enchants = is.getEnchantments();
if (enchants.size() == 0) {
return;
}
int rank = getArcaneForgingRank(Users.getProfile(player));
if (rank == 0 || !permInstance.arcaneForging(player)) {
for (Enchantment x : enchants.keySet()) {
is.removeEnchantment(x);
}
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Lost"));
return;
}
boolean downgraded = false;
for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
Enchantment enchantment = enchant.getKey();
if (random.nextInt(100) <= getEnchantChance(rank)) {
int enchantLevel = enchant.getValue();
if (configInstance.getArcaneForgingDowngradeEnabled() && enchantLevel > 1) {
if (random.nextInt(100) <= getDowngradeChance(rank)) {
is.addEnchantment(enchantment, enchantLevel--);
downgraded = true;
}
}
}
else {
is.removeEnchantment(enchantment);
}
}
Map<Enchantment, Integer> newEnchants = is.getEnchantments();
if (newEnchants.isEmpty()) {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Fail"));
}
else if (downgraded || newEnchants.size() < enchants.size()) {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Downgrade"));
}
else {
player.sendMessage(LocaleLoader.getString("Repair.Arcane.Perfect"));
}
}
/**
* Gets chance of keeping enchantment during repair.
*
* @param rank Arcane Forging rank
* @return The chance of keeping the enchantment
*/
public static int getEnchantChance(int rank) {
switch (rank) {
case 4:
return configInstance.getArcaneForgingKeepEnchantsChanceRank4();
case 3:
return configInstance.getArcaneForgingKeepEnchantsChanceRank3();
case 2:
return configInstance.getArcaneForgingKeepEnchantsChanceRank2();
case 1:
return configInstance.getArcaneForgingKeepEnchantsChanceRank1();
default:
return 0;
}
}
/**
* Gets chance of enchantment being downgraded during repair.
*
* @param rank Arcane Forging rank
* @return The chance of the enchantment being downgraded
*/
public static int getDowngradeChance(int rank) {
switch (rank) {
case 4:
return configInstance.getArcaneForgingDowngradeChanceRank4();
case 3:
return configInstance.getArcaneForgingDowngradeChanceRank3();
case 2:
return configInstance.getArcaneForgingDowngradeChanceRank2();
case 1:
return configInstance.getArcaneForgingDowngradeChanceRank1();
default:
return 100;
}
}
/**
* Computes repair bonuses.
*
* @param player The player repairing an item
* @param skillLevel the skillLevel of the player in Repair
* @param durability The durability of the item being repaired
* @param repairAmount The base amount of durability repaired to the item
* @return The final amount of durability repaired to the item
*/
protected static short repairCalculate(Player player, int skillLevel, short durability, int repairAmount) {
float bonus = (float) skillLevel / 500;
if (permInstance.repairMastery(player)) {
bonus = (repairAmount * bonus);
repairAmount += bonus;
}
if (checkPlayerProcRepair(player)) {
repairAmount = (short) (repairAmount * 2);
}
durability -= repairAmount;
if (durability < 0) {
durability = 0;
}
return durability;
}
/**
* Checks for Super Repair bonus.
*
* @param player The player repairing an item
* @return true if bonus granted, false otherwise
*/
public static boolean checkPlayerProcRepair(Player player) {
final int MAX_BONUS_LEVEL = 1000;
int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.REPAIR);
if ((skillLevel > MAX_BONUS_LEVEL || random.nextInt(1000) <= skillLevel) && permInstance.repairBonus(player)) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.FeltEasy"));
return true;
}
return false;
}
/**
* Handles notifications for placing an anvil.
*
* @param player The player placing the anvil
* @param anvilID The item ID of the anvil block
*/
public static void placedAnvilCheck(Player player, int anvilID) {
PlayerProfile PP = Users.getProfile(player);
if (!PP.getPlacedAnvil()) {
if (configInstance.spoutEnabled) {
SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
if (sPlayer.isSpoutCraftEnabled()) {
sPlayer.sendNotification("[mcMMO] Anvil Placed", "Right click to repair!", Material.getMaterial(anvilID)); //TODO: Use Locale
}
}
else {
player.sendMessage(LocaleLoader.getString("Repair.Listener.Anvil"));
}
PP.togglePlacedAnvil();
}
}
}

View File

@@ -28,6 +28,22 @@ public interface RepairManager {
*/
public boolean isRepairable(int itemId);
/**
* Checks if an item is repairable
*
* @param itemStack Item to check if repairable
* @return true if repairable, false if not
*/
public boolean isRepairable(ItemStack itemStack);
/**
* Gets the repairable with this id
*
* @param id Id of the repairable to look for
* @return the repairable, can be null
*/
public Repairable getRepairable(int id);
/**
* Handle the repairing of this object
*

View File

@@ -67,4 +67,11 @@ public interface Repairable {
* @return the minimum level to repair this item, or 0 for no minimum
*/
public int getMinimumLevel();
/**
* Gets the xpMultiplier for this repairable
*
* @return the xpMultiplier of this repairable
*/
public double getXpMultiplier();
}

View File

@@ -1,8 +1,12 @@
package com.gmail.nossr50.skills.repair;
public class RepairableFactory {
public static Repairable getRepairable(int itemId, int repairMaterialId, byte repairMetadata, int minimumLevel, int minimumQuantity, short maximumDurability, RepairItemType repairItemType, RepairMaterialType repairMaterialType) {
// TODO: Add in loading from config what type of manager we want.
return new SimpleRepairable(itemId, repairMaterialId, repairMetadata, minimumLevel, minimumQuantity, maximumDurability, repairItemType, repairMaterialType);
public static Repairable getRepairable(int itemId, int repairMaterialId, byte repairMetadata, int minimumQuantity, short maximumDurability) {
return getRepairable(itemId, repairMaterialId, repairMetadata, 0, minimumQuantity, maximumDurability, RepairItemType.OTHER, RepairMaterialType.OTHER, 1);
}
public static Repairable getRepairable(int itemId, int repairMaterialId, byte repairMetadata, int minimumLevel, int minimumQuantity, short maximumDurability, RepairItemType repairItemType, RepairMaterialType repairMaterialType, double xpMultiplier) {
// TODO: Add in loading from config what type of repairable we want.
return new SimpleRepairable(itemId, repairMaterialId, repairMetadata, minimumLevel, minimumQuantity, maximumDurability, repairItemType, repairMaterialType, xpMultiplier);
}
}

View File

@@ -3,8 +3,20 @@ package com.gmail.nossr50.skills.repair;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.SkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerRepairCheckEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class SimpleRepairManager implements RepairManager {
private HashMap<Integer, Repairable> repairables;
@@ -35,8 +47,168 @@ public class SimpleRepairManager implements RepairManager {
return repairables.containsKey(itemId);
}
@Override
public boolean isRepairable(ItemStack itemStack) {
return isRepairable(itemStack.getTypeId());
}
@Override
public Repairable getRepairable(int id) {
return repairables.get(id);
}
@Override
public void handleRepair(Player player, ItemStack item) {
// TODO Auto-generated method stub
// Load some variables for use
PlayerProfile PP = Users.getProfile(player);
short startDurability = item.getDurability();
PlayerInventory inventory = player.getInventory();
int skillLevel = PP.getSkillLevel(SkillType.REPAIR);
Repairable repairable = repairables.get(item.getTypeId());
// Permissions checks on material and item types
if(!repairable.getRepairItemType().getPermissions(player)) {
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
return;
}
if(!repairable.getRepairMaterialType().getPermissions(player)) {
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
return;
}
// Level check
if(skillLevel < repairable.getMinimumLevel()) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.Adept", new Object[] { String.valueOf(repairable.getMinimumLevel()), Misc.prettyItemString(item.getTypeId()) } ));
return;
}
// Check if they have the proper material to repair with
if(!inventory.contains(repairable.getRepairMaterialId())) {
String message = LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.YELLOW + Misc.prettyItemString(repairable.getRepairMaterialId());
if(repairable.getRepairMaterialMetadata() != (byte) -1) {
// TODO: Do something nicer than append the metadata as a :# ?
if(findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata()) == -1) {
message += ":" + repairable.getRepairMaterialMetadata();
}
}
player.sendMessage(message);
return;
}
// Do not repair if at full durability
if(startDurability <= 0) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability"));
return;
}
// Do not repair stacked items
if(item.getAmount() != 1) {
player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems"));
return;
}
// Lets get down to business,
// To defeat, the huns.
int baseRepairAmount = repairable.getBaseRepairDurability();
short newDurability = Repair.repairCalculate(player, skillLevel, startDurability, baseRepairAmount);
// We're going to hold onto our repair item location
int repairItemLocation;
if(repairable.getRepairMaterialMetadata() == (byte) -1) {
repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId());
} else {
// Special case for when the repairable has metadata that must be addressed
repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata());
}
// This should never happen, but if it does we need to complain loudly about it.
if(repairItemLocation == -1) {
player.sendMessage("mcMMO encountered an error attempting to repair this item!"); // TODO: Locale ?
return;
}
// Call event
McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (startDurability - newDurability), inventory.getItem(repairItemLocation), item);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
// Handle the enchants
if (Config.getInstance().getArcaneForgingEnchantLossEnabled() && !Permissions.getInstance().arcaneBypass(player)) {
// Generalize away enchantment work
Repair.addEnchants(player, item);
}
// Remove the item
removeOneFrom(inventory, repairItemLocation);
// Give out XP like candy
Repair.xpHandler(player, PP, startDurability, newDurability, repairable.getXpMultiplier());
// Repair the item!
item.setDurability(newDurability);
}
/**
* Decrease the amount of items in this slot by one
*
* @param inventory PlayerInventory to work in
* @param index Item index to decrement
*/
private void removeOneFrom(PlayerInventory inventory, int index) {
ItemStack item = inventory.getItem(index);
if(item.getAmount() > 1) {
item.setAmount(item.getAmount() - 1);
} else {
item = new ItemStack(0);
}
// I suspect this may not be needed, but I don't think it hurts
inventory.setItem(index, item);
}
/**
* Search the inventory for an item and return the index.
*
* @param inventory PlayerInventory to scan
* @param itemId Item id to look for
* @return index location where the item was found, or -1 if not found
*/
private int findInInventory(PlayerInventory inventory, int itemId) {
int location = inventory.first(itemId);
// VALIDATE
if(inventory.getItem(location).getTypeId() == itemId) {
return location;
} else {
return -1;
}
}
/**
* Search the inventory for an item and return the index.
*
* @param inventory PlayerInventory to scan
* @param itemId Item id to look for
* @param metadata Metadata to look for
* @return index location where the item was found, or -1 if not found
*/
private int findInInventory(PlayerInventory inventory, int itemId, byte metadata) {
int location = -1;
ItemStack[] contents = inventory.getContents();
for(int i = 0; i < contents.length; i++) {
ItemStack item = contents[i];
if(item.getTypeId() == itemId) {
if(item.getData().getData() == metadata) {
location = i;
}
}
if(location != -1) break;
}
return location;
}
}

View File

@@ -6,8 +6,9 @@ public class SimpleRepairable implements Repairable {
private final byte repairMetadata;
private final RepairItemType repairItemType;
private final RepairMaterialType repairMaterialType;
private final double xpMultiplier;
protected SimpleRepairable(int itemId, int repairMaterialId, byte repairMetadata, int minimumLevel, int minimumQuantity, short maximumDurability, RepairItemType repairItemType, RepairMaterialType repairMaterialType) {
protected SimpleRepairable(int itemId, int repairMaterialId, byte repairMetadata, int minimumLevel, int minimumQuantity, short maximumDurability, RepairItemType repairItemType, RepairMaterialType repairMaterialType, double xpMultiplier) {
this.itemId = itemId;
this.repairMaterialId = repairMaterialId;
this.repairMetadata = repairMetadata;
@@ -17,6 +18,7 @@ public class SimpleRepairable implements Repairable {
this.minimumQuantity = minimumQuantity;
this.maximumDurability = maximumDurability;
this.baseRepairDurability = (short) (maximumDurability / minimumQuantity);
this.xpMultiplier = xpMultiplier;
}
@Override
@@ -63,4 +65,9 @@ public class SimpleRepairable implements Repairable {
public int getMinimumLevel() {
return minimumLevel;
}
@Override
public double getXpMultiplier() {
return xpMultiplier;
}
}

View File

@@ -1,5 +1,7 @@
package com.gmail.nossr50.util;
import org.bukkit.CropState;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
@@ -158,7 +160,6 @@ public class BlockChecks {
switch (block.getType()) {
case BROWN_MUSHROOM:
case CACTUS:
case CROPS:
case MELON_BLOCK:
case NETHER_WARTS:
case PUMPKIN:
@@ -170,6 +171,14 @@ public class BlockChecks {
case YELLOW_FLOWER:
return true;
case CROPS:
if (block.getData() == CropState.RIPE.getData()) {
return true;
}
else {
return false;
}
default:
if (customBlocksEnabled && CustomBlocksConfig.getInstance().customHerbalismBlocks.contains(new ItemStack(block.getTypeId(), 1, (short) 0, block.getData()))) {
return true;
@@ -263,4 +272,13 @@ public class BlockChecks {
}
}
}
public static boolean isLog (Block block){
if (block.getType().equals(Material.LOG) || (customBlocksEnabled && ModChecks.isCustomLogBlock(block))) {
return true;
}
else {
return false;
}
}
}

View File

@@ -3,12 +3,13 @@ package com.gmail.nossr50.util;
import org.bukkit.Material;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Wolf;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
@@ -51,11 +52,11 @@ public class Combat {
Entity damager = event.getDamager();
LivingEntity target = (LivingEntity) event.getEntity();
EntityType damagerType = damager.getType();
EntityType targetType = target.getType();
switch (damagerType) {
case PLAYER:
boolean targetIsPlayer = target instanceof Player;
boolean targetIsTamedPet = (target instanceof Tameable) ? ((Tameable) target).isTamed() : false;
if (damager instanceof Player) {
Player attacker = (Player) event.getDamager();
ItemStack itemInHand = attacker.getItemInHand();
PlayerProfile PPa = Users.getProfile(attacker);
@@ -64,19 +65,19 @@ public class Combat {
if (ItemChecks.isSword(itemInHand) && permInstance.swords(attacker)) {
if (!configInstance.getSwordsPVP()) {
if (targetType.equals(EntityType.PLAYER) || (targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (targetIsPlayer || targetIsTamedPet) {
return;
}
}
if (!configInstance.getSwordsPVE()) {
if (!targetType.equals(EntityType.PLAYER) || !(targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (!targetIsPlayer || !targetIsTamedPet) {
return;
}
}
if (permInstance.swordsBleed(attacker)) {
Swords.bleedCheck(attacker, target, plugin);
Swords.bleedCheck(attacker, target);
}
if (PPa.getAbilityMode(AbilityType.SERRATED_STRIKES) && permInstance.serratedStrikes(attacker)) {
@@ -88,13 +89,13 @@ public class Combat {
}
else if (ItemChecks.isAxe(itemInHand) && permInstance.axes(attacker)) {
if (!configInstance.getAxesPVP()) {
if (targetType.equals(EntityType.PLAYER) || (targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (targetIsPlayer || targetIsTamedPet) {
return;
}
}
if (!configInstance.getAxesPVE()) {
if (!targetType.equals(EntityType.PLAYER) || !(targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (!targetIsPlayer || !targetIsTamedPet) {
return;
}
}
@@ -119,13 +120,13 @@ public class Combat {
}
else if (itemInHand.getType().equals(Material.AIR) && permInstance.unarmed(attacker)) {
if (!configInstance.getUnarmedPVP()) {
if (targetType.equals(EntityType.PLAYER) || (targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (targetIsPlayer || targetIsTamedPet) {
return;
}
}
if (!configInstance.getUnarmedPVE()) {
if (!targetType.equals(EntityType.PLAYER) || !(targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (!targetIsPlayer || !targetIsTamedPet) {
return;
}
}
@@ -138,7 +139,7 @@ public class Combat {
event.setDamage((int) (event.getDamage() * 1.5));
}
if (targetType.equals(EntityType.PLAYER) && permInstance.disarm(attacker)) {
if (targetIsPlayer && permInstance.disarm(attacker)) {
Unarmed.disarmProcCheck(attacker, (Player) target);
}
@@ -147,9 +148,8 @@ public class Combat {
else if (itemInHand.getType().equals(Material.BONE) && permInstance.beastLore(attacker)) {
Taming.beastLore(event, target, attacker);
}
break;
case WOLF:
}
else if (damager instanceof Wolf) {
Wolf wolf = (Wolf) damager;
if (wolf.isTamed() && wolf.getOwner() instanceof Player) {
@@ -157,66 +157,64 @@ public class Combat {
PlayerProfile PPo = Users.getProfile(master);
if (!configInstance.getTamingPVP()) {
if (targetType.equals(EntityType.PLAYER) || (targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (targetIsPlayer || targetIsTamedPet) {
return;
}
}
if (!configInstance.getTamingPVE()) {
if (!targetType.equals(EntityType.PLAYER) || !(targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (!targetIsPlayer || !targetIsTamedPet) {
return;
}
}
if (permInstance.fastFoodService(master)) {
Taming.fastFoodService(PPo, wolf, event.getDamage());
}
if (permInstance.sharpenedClaws(master)) {
Taming.sharpenedClaws(PPo, event);
}
if (permInstance.gore(master)) {
Taming.gore(PPo, event, master);
}
if (permInstance.taming(master)) {
if (permInstance.fastFoodService(master)) {
Taming.fastFoodService(PPo, wolf, event);
}
if (permInstance.sharpenedClaws(master)) {
Taming.sharpenedClaws(PPo, event);
}
if (permInstance.gore(master)) {
Taming.gore(PPo, event, master, plugin);
}
startGainXp(master, PPo, target, SkillType.TAMING, plugin);
}
}
break;
case ARROW:
if (!configInstance.getArcheryPVP() && ((Arrow) damager).getShooter().getType().equals(EntityType.PLAYER)) {
if (targetType.equals(EntityType.PLAYER) || (targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
}
else if (damager instanceof Projectile) {
if (!configInstance.getArcheryPVP() && ((Projectile) damager).getShooter().getType().equals(EntityType.PLAYER)) {
if (targetIsPlayer || targetIsTamedPet) {
return;
}
}
if (!configInstance.getArcheryPVE() && !((Arrow) damager).getShooter().getType().equals(EntityType.PLAYER)) {
if (!targetType.equals(EntityType.PLAYER) || !(targetType.equals(EntityType.WOLF) && ((Wolf) target).isTamed())) {
if (!configInstance.getArcheryPVE() && !((Projectile) damager).getShooter().getType().equals(EntityType.PLAYER)) {
if (!targetIsPlayer || !targetIsTamedPet) {
return;
}
}
archeryCheck(event, plugin);
break;
}
if (targetType.equals(EntityType.PLAYER)) {
if (configInstance.getSwordsPVP() && damagerType.equals(EntityType.PLAYER)) {
Swords.counterAttackChecks(event);
if (target instanceof Player) {
if (configInstance.getSwordsPVP() && damager instanceof Player) {
Swords.counterAttackChecks(damager, (Player) target, event.getDamage());
}
if (configInstance.getSwordsPVE() && !damagerType.equals(EntityType.PLAYER)) {
Swords.counterAttackChecks(event);
if (configInstance.getSwordsPVE() && !(damager instanceof Player)) {
Swords.counterAttackChecks(damager, (Player) target, event.getDamage());
}
if (configInstance.getAcrobaticsPVP() && damagerType.equals(EntityType.PLAYER)) {
if (configInstance.getAcrobaticsPVP() && damager instanceof Player) {
Acrobatics.dodgeChecks(event);
}
if (configInstance.getAcrobaticsPVE() && !damagerType.equals(EntityType.PLAYER)) {
if (configInstance.getAcrobaticsPVE() && !(damager instanceof Player)) {
Acrobatics.dodgeChecks(event);
}
}
@@ -248,7 +246,7 @@ public class Combat {
* @param pluginx mcMMO plugin instance
*/
public static void archeryCheck(EntityDamageByEntityEvent event, mcMMO pluginx) {
Arrow arrow = (Arrow) event.getDamager();
Projectile arrow = (Projectile) event.getDamager();
LivingEntity shooter = arrow.getShooter();
LivingEntity target = (LivingEntity) event.getEntity();
@@ -290,7 +288,7 @@ public class Combat {
}
if (permInstance.trackArrows(attacker)) {
Archery.trackArrows(pluginx, target, PPa);
Archery.trackArrows(target, PPa);
}
if (target != attacker) {
@@ -368,10 +366,8 @@ public class Combat {
private static void applyAbilityAoE(Player attacker, LivingEntity target, int damage, mcMMO plugin, SkillType type) {
ItemStack inHand = attacker.getItemInHand();
if (Config.getInstance().getToolModsEnabled()) {
if (ItemChecks.isCustomTool(inHand) && !ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
return;
}
if (ModChecks.isCustomTool(inHand) && !ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
return;
}
int numberOfTargets = Misc.getTier(attacker.getItemInHand()); //The higher the weapon tier, the more targets you hit
@@ -390,19 +386,7 @@ public class Combat {
break;
}
switch (entity.getType()) {
case WOLF:
AnimalTamer tamer = ((Wolf) entity).getOwner();
if (tamer instanceof Player) {
if (tamer.equals(attacker) || Party.getInstance().inSameParty(attacker, (Player) tamer)) {
continue;
}
}
break;
case PLAYER:
if (entity instanceof Player) {
Player defender = (Player) entity;
if (!target.getWorld().getPVP()) {
@@ -422,11 +406,14 @@ public class Combat {
if (playerProfile.getGodMode()) {
continue;
}
} else if (entity instanceof Tameable) {
AnimalTamer tamer = ((Tameable) entity).getOwner();
break;
default:
break;
if (tamer instanceof Player) {
if (tamer.equals(attacker) || Party.getInstance().inSameParty(attacker, (Player) tamer)) {
continue;
}
}
}
switch (type) {

View File

@@ -9,33 +9,64 @@ import com.gmail.nossr50.datatypes.SkillType;
public class Hardcore {
public static void invokeStatPenalty(Player player) {
if(Config.getInstance().getHardcoreDeathStatPenaltyPercentage() <= 0)
return;
PlayerProfile PP = Users.getProfile(player);
int totalCount = 0;
for(SkillType st : SkillType.values()) {
if(st.equals(SkillType.ALL))
continue;
int newValue = (int) (PP.getSkillLevel(st) - (PP.getSkillLevel(st) * (Config.getInstance().getHardcoreDeathStatPenaltyPercentage() * 0.01D)));
if(newValue < 0)
newValue = 0;
totalCount+=PP.getSkillLevel(st)-newValue;
PP.modifySkill(st, newValue);
}
player.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.DARK_RED+"You've suffered a penalty to skills from death.");
player.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.DARK_RED+"You've lost "+ChatColor.BLUE+totalCount+ChatColor.DARK_RED+" from death.");
}
public static void invokeVampirism(Player killer, Player defender) {
if(Config.getInstance().getHardcoreVampirismStatLeechPercentage() <= 0)
return;
PlayerProfile PPk = Users.getProfile(killer);
PlayerProfile PPd = Users.getProfile(defender);
int totalCount = 0;
for(SkillType st : SkillType.values()) {
if(st.equals(SkillType.ALL))
continue;
if(PPd.getSkillLevel(st) <= 0 || PPd.getSkillLevel(st) < (PPk.getSkillLevel(st)/2))
continue;
int newValue = (int) (PPd.getSkillLevel(st) * (Config.getInstance().getHardcoreVampirismStatLeechPercentage() * 0.01D));
if(newValue <= 0)
newValue = 1;
totalCount+=1;
PPk.modifySkill(st, newValue+PPk.getSkillLevel(st));
PPd.modifySkill(st, PPd.getSkillLevel(st)-newValue);
}
killer.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.DARK_AQUA+"You've stolen knowledge from that player.");
if(totalCount >= 1) {
killer.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.DARK_AQUA+"You've stolen "+ChatColor.BLUE+totalCount+ChatColor.DARK_AQUA+" levels from that player.");
defender.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.YELLOW+killer.getName()+ChatColor.DARK_RED+" has stolen "+ChatColor.BLUE+totalCount+ChatColor.DARK_RED+" levels from you!");
} else {
killer.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.GRAY+"That player was too unskilled to grant you any knowledge.");
defender.sendMessage(ChatColor.GOLD+"[mcMMO] "+ChatColor.YELLOW+killer.getName()+ChatColor.GRAY+" was unable to steal knowledge from you!");
}
}
}

View File

@@ -242,21 +242,6 @@ public class ItemChecks {
return isLeatherArmor(is) || isGoldArmor(is) || isIronArmor(is) || isDiamondArmor(is);
}
/**
* Checks to see if an item is custom armor.
*
* @param is Item to check
* @return true if the item is custom armor, false otherwise
*/
public static boolean isCustomArmor(ItemStack is) {
if (customArmorEnabled && CustomArmorConfig.getInstance().customIDs.contains(is.getTypeId())) {
return true;
}
else {
return false;
}
}
/**
* Checks to see if an item is a leather armor piece.
*
@@ -343,21 +328,6 @@ public class ItemChecks {
return isStoneTool(is) || isWoodTool(is) || isGoldTool(is) || isIronTool(is) || isDiamondTool(is) || isStringTool(is);
}
/**
* Checks to see if an item is a custom tool.
*
* @param is Item to check
* @return true if the item is a custom tool, false otherwise
*/
public static boolean isCustomTool(ItemStack is) {
if (customToolsEnabled && CustomToolsConfig.getInstance().customIDs.contains(is.getTypeId())) {
return true;
}
else {
return false;
}
}
/**
* Checks to see if an item is a stone tool.
*

View File

@@ -94,7 +94,7 @@ public class Misc {
return false;
}
}
/**
* Simulate a block break event.
*
@@ -146,7 +146,7 @@ public class Misc {
else if (ItemChecks.isDiamondTool(inHand)) {
tier = 4;
}
else if (ItemChecks.isCustomTool(inHand)) {
else if (ModChecks.isCustomTool(inHand)) {
tier = ModChecks.getToolFromItemStack(inHand).getTier();
}
@@ -197,9 +197,9 @@ public class Misc {
* @param is The items to drop
* @param quantity The amount of items to drop
*/
public static void mcDropItems(Location location, ItemStack is, int quantity) {
public static void dropItems(Location location, ItemStack is, int quantity) {
for (int i = 0; i < quantity; i++) {
mcDropItem(location, is);
dropItem(location, is);
}
}
@@ -210,9 +210,9 @@ public class Misc {
* @param is The item to drop
* @param chance The percentage chance for the item to drop
*/
public static void mcRandomDropItem(Location location, ItemStack is, double chance) {
public static void randomDropItem(Location location, ItemStack is, double chance) {
if (random.nextInt(100) < chance) {
mcDropItem(location, is);
dropItem(location, is);
}
}
@@ -224,9 +224,9 @@ public class Misc {
* @param chance The percentage chance for the item to drop
* @param quantity The amount of items to drop
*/
public static void mcRandomDropItems(Location location, ItemStack is, int chance, int quantity) {
public static void randomDropItems(Location location, ItemStack is, int chance, int quantity) {
for(int i = 0; i < quantity; i++) {
mcRandomDropItem(location, is, chance);
randomDropItem(location, is, chance);
}
}
@@ -236,7 +236,7 @@ public class Misc {
* @param location The location to drop the item at
* @param itemStack The item to drop
*/
public static void mcDropItem(Location location, ItemStack itemStack) {
public static void dropItem(Location location, ItemStack itemStack) {
// We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack);
@@ -266,8 +266,10 @@ public class Misc {
}
public static int getPowerLevelCap() {
if (Config.getInstance().getPowerLevelCap() > 0) {
return Config.getInstance().getPowerLevelCap();
int levelCap = Config.getInstance().getPowerLevelCap();
if (levelCap > 0) {
return levelCap;
}
else {
return Integer.MAX_VALUE;

View File

@@ -3,6 +3,7 @@ package com.gmail.nossr50.util;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.mods.CustomBlocksConfig;
import com.gmail.nossr50.config.mods.CustomArmorConfig;
import com.gmail.nossr50.config.mods.CustomToolsConfig;
@@ -11,6 +12,11 @@ import com.gmail.nossr50.datatypes.mods.CustomItem;
import com.gmail.nossr50.datatypes.mods.CustomTool;
public class ModChecks {
private static Config configInstance = Config.getInstance();
private static boolean customToolsEnabled = configInstance.getToolModsEnabled();
private static boolean customArmorEnabled = configInstance.getArmorModsEnabled();
private static boolean customBlocksEnabled = configInstance.getBlockModsEnabled();
private static CustomToolsConfig toolInstance = CustomToolsConfig.getInstance();
private static CustomArmorConfig armorInstance = CustomArmorConfig.getInstance();
private static CustomBlocksConfig blocksInstance = CustomBlocksConfig.getInstance();
@@ -19,44 +25,20 @@ public class ModChecks {
* Get the custom armor associated with an item.
*
* @param item The item to check
* @return the ay if it exists, null otherwise
* @return the armor if it exists, null otherwise
*/
public static CustomItem getArmorFromItemStack(ItemStack item) {
int id = item.getTypeId();
if (!armorInstance.customIDs.contains(id)) {
return null;
}
for (CustomItem armor : armorInstance.customItems) {
if (armor.getItemID() == id) {
return armor;
}
}
return null;
return armorInstance.customArmor.get(item.getTypeId());
}
/**
* Get the custom tool associated with an item.
*
* @param item The item to check
* @return the armor if it exists, null otherwise
* @return the tool if it exists, null otherwise
*/
public static CustomTool getToolFromItemStack(ItemStack item) {
int id = item.getTypeId();
if (!toolInstance.customIDs.contains(id)) {
return null;
}
for (CustomItem tool : toolInstance.customItems) {
if (tool.getItemID() == id) {
return (CustomTool) tool;
}
}
return null;
return toolInstance.customTools.get(item.getTypeId());
}
/**
@@ -79,6 +61,21 @@ public class ModChecks {
return null;
}
/**
* Check if a custom block is a custom block.
*
* @param block The block to check
* @return true if the block is custom, false otherwise
*/
public static boolean isCustomMiningBlock(Block block) {
if (customBlocksEnabled && blocksInstance.customMiningBlocks.contains(new ItemStack(block.getTypeId(), 1, (short) 0, block.getData()))) {
return true;
}
else {
return false;
}
}
/**
* Check if a custom block is a leaf block.
*
@@ -123,4 +120,34 @@ public class ModChecks {
return false;
}
}
/**
* Checks to see if an item is a custom tool.
*
* @param is Item to check
* @return true if the item is a custom tool, false otherwise
*/
public static boolean isCustomTool(ItemStack item) {
if (customToolsEnabled && toolInstance.customTools.containsKey(item.getTypeId())) {
return true;
}
else {
return false;
}
}
/**
* Checks to see if an item is custom armor.
*
* @param is Item to check
* @return true if the item is custom armor, false otherwise
*/
public static boolean isCustomArmor(ItemStack item) {
if (customArmorEnabled && armorInstance.customArmor.containsKey(item.getTypeId())) {
return true;
}
else {
return false;
}
}
}

View File

@@ -1,5 +1,7 @@
package com.gmail.nossr50.util;
import java.util.Random;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
@@ -25,6 +27,8 @@ public class Skills {
private final static int TIME_CONVERSION_FACTOR = 1000;
private final static double MAX_DISTANCE_AWAY = 10.0;
private final static Random random = new Random();
/**
* Checks to see if the cooldown for an item or ability is expired.
*
@@ -264,9 +268,11 @@ public class Skills {
*/
public static SkillType getSkillType(String skillName) {
for (SkillType x : SkillType.values()) {
if (x.toString().equals(skillName.toUpperCase()))
if (x.toString().equals(skillName.toUpperCase())) {
return x;
}
}
return null;
}
@@ -341,14 +347,18 @@ public class Skills {
/**
* Handle tool durability loss from abilities.
*
* @param inhand The item to damage
* @param inHand The item to damage
* @param durabilityLoss The durability to remove from the item
*/
public static void abilityDurabilityLoss(ItemStack inhand, int durabilityLoss) {
public static void abilityDurabilityLoss(ItemStack inHand, int durabilityLoss) {
if (Config.getInstance().getAbilitiesDamageTools()) {
if (!inhand.containsEnchantment(Enchantment.DURABILITY)) {
inhand.setDurability((short) (inhand.getDurability() + durabilityLoss));
if (inHand.containsEnchantment(Enchantment.DURABILITY)) {
int level = inHand.getEnchantmentLevel(Enchantment.DURABILITY);
if (random.nextInt(level + 1) > 0) {
return;
}
}
inHand.setDurability((short) (inHand.getDurability() + durabilityLoss));
}
}
@@ -379,6 +389,9 @@ public class Skills {
}
int ticks = 2 + (PP.getSkillLevel(type) / 50);
if (ability.getMaxTicks() != 0 && ticks > ability.getMaxTicks()) {
ticks = ability.getMaxTicks();
}
if (!PP.getAbilityMode(ability) && cooldownOver(PP.getSkillDATS(ability), ability.getCooldown())) {
player.sendMessage(ability.getAbilityOn());

View File

@@ -1,8 +1,15 @@
package com.gmail.nossr50.util.blockmeta;
import com.gmail.nossr50.config.HiddenConfig;
public class ChunkletManagerFactory {
public static ChunkletManager getChunkletManager() {
// TODO: Add in loading from config what type of manager we want.
return new HashChunkletManager();
HiddenConfig hConfig = HiddenConfig.getInstance();
if(hConfig.getChunkletsEnabled()) {
return new HashChunkletManager();
} else {
return new NullChunkletManager();
}
}
}

View File

@@ -36,25 +36,19 @@ public class HashChunkletManager implements ChunkletManager {
}
public void chunkUnloaded(int cx, int cz, World world) {
boolean found = false;
for(String key : store.keySet()) {
if(key.startsWith(world.getName() + "," + cx + "," + cz)) found = true;
}
if(!found) return;
File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
File cxDir = new File(dataDir, "" + cx);
if(!cxDir.exists()) cxDir.mkdir();
File czDir = new File(cxDir, "" + cz);
if(!czDir.exists()) czDir.mkdir();
for(int y = 1; y <= 4; y++) {
File yFile = new File(czDir, "" + y);
if(store.containsKey(world.getName() + "," + cx + "," + cz + "," + y)) {
File cxDir = new File(dataDir, "" + cx);
if(!cxDir.exists()) cxDir.mkdir();
File czDir = new File(cxDir, "" + cz);
if(!czDir.exists()) czDir.mkdir();
File yFile = new File(czDir, "" + y);
ChunkletStore out = store.get(world.getName() + "," + cx + "," + cz + "," + y);
serializeChunkletStore(out, yFile);
store.remove(world.getName() + "," + cx + "," + cz + "," + y);
}
}
}

View File

@@ -0,0 +1,76 @@
package com.gmail.nossr50.util.blockmeta;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* A ChunkletManager implementation that does nothing and returns false for all checks.
*
* Useful for turning off Chunklets without actually doing much work
*/
public class NullChunkletManager implements ChunkletManager {
@Override
public void chunkLoaded(int cx, int cz, World world) {
return;
}
@Override
public void chunkUnloaded(int cx, int cz, World world) {
return;
}
@Override
public void saveWorld(World world) {
return;
}
@Override
public void unloadWorld(World world) {
return;
}
@Override
public void saveAll() {
return;
}
@Override
public void unloadAll() {
return;
}
@Override
public boolean isTrue(int x, int y, int z, World world) {
return false;
}
@Override
public boolean isTrue(Block block) {
return false;
}
@Override
public void setTrue(int x, int y, int z, World world) {
return;
}
@Override
public void setTrue(Block block) {
return;
}
@Override
public void setFalse(int x, int y, int z, World world) {
return;
}
@Override
public void setFalse(Block block) {
return;
}
@Override
public void cleanUp() {
return;
}
}

View File

@@ -152,24 +152,6 @@ Skills:
Level_Cap: 0
Anvil_Messages: true
Anvil_ID: 42
Leather:
ID: 334
String:
ID: 287
Stone:
Level_Required: 0
ID: 4
Wood:
ID: 5
Gold:
Level_Required: 0
ID: 266
Iron:
Level_Required: 0
ID: 265
Diamond:
Level_Required: 50
ID: 264
Swords:
Enabled_For_PVP: true
Enabled_For_PVE: true

View File

@@ -0,0 +1,7 @@
#
# WARNING: THIS CONFIG IS FOR ADVANCED USERS ONLY.
# You will need to reset any values in this config every time you update mcMMO
###
Options:
# true to use Chunklets metadata store system, false to disable
Chunklets: true

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Nemas dostatek dovednosti pro opravu Diam
Repair.Skills.AdeptGold=[[DARK_RED]]Nemas dostatek dovednosti pro opravu Zlatych predmetu.
Repair.Skills.AdeptIron=[[DARK_RED]]Nejsi dostatecne zkuseny na opravu s Ironem.
Repair.Skills.AdeptStone=[[DARK_RED]]Nemas dostatek dovednosti pro opravu Kamennych predmetu.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[TYWYLL_COCH]] Dydych chi ddim yn ddigon medrus i dr
Repair.Skills.AdeptGold=[[TYWYLL COCH]] Dydych chi ddim yn ddigon medrus i drwsio Aur.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[TYWYLL_COCH]] Dydych chi ddim yn ddigon medrus i drwsio cerrig.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Du er ikke kvalificeret nok til at repare
Repair.Skills.AdeptGold=[[DARK_RED]]Du er ikke kvalificeret nok til at reparere guld.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]Du er ikke kvalificeret nok til at reparere sten.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Deine Fertigkeit ist nicht hoch genug, um
Repair.Skills.AdeptGold=[[DARK_RED]]Deine Fertigkeit ist nicht hoch genug um Gold zu reparieren.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]Deine Fertigkeit ist nicht hoch genug, um Steine zu reparieren.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -212,6 +212,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You're not skilled enough to repair Diamo
Repair.Skills.AdeptGold=[[DARK_RED]]You're not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You're not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You're not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]No tienes la suficiente habilidad para re
Repair.Skills.AdeptGold=[[DARK_RED]]No tienes la suficiente habilidad para reparar Oro.
Repair.Skills.AdeptIron=[[DARK_RED]]No tienes la suficiente habilidad para reparar Hierro.
Repair.Skills.AdeptStone=[[DARK_RED]]No tienes la suficiente habilidad para reparar Piedra.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]Eso ha sido f\u00e1cil.
Repair.Skills.FullDurability=[[GRAY]]Esto est\u00e1 nuevo.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Vous n\'\u00eates pas suffisamment comp\u
Repair.Skills.AdeptGold=[[DARK_RED]]Vous n\'\u00eates pas suffisamment comp\u00e9tent pour r\u00e9parer l\'or.
Repair.Skills.AdeptIron=[[DARK_RED]]Vous n\'\u00eates pas suffisamment comp\u00e9tent pour r\u00e9parer le fer.
Repair.Skills.AdeptStone=[[DARK_RED]]Vous n\'\u00eates pas suffisamment comp\u00e9tent pour r\u00e9parer la pierre.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]Plut\u00f4t facile.
Repair.Skills.FullDurability=[[GRAY]]C\'est d\u00e9j\u00e0 r\u00e9par\u00e9.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Non sei abbastanza abile da riparare il D
Repair.Skills.AdeptGold=[[DARK_RED]]Non sei abbastanza abile da riparare l\'Oro.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]Non sei abbastanza abile da riparare la Pietra.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]\u00c8 gi\u00e0 a piena durevolezza.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]Tas lik\u0101s viegli.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Je bent nog niet sterk genoeg om diamant
Repair.Skills.AdeptGold=[[DARK_RED]]Je bent niet goed genoeg om goud te repareren.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]Je bent nog niet sterk genoeg om steen te repareren.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]Dat ging makkelijk.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]Du er ikke dyktig nok til \u00e5 reparere
Repair.Skills.AdeptGold=[[DARK_RED]]Du er ikke dyktig nok til \u00e5 reparere Gull.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]Du er ikke dyktig nok til \u00e5 reparere stein.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]\u0412\u044b \u043d\u0435\u0434\u043e\u04
Repair.Skills.AdeptGold=[[DARK_RED]]\u0412\u044b \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u043f\u044b\u0442\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0447\u0438\u043d\u0438\u0442\u044c \u0437\u043e\u043b\u043e\u0442\u044b\u0435 \u0432\u0435\u0449\u0438.
Repair.Skills.AdeptIron=[[DARK_RED]]\u0412\u044b \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u043f\u044b\u0442\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0447\u0438\u043d\u0438\u0442\u044c \u0436\u0435\u043b\u0435\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438.
Repair.Skills.AdeptStone=[[DARK_RED]]\u0412\u044b \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u043f\u044b\u0442\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0447\u0438\u043d\u0438\u0442\u044c \u043a\u0430\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0449\u0438.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]\u042d\u0442\u043e \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u043a\u043e.
Repair.Skills.FullDurability=[[GRAY]]\u042d\u0442\u043e \u0443\u0436\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0447\u043d\u043e\u0441\u0442\u044c.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -178,6 +178,7 @@ Repair.Skills.AdeptDiamond=[[DARK_RED]]You\'re not skilled enough to repair Diam
Repair.Skills.AdeptGold=[[DARK_RED]]You\'re not skilled enough to repair Gold.
Repair.Skills.AdeptIron=[[DARK_RED]]You\'re not skilled enough to repair Iron.
Repair.Skills.AdeptStone=[[DARK_RED]]You\'re not skilled enough to repair Stone.
Repair.Skills.Adept=[[RED]]You must be level [[YELLOW]]{0}[[RED]] to repair [[YELLOW]]{1}
Repair.Skills.FeltEasy=[[GRAY]]That felt easy.
Repair.Skills.FullDurability=[[GRAY]]That is at full durability.
Repair.Skills.Mastery=[[RED]]Repair Mastery: [[YELLOW]]Extra {0} durability restored

View File

@@ -0,0 +1,515 @@
#
# Any file named repair.*.yml in the mcmmmo folder will be loaded as a repair config
# All repair configs have a main section titled "Repairables"
# Afterwards, all sub-items are considered a Repairable to be loaded
# The bare minimum of a Repairable is that it have an ItemId, a RepairMaterialId, and a MaximumDurability
#
# ItemId: This is the id of the item to be repairable.
## This is required to be set.
#
# ItemType: This is the type of item to be repaired, this is only important to permissions.
## Valid values are ARMOR, TOOL, and OTHER.
## This defaults to OTHER.
#
# MaterialType: This is the type of the material of the item to be repaired, this is only important for permissions.
## Valid values are STRING, LEATHER, WOOD, STONE, IRON, GOLD, DIAMOND, and OTHER
## This defaults to OTHER.
#
# RepairMaterialId: This is the id of the item used to repair this repairable.
## This is required to be set.
#
# RepairMaterialMetadata: This is the metadata of the item used to repair this repairable.
## A value of -1 means to ignore all metadata when repairing.
## This defaults to -1
#
# MaximumDurability: This is the maximum durability of the item.
## This is required to be set.
#
# MinimumLevel: This is the minimum repair level needed to repair this item.
## Valid values are > 0
## This defaults to 0
#
# MinimumQuantity: This is the minimum number of items needed to repair this item ignoring all other repair bonuses.
## This is typically the number of the repair material needed to create a new item, for example for a sword it is 2, for an axe it is 3
## This defaults to 2
#
# XpMultiplier: This is the amount to multiply the xp bonus by.
## This defaults to 1
#
#
# The following is the default repair config that ships with mcMMO, it contains all vanilla items that are repairable.
#
#
###
Repairables:
#
# Wooden repairables
###
# Tools
WoodSword:
ItemId: 268
ItemType: TOOL
MaterialType: WOOD
RepairMaterialId: 5
RepairMaterialMetadata: -1
MaximumDurability: 59
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .25
WoodShovel:
ItemId: 269
ItemType: TOOL
MaterialType: WOOD
RepairMaterialId: 5
RepairMaterialMetadata: -1
MaximumDurability: 59
MinimumLevel: 0
MinimumQuantity: 1
XpMultiplier: .16
WoodPickaxe:
ItemId: 270
ItemType: TOOL
MaterialType: WOOD
RepairMaterialId: 5
RepairMaterialMetadata: -1
MaximumDurability: 59
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: .5
WoodAxe:
ItemId: 271
ItemType: TOOL
MaterialType: WOOD
RepairMaterialId: 5
RepairMaterialMetadata: -1
MaximumDurability: 59
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: .5
WoodHoe:
ItemId: 290
ItemType: TOOL
MaterialType: WOOD
RepairMaterialId: 5
RepairMaterialMetadata: -1
MaximumDurability: 59
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .25
#
# Stone repairables
###
# Tools
StoneSword:
ItemId: 272
ItemType: TOOL
MaterialType: STONE
RepairMaterialId: 4
RepairMaterialMetadata: -1
MaximumDurability: 131
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .25
StoneShovel:
ItemId: 273
ItemType: TOOL
MaterialType: STONE
RepairMaterialId: 4
RepairMaterialMetadata: -1
MaximumDurability: 131
MinimumLevel: 0
MinimumQuantity: 1
XpMultiplier: .16
StonePickaxe:
ItemId: 274
ItemType: TOOL
MaterialType: STONE
RepairMaterialId: 4
RepairMaterialMetadata: -1
MaximumDurability: 131
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: .5
StoneAxe:
ItemId: 275
ItemType: TOOL
MaterialType: STONE
RepairMaterialId: 4
RepairMaterialMetadata: -1
MaximumDurability: 131
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: .5
StoneHoe:
ItemId: 291
ItemType: TOOL
MaterialType: STONE
RepairMaterialId: 4
RepairMaterialMetadata: -1
MaximumDurability: 131
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .25
#
# Iron repairables
###
# Tools
IronSword:
ItemId: 267
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 250
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .5
IronShovel:
ItemId: 256
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 250
MinimumLevel: 0
MinimumQuantity: 1
XpMultiplier: .3
IronPickaxe:
ItemId: 257
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 250
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: 1
IronAxe:
ItemId: 258
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 250
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: 1
IronHoe:
ItemId: 292
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 250
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .5
Shears:
ItemId: 359
ItemType: TOOL
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 238
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: 1
# Armor
IronHelmet:
ItemId: 306
ItemType: ARMOR
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 165
MinimumLevel: 0
MinimumQuantity: 5
XpMultiplier: 2
IronChest:
ItemId: 307
ItemType: ARMOR
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 240
MinimumLevel: 0
MinimumQuantity: 8
XpMultiplier: 2
IronLegs:
ItemId: 308
ItemType: ARMOR
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 225
MinimumLevel: 0
MinimumQuantity: 7
XpMultiplier: 2
IronBoots:
ItemId: 309
ItemType: ARMOR
MaterialType: IRON
RepairMaterialId: 265
RepairMaterialMetadata: -1
MaximumDurability: 195
MinimumLevel: 0
MinimumQuantity: 4
XpMultiplier: 2
#
# Gold repairables
###
# Tools
GoldSword:
ItemId: 283
ItemType: TOOL
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 32
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: 4
GoldShovel:
ItemId: 284
ItemType: TOOL
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 32
MinimumLevel: 0
MinimumQuantity: 1
XpMultiplier: 2.6
GoldPickaxe:
ItemId: 285
ItemType: TOOL
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 32
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: 8
GoldAxe:
ItemId: 286
ItemType: TOOL
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 32
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: 8
GoldHoe:
ItemId: 294
ItemType: TOOL
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 32
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: 4
# Armor
GoldHelmet:
ItemId: 314
ItemType: ARMOR
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 77
MinimumLevel: 0
MinimumQuantity: 5
XpMultiplier: 4
GoldChest:
ItemId: 315
ItemType: ARMOR
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 112
MinimumLevel: 0
MinimumQuantity: 8
XpMultiplier: 4
GoldLegs:
ItemId: 316
ItemType: ARMOR
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 105
MinimumLevel: 0
MinimumQuantity: 7
XpMultiplier: 4
GoldBoots:
ItemId: 317
ItemType: ARMOR
MaterialType: GOLD
RepairMaterialId: 266
RepairMaterialMetadata: -1
MaximumDurability: 91
MinimumLevel: 0
MinimumQuantity: 4
XpMultiplier: 4
#
# Diamond repairables
###
# Tools
DiamondSword:
ItemId: 276
ItemType: TOOL
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 1561
MinimumLevel: 50
MinimumQuantity: 2
XpMultiplier: .5
DiamondShovel:
ItemId: 277
ItemType: TOOL
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 1561
MinimumLevel: 50
MinimumQuantity: 1
XpMultiplier: .3
DiamondPickaxe:
ItemId: 278
ItemType: TOOL
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 1561
MinimumLevel: 50
MinimumQuantity: 3
XpMultiplier: 1
DiamondAxe:
ItemId: 279
ItemType: TOOL
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 1561
MinimumLevel: 50
MinimumQuantity: 3
XpMultiplier: 1
DiamondHoe:
ItemId: 293
ItemType: TOOL
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 1561
MinimumLevel: 50
MinimumQuantity: 2
XpMultiplier: .5
# Armor
DiamondHelmet:
ItemId: 310
ItemType: ARMOR
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 363
MinimumLevel: 50
MinimumQuantity: 5
XpMultiplier: 6
DiamondChest:
ItemId: 311
ItemType: ARMOR
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 528
MinimumLevel: 50
MinimumQuantity: 8
XpMultiplier: 6
DiamondLegs:
ItemId: 312
ItemType: ARMOR
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 495
MinimumLevel: 50
MinimumQuantity: 7
XpMultiplier: 6
DiamondBoots:
ItemId: 313
ItemType: ARMOR
MaterialType: DIAMOND
RepairMaterialId: 264
RepairMaterialMetadata: -1
MaximumDurability: 429
MinimumLevel: 50
MinimumQuantity: 4
XpMultiplier: 6
#
# Leather repairables
###
# Armor
LeatherHelmet:
ItemId: 298
ItemType: ARMOR
MaterialType: LEATHER
RepairMaterialId: 334
RepairMaterialMetadata: -1
MaximumDurability: 55
MinimumLevel: 0
MinimumQuantity: 5
XpMultiplier: 1
LeatherChest:
ItemId: 299
ItemType: ARMOR
MaterialType: LEATHER
RepairMaterialId: 334
RepairMaterialMetadata: -1
MaximumDurability: 80
MinimumLevel: 0
MinimumQuantity: 8
XpMultiplier: 1
LeatherLegs:
ItemId: 300
ItemType: ARMOR
MaterialType: LEATHER
RepairMaterialId: 334
RepairMaterialMetadata: -1
MaximumDurability: 75
MinimumLevel: 0
MinimumQuantity: 7
XpMultiplier: 1
LeatherBoots:
ItemId: 301
ItemType: ARMOR
MaterialType: LEATHER
RepairMaterialId: 334
RepairMaterialMetadata: -1
MaximumDurability: 65
MinimumLevel: 0
MinimumQuantity: 4
XpMultiplier: 1
#
# String repairables
###
# Tools
FishingRod:
ItemId: 346
ItemType: TOOL
MaterialType: STRING
RepairMaterialId: 287
RepairMaterialMetadata: -1
MaximumDurability: 64
MinimumLevel: 0
MinimumQuantity: 2
XpMultiplier: .5
Bow:
ItemId: 261
ItemType: TOOL
MaterialType: STRING
RepairMaterialId: 287
RepairMaterialMetadata: -1
MaximumDurability: 384
MinimumLevel: 0
MinimumQuantity: 3
XpMultiplier: .5