All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
185 lines
7.2 KiB
Java
185 lines
7.2 KiB
Java
package net.knarcraft.blacksmith.trait;
|
|
|
|
import net.citizensnpcs.api.npc.NPC;
|
|
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
|
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
|
|
import net.knarcraft.blacksmith.event.ScrapperSalvageFailEvent;
|
|
import net.knarcraft.blacksmith.event.ScrapperSalvageSucceedEvent;
|
|
import net.knarcraft.blacksmith.manager.EconomyManager;
|
|
import net.knarcraft.blacksmith.property.SalvageMethod;
|
|
import net.knarcraft.blacksmith.util.ItemHelper;
|
|
import net.knarcraft.blacksmith.util.SalvageHelper;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.Sound;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Calendar;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.Random;
|
|
|
|
import static net.knarcraft.blacksmith.formatting.BlacksmithStringFormatter.sendNPCMessage;
|
|
|
|
/**
|
|
* A representation of the session between a player and a scrapper
|
|
*/
|
|
public class SalvageSession extends Session implements Runnable {
|
|
|
|
private final ScrapperTrait scrapperTrait;
|
|
private final ItemStack itemToSalvage;
|
|
private final ScrapperNPCSettings config;
|
|
private final List<ItemStack> salvage;
|
|
private final int itemsConsumed;
|
|
private final int enchantmentLevels;
|
|
protected final SalvageMethod salvageMethod;
|
|
private static final Random random = new Random();
|
|
|
|
/**
|
|
* Instantiates a new session
|
|
*
|
|
* @param scrapperTrait <p>A reference to the scrapper trait</p>
|
|
* @param player <p>The player initiating the session</p>
|
|
* @param npc <p>The scrapper NPC involved in the session</p>
|
|
* @param config <p>The config to use for the session</p>
|
|
* @param salvageMethod <p>The salvage method performed in this session</p>
|
|
* @param itemsConsumed <p>The number of items actually consumed, in case a salvaging fails</p>
|
|
*/
|
|
public SalvageSession(@NotNull ScrapperTrait scrapperTrait, @NotNull Player player, @NotNull NPC npc,
|
|
@NotNull ScrapperNPCSettings config, @NotNull List<ItemStack> salvage,
|
|
@NotNull SalvageMethod salvageMethod, int itemsConsumed) {
|
|
super(player, npc);
|
|
this.scrapperTrait = scrapperTrait;
|
|
this.itemToSalvage = player.getInventory().getItemInMainHand().clone();
|
|
this.config = config;
|
|
this.salvage = salvage;
|
|
this.enchantmentLevels = SalvageHelper.getTotalEnchantmentLevels(this.itemToSalvage);
|
|
this.salvageMethod = salvageMethod;
|
|
this.itemsConsumed = itemsConsumed;
|
|
}
|
|
|
|
@Override
|
|
public boolean isSessionInvalid() {
|
|
// Prevent player from switching items during session
|
|
ItemStack itemInHand = this.player.getInventory().getItemInMainHand();
|
|
if (!itemToSalvage.equals(itemInHand)) {
|
|
sendNPCMessage(this.npc, this.player, this.config.getItemChangedMessage());
|
|
return true;
|
|
}
|
|
|
|
if (EconomyManager.cannotPayForSalvage(this.player, this.salvageMethod)) {
|
|
sendNPCMessage(this.npc, this.player, this.config.getInsufficientFundsMessage());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected int getActionDelay() {
|
|
if (this.config.getMaxSalvageDelay() > 0) {
|
|
//Finish the salvaging after a random delay between the max and min
|
|
return new Random().nextInt(this.config.getMaxSalvageDelay()) + this.config.getMinSalvageDelay();
|
|
} else {
|
|
//Finish the salvaging as soon as possible
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected @NotNull Material getCraftingStation() {
|
|
return switch (this.salvageMethod) {
|
|
case EXTENDED_SALVAGE -> Material.CRAFTING_TABLE;
|
|
case SALVAGE -> Material.ANVIL;
|
|
case NETHERITE, ARMOR_TRIM -> Material.SMITHING_TABLE;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Runs the actual salvage which fixes the item and gives it back to the player
|
|
*/
|
|
@Override
|
|
public void run() {
|
|
salvageItem();
|
|
|
|
//Stop the reforged item from displaying in the scrapper's hand
|
|
if (this.npc.getEntity() instanceof Player) {
|
|
((Player) this.npc.getEntity()).getInventory().setItemInMainHand(null);
|
|
} else {
|
|
Objects.requireNonNull(((LivingEntity) this.npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
|
}
|
|
|
|
//Mark this scrapper as available
|
|
this.scrapperTrait.unsetSession();
|
|
|
|
// Start cool-down
|
|
Calendar wait = Calendar.getInstance();
|
|
wait.add(Calendar.SECOND, this.config.getSalvageCoolDown());
|
|
this.scrapperTrait.addCoolDown(this.player.getUniqueId(), wait);
|
|
}
|
|
|
|
/**
|
|
* Gets the number of items consumed in order to perform the salvage
|
|
*
|
|
* @return <p>The number of items consumed as part of this salvage</p>
|
|
*/
|
|
public int getItemsConsumed() {
|
|
return this.itemsConsumed;
|
|
}
|
|
|
|
/**
|
|
* Trues to salvage an item, and gives the return item
|
|
*/
|
|
private void salvageItem() {
|
|
if (random.nextInt(100) < this.config.getFailChance()) {
|
|
playSound(Sound.ENTITY_VILLAGER_NO);
|
|
failSalvage();
|
|
BlacksmithPlugin.getInstance().callEvent(new ScrapperSalvageFailEvent(this.npc, this.player));
|
|
} else {
|
|
playSound(Sound.BLOCK_ANVIL_USE);
|
|
giveSalvage();
|
|
BlacksmithPlugin.getInstance().callEvent(new ScrapperSalvageSucceedEvent(this.npc, this.player));
|
|
sendNPCMessage(this.npc, this.player, this.config.getSuccessMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The method to run when a crapper fails salvaging an item
|
|
*/
|
|
private void failSalvage() {
|
|
// Make sure the given amount is the same amount taken for salvage to avoid duplication
|
|
this.itemToSalvage.setAmount(itemsConsumed);
|
|
|
|
if (ItemHelper.getMaxDurability(this.itemToSalvage) > 0) {
|
|
//Damage the item if possible
|
|
damageItemRandomly(this.itemToSalvage);
|
|
giveResultingItem(this.config.getMaxSalvageDelay() > 0, this.config.getDropItem(), this.npc,
|
|
this.itemToSalvage);
|
|
sendNPCMessage(this.npc, this.player, this.config.getFailSalvageMessage());
|
|
} else {
|
|
// Give half the salvage
|
|
List<ItemStack> halfSalvage = SalvageHelper.pickRandomSalvage(this.salvage, new ArrayList<>(), 0.5);
|
|
for (ItemStack item : halfSalvage) {
|
|
giveResultingItem(this.config.getMaxSalvageDelay() > 0, this.config.getDropItem(), this.npc, item);
|
|
}
|
|
sendNPCMessage(this.npc, this.player, this.config.getFailExtendedSalvageMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gives the player the calculated salvage
|
|
*/
|
|
private void giveSalvage() {
|
|
// TODO: Find a better calculation than 1 enchantment level = 1 exp level
|
|
// Gives the player back some of the EXP used on an item
|
|
this.player.giveExpLevels(this.enchantmentLevels);
|
|
BlacksmithPlugin.debug("Giving salvage " + this.salvage);
|
|
for (ItemStack item : this.salvage) {
|
|
giveResultingItem(this.config.getMaxSalvageDelay() > 0, this.config.getDropItem(), this.npc, item);
|
|
}
|
|
}
|
|
|
|
}
|