Loot chests update, default configs and new cooldown option

This commit is contained in:
Indyuce 2020-07-13 00:07:46 +02:00
parent 77fdcf6990
commit 87c75588fa
10 changed files with 109 additions and 78 deletions

View File

@ -25,7 +25,7 @@ public class ChestAlgorithmOptions {
* finder algorithm.
*/
public ChestAlgorithmOptions(ConfigurationSection config) {
Validate.notNull(config, "Config cannot be nulm");
Validate.notNull(config, "Config cannot be null");
minRange = config.getDouble("min-range", DEFAULT.minRange);
maxRange = config.getDouble("max-range", DEFAULT.maxRange);

View File

@ -3,6 +3,7 @@ package net.Indyuce.mmocore.api.loot;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
@ -109,6 +110,7 @@ public class LootChestRegion {
}
// TODO improve
// TODO stat to increase chance to get higher tiers?
public ChestTier rollTier() {
double s = 0;
@ -116,7 +118,6 @@ public class LootChestRegion {
if (random.nextDouble() < tier.chance / (1 - s))
return tier;
s += tier.chance;
}
return tiers.stream().findAny().get();
@ -166,4 +167,21 @@ public class LootChestRegion {
private boolean isSuitable(Location loc) {
return !loc.getBlock().getType().isSolid() && loc.clone().add(0, -1, 0).getBlock().getType().isSolid();
}
public class LootChestRunnable extends BukkitRunnable {
private final LootChestRegion region;
public LootChestRunnable(LootChestRegion region) {
this.region = region;
runTaskTimer(MMOCore.plugin, region.getChestSpawnPeriod() * 20, region.getChestSpawnPeriod() * 20);
}
@Override
public void run() {
Optional<PlayerData> found = region.getBounds().getPlayers().filter(data -> data.canSpawnLootChest()).findAny();
if (found.isPresent())
region.spawnChest(found.get());
}
}
}

View File

@ -1,28 +0,0 @@
package net.Indyuce.mmocore.api.loot;
import java.util.Optional;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
public class LootChestRunnable extends BukkitRunnable {
private final LootChestRegion region;
public LootChestRunnable(LootChestRegion region) {
this.region = region;
runTaskTimer(MMOCore.plugin, region.getChestSpawnPeriod() * 20, region.getChestSpawnPeriod() * 20);
}
// TODO add option so that players cannot have more than X chests every X
// time
@Override
public void run() {
Optional<Player> found = region.getBounds().getPlayers().findAny();
if (found.isPresent())
region.spawnChest(PlayerData.get(found.get()));
}
}

View File

@ -9,13 +9,19 @@ import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import net.Indyuce.mmocore.api.player.PlayerData;
public class RegionBounds {
private final World world;
private final int x1, z1, x2, z2;
public RegionBounds(ConfigurationSection config) {
Validate.notNull(config, "Could not load config");
Validate.notNull(world = Bukkit.getWorld(config.getString("world")), "Could not find world " + config.getString("world"));
String name = config.getString("world");
Validate.notNull(name, "Could not find world name");
Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world"));
x1 = Math.min(config.getInt("x1"), config.getInt("x2"));
x2 = Math.max(config.getInt("x1"), config.getInt("x2"));
@ -33,8 +39,8 @@ public class RegionBounds {
z2 = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
}
public Stream<Player> getPlayers() {
return world.getPlayers().stream().filter(player -> isInRegion(player));
public Stream<PlayerData> getPlayers() {
return world.getPlayers().stream().filter(player -> isInRegion(player)).map(player -> PlayerData.get(player));
}
public boolean isInRegion(Player player) {

View File

@ -25,7 +25,7 @@ public class CombatRunnable extends BukkitRunnable {
@Override
public void run() {
if (lastHit + (MMOCore.plugin.configManager.combatLogTimer * 1000) < System.currentTimeMillis()) {
if (lastHit + MMOCore.plugin.configManager.combatLogTimer < System.currentTimeMillis()) {
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, false));
MMOCore.plugin.configManager.getSimpleMessage("leave-combat").send(player.getPlayer());
close();

View File

@ -88,7 +88,7 @@ public class PlayerData extends OfflinePlayerData {
private final PlayerAttributes attributes = new PlayerAttributes(this);
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
private long lastWaypoint, lastLogin, lastFriendRequest, actionBarTimeOut;
private long lastWaypoint, lastLogin, lastFriendRequest, actionBarTimeOut, lastLootChest;
/*
* NON-FINAL player data stuff made public to facilitate field change
@ -325,6 +325,19 @@ public class PlayerData extends OfflinePlayerData {
return Math.max(0, lastWaypoint + 5000 - System.currentTimeMillis());
}
/*
* handles the per-player loot chest cooldown. that is to reduce the risk of
* spawning multiple chests in a row around the same player which could
* break the gameplay
*/
public boolean canSpawnLootChest() {
return lastLootChest + MMOCore.plugin.configManager.lootChestPlayerCooldown < System.currentTimeMillis();
}
public void applyLootChestCooldown() {
lastLootChest = System.currentTimeMillis();
}
public void heal(double heal) {
double newest = Math.max(0, Math.min(player.getHealth() + heal, player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
if (player.getHealth() == newest)

View File

@ -28,7 +28,7 @@ public class ConfigManager {
public double expPartyBuff, regenPartyBuff;
public String partyChatPrefix, noSkillBoundPlaceholder;
public ChatColor staminaFull, staminaHalf, staminaEmpty;
public int combatLogTimer, lootChestExpireTime;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown;
public final DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols();
public final DecimalFormat decimal = new DecimalFormat("0.#", formatSymbols), decimals = new DecimalFormat("0.##", formatSymbols);
@ -87,7 +87,7 @@ public class ConfigManager {
loadDefaultFile("stats.yml");
loadDefaultFile("waypoints.yml");
loadDefaultFile("restrictions.yml");
// loadDefaultFile("chests.yml");
loadDefaultFile("loot-chests.yml");
loadDefaultFile("commands.yml");
loadDefaultFile("guilds.yml");
@ -100,8 +100,9 @@ public class ConfigManager {
chatInput = MMOCore.plugin.getConfig().getBoolean("use-chat-input");
partyChatPrefix = MMOCore.plugin.getConfig().getString("party.chat-prefix");
formatSymbols.setDecimalSeparator(getFirstChar(MMOCore.plugin.getConfig().getString("number-format.decimal-separator"), ','));
combatLogTimer = MMOCore.plugin.getConfig().getInt("combat-log.timer");
lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chest-expire-time"), 1) * 1000;
combatLogTimer = MMOCore.plugin.getConfig().getInt("combat-log.timer") * 1000;
lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 1000;
lootChestPlayerCooldown = MMOCore.plugin.getConfig().getInt("player-cooldown") * 1000;
noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message();
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
@ -178,8 +179,10 @@ public class ConfigManager {
String msg = hasPlaceholders ? MMOCore.plugin.placeholderParser.parse(player, message) : message;
if (!msg.isEmpty()) {
if (actionbar) PlayerData.get(player.getUniqueId()).displayActionBar(msg);
else player.sendMessage(msg);
if (actionbar)
PlayerData.get(player.getUniqueId()).displayActionBar(msg);
else
player.sendMessage(msg);
}
return !msg.isEmpty();
}

View File

@ -32,9 +32,15 @@ lootsplosion:
offset: .2
height: .6
# Time in seconds it takes for a loot chest to
# expire after it was spawned. 600 is 10 minutes.
loot-chest-expire-time: 600
loot-chests:
# Time in seconds it takes for a loot chest to
# expire after it was spawned. 600 is 10 minutes.
chest-expire-time: 600
# Interval in seconds before the same player
# spawns two loot chests in ANY region.
player-cooldown: 600
# Settings for the default action bar
action-bar:
@ -110,7 +116,7 @@ use-chat-input: true
# Prevents mobs spawned from spawners from giving XP points.
prevent-spawner-xp: true
#Timer for combat log to expire (in seconds)
# Timer for combat log to expire (in seconds)
combat-log:
timer: 10

View File

@ -1,24 +0,0 @@
'world 59 71 131':
# Create directly your drop table here.
drop-table:
items:
- 'vanilla{type=DIAMOND} 1 1-3'
- 'gold{} .9 1-3'
- 'gold{} .9 1-3'
- 'gold{} .9 1-3'
- 'gold{} .9 1-3'
- 'gold{} .9 1-3'
- 'gold{} .9 1-3'
- 'note{min=1;max=10} .9 1-3'
# Ticks the chest takes to appear again.
regen-time: 40
# The particle played every 4sec around the chest.
# Types available: helix|offset|galaxy
# Particle names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
effect:
type: helix
particle: FLAME

View File

@ -0,0 +1,37 @@
sample-region:
# Region boundaries
bounds:
world: world_name_here
x1: 32
x2: -15
z1: -419
z2: -375
# Chest spawn period in seconds
spawn-period: 120
# Extra options for the random location algorithm
algorithm-options:
min-range: 8 # Min range from chest to player
max-range: 20 # Max range from chest to player
height: 15 # Maximum Y coord delta between the chest and player
iterations: 15 # Amount of random locations taken (tries) before canceling loot chest spawning
tiers:
# Some tier
normal:
# Particle effect played around a spawned loot chest
effect:
type: OFFSET # Type of particle effect used
particle: FLAME # Particle used to play the effect
period: 60 # Plays the effect every 60 ticks
capacity: 10
chance: 1
drops:
items:
- 'vanilla{type=DIAMOND}'