Add Villager Properties support

This commit is contained in:
Sam 2017-01-30 19:09:07 +00:00
parent 7200572583
commit fb35f19c3d
4 changed files with 227 additions and 39 deletions

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}