Partially finished merge

This commit is contained in:
nossr50
2019-08-20 11:24:47 -04:00
119 changed files with 2592 additions and 961 deletions

View File

@@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.skills.behaviours.AcrobaticsBehaviour;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.Location;
@@ -64,7 +63,7 @@ public class AcrobaticsManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.ACROBATICS_DODGE))
return false;
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.ACROBATICS_DODGE)) {
if (pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.ACROBATICS_DODGE)) {
/*if (damager instanceof LightningStrike && Acrobatics.dodgeLightningDisabled) {
return false;
}*/

View File

@@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.skills.behaviours.ArcheryBehaviour;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@@ -34,21 +33,21 @@ public class ArcheryManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.ARCHERY_DAZE))
return false;
return target instanceof Player && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_DAZE);
return target instanceof Player && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_DAZE);
}
public boolean canSkillShot() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.ARCHERY_SKILL_SHOT))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_SKILL_SHOT);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_SKILL_SHOT);
}
public boolean canRetrieveArrows() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.ARCHERY_ARROW_RETRIEVAL))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_ARROW_RETRIEVAL);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.ARCHERY_ARROW_RETRIEVAL);
}
/**

View File

@@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.datatypes.skills.behaviours.AxesBehaviour;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.entity.LivingEntity;
@@ -32,39 +31,39 @@ public class AxesManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_AXE_MASTERY))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.AXES_AXE_MASTERY);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.AXES_AXE_MASTERY);
}
public boolean canCriticalHit(LivingEntity target) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_CRITICAL_STRIKES))
return false;
return target.isValid() && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.AXES_CRITICAL_STRIKES);
return target.isValid() && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.AXES_CRITICAL_STRIKES);
}
public boolean canImpact(LivingEntity target) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_ARMOR_IMPACT))
return false;
return target.isValid() && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.AXES_ARMOR_IMPACT) && axesBehaviour.hasArmor(target);
return target.isValid() && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.AXES_ARMOR_IMPACT) && axesBehaviour.hasArmor(target);
}
public boolean canGreaterImpact(LivingEntity target) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_GREATER_IMPACT))
return false;
return target.isValid() && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.AXES_GREATER_IMPACT) && !axesBehaviour.hasArmor(target);
return target.isValid() && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.AXES_GREATER_IMPACT) && !axesBehaviour.hasArmor(target);
}
public boolean canUseSkullSplitter(LivingEntity target) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.AXES_SKULL_SPLITTER))
return false;
return target.isValid() && mcMMOPlayer.getAbilityMode(SuperAbilityType.SKULL_SPLITTER) && Permissions.skullSplitter(getPlayer());
return target.isValid() && mcMMOPlayer.getAbilityMode(SuperAbilityType.SKULL_SPLITTER) && pluginRef.getPermissionTools().skullSplitter(getPlayer());
}
public boolean canActivateAbility() {
return mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && Permissions.skullSplitter(getPlayer());
return mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && pluginRef.getPermissionTools().skullSplitter(getPlayer());
}
/**

View File

@@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.treasure.ExcavationTreasure;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.Location;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
@@ -35,7 +34,7 @@ public class ExcavationManager extends SkillManager {
public void excavationBlockCheck(BlockState blockState) {
int xp = excavationBehaviour.getBlockXP(blockState);
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
if (pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
List<ExcavationTreasure> treasures = excavationBehaviour.getTreasures(blockState);
if (!treasures.isEmpty()) {
@@ -76,7 +75,7 @@ public class ExcavationManager extends SkillManager {
public void printExcavationDebug(Player player, BlockState blockState)
{
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
if (pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
List<ExcavationTreasure> treasures = excavationBehaviour.getTreasures(blockState);
if (!treasures.isEmpty()) {

View File

@@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.fishing;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.treasure.FishingTreasureConfig;
import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
@@ -18,7 +17,6 @@ import com.gmail.nossr50.events.skills.fishing.McMMOPlayerShakeEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
@@ -62,11 +60,11 @@ public class FishingManager extends SkillManager {
}
public boolean canShake(Entity target) {
return target instanceof LivingEntity && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.FISHING_SHAKE) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_SHAKE);
return target instanceof LivingEntity && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.FISHING_SHAKE) && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_SHAKE);
}
public boolean canMasterAngler() {
return getSkillLevel() >= pluginRef.getRankTools().getUnlockLevel(SubSkillType.FISHING_MASTER_ANGLER) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_MASTER_ANGLER);
return getSkillLevel() >= pluginRef.getRankTools().getUnlockLevel(SubSkillType.FISHING_MASTER_ANGLER) && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_MASTER_ANGLER);
}
public void setFishingRodCastTimestamp() {
@@ -146,7 +144,7 @@ public class FishingManager extends SkillManager {
if (overFishCount == 2) {
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.isOp() || Permissions.adminChat(player)) {
if (player.isOp() || pluginRef.getPermissionTools().adminChat(player)) {
player.sendMessage(pluginRef.getLocaleManager().getString("Fishing.OverFishingDetected", getPlayer().getDisplayName()));
}
}
@@ -180,7 +178,7 @@ public class FishingManager extends SkillManager {
Player player = getPlayer();
if (!Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_ICE_FISHING)) {
if (!pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_ICE_FISHING)) {
return false;
}
@@ -262,7 +260,7 @@ public class FishingManager extends SkillManager {
public boolean isMagicHunterEnabled() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.FISHING_MAGIC_HUNTER)
&& pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.FISHING_TREASURE_HUNTER)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_TREASURE_HUNTER);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.FISHING_TREASURE_HUNTER);
}
/**
@@ -277,7 +275,7 @@ public class FishingManager extends SkillManager {
FishingTreasure treasure = null;
if (pluginRef.getConfigManager().getConfigFishing().isAllowCustomDrops()
&& Permissions.isSubSkillEnabled(player, SubSkillType.FISHING_TREASURE_HUNTER)) {
&& pluginRef.getPermissionTools().isSubSkillEnabled(player, SubSkillType.FISHING_TREASURE_HUNTER)) {
treasure = getFishingTreasure();
}

View File

@@ -1,8 +1,9 @@
package com.gmail.nossr50.skills.herbalism;
import com.gmail.nossr50.config.treasure.HerbalismTreasureConfig;
import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.BlockSnapshot;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.experience.XPGainSource;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -12,22 +13,29 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.datatypes.skills.behaviours.HerbalismBehaviour;
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.skills.DelayedHerbalismXPCheckTask;
import com.gmail.nossr50.runnables.skills.HerbalismBlockUpdaterTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.metadata.FixedMetadataValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class HerbalismManager extends SkillManager {
@@ -50,7 +58,7 @@ public class HerbalismManager extends SkillManager {
Player player = getPlayer();
ItemStack item = player.getInventory().getItemInMainHand();
return item.getAmount() > 0 && item.getType() == Material.WHEAT_SEEDS && pluginRef.getBlockTools().canMakeMossy(blockState) && Permissions.greenThumbBlock(player, blockState.getType());
return item.getAmount() > 0 && item.getType() == Material.WHEAT_SEEDS && pluginRef.getBlockTools().canMakeMossy(blockState) && pluginRef.getPermissionTools().greenThumbBlock(player, blockState.getType());
}
public boolean canUseShroomThumb(BlockState blockState) {
@@ -61,14 +69,14 @@ public class HerbalismManager extends SkillManager {
PlayerInventory inventory = player.getInventory();
Material itemType = inventory.getItemInMainHand().getType();
return (itemType == Material.BROWN_MUSHROOM || itemType == Material.RED_MUSHROOM) && inventory.contains(Material.BROWN_MUSHROOM, 1) && inventory.contains(Material.RED_MUSHROOM, 1) && pluginRef.getBlockTools().canMakeShroomy(blockState) && Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_SHROOM_THUMB);
return (itemType == Material.BROWN_MUSHROOM || itemType == Material.RED_MUSHROOM) && inventory.contains(Material.BROWN_MUSHROOM, 1) && inventory.contains(Material.RED_MUSHROOM, 1) && pluginRef.getBlockTools().canMakeShroomy(blockState) && pluginRef.getPermissionTools().isSubSkillEnabled(player, SubSkillType.HERBALISM_SHROOM_THUMB);
}
public boolean canUseHylianLuck() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK);
}
public boolean canGreenTerraBlock(BlockState blockState) {
@@ -76,10 +84,10 @@ public class HerbalismManager extends SkillManager {
}
public boolean canActivateAbility() {
return mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer());
return mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && pluginRef.getPermissionTools().greenTerra(getPlayer());
}
public boolean canGreenTerraPlant() {
public boolean isGreenTerraActive() {
return mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA);
}
@@ -99,10 +107,10 @@ public class HerbalismManager extends SkillManager {
* @param blockState The {@link BlockState} to check ability activation for
* @return true if the ability was successful, false otherwise
*/
public boolean processGreenTerra(BlockState blockState) {
public boolean processGreenTerraBlockConversion(BlockState blockState) {
Player player = getPlayer();
if (!Permissions.greenThumbBlock(player, blockState.getType())) {
if (!pluginRef.getPermissionTools().greenThumbBlock(player, blockState.getType())) {
return false;
}
@@ -121,62 +129,399 @@ public class HerbalismManager extends SkillManager {
}
/**
* @param blockState The {@link BlockState} to check ability activation for
* Handles herbalism abilities and XP rewards from a BlockBreakEvent
* @param blockBreakEvent The Block Break Event to process
*/
public void herbalismBlockCheck(BlockState blockState) {
public void processHerbalismBlockBreakEvent(BlockBreakEvent blockBreakEvent) {
Player player = getPlayer();
Material material = blockState.getType();
boolean oneBlockPlant = isOneBlockPlant(material);
// Prevents placing and immediately breaking blocks for exp
if (oneBlockPlant && pluginRef.getPlaceStore().isTrue(blockState)) {
if (pluginRef.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitHerbalism().isPreventVehicleAutoFarming() && player.isInsideVehicle()) {
return;
}
if (!canBlockCheck()) {
return;
}
/*
* There are single-block plants and multi-block plants in Minecraft
* In order to give out proper rewards, we need to collect all blocks that would be broken from this event
*/
int amount;
int xp;
boolean greenTerra = mcMMOPlayer.getAbilityMode(skill.getSuperAbility());
//Grab all broken blocks
HashSet<Block> brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent);
// if (mcMMO.getModManager().isCustomHerbalismBlock(blockState)) {
// CustomBlock customBlock = mcMMO.getModManager().getBlock(blockState);
// xp = customBlock.getXpGain();
//
// if (Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && customBlock.isDoubleDropEnabled()) {
// drops = blockState.getBlock().getDrops();
// }
// }
// else {
xp = pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(blockState.getType());
if (!oneBlockPlant) {
//Kelp is actually two blocks mixed together
if (material == Material.KELP_PLANT || material == Material.KELP) {
amount = herbalismBehaviour.countAndMarkDoubleDropsKelp(blockState, greenTerra, this);
} else {
amount = herbalismBehaviour.countAndMarkDoubleDropsMultiBlockPlant(blockState, greenTerra, this);
}
xp *= amount;
} else {
/* MARK SINGLE BLOCK CROP FOR DOUBLE DROP */
if (checkDoubleDrop(blockState))
pluginRef.getBlockTools().markDropsAsBonus(blockState, greenTerra);
}
if (Permissions.greenThumbPlant(player, material)) {
processGreenThumbPlants(blockState, greenTerra);
}
//} mod config close
applyXpGain(xp, XPGainReason.PVE);
//Handle rewards, xp, ability interactions, etc
processHerbalismOnBlocksBroken(blockBreakEvent, brokenBlocks);
}
public boolean isOneBlockPlant(Material material) {
return !pluginRef.getMaterialMapStore().isMultiBlock(material);
/**
* Process rewards for a set of plant blocks for Herbalism
* @param blockBreakEvent the block break event
* @param brokenPlants plant blocks to process
*/
private void processHerbalismOnBlocksBroken(BlockBreakEvent blockBreakEvent, HashSet<Block> brokenPlants) {
BlockState originalBreak = blockBreakEvent.getBlock().getState();
//TODO: The design of Green Terra needs to change, this is a mess
if(pluginRef.getPermissionTools().greenThumbPlant(getPlayer(), originalBreak.getType())) {
processGreenThumbPlants(originalBreak, isGreenTerraActive());
}
/*
* Mark blocks for double drops
* Be aware of the hacky interactions we are doing with Chorus Plants
*/
checkDoubleDropsOnBrokenPlants(brokenPlants);
//It would take an expensive algorithm to predict which parts of a Chorus Tree will break as a result of root break
//So this hacky method is used instead
ArrayList<BlockSnapshot> delayedChorusBlocks = new ArrayList<>(); //Blocks that will be checked in future ticks
HashSet<Block> noDelayPlantBlocks = new HashSet<>(); //Blocks that will be checked immediately
for(Block brokenPlant : brokenPlants) {
/*
* This check is to make XP bars appear to work properly with Chorus Trees by giving XP for the originalBreak immediately instead of later
*/
if(brokenPlant.getLocation().equals(originalBreak.getBlock().getLocation())) {
//If its the same block as the original, we are going to directly check it for being a valid XP gain and add it to the nonChorusBlocks list even if its a chorus block
//This stops a delay from happening when bringing up the XP bar for chorus trees
if(!pluginRef.getPlaceStore().isTrue(originalBreak)) {
//Even if its a chorus block, the original break will be moved to nonChorusBlocks for immediate XP rewards
noDelayPlantBlocks.add(brokenPlant);
} else {
if(isChorusTree(brokenPlant.getType())) {
//If its a chorus tree AND it was marked as true in the placestore then we add this block to the list of chorus blocks
delayedChorusBlocks.add(new BlockSnapshot(brokenPlant.getType(), brokenPlant));
} else {
noDelayPlantBlocks.add(brokenPlant); //If its not a chorus plant that was marked as unnatural but it was marked unnatural, put it in the nodelay list to be handled
}
}
} else if(isChorusTree(brokenPlant.getType())) {
//Chorus Blocks get checked for XP several ticks later to avoid expensive calculations
delayedChorusBlocks.add(new BlockSnapshot(brokenPlant.getType(), brokenPlant));
} else {
noDelayPlantBlocks.add(brokenPlant);
}
}
//Give out XP to the non-chorus blocks
if(noDelayPlantBlocks.size() > 0) {
//Note: Will contain 1 chorus block if the original block was a chorus block, this is to prevent delays for the XP bar
awardXPForPlantBlocks(noDelayPlantBlocks);
}
if(delayedChorusBlocks.size() > 0) {
//Check XP for chorus blocks
DelayedHerbalismXPCheckTask delayedHerbalismXPCheckTask = new DelayedHerbalismXPCheckTask(mcMMOPlayer, delayedChorusBlocks);
//Large delay because the tree takes a while to break
delayedHerbalismXPCheckTask.runTaskLater(pluginRef, 20); //Calculate Chorus XP + Bonus Drops 1 tick later
}
}
public void checkDoubleDropsOnBrokenPlants(Collection<Block> brokenPlants) {
for(Block brokenPlant : brokenPlants) {
BlockState brokenPlantState = brokenPlant.getState();
BlockData plantData = brokenPlantState.getBlockData();
//Check for double drops
if(!pluginRef.getPlaceStore().isTrue(brokenPlant)) {
/*
*
* Natural Blocks
*
*
*
*/
//Not all things that are natural should give double drops, make sure its fully mature as well
if(plantData instanceof Ageable) {
Ageable ageable = (Ageable) plantData;
if(isAgeableMature(ageable) || isBizarreAgeable(plantData)) {
markForBonusDrops(brokenPlantState);
}
} else if(checkDoubleDrop(brokenPlantState)) {
//Add metadata to mark this block for double or triple drops
markForBonusDrops(brokenPlantState);
}
} else {
/*
*
* Unnatural Blocks
*
*/
//If its a Crop we need to reward XP when its fully grown
if(isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
//Add metadata to mark this block for double or triple drops
markForBonusDrops(brokenPlantState);
}
}
}
}
/**
* Checks if BlockData is ageable and we can trust that age for Herbalism rewards/XP reasons
* The age of Cactus and sugar canes seems to be useless to use, hence they are bizarre
* @param blockData target BlockData
* @return returns true if the ageable is trustworthy for Herbalism XP / Rewards
*/
public boolean isBizarreAgeable(BlockData blockData) {
if(blockData instanceof Ageable) {
//Catcus and Sugar Canes cannot be trusted
switch(blockData.getMaterial()) {
case CACTUS:
case SUGAR_CANE:
return true;
default:
return false;
}
}
return false;
}
public void markForBonusDrops(BlockState brokenPlantState) {
//Add metadata to mark this block for double or triple drops
boolean awardTriple = mcMMOPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA);
pluginRef.getBlockTools().markDropsAsBonus(brokenPlantState, awardTriple);
}
/**
* Checks if a block is an ageable and if that ageable is fully mature
* @param plantData target plant
* @return returns true if the block is both an ageable and fully mature
*/
public boolean isAgeableAndFullyMature(BlockData plantData) {
return plantData instanceof Ageable && isAgeableMature((Ageable) plantData);
}
public void awardXPForPlantBlocks(HashSet<Block> brokenPlants) {
int xpToReward = 0;
for(Block brokenPlantBlock : brokenPlants) {
BlockState brokenBlockNewState = brokenPlantBlock.getState();
BlockData plantData = brokenBlockNewState.getBlockData();
if(pluginRef.getPlaceStore().isTrue(brokenBlockNewState)) {
/*
*
* Unnatural Blocks
*
*
*/
//If its a Crop we need to reward XP when its fully grown
if(isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenBlockNewState.getType());
}
//Mark it as natural again as it is being broken
pluginRef.getPlaceStore().setFalse(brokenBlockNewState);
} else {
/*
*
* Natural Blocks
*
*
*/
//Calculate XP
if(plantData instanceof Ageable) {
Ageable plantAgeable = (Ageable) plantData;
if(isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) {
xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenBlockNewState.getType());
}
} else {
xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenPlantBlock.getType());
}
}
}
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Plants processed: "+brokenPlants.size());
}
//Reward XP
if(xpToReward > 0) {
applyXpGain(xpToReward, XPGainReason.PVE, XPGainSource.SELF);
}
}
public boolean isAgeableMature(Ageable ageable) {
return ageable.getAge() == ageable.getMaximumAge()
&& ageable.getAge() != 0;
}
/**
* Award XP for any blocks that used to be something else but are now AIR
* @param brokenPlants snapshot of broken blocks
*/
public void awardXPForBlockSnapshots(ArrayList<BlockSnapshot> brokenPlants) {
/*
* This handles XP for blocks that we need to check are broken after the fact
* This only applies to chorus trees right now
*/
int xpToReward = 0;
int blocksGivingXP = 0;
for(BlockSnapshot blockSnapshot : brokenPlants) {
BlockState brokenBlockNewState = blockSnapshot.getBlockRef().getState();
//Remove metadata from the snapshot of blocks
if(brokenBlockNewState.hasMetadata(MetadataConstants.BONUS_DROPS_METAKEY)) {
brokenBlockNewState.removeMetadata(MetadataConstants.BONUS_DROPS_METAKEY, pluginRef);
}
//If the block is not AIR that means it wasn't broken
if(brokenBlockNewState.getType() != Material.AIR) {
continue;
}
if(pluginRef.getPlaceStore().isTrue(brokenBlockNewState)) {
//Mark it as natural again as it is being broken
pluginRef.getPlaceStore().setFalse(brokenBlockNewState);
} else {
//TODO: Do we care about chorus flower age?
//Calculate XP for the old type
xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(blockSnapshot.getOldType());
blocksGivingXP++;
}
}
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Chorus Plants checked for XP: "+brokenPlants.size());
mcMMOPlayer.getPlayer().sendMessage("Valid Chorus Plant XP Gains: "+blocksGivingXP);
}
//Reward XP
if(xpToReward > 0) {
applyXpGain(xpToReward, XPGainReason.PVE, XPGainSource.SELF);
}
}
/**
* Process and return plant blocks from a BlockBreakEvent
* @param blockBreakEvent target event
* @return a set of plant-blocks that were broken as a result of this event
*/
private HashSet<Block> getBrokenHerbalismBlocks(BlockBreakEvent blockBreakEvent) {
//Get an updated capture of this block
BlockState originalBlockBlockState = blockBreakEvent.getBlock().getState();
Material originalBlockMaterial = originalBlockBlockState.getType();
HashSet<Block> blocksBroken = new HashSet<>(); //Blocks broken
//Check if this block is a one block plant or not
boolean oneBlockPlant = isOneBlockPlant(originalBlockMaterial);
if(oneBlockPlant) {
//If the block is a one-block plant return only that
blocksBroken.add(originalBlockBlockState.getBlock());
} else {
//If the block is a multi-block structure, capture a set of all blocks broken and return that
blocksBroken = getBrokenBlocksMultiBlockPlants(originalBlockBlockState, blockBreakEvent);
}
//Return all broken plant-blocks
return blocksBroken;
}
private HashSet<Block> getBrokenChorusBlocks(BlockState originalBreak) {
HashSet<Block> traversedBlocks = grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>());
return traversedBlocks;
}
private HashSet<Block> grabChorusTreeBrokenBlocksRecursive(Block currentBlock, HashSet<Block> traversed) {
if (!isChorusTree(currentBlock.getType()))
return traversed;
// Prevent any infinite loops, who needs more than 256 chorus anyways
if (traversed.size() > 256)
return traversed;
if (!traversed.add(currentBlock))
return traversed;
//Grab all Blocks in the Tree
for (BlockFace blockFace : new BlockFace[] { BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST ,BlockFace.WEST})
grabChorusTreeBrokenBlocksRecursive(currentBlock.getRelative(blockFace, 1), traversed);
traversed.add(currentBlock);
return traversed;
}
/**
* Grab a set of all plant blocks that are broken as a result of this event
* The method to grab these blocks is a bit hacky and does not hook into the API
* Basically we expect the blocks to be broken if this event is not cancelled and we determine which block are broken on our end rather than any event state captures
*
* @param blockBreakEvent target event
* @return a set of plant-blocks broken from this event
*/
protected HashSet<Block> getBrokenBlocksMultiBlockPlants(BlockState originalBlockBroken, BlockBreakEvent blockBreakEvent) {
//Track the broken blocks
HashSet<Block> brokenBlocks;
if (isChorusBranch(originalBlockBroken.getType())) {
brokenBlocks = getBrokenChorusBlocks(originalBlockBroken);
} else {
brokenBlocks = getBlocksBrokenAbove(originalBlockBroken);
}
return brokenBlocks;
}
private boolean isChorusBranch(Material blockType) {
return blockType == Material.CHORUS_PLANT;
}
private boolean isChorusTree(Material blockType) {
return blockType == Material.CHORUS_PLANT || blockType == Material.CHORUS_FLOWER;
}
/**
* Grabs blocks upwards from a target block
* A lot of Plants/Crops in Herbalism only break vertically from a broken block
* The vertical search returns early if it runs into anything that is not a multi-block plant
* Multi-block plants are hard-coded and kept in {@link com.gmail.nossr50.core.MaterialMapStore}
*
* @param breakPointBlockState The point of the "break"
* @return A set of blocks above the target block which can be assumed to be broken
*/
private HashSet<Block> getBlocksBrokenAbove(BlockState breakPointBlockState) {
HashSet<Block> brokenBlocks = new HashSet<>();
Block block = breakPointBlockState.getBlock();
//Add the initial block to the set
brokenBlocks.add(block);
//Limit our search
int maxHeight = 255;
// Search vertically for multi-block plants, exit early if any non-multi block plants
for (int y = 1; y < maxHeight; y++) {
//TODO: Should this grab state? It would be more expensive..
Block relativeUpBlock = block.getRelative(BlockFace.UP, y);
//Abandon our search if the block isn't multi
if(!pluginRef.getMaterialMapStore().isMultiBlockPlant(relativeUpBlock.getType()))
break;
brokenBlocks.add(relativeUpBlock);
}
return brokenBlocks;
}
/**
* If the plant is considered a one block plant
* This is determined by seeing if it exists in a hard-coded collection of Multi-Block plants
* @param material target plant material
* @return true if the block is not contained in the collection of multi-block plants
*/
private boolean isOneBlockPlant(Material material) {
return !pluginRef.getMaterialMapStore().isMultiBlockPlant(material);
}
/**
@@ -324,7 +669,7 @@ public class HerbalismManager extends SkillManager {
return;
}
if (!handleBlockState(blockState, greenTerra)) {
if (!processGrowingPlants(blockState, greenTerra)) {
return;
}
@@ -340,7 +685,7 @@ public class HerbalismManager extends SkillManager {
new HerbalismBlockUpdaterTask(blockState).runTaskLater(pluginRef, 0);
}
private boolean handleBlockState(BlockState blockState, boolean greenTerra) {
private boolean processGrowingPlants(BlockState blockState, boolean greenTerra) {
int greenThumbStage = getGreenThumbStage();
blockState.setMetadata(MetadataConstants.GREEN_THUMB_METAKEY, new FixedMetadataValue(pluginRef, (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)));

View File

@@ -12,7 +12,6 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
@@ -51,7 +50,7 @@ public class MiningManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DEMOLITIONS_EXPERTISE))
return false;
return getSkillLevel() >= miningBehaviour.getDemolitionExpertUnlockLevel() && Permissions.demolitionsExpertise(getPlayer());
return getSkillLevel() >= miningBehaviour.getDemolitionExpertUnlockLevel() && pluginRef.getPermissionTools().demolitionsExpertise(getPlayer());
}
public boolean canDetonate() {
@@ -59,7 +58,7 @@ public class MiningManager extends SkillManager {
return canUseBlastMining() && player.isSneaking()
&& miningBehaviour.isDetonator(player.getInventory().getItemInMainHand())
&& Permissions.remoteDetonation(player);
&& pluginRef.getPermissionTools().remoteDetonation(player);
}
public boolean canUseBlastMining() {
@@ -71,11 +70,11 @@ public class MiningManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_BIGGER_BOMBS))
return false;
return getSkillLevel() >= miningBehaviour.getBiggerBombsUnlockLevel() && Permissions.biggerBombs(getPlayer());
return getSkillLevel() >= miningBehaviour.getBiggerBombsUnlockLevel() && pluginRef.getPermissionTools().biggerBombs(getPlayer());
}
public boolean canDoubleDrop() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS);
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS) && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS);
}
/**

View File

@@ -7,7 +7,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.sounds.SoundManager;
@@ -233,7 +232,7 @@ public class RepairManager extends SkillManager {
private short repairCalculate(short durability, int repairAmount) {
Player player = getPlayer();
if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_REPAIR_MASTERY)
if (pluginRef.getPermissionTools().isSubSkillEnabled(player, SubSkillType.REPAIR_REPAIR_MASTERY)
&& pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_REPAIR_MASTERY)) {
double maxBonusCalc = pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getMaxBonus(SubSkillType.REPAIR_REPAIR_MASTERY) / 100.0D;
@@ -243,7 +242,7 @@ public class RepairManager extends SkillManager {
repairAmount += bonus;
}
if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_SUPER_REPAIR) && checkPlayerProcRepair()) {
if (pluginRef.getPermissionTools().isSubSkillEnabled(player, SubSkillType.REPAIR_SUPER_REPAIR) && checkPlayerProcRepair()) {
repairAmount *= 2.0D;
}
@@ -285,12 +284,12 @@ public class RepairManager extends SkillManager {
return;
}
if (Permissions.arcaneBypass(player)) {
if (pluginRef.getPermissionTools().arcaneBypass(player)) {
pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Repair.Arcane.Perfect");
return;
}
if (getArcaneForgingRank() == 0 || !Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_ARCANE_FORGING)) {
if (getArcaneForgingRank() == 0 || !pluginRef.getPermissionTools().isSubSkillEnabled(player, SubSkillType.REPAIR_ARCANE_FORGING)) {
for (Enchantment enchant : enchants.keySet()) {
item.removeEnchantment(enchant);
}

View File

@@ -9,7 +9,6 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
import com.gmail.nossr50.util.sounds.SoundManager;
@@ -66,12 +65,12 @@ public class SalvageManager extends SkillManager {
}
// Permissions checks on material and item types
if (!Permissions.salvageItemType(player, salvageable.getSalvageItemType())) {
if (!pluginRef.getPermissionTools().salvageItemType(player, salvageable.getSalvageItemType())) {
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
return;
}
if (!Permissions.salvageMaterialType(player, salvageable.getSalvageItemMaterialCategory())) {
if (!pluginRef.getPermissionTools().salvageMaterialType(player, salvageable.getSalvageItemMaterialCategory())) {
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
return;
}
@@ -203,7 +202,7 @@ public class SalvageManager extends SkillManager {
}*/
public double getExtractFullEnchantChance() {
if (Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
if (pluginRef.getPermissionTools().hasSalvageEnchantBypassPerk(getPlayer()))
return 100.0D;
return pluginRef.getConfigManager().getConfigSalvage().getConfigArcaneSalvage().getExtractFullEnchantChance().get(getArcaneSalvageRank());
@@ -216,7 +215,7 @@ public class SalvageManager extends SkillManager {
private ItemStack arcaneSalvageCheck(Map<Enchantment, Integer> enchants) {
Player player = getPlayer();
if (!pluginRef.getRankTools().hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !Permissions.arcaneSalvage(player)) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !pluginRef.getPermissionTools().arcaneSalvage(player)) {
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed");
return null;
}
@@ -238,7 +237,7 @@ public class SalvageManager extends SkillManager {
}
if (!salvageBehaviour.isArcaneSalvageEnchantLoss()
|| Permissions.hasSalvageEnchantBypassPerk(player)
|| pluginRef.getPermissionTools().hasSalvageEnchantBypassPerk(player)
|| pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true);

View File

@@ -7,7 +7,6 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.event.inventory.FurnaceBurnEvent;
import org.bukkit.inventory.ItemStack;
@@ -18,7 +17,7 @@ public class SmeltingManager extends SkillManager {
}
public boolean isSecondSmeltSuccessful() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_SECOND_SMELT)
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_SECOND_SMELT)
&& pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SMELTING_SECOND_SMELT, getPlayer());
}

