302 lines
11 KiB
Java
302 lines
11 KiB
Java
package pw.hamzantal.minionsplus.model;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonObject;
|
|
import lombok.AccessLevel;
|
|
import lombok.Getter;
|
|
import lombok.Setter;
|
|
import pw.hamzantal.minionsplus.MinionsPlus;
|
|
import me.loganb1max.minionsplus.model.minions.*;
|
|
import me.loganb1max.minionsplus.util.*;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.configuration.ConfigurationSection;
|
|
import org.bukkit.entity.ArmorStand;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import pw.hamzantal.minionsplus.model.minions.*;
|
|
import pw.hamzantal.minionsplus.util.*;
|
|
|
|
import java.text.DecimalFormat;
|
|
import java.util.*;
|
|
|
|
@Getter
|
|
public abstract class Minion {
|
|
|
|
private final ConfigurationSection section;
|
|
private final UUID owner;
|
|
private final String ownerName;
|
|
@Setter(AccessLevel.PROTECTED) private Location location;
|
|
@Setter(AccessLevel.PROTECTED) private double energy = 0.0;
|
|
@Setter(AccessLevel.PROTECTED) private int level = 1;
|
|
@Setter(AccessLevel.PROTECTED)private Set<Block> linkedBlocks = new HashSet<>();
|
|
private ArmorStand stand;
|
|
|
|
@Getter(AccessLevel.NONE)
|
|
private double offset = 0.1;
|
|
|
|
public Minion(final ConfigurationSection section, final UUID owner, final String ownerName) {
|
|
this.section = section;
|
|
this.owner = owner;
|
|
this.ownerName = ownerName;
|
|
}
|
|
|
|
protected void findStand() {
|
|
if (this.stand != null) return;
|
|
this.location.getChunk().load();
|
|
this.location.getWorld().getNearbyEntities(this.location, 0.5, 0.5, 0.5).stream().filter(entity -> entity instanceof ArmorStand && !entity.getCustomName().isEmpty()).findFirst().ifPresent(entity -> {
|
|
this.stand = (ArmorStand) entity;
|
|
});
|
|
}
|
|
|
|
public void spawn(final Location location) {
|
|
this.location = location;
|
|
if (this.stand == null) {
|
|
this.stand = (ArmorStand) location.getWorld().spawnEntity(location, EntityType.ARMOR_STAND);
|
|
this.stand.setSmall(true);
|
|
this.stand.setBasePlate(false);
|
|
this.stand.setGravity(false);
|
|
this.stand.setCanPickupItems(false);
|
|
this.stand.setRemoveWhenFarAway(false);
|
|
this.stand.setMarker(false);
|
|
this.stand.setCustomName(Text.color(getName()));
|
|
this.stand.setCustomNameVisible(true);
|
|
this.stand.setRightArmPose(this.stand.getRightLegPose().setX(6));
|
|
this.equipEquipment(this.stand);
|
|
MinionsPlus.getInstance().getMinionManager().getMinions().add(this);
|
|
} else {
|
|
this.stand.teleport(location);
|
|
}
|
|
}
|
|
|
|
public void despawn(final Player player) {
|
|
if (this.stand == null) return;
|
|
this.location = null;
|
|
this.stand.remove();
|
|
this.stand = null;
|
|
this.linkedBlocks.clear();
|
|
player.getInventory().addItem(this.toItemStack()).forEach((integer, itemStack) -> player.getWorld().dropItemNaturally(player.getLocation(), itemStack));
|
|
MinionsPlus.getInstance().getMinionManager().getMinions().remove(this);
|
|
}
|
|
|
|
public void animationTick() {
|
|
if (this.stand == null) return;
|
|
if (this.stand.getRightArmPose().getX() < 5) offset = 0.1;
|
|
if (this.stand.getRightArmPose().getX() > 6) offset = -0.1;
|
|
if (this.energy > 0) this.stand.setRightArmPose(this.stand.getRightArmPose().add(offset, 0, 0));
|
|
final DecimalFormat format = new DecimalFormat("#.#");
|
|
this.stand.setCustomName(Text.color(getName() + " &8[&f" + format.format(getEnergy()) + "&8]"));
|
|
this.stand.setFireTicks(0);
|
|
}
|
|
|
|
public double gainEnergy(final double amount) {
|
|
return this.energy += amount;
|
|
}
|
|
|
|
public double consumeEnergy(final double amount) {
|
|
return this.energy -= amount;
|
|
}
|
|
|
|
public void equipEquipment(final ArmorStand stand) {
|
|
final String skull = this.section.getString("Equipment.Skull", "");
|
|
ItemStack skullItem = SkullCreator.itemFromBase64(skull);
|
|
stand.setHelmet(skullItem);
|
|
final ItemStack chestplate = ItemUtil.fromConfigSection(this.section.getConfigurationSection("Equipment.Chestplate"));
|
|
stand.setChestplate(chestplate);
|
|
final ItemStack leggings = ItemUtil.fromConfigSection(this.section.getConfigurationSection("Equipment.Leggings"));
|
|
stand.setLeggings(leggings);
|
|
final ItemStack boots = ItemUtil.fromConfigSection(this.section.getConfigurationSection("Equipment.Boots"));
|
|
stand.setBoots(boots);
|
|
final ItemStack rightHand = ItemUtil.fromConfigSection(this.section.getConfigurationSection("Equipment.RightHand"));
|
|
stand.setItemInHand(rightHand);
|
|
}
|
|
|
|
public ItemStack toItemStack() {
|
|
ItemStack item = getIcon();
|
|
item = ItemUtil.setKeyString(item, "minion-type", getType());
|
|
item = ItemUtil.setKeyString(item, "minion-owner", this.owner.toString());
|
|
item = ItemUtil.setKeyString(item, "minion-owner-name", this.ownerName);
|
|
item = ItemUtil.setKeyInt(item, "minion-level", this.level);
|
|
item = ItemUtil.setKeyDouble(item, "minion-energy", this.energy);
|
|
return item;
|
|
}
|
|
|
|
public ItemStack getIcon() {
|
|
final Material material = Material.getMaterial(this.section.getString("Item.Material"));
|
|
final int durability = this.section.getInt("Item.Durability");
|
|
final String skull = this.section.getString("Item.Skull", null);
|
|
final String displayName = this.section.getString("Item.DisplayName");
|
|
final List<String> lore = this.section.getStringList("Item.Lore");
|
|
|
|
ItemStack item = null;
|
|
|
|
if (material == Material.SKULL_ITEM) {
|
|
item = SkullCreator.itemFromBase64(skull);
|
|
} else {
|
|
item = new ItemStack(material);
|
|
}
|
|
|
|
item = ItemBuilder.of(item)
|
|
.durability((short) durability)
|
|
.name(displayName)
|
|
.lore(getReplacer().replace(lore))
|
|
.build();
|
|
|
|
return item;
|
|
}
|
|
|
|
public UUID getId() {
|
|
if (this.stand == null) return null;
|
|
return this.stand.getUniqueId();
|
|
}
|
|
|
|
public String getType() {
|
|
return this.section.getName();
|
|
}
|
|
|
|
public String getName() {
|
|
return this.section.getString("Name");
|
|
}
|
|
|
|
public double getEnergyPerUse(final int level) {
|
|
return this.section.getDouble("Levels." + level + ".EnergyPerAction", 0.0);
|
|
}
|
|
|
|
public double getPrice(final int level) {
|
|
return this.section.getDouble("Levels." + level + ".Price", 0.0);
|
|
}
|
|
|
|
public int getMaxLevel() {
|
|
return this.section.getConfigurationSection("Levels").getKeys(false).size();
|
|
}
|
|
|
|
public boolean isMaxLevel() {
|
|
return getLevel() == getMaxLevel();
|
|
}
|
|
|
|
public void levelUp() {
|
|
this.level++;
|
|
}
|
|
|
|
public JsonElement serialize() {
|
|
final Gson gson = new Gson();
|
|
final JsonObject object = new JsonObject();
|
|
object.addProperty("type", getType());
|
|
object.addProperty("owner", this.owner.toString());
|
|
object.addProperty("ownerName", this.ownerName);
|
|
final JsonObject loc = new JsonObject();
|
|
loc.addProperty("world", this.location.getWorld().getName());
|
|
loc.addProperty("x", this.location.getX());
|
|
loc.addProperty("y", this.location.getY());
|
|
loc.addProperty("z", this.location.getZ());
|
|
object.add("location", loc);
|
|
object.addProperty("energy", this.energy);
|
|
object.addProperty("level", this.level);
|
|
final List<JsonElement> linked = new ArrayList<>();
|
|
this.linkedBlocks.forEach(block -> {
|
|
JsonObject b = new JsonObject();
|
|
b.addProperty("world", block.getWorld().getName());
|
|
b.addProperty("x", block.getX());
|
|
b.addProperty("y", block.getY());
|
|
b.addProperty("z", block.getZ());
|
|
linked.add(b);
|
|
});
|
|
object.add("linkedBlocks", gson.toJsonTree(linked));
|
|
return object;
|
|
}
|
|
|
|
public static Minion deserialize(final MinionsPlus plugin, final JsonElement element) {
|
|
final JsonObject data = element.getAsJsonObject();
|
|
final String type = data.get("type").getAsString();
|
|
final UUID owner = UUID.fromString(data.get("owner").getAsString());
|
|
final String ownerName = data.get("ownerName").getAsString();
|
|
final JsonObject locData = data.get("location").getAsJsonObject();
|
|
final Location location = new Location(Bukkit.getWorld(locData.get("world").getAsString()), locData.get("x").getAsDouble(), locData.get("y").getAsDouble(), locData.get("z").getAsDouble());
|
|
final double energy = data.get("energy").getAsDouble();
|
|
final int level = data.get("level").getAsInt();
|
|
final Set<Block> linkedBlocks = new HashSet<>();
|
|
for (JsonElement el : data.get("linkedBlocks").getAsJsonArray()) {
|
|
JsonObject o = el.getAsJsonObject();
|
|
final Block b = Bukkit.getWorld(o.get("world").getAsString()).getBlockAt(
|
|
o.get("x").getAsInt(),
|
|
o.get("y").getAsInt(),
|
|
o.get("z").getAsInt()
|
|
);
|
|
linkedBlocks.add(b);
|
|
}
|
|
Minion toReturn = null;
|
|
switch (type) {
|
|
case "Miner":
|
|
toReturn = new MinerMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Farmer":
|
|
toReturn = new FarmerMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Fisher":
|
|
toReturn = new FisherMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Seller":
|
|
toReturn = new SellerMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Butcher":
|
|
toReturn = new ButcherMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Collector":
|
|
toReturn = new CollectorMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
case "Breeder":
|
|
toReturn = new BreederMinion(owner, ownerName, location, energy, level, linkedBlocks);
|
|
break;
|
|
}
|
|
return toReturn;
|
|
}
|
|
|
|
public static boolean isMinion(final ItemStack itemStack) {
|
|
if (itemStack == null || itemStack.getType() == Material.AIR) return false;
|
|
return ItemUtil.hasKey(itemStack, "minion-type");
|
|
}
|
|
|
|
public static Minion of(final ItemStack itemStack, final Location location) {
|
|
if (!isMinion(itemStack)) return null;
|
|
final String type = ItemUtil.getKeyString(itemStack, "minion-type");
|
|
final UUID owner = UUID.fromString(ItemUtil.getKeyString(itemStack, "minion-owner"));
|
|
final String ownerName = ItemUtil.getKeyString(itemStack, "minion-owner-name");
|
|
final int level = ItemUtil.getKeyInt(itemStack, "minion-level");
|
|
final double energy = ItemUtil.getKeyDouble(itemStack, "minion-energy");
|
|
Minion toReturn = null;
|
|
switch (type) {
|
|
case "Miner":
|
|
toReturn = new MinerMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Farmer":
|
|
toReturn = new FarmerMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Fisher":
|
|
toReturn = new FisherMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Seller":
|
|
toReturn = new SellerMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Butcher":
|
|
toReturn = new ButcherMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Collector":
|
|
toReturn = new CollectorMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
case "Breeder":
|
|
toReturn = new BreederMinion(owner, ownerName, location, energy, level, new HashSet<>());
|
|
break;
|
|
}
|
|
return toReturn;
|
|
}
|
|
|
|
public abstract void tick();
|
|
|
|
public abstract Replacer getReplacer();
|
|
|
|
}
|