Update PR to changes in master

- Special thanks, instead of in dev team
- Fix formatting issues
  * Remove trailing whitespaces
  * Rename method names of event listeners
  * Check for negative instead of positive
- Added Alchemy skill guide
This commit is contained in:
TfT_02 2013-12-31 00:30:58 +01:00
parent 8f83e328b0
commit 6143003516
17 changed files with 200 additions and 156 deletions

View File

@ -8,7 +8,7 @@ Key:
- Removal - Removal
Version 1.4.08-dev Version 1.4.08-dev
+ Added new Skill - Alchemy! + Added a new skill; Alchemy. Special thanks to EasyMFnE for creating this!
+ Added SecondaryAbilityType enum, and new SecondaryAbilityWeightedActivationCheckEvent, fired when a secondary ability checkes its activation chances + Added SecondaryAbilityType enum, and new SecondaryAbilityWeightedActivationCheckEvent, fired when a secondary ability checkes its activation chances
+ Added the possibility to gain experience when using Fishing "Shake" + Added the possibility to gain experience when using Fishing "Shake"
+ Added config options to disable various sound effects + Added config options to disable various sound effects

View File

@ -31,12 +31,15 @@ mcMMO is currently developed by a team of individuals from all over the world.
(https://github.com/t00thpick1) (https://github.com/t00thpick1)
[![riking](https://1.gravatar.com/avatar/aca9f37e569ac3a63929920035a91ba4.png)] [![riking](https://1.gravatar.com/avatar/aca9f37e569ac3a63929920035a91ba4.png)]
(https://github.com/riking) (https://github.com/riking)
### Special thanks
[![EasyMFnE](https://www.gravatar.com/avatar/99c9a1fa3bbf957791ceac7b45daadb0.png)] [![EasyMFnE](https://www.gravatar.com/avatar/99c9a1fa3bbf957791ceac7b45daadb0.png)]
(https://github.com/EasyMFnE) (https://github.com/EasyMFnE)
Added the Alchemy skill
## Compiling ## Compiling
mcMMO uses Maven 3 to manage dependancies, packaging, and shading of necessary classes; Maven 3 is required to compile mcMMO. mcMMO uses Maven 3 to manage dependencies, packaging, and shading of necessary classes; Maven 3 is required to compile mcMMO.
The typical command used to build mcMMO is: `mvn clean package install` The typical command used to build mcMMO is: `mvn clean package install`

View File

@ -6,9 +6,11 @@ import java.util.List;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.alchemy.Alchemy.Tier; import com.gmail.nossr50.skills.alchemy.Alchemy.Tier;
import com.gmail.nossr50.skills.alchemy.AlchemyManager;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
@ -27,11 +29,12 @@ public class AlchemyCommand extends SkillCommand {
super(SkillType.ALCHEMY); super(SkillType.ALCHEMY);
} }
protected String[] calculateAbilityDisplayValues(Player player, float skillValue, boolean isLucky) { protected String[] calculateAbilityDisplayValues(Player player, boolean isLucky) {
AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
String[] displayValues = new String[2]; String[] displayValues = new String[2];
displayValues[0] = decimal.format(UserManager.getPlayer(player).getAlchemyManager().getBrewSpeed()) + "x"; displayValues[0] = decimal.format(alchemyManager.getBrewSpeed()) + "x";
displayValues[1] = isLucky ? decimal.format(UserManager.getPlayer(player).getAlchemyManager().getBrewSpeedLucky()) + "x" : null; displayValues[1] = isLucky ? decimal.format(alchemyManager.getBrewSpeedLucky()) + "x" : null;
return displayValues; return displayValues;
} }
@ -40,29 +43,30 @@ public class AlchemyCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue, boolean isLucky) { protected void dataCalculations(Player player, float skillValue, boolean isLucky) {
// CATALYSIS // CATALYSIS
if (canCatalysis) { if (canCatalysis) {
String[] catalysisStrings = calculateAbilityDisplayValues(player, skillValue, isLucky); String[] catalysisStrings = calculateAbilityDisplayValues(player, isLucky);
brewSpeed = catalysisStrings[0]; brewSpeed = catalysisStrings[0];
brewSpeedLucky = catalysisStrings[1]; brewSpeedLucky = catalysisStrings[1];
} }
// CONCOCTIONS // CONCOCTIONS
if (canConcoctions) { if (canConcoctions) {
tier = UserManager.getPlayer(player).getAlchemyManager().getTier(); AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
ingredientCount = UserManager.getPlayer(player).getAlchemyManager().getIngredients().size(); tier = alchemyManager.getTier();
ingredientList = UserManager.getPlayer(player).getAlchemyManager().getIngredientList(); ingredientCount = alchemyManager.getIngredients().size();
ingredientList = alchemyManager.getIngredientList();
} }
} }
@Override @Override
protected void permissionsCheck(Player player) { protected void permissionsCheck(Player player) {
canCatalysis = Permissions.catalysis(player); canCatalysis = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CATALYSIS);
canConcoctions = Permissions.concoctions(player); canConcoctions = Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CONCOCTIONS);
} }
@Override @Override
protected List<String> effectsDisplay() { protected List<String> effectsDisplay() {
List<String> messages = new ArrayList<String>(); List<String> messages = new ArrayList<String>();
if (canCatalysis) { if (canCatalysis) {
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Alchemy.Effect.0"), LocaleLoader.getString("Alchemy.Effect.1"))); messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Alchemy.Effect.0"), LocaleLoader.getString("Alchemy.Effect.1")));
} }
@ -70,7 +74,7 @@ public class AlchemyCommand extends SkillCommand {
if (canConcoctions) { if (canConcoctions) {
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Alchemy.Effect.2"), LocaleLoader.getString("Alchemy.Effect.3"))); messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Alchemy.Effect.2"), LocaleLoader.getString("Alchemy.Effect.3")));
} }
return messages; return messages;
} }

View File