View File

@@ -8,7 +8,6 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
@@ -24,22 +23,22 @@ public class SwordsManager extends SkillManager {
}
public boolean canActivateAbility() {
return mcMMOPlayer.getToolPreparationMode(ToolType.SWORD) && Permissions.serratedStrikes(getPlayer());
return mcMMOPlayer.getToolPreparationMode(ToolType.SWORD) && pluginRef.getPermissionTools().serratedStrikes(getPlayer());
}
public boolean canUseStab() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_STAB) && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_STAB);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_STAB) && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_STAB);
}
public boolean canUseRupture() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_RUPTURE) && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_RUPTURE);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_RUPTURE) && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_RUPTURE);
}
public boolean canUseCounterAttack(Entity target) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_COUNTER_ATTACK))
return false;
return target instanceof LivingEntity && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_COUNTER_ATTACK);
return target instanceof LivingEntity && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_COUNTER_ATTACK);
}
public boolean canUseSerratedStrike() {

View File

@@ -1,22 +1,25 @@
package com.gmail.nossr50.skills.taming;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.events.fake.FakeEntityTameEvent;
import com.gmail.nossr50.datatypes.skills.behaviours.TamingBehaviour;
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
import com.gmail.nossr50.datatypes.skills.subskills.taming.TamingSummon;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
@@ -25,72 +28,79 @@ import java.util.HashMap;
import java.util.List;
public class TamingManager extends SkillManager {
private HashMap<EntityType, List<TrackedTamingEntity>> summonedEntities = new HashMap<>();
//TODO: Temporary cache, will be changed in 2.2
private long lastSummonTimeStamp;
private TamingBehaviour tamingBehaviour;
private HashMap<CallOfTheWildType, List<TrackedTamingEntity>> playerSummonedEntities;
public TamingManager(mcMMO pluginRef, McMMOPlayer mcMMOPlayer) {
super(pluginRef, mcMMOPlayer, PrimarySkillType.TAMING);
init();
}
protected void addToTracker(LivingEntity livingEntity) {
TrackedTamingEntity trackedEntity = new TrackedTamingEntity(livingEntity);
//TODO: Hacky stuff for 2.1, will be cleaned up in 2.2
private void init() {
//Init Behaviour
tamingBehaviour = new TamingBehaviour(pluginRef);
if (!summonedEntities.containsKey(livingEntity.getType())) {
summonedEntities.put(livingEntity.getType(), new ArrayList<>());
//prevents accidentally summoning too many things when holding down left click
lastSummonTimeStamp = 0L;
//Init per-player tracking of summoned entities
initPerPlayerSummonTracking();
}
private void initPerPlayerSummonTracking() {
playerSummonedEntities = new HashMap<>();
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
playerSummonedEntities.put(callOfTheWildType, new ArrayList<TrackedTamingEntity>());
}
summonedEntities.get(livingEntity.getType()).add(trackedEntity);
}
protected List<TrackedTamingEntity> getTrackedEntities(EntityType entityType) {
return summonedEntities.get(entityType);
}
protected void removeFromTracker(TrackedTamingEntity trackedEntity) {
summonedEntities.get(trackedEntity.getLivingEntity().getType()).remove(trackedEntity);
}
public boolean canUseThickFur() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_THICK_FUR)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_THICK_FUR);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_THICK_FUR);
}
public boolean canUseEnvironmentallyAware() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_ENVIRONMENTALLY_AWARE)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_ENVIRONMENTALLY_AWARE);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_ENVIRONMENTALLY_AWARE);
}
public boolean canUseShockProof() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_SHOCK_PROOF)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_SHOCK_PROOF);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_SHOCK_PROOF);
}
public boolean canUseHolyHound() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_ENVIRONMENTALLY_AWARE)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_HOLY_HOUND);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_HOLY_HOUND);
}
public boolean canUseFastFoodService() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_FAST_FOOD_SERVICE)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_FAST_FOOD_SERVICE);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_FAST_FOOD_SERVICE);
}
public boolean canUseSharpenedClaws() {
return pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_SHARPENED_CLAWS)
&& Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_SHARPENED_CLAWS);
&& pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_SHARPENED_CLAWS);
}
public boolean canUseGore() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_GORE))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_GORE))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_GORE);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_GORE);
}
public boolean canUseBeastLore() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_BEAST_LORE))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_BEAST_LORE))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_BEAST_LORE);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.TAMING_BEAST_LORE);
}
/**
@@ -99,17 +109,16 @@ public class TamingManager extends SkillManager {
* @param entity The LivingEntity to award XP for
*/
public void awardTamingXP(LivingEntity entity) {
applyXpGain(pluginRef.getDynamicSettingsManager().getExperienceManager().getTamingXp(entity.getType()), XPGainReason.PVE);
applyXpGain(ExperienceConfig.getInstance().getTamingXP(entity.getType()), XPGainReason.PVE);
}
/**
* Apply the Fast Food Service ability.
*
* @param wolf The wolf using the ability
* @param wolf The wolf using the ability
* @param damage The damage being absorbed by the wolf
*/
public void fastFoodService(Wolf wolf, double damage) {
//chance (3rd param)
if (!pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.TAMING_FAST_FOOD_SERVICE, getPlayer())) {
return;
}
@@ -134,62 +143,66 @@ public class TamingManager extends SkillManager {
return 0;
}
pluginRef.getBleedTimerTask().add(target, getPlayer(), Taming.getInstance().getGoreBleedTicks(), 1, 2);
pluginRef.getBleedTimerTask().add(target, getPlayer(), pluginRef.getConfigManager().getConfigTaming().getSubSkills().getGore().getGoreBleedTicks(), 1, 2);
if (target instanceof Player) {
pluginRef.getNotificationManager().sendPlayerInformation((Player) target, NotificationType.SUBSKILL_MESSAGE, "Combat.StruckByGore");
pluginRef.getNotificationManager().sendPlayerInformation((Player)target, NotificationType.SUBSKILL_MESSAGE, "Combat.StruckByGore");
}
pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.Gore");
damage = (damage * Taming.getInstance().getGoreModifier()) - damage;
damage = (damage * pluginRef.getConfigManager().getConfigTaming().getSubSkills().getGore().getGoreMofifier()) - damage;
return damage;
}
public double getSharpenedClawsDamage() {
return Taming.getInstance().getSharpenedClawsBonusDamage();
//TODO: Add tooltips to /taming for this
public double sharpenedClaws(boolean PVE) {
if(PVE)
return pluginRef.getConfigManager().getConfigTaming().getSubSkills().getSharpenedClaws().getBonusDamage().getPVEModifier();
else
return pluginRef.getConfigManager().getConfigTaming().getSubSkills().getSharpenedClaws().getBonusDamage().getPVPModifier();
}
/**
* Summon an ocelot to your side.
*/
public void summonOcelot() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
return;
if (!Permissions.callOfTheWild(getPlayer(), EntityType.OCELOT)) {
if (!pluginRef.getPermissionTools().callOfTheWild(getPlayer(), EntityType.OCELOT)) {
return;
}
callOfTheWild(EntityType.OCELOT, MainConfig.getInstance().getTamingCOTWCost(EntityType.OCELOT));
processCallOfTheWild();
}
/**
* Summon a wolf to your side.
*/
public void summonWolf() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
return;
if (!Permissions.callOfTheWild(getPlayer(), EntityType.WOLF)) {
if (!pluginRef.getPermissionTools().callOfTheWild(getPlayer(), EntityType.WOLF)) {
return;
}
callOfTheWild(EntityType.WOLF, MainConfig.getInstance().getTamingCOTWCost(EntityType.WOLF));
processCallOfTheWild();
}
/**
* Summon a horse to your side.
*/
public void summonHorse() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_CALL_OF_THE_WILD))
return;
if (!Permissions.callOfTheWild(getPlayer(), EntityType.HORSE)) {
if (!pluginRef.getPermissionTools().callOfTheWild(getPlayer(), EntityType.HORSE)) {
return;
}
callOfTheWild(EntityType.HORSE, MainConfig.getInstance().getTamingCOTWCost(EntityType.HORSE));
processCallOfTheWild();
}
/**
@@ -223,10 +236,10 @@ public class TamingManager extends SkillManager {
}
public void pummel(LivingEntity target, Wolf wolf) {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_PUMMEL))
if(!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_PUMMEL))
return;
if (!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(AdvancedConfig.getInstance().getPummelChance(), getPlayer(), SubSkillType.TAMING_PUMMEL)))
if(!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getStaticChance(SubSkillType.TAMING_PUMMEL), getPlayer(), SubSkillType.TAMING_PUMMEL)))
return;
ParticleEffectUtils.playGreaterImpactEffect(target);
@@ -242,9 +255,11 @@ public class TamingManager extends SkillManager {
}
public void attackTarget(LivingEntity target) {
if (target instanceof Tameable) {
if(target instanceof Tameable)
{
Tameable tameable = (Tameable) target;
if (tameable.getOwner() == getPlayer()) {
if(tameable.getOwner() == getPlayer())
{
return;
}
}
@@ -266,133 +281,258 @@ public class TamingManager extends SkillManager {
}
}
private void processCallOfTheWild() {
//Prevent summoning too many things accidentally if a player holds down the button
if(lastSummonTimeStamp + 150 > System.currentTimeMillis()) {
return;
} else {
lastSummonTimeStamp = System.currentTimeMillis();
}
Player player = getPlayer();
ItemStack itemInMainHand = player.getInventory().getItemInMainHand();
//Check if the item the player is currently holding is a COTW item
if(isCOTWItem(itemInMainHand)) {
//Get the summoning type
CallOfTheWildType callOfTheWildType = pluginRef.getDynamicSettingsManager().getTamingItemManager().getCallType(itemInMainHand.getType());
TamingSummon tamingSummon = tamingBehaviour.getSummon(callOfTheWildType);
//Players will pay for the cost if at least one thing was summoned
int amountSummoned = 0;
//Check to see if players have the correct amount of the item required to summon
if(itemInMainHand.getAmount() >= tamingSummon.getItemAmountRequired()) {
//Initial Spawn location
Location spawnLocation = Misc.getLocationOffset(player.getLocation(), 1);
//COTW can summon multiple entities per usage
for (int i = 0; i < tamingSummon.getEntitiesSummoned(); i++) {
if (getAmountCurrentlySummoned(callOfTheWildType) >= tamingSummon.getSummonCap()) {
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Taming.Summon.COTW.Limit",
String.valueOf(tamingSummon.getSummonCap()),
StringUtils.getCapitalized(callOfTheWildType.toString()));
break;
}
spawnLocation = Misc.getLocationOffset(spawnLocation, 1);
spawnCOTWEntity(callOfTheWildType, spawnLocation, tamingSummon.getEntityType());
//Inform the player about what they have just done
if (tamingSummon.getSummonLifespan() > 0) {
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Taming.Summon.COTW.Success.WithLifespan",
StringUtils.getCapitalized(callOfTheWildType.toString()), String.valueOf(tamingSummon.getSummonLifespan()));
} else {
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Taming.Summon.COTW.Success.WithoutLifespan", StringUtils.getCapitalized(callOfTheWildType.toString()));
}
//Send Sound
SoundManager.sendSound(player, player.getLocation(), SoundType.ABILITY_ACTIVATED_GENERIC);
amountSummoned++;
}
//Remove items from the player if they had at least one entity summoned successfully
if(amountSummoned >= 1) {
//Remove the items used to summon
int itemAmountAfterPayingCost = itemInMainHand.getAmount() - tamingSummon.getItemAmountRequired();
itemInMainHand.setAmount(itemAmountAfterPayingCost);
player.updateInventory();
}
} else {
//Player did not have enough of the item in their main hand
int difference = tamingSummon.getItemAmountRequired() - itemInMainHand.getAmount();
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(player, "Taming.Summon.COTW.NeedMoreItems", String.valueOf(difference), StringUtils.getPrettyItemString(itemInMainHand.getType()));
}
}
}
private void spawnCOTWEntity(CallOfTheWildType callOfTheWildType, Location spawnLocation, EntityType entityType) {
switch(callOfTheWildType) {
case CAT:
//Entity type is needed for cats because in 1.13 and below we spawn ocelots, in 1.14 and above we spawn cats
spawnCat(spawnLocation, entityType);
break;
case HORSE:
spawnHorse(spawnLocation);
break;
case WOLF:
spawnWolf(spawnLocation);
break;
}
}
private void spawnWolf(Location spawnLocation) {
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, EntityType.WOLF);
//This is used to prevent XP gains for damaging this entity
applyMetaDataToCOTWEntity(callOfWildEntity);
setBaseCOTWEntityProperties(callOfWildEntity);
((Wolf) callOfWildEntity).setAdult();
addToTracker(callOfWildEntity, CallOfTheWildType.WOLF);
//Setup wolf stats
callOfWildEntity.setMaxHealth(20.0);
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.WOLF)));
}
private void spawnCat(Location spawnLocation, EntityType entityType) {
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, entityType);
//This is used to prevent XP gains for damaging this entity
applyMetaDataToCOTWEntity(callOfWildEntity);
setBaseCOTWEntityProperties(callOfWildEntity);
addToTracker(callOfWildEntity, CallOfTheWildType.CAT);
//Randomize the cat
if(callOfWildEntity instanceof Ocelot) {
int numberOfTypes = Ocelot.Type.values().length;
((Ocelot) callOfWildEntity).setCatType(Ocelot.Type.values()[Misc.getRandom().nextInt(numberOfTypes)]);
((Ocelot) callOfWildEntity).setAdult();
} else if(callOfWildEntity instanceof Cat) {
int numberOfTypes = Cat.Type.values().length;
((Cat) callOfWildEntity).setCatType(Cat.Type.values()[Misc.getRandom().nextInt(numberOfTypes)]);
((Cat) callOfWildEntity).setAdult();
}
callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(entityType)));
//Particle effect
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
}
private void spawnHorse(Location spawnLocation) {
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, EntityType.HORSE);
applyMetaDataToCOTWEntity(callOfWildEntity);
setBaseCOTWEntityProperties(callOfWildEntity);
addToTracker(callOfWildEntity, CallOfTheWildType.HORSE);
//Randomize Horse
Horse horse = (Horse) callOfWildEntity;
callOfWildEntity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
horse.setJumpStrength(Math.max(pluginRef.getConfigManager().getConfigTaming().getMinHorseJumpStrength(),
Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, pluginRef.getConfigManager().getConfigTaming().getMaxHorseJumpStrength())));
horse.setAdult();
//TODO: setSpeed, once available
callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.HORSE)));
//Particle effect
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
}
private void setBaseCOTWEntityProperties(LivingEntity callOfWildEntity) {
((Tameable) callOfWildEntity).setOwner(getPlayer());
callOfWildEntity.setRemoveWhenFarAway(false);
}
private void applyMetaDataToCOTWEntity(LivingEntity callOfWildEntity) {
//This is used to prevent XP gains for damaging this entity
callOfWildEntity.setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
//This helps identify the entity as being summoned by COTW
callOfWildEntity.setMetadata(MetadataConstants.COTW_TEMPORARY_SUMMON, MetadataConstants.metadataValue);
}
/**
* Handle the Call of the Wild ability.
*
* @param type The type of entity to summon.
* @param summonAmount The amount of material needed to summon the entity
* Whether or not the itemstack is used for COTW
* @param itemStack target ItemStack
* @return true if it is used for any COTW
*/
private void callOfTheWild(EntityType type, int summonAmount) {
Player player = getPlayer();
ItemStack heldItem = player.getInventory().getItemInMainHand();
int heldItemAmount = heldItem.getAmount();
Location location = player.getLocation();
if (heldItemAmount < summonAmount) {
int moreAmount = summonAmount - heldItemAmount;
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.NotEnough", String.valueOf(moreAmount), StringUtils.getPrettyItemString(heldItem.getType()));
return;
}
if (!rangeCheck(type)) {
return;
}
int amount = MainConfig.getInstance().getTamingCOTWAmount(type);
int tamingCOTWLength = MainConfig.getInstance().getTamingCOTWLength(type);
for (int i = 0; i < amount; i++) {
if (!summonAmountCheck(type)) {
return;
}
location = Misc.getLocationOffset(location, 1);
LivingEntity callOfWildEntity = (LivingEntity) player.getWorld().spawnEntity(location, type);
FakeEntityTameEvent event = new FakeEntityTameEvent(callOfWildEntity, player);
pluginRef.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
continue;
}
callOfWildEntity.setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
((Tameable) callOfWildEntity).setOwner(player);
callOfWildEntity.setRemoveWhenFarAway(false);
addToTracker(callOfWildEntity);
switch (type) {
case OCELOT:
((Ocelot) callOfWildEntity).setCatType(Ocelot.Type.values()[1 + Misc.getRandom().nextInt(3)]);
break;
case WOLF:
callOfWildEntity.setMaxHealth(20.0);
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
break;
case HORSE:
Horse horse = (Horse) callOfWildEntity;
callOfWildEntity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
horse.setJumpStrength(Math.max(AdvancedConfig.getInstance().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, AdvancedConfig.getInstance().getMaxHorseJumpStrength())));
//TODO: setSpeed, once available
break;
default:
break;
}
if (Permissions.renamePets(player)) {
callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", player.getName(), StringUtils.getPrettyEntityTypeString(type)));
}
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
}
ItemStack leftovers = new ItemStack(heldItem);
leftovers.setAmount(heldItemAmount - summonAmount);
player.getInventory().setItemInMainHand(heldItemAmount == summonAmount ? null : leftovers);
String lifeSpan = "";
if (tamingCOTWLength > 0) {
lifeSpan = pluginRef.getLocaleManager().getString("Taming.Summon.Lifespan", tamingCOTWLength);
}
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Taming.Summon.Complete", lifeSpan);
player.playSound(location, Sound.ENTITY_FIREWORK_ROCKET_BLAST_FAR, 1F, 0.5F);
public boolean isCOTWItem(ItemStack itemStack) {
return pluginRef.getDynamicSettingsManager().getTamingItemManager().isCOTWItem(itemStack.getType());
}
private boolean rangeCheck(EntityType type) {
double range = MainConfig.getInstance().getTamingCOTWRange();
Player player = getPlayer();
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
private int getAmountCurrentlySummoned(CallOfTheWildType callOfTheWildType) {
//The tracker is unreliable so validate its contents first
recalibrateTracker();
if (range == 0) {
return true;
return playerSummonedEntities.get(callOfTheWildType).size();
}
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
private void addToTracker(LivingEntity livingEntity, CallOfTheWildType callOfTheWildType) {
TrackedTamingEntity trackedEntity = new TrackedTamingEntity(pluginRef, livingEntity, callOfTheWildType, this);
playerSummonedEntities.get(callOfTheWildType).add(trackedEntity);
}
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
public List<TrackedTamingEntity> getTrackedEntities(CallOfTheWildType callOfTheWildType) {
return playerSummonedEntities.get(callOfTheWildType);
}
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
public void removeFromTracker(TrackedTamingEntity trackedEntity) {
if(playerSummonedEntities.get(trackedEntity.getCallOfTheWildType()).contains(trackedEntity))
playerSummonedEntities.get(trackedEntity.getCallOfTheWildType()).remove(trackedEntity);
pluginRef.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Taming.Summon.COTW.TimeExpired", StringUtils.getPrettyEntityTypeString(trackedEntity.getLivingEntity().getType()));
}
/**
* Builds a new tracked list by determining which tracked things are still valid
*/
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
private void recalibrateTracker() {
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
ArrayList<TrackedTamingEntity> validEntities = getValidTrackedEntities(callOfTheWildType);
playerSummonedEntities.put(callOfTheWildType, validEntities); //Replace the old list with the new list
}
}
for (Entity entity : player.getNearbyEntities(range, range, range)) {
if (entity.getType() == type) {
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, Taming.getInstance().getCallOfTheWildFailureMessage(type));
return false;
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
private ArrayList<TrackedTamingEntity> getValidTrackedEntities(CallOfTheWildType callOfTheWildType) {
ArrayList<TrackedTamingEntity> validTrackedEntities = new ArrayList<>();
for(TrackedTamingEntity trackedTamingEntity : getTrackedEntities(callOfTheWildType)) {
LivingEntity livingEntity = trackedTamingEntity.getLivingEntity();
//Remove from existence
if(livingEntity != null && livingEntity.isValid()) {
validTrackedEntities.add(trackedTamingEntity);
}
}
return true;
return validTrackedEntities;
}
private boolean summonAmountCheck(EntityType entityType) {
Player player = getPlayer();
/**
* Remove all tracked entities from existence if they currently exist
* Clear the tracked entity lists afterwards
*/
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
public void cleanupAllSummons() {
for(List<TrackedTamingEntity> trackedTamingEntities : playerSummonedEntities.values()) {
for(TrackedTamingEntity trackedTamingEntity : trackedTamingEntities) {
LivingEntity livingEntity = trackedTamingEntity.getLivingEntity();
int maxAmountSummons = MainConfig.getInstance().getTamingCOTWMaxAmount(entityType);
//Remove from existence
if(livingEntity != null && livingEntity.isValid()) {
livingEntity.setHealth(0);
livingEntity.remove();
}
}
if (maxAmountSummons <= 0) {
return true;
//Clear the list
trackedTamingEntities.clear();
}
List<TrackedTamingEntity> trackedEntities = getTrackedEntities(entityType);
int summonAmount = trackedEntities == null ? 0 : trackedEntities.size();
if (summonAmount >= maxAmountSummons) {
pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Taming.Summon.Fail.TooMany", String.valueOf(maxAmountSummons));
return false;
}
return true;
}
}

View File

@@ -1,26 +1,31 @@
package com.gmail.nossr50.skills.taming;
import com.gmail.nossr50.config.MainConfig;
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID;
public class TrackedTamingEntity extends BukkitRunnable {
private LivingEntity livingEntity;
private final CallOfTheWildType callOfTheWildType;
private UUID id;
private int length;
private final TamingManager tamingManagerRef;
private final mcMMO pluginRef;
protected TrackedTamingEntity(LivingEntity livingEntity) {
protected TrackedTamingEntity(mcMMO pluginRef, LivingEntity livingEntity, CallOfTheWildType callOfTheWildType, TamingManager tamingManagerRef) {
this.tamingManagerRef = tamingManagerRef;
this.callOfTheWildType = callOfTheWildType;
this.livingEntity = livingEntity;
this.id = livingEntity.getUniqueId();
int tamingCOTWLength = MainConfig.getInstance().getTamingCOTWLength(livingEntity.getType());
int tamingCOTWLength = pluginRef.getConfigManager().getConfigTaming().getSubSkills().getCallOfTheWild()..getTamingCOTWLength(livingEntity.getType());
if (tamingCOTWLength > 0) {
this.length = tamingCOTWLength * Misc.TICK_CONVERSION_FACTOR;
@@ -35,17 +40,26 @@ public class TrackedTamingEntity extends BukkitRunnable {
location.getWorld().playSound(location, Sound.BLOCK_FIRE_EXTINGUISH, 0.8F, 0.8F);
ParticleEffectUtils.playCallOfTheWildEffect(livingEntity);
pluginRef.getCombatTools().dealDamage(livingEntity, livingEntity.getMaxHealth(), DamageCause.SUICIDE, livingEntity);
if(tamingManagerRef != null)
tamingManagerRef.removeFromTracker(this);
livingEntity.setHealth(0);
livingEntity.remove();
}
TamingManager.removeFromTracker(this);
this.cancel();
}
protected LivingEntity getLivingEntity() {
public CallOfTheWildType getCallOfTheWildType() {
return callOfTheWildType;
}
public LivingEntity getLivingEntity() {
return livingEntity;
}
protected UUID getID() {
public UUID getID() {
return id;
}
}

View File

@@ -9,8 +9,6 @@ import org.bukkit.inventory.ItemStack;
public class Unarmed {
// public static boolean blockCrackerSmoothBrick = MainConfig.getInstance().getUnarmedBlockCrackerSmoothbrickToCracked();
public static double berserkDamageModifier = 1.5;
public static long lastAttacked = 0;
public static long attackInterval = 750;
public static void handleItemPickup(Player player, EntityPickupItemEvent event) {
ItemStack[] storageContents = player.getInventory().getStorageContents();

View File

@@ -10,30 +10,40 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class UnarmedManager extends SkillManager {
private long lastAttacked;
private long attackInterval;
public UnarmedManager(mcMMO pluginRef, McMMOPlayer mcMMOPlayer) {
super(pluginRef, mcMMOPlayer, PrimarySkillType.UNARMED);
initUnarmedPerPlayerVars();
}
/**
* Inits variables used for each player for unarmed
*/
private void initUnarmedPerPlayerVars() {
lastAttacked = 0;
attackInterval = 750;
}
public boolean canActivateAbility() {
return mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && Permissions.berserk(getPlayer());
return mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && pluginRef.getPermissionTools().berserk(getPlayer());
}
public boolean canUseIronArm() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
}
public boolean canUseBerserk() {
@@ -44,7 +54,7 @@ public class UnarmedManager extends SkillManager {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.UNARMED_DISARM))
return false;
return target instanceof Player && ((Player) target).getInventory().getItemInMainHand().getType() != Material.AIR && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_DISARM);
return target instanceof Player && ((Player) target).getInventory().getItemInMainHand().getType() != Material.AIR && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_DISARM);
}
public boolean canDeflect() {
@@ -53,14 +63,14 @@ public class UnarmedManager extends SkillManager {
Player player = getPlayer();
return pluginRef.getItemTools().isUnarmed(player.getInventory().getItemInMainHand()) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_ARROW_DEFLECT);
return pluginRef.getItemTools().isUnarmed(player.getInventory().getItemInMainHand()) && pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_ARROW_DEFLECT);
}
public boolean canUseBlockCracker() {
if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.UNARMED_BLOCK_CRACKER))
return false;
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_BLOCK_CRACKER);
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_BLOCK_CRACKER);
}
public boolean blockCrackerCheck(BlockState blockState) {
@@ -68,8 +78,6 @@ public class UnarmedManager extends SkillManager {
return false;
}
BlockData data = blockState.getBlockData();
switch (blockState.getType()) {
case STONE_BRICKS:
/*if (!Unarmed.blockCrackerSmoothBrick) {
@@ -144,7 +152,7 @@ public class UnarmedManager extends SkillManager {
}
public boolean isPunchingCooldownOver() {
return (Unarmed.lastAttacked + Unarmed.attackInterval) <= System.currentTimeMillis();
return (lastAttacked + attackInterval) <= System.currentTimeMillis();
}
public double getIronArmDamage() {
@@ -164,8 +172,9 @@ public class UnarmedManager extends SkillManager {
* @return true if the defender was not disarmed, false otherwise
*/
private boolean hasIronGrip(Player defender) {
if (!Misc.isNPCEntityExcludingVillagers(defender) && Permissions.isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP)
&& pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_IRON_GRIP, getPlayer())) {
if (!Misc.isNPCEntityExcludingVillagers(defender)
&& pluginRef.getPermissionTools().isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP)
&& pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_IRON_GRIP, defender)) {
pluginRef.getNotificationManager().sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Defender");
pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Attacker");
@@ -174,4 +183,20 @@ public class UnarmedManager extends SkillManager {
return false;
}
public long getLastAttacked() {
return lastAttacked;
}
public void setLastAttacked(long lastAttacked) {
this.lastAttacked = lastAttacked;
}
public long getAttackInterval() {
return attackInterval;
}
public void setAttackInterval(long attackInterval) {
this.attackInterval = attackInterval;
}
}

View File

@@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.skills.behaviours.WoodcuttingBehaviour;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -36,7 +35,7 @@ public class WoodcuttingManager extends SkillManager {
}
public boolean canUseLeafBlower(ItemStack heldItem) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_LEAF_BLOWER)
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_LEAF_BLOWER)
&& pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.WOODCUTTING_LEAF_BLOWER)
&& pluginRef.getItemTools().isAxe(heldItem);
}
@@ -46,8 +45,8 @@ public class WoodcuttingManager extends SkillManager {
&& pluginRef.getItemTools().isAxe(heldItem);
}
public boolean canGetDoubleDrops() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
private boolean canGetDoubleDrops() {
return pluginRef.getPermissionTools().isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& pluginRef.getRankTools().hasReachedRank(1, getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.WOODCUTTING_HARVEST_LUMBER, getPlayer());
}
@@ -108,7 +107,7 @@ public class WoodcuttingManager extends SkillManager {
return;
}
dropBlocks(treeFellerBlocks);
dropTreeFellerLootFromBlocks(treeFellerBlocks);
treeFellerReachedThreshold = false; // Reset the value after we're done with Tree Feller each time.
}
@@ -247,7 +246,7 @@ public class WoodcuttingManager extends SkillManager {
*
* @param treeFellerBlocks List of blocks to be dropped
*/
private void dropBlocks(Set<BlockState> treeFellerBlocks) {
private void dropTreeFellerLootFromBlocks(Set<BlockState> treeFellerBlocks) {
Player player = getPlayer();
int xp = 0;
int processedLogCount = 0;