New skill 'Knock On Wood', changes to axe readying messages

This commit is contained in:
nossr50 2020-11-10 15:17:52 -08:00
parent 8f6819edc5
commit b31e1e533b
14 changed files with 168 additions and 38 deletions

View File

@ -1,4 +1,13 @@
Version 2.1.156
Added Woodcutting skill 'Knock on Wood' - This ability gives you goodies (saplings, xp orbs, apples, etc) when using Tree Feller
Tree Feller no longer gives non-wood items by default, it now requires Knock on Wood for additional loot
Added new permission node 'mcmmo.ability.woodcutting.knockonwood'
Added new locale line 'Woodcutting.SubSkill.KnockOnWood.Name'
Added new locale line 'Woodcutting.SubSkill.KnockOnWood.Stat'
Added new locale line 'Woodcutting.SubSkill.KnockOnWood.Description'
Added new locale line 'Woodcutting.SubSkill.KnockOnWood.Loot.Normal'
Added new locale line 'Woodcutting.SubSkill.KnockOnWood.Loot.Rank2'
When you raise your axe you will now see information about any super abilities on CD
Fixed a bug where Green Thumb would replant blocks floating in the air
Fixed a bug where the admin and party chat toggles in chat.yml didn't function as intended
* Fixed a bug where Master Angler rank 1 level requirement was set too high (default configs)
@ -8,6 +17,7 @@ Version 2.1.156
Removed incorrect translations of Master Angler from various locales
Modified Master Angler stat lines in /fishing
Updated Green Thumb description to mention that it needs a hoe
'Abilities.Limits.Tree_Feller_Threshold' in config.yml now defaults to 1000 instead of 500
NOTES:
You don't need to touch your config files, this update handles everything automagically.

View File

@ -22,6 +22,7 @@ public class WoodcuttingCommand extends SkillCommand {
private boolean canTreeFell;
private boolean canLeafBlow;
private boolean canDoubleDrop;
private boolean canKnockOnWood;
private boolean canSplinter;
private boolean canBarkSurgeon;
private boolean canNaturesBounty;
@ -56,6 +57,7 @@ public class WoodcuttingCommand extends SkillCommand {
canTreeFell = RankUtils.hasUnlockedSubskill(player, SubSkillType.WOODCUTTING_TREE_FELLER) && Permissions.treeFeller(player);
canDoubleDrop = canUseSubskill(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) && !skill.getDoubleDropsDisabled() && RankUtils.getRank(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) >= 1;
canLeafBlow = canUseSubskill(player, SubSkillType.WOODCUTTING_LEAF_BLOWER);
canKnockOnWood = canTreeFell && canUseSubskill(player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD);
/*canSplinter = canUseSubskill(player, SubSkillType.WOODCUTTING_SPLINTER);
canBarkSurgeon = canUseSubskill(player, SubSkillType.WOODCUTTING_BARK_SURGEON);
canNaturesBounty = canUseSubskill(player, SubSkillType.WOODCUTTING_NATURES_BOUNTY);*/
@ -70,6 +72,18 @@ public class WoodcuttingCommand extends SkillCommand {
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", doubleDropChanceLucky) : ""));
}
if (canKnockOnWood) {
String lootNote;
if(RankUtils.hasReachedRank(2, player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
lootNote = LocaleLoader.getString("Woodcutting.SubSkill.KnockOnWood.Loot.Rank2");
} else {
lootNote = LocaleLoader.getString("Woodcutting.SubSkill.KnockOnWood.Loot.Normal");
}
messages.add(getStatMessage(SubSkillType.WOODCUTTING_KNOCK_ON_WOOD, lootNote));
}
if (canLeafBlow) {
messages.add(LocaleLoader.getString("Ability.Generic.Template", LocaleLoader.getString("Woodcutting.Ability.0"), LocaleLoader.getString("Woodcutting.Ability.1")));
}

View File

@ -450,7 +450,7 @@ public class Config extends AutoUpdateConfigLoader {
public int getAbilityToolDamage() { return config.getInt("Abilities.Tools.Durability_Loss", 1); }
/* Thresholds */
public int getTreeFellerThreshold() { return config.getInt("Abilities.Limits.Tree_Feller_Threshold", 500); }
public int getTreeFellerThreshold() { return config.getInt("Abilities.Limits.Tree_Feller_Threshold", 1000); }
/*
* SKILL SETTINGS

View File

@ -14,8 +14,10 @@ import com.gmail.nossr50.datatypes.mods.CustomTool;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.SubSkill;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
@ -40,6 +42,7 @@ import com.gmail.nossr50.skills.swords.SwordsManager;
import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
@ -57,6 +60,7 @@ import net.kyori.adventure.identity.Identity;
import org.apache.commons.lang.Validate;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
@ -918,14 +922,25 @@ public class McMMOPlayer implements Identified {
if (skill != PrimarySkillType.WOODCUTTING && skill != PrimarySkillType.AXES) {
int timeRemaining = calculateTimeRemaining(ability);
if (!getAbilityMode(ability) && timeRemaining > 0) {
if (isAbilityOnCooldown(ability)) {
NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
return;
}
}
if (Config.getInstance().getAbilityMessagesEnabled()) {
/*
*
* IF THE TOOL IS AN AXE
*
*/
if(tool == ToolType.AXE) {
processAxeToolMessages();
} else {
NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, tool.getRaiseTool());
}
//Send Sound
SoundManager.sendSound(player, player.getLocation(), SoundType.TOOL_READY);
}
@ -934,6 +949,53 @@ public class McMMOPlayer implements Identified {
}
}
public void processAxeToolMessages() {
Block rayCast = player.getTargetBlock(null, 100);
/*
* IF BOTH TREE FELLER & SKULL SPLITTER ARE ON CD
*/
if(isAbilityOnCooldown(SuperAbilityType.TREE_FELLER) && isAbilityOnCooldown(SuperAbilityType.SKULL_SPLITTER)) {
tooTiredMultiple(PrimarySkillType.WOODCUTTING, SubSkillType.WOODCUTTING_TREE_FELLER, SuperAbilityType.TREE_FELLER, SubSkillType.AXES_SKULL_SPLITTER, SuperAbilityType.SKULL_SPLITTER);
/*
* IF TREE FELLER IS ON CD
* AND PLAYER IS LOOKING AT TREE
*/
} else if(isAbilityOnCooldown(SuperAbilityType.TREE_FELLER)
&& BlockUtils.isPartOfTree(rayCast)) {
raiseToolWithCooldowns(SubSkillType.WOODCUTTING_TREE_FELLER, SuperAbilityType.TREE_FELLER);
/*
* IF SKULL SPLITTER IS ON CD
*/
} else if(isAbilityOnCooldown(SuperAbilityType.SKULL_SPLITTER)) {
raiseToolWithCooldowns(SubSkillType.AXES_SKULL_SPLITTER, SuperAbilityType.SKULL_SPLITTER);
} else {
NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, ToolType.AXE.getRaiseTool());
}
}
private void tooTiredMultiple(PrimarySkillType primarySkillType, SubSkillType aSubSkill, SuperAbilityType aSuperAbility, SubSkillType bSubSkill, SuperAbilityType bSuperAbility) {
String aSuperAbilityCD = LocaleLoader.getString("Skills.TooTired.Named", aSubSkill.getLocaleName(), String.valueOf(calculateTimeRemaining(aSuperAbility)));
String bSuperAbilityCD = LocaleLoader.getString("Skills.TooTired.Named", bSubSkill.getLocaleName(), String.valueOf(calculateTimeRemaining(bSuperAbility)));
String allCDStr = aSuperAbilityCD + ", " + bSuperAbilityCD;
NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, "Skills.TooTired.Extra",
primarySkillType.getName(),
allCDStr);
}
private void raiseToolWithCooldowns(SubSkillType subSkillType, SuperAbilityType superAbilityType) {
NotificationManager.sendPlayerInformation(player, NotificationType.TOOL,
"Axes.Ability.Ready.Extra",
subSkillType.getLocaleName(),
String.valueOf(calculateTimeRemaining(superAbilityType)));
}
public boolean isAbilityOnCooldown(SuperAbilityType ability) {
return !getAbilityMode(ability) && calculateTimeRemaining(ability) > 0;
}
/**
* Calculate the time remaining until the ability's cooldown expires.
*

View File

@ -63,7 +63,7 @@ public enum PrimarySkillType {
UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS,
ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_STEEL_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)),
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE,
ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER));
ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD));
private final Class<? extends SkillManager> managerClass;
private final Color skillColor;

View File

@ -101,6 +101,7 @@ public enum SubSkillType {
/* Woodcutting */
/* WOODCUTTING_BARK_SURGEON(3),*/
WOODCUTTING_KNOCK_ON_WOOD(2),
WOODCUTTING_HARVEST_LUMBER(1),
WOODCUTTING_LEAF_BLOWER(1),
/* WOODCUTTING_NATURES_BOUNTY(3),

View File

@ -15,8 +15,6 @@ import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import org.bukkit.Location;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import java.util.List;
@ -47,8 +45,7 @@ public class ExcavationManager extends SkillManager {
//Spawn Vanilla XP orbs if a dice roll succeeds
if(RandomChanceUtil.rollDice(getArchaelogyExperienceOrbChance(), 100)) {
ExperienceOrb experienceOrb = (ExperienceOrb) getPlayer().getWorld().spawnEntity(location, EntityType.EXPERIENCE_ORB);
experienceOrb.setExperience(getExperienceOrbsReward());
Misc.spawnExperienceOrb(location, getExperienceOrbsReward());
}
xp += treasure.getXp();

View File

@ -301,8 +301,20 @@ public class WoodcuttingManager extends SkillManager {
processHarvestLumber(blockState);
} else if (BlockUtils.isNonWoodPartOfTree(blockState)) {
//Drop displaced non-woodcutting XP blocks
// Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK, 1);
if(RankUtils.hasUnlockedSubskill(player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK);
if(RankUtils.hasReachedRank(2, player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
if(RandomChanceUtil.rollDice(75, 100)) {
int randOrbCount = Math.max(1, Misc.getRandom().nextInt(50));
Misc.spawnExperienceOrb(blockState.getLocation(), randOrbCount);
}
}
} else {
Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK, 1);
}
}
blockState.setType(Material.AIR);

View File

@ -11,6 +11,7 @@ import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.util.random.RandomChanceSkill;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
@ -179,6 +180,10 @@ public final class BlockUtils {
return mcMMO.getMaterialMapStore().isTreeFellerDestructible(blockState.getType());
}
public static boolean isNonWoodPartOfTree(Material material) {
return mcMMO.getMaterialMapStore().isTreeFellerDestructible(material);
}
/**
* Determine if a given block should be affected by Flux Mining
*
@ -274,4 +279,8 @@ public final class BlockUtils {
}
return true;
}
public static boolean isPartOfTree(Block rayCast) {
return hasWoodcuttingXP(rayCast.getState()) || isNonWoodPartOfTree(rayCast.getType());
}
}

View File

@ -12,6 +12,7 @@ import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -310,4 +311,37 @@ public final class Misc {
public static boolean isPartyLeader(@NotNull McMMOPlayer mmoPlayer) {
return mmoPlayer.getParty().getLeader().getUniqueId().equals(mmoPlayer.getPlayer().getUniqueId());
}
// public static void spawnExperienceOrb(@NotNull Location location, int orbAmount, int experienceValue) {
// for (int i = 0; i < orbAmount; i++) {
// new SpawnOrbTask(location, experienceValue).runTaskLater(mcMMO.p, 20);
// }
// }
public static void spawnExperienceOrb(@NotNull Location location, int experienceValue) {
if(location.getWorld() == null)
return;
ExperienceOrb experienceOrb = (ExperienceOrb) location.getWorld().spawnEntity(location, EntityType.EXPERIENCE_ORB);
experienceOrb.setExperience(experienceValue);
}
private static class SpawnOrbTask extends BukkitRunnable {
private final Location location;
private int orbExpValue;
private SpawnOrbTask(Location location, int orbExpValue) {
this.location = location;
this.orbExpValue = orbExpValue;
}
@Override
public void run() {
if(location == null || location.getWorld() == null)
return;
ExperienceOrb experienceOrb = (ExperienceOrb) location.getWorld().spawnEntity(location, EntityType.EXPERIENCE_ORB);
experienceOrb.setExperience(orbExpValue);
}
}
}

View File

@ -303,7 +303,7 @@ Abilities:
Super_Breaker: 0
Tree_Feller: 0
Limits:
Tree_Feller_Threshold: 500
Tree_Feller_Threshold: 1000
Tools:
# Use more tool durability while using abilities. Set Durability_Loss to 0 to disable the extra durability damage.
Durability_Loss: 1

View File

@ -184,6 +184,7 @@ Axes.Ability.Bonus.4=Greater Impact
Axes.Ability.Bonus.5=Deal {0} Bonus DMG to unarmored foes
Axes.Ability.Lower=&7You lower your Axe.
Axes.Ability.Ready=&3You &6ready&3 your Axe.
Axes.Ability.Ready.Extra=&3You &6ready&3 your Axe. [[GRAY]]({0} is on cooldown for {1}s)
Axes.Combat.CritStruck=&4You were CRITICALLY hit!
Axes.Combat.CriticalHit=CRITICAL HIT!
Axes.Combat.GI.Proc=&a**STRUCK WITH GREAT FORCE**
@ -531,6 +532,11 @@ Woodcutting.SubSkill.TreeFeller.Description=Make trees explode
Woodcutting.SubSkill.TreeFeller.Stat=Tree Feller Length
Woodcutting.SubSkill.LeafBlower.Name=Leaf Blower
Woodcutting.SubSkill.LeafBlower.Description=Blow Away Leaves
Woodcutting.SubSkill.KnockOnWood.Name=Knock On Wood
Woodcutting.SubSkill.KnockOnWood.Description=Find additional goodies when using Tree Feller
Woodcutting.SubSkill.KnockOnWood.Stat=Knock on Wood
Woodcutting.SubSkill.KnockOnWood.Loot.Normal=Standard loot from trees
Woodcutting.SubSkill.KnockOnWood.Loot.Rank2=Standard loot from trees and experience orbs
Woodcutting.SubSkill.HarvestLumber.Name=Harvest Lumber
Woodcutting.SubSkill.HarvestLumber.Description=Skillfully extract more Lumber
Woodcutting.SubSkill.HarvestLumber.Stat=Double Drop Chance
@ -989,6 +995,8 @@ Skills.Stats={0}&a{1}&3 XP(&7{2}&3/&7{3}&3)
Skills.ChildStats={0}&a{1}
Skills.MaxXP=Max
Skills.TooTired=You are too tired to use that ability again. &e({0}s)
Skills.TooTired.Named=[[GRAY]](&6{0}&e {1}s[[GRAY]])
Skills.TooTired.Extra=&6{0} &eSuper Ability CDs - {1}
Skills.Cancelled=&6{0} &ccancelled!
Skills.ConfirmOrCancel=&aRight-click again to confirm &6{0}&a. Left-click to cancel.
Skills.AbilityGateRequirementFail=&7You require &e{0}&7 more levels of &3{1}&7 to use this super ability.

View File

@ -695,8 +695,11 @@ permissions:
mcmmo.ability.woodcutting.splinter: true
mcmmo.ability.woodcutting.barksurgeon: true
mcmmo.ability.woodcutting.naturesbounty: true
mcmmo.ability.woodcutting.knockonwood: true
mcmmo.ability.woodcutting.leafblower: true
mcmmo.ability.woodcutting.treefeller: true
mcmmo.ability.woodcutting.knockonwood:
description: Allows access to Knock on Wood subskill
mcmmo.ability.woodcutting.splinter:
description: Allows access to Splinter
mcmmo.ability.woodcutting.barksurgeon:

View File

@ -605,15 +605,6 @@ Unarmed:
Rank_20: 1000
Woodcutting:
Splinter:
Standard:
Rank_1: 5
Rank_2: 30
Rank_3: 55
RetroMode:
Rank_1: 50
Rank_2: 300
Rank_3: 550
TreeFeller:
Standard:
Rank_1: 5
@ -627,29 +618,18 @@ Woodcutting:
Rank_3: 500
Rank_4: 750
Rank_5: 1000
BarkSurgeon:
Standard:
Rank_1: 70
Rank_2: 80
Rank_3: 95
RetroMode:
Rank_1: 700
Rank_2: 800
Rank_3: 950
NaturesBounty:
Standard:
Rank_1: 40
Rank_2: 60
Rank_3: 90
RetroMode:
Rank_1: 400
Rank_2: 600
Rank_3: 900
HarvestLumber:
Standard:
Rank_1: 1
RetroMode:
Rank_1: 1
KnockOnWood:
Standard:
Rank_1: 30
Rank_2: 60
RetroMode:
Rank_1: 300
Rank_2: 600
LeafBlower:
Standard:
Rank_1: 15