@ -41,7 +41,7 @@ public class PotionConfig extends ConfigLoader {
return instance; return instance;
} }
@Override @Override
protected void loadKeys() { protected void loadKeys() {
loadConcoctions(); loadConcoctions();
@ -59,7 +59,7 @@ public class PotionConfig extends ConfigLoader {
loadConcoctionsTier(concoctionsIngredientsTierSix, concoctionSection.getStringList("Tier_Six_Ingredients")); loadConcoctionsTier(concoctionsIngredientsTierSix, concoctionSection.getStringList("Tier_Six_Ingredients"));
loadConcoctionsTier(concoctionsIngredientsTierSeven, concoctionSection.getStringList("Tier_Seven_Ingredients")); loadConcoctionsTier(concoctionsIngredientsTierSeven, concoctionSection.getStringList("Tier_Seven_Ingredients"));
loadConcoctionsTier(concoctionsIngredientsTierEight, concoctionSection.getStringList("Tier_Eight_Ingredients")); loadConcoctionsTier(concoctionsIngredientsTierEight, concoctionSection.getStringList("Tier_Eight_Ingredients"));
concoctionsIngredientsTierTwo.addAll(concoctionsIngredientsTierOne); concoctionsIngredientsTierTwo.addAll(concoctionsIngredientsTierOne);
concoctionsIngredientsTierThree.addAll(concoctionsIngredientsTierTwo); concoctionsIngredientsTierThree.addAll(concoctionsIngredientsTierTwo);
concoctionsIngredientsTierFour.addAll(concoctionsIngredientsTierThree); concoctionsIngredientsTierFour.addAll(concoctionsIngredientsTierThree);
@ -73,7 +73,7 @@ public class PotionConfig extends ConfigLoader {
if (ingredientStrings != null && ingredientStrings.size() > 0) { if (ingredientStrings != null && ingredientStrings.size() > 0) {
for (String ingredientString : ingredientStrings) { for (String ingredientString : ingredientStrings) {
ItemStack ingredient = loadIngredient(ingredientString); ItemStack ingredient = loadIngredient(ingredientString);
if (ingredient != null) { if (ingredient != null) {
ingredientList.add(ingredient); ingredientList.add(ingredient);
} }
@ -91,7 +91,7 @@ public class PotionConfig extends ConfigLoader {
for (String dataValue : potionSection.getKeys(false)) { for (String dataValue : potionSection.getKeys(false)) {
AlchemyPotion potion = loadPotion(potionSection.getConfigurationSection(dataValue)); AlchemyPotion potion = loadPotion(potionSection.getConfigurationSection(dataValue));
if (potion != null) { if (potion != null) {
potionMap.put(potion.getDataValue(), potion); potionMap.put(potion.getDataValue(), potion);
pass++; pass++;
@ -100,30 +100,31 @@ public class PotionConfig extends ConfigLoader {
fail++; fail++;
} }
} }
mcMMO.p.getLogger().info("Loaded " + pass + " Alchemy potions, skipped " + fail + "."); mcMMO.p.debug("Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
} }
/** /**
* Parse a ConfigurationSection representing a AlchemyPotion. * Parse a ConfigurationSection representing a AlchemyPotion.
* Returns null if input cannot be parsed. * Returns null if input cannot be parsed.
* *
* @param potion_section ConfigurationSection to be parsed. * @param potion_section ConfigurationSection to be parsed.
*
* @return Parsed AlchemyPotion. * @return Parsed AlchemyPotion.
*/ */
private AlchemyPotion loadPotion(ConfigurationSection potion_section) { private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
try { try {
short dataValue = Short.parseShort(potion_section.getName()); short dataValue = Short.parseShort(potion_section.getName());
String name = potion_section.getString("Name"); String name = potion_section.getString("Name");
List<String> lore = new ArrayList<String>(); List<String> lore = new ArrayList<String>();
if (potion_section.contains("Lore")) { if (potion_section.contains("Lore")) {
for (String line : potion_section.getStringList("Lore")) { for (String line : potion_section.getStringList("Lore")) {
lore.add(line); lore.add(line);
} }
} }
List<PotionEffect> effects = new ArrayList<PotionEffect>(); List<PotionEffect> effects = new ArrayList<PotionEffect>();
if (potion_section.contains("Effects")) { if (potion_section.contains("Effects")) {
for (String effect : potion_section.getStringList("Effects")) { for (String effect : potion_section.getStringList("Effects")) {
@ -167,22 +168,25 @@ public class PotionConfig extends ConfigLoader {
* Parse a string representation of an ingredient. * Parse a string representation of an ingredient.
* Format: '&lt;MATERIAL&gt;[:data]' * Format: '&lt;MATERIAL&gt;[:data]'
* Returns null if input cannot be parsed. * Returns null if input cannot be parsed.
* *
* @param ingredient String representing an ingredient. * @param ingredient String representing an ingredient.
*
* @return Parsed ingredient. * @return Parsed ingredient.
*/ */
private ItemStack loadIngredient(String ingredient) { private ItemStack loadIngredient(String ingredient) {
if (ingredient == null || ingredient.isEmpty()) { if (ingredient == null || ingredient.isEmpty()) {
return null; return null;
} }
String[] parts = ingredient.split(":"); String[] parts = ingredient.split(":");
Material material = parts.length > 0 ? Material.getMaterial(parts[0]) : null; Material material = parts.length > 0 ? Material.getMaterial(parts[0]) : null;
short data = parts.length > 1 ? Short.parseShort(parts[1]) : 0; short data = parts.length > 1 ? Short.parseShort(parts[1]) : 0;
if (material != null) { if (material != null) {
return new ItemStack(material, 1, data); return new ItemStack(material, 1, data);
} }
return null; return null;
} }
} }

View File

@ -6,6 +6,10 @@ public enum SecondaryAbility {
GRACEFUL_ROLL, GRACEFUL_ROLL,
ROLL, ROLL,
/* ALCHEMY */
CATALYSIS,
CONCOCTIONS,
/* ARCHERY */ /* ARCHERY */
DAZE, DAZE,
RETRIEVE, RETRIEVE,

View File

@ -36,7 +36,7 @@ import com.google.common.collect.ImmutableList;
public enum SkillType { public enum SkillType {
ACROBATICS(AcrobaticsManager.class, Color.WHITE, ImmutableList.of(SecondaryAbility.DODGE, SecondaryAbility.GRACEFUL_ROLL, SecondaryAbility.ROLL)), ACROBATICS(AcrobaticsManager.class, Color.WHITE, ImmutableList.of(SecondaryAbility.DODGE, SecondaryAbility.GRACEFUL_ROLL, SecondaryAbility.ROLL)),
ALCHEMY(AlchemyManager.class, Color.FUCHSIA, null), ALCHEMY(AlchemyManager.class, Color.FUCHSIA, ImmutableList.of(SecondaryAbility.CATALYSIS, SecondaryAbility.CONCOCTIONS)),
ARCHERY(ArcheryManager.class, Color.MAROON, ImmutableList.of(SecondaryAbility.DAZE, SecondaryAbility.RETRIEVE, SecondaryAbility.SKILL_SHOT)), ARCHERY(ArcheryManager.class, Color.MAROON, ImmutableList.of(SecondaryAbility.DAZE, SecondaryAbility.RETRIEVE, SecondaryAbility.SKILL_SHOT)),
AXES(AxesManager.class, Color.AQUA, AbilityType.SKULL_SPLITTER, ToolType.AXE, ImmutableList.of(SecondaryAbility.ARMOR_IMPACT, SecondaryAbility.AXE_MASTERY, SecondaryAbility.CRITICAL_HIT, SecondaryAbility.GREATER_IMPACT)), AXES(AxesManager.class, Color.AQUA, AbilityType.SKULL_SPLITTER, ToolType.AXE, ImmutableList.of(SecondaryAbility.ARMOR_IMPACT, SecondaryAbility.AXE_MASTERY, SecondaryAbility.CRITICAL_HIT, SecondaryAbility.GREATER_IMPACT)),
EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), AbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL, ImmutableList.of(SecondaryAbility.EXCAVATION_TREASURE_HUNTER)), EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), AbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL, ImmutableList.of(SecondaryAbility.EXCAVATION_TREASURE_HUNTER)),

View File

@ -10,7 +10,7 @@ import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
public class McMMOPlayerBrewEvent extends McMMOPlayerSkillEvent implements Cancellable { public class McMMOPlayerBrewEvent extends McMMOPlayerSkillEvent implements Cancellable {
private Block brewingStand; private Block brewingStand;
private boolean cancelled; private boolean cancelled;
public McMMOPlayerBrewEvent(Player player, Block brewingStand) { public McMMOPlayerBrewEvent(Player player, Block brewingStand) {

View File

@ -8,7 +8,7 @@ import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
public class McMMOPlayerCatalysisEvent extends McMMOPlayerSkillEvent implements Cancellable { public class McMMOPlayerCatalysisEvent extends McMMOPlayerSkillEvent implements Cancellable {
private double speed; private double speed;
private boolean cancelled; private boolean cancelled;
public McMMOPlayerCatalysisEvent(Player player, double speed) { public McMMOPlayerCatalysisEvent(Player player, double speed) {

View File

@ -598,20 +598,21 @@ public class EntityListener implements Listener {
/** /**
* Handle PotionSplash events in order to fix broken Splash Potion of Saturation. * Handle PotionSplash events in order to fix broken Splash Potion of Saturation.
* *
* @param event The event to process * @param event The event to process
*/ */
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPotionSplash(PotionSplashEvent event) { public void onPotionSplash(PotionSplashEvent event) {
for (PotionEffect effect : ((PotionMeta) event.getEntity().getItem().getItemMeta()).getCustomEffects()) { for (PotionEffect effect : ((PotionMeta) event.getEntity().getItem().getItemMeta()).getCustomEffects()) {
// (effect.getType() == PotionEffectType.SATURATION) is seemingly broken, so we use deprecated method for now. // (effect.getType() != PotionEffectType.SATURATION) is seemingly broken, so we use deprecated method for now.
if (effect.getType().getId() == 23) { if (effect.getType().getId() != 23) {
for (LivingEntity entity : event.getAffectedEntities()) { return;
int duration = (int) (effect.getDuration() * event.getIntensity(entity)); }
entity.addPotionEffect(new PotionEffect(effect.getType(), duration, effect.getAmplifier(), effect.isAmbient()));
} for (LivingEntity entity : event.getAffectedEntities()) {
int duration = (int) (effect.getDuration() * event.getIntensity(entity));
entity.addPotionEffect(new PotionEffect(effect.getType(), duration, effect.getAmplifier(), effect.isAmbient()));
} }
return;
} }
} }
} }

View File

@ -136,8 +136,8 @@ public class InventoryListener implements Listener {
event.setExpToDrop(UserManager.getPlayer(player).getSmeltingManager().vanillaXPBoost(event.getExpToDrop())); event.setExpToDrop(UserManager.getPlayer(player).getSmeltingManager().vanillaXPBoost(event.getExpToDrop()));
} }
@EventHandler(ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onAlchemyClickEvent(InventoryClickEvent event) { public void onInventoryClickEventNormal(InventoryClickEvent event) {
if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) { if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) {
return; return;
} }
@ -149,8 +149,8 @@ public class InventoryListener implements Listener {
AlchemyPotionBrewer.handleInventoryClick(event); AlchemyPotionBrewer.handleInventoryClick(event);
} }
@EventHandler(ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onAlchemyDragEvent(InventoryDragEvent event) { public void onInventoryDragEvent(InventoryDragEvent event) {
if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) { if (event.getInventory().getType() != InventoryType.BREWING || !(event.getInventory().getHolder() instanceof BrewingStand)) {
return; return;
} }
@ -162,13 +162,13 @@ public class InventoryListener implements Listener {
AlchemyPotionBrewer.handleInventoryDrag(event); AlchemyPotionBrewer.handleInventoryDrag(event);
} }
@EventHandler(ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onAlchemyMoveItemEvent(InventoryMoveItemEvent event) { public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) {
if (event.getDestination().getType() != InventoryType.BREWING || !(event.getDestination().getHolder() instanceof BrewingStand)) { if (event.getDestination().getType() != InventoryType.BREWING || !(event.getDestination().getHolder() instanceof BrewingStand)) {
return; return;
} }
if (Config.getInstance().getPreventHopperTransfer() && event.getItem() != null && event.getItem().getType() != Material.POTION) { if (Config.getInstance().getPreventHopperTransfer() && event.getItem() != null && event.getItem().getType() != Material.POTION) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }

View File

@ -6,6 +6,7 @@ import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerBrewEvent; import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerBrewEvent;
@ -32,7 +33,7 @@ public class AlchemyBrewTask extends BukkitRunnable {
brewSpeed = DEFAULT_BREW_SPEED; brewSpeed = DEFAULT_BREW_SPEED;
brewTimer = DEFAULT_BREW_TICKS; brewTimer = DEFAULT_BREW_TICKS;
if (player != null && !Misc.isNPCEntity(player) && Permissions.catalysis(player)) { if (player != null && !Misc.isNPCEntity(player) && Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CATALYSIS)) {
double catalysis = UserManager.getPlayer(player).getAlchemyManager().getBrewSpeed(); double catalysis = UserManager.getPlayer(player).getAlchemyManager().getBrewSpeed();
if (Permissions.lucky(player, SkillType.ALCHEMY)) { if (Permissions.lucky(player, SkillType.ALCHEMY)) {

View File

@ -2,13 +2,11 @@ package com.gmail.nossr50.skills.alchemy;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.runnables.skills.AlchemyBrewTask; import com.gmail.nossr50.runnables.skills.AlchemyBrewTask;
public final class Alchemy { public final class Alchemy {
@ -31,7 +29,7 @@ public final class Alchemy {
public int toNumerical() { public int toNumerical() {
return numerical; return numerical;
} }
public static Tier fromNumerical(int numerical) { public static Tier fromNumerical(int numerical) {
for (Tier tier : Tier.values()) { for (Tier tier : Tier.values()) {
if (tier.toNumerical() == numerical) { if (tier.toNumerical() == numerical) {
@ -45,22 +43,21 @@ public final class Alchemy {
return AdvancedConfig.getInstance().getConcoctionsTierLevel(this); return AdvancedConfig.getInstance().getConcoctionsTierLevel(this);
} }
} }
public static int catalysisUnlockLevel = AdvancedConfig.getInstance().getCatalysisUnlockLevel(); public static int catalysisUnlockLevel = AdvancedConfig.getInstance().getCatalysisUnlockLevel();
public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel(); public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel();
public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed(); public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed();
public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed(); public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed();
public static double potionXp = ExperienceConfig.getInstance().getPotionXP();
public static Map<Block, AlchemyBrewTask> brewingStandMap = new HashMap<Block, AlchemyBrewTask>(); public static Map<Block, AlchemyBrewTask> brewingStandMap = new HashMap<Block, AlchemyBrewTask>();
private Alchemy() {}; private Alchemy() {}
/** /**
* Calculate base brewing speed, given a skill level and ignoring all perks. * Calculate base brewing speed, given a skill level and ignoring all perks.
* *
* @param skillLevel Skill level used for calculation. * @param skillLevel Skill level used for calculation.
*
* @return Base brewing speed for the level. * @return Base brewing speed for the level.
*/ */
public static double calculateBrewSpeed(int skillLevel) { public static double calculateBrewSpeed(int skillLevel) {
@ -70,14 +67,14 @@ public final class Alchemy {
return Math.min(catalysisMaxSpeed, catalysisMinSpeed + (catalysisMaxSpeed - catalysisMinSpeed) * (skillLevel - catalysisUnlockLevel) / (catalysisMaxBonusLevel - catalysisUnlockLevel)); return Math.min(catalysisMaxSpeed, catalysisMinSpeed + (catalysisMaxSpeed - catalysisMinSpeed) * (skillLevel - catalysisUnlockLevel) / (catalysisMaxBonusLevel - catalysisUnlockLevel));
} }
/** /**
* Finish all active brews. Used upon Disable to prevent vanilla potions from being brewed upon next Enable. * Finish all active brews. Used upon Disable to prevent vanilla potions from being brewed upon next Enable.
*/ */
public static void finishAllBrews() { public static void finishAllBrews() {
mcMMO.p.getLogger().info("Completing " + brewingStandMap.size() + " unfinished Alchemy brews."); mcMMO.p.debug("Completing " + brewingStandMap.size() + " unfinished Alchemy brews.");
for (Entry<Block, AlchemyBrewTask> entry : brewingStandMap.entrySet()) { for (AlchemyBrewTask alchemyBrewTask : brewingStandMap.values()) {
entry.getValue().finishImmediately(); alchemyBrewTask.finishImmediately();
} }
} }
} }

View File

@ -7,6 +7,7 @@ import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.potion.PotionConfig; import com.gmail.nossr50.config.potion.PotionConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
@ -20,7 +21,11 @@ public class AlchemyManager extends SkillManager {
} }
public boolean canCatalysis() { public boolean canCatalysis() {
return Permissions.catalysis(getPlayer()); return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.CATALYSIS);
}
public boolean canConcoctions() {
return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.CONCOCTIONS);
} }
public boolean canUseIngredient(ItemStack item) { public boolean canUseIngredient(ItemStack item) {
@ -66,21 +71,28 @@ public class AlchemyManager extends SkillManager {
public String getIngredientList() { public String getIngredientList() {
String list = ""; String list = "";
for (ItemStack ingredient : getIngredients()) { for (ItemStack ingredient : getIngredients()) {
list += ", " + StringUtils.getPrettyItemString(ingredient.getType()) + (ingredient.getDurability() != 0 ? ":" + ingredient.getDurability() : ""); String string = StringUtils.getPrettyItemString(ingredient.getType()) + (ingredient.getDurability() != 0 ? ":" + ingredient.getDurability() : "");
if (string.equals("LONG_GRASS:2")) {
string = "Fern";
}
else if (string.equals("RAW_FISH:3")) {
string = "Pufferfish";
}
list += ", " + string;
} }
return list.substring(2); return list.substring(2);
} }
public double getBrewSpeed() { public double getBrewSpeed() {
return Alchemy.calculateBrewSpeed(getSkillLevel()); return Alchemy.calculateBrewSpeed(getSkillLevel());
} }
public double getBrewSpeedLucky() { public double getBrewSpeedLucky() {
return LUCKY_MODIFIER * Alchemy.calculateBrewSpeed(getSkillLevel()); return LUCKY_MODIFIER * Alchemy.calculateBrewSpeed(getSkillLevel());
} }
public void handlePotionBrewSuccesses(int amount) { public void handlePotionBrewSuccesses(int amount) {
applyXpGain((float) (ExperienceConfig.getInstance().getPotionXP() * amount)); applyXpGain((float) (ExperienceConfig.getInstance().getPotionXP() * amount));
} }
} }

View File

@ -21,36 +21,40 @@ import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.potion.PotionConfig; import com.gmail.nossr50.config.potion.PotionConfig;
import com.gmail.nossr50.datatypes.AlchemyPotion; import com.gmail.nossr50.datatypes.AlchemyPotion;
import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
import com.gmail.nossr50.runnables.PlayerUpdateInventoryTask; import com.gmail.nossr50.runnables.PlayerUpdateInventoryTask;
import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask; import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
public final class AlchemyPotionBrewer { public final class AlchemyPotionBrewer {
private final static int[] BOTTLE_SLOTS = new int[] { 0, 1, 2 }; private final static int[] BOTTLE_SLOTS = new int[]{0, 1, 2};
private final static int INGREDIENT_SLOT = 3; private final static int INGREDIENT_SLOT = 3;
public static boolean isValidBrew(Player player, ItemStack[] contents) { public static boolean isValidBrew(Player player, ItemStack[] contents) {
if (isValidIngredient(player, contents[INGREDIENT_SLOT])) { if (!isValidIngredient(player, contents[INGREDIENT_SLOT])) {
for (int bottle : BOTTLE_SLOTS) { return false;
if (contents[bottle] != null && contents[bottle].getType() == Material.POTION) { }
AlchemyPotion potion = PotionConfig.getInstance().potionMap.get(contents[bottle].getDurability());
for (int bottle : BOTTLE_SLOTS) {
if (getChildPotion(potion, contents[INGREDIENT_SLOT]) != null) { if (contents[bottle] != null && contents[bottle].getType() == Material.POTION) {
return true; AlchemyPotion potion = PotionConfig.getInstance().potionMap.get(contents[bottle].getDurability());
}
if (getChildPotion(potion, contents[INGREDIENT_SLOT]) != null) {
return true;
} }
} }
} }
return false; return false;
} }
private static AlchemyPotion getChildPotion(AlchemyPotion potion, ItemStack ingredient) { private static AlchemyPotion getChildPotion(AlchemyPotion potion, ItemStack ingredient) {
if (potion != null && potion.getChildDataValue(ingredient) != -1) { if (potion != null && potion.getChildDataValue(ingredient) != -1) {
return PotionConfig.getInstance().potionMap.get(potion.getChildDataValue(ingredient)); return PotionConfig.getInstance().potionMap.get(potion.getChildDataValue(ingredient));
} }
return null; return null;
} }
@ -60,19 +64,19 @@ public final class AlchemyPotionBrewer {
private static boolean removeIngredient(BrewerInventory inventory, Player player) { private static boolean removeIngredient(BrewerInventory inventory, Player player) {
ItemStack ingredient = inventory.getIngredient(); ItemStack ingredient = inventory.getIngredient();
if (isEmpty(ingredient) || !isValidIngredient(player, ingredient)) { if (isEmpty(ingredient) || !isValidIngredient(player, ingredient)) {
return false; return false;
} }
else if (ingredient.getAmount() <= 1) { else if (ingredient.getAmount() <= 1) {
inventory.setItem(INGREDIENT_SLOT, null); inventory.setItem(INGREDIENT_SLOT, null);
return true; return true;
} }
else { else {
ingredient.setAmount(ingredient.getAmount() - 1); ingredient.setAmount(ingredient.getAmount() - 1);
inventory.setItem(INGREDIENT_SLOT, ingredient); inventory.setItem(INGREDIENT_SLOT, ingredient);
return true; return true;
} }
} }
@ -81,21 +85,21 @@ public final class AlchemyPotionBrewer {
if (isEmpty(item)) { if (isEmpty(item)) {
return false; return false;
} }
for (ItemStack ingredient : getValidIngredients(player)) { for (ItemStack ingredient : getValidIngredients(player)) {
if (item.isSimilar(ingredient)) { if (item.isSimilar(ingredient)) {
return true; return true;
} }
} }
return false; return false;
} }
private static List<ItemStack> getValidIngredients(Player player) { private static List<ItemStack> getValidIngredients(Player player) {
if (player == null || !Permissions.concoctions(player)) { if (player == null || !Permissions.secondaryAbilityEnabled(player, SecondaryAbility.CONCOCTIONS)) {
return PotionConfig.getInstance().concoctionsIngredientsTierOne; return PotionConfig.getInstance().concoctionsIngredientsTierOne;
} }
switch (UserManager.getPlayer(player).getAlchemyManager().getTier()) { switch (UserManager.getPlayer(player).getAlchemyManager().getTier()) {
case 5: case 5:
return PotionConfig.getInstance().concoctionsIngredientsTierFive; return PotionConfig.getInstance().concoctionsIngredientsTierFive;
@ -114,38 +118,38 @@ public final class AlchemyPotionBrewer {
if (!(brewingStand.getState() instanceof BrewingStand)) { if (!(brewingStand.getState() instanceof BrewingStand)) {
return; return;
} }
BrewerInventory inventory = ((BrewingStand) brewingStand.getState()).getInventory(); BrewerInventory inventory = ((BrewingStand) brewingStand.getState()).getInventory();
ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone(); ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
if (removeIngredient(inventory, player)) { if (!removeIngredient(inventory, player)) {
for (int bottle : BOTTLE_SLOTS) { return;
if (!isEmpty(inventory.getItem(bottle)) && PotionConfig.getInstance().potionMap.containsKey(inventory.getItem(bottle).getDurability())) { }
AlchemyPotion input = PotionConfig.getInstance().potionMap.get(inventory.getItem(bottle).getDurability());
AlchemyPotion output = PotionConfig.getInstance().potionMap.get(input.getChildDataValue(ingredient)); for (int bottle : BOTTLE_SLOTS) {
if (!isEmpty(inventory.getItem(bottle)) && PotionConfig.getInstance().potionMap.containsKey(inventory.getItem(bottle).getDurability())) {
if (output != null) { AlchemyPotion input = PotionConfig.getInstance().potionMap.get(inventory.getItem(bottle).getDurability());
inventory.setItem(bottle, output.toItemStack(inventory.getItem(bottle).getAmount()).clone()); AlchemyPotion output = PotionConfig.getInstance().potionMap.get(input.getChildDataValue(ingredient));
if (player != null) { if (output != null) {
UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(1); inventory.setItem(bottle, output.toItemStack(inventory.getItem(bottle).getAmount()).clone());
}
if (player != null) {
UserManager.getPlayer(player).getAlchemyManager().handlePotionBrewSuccesses(1);
} }
} }
} }
}
if (!forced) {
scheduleUpdate(inventory); if (!forced) {
} scheduleUpdate(inventory);
return;
} }
} }
private static boolean transferOneItem(InventoryView view, int fromSlot, int toSlot) { private static boolean transferOneItem(InventoryView view, int fromSlot, int toSlot) {
ItemStack from = view.getItem(fromSlot).clone(); ItemStack from = view.getItem(fromSlot).clone();
ItemStack to = view.getItem(toSlot).clone(); ItemStack to = view.getItem(toSlot).clone();
if (isEmpty(from)) { if (isEmpty(from)) {
return false; return false;
} }
@ -160,14 +164,14 @@ public final class AlchemyPotionBrewer {
else { else {
to.setAmount(to.getAmount() + 1); to.setAmount(to.getAmount() + 1);
} }
from.setAmount(from.getAmount() - 1); from.setAmount(from.getAmount() - 1);
view.setItem(toSlot, isEmpty(to) ? null : to); view.setItem(toSlot, isEmpty(to) ? null : to);
view.setItem(fromSlot, isEmpty(from) ? null : from); view.setItem(fromSlot, isEmpty(from) ? null : from);
return true; return true;
} }
return false; return false;
} }
@ -181,29 +185,29 @@ public final class AlchemyPotionBrewer {
else if (isEmpty(view.getItem(toSlot))) { else if (isEmpty(view.getItem(toSlot))) {
view.setItem(toSlot, view.getItem(fromSlot).clone()); view.setItem(toSlot, view.getItem(fromSlot).clone());
view.setItem(fromSlot, null); view.setItem(fromSlot, null);
return true; return true;
} }
else if (view.getItem(fromSlot).isSimilar(view.getItem(toSlot))) { else if (view.getItem(fromSlot).isSimilar(view.getItem(toSlot))) {
if (view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() > view.getItem(toSlot).getType().getMaxStackSize()) { if (view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() > view.getItem(toSlot).getType().getMaxStackSize()) {
int left = view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() - view.getItem(toSlot).getType().getMaxStackSize(); int left = view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount() - view.getItem(toSlot).getType().getMaxStackSize();
ItemStack to = new ItemStack(view.getItem(toSlot)); ItemStack to = new ItemStack(view.getItem(toSlot));
to.setAmount(to.getType().getMaxStackSize()); to.setAmount(to.getType().getMaxStackSize());
view.setItem(toSlot, to); view.setItem(toSlot, to);
ItemStack from = new ItemStack(view.getItem(fromSlot)); ItemStack from = new ItemStack(view.getItem(fromSlot));
from.setAmount(left); from.setAmount(left);
view.setItem(fromSlot, from); view.setItem(fromSlot, from);
return true; return true;
} }
ItemStack to = new ItemStack(view.getItem(toSlot)); ItemStack to = new ItemStack(view.getItem(toSlot));
to.setAmount(view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount()); to.setAmount(view.getItem(fromSlot).getAmount() + view.getItem(toSlot).getAmount());
view.setItem(fromSlot, null); view.setItem(fromSlot, null);
view.setItem(toSlot, to); view.setItem(toSlot, to);
return true; return true;
} }
return false; return false;
@ -214,12 +218,13 @@ public final class AlchemyPotionBrewer {
} }
private static void scheduleUpdate(Inventory inventory) { private static void scheduleUpdate(Inventory inventory) {
for (HumanEntity he : inventory.getViewers()) { for (HumanEntity humanEntity : inventory.getViewers()) {
if (he instanceof Player) { if (humanEntity instanceof Player) {
scheduleUpdate((Player) he); scheduleUpdate((Player) humanEntity);
} }
} }
} }
private static void scheduleUpdate(Player player) { private static void scheduleUpdate(Player player) {
Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, new PlayerUpdateInventoryTask(player)); Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, new PlayerUpdateInventoryTask(player));
} }
@ -227,19 +232,19 @@ public final class AlchemyPotionBrewer {
public static void handleInventoryClick(InventoryClickEvent event) { public static void handleInventoryClick(InventoryClickEvent event) {
Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null; Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null;
BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder(); BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder();
ItemStack cursor = event.getCursor(); ItemStack cursor = event.getCursor();
ItemStack clicked = event.getCurrentItem(); ItemStack clicked = event.getCurrentItem();
if (clicked != null && clicked.getType() == Material.POTION) { if (clicked != null && clicked.getType() == Material.POTION) {
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
if (event.isShiftClick()) { if (event.isShiftClick()) {
if (event.getSlotType() == SlotType.FUEL) { if (event.getSlotType() == SlotType.FUEL) {
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
else if (event.getSlotType() == SlotType.CONTAINER || event.getSlotType() == SlotType.QUICKBAR) { else if (event.getSlotType() == SlotType.CONTAINER || event.getSlotType() == SlotType.QUICKBAR) {
@ -250,12 +255,12 @@ public final class AlchemyPotionBrewer {
else if (event.isRightClick()) { else if (event.isRightClick()) {
transferOneItem(event.getView(), event.getRawSlot(), INGREDIENT_SLOT); transferOneItem(event.getView(), event.getRawSlot(), INGREDIENT_SLOT);
} }
event.setCancelled(true); event.setCancelled(true);
scheduleUpdate(brewingStand.getInventory()); scheduleUpdate(brewingStand.getInventory());
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
} }
@ -266,37 +271,37 @@ public final class AlchemyPotionBrewer {
} }
else if (isEmpty(cursor)) { else if (isEmpty(cursor)) {
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
else if (isEmpty(clicked)) { else if (isEmpty(clicked)) {
if (isValidIngredient(player, event.getCursor())) { if (isValidIngredient(player, event.getCursor())) {
if (event.getClick() == ClickType.LEFT || (event.getClick() == ClickType.RIGHT && event.getCursor().getAmount() == 1)) { if (event.getClick() == ClickType.LEFT || (event.getClick() == ClickType.RIGHT && event.getCursor().getAmount() == 1)) {
event.setCancelled(true); event.setCancelled(true);
event.setCurrentItem(event.getCursor().clone()); event.setCurrentItem(event.getCursor().clone());
event.setCursor(null); event.setCursor(null);
scheduleUpdate(brewingStand.getInventory()); scheduleUpdate(brewingStand.getInventory());
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
else if (event.getClick() == ClickType.RIGHT) { else if (event.getClick() == ClickType.RIGHT) {
event.setCancelled(true); event.setCancelled(true);
ItemStack one = event.getCursor().clone(); ItemStack one = event.getCursor().clone();
one.setAmount(1); one.setAmount(1);
ItemStack rest = event.getCursor().clone(); ItemStack rest = event.getCursor().clone();
rest.setAmount(event.getCursor().getAmount() - 1); rest.setAmount(event.getCursor().getAmount() - 1);
event.setCurrentItem(one); event.setCurrentItem(one);
event.setCursor(rest); event.setCursor(rest);
scheduleUpdate(brewingStand.getInventory()); scheduleUpdate(brewingStand.getInventory());
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
} }
@ -308,41 +313,44 @@ public final class AlchemyPotionBrewer {
public static void handleInventoryDrag(InventoryDragEvent event) { public static void handleInventoryDrag(InventoryDragEvent event) {
Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null; Player player = event.getWhoClicked() instanceof Player ? (Player) event.getWhoClicked() : null;
BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder(); BrewingStand brewingStand = (BrewingStand) event.getInventory().getHolder();
ItemStack cursor = event.getCursor(); ItemStack cursor = event.getCursor();
ItemStack ingredient = brewingStand.getInventory().getIngredient(); ItemStack ingredient = brewingStand.getInventory().getIngredient();
if (event.getInventorySlots().contains(INGREDIENT_SLOT)) { if (!event.getInventorySlots().contains(INGREDIENT_SLOT)) {
if (isEmpty(ingredient) || ingredient.isSimilar(cursor)) { return;
if (isValidIngredient(player, cursor)) { }
// Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
scheduleCheck(player, brewingStand); if (isEmpty(ingredient) || ingredient.isSimilar(cursor)) {
if (isValidIngredient(player, cursor)) {
return; // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
} scheduleCheck(player, brewingStand);
else {
event.setCancelled(true); return;
}
scheduleUpdate(brewingStand.getInventory()); else {
event.setCancelled(true);
return;
} scheduleUpdate(brewingStand.getInventory());
return;
} }
} }
} }
public static void handleInventoryMoveItem(InventoryMoveItemEvent event) { public static void handleInventoryMoveItem(InventoryMoveItemEvent event) {
Player player = null; Player player = null;
BrewingStand brewingStand = (BrewingStand) event.getDestination().getHolder(); BrewingStand brewingStand = (BrewingStand) event.getDestination().getHolder();
if (isValidIngredient(player, event.getItem())) { if (isValidIngredient(player, event.getItem())) {
scheduleCheck(player, brewingStand); scheduleCheck(player, brewingStand);
return; return;
} }
else { else {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} }

View File

@ -40,7 +40,7 @@ Alchemy.Effect.3=Brew potions with more ingredients
Alchemy.Listener=Alchemy: Alchemy.Listener=Alchemy:
Alchemy.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (CATALYSIS) Alchemy.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (CATALYSIS)
Alchemy.Catalysis.Speed=[[RED]]Brewing Speed: [[YELLOW]]{0} Alchemy.Catalysis.Speed=[[RED]]Brewing Speed: [[YELLOW]]{0}
Alchemy.Concoctions.Rank=[[RED]]Concoctions Rank: [[YELLOW]]{0} Alchemy.Concoctions.Rank=[[RED]]Concoctions Rank: [[YELLOW]]{0}/{1}
Alchemy.Concoctions.Ingredients=[[RED]]Ingredients [[[YELLOW]]{0}[[RED]]]: [[YELLOW]]{1} Alchemy.Concoctions.Ingredients=[[RED]]Ingredients [[[YELLOW]]{0}[[RED]]]: [[YELLOW]]{1}
Alchemy.SkillName=ALCHEMY Alchemy.SkillName=ALCHEMY
Alchemy.Skillup=[[YELLOW]]Alchemy skill increased by {0}. Total ({1}) Alchemy.Skillup=[[YELLOW]]Alchemy skill increased by {0}. Total ({1})
@ -421,7 +421,7 @@ Combat.TouchedFuzzy=[[DARK_RED]]Touched Fuzzy. Felt Dizzy.
#COMMANDS #COMMANDS
##generic ##generic
mcMMO.Description=[[DARK_AQUA]]About the [[YELLOW]]mcMMO[[DARK_AQUA]] Project:,[[GOLD]]mcMMO is an [[RED]]open source[[GOLD]] RPG mod created in February 2011,[[GOLD]]by [[BLUE]]nossr50[[GOLD]]. The goal is to provide a quality RPG experience.,[[DARK_AQUA]]Tips:,[[GOLD]] - [[GREEN]]Use [[RED]]/mcmmo help[[GREEN]] to see commands,[[GOLD]] - [[GREEN]]Type [[RED]]/SKILLNAME[[GREEN]] to see detailed skill info,[[DARK_AQUA]]Developers:,[[GOLD]] - [[GREEN]]nossr50 [[BLUE]](Founder),[[GOLD]] - [[GREEN]]GJ [[BLUE]](Project Lead),[[GOLD]] - [[GREEN]]NuclearW [[BLUE]](Developer),[[GOLD]] - [[GREEN]]bm01 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]TfT_02 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]Glitchfinder [[BLUE]](Developer),[[GOLD]] - [[GREEN]]t00thpick1 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]EasyMFnE [[BLUE]](Developer),[[DARK_AQUA]]Useful Links:,[[GOLD]] - [[GREEN]]https://github.com/mcMMO-Dev/mcMMO/issues[[GOLD]] Bug Reporting,[[GOLD]] - [[GREEN]]#mcmmo @ irc.esper.net[[GOLD]] IRC Chat, mcMMO.Description=[[DARK_AQUA]]About the [[YELLOW]]mcMMO[[DARK_AQUA]] Project:,[[GOLD]]mcMMO is an [[RED]]open source[[GOLD]] RPG mod created in February 2011,[[GOLD]]by [[BLUE]]nossr50[[GOLD]]. The goal is to provide a quality RPG experience.,[[DARK_AQUA]]Tips:,[[GOLD]] - [[GREEN]]Use [[RED]]/mcmmo help[[GREEN]] to see commands,[[GOLD]] - [[GREEN]]Type [[RED]]/SKILLNAME[[GREEN]] to see detailed skill info,[[DARK_AQUA]]Developers:,[[GOLD]] - [[GREEN]]nossr50 [[BLUE]](Founder),[[GOLD]] - [[GREEN]]GJ [[BLUE]](Project Lead),[[GOLD]] - [[GREEN]]NuclearW [[BLUE]](Developer),[[GOLD]] - [[GREEN]]bm01 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]TfT_02 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]Glitchfinder [[BLUE]](Developer),[[GOLD]] - [[GREEN]]t00thpick1 [[BLUE]](Developer),[[DARK_AQUA]]Useful Links:,[[GOLD]] - [[GREEN]]https://github.com/mcMMO-Dev/mcMMO/issues[[GOLD]] Bug Reporting,[[GOLD]] - [[GREEN]]#mcmmo @ irc.esper.net[[GOLD]] IRC Chat,
Commands.addlevels.AwardAll.1=[[GREEN]]You were awarded {0} levels in all skills! Commands.addlevels.AwardAll.1=[[GREEN]]You were awarded {0} levels in all skills!
Commands.addlevels.AwardAll.2=[[RED]]All skills have been modified for {0}. Commands.addlevels.AwardAll.2=[[RED]]All skills have been modified for {0}.
Commands.addlevels.AwardSkill.1=[[GREEN]]You were awarded {0} levels in {1}! Commands.addlevels.AwardSkill.1=[[GREEN]]You were awarded {0} levels in {1}!
@ -669,6 +669,15 @@ Guides.Acrobatics.Section.0=[[DARK_AQUA]]About Acrobatics:\n[[YELLOW]]Acrobatics
Guides.Acrobatics.Section.1=[[DARK_AQUA]]How does Rolling work?\n[[YELLOW]]You have a passive chance when you take fall damage\n[[YELLOW]]to negate the damage done. You can hold the sneak button to\n[[YELLOW]]double your chances during the fall.\n[[YELLOW]]This triggers a Graceful Roll instead of a standard one.\n[[YELLOW]]Graceful Rolls are like regular rolls but are twice as likely to\n[[YELLOW]]occur and provide more damage safety than regular rolls.\n[[YELLOW]]Rolling chance is tied to your skill level Guides.Acrobatics.Section.1=[[DARK_AQUA]]How does Rolling work?\n[[YELLOW]]You have a passive chance when you take fall damage\n[[YELLOW]]to negate the damage done. You can hold the sneak button to\n[[YELLOW]]double your chances during the fall.\n[[YELLOW]]This triggers a Graceful Roll instead of a standard one.\n[[YELLOW]]Graceful Rolls are like regular rolls but are twice as likely to\n[[YELLOW]]occur and provide more damage safety than regular rolls.\n[[YELLOW]]Rolling chance is tied to your skill level
Guides.Acrobatics.Section.2=[[DARK_AQUA]]How does Dodge work?\n[[YELLOW]]Dodge is a passive chance when you are\n[[YELLOW]]injured in combat to halve the damage taken.\n[[YELLOW]]It is tied to your skill level. Guides.Acrobatics.Section.2=[[DARK_AQUA]]How does Dodge work?\n[[YELLOW]]Dodge is a passive chance when you are\n[[YELLOW]]injured in combat to halve the damage taken.\n[[YELLOW]]It is tied to your skill level.
##Alchemy
Guides.Alchemy.Section.0=[[DARK_AQUA]]About Alchemy:\n[[YELLOW]]Alchemy is about brewing potions.\n[[YELLOW]]It provides a speed increase in the potion brew time, as well\n[[YELLOW]]as the addition of new (previously) unobtainable potions.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to brew potions.
Guides.Alchemy.Section.1=[[DARK_AQUA]]How does Catalysis work?\n[[YELLOW]]Catalysis speeds of the brewing process, with a\n[[YELLOW]]max speed of 4x at level 1000.\n[[YELLOW]]This ability is unlocked at level 100 by default.
Guides.Alchemy.Section.2=[[DARK_AQUA]]How does Concoctions work?\n[[YELLOW]]Concoctions allows brewing of more potions with custom ingredients.\n[[YELLOW]]Which special ingredients are unlocked is determined\n[[YELLOW]]by your Rank. There are 8 ranks to unlock.
Guides.Alchemy.Section.3=[[DARK_AQUA]]Concotions tier 1 ingredients:\n[[YELLOW]]Blaze Powder, Fermented Spider Eye, Ghast Tear, Redstone,\n[[YELLOW]]Glowstone Dust, Sugar, Glistering Melon, Golden Carrot,\n[[YELLOW]]Magma Cream, Nether Wart, Spider Eye, Suplhur, Water Lily,\n[[YELLOW]]Pufferfish\n[[YELLOW]](Vanilla Potions)
Guides.Alchemy.Section.4=[[DARK_AQUA]]Concotions tier 2 ingredients:\n[[YELLOW]]Carrot (Potion of Haste)\n[[YELLOW]]Slimeball (Potion of Dullness)\n\n[[DARK_AQUA]]Concotions tier 3 ingredients:\n[[YELLOW]]Quartz (Potion of Absorption)\n[[YELLOW]]Red Mushroom (Potion of Leaping)
Guides.Alchemy.Section.5=[[DARK_AQUA]]Concotions tier 4 ingredients:\n[[YELLOW]]Apple (Potion of Health Boost)\n[[YELLOW]]Rotten Flesh (Potion of Hunger)\n\n[[DARK_AQUA]]Concotions tier 5 ingredients:\n[[YELLOW]]Brown Mushroom (Potion of Nausea)\n[[YELLOW]]Ink Sack (Potion of Blindness)
Guides.Alchemy.Section.6=[[DARK_AQUA]]Concotions tier 6 ingredients:\n[[YELLOW]]Fern (Potion of Saturation)\n\n[[DARK_AQUA]]Concotions tier 7 ingredients:\n[[YELLOW]]Poisonous Potato (Potion of Decay)\n\n[[DARK_AQUA]]Concotions tier 8 ingredients:\n[[YELLOW]]Regular Golden Apple (Potion of Resistance)
##Archery ##Archery
Guides.Archery.Section.0=[[DARK_AQUA]]About Archery:\n[[YELLOW]]Archery is about shooting with your bow and arrow.\n[[YELLOW]]It provides various combat bonuses, such as a damage boost\n[[YELLOW]]that scales with your level and the ability to daze your\n[[YELLOW]]opponents in PvP. In addition to this, you can retrieve\n[[YELLOW]]some of your spent arrows from the corpses of your foes.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to shoot mobs or\n[[YELLOW]]other players. Guides.Archery.Section.0=[[DARK_AQUA]]About Archery:\n[[YELLOW]]Archery is about shooting with your bow and arrow.\n[[YELLOW]]It provides various combat bonuses, such as a damage boost\n[[YELLOW]]that scales with your level and the ability to daze your\n[[YELLOW]]opponents in PvP. In addition to this, you can retrieve\n[[YELLOW]]some of your spent arrows from the corpses of your foes.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to shoot mobs or\n[[YELLOW]]other players.
Guides.Archery.Section.1=[[DARK_AQUA]]How does Skill Shot work?\n[[YELLOW]]Skill Shot provides additional damage to your shots.\n[[YELLOW]]The bonus damage from Skill Shot increases as you\n[[YELLOW]]level in Archery.\n[[YELLOW]]With the default settings, your archery damage increases 10%\n[[YELLOW]]every 50 levels, to a maximum of 200% bonus damage. Guides.Archery.Section.1=[[DARK_AQUA]]How does Skill Shot work?\n[[YELLOW]]Skill Shot provides additional damage to your shots.\n[[YELLOW]]The bonus damage from Skill Shot increases as you\n[[YELLOW]]level in Archery.\n[[YELLOW]]With the default settings, your archery damage increases 10%\n[[YELLOW]]every 50 levels, to a maximum of 200% bonus damage.

View File

@ -11,7 +11,7 @@ description: >
in order to evaluate and balance the mechanics of mcMMO in every update. in order to evaluate and balance the mechanics of mcMMO in every update.
author: nossr50 author: nossr50
authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking, EasyMFnE] authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking]
website: http://dev.bukkit.org/server-mods/mcmmo/ website: http://dev.bukkit.org/server-mods/mcmmo/
main: com.gmail.nossr50.mcMMO main: com.gmail.nossr50.mcMMO

View File

@ -16,7 +16,8 @@ Concoctions:
- SPIDER_EYE - SPIDER_EYE
- SUGAR - SUGAR
- SULPHUR - SULPHUR
- WATER_LILY # TODO: 'RAW_FISH:3' (Minecraft 1.7) - WATER_LILY
- 'RAW_FISH:3'
Tier_Two_Ingredients: Tier_Two_Ingredients:
- CARROT_ITEM - CARROT_ITEM
- SLIME_BALL - SLIME_BALL
@ -97,7 +98,7 @@ Potions:
SPIDER_EYE: 4868 # Potion of Poison SPIDER_EYE: 4868 # Potion of Poison
SUGAR: 258 # Potion of Swiftness SUGAR: 258 # Potion of Swiftness
WATER_LILY: 3341 # Potion of Water Breathing (Minecraft 1.6) WATER_LILY: 3341 # Potion of Water Breathing (Minecraft 1.6)
# 'RAW_FISH:3': 3341 # TODO: Potion of Water Breathing (Minecraft 1.7) 'RAW_FISH:3': 3341 # Potion of Water Breathing (Minecraft 1.7)
32: # Thick Potion 32: # Thick Potion
Children: Children: