forked from Upstream/mmocore
Loot chest O(1) lookup time
This commit is contained in:
parent
13c0469594
commit
a7e3f9554f
@ -1,15 +1,11 @@
|
||||
package net.Indyuce.mmocore.api.player;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.player.TemporaryPlayerData;
|
||||
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.player.Unlockable;
|
||||
import net.Indyuce.mmocore.waypoint.CostType;
|
||||
import net.Indyuce.mmocore.waypoint.Waypoint;
|
||||
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
|
||||
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
|
||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||
@ -25,7 +21,6 @@ import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||
import net.Indyuce.mmocore.api.util.Closable;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
import net.Indyuce.mmocore.experience.ExperienceObject;
|
||||
import net.Indyuce.mmocore.experience.ExperienceTableClaimer;
|
||||
@ -33,11 +28,14 @@ import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import net.Indyuce.mmocore.party.provided.Party;
|
||||
import net.Indyuce.mmocore.player.Unlockable;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||
import net.Indyuce.mmocore.waypoint.Waypoint;
|
||||
import net.Indyuce.mmocore.waypoint.WaypointOption;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
@ -88,8 +86,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
/**
|
||||
* Saves all the items that have been unlocked so far by
|
||||
* the player. This can be used by other plugins by
|
||||
* implementing the {@link Unlockable} interface
|
||||
* the player. This is used for:
|
||||
* - waypoints
|
||||
* - skills
|
||||
*
|
||||
* @see {@link Unlockable}
|
||||
*/
|
||||
@ -289,8 +288,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return guild != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the item is unlocked by the player
|
||||
*/
|
||||
public boolean hasUnlocked(Unlockable unlockable) {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
return unlockedItems.contains(unlockable.getUnlockNamespacedKey());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -299,7 +301,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
* @return If the item was already unlocked when calling this method
|
||||
*/
|
||||
public boolean unlock(Unlockable unlockable) {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
return unlockedItems.add(unlockable.getUnlockNamespacedKey());
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
|
@ -1,16 +1,20 @@
|
||||
package net.Indyuce.mmocore.listener;
|
||||
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.loot.chest.LootChest;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
|
||||
public class LootableChestsListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void a(InventoryCloseEvent event) {
|
||||
public void expireOnClose(InventoryCloseEvent event) {
|
||||
if (!(event.getInventory().getHolder() instanceof Chest))
|
||||
return;
|
||||
|
||||
@ -19,4 +23,14 @@ public class LootableChestsListener implements Listener {
|
||||
if (lootChest != null)
|
||||
lootChest.expire(true);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
public void noBreaking(BlockBreakEvent event) {
|
||||
Block block = event.getBlock();
|
||||
if (block.getType() == Material.CHEST) {
|
||||
LootChest lootChest = MMOCore.plugin.lootChests.getChest(block.getLocation());
|
||||
if (lootChest != null)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.Indyuce.mmocore.loot.chest;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.util.item.HashableLocation;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -52,7 +53,7 @@ public class LootChest {
|
||||
|
||||
public boolean hasPlayerNearby() {
|
||||
for (Player player : block.loc.getWorld().getPlayers())
|
||||
if (player.getLocation().distanceSquared(block.loc) < 625)
|
||||
if (player.getLocation().distanceSquared(block.loc.bukkit()) < 625)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -78,8 +79,8 @@ public class LootChest {
|
||||
|
||||
// If a player is responsible of closing the chest, close it with sound
|
||||
if (player) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc);
|
||||
block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.clone().add(.5, .5, .5), 16, 0, 0, 0, .5);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc.bukkit());
|
||||
block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.bukkit().add(.5, .5, .5), 16, 0, 0, 0, .5);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -87,7 +88,7 @@ public class LootChest {
|
||||
* off and accumulate on the ground (+during dev phase)
|
||||
*/
|
||||
else
|
||||
((Chest) block.loc.getBlock().getState()).getBlockInventory().clear();
|
||||
((Chest) block.loc.bukkit().getBlock().getState()).getBlockInventory().clear();
|
||||
|
||||
block.restore();
|
||||
if (effectRunnable != null)
|
||||
@ -97,22 +98,28 @@ public class LootChest {
|
||||
public static class ReplacedBlock {
|
||||
private final Material material;
|
||||
private final BlockData data;
|
||||
private final Location loc;
|
||||
private final HashableLocation loc;
|
||||
|
||||
public ReplacedBlock(Block block) {
|
||||
this.material = block.getType();
|
||||
this.data = block.getBlockData();
|
||||
this.loc = block.getLocation();
|
||||
this.loc = new HashableLocation(block.getLocation());
|
||||
}
|
||||
|
||||
public HashableLocation getLocation() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean matches(Location loc) {
|
||||
return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getBlockX() == loc.getBlockX() && this.loc.getBlockY() == loc.getBlockY()
|
||||
&& this.loc.getBlockZ() == loc.getBlockZ();
|
||||
return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getX() == loc.getBlockX() && this.loc.getY() == loc.getBlockY()
|
||||
&& this.loc.getZ() == loc.getBlockZ();
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
loc.getBlock().setType(material);
|
||||
loc.getBlock().setBlockData(data);
|
||||
Block block = loc.bukkit().getBlock();
|
||||
block.setType(material);
|
||||
block.setBlockData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,27 @@
|
||||
package net.Indyuce.mmocore.manager;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.loot.chest.LootChest;
|
||||
import net.Indyuce.mmocore.loot.chest.LootChestRegion;
|
||||
import net.Indyuce.mmocore.util.item.HashableLocation;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class LootChestManager implements MMOCoreManager {
|
||||
|
||||
/**
|
||||
* Active loot chests in the server
|
||||
*/
|
||||
private final Set<LootChest> active = new HashSet<>();
|
||||
private final Map<HashableLocation, LootChest> active = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registered loot chest regions
|
||||
@ -42,26 +45,21 @@ public class LootChestManager implements MMOCoreManager {
|
||||
return regions.values();
|
||||
}
|
||||
|
||||
public Set<LootChest> getActive() {
|
||||
return active;
|
||||
public Collection<LootChest> getActive() {
|
||||
return active.values();
|
||||
}
|
||||
|
||||
public void register(LootChest chest) {
|
||||
active.add(chest);
|
||||
active.put(chest.getBlock().getLocation(), chest);
|
||||
}
|
||||
|
||||
public void unregister(LootChest chest) {
|
||||
active.remove(chest);
|
||||
active.remove(chest.getBlock().getLocation());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LootChest getChest(Location loc) {
|
||||
|
||||
for (LootChest chest : active)
|
||||
if (chest.getBlock().matches(loc))
|
||||
return chest;
|
||||
|
||||
return null;
|
||||
return active.get(new HashableLocation(loc));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,6 +78,5 @@ public class LootChestManager implements MMOCoreManager {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING,
|
||||
"An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package net.Indyuce.mmocore.player;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
/**
|
||||
* Some item that can be unlocked. ALl unlockable are saved in the same list in
|
||||
* the player data. This useful list can be used for:
|
||||
* Some item that can be unlocked. All unlockables are saved in the
|
||||
* same list in the player data. This useful list can be used for:
|
||||
* - waypoints
|
||||
* - skill tree nodes
|
||||
* - skills using skill books? TODO
|
||||
@ -15,8 +15,8 @@ import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
public interface Unlockable {
|
||||
|
||||
/**
|
||||
* Format being used is the minecraft's default
|
||||
* namespaced key format, e.g "skill_tree:strength_1_5"
|
||||
* Format being used is the minecraft's default namespaced
|
||||
* key format, e.g "skill_tree:strength_1_5" for readability
|
||||
*/
|
||||
String getUnlockNamespacedKey();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import io.lumine.mythic.lib.player.cooldown.CooldownObject;
|
||||
import io.lumine.mythic.lib.player.modifier.ModifierSource;
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
||||
import io.lumine.mythic.lib.skill.custom.condition.Condition;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||
@ -17,6 +18,9 @@ public class ClassSkill implements CooldownObject {
|
||||
private final int unlockLevel, maxSkillLevel;
|
||||
private final Map<String, LinearValue> modifiers = new HashMap<>();
|
||||
|
||||
@Deprecated
|
||||
private final Set<Condition> unlockConditions = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Class used to save information about skills IN A CLASS CONTEXT i.e at
|
||||
* which level the skill can be unlocked, etc.
|
||||
|
@ -5,6 +5,7 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||
import net.Indyuce.mmocore.player.Unlockable;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -15,7 +16,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RegisteredSkill {
|
||||
public class RegisteredSkill implements Unlockable {
|
||||
private final SkillHandler<?> handler;
|
||||
private final String name;
|
||||
private final Map<String, LinearValue> defaultModifiers = new HashMap<>();
|
||||
@ -45,6 +46,11 @@ public class RegisteredSkill {
|
||||
this.triggerType = triggerType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlockNamespacedKey() {
|
||||
return "registered_skill:" + handler.getId().toLowerCase();
|
||||
}
|
||||
|
||||
public SkillHandler<?> getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package net.Indyuce.mmocore.tree.modifier;
|
||||
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.player.modifier.ModifierSource;
|
||||
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
public class UnlockSkillModifier extends PlayerModifier {
|
||||
private RegisteredSkill unlocked = null;
|
||||
|
||||
public UnlockSkillModifier(String key, EquipmentSlot slot, ModifierSource source) {
|
||||
super(key, slot, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(MMOPlayerData mmoPlayerData) {
|
||||
PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
|
||||
// playerData.unlock(unlocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(MMOPlayerData mmoPlayerData) {
|
||||
throw new NotImplementedException("");
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package net.Indyuce.mmocore.util.item;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class HashableLocation {
|
||||
private final World world;
|
||||
private final int x, y, z;
|
||||
|
||||
public HashableLocation(Location loc) {
|
||||
this.world = loc.getWorld();
|
||||
this.x = loc.getBlockX();
|
||||
this.y = loc.getBlockY();
|
||||
this.z = loc.getBlockZ();
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public Location bukkit() {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
HashableLocation that = (HashableLocation) o;
|
||||
return x == that.x && y == that.y && z == that.z && world.equals(that.world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(world, x, y, z);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user