Public Repository for the Magicbane Shadowbane Emulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1050 lines
42 KiB

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.objects;
import engine.Enum;
import engine.Enum.ItemContainerType;
import engine.Enum.ItemType;
import engine.Enum.OwnerType;
import engine.gameManager.*;
import engine.loot.ModTableEntry;
import engine.loot.ModTypeTableEntry;
import engine.net.ItemProductionManager;
import engine.net.ItemQueue;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ErrorPopupMsg;
import engine.powers.EffectsBase;
import engine.server.MBServerStatics;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
public class ItemFactory {
public static void fillInventory(PlayerCharacter pc, int objectID, int count) {
if (pc == null)
return;
int max = 20;
CharacterItemManager itemManager = pc.getCharItemManager();
ItemBase ib = ItemBase.getItemBase(objectID);
if (count > max)
count = max;
ClientConnection cc = pc.getClientConnection();
if (itemManager == null || ib == null || cc == null)
return;
boolean worked;
for (int i = 0; i < count; i++) {
worked = false;
if (!itemManager.hasRoomInventory(ib.getWeight())) {
if (pc != null)
ChatManager.chatSystemInfo(pc, "You can not carry any more of that item.");
break;
}
Item item = new Item(ib, pc.getObjectUUID(), OwnerType.PlayerCharacter, (byte) 0, (byte) 0,
(short) 1, (short) 1, true, false, ItemContainerType.INVENTORY, (byte) 0,
new ArrayList<>(), "");
try {
item = DbManager.ItemQueries.ADD_ITEM(item);
worked = true;
} catch (Exception e) {
Logger.error(e);
}
if (worked) {
itemManager.addItemToInventory(item);
}
}
itemManager.updateInventory();
}
public static Item fillForge(NPC npc, PlayerCharacter pc, int itemsToRoll, int itemID, int pToken, int sToken, String customName) {
String prefixString = "";
String suffixString = "";
if (npc == null)
return null;
boolean useWarehouse = false;
ItemBase ib = ItemBase.getItemBase(itemID);
if (ib == null)
return null;
Building forge = npc.getBuilding();
if (forge == null)
return null;
if (!npc.getCharItemManager().hasRoomInventory(ib.getWeight())) {
if (pc != null)
ErrorPopupMsg.sendErrorPopup(pc, 21);
return null;
}
Zone zone = npc.getBuilding().getParentZone();
if (zone == null)
return null;
City city = City.getCity(zone.getPlayerCityUUID());
if (city == null)
return null;
MobLoot ml = null;
city.transactionLock.writeLock().lock();
try {
Warehouse cityWarehouse = city.getWarehouse();
if (cityWarehouse != null && forge.assetIsProtected())
useWarehouse = true;
// ROLL BANE SCROLL.
if (ib.getUUID() > 910010 && ib.getUUID() < 910019) {
ConcurrentHashMap<ItemBase, Integer> resources = cityWarehouse.getResources();
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, ib.getBaseValue());
int overdraft = BuildingManager.GetOverdraft(forge, ib.getBaseValue());
if (overdraft > 0 && !useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + " " + ib.getName());
return null;
}
if (overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + " " + ib.getName());
return null;
}
if (overdraft > resources.get(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + " " + ib.getName());
return null;
}
//All checks passed, lets withdraw from building first.
// if (pc != null){
// ChatManager.chatGuildInfo(pc.getGuild(), "Building withdraw = " + buildingWithdraw);
// ChatManager.chatGuildInfo(pc.getGuild(), "Warehouse overdraft withdraw = " + overdraft);
//
// ChatManager.chatGuildInfo(pc.getGuild(), "total withdraw = " + (overdraft + buildingWithdraw));
// }
if (!forge.transferGold(-buildingWithdraw, false)) {
overdraft += buildingWithdraw;
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + ib.getName());
return null;
} else {
if (overdraft > resources.get(ItemBase.GOLD_ITEM_BASE)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + ib.getName());
return null;
}
}
}
if (overdraft > 0)
if (!cityWarehouse.withdraw(npc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
//ChatManager.chatGuildError(pc, "Failed to create Item");
Logger.error("Warehouse With UID of " + cityWarehouse.getUID() + " Failed to Create Item." + ib.getName());
return null;
}
ml = new MobLoot(npc, ib, false);
ml.containerType = Enum.ItemContainerType.FORGE;
ml.setValue(0);
ml.loadEnchantments();
float time;
float rank = npc.getBuilding().getRank() - 1;
float rate = (float) (2.5 * rank);
time = (20 - rate);
time *= MBServerStatics.ONE_MINUTE;
if (ml.getItemBase().getUUID() > 910010 && ml.getItemBase().getUUID() < 910019) {
rank = ml.getItemBaseID() - 910010;
time = rank * 60 * 60 * 3 * 1000;
}
// No job is submitted, as object's upgradetime field
// is used to determin whether or not an object has
// compelted rolling. The game object exists previously
// to this, not when 'compelte' is pressed.
long upgradeTime = System.currentTimeMillis() + (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
DateTime dateTime = new DateTime();
dateTime = dateTime.withMillis(upgradeTime);
ml.setDateToUpgrade(upgradeTime);
npc.addItemToForge(ml);
int playerID = 0;
if (pc != null)
playerID = pc.getObjectUUID();
DbManager.NPCQueries.ADD_TO_PRODUCTION_LIST(ml.getObjectUUID(), npc.getObjectUUID(), ml.getItemBaseID(), dateTime, "", "", "", false, playerID);
ProducedItem pi = new ProducedItem(ml.getObjectUUID(), npc.getObjectUUID(), ml.getItemBaseID(), dateTime, false, "", "", "", playerID);
pi.setProducedItemID(ml.getObjectUUID());
pi.setAmount(itemsToRoll);
pi.setRandom(false);
ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())));
ItemProductionManager.send(produced);
return ml;
}
int galvorAmount = 0;
int wormwoodAmount = 0;
int prefixCost = 0;
int suffixCost = 0;
if (ib.getType() == ItemType.WEAPON && ib.getPercentRequired() == 110) {
switch (ib.getSkillRequired()) {
case "Bow":
case "Crossbow":
case "Spear":
case "Pole Arm":
case "Staff":
wormwoodAmount = 20;
break;
case "Axe":
case "Dagger":
case "Sword":
case "Hammer":
case "Unarmed Combat":
if (ib.isTwoHanded())
galvorAmount = 20;
else
galvorAmount = 10;
break;
}
}
ItemBase galvor = ItemBase.getItemBase(1580017);
ItemBase wormwood = ItemBase.getItemBase(1580018);
if (galvorAmount > 0 || wormwoodAmount > 0)
if (!useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "This item requires resources to roll! Please make sure the forge is protected to access the warehouse." + ib.getName());
return null;
}
if (galvorAmount > 0) {
if (cityWarehouse.isResourceLocked(galvor)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + ib.getName());
return null;
}
if (cityWarehouse.getResources().get(galvor) < galvorAmount) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + ib.getName());
return null;
}
}
if (wormwoodAmount > 0) {
if (cityWarehouse.isResourceLocked(wormwood)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Wormwood is locked." + ib.getName());
return null;
}
if (cityWarehouse.getResources().get(wormwood) < wormwoodAmount) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Wormwood in warehouse to roll this item." + ib.getName());
return null;
}
}
ConcurrentHashMap<ItemBase, Integer> suffixResourceCosts = null;
ConcurrentHashMap<ItemBase, Integer> prefixResourceCosts = null;
EffectsBase prefix = null;
if (pToken != 0) {
if (!useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Forge cannot access warehouse! Check to make sure forge is protected." + ib.getName());
return null;
}
prefix = PowersManager.getEffectByToken(pToken);
if (prefix == null)
return null;
EffectsBase prefixValue = PowersManager.getEffectByIDString(prefix.getIDString() + 'A');
if (prefixValue == null)
return null;
int baseCost = ib.getBaseValue();
int effectCost = (int) prefixValue.getValue();
int total = baseCost * 10 + effectCost;
prefixCost = effectCost;
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, total);
int overdraft = BuildingManager.GetOverdraft(forge, total);
if (overdraft > 0 && !useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
prefixResourceCosts = prefix.getResourcesForEffect();
for (ItemBase ibResources : prefixResourceCosts.keySet()) {
int warehouseAmount = cityWarehouse.getResources().get(ibResources);
int creationAmount = prefixResourceCosts.get(ibResources);
//ChatManager.chatInfoError(pc, "Prefix : " + ibResources.getName() + " / " + creationAmount);
if (warehouseAmount < creationAmount) {
//ChatManager.chatInfoError(pc, "You need at least " + creationAmount + " " + ibResources.getName() + " to Create this item.");
return null;
}
}
}
EffectsBase suffix = null;
if (sToken != 0) {
if (!useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Forge cannot access warehouse! Check to make sure forge is protected." + ib.getName());
return null;
}
suffix = PowersManager.getEffectByToken(sToken);
if (suffix == null)
return null;
EffectsBase suffixValue = PowersManager.getEffectByIDString(suffix.getIDString() + 'A');
if (suffixValue == null)
return null;
suffixResourceCosts = suffix.getResourcesForEffect();
int baseCost = ib.getBaseValue();
int effectCost = (int) suffixValue.getValue();
suffixCost = effectCost;
int total = baseCost * 10 + effectCost;
// int buildingWithdraw = Building.GetWithdrawAmountForRolling(forge, total);
int overdraft = BuildingManager.GetOverdraft(forge, total);
if (overdraft > 0 && !useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
for (ItemBase ibResources : suffixResourceCosts.keySet()) {
int warehouseAmount = cityWarehouse.getResources().get(ibResources);
int creationAmount = suffixResourceCosts.get(ibResources);
if (warehouseAmount < creationAmount) {
// if (pc != null)
// ChatManager.chatInfoError(pc, "You need at least " + creationAmount + " " + ibResources.getName() + " to Create this item.");
return null;
}
}
}
//Check if Total suffix and prefix costs + itemCost can be withdrawn.
int costToCreate = suffixCost + prefixCost + (ib.getBaseValue());
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, costToCreate);
int overdraft = BuildingManager.GetOverdraft(forge, costToCreate);
if (overdraft > 0 && !useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (overdraft > 0 && useWarehouse && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (useWarehouse && overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
// if (pc != null){
// ChatManager.chatGuildInfo(pc.getGuild(), "Building withdraw = " + buildingWithdraw);
// ChatManager.chatGuildInfo(pc.getGuild(), "Warehouse overdraft withdraw = " + overdraft);
//
// ChatManager.chatGuildInfo(pc.getGuild(), "total withdraw = " + (overdraft + buildingWithdraw));
// }
if (!forge.transferGold(-buildingWithdraw, false)) {
overdraft += buildingWithdraw;
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + ib.getName());
return null;
} else {
if (overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + ib.getName());
return null;
}
}
}
if (overdraft > 0 && useWarehouse)
if (!cityWarehouse.withdraw(npc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
//ChatManager.chatGuildError(pc, "Failed to create Item");
Logger.error("Warehouse With UID of " + cityWarehouse.getUID() + " Failed to Create Item." + ib.getName());
return null;
}
if (prefix != null) {
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Cannot Resource Roll without access to the warehouse! Make sure the forge is currently protected." + ib.getName());
return null;
}
for (ItemBase ibResources : prefixResourceCosts.keySet()) {
int creationAmount = prefixResourceCosts.get(ibResources);
if (cityWarehouse.isResourceLocked(ibResources) == true)
return null;
int oldAmount = cityWarehouse.getResources().get(ibResources);
int amount = creationAmount;
if (oldAmount < amount)
amount = oldAmount;
if (!cityWarehouse.withdraw(npc, ibResources, amount, false, true)) {
//ChatManager.chatGuildError(pc, "Failed to create Item");
Logger.error("Warehouse With UID of " + cityWarehouse.getUID() + " Failed to Create Item." + ib.getName());
return null;
}
}
}
if (suffix != null) {
for (ItemBase ibResources : suffixResourceCosts.keySet()) {
int creationAmount = suffixResourceCosts.get(ibResources);
if (cityWarehouse.isResourceLocked(ibResources) == true) {
ChatManager.chatSystemError(pc, ibResources.getName() + " is locked!" + ib.getName());
return null;
}
int oldAmount = cityWarehouse.getResources().get(ibResources);
int amount = creationAmount;
if (oldAmount < amount)
amount = oldAmount;
if (!cityWarehouse.withdraw(npc, ibResources, amount, false, true)) {
//ChatManager.chatGuildError(pc, "Failed to create Item");
Logger.error("Warehouse With UID of " + cityWarehouse.getUID() + " Failed to Create Item." + ib.getName());
return null;
}
}
}
if (prefix == null && suffix == null) {
int baseCost = ib.getBaseValue();
int total = (int) (baseCost + baseCost * (float) .10);
buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, total);
overdraft = BuildingManager.GetOverdraft(forge, total);
if (overdraft > 0 && !useWarehouse) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (useWarehouse && overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
}
if (!forge.transferGold(-buildingWithdraw, false)) {
overdraft += buildingWithdraw;
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + ib.getName());
return null;
} else {
if (overdraft > cityWarehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + ib.getName());
return null;
}
}
}
if (overdraft > 0)
if (!cityWarehouse.withdraw(npc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
//ChatManager.chatGuildError(pc, "Failed to create Item");
Logger.error("Warehouse With UID of " + cityWarehouse.getUID() + " Failed to Create Item." + ib.getName());
return null;
}
// ChatManager.chatGuildInfo(pc, "Gold Cost = " + total);
if (galvorAmount > 0) {
if (!cityWarehouse.withdraw(npc, galvor, galvorAmount, false, true)) {
ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Galvor from warehouse!" + ib.getName());
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
if (wormwoodAmount > 0) {
if (!cityWarehouse.withdraw(npc, wormwood, wormwoodAmount, false, true)) {
ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Wormwood from warehouse!" + ib.getName());
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
ml = new MobLoot(npc, ib, false);
ml.containerType = Enum.ItemContainerType.FORGE;
ml.setName(customName);
if (prefix != null) {
ml.addPermanentEnchantment(prefix.getIDString(), 0, 0, true);
ml.setPrefix(prefix.getIDString());
prefixString = prefix.getIDString();
}
if (suffix != null) {
ml.addPermanentEnchantment(suffix.getIDString(), 0, 0, false);
ml.setSuffix(suffix.getIDString());
suffixString = suffix.getIDString();
}
ml.loadEnchantments();
//set value to 0 so magicvalue can be recalculated in getValue.
ml.setValue(0);
float time;
float rank = npc.getBuilding().getRank() - 1;
float rate = (float) (2.5 * rank);
time = (20 - rate);
time *= MBServerStatics.ONE_MINUTE;
if (ml.getItemBase().getUUID() > 910010 && ml.getItemBase().getUUID() < 910019) {
rank = ml.getItemBaseID() - 910010;
time = rank * 60 * 60 * 3 * 1000;
}
// No job is submitted, as object's upgradetime field
// is used to determin whether or not an object has
// compelted rolling. The game object exists previously
// to this, not when 'compelte' is pressed.
long upgradeTime = System.currentTimeMillis() + (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
DateTime dateTime = new DateTime();
dateTime = dateTime.withMillis(upgradeTime);
ml.setDateToUpgrade(upgradeTime);
npc.addItemToForge(ml);
int playerID = 0;
if (pc != null)
playerID = pc.getObjectUUID();
DbManager.NPCQueries.ADD_TO_PRODUCTION_LIST(ml.getObjectUUID(), npc.getObjectUUID(), ml.getItemBaseID(), dateTime, prefixString, suffixString, ml.getCustomName(), false, playerID);
ProducedItem pi = new ProducedItem(npc.getRolling().size(), npc.getObjectUUID(), ml.getItemBaseID(), dateTime, false, prefixString, suffixString, ml.getCustomName(), playerID);
pi.setProducedItemID(ml.getObjectUUID());
pi.setAmount(itemsToRoll);
ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())));
ItemProductionManager.send(produced);
} catch (Exception e) {
Logger.error(e);
} finally {
city.transactionLock.writeLock().unlock();
}
// npc.addItemToForge(item);
return ml;
}
public static Item randomRoll(NPC vendor, PlayerCharacter playerCharacter, int itemsToRoll, int itemBaseID) {
byte itemModTable;
int prefixMod = 0;
int suffixMod = 0;
String prefix = "";
String suffix = "";
ModTableEntry prefixEntry = null;
ModTableEntry suffixEntry = null;
ItemBase ib = ItemBase.getItemBase(itemBaseID);
if (ib == null)
return null;
if (!vendor.getCharItemManager().hasRoomInventory(ib.getWeight())) {
if (playerCharacter != null)
ChatManager.chatSystemInfo(playerCharacter, vendor.getName() + " " + vendor.getContract().getName() + " Inventory is full.");
return null;
}
itemModTable = (byte) ib.getModTable();
if (!vendor.getItemModTable().contains(itemModTable)) {
if (playerCharacter != null)
ErrorPopupMsg.sendErrorPopup(playerCharacter, 59);
return null;
}
for (byte temp : vendor.getItemModTable()) {
if (itemModTable != temp)
continue;
prefixMod = vendor.getModTypeTable().get(vendor.getItemModTable().indexOf(temp));
suffixMod = vendor.getModSuffixTable().get(vendor.getItemModTable().indexOf(temp));
}
if (prefixMod == 0 && suffixMod == 0) {
Logger.info("Failed to find modTables for item " + ib.getName());
return null;
}
// Roll on the tables for this vendor
ModTypeTableEntry prefixTypeTable = ModTypeTableEntry.rollTable(prefixMod, ThreadLocalRandom.current().nextInt(1, 100 + 1));
ModTypeTableEntry suffixTypeTable = ModTypeTableEntry.rollTable(suffixMod, ThreadLocalRandom.current().nextInt(1, 100 + 1));
// Sanity check.
if (prefixTypeTable == null || suffixTypeTable == null)
return null;
int rollPrefix = ThreadLocalRandom.current().nextInt(1, 100 + 1);
if (rollPrefix < 80) {
int randomPrefix = LootManager.TableRoll(vendor.getLevel(), false);
prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix);
if (prefixEntry != null)
prefix = prefixEntry.action;
}
int rollSuffix = ThreadLocalRandom.current().nextInt(1, 100 + 1);
// Always have at least one mod on a magic rolled item.
// Suffix will be our backup plan.
if (rollSuffix < 80 || prefixEntry == null) {
int randomSuffix = LootManager.TableRoll(vendor.getLevel(), false);
suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix);
if (suffixEntry != null)
suffix = suffixEntry.action;
}
MobLoot toRoll = ItemFactory.produceRandomRoll(vendor, playerCharacter, prefix, suffix, itemBaseID);
if (toRoll == null)
return null;
toRoll.setValue(0);
float time;
float rank = vendor.getBuilding().getRank() - 1;
float rate = (float) (2.5 * rank);
time = (20 - rate);
time *= MBServerStatics.ONE_MINUTE;
if (toRoll.getItemBase().getUUID() > 910010 && toRoll.getItemBase().getUUID() < 910019) {
rank = toRoll.getItemBaseID() - 910010;
time = rank * 60 * 60 * 3 * 1000;
}
// No job is submitted, as object's upgradetime field
// is used to determine whether an object has
// completed rolling. The game object exists previously
// to this, not when 'complete' is pressed.
long upgradeTime = System.currentTimeMillis() + (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
DateTime dateTime = new DateTime();
dateTime = dateTime.withMillis(upgradeTime);
toRoll.setDateToUpgrade(upgradeTime);
int playerID = 0;
if (playerCharacter != null)
playerID = playerCharacter.getObjectUUID();
DbManager.NPCQueries.ADD_TO_PRODUCTION_LIST(toRoll.getObjectUUID(), vendor.getObjectUUID(), toRoll.getItemBaseID(), dateTime, prefix, suffix, toRoll.getCustomName(), true, playerID);
ProducedItem pi = new ProducedItem(toRoll.getObjectUUID(), vendor.getObjectUUID(), toRoll.getItemBaseID(), dateTime, true, prefix, suffix, toRoll.getCustomName(), playerID);
pi.setProducedItemID(toRoll.getObjectUUID());
pi.setAmount(itemsToRoll);
ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())));
ItemProductionManager.send(produced);
return toRoll;
}
public static MobLoot produceRandomRoll(NPC npc, PlayerCharacter pc, String prefixString, String suffixString, int itemID) {
boolean useWarehouse = false;
if (npc == null)
return null;
ItemBase ib = ItemBase.getItemBase(itemID);
if (ib == null)
return null;
Building forge = npc.getBuilding();
if (forge == null)
return null;
Zone zone = npc.getBuilding().getParentZone();
if (zone == null)
return null;
City city = City.getCity(zone.getPlayerCityUUID());
if (city == null)
return null;
MobLoot ml = null;
city.transactionLock.writeLock().lock();
try {
Warehouse cityWarehouse = city.getWarehouse();
if (cityWarehouse != null && forge.assetIsProtected())
useWarehouse = true;
ConcurrentHashMap<ItemBase, Integer> resources = null;
if (useWarehouse)
resources = cityWarehouse.getResources();
int galvorAmount = 0;
int wormwoodAmount = 0;
if (ib.getType() == ItemType.WEAPON && ib.getPercentRequired() == 110) {
switch (ib.getSkillRequired()) {
case "Bow":
case "Crossbow":
case "Spear":
case "Pole Arm":
case "Staff":
wormwoodAmount = 22;
break;
case "Axe":
case "Dagger":
case "Sword":
case "Hammer":
case "Unarmed Combat":
if (ib.isTwoHanded())
galvorAmount = 22;
else
galvorAmount = 11;
break;
}
}
ItemBase galvor = ItemBase.getItemBase(1580017);
ItemBase wormwood = ItemBase.getItemBase(1580018);
//Cant roll 110% weapons that require resources if not allowed to use warehouse.
if (galvorAmount > 0 || wormwoodAmount > 0)
if (!useWarehouse)
return null;
if (galvorAmount > 0) {
if (cityWarehouse.isResourceLocked(galvor)) {
ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + ib.getName());
return null;
}
if (cityWarehouse.getResources().get(galvor) < galvorAmount) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + ib.getName());
return null;
}
}
if (wormwoodAmount > 0) {
if (cityWarehouse.isResourceLocked(wormwood)) {
ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + ib.getName());
return null;
}
if (cityWarehouse.getResources().get(wormwood) < wormwoodAmount) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + ib.getName());
return null;
}
}
EffectsBase prefix = null;
if (!prefixString.isEmpty()) {
prefix = PowersManager.getEffectByIDString(prefixString);
if (prefix == null)
return null;
}
ItemBase goldIB = ItemBase.getGoldItemBase();
int baseCost = ib.getBaseValue();
int total = (int) (baseCost + baseCost * .10);
EffectsBase suffix = null;
if (!suffixString.isEmpty()) {
suffix = PowersManager.getEffectByIDString(suffixString);
if (suffix == null)
return null;
}
//calculate gold costs and remove from the warehouse
if (prefix != null || suffix != null) {
int costToCreate = (int) (ib.getBaseValue() + ib.getBaseValue() * .10f);
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, costToCreate);
int overdraft = BuildingManager.GetOverdraft(forge, costToCreate);
if (overdraft > 0 && !useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (useWarehouse && overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (useWarehouse && overdraft > resources.get(goldIB)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
if (!forge.transferGold(-buildingWithdraw, false)) {
overdraft += buildingWithdraw;
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + ib.getName());
return null;
} else {
if (overdraft > resources.get(goldIB)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + ib.getName());
return null;
}
}
}
// there was an overdraft, withdraw the rest from warehouse.
if (overdraft > 0) {
if (pc != null) {
if (!cityWarehouse.withdraw(pc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
} else {
if (!cityWarehouse.withdraw(npc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
}
}
if (prefix == null && suffix == null) {
int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, total);
int overdraft = BuildingManager.GetOverdraft(forge, total);
if (overdraft > 0 && !useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + ib.getName());
return null;
}
if (useWarehouse && overdraft > 0 && cityWarehouse.isResourceLocked(ItemBase.GOLD_ITEM_BASE)) {
if (pc != null)
ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + ib.getName());
return null;
}
if (useWarehouse && overdraft > resources.get(goldIB)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + ib.getName());
return null;
}
if (!forge.transferGold(-buildingWithdraw, false)) {
overdraft += buildingWithdraw;
if (!useWarehouse) {
ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + ib.getName());
return null;
} else {
if (overdraft > resources.get(goldIB)) {
ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + ib.getName());
return null;
}
}
}
if (overdraft > 0 && useWarehouse) {
if (pc != null) {
if (!cityWarehouse.withdraw(pc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
} else {
if (!cityWarehouse.withdraw(npc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) {
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
}
}
if (galvorAmount > 0 && useWarehouse) {
//ChatManager.chatGuildInfo(pc, "Withdrawing " + galvorAmount + " galvor from warehouse");
if (!cityWarehouse.withdraw(npc, galvor, galvorAmount, false, true)) {
ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Galvor from warehouse!" + ib.getName());
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
if (wormwoodAmount > 0 && useWarehouse) {
//ChatManager.chatGuildInfo(pc, "Withdrawing " + wormwoodAmount + " wormwood from warehouse");
if (!cityWarehouse.withdraw(npc, wormwood, wormwoodAmount, false, true)) {
ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Wormwood from warehouse for " + ib.getName());
Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl ");
return null;
}
}
ml = new MobLoot(npc, ib, false);
ml.containerType = Enum.ItemContainerType.FORGE;
if (prefix != null) {
ml.addPermanentEnchantment(prefix.getIDString(), 0, 0, true);
ml.setPrefix(prefix.getIDString());
}
if (suffix != null) {
ml.addPermanentEnchantment(suffix.getIDString(), 0, 0, false);
ml.setSuffix(suffix.getIDString());
}
ml.loadEnchantments();
ml.setValue(0);
ml.setRandom(true);
npc.addItemToForge(ml);
} catch (Exception e) {
Logger.error(e);
} finally {
city.transactionLock.writeLock().unlock();
}
return ml;
}
}