Add Villager Properties support
This commit is contained in:
parent
7200572583
commit
fb35f19c3d
@ -1,24 +1,30 @@
|
||||
package mineplex.gemhunters.shop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
import mineplex.core.google.GoogleSheetsManager;
|
||||
import mineplex.core.google.SheetObjectDeserialiser;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
|
||||
import mineplex.gemhunters.safezone.SafezoneModule;
|
||||
import mineplex.gemhunters.shop.deserialisers.VillagerPropertiesDeserialiser;
|
||||
import mineplex.gemhunters.util.SlackSheetsBot;
|
||||
import mineplex.gemhunters.world.WorldDataModule;
|
||||
|
||||
@ -27,6 +33,8 @@ public class ShopModule extends MiniPlugin
|
||||
{
|
||||
|
||||
private static final String SHEET_FILE_NAME = "GEM_HUNTERS_SHOP";
|
||||
private static final String VILLAGER_MASTER_SHEET_NAME = "VILLAGER_MASTER";
|
||||
private static final VillagerPropertiesDeserialiser VILLAGER_PROPERTIES_DESERIALISER = new VillagerPropertiesDeserialiser();
|
||||
private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser();
|
||||
private static final SheetObjectDeserialiser<Integer> COST_DESERIALISER = new SheetObjectDeserialiser<Integer>()
|
||||
{
|
||||
@ -36,18 +44,26 @@ public class ShopModule extends MiniPlugin
|
||||
{
|
||||
return Integer.parseInt(values[10]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
private static final int MINIMUM_ITEMS = 1;
|
||||
private static final int MAXIMUM_ITEMS = 5;
|
||||
private static final int MAX_SEARCH_ATTEMPTS = 40;
|
||||
|
||||
private static final String[] NAMES = {
|
||||
|
||||
};
|
||||
|
||||
private final GoogleSheetsManager _sheets;
|
||||
private final SafezoneModule _safezone;
|
||||
private final WorldDataModule _worldData;
|
||||
|
||||
private final Map<String, Set<TradeableItem>> _trades;
|
||||
private final Map<String, VillagerProperties> _properties;
|
||||
|
||||
private boolean _npcsSpawned;
|
||||
private final List<TraderNPC> _npcs;
|
||||
private final Map<String, Set<Integer>> _spawnedIndexes;
|
||||
|
||||
private ShopModule()
|
||||
{
|
||||
@ -58,6 +74,10 @@ public class ShopModule extends MiniPlugin
|
||||
_worldData = require(WorldDataModule.class);
|
||||
|
||||
_trades = new HashMap<>();
|
||||
_properties = new HashMap<>();
|
||||
|
||||
_npcs = new ArrayList<>();
|
||||
_spawnedIndexes = new HashMap<>();
|
||||
|
||||
runSyncLater(() -> updateVillagerTrades(), 20);
|
||||
}
|
||||
@ -69,6 +89,32 @@ public class ShopModule extends MiniPlugin
|
||||
|
||||
for (String key : map.keySet())
|
||||
{
|
||||
if (key.equals(VILLAGER_MASTER_SHEET_NAME))
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
for (List<String> rows : map.get(key))
|
||||
{
|
||||
row++;
|
||||
try
|
||||
{
|
||||
VillagerProperties properties = VILLAGER_PROPERTIES_DESERIALISER.deserialise(rows.toArray(new String[0]));
|
||||
_properties.put(properties.getDataKey(), properties);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (row != 1)
|
||||
{
|
||||
SlackSheetsBot.reportParsingError(e, "Villager Trades", key, row);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Set<TradeableItem> items = new HashSet<>();
|
||||
int row = 0;
|
||||
|
||||
@ -98,37 +144,90 @@ public class ShopModule extends MiniPlugin
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerJoin(PlayerJoinEvent event)
|
||||
public void updateSpawnedVillagers(UpdateEvent event)
|
||||
{
|
||||
if (_npcsSpawned)
|
||||
if (event.getType() != UpdateType.SEC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_npcsSpawned = true;
|
||||
|
||||
for (String key : _trades.keySet())
|
||||
for (String key : _properties.keySet())
|
||||
{
|
||||
for (Location location : _worldData.getSpawnLocation(key))
|
||||
List<Location> locations = _worldData.getDataLocation(key);
|
||||
VillagerProperties properties = _properties.get(key);
|
||||
|
||||
if (!UtilTime.elapsed(properties.getLastSpawn(), properties.getSpawnRate()))
|
||||
{
|
||||
boolean vegetated = _safezone.isInSafeZone(location);
|
||||
Set<TradeableItem> items = getRandomItemSet(_trades.get(key));
|
||||
|
||||
new TraderNPC(_plugin, location, Villager.class, "Sam", vegetated, items);
|
||||
continue;
|
||||
}
|
||||
|
||||
properties.setLastSpawn();
|
||||
|
||||
// Only spawn more chests if we need to
|
||||
int max = properties.getMax();
|
||||
int spawned = 0;
|
||||
|
||||
for (TraderNPC npc : _npcs)
|
||||
{
|
||||
if (npc.getProperties().getDataKey().equals(key))
|
||||
{
|
||||
spawned++;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are too many chests of this type we can ignore it
|
||||
if (spawned > max)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Integer> usedIndexes = _spawnedIndexes.get(key);
|
||||
|
||||
if (usedIndexes == null)
|
||||
{
|
||||
_spawnedIndexes.put(key, new HashSet<>());
|
||||
usedIndexes = _spawnedIndexes.get(key);
|
||||
}
|
||||
|
||||
if (locations.size() == usedIndexes.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Location randomLocation = null;
|
||||
int attempts = 0;
|
||||
int index = -1;
|
||||
|
||||
while (index == -1 || usedIndexes.contains(index) && attempts < MAX_SEARCH_ATTEMPTS)
|
||||
{
|
||||
index = UtilMath.r(locations.size());
|
||||
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
usedIndexes.add(index);
|
||||
randomLocation = locations.get(index);
|
||||
|
||||
Bukkit.broadcastMessage("Trader at " + UtilWorld.locToStrClean(randomLocation) + " with key=" + key + " and index=" + index + " and max=" + max);
|
||||
_npcs.add(new TraderNPC(_plugin, randomLocation, Villager.class, NAMES[UtilMath.r(NAMES.length)], _safezone.isInSafeZone(randomLocation), properties, getRandomItemSet(_trades.get(key))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Set<TradeableItem> getRandomItemSet(Set<TradeableItem> items)
|
||||
{
|
||||
int size = UtilMath.rRange(MINIMUM_ITEMS, MAXIMUM_ITEMS);
|
||||
Set<TradeableItem> items2 = new HashSet<>(size);
|
||||
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
items2.add(UtilAlg.Random(items));
|
||||
}
|
||||
|
||||
|
||||
return items2;
|
||||
}
|
||||
|
||||
|
@ -19,41 +19,43 @@ import mineplex.gemhunters.util.SimpleNPC;
|
||||
|
||||
public class TraderNPC extends SimpleNPC
|
||||
{
|
||||
|
||||
|
||||
private final EconomyModule _economy;
|
||||
|
||||
|
||||
private final VillagerProperties _properties;
|
||||
private final Set<TradeableItem> _selling;
|
||||
private final Inventory _inv;
|
||||
|
||||
public TraderNPC(JavaPlugin plugin, Location spawn, Class<? extends LivingEntity> type, String name, boolean vegetated, Set<TradeableItem> selling)
|
||||
|
||||
public TraderNPC(JavaPlugin plugin, Location spawn, Class<? extends LivingEntity> type, String name, boolean vegetated, VillagerProperties properties, Set<TradeableItem> selling)
|
||||
{
|
||||
super(plugin, spawn, type, name, null, vegetated);
|
||||
|
||||
|
||||
_economy = Managers.require(EconomyModule.class);
|
||||
|
||||
|
||||
_properties = properties;
|
||||
_selling = selling;
|
||||
_inv = plugin.getServer().createInventory(null, 9, name);
|
||||
|
||||
|
||||
int index = 1;
|
||||
|
||||
|
||||
for (TradeableItem item : _selling)
|
||||
{
|
||||
_inv.setItem(index++, item.getLootItem().getItemStack());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void npcClick(PlayerInteractEntityEvent event)
|
||||
{
|
||||
super.npcClick(event);
|
||||
|
||||
|
||||
if (event.getRightClicked().equals(_entity))
|
||||
{
|
||||
event.getPlayer().openInventory(_inv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void inventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
@ -61,43 +63,43 @@ public class TraderNPC extends SimpleNPC
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!event.getInventory().equals(_inv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ItemStack itemStack = event.getCurrentItem();
|
||||
|
||||
|
||||
if (itemStack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
int gems = _economy.getGems(player);
|
||||
int cost = fromItemStack(itemStack);
|
||||
|
||||
|
||||
if (cost == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
|
||||
if (cost > gems)
|
||||
{
|
||||
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_economy.removeFromStore(player, cost);
|
||||
|
||||
|
||||
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1.2F);
|
||||
player.getInventory().addItem(itemStack);
|
||||
player.closeInventory();
|
||||
}
|
||||
|
||||
|
||||
public int fromItemStack(ItemStack itemStack)
|
||||
{
|
||||
for (TradeableItem item : _selling)
|
||||
@ -107,8 +109,13 @@ public class TraderNPC extends SimpleNPC
|
||||
return item.getCost();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public final VillagerProperties getProperties()
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package mineplex.gemhunters.shop;
|
||||
|
||||
public class VillagerProperties
|
||||
{
|
||||
|
||||
private final String _name;
|
||||
private final String _dataKey;
|
||||
private final int _spawnRate;
|
||||
private final int _expireRate;
|
||||
private final int _max;
|
||||
|
||||
private long _lastSpawn;
|
||||
|
||||
public VillagerProperties(String name, String dataKey, int spawnRate, int expireRate, int max)
|
||||
{
|
||||
_name = name;
|
||||
_dataKey = dataKey;
|
||||
_spawnRate = spawnRate;
|
||||
_expireRate = expireRate;
|
||||
_max = max;
|
||||
|
||||
setLastSpawn();
|
||||
}
|
||||
|
||||
public final String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
public final String getDataKey()
|
||||
{
|
||||
return _dataKey;
|
||||
}
|
||||
|
||||
public final int getSpawnRate()
|
||||
{
|
||||
return _spawnRate;
|
||||
}
|
||||
|
||||
public final int getExpireRate()
|
||||
{
|
||||
return _expireRate;
|
||||
}
|
||||
|
||||
public final int getMax()
|
||||
{
|
||||
return _max;
|
||||
}
|
||||
|
||||
public void setLastSpawn()
|
||||
{
|
||||
_lastSpawn = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getLastSpawn()
|
||||
{
|
||||
return _lastSpawn;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package mineplex.gemhunters.shop.deserialisers;
|
||||
|
||||
import mineplex.core.google.SheetObjectDeserialiser;
|
||||
import mineplex.gemhunters.shop.VillagerProperties;
|
||||
|
||||
public class VillagerPropertiesDeserialiser implements SheetObjectDeserialiser<VillagerProperties>
|
||||
{
|
||||
|
||||
@Override
|
||||
public VillagerProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException
|
||||
{
|
||||
String name = values[0];
|
||||
String dataKey = values[1];
|
||||
|
||||
int spawnRate = Integer.parseInt(values[2]);
|
||||
int expireRate = Integer.parseInt(values[3]);
|
||||
|
||||
int max = Integer.parseInt(values[4]);
|
||||
|
||||
return new VillagerProperties(name, dataKey, spawnRate, expireRate, max);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user