// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // 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.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; public class ItemFactory { public static void fillInventory(PlayerCharacter pc, int templateID, int count) { if (pc == null) return; int max = 20; CharacterItemManager itemManager = pc.getCharItemManager(); ItemTemplate template = ItemTemplate.itemTemplates.get(templateID); if (count > max) count = max; ClientConnection cc = pc.getClientConnection(); if (itemManager == null || template == null || cc == null) return; boolean worked; for (int i = 0; i < count; i++) { worked = false; if (!itemManager.hasRoomInventory(template.item_wt)) { if (pc != null) ChatManager.chatSystemInfo(pc, "You can not carry any more of that item."); break; } Item item = new Item(templateID); item.ownerID = pc.getObjectUUID(); item.ownerType = OwnerType.PlayerCharacter; item.containerType = ItemContainerType.INVENTORY; try { item = DbManager.ItemQueries.PERSIST(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 templateID, int pToken, int sToken, String customName) { String prefixString = ""; String suffixString = ""; if (npc == null) return null; boolean useWarehouse = false; ItemBase ib = ItemBase.getItemBase(templateID); ItemTemplate template = ItemTemplate.itemTemplates.get(templateID); if (template == null) return null; Building forge = npc.getBuilding(); if (forge == null) return null; if (!npc.getCharItemManager().hasRoomInventory(template.item_wt)) { if (pc != null) ErrorPopupMsg.sendErrorPopup(pc, 21); return null; } Zone zone = npc.getBuilding().getParentZone(); if (zone == null) return null; City city = City.getCity(zone.playerCityUUID); 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 (templateID > 910010 && templateID < 910019) { ConcurrentHashMap resources = cityWarehouse.resources; int buildingWithdraw = BuildingManager.GetWithdrawAmountForRolling(forge, template.item_value); int overdraft = BuildingManager.GetOverdraft(forge, template.item_value); if (overdraft > 0 && !useWarehouse) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough gold in building strongbox." + " " + template.item_base_name); return null; } if (overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + " " + template.item_base_name); return null; } if (overdraft > resources.get(ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + " " + template.item_base_name); return null; } if (!forge.transferGold(-buildingWithdraw, false)) { overdraft += buildingWithdraw; if (!useWarehouse) { ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + template.item_base_name); return null; } else { if (overdraft > resources.get(ItemBase.GOLD_ITEM_BASE)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + template.item_base_name); return null; } } } if (overdraft > 0) if (!Warehouse.withdraw(cityWarehouse, npc, ItemBase.GOLD_ITEM_BASE, overdraft, true)) { Logger.error("Warehouse With UID of " + cityWarehouse.UID + " Failed to Create Item." + template.item_base_name); 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.getTemplsteID() - 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.getTemplsteID(), dateTime, "", "", "", false, playerID); ProducedItem pi = new ProducedItem(ml.getObjectUUID(), npc.getObjectUUID(), ml.getTemplsteID(), 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 (template.item_type.equals(ItemType.WEAPON) && ib.getPercentRequired() == 110) { switch (template.item_skill_used) { 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 (ItemTemplate.isTwoHanded(template)) 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." + template.item_base_name); return null; } if (galvorAmount > 0) { if (Warehouse.isResourceLocked(cityWarehouse, galvor)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + template.item_base_name); return null; } if (cityWarehouse.resources.get(galvor) < galvorAmount) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + template.item_base_name); return null; } } if (wormwoodAmount > 0) { if (Warehouse.isResourceLocked(cityWarehouse, wormwood)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Wormwood is locked." + template.item_base_name); return null; } if (cityWarehouse.resources.get(wormwood) < wormwoodAmount) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Wormwood in warehouse to roll this item." + template.item_base_name); return null; } } ConcurrentHashMap suffixResourceCosts = null; ConcurrentHashMap 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." + template.item_base_name); 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 = template.item_value; 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." + template.item_base_name); return null; } if (overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); return null; } prefixResourceCosts = prefix.getResourcesForEffect(); for (ItemBase ibResources : prefixResourceCosts.keySet()) { int warehouseAmount = cityWarehouse.resources.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." + template.item_base_name); 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 = template.item_value; 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." + template.item_base_name); return null; } if (overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); return null; } for (ItemBase ibResources : suffixResourceCosts.keySet()) { int warehouseAmount = cityWarehouse.resources.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 + template.item_value; 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." + template.item_base_name); return null; } if (overdraft > 0 && useWarehouse && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (useWarehouse && overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); 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." + template.item_base_name); return null; } else { if (overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + template.item_base_name); return null; } } } if (overdraft > 0 && useWarehouse) if (!Warehouse.withdraw(cityWarehouse, npc, ItemBase.GOLD_ITEM_BASE, overdraft, true)) { //ChatManager.chatGuildError(pc, "Failed to create Item"); Logger.error("Warehouse With UID of " + cityWarehouse.UID + " Failed to Create Item." + template.item_base_name); 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." + template.item_base_name); return null; } for (ItemBase ibResources : prefixResourceCosts.keySet()) { int creationAmount = prefixResourceCosts.get(ibResources); if (Warehouse.isResourceLocked(cityWarehouse, ibResources) == true) return null; int oldAmount = cityWarehouse.resources.get(ibResources); int amount = creationAmount; if (oldAmount < amount) amount = oldAmount; if (!Warehouse.withdraw(cityWarehouse, npc, ibResources, amount, true)) { //ChatManager.chatGuildError(pc, "Failed to create Item"); Logger.error("Warehouse With UID of " + cityWarehouse.UID + " Failed to Create Item." + template.item_base_name); return null; } } } if (suffix != null) { for (ItemBase ibResources : suffixResourceCosts.keySet()) { int creationAmount = suffixResourceCosts.get(ibResources); if (Warehouse.isResourceLocked(cityWarehouse, ibResources) == true) { ChatManager.chatSystemError(pc, "Resource is locked!" + template.item_base_name); return null; } int oldAmount = cityWarehouse.resources.get(ibResources); int amount = creationAmount; if (oldAmount < amount) amount = oldAmount; if (!Warehouse.withdraw(cityWarehouse, npc, ibResources, amount, true)) { //ChatManager.chatGuildError(pc, "Failed to create Item"); Logger.error("Warehouse With UID of " + cityWarehouse.UID + " Failed to Create Item." + template.item_base_name); return null; } } } if (prefix == null && suffix == null) { int baseCost = template.item_value; 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." + template.item_base_name); return null; } if (overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (useWarehouse && overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); return null; } } if (!forge.transferGold(-buildingWithdraw, false)) { overdraft += buildingWithdraw; if (!useWarehouse) { ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + template.item_base_name); return null; } else { if (overdraft > cityWarehouse.resources.get(ItemBase.GOLD_ITEM_BASE)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + template.item_base_name); return null; } } } if (overdraft > 0) if (!Warehouse.withdraw(cityWarehouse, npc, ItemBase.GOLD_ITEM_BASE, overdraft, true)) { //ChatManager.chatGuildError(pc, "Failed to create Item"); Logger.error("Warehouse With UID of " + cityWarehouse.UID + " Failed to Create Item." + template.item_base_name); return null; } // ChatManager.chatGuildInfo(pc, "Gold Cost = " + total); if (galvorAmount > 0) { if (!Warehouse.withdraw(cityWarehouse, npc, galvor, galvorAmount, true)) { ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Galvor from warehouse!" + template.item_base_name); Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl "); return null; } } if (wormwoodAmount > 0) { if (!Warehouse.withdraw(cityWarehouse, npc, wormwood, wormwoodAmount, true)) { ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Wormwood from warehouse!" + template.item_base_name); 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.getTemplsteID() - 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.getTemplsteID(), dateTime, prefixString, suffixString, ml.getCustomName(), false, playerID); ProducedItem pi = new ProducedItem(npc.getRolling().size(), npc.getObjectUUID(), ml.getTemplsteID(), 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); ItemTemplate template = ItemTemplate.itemTemplates.get(itemBaseID); if (template == null) return null; if (!vendor.getCharItemManager().hasRoomInventory(template.item_wt)) { 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 " + template.item_base_name); 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.getTemplsteID() - 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.getTemplsteID(), dateTime, prefix, suffix, toRoll.getCustomName(), true, playerID); ProducedItem pi = new ProducedItem(toRoll.getObjectUUID(), vendor.getObjectUUID(), toRoll.getTemplsteID(), 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); ItemTemplate template = ItemTemplate.itemTemplates.get(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.playerCityUUID); 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 resources = null; if (useWarehouse) resources = cityWarehouse.resources; int galvorAmount = 0; int wormwoodAmount = 0; if (template.item_type.equals(ItemType.WEAPON) && ib.getPercentRequired() == 110) { switch (template.item_skill_used) { 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 (ItemTemplate.isTwoHanded(template)) 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 (Warehouse.isResourceLocked(cityWarehouse, galvor)) { ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + template.item_base_name); return null; } if (cityWarehouse.resources.get(galvor) < galvorAmount) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + template.item_base_name); return null; } } if (wormwoodAmount > 0) { if (Warehouse.isResourceLocked(cityWarehouse, wormwood)) { ErrorPopupMsg.sendErrorMsg(pc, "Galvor is locked." + template.item_base_name); return null; } if (cityWarehouse.resources.get(wormwood) < wormwoodAmount) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Galvor in warehouse to roll this item." + template.item_base_name); return null; } } EffectsBase prefix = null; if (!prefixString.isEmpty()) { prefix = PowersManager.getEffectByIDString(prefixString); if (prefix == null) return null; } ItemBase goldIB = ItemBase.getGoldItemBase(); int baseCost = template.item_value; 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) (template.item_value + template.item_value * .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." + template.item_base_name); return null; } if (useWarehouse && overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (useWarehouse && overdraft > resources.get(goldIB)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); return null; } if (!forge.transferGold(-buildingWithdraw, false)) { overdraft += buildingWithdraw; if (!useWarehouse) { ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + template.item_base_name); return null; } else { if (overdraft > resources.get(goldIB)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + template.item_base_name); return null; } } } // there was an overdraft, withdraw the rest from warehouse. if (overdraft > 0) { if (pc != null) { if (!Warehouse.withdraw(cityWarehouse, pc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) { Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl "); return null; } } else { if (!Warehouse.withdraw(cityWarehouse, npc, ItemBase.GOLD_ITEM_BASE, overdraft, 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." + template.item_base_name); return null; } if (useWarehouse && overdraft > 0 && Warehouse.isResourceLocked(cityWarehouse, ItemBase.GOLD_ITEM_BASE)) { if (pc != null) ErrorPopupMsg.sendErrorMsg(pc, "Warehouse gold is barred! Overdraft cannot be withdrawn from warehouse." + template.item_base_name); return null; } if (useWarehouse && overdraft > resources.get(goldIB)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse for overdraft." + template.item_base_name); return null; } if (!forge.transferGold(-buildingWithdraw, false)) { overdraft += buildingWithdraw; if (!useWarehouse) { ErrorPopupMsg.sendErrorMsg(pc, "Building does not have enough gold to produce this item." + template.item_base_name); return null; } else { if (overdraft > resources.get(goldIB)) { ErrorPopupMsg.sendErrorMsg(pc, "Not enough Gold in Warehouse to produce this item." + template.item_base_name); return null; } } } if (overdraft > 0 && useWarehouse) { if (pc != null) { if (!Warehouse.withdraw(cityWarehouse, pc, ItemBase.GOLD_ITEM_BASE, overdraft, false, true)) { Logger.error("Warehouse with UID of" + cityWarehouse.getObjectUUID() + "Failed to Withdrawl "); return null; } } else { if (!Warehouse.withdraw(cityWarehouse, npc, ItemBase.GOLD_ITEM_BASE, overdraft, 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 (!Warehouse.withdraw(cityWarehouse, npc, galvor, galvorAmount, true)) { ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Galvor from warehouse!" + template.item_base_name); 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 (!Warehouse.withdraw(cityWarehouse, npc, wormwood, wormwoodAmount, true)) { ErrorPopupMsg.sendErrorMsg(pc, "Failed to withdraw Wormwood from warehouse for " + template.item_base_name); 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; } }