Writes a lot of code necessary for the scrapper
Adds the classes necessary for the new scrapper Partly implements some scrapper functionality Restructures some classes to reduce code duplication Moves some classes to make some classes easier to find Adds a bunch of TODOs where things have an unfinished implementation
This commit is contained in:
180
src/main/java/net/knarcraft/blacksmith/trait/CustomTrait.java
Normal file
180
src/main/java/net/knarcraft/blacksmith/trait/CustomTrait.java
Normal file
@ -0,0 +1,180 @@
|
||||
package net.knarcraft.blacksmith.trait;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.knarcraft.blacksmith.config.TraitSettings;
|
||||
import net.knarcraft.blacksmith.formatting.TimeFormatter;
|
||||
import net.knarcraft.blacksmith.manager.EconomyManager;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.blacksmith.formatting.BlacksmithStringFormatter.sendNPCMessage;
|
||||
|
||||
/**
|
||||
* A custom trait that utilizes sessions
|
||||
*/
|
||||
public abstract class CustomTrait extends Trait {
|
||||
|
||||
protected Session session;
|
||||
protected TraitSettings config;
|
||||
protected final Map<UUID, Calendar> coolDowns = new HashMap<>();
|
||||
protected long currentSessionStartTime = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Instantiates a new custom trait
|
||||
*
|
||||
* @param name <p>The name of the new trait</p>
|
||||
*/
|
||||
protected CustomTrait(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the trait settings object containing this trait's configuration
|
||||
*
|
||||
* @param config <p>The trait settings to use</p>
|
||||
*/
|
||||
protected void setTraitSettings(TraitSettings config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new session, and prepares to repair the player's item
|
||||
*
|
||||
* @param player <p>The player to start the session for</p>
|
||||
*/
|
||||
public abstract void startSession(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Tries to continue the session for the given player
|
||||
*
|
||||
* @param player <p>The player to continue the session for</p>
|
||||
*/
|
||||
public void continueSession(@NotNull Player player) {
|
||||
//Another player is using the blacksmith
|
||||
if (session.isNotInSession(player)) {
|
||||
sendNPCMessage(this.npc, player, config.getBusyWithPlayerMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
//The blacksmith is already reforging for the player
|
||||
if (session.isRunning()) {
|
||||
int timeRemaining = (int) ((session.getFinishTime() - System.currentTimeMillis()) / 1000);
|
||||
boolean showExactTime = showExactTime();
|
||||
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(config.getBusyWorkingMessage(),
|
||||
"{time}", TimeFormatter.formatTime(showExactTime, timeRemaining)));
|
||||
return;
|
||||
}
|
||||
if (session.isSessionInvalid()) {
|
||||
//Quit if the player cannot afford, or has changed their item
|
||||
session = null;
|
||||
} else {
|
||||
//Start reforging for the player
|
||||
startMainAction(npc, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this blacksmith is already in a reforging session
|
||||
*
|
||||
* @return <p>Whether already in a salvage session</p>
|
||||
*/
|
||||
public boolean hasSession() {
|
||||
return this.session != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cool-down for the given player's next blacksmith reforge
|
||||
*
|
||||
* @param playerUUID <p>The ID of the player to add the cool-down for</p>
|
||||
* @param waitUntil <p>The time when the player can interact again</p>
|
||||
*/
|
||||
public void addCoolDown(@NotNull UUID playerUUID, @NotNull Calendar waitUntil) {
|
||||
coolDowns.put(playerUUID, waitUntil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets the session of this scrapper, making it ready for another round
|
||||
*/
|
||||
public void unsetSession() {
|
||||
this.session = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs necessary work before the session is started or continued
|
||||
*
|
||||
* @param player <p>The player to prepare the session for</p>
|
||||
* @return <p>True if preparations were successful. False if a session shouldn't be started</p>
|
||||
*/
|
||||
public boolean prepareForSession(@NotNull Player player) {
|
||||
UUID playerId = player.getUniqueId();
|
||||
//If cool-down has been disabled after it was set for this player, remove the cool-down
|
||||
if (config.getDisableCoolDown() && coolDowns.get(playerId) != null) {
|
||||
coolDowns.remove(playerId);
|
||||
}
|
||||
//Deny if permission is missing
|
||||
if (!player.hasPermission("blacksmith.use")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Deny if on cool-down, or remove cool-down if expired
|
||||
if (coolDowns.get(playerId) != null) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (!calendar.after(coolDowns.get(playerId))) {
|
||||
int secondDifference = (int) (coolDowns.get(playerId).getTimeInMillis() - calendar.getTimeInMillis()) / 1000;
|
||||
boolean exactTime = showExactTime();
|
||||
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(config.getCoolDownUnexpiredMessage(),
|
||||
"{time}", TimeFormatter.formatTime(exactTime, secondDifference)));
|
||||
return false;
|
||||
}
|
||||
coolDowns.remove(playerId);
|
||||
}
|
||||
|
||||
//If already in a session, but the player has failed to interact, and left the blacksmith, allow a new session
|
||||
if (session != null && !session.isRunning() && (System.currentTimeMillis() > currentSessionStartTime + 10 * 1000 ||
|
||||
this.npc.getEntity().getLocation().distance(session.getPlayer().getLocation()) > 20)) {
|
||||
session = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to show exact time when displaying the remaining time left
|
||||
*
|
||||
* @return <p>Whether to show exact time, or vague words</p>
|
||||
*/
|
||||
protected abstract boolean showExactTime();
|
||||
|
||||
/**
|
||||
* Starts reforging the player's item
|
||||
*
|
||||
* @param npc <p>The NPC performing the reforge</p>
|
||||
* @param player <p>The player that initiated the reforge</p>
|
||||
*/
|
||||
private void startMainAction(@NotNull NPC npc, @NotNull Player player) {
|
||||
sendNPCMessage(this.npc, player, config.getStartWorkingMessage());
|
||||
// TODO: Differentiate between blacksmiths and scrappers when withdrawing money
|
||||
EconomyManager.withdraw(player);
|
||||
session.scheduleAction();
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
|
||||
//Display the item in the NPC's hand
|
||||
if (npc.getEntity() instanceof Player) {
|
||||
((Player) npc.getEntity()).getInventory().setItemInMainHand(heldItem);
|
||||
} else {
|
||||
Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(heldItem);
|
||||
}
|
||||
//Remove the item from the player's inventory
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user