diff --git a/Changelog.txt b/Changelog.txt index c5c6a8fcc..348e820c2 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -171,6 +171,15 @@ Version 2.2.0 Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition Added API method to check if a skill was being level capped Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill +Version 2.1.84 + Added some code to make mcMMO more compatible with EpicSpawners + +Version 2.1.83 + You can no longer set party members on fire with your bow + (FIX) Arrow Retrieval will no longer work with piercing enchant on crossbows + WG Flags should now correctly recognize when a projectile belongs to a player and respect flag settings + Updated hu_HU locale (thanks andris155) + Version 2.1.82 Added new WG flag 'mcmmo-hardcore' if set to negative players will not be penalized by hardcore mode (if hardcore mode is enabled) it defaults to true Added proper error handling when loading parties file diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java index 127551cd0..d16f8029f 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java @@ -23,7 +23,6 @@ import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.skills.RankUtils; import com.google.common.collect.ImmutableList; import org.bukkit.Color; -import org.bukkit.OfflinePlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index fd51045f4..a91bef3ef 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -20,7 +20,9 @@ import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.player.UserManager; +import com.gmail.nossr50.util.random.RandomChanceUtil; import com.gmail.nossr50.util.skills.CombatUtils; +import com.gmail.nossr50.util.skills.SkillActivationType; import com.gmail.nossr50.worldguard.WorldGuardManager; import com.gmail.nossr50.worldguard.WorldGuardUtils; import org.bukkit.Material; @@ -28,9 +30,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.event.*; import org.bukkit.event.entity.*; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; @@ -40,6 +40,7 @@ import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.projectiles.ProjectileSource; +import sun.security.krb5.Config; public class EntityListener implements Listener { private final mcMMO plugin; @@ -99,8 +100,9 @@ public class EntityListener implements Listener { ItemStack bow = event.getBow(); - if (bow != null && bow.containsEnchantment(Enchantment.ARROW_INFINITE)) { - projectile.setMetadata(MetadataConstants.INFINITE_ARROW_METAKEY, MetadataConstants.metadataValue); + if (bow != null + && bow.containsEnchantment(Enchantment.ARROW_INFINITE)) { + projectile.setMetadata(MetadataConstants.ARROW_TRACKER_METAKEY, MetadataConstants.metadataValue); } projectile.setMetadata(MetadataConstants.BOW_FORCE_METAKEY, @@ -116,24 +118,36 @@ public class EntityListener implements Listener { if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld())) return; - if (event.getEntity() instanceof Player) { - Player player = (Player) event.getEntity(); + if(event.getEntity().getShooter() instanceof Player) + { + + Player player = (Player) event.getEntity().getShooter(); /* WORLD GUARD MAIN FLAG CHECK */ if (WorldGuardUtils.isWorldGuardLoaded()) { if (!WorldGuardManager.getInstance().hasMainFlag(player)) return; } + + Projectile projectile = event.getEntity();//Hacky stuff for 1.13/1.14 compat + + String itemKey = player.getInventory().getItemInMainHand().getType().getKey().toString(); + + if(!itemKey.equalsIgnoreCase("minecraft:bow") && !itemKey.equalsIgnoreCase("minecraft:crossbow")) + return; + + projectile.setMetadata(MetadataConstants.BOW_FORCE_METAKEY, new FixedMetadataValue(plugin, 1.0)); + projectile.setMetadata(MetadataConstants.ARROW_DISTANCE_METAKEY, new FixedMetadataValue(plugin, projectile.getLocation())); + + for(Enchantment enchantment : player.getInventory().getItemInMainHand().getEnchantments().keySet()) { + if(enchantment.getName().equalsIgnoreCase("piercing")) + return; + } + + if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ARCHERY_ARROW_RETRIEVAL, player)) { + projectile.setMetadata(MetadataConstants.ARROW_TRACKER_METAKEY, MetadataConstants.metadataValue); + } } - - Projectile projectile = event.getEntity(); - - if (!(projectile instanceof Arrow) || projectile.hasMetadata(MetadataConstants.BOW_FORCE_METAKEY)) { - return; - } - - projectile.setMetadata(MetadataConstants.BOW_FORCE_METAKEY, new FixedMetadataValue(plugin, 1.0)); - projectile.setMetadata(MetadataConstants.ARROW_DISTANCE_METAKEY, new FixedMetadataValue(plugin, projectile.getLocation())); } /** @@ -242,6 +256,27 @@ public class EntityListener implements Listener { } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityCombustByEntityEvent(EntityCombustByEntityEvent event) { + //Prevent players from setting fire to each other if they are in the same party + if(event.getEntity() instanceof Player) { + Player defender = (Player) event.getEntity(); + + if(event.getCombuster() instanceof Projectile) { + Projectile projectile = (Projectile) event.getCombuster(); + if(projectile.getShooter() instanceof Player) { + Player attacker = (Player) projectile.getShooter(); + if(checkParties(event, defender, attacker)) + return; + } + } else if(event.getCombuster() instanceof Player) { + Player attacker = (Player) event.getCombuster(); + if(checkParties(event, defender, attacker)) + return; + } + } + } + /** * Handle EntityDamageByEntity events that involve modifying the event. * @@ -253,6 +288,25 @@ public class EntityListener implements Listener { Entity defender = event.getEntity(); Entity attacker = event.getDamager(); + if(WorldGuardUtils.isWorldGuardLoaded()) + { + if(attacker instanceof Player) { + + if(!WorldGuardManager.getInstance().hasMainFlag((Player) attacker)) + return; + + } else if(attacker instanceof Projectile) { + + Projectile projectile = (Projectile) attacker; + + if(projectile.getShooter() instanceof Player) { + if(!WorldGuardManager.getInstance().hasMainFlag((Player) projectile.getShooter())) + return; + } + + } + } + /* WORLD BLACKLIST CHECK */ if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld())) return; @@ -270,41 +324,6 @@ public class EntityListener implements Listener { return; } - if (attacker instanceof Player) { - Player player = (Player) attacker; - - /* WORLD GUARD MAIN FLAG CHECK */ - if (WorldGuardUtils.isWorldGuardLoaded()) { - if (!WorldGuardManager.getInstance().hasMainFlag(player)) - return; - } - } - - if (damage <= 0) { - if (defender instanceof Player && attacker instanceof Player) { - Player defendingPlayer = (Player) defender; - Player attackingPlayer = (Player) attacker; - if (event.getDamage(DamageModifier.ABSORPTION) > 0) { - //If friendly fire is off don't allow players to hurt one another - if (!mcMMO.getConfigManager().getConfigParty().isPartyFriendlyFireEnabled()) - if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) { - event.setCancelled(true); - return; - } - } - } - return; - } - - - /* - As far as I can tell at one point we registered meta-data about custom damage and we no longer do that. - - if (defender.hasMetadata(mcMMO.customDamageKey)) { - defender.removeMetadata(mcMMO.customDamageKey, plugin); - return; - } - */ if (Misc.isNPCEntityExcludingVillagers(defender) || !defender.isValid() || !(defender instanceof LivingEntity)) { return; @@ -320,26 +339,7 @@ public class EntityListener implements Listener { return; } - if (attacker instanceof Projectile) { - ProjectileSource projectileSource = ((Projectile) attacker).getShooter(); - - if (projectileSource instanceof LivingEntity) { - attacker = (LivingEntity) projectileSource; - } - - if(defender instanceof Player) { - Player playerDefender = (Player) defender; - UnarmedManager unarmedManager = UserManager.getPlayer(playerDefender).getUnarmedManager(); - - if (unarmedManager.canDeflect()) { - if(unarmedManager.deflectCheck()) { - event.setCancelled(true); - return; - } - } - } - } - else if (attacker instanceof Tameable) { + if (attacker instanceof Tameable) { AnimalTamer animalTamer = ((Tameable) attacker).getOwner(); if (animalTamer != null && ((OfflinePlayer) animalTamer).isOnline()) { @@ -351,27 +351,50 @@ public class EntityListener implements Listener { } } - if (defender instanceof Player && attacker instanceof Player) { + //Friendly fire checks + if (defender instanceof Player) { Player defendingPlayer = (Player) defender; - Player attackingPlayer = (Player) attacker; + Player attackingPlayer; - if (!UserManager.hasPlayerDataKey(defendingPlayer) || !UserManager.hasPlayerDataKey(attackingPlayer)) { - return; - } + //If the attacker is a Player or a projectile beloning to a player + if(attacker instanceof Projectile || attacker instanceof Player) { + if(attacker instanceof Projectile) { + Projectile projectile = (Projectile) attacker; + if(((Projectile) attacker).getShooter() instanceof Player) { + attackingPlayer = (Player) projectile.getShooter(); - // We want to make sure we're not gaining XP or applying abilities - // when we hit ourselves - if (defendingPlayer.equals(attackingPlayer)) { - return; - } + //Check for party friendly fire and cancel the event + if (checkParties(event, defendingPlayer, attackingPlayer)) + { + return; + } - //Party Friendly Fire - if (!mcMMO.getConfigManager().getConfigParty().isPartyFriendlyFireEnabled()) - if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) - || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) { - event.setCancelled(true); - return; + } + + //Deflect checks + UnarmedManager unarmedManager = UserManager.getPlayer(defendingPlayer).getUnarmedManager(); + + if (unarmedManager.canDeflect()) { + if(unarmedManager.deflectCheck()) { + event.setCancelled(true); + return; + } + } + } else { + attackingPlayer = (Player) attacker; + //Check for party friendly fire and cancel the event + if (checkParties(event, defendingPlayer, attackingPlayer)) + return; } + } + } + + //Required setup for processCombatAttack + if(attacker instanceof Projectile) { + ProjectileSource shooter = ((Projectile) attacker).getShooter(); + if(shooter instanceof LivingEntity) { + attacker = (LivingEntity) shooter; + } } CombatUtils.processCombatAttack(event, attacker, target); @@ -390,6 +413,29 @@ public class EntityListener implements Listener { } + public boolean checkParties(Cancellable event, Player defendingPlayer, Player attackingPlayer) { + if (!UserManager.hasPlayerDataKey(defendingPlayer) || !UserManager.hasPlayerDataKey(attackingPlayer)) { + return true; + } + + // We want to make sure we're not gaining XP or applying abilities + // when we hit ourselves + if (defendingPlayer.equals(attackingPlayer)) { + return true; + } + + //Party Friendly Fire + if(!mcMMO.getConfigManager().getConfigParty().isPartyFriendlyFireEnabled()) + if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) + || PartyManager.areAllies(defendingPlayer, attackingPlayer)) + && !(Permissions.friendlyFire(attackingPlayer) + && Permissions.friendlyFire(defendingPlayer))) { + event.setCancelled(true); + return true; + } + return false; + } + /** * Handle EntityDamage events that involve modifying the event. * @@ -614,7 +660,7 @@ public class EntityListener implements Listener { * * @param event The event to watch */ - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.MONITOR) public void onCreatureSpawn(CreatureSpawnEvent event) { /* WORLD BLACKLIST CHECK */ if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld())) diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index 901465257..792d70d59 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -440,7 +440,11 @@ public class PlayerListener implements Listener { McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); Item drop = event.getItem(); + //Remove tracking ItemStack dropStack = drop.getItemStack(); + if(drop.hasMetadata(MetadataConstants.ARROW_TRACKER_METAKEY)) { + drop.removeMetadata(MetadataConstants.ARROW_TRACKER_METAKEY, mcMMO.p); + } if (drop.hasMetadata(MetadataConstants.DISARMED_ITEM_METAKEY)) { if (!player.getName().equals(drop.getMetadata(MetadataConstants.DISARMED_ITEM_METAKEY).get(0).asString())) { diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index a22493f54..4bcd97a84 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -79,7 +79,6 @@ public class mcMMO extends JavaPlugin { private static boolean serverAPIOutdated = false; // XP Event Check private boolean xpEventEnabled; - /** * Things to be run when the plugin is enabled. */ diff --git a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java index ad6b53f03..39b2b467c 100644 --- a/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java +++ b/src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java @@ -16,6 +16,7 @@ import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -67,9 +68,10 @@ public class ArcheryManager extends SkillManager { * * @param target The {@link LivingEntity} damaged by the arrow */ - public void processArrowRetrievalActivation(LivingEntity target) { - if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ARCHERY_ARROW_RETRIEVAL, getPlayer())) { + public void processArrowRetrievalActivation(LivingEntity target, Projectile projectile) { + if(projectile.hasMetadata(MetadataConstants.ARROW_TRACKER_METAKEY)) { Archery.incrementArrowCount(target); + projectile.removeMetadata(MetadataConstants.ARROW_TRACKER_METAKEY, mcMMO.p); //Only 1 entity per projectile } } diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java index 8f3e96255..9be5d8d73 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -217,7 +217,7 @@ public final class CombatUtils { } if (!arrow.hasMetadata(MetadataConstants.INFINITE_ARROW_METAKEY) && archeryManager.canRetrieveArrows()) { - archeryManager.processArrowRetrievalActivation(target); + archeryManager.processArrowRetrievalActivation(target, arrow); } if (canUseLimitBreak(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK)) { @@ -460,35 +460,6 @@ public final class CombatUtils { target.setMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, MetadataConstants.metadataValue); target.damage(damage, attacker); - -// //IFrame storage -//// int noDamageTicks = target.getNoDamageTicks(); -// -//// String debug = "BLEED DMG RESULT: INC DMG:"+damage+", HP-Before:"+target.getHealth()+", HP-After:"; -// -//// double incDmg = getFakeDamageFinalResult(attacker, target, DamageCause.ENTITY_ATTACK, damage); -// -//// double newHealth = Math.max(0, target.getHealth() - incDmg); -// -// //Don't kill things with a stone or wooden weapon -//// if(toolTier < 3 && newHealth == 0) -//// return; -// -// target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue); -// -// if(newHealth == 0 && !(target instanceof Player)) -// { -// target.damage(99999, attacker); -// } -// else -// { -//// Vector beforeRuptureVec = new Vector(target.getVelocity().getX(), target.getVelocity().getY(), target.getVelocity().getZ()); ; -// target.damage(damage, attacker); -//// debug+=target.getHealth(); -// Bukkit.broadcastMessage(debug); -//// target.setNoDamageTicks(noDamageTicks); //Do not add additional IFrames -//// target.setVelocity(beforeRuptureVec); -// } } /** @@ -593,7 +564,7 @@ public final class CombatUtils { } } - if (target.hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY)) { + if (target.hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY) || target.hasMetadata("ES")) { baseXPMultiplier *= mcMMO.getDynamicSettingsManager().getExperienceManager().getSpecialCombatXP(SpecialXPKey.SPAWNED); } diff --git a/src/main/resources/locale/locale_hu_HU.properties b/src/main/resources/locale/locale_hu_HU.properties index 97f46beb6..2667072e3 100644 --- a/src/main/resources/locale/locale_hu_HU.properties +++ b/src/main/resources/locale/locale_hu_HU.properties @@ -54,6 +54,7 @@ JSON.Notification.SuperAbility={0} #These are the JSON Strings used for SubSkills JSON.Acrobatics.Roll.Interaction.Activated=Teszt [[RED]]Gurul\u00E1s Teszt JSON.Acrobatics.SubSkill.Roll.Details.Tips=Ha guggolsz es\u00E9s k\u00F6zben megakad\u00E1lyozhatod, hogy k\u00E9tszer annyi k\u00E1rt szenvedj, amit \u00E1ltal\u00E1ban! +Anvil.SingleItemStack=[[RED]]Nem lehet \u00FAjrahasznos\u00EDtani, vagy jav\u00EDtani \u00F6sszerakott t\u00E1rgyakat, el\u0151sz\u00F6r szed sz\u00E9t az \u00F6sszerakott t\u00E1rgyakat. #DO NOT USE COLOR CODES IN THE JSON KEYS #COLORS ARE DEFINED IN advanced.yml IF YOU WISH TO CHANGE THEM @@ -103,6 +104,8 @@ Commands.Party.Header=[[RED]]-----[][[GREEN]]PARTY[[RED]][]----- Commands.Party.Features.Header=[[RED]]-----[][[GREEN]]FUNKCI\u00D3K[[RED]][]----- # XP BAR Allows for the following variables -- {0} = Skill Level, {1} Current XP, {2} XP Needed for next level, {3} Power Level, {4} Percentage of Level # Make sure you turn on Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained if you want the XP bar title to update every time a player gains XP! +XPBar.Template={0} +XPBar.Template.EarlyGameBoost=[[GOLD]]Egy \u00FAj k\u00E9pess\u00E9g tanul\u00E1sa... XPBar.Acrobatics=Akrobatika [[GOLD]]{0}. [[WHITE]]Szint XPBar.Alchemy=Alk\u00EDmia [[GOLD]]{0}. [[WHITE]]Szint XPBar.Archery=\u00CDj\u00E1szat [[GOLD]]{0}. [[WHITE]]Szint @@ -367,29 +370,32 @@ Repair.Arcane.Fail=A m\u00E1gikus er\u0151 v\u00E9gleg elhagyta ezt a t\u00E1rgy Repair.Arcane.Lost=Nem volt\u00E1l el\u00E9g tapasztalt ahhoz, hogy megtarthass valamilyen var\u00E1zslatot is. Repair.Arcane.Perfect=[[GREEN]]Sikeresen megtartottad a m\u00E1gikus energi\u00E1kat ebben a t\u00E1rgyban. #SALVAGE -Salvage.Pretty.Name=\u00C9rt\u00E9kment\u00E9s +Salvage.Pretty.Name=\u00DAjrahasznos\u00EDt\u00E1s Salvage.SubSkill.UnderstandingTheArt.Name=A M\u0171v\u00E9szet Meg\u00E9rt\u00E9se Salvage.SubSkill.UnderstandingTheArt.Description=Nem csak a szomsz\u00E9dok szem\u00E9t\u00E9ben kutatsz, hanem gondoskodsz a k\u00F6rnyezetr\u0151l is.\nAz \u00C9rt\u00E9kment\u00E9s k\u00FCl\u00F6nb\u00F6z\u0151 tulajdons\u00E1gait n\u00F6veli. -Salvage.SubSkill.AdvancedSalvage.Name=Fejlesztett \u00DAjrahasznos\u00EDt\u00E1s -Salvage.SubSkill.AdvancedSalvage.Description=S\u00E9r\u00FClt t\u00E1rgyak \u00FAjrahasznos\u00EDt\u00E1sa +Salvage.SubSkill.ScrapCollector.Name=Hullad\u00E9kgy\u0171jt\u0151 +Salvage.SubSkill.ScrapCollector.Description=Hasznos\u00EDtsd \u00FAjra az anyagokat egy t\u00E1rgyb\u00F3l, egy sikeres \u00FAjrahasznos\u00EDt\u00E1s a k\u00E9pess\u00E9gen \u00E9s a szerencs\u00E9n m\u00FAlik. +Salvage.SubSkill.ScrapCollector.Stat=Hullad\u00E9kgy\u0171jt\u0151: [[GREEN]]Hullad\u00E9kgy\u0171jt\u0151: [[GREEN]]Hasznos\u00EDts \u00FAjra ak\u00E1r [[YELLOW]]{0}[[GREEN]] t\u00E1rgyat. Egy kis szerencs\u00E9vel. Salvage.SubSkill.ArcaneSalvage.Name=M\u00E1gikus \u00DAjrahasznos\u00EDt\u00E1s Salvage.SubSkill.ArcaneSalvage.Description=Var\u00E1zslatok kinyer\u00E9se t\u00E1rgyakb\u00F3l Salvage.SubSkill.ArcaneSalvage.Stat=M\u00E1gikus \u00DAjrahasznos\u00EDt\u00E1s Szint: [[YELLOW]] {0}/{1} -Salvage.Ability.Locked.0=LEZ\u00C1RVA {0}+ SZINT ALATT FEJLESZTETT \u00DAJRAHASZNOS\u00CDT\u00C1S -Salvage.Ability.Bonus.0=Fejlesztett \u00DAjrahasznos\u00EDt\u00E1s -Salvage.Ability.Bonus.1=Az \u00FAjhasznos\u00EDt\u00E1sb\u00F3l visszanyert maxim\u00E1lis anyagok {0} +Salvage.Ability.Bonus.0=Hullad\u00E9kgy\u0171jt\u0151 +Salvage.Ability.Bonus.1=Hasznos\u00EDts \u00FAjra ak\u00E1r [[YELLOW]]{0}[[GREEN]] t\u00E1rgyat. Egy kis szerencs\u00E9vel. Salvage.Arcane.ExtractFull=[[GRAY]]M\u00C9 Teljes-Var\u00E1zslat Es\u00E9ly Salvage.Arcane.ExtractPartial=[[GRAY]]M\u00C9 R\u00E9szleges-Var\u00E1zslat Es\u00E9ly Salvage.Skills.Success=[[GREEN]]T\u00E1rgy \u00DAjrahasznos\u00EDtva! Salvage.Skills.Adept.Damaged=[[DARK_RED]]Nem vagy el\u00E9g tapasztalt, hogy s\u00E9r\u00FClt t\u00E1rgyakat hasznos\u00EDthass \u00FAjra. -Salvage.Skills.Adept.Level=Sz\u00FCks\u00E9ges szint [[YELLOW]]{1}[[RED]] \u00FAjrafelhaszn\u00E1l\u00E1s\u00E1hoz: [[YELLOW]]{0} -Salvage.Skills.TooDamaged=[[DARK_RED]]Ez a t\u00E1rgy t\u00FAls\u00E1gosan s\u00E9r\u00FClt az \u00FAjrafelhaszn\u00E1l\u00E1shoz. +Salvage.Skills.Adept.Level=Sz\u00FCks\u00E9ges szint [[YELLOW]]{1}[[RED]] \u00FAjrahasznos\u00EDt\u00E1shoz: [[YELLOW]]{0} +Salvage.Skills.TooDamaged=[[DARK_RED]]Ez a t\u00E1rgy t\u00FAls\u00E1gosan s\u00E9r\u00FClt az \u00FAjrahasznos\u00EDt\u00E1shoz. Salvage.Skills.ArcaneFailed=[[RED]]Nem tudtad kinyerni a tud\u00E1st, ami ebben a t\u00E1rgyban lakozik. Salvage.Skills.ArcanePartial=[[RED]]Csak r\u00E9szleges tud\u00E1st tudt\u00E1l kinyerni ebb\u0151l a t\u00E1rgyb\u00F3l. Salvage.Skills.ArcaneSuccess=[[GREEN]]Sikeresen kinyert\u00E9l minden tud\u00E1st ebb\u0151l a t\u00E1rgyb\u00F3l! -Salvage.Listener.Anvil=[[DARK_RED]]Lehelyezt\u00E9l egy \u00C9rt\u00E9kment\u0151 \u00DCll\u0151t. Haszn\u00E1ld ezt eszk\u00F6z\u00F6k \u00E9s p\u00E1nc\u00E9lzatok \u00FAjrafelhaszn\u00E1l\u00E1shoz. +Salvage.Listener.Anvil=[[DARK_RED]]Lehelyezt\u00E9l egy \u00C9rt\u00E9kment\u0151 \u00DCll\u0151t. Haszn\u00E1ld ezt eszk\u00F6z\u00F6k, \u00E9s p\u00E1nc\u00E9lzatok \u00FAjrahasznos\u00EDt\u00E1shoz. Salvage.Listener=\u00DAjrahasznos\u00EDt\u00E1s: Salvage.SkillName=\u00DAJRAHASZNOS\u00CDT\u00C1S +Salvage.Skills.Lottery.Normal=[[GOLD]]\u00DAjrahasznos\u00EDthatsz [[GREEN]]{0}[[GOLD]] anyagot ebb\u0151l [[DARK_AQUA]]{1}[[GOLD]]. +Salvage.Skills.Lottery.Perfect=[[GREEN]][[BOLD]]T\u00F6k\u00E9letes![[RESET]][[GOLD]] K\u00F6nnyed\u00E9n \u00FAjrahasznos\u00EDtott\u00E1l egy [[GREEN]]{1}[[GOLD]]-t visszanyerve [[DARK_AQUA]]{0}[[GOLD]] anyagot. +Salvage.Skills.Lottery.Untrained=[[GRAY]]M\u00E9g nem vagy el\u00E9g k\u00E9pezett az \u00FAjrahasznos\u00EDt\u00E1sban. Csak [[RED]]{0}[[GRAY]] anyagot tudt\u00E1l helyre\u00E1ll\u00EDtani ebb\u0151l [[GREEN]]{1}[[GRAY]]. #Anvil (Shared between SALVAGE and REPAIR) Anvil.Unbreakable=Ez a t\u00E1rgy t\u00F6rhetetlen! #SWORDS