Fix bug relating to Energy Shop purchases and item functionality. Fix bug with GoldManager not being properly initialized on plugin start-up. Add Shops safe-zone to region claims for default clans across world. Create BankShop for all interactions related to economy management, specifically buying & selling GoldTokens as well as converting Gems into Gold on a daily basis.

This commit is contained in:
Ty Sayers 2015-06-05 19:18:06 -04:00
parent fa3e6c3d1f
commit 971612a538
17 changed files with 452 additions and 21 deletions

View File

@ -128,7 +128,6 @@ public class BlockRestore extends MiniPlugin
return restored;
}
public void Add(Block block, int toID, byte toData, long expireTime)
{
Add(block, toID, toData, block.getTypeId(), block.getData(), expireTime);

View File

@ -66,6 +66,7 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
return _availableCurrencyTypes;
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerDamageEntity(NpcDamageByEntityEvent event)
{
@ -97,7 +98,9 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
openShopForPlayer(player);
if (!_playerPageMap.containsKey(player.getName()))
{
_playerPageMap.put(player.getName(), buildPagesFor(player));
System.out.println("Put " + player.getName());
}
openPageForPlayer(player, getOpeningPageForPlayer(player));
@ -108,6 +111,12 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
return false;
}
public void removePlayerPages(String playerName)
{
System.out.println("REMOVING " + playerName);
_playerPageMap.remove(playerName);
}
public boolean attemptShopOpen(Player player)
{
if (!_openedShop.contains(player.getName()))
@ -142,7 +151,6 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
if (_playerPageMap.containsKey(event.getWhoClicked().getName()) && _playerPageMap.get(event.getWhoClicked().getName()).getName().equalsIgnoreCase(event.getInventory().getName()))
{
_playerPageMap.get(event.getWhoClicked().getName()).playerClicked(event);
event.setCancelled(true);
}
}
@ -154,7 +162,7 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
_playerPageMap.get(event.getPlayer().getName()).playerClosed();
_playerPageMap.get(event.getPlayer().getName()).dispose();
_playerPageMap.remove(event.getPlayer().getName());
removePlayerPages(event.getPlayer().getName());
closeShopForPlayer((Player) event.getPlayer());
@ -162,18 +170,18 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
}
}
@EventHandler(priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryOpen(InventoryOpenEvent event)
{
if (!event.isCancelled())
return;
System.out.println("On Inventory Open");
if (true) return;
if (_playerPageMap.containsKey(event.getPlayer().getName()) && _playerPageMap.get(event.getPlayer().getName()).getTitle() != null && _playerPageMap.get(event.getPlayer().getName()).getTitle().equalsIgnoreCase(event.getInventory().getTitle()))
{
_playerPageMap.get(event.getPlayer().getName()).playerClosed();
_playerPageMap.get(event.getPlayer().getName()).dispose();
_playerPageMap.remove(event.getPlayer().getName());
removePlayerPages(event.getPlayer().getName());
closeShopForPlayer((Player) event.getPlayer());
@ -201,7 +209,7 @@ public abstract class ShopBase<PluginType extends MiniPlugin> implements Listene
event.getPlayer().closeInventory();
closeShopForPlayer(event.getPlayer());
_playerPageMap.remove(event.getPlayer().getName());
removePlayerPages(event.getPlayer().getName());
_openedShop.remove(event.getPlayer().getName());
}

View File

@ -19,6 +19,11 @@ public class ShopItem extends ItemStack
private boolean _locked;
private boolean _displayItem;
public ShopItem(ItemStack itemStack, boolean locked, boolean displayItem)
{
this(itemStack, itemStack.getItemMeta().getDisplayName(), itemStack.getItemMeta().getDisplayName(), 1, locked, displayItem);
}
public ShopItem(ItemStack itemStack, String name, String deliveryName, int deliveryAmount, boolean locked, boolean displayItem)
{
super(itemStack);

View File

@ -7,6 +7,7 @@ import org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
@ -134,23 +135,28 @@ public abstract class ShopPageBase<PluginType extends MiniPlugin, ShopType exten
public void playerClicked(InventoryClickEvent event)
{
System.out.println("Clicked " + event.getRawSlot() + " --- vs " + event.getSlot() + " --- " + event.getInventory().getSize() + " --- " + inventory.getSize() + event.getInventory().getName());
if (_buttonMap.containsKey(event.getRawSlot()))
{
_buttonMap.get(event.getRawSlot()).onClick(_player, event.getClick());
event.setCancelled(true);
}
else if (event.getRawSlot() != -999)
{
if (event.getInventory().getTitle() == inventory.getInventoryName() && (inventory.getSize() <= event.getSlot() || inventory.getItem(event.getSlot()) != null))
{
playDenySound(_player);
}
else if (event.getInventory() == _player.getInventory() && _player.getInventory().getItem(event.getSlot()) != null)
if (event.getRawSlot() < inventory.getSize())
{
playDenySound(_player);
event.setCancelled(true);
}
}
}
private boolean matchesInventory(Inventory newInventory)
{
return newInventory.getTitle() == inventory.getInventoryName();
}
public void playerOpened()
{

View File

@ -44,8 +44,10 @@ import mineplex.game.clans.clans.repository.tokens.ClanMemberToken;
import mineplex.game.clans.clans.repository.tokens.ClanTerritoryToken;
import mineplex.game.clans.clans.repository.tokens.ClanToken;
import mineplex.game.clans.clans.war.WarManager;
import mineplex.game.clans.economy.GoldManager;
import mineplex.game.clans.fields.Field;
import mineplex.game.clans.gameplay.Gameplay;
import mineplex.game.clans.shop.ShopManager;
import mineplex.game.clans.spawn.Spawn;
import mineplex.minecraft.game.classcombat.Class.ClassManager;
import mineplex.minecraft.game.classcombat.Class.repository.token.CustomBuildToken;
@ -131,7 +133,12 @@ public class ClansManager extends MiniClientPlugin<ClientClan> implements IRelat
Creature creature = new Creature(plugin);
new Field(plugin, creature, _condition, energy, serverName);
// Required managers to be initialized
new Spawn(plugin);
new ShopManager(this, _clientManager, donationManager);
new GoldManager(this, _clientManager, donationManager);
DamageManager damageManager = new DamageManager(plugin, _combatManager, new NpcManager(plugin, creature), disguiseManager);

View File

@ -17,7 +17,8 @@ public class ClansRegions
{
public final static String DEFAULT_WORLD_NAME = "world";
public final static int SPAWN_RADIUS = 2; // Radius of spawn claim area (measured in chunks)
public final static int FIELDS_RADIUS = 8; // Radius of fields claim area (measured in chunks)
public final static int SHOP_RADIUS = 2; // Radius of shop claim area (measured in chunks)
public final static int FIELDS_RADIUS = 7; // Radius of fields claim area (measured in chunks)
public final static int BORDERLANDS_RADIUS = 75; // Radius of borderlands claim area (measured in chunks)
private ClansManager _manager;
@ -41,7 +42,9 @@ public class ClansRegions
// Initialize Spawn faction and claims
Set<Location> spawns = Spawn.getInstance().getSpawnLocations();
Location[] spawnsArray = spawns.toArray(new Location[spawns.size()]);
Location[] shopsArray = {new Location(_world, 0, 0, 200), new Location(_world, 0, 0, -200)};
claimArea("Spawn", SPAWN_RADIUS, 0, true, spawnsArray);
claimArea("Shops", SHOP_RADIUS, 0, true, shopsArray);
// Initialize Fields and Borderlands factions and claims
claimArea("Fields", FIELDS_RADIUS, 0, false, worldCenter);

View File

@ -17,6 +17,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import mineplex.game.clans.items.economy.GoldToken;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.CurrencyType;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
@ -26,8 +27,10 @@ import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor;
import mineplex.core.energy.Energy;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.fields.repository.FieldRepository;
import mineplex.game.clans.items.generation.WeightSet;
import mineplex.game.clans.shop.bank.BankShop;
import mineplex.minecraft.game.core.condition.ConditionFactory;
import mineplex.minecraft.game.core.condition.ConditionManager;
@ -39,15 +42,17 @@ public class GoldManager extends MiniPlugin
public static GoldManager getInstance() { return _instance; }
private DonationManager _donationManager;
private BankShop _bankShop;
public GoldManager(JavaPlugin plugin, DonationManager donationManager)
public GoldManager(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super("Clans Gold", plugin);
super("Clans Gold", plugin.getPlugin());
_instance = this;
_donationManager = donationManager;
_bankShop = new BankShop(plugin, clientManager, donationManager);
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event)
{
@ -76,6 +81,7 @@ public class GoldManager extends MiniPlugin
if (event.getMessage().startsWith("/gold"))
{
notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g");
addGold(event.getPlayer(), 100000);
event.setCancelled(true);
}
}
@ -102,6 +108,14 @@ public class GoldManager extends MiniPlugin
notify(player, String.format("You have cashed in a gold token worth %dg!", value));
}
public void purchaseToken(Player player, int tokenValue)
{
GoldToken token = new GoldToken(tokenValue);
deductGold(player, tokenValue);
player.getInventory().addItem(token.toItemStack());
notify(player, String.format("You have purchased a gold token worth %dg!", tokenValue));
}
private Donor getDonor(Player player)
{
return _donationManager.Get(player.getName());

View File

@ -21,6 +21,7 @@ import mineplex.game.clans.items.attributes.ItemAttribute;
import mineplex.game.clans.items.attributes.weapon.*;
import mineplex.game.clans.items.attributes.armor.*;
import mineplex.game.clans.items.commands.GearCommand;
import mineplex.game.clans.items.economy.GoldToken;
import mineplex.game.clans.items.generation.Weight;
import mineplex.game.clans.items.generation.WeightSet;
import mineplex.game.clans.items.legendaries.*;
@ -56,7 +57,6 @@ import com.google.gson.GsonBuilder;
public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
{
private static final String ITEM_SERIALIZATION_TAG = "-JSON-";
private static Random random = new Random();
private static Gson _gson;
private static GearManager _instance; // Singleton instance
@ -142,6 +142,7 @@ public class GearManager extends MiniPlugin implements IPacketHandler, Runnable
.of(CustomItem.class);
customItemType.registerSubtype(CustomItem.class);
customItemType.registerSubtype(LegendaryItem.class);
customItemType.registerSubtype(GoldToken.class);
for (Class<? extends CustomItem> itemType : _legendaryWeights.elements())
{
customItemType.registerSubtype(itemType);

View File

@ -10,6 +10,12 @@ public class GoldToken extends CustomItem
private int _goldValue;
public int getGoldValue() { return _goldValue; }
public GoldToken()
{
this(0);
}
public GoldToken(int goldValue)
{
super("Gold Token", null, Material.GOLD_INGOT);

View File

@ -0,0 +1,104 @@
package mineplex.game.clans.shop;
import java.util.HashSet;
import java.util.Set;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.ShopBase;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.items.generation.WeightSet;
import mineplex.game.clans.shop.energy.EnergyShop;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class ShopManager extends MiniPlugin
{
private ClansManager _clansManager;
private CoreClientManager _clientManager;
private DonationManager _donationManager;
private Set<ShopNPC> _shopNpcs;
public ShopManager(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super("Clans Shop Manager", plugin.getPlugin());
_shopNpcs = new HashSet<ShopNPC>();
_clansManager = plugin;
_clientManager = clientManager;
_donationManager = donationManager;
initialize();
}
public void initialize()
{
// Spawn appropriate shop NPCs
World world = Bukkit.getWorld("world");
}
@Override
public void disable()
{
System.out.println("Killing shop npcs");
// Despawn/kill all shop NPCs on server shutdown
for (ShopNPC npc : _shopNpcs)
{
npc.despawn();
}
}
public void addShopNPC(Location location, String shopName, ShopBase<ClansManager> shop)
{
ShopNPC npc = new ShopNPC(location, shopName, shop);
_shopNpcs.add(npc);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerClickEntity(PlayerInteractEntityEvent event)
{
Entity clicked = event.getRightClicked();
ShopNPC shop = getShopNpc(clicked.getEntityId());
if (shop != null) // Player interacted with a Shop NPC
{
shop.onInteracted(event.getPlayer());
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityDamaged(EntityDamageEvent event)
{
if (isShopNpc(event.getEntity()))
{
event.setCancelled(true);
}
}
private boolean isShopNpc(Entity entity)
{
return getShopNpc(entity.getEntityId()) != null;
}
private ShopNPC getShopNpc(int entityId)
{
for (ShopNPC npc : _shopNpcs)
{
if (npc.getEntityId() == entityId)
{
return npc;
}
}
return null;
}
}

View File

@ -0,0 +1,77 @@
package mineplex.game.clans.shop;
import net.minecraft.server.v1_7_R4.EntityInsentient;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftLivingEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.core.shop.ShopBase;
import mineplex.game.clans.clans.ClansManager;
public class ShopNPC
{
public final static EntityType NPC_TYPE = EntityType.VILLAGER;
private ShopBase<ClansManager> _shop;
private String _name;
private Location _spawn;
private LivingEntity _npc;
public int getEntityId() { return _npc.getEntityId(); }
public ShopNPC(Location location, String name, ShopBase<ClansManager> shop)
{
_name = name;
_shop = shop;
_spawn = location;
spawn();
}
/**
* Called when a player interacts with the {@link Entity} associated
* with this ShopNPC.
* @param player - the player that interacted with the shop NPC
*/
public void onInteracted(Player player)
{
_shop.attemptShopOpen(player);
}
public void spawn()
{
if (_npc != null) despawn();
_npc = spawnNpc(_spawn, _name);
}
public void despawn()
{
if (_npc != null)
{
_npc.remove();
_npc = null;
}
}
private static LivingEntity spawnNpc(Location location, String name)
{
World world = location.getWorld();
LivingEntity entity = (LivingEntity) world.spawnEntity(location, NPC_TYPE);
// Initialize proper values of entity NPC on spawn
entity.setCustomNameVisible(true);
entity.setCustomName(ChatColor.RESET + name);
entity.setCanPickupItems(false);
entity.setRemoveWhenFarAway(false);
((EntityInsentient) ((CraftLivingEntity) entity).getHandle()).persistent = true;
return entity;
}
}

View File

@ -0,0 +1,103 @@
package mineplex.game.clans.shop.bank;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.economy.GoldManager;
import mineplex.game.clans.shop.PvpItem;
import mineplex.game.clans.shop.PvpShopButton;
import mineplex.game.clans.shop.building.BuildingPage;
public class BankPage extends ShopPageBase<ClansManager, BankShop>
{
public static final int TOKEN_VALUE = 50000; // Value of a GoldToken (in gold) that can be stored/cashed in here
private ClanInfo _clanInfo;
public BankPage(ClansManager plugin, BankShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, "Bank Shop", player, 9);
_clanInfo = getPlugin().getClan(getPlayer());
buildPage();
}
@Override
protected void buildPage()
{
buildCashIn();
if (hasEnoughGold())
{
buildTokenPurchasable();
}
else
{
buildTokenUnpurchasable();
}
}
private void buildCashIn()
{
int playerGold = getPlayerGold();
CashInButton button = new CashInButton(this);
String title = "Cash In Gold Token";
String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g");
String description = ChatColor.RESET + C.cWhite + "Click with GoldToken to exchange for gold!";
ShopItem shopItem = new ShopItem(Material.FURNACE, title, new String[] {" ", playerGoldString, description}, 0, true, true);
addButton(5, shopItem, button);
}
private void buildTokenPurchasable()
{
int playerGold = getPlayerGold();
StoreGoldButton button = new StoreGoldButton(this);
String title = ChatColor.GOLD + C.Bold + "Purchase Gold Token!";
String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g");
String purchaseString = ChatColor.RESET + F.value("Token Value", TOKEN_VALUE + "g");
String goldString = ChatColor.RESET + C.cWhite + "Store your bank gold in the form of a gold token!";
ShopItem shopItem = new ShopItem(Material.GOLD_INGOT, title, new String[] {" ", playerGoldString, purchaseString, goldString}, 0, true, true);
addButton(3, shopItem, button);
}
private void buildTokenUnpurchasable()
{
int playerGold = getPlayerGold();
int goldCost = TOKEN_VALUE;
StoreGoldButton button = new StoreGoldButton(this);
String title = ChatColor.RED + C.Bold + "Missing Gold!";
String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g");
String purchaseString = ChatColor.RESET + C.cWhite + "You don't have enough gold";
String goldString = ChatColor.RESET + C.cWhite + "You need " + C.cYellow + goldCost + C.cWhite + " gold to purchase a token.";
ShopItem shopItem = new ShopItem(Material.GOLD_INGOT, title, new String[] {" ", playerGoldString, purchaseString, goldString}, 0, true, true);
addButton(3, shopItem, button);
}
public void addPvpItem(int slot, PvpItem item)
{
addButton(slot, item, new PvpShopButton<BankPage>(this, item));
}
public boolean hasEnoughGold()
{
return getPlayerGold() >= TOKEN_VALUE;
}
private int getPlayerGold()
{
return GoldManager.getInstance().getGold(getPlayer());
}
}

View File

@ -0,0 +1,23 @@
package mineplex.game.clans.shop.bank;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.game.clans.clans.ClansManager;
public class BankShop extends ShopBase<ClansManager>
{
public BankShop(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, "Bank Shop");
}
@Override
protected ShopPageBase<ClansManager, ? extends ShopBase<ClansManager>> buildPagesFor(Player player)
{
return new BankPage(getPlugin(), this, getClientManager(), getDonationManager(), player);
}
}

View File

@ -0,0 +1,44 @@
package mineplex.game.clans.shop.bank;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.Callback;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.IButton;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.economy.GoldManager;
import mineplex.game.clans.items.CustomItem;
import mineplex.game.clans.items.GearManager;
import mineplex.game.clans.items.economy.GoldToken;
public class CashInButton implements IButton
{
private BankPage _page;
public CashInButton(BankPage page)
{
_page = page;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (clickType != ClickType.LEFT && clickType != ClickType.RIGHT) return;
ItemStack item = player.getItemOnCursor();
CustomItem cursorItem = GearManager.parseItem(item);
if (cursorItem instanceof GoldToken)
{
GoldToken token = (GoldToken) cursorItem;
GoldManager.getInstance().cashIn(player, token);
player.setItemOnCursor(null); // Delete the gold token on cursor
_page.refresh();
}
}
}

View File

@ -0,0 +1,32 @@
package mineplex.game.clans.shop.bank;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.shop.item.IButton;
import mineplex.game.clans.economy.GoldManager;
public class StoreGoldButton implements IButton
{
private BankPage _page;
public StoreGoldButton(BankPage page)
{
_page = page;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (clickType != ClickType.LEFT) return;
if (_page.hasEnoughGold())
{
int cost = BankPage.TOKEN_VALUE;
GoldManager.getInstance().purchaseToken(player, cost);
_page.refresh();
}
}
}

View File

@ -10,12 +10,12 @@ import mineplex.game.clans.clans.ClansManager;
public class EnergyShop extends ShopBase<ClansManager>
{
public EnergyShop(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, "Energy Shop");
}
@Override
protected ShopPageBase<ClansManager, ? extends ShopBase<ClansManager>> buildPagesFor(Player player)
{

View File

@ -29,7 +29,6 @@ public class EnergyShopButton implements IButton
_page = page;
}
@Override
public void onClick(final Player player, ClickType clickType)
{