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.

264 lines
8.9 KiB

package engine.gameManager;
import engine.loot.WorkOrder;
import engine.mbEnums;
import engine.objects.*;
import engine.powers.poweractions.AbstractPowerAction;
import org.pmw.tinylog.Logger;
import java.util.EnumSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
public enum ItemManager {
ITEMMANAGER;
public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty())
return true;
if (item.template.item_race_req.isEmpty() == false)
if (item.template.item_race_req.contains(race))
return true;
if (item.template.item_race_res.isEmpty() == false)
if (item.template.item_class_res.contains(race) == false)
return true;
return false;
}
public static Boolean ValidClass(Item item, mbEnums.ClassType base, mbEnums.ClassType profession) {
// Early exit if no entry
if (item.template.item_class_req.isEmpty() && item.template.item_class_res.isEmpty())
return true;
if (item.template.item_class_req.isEmpty() == false)
if (item.template.item_class_req.contains(base) || item.template.item_class_req.contains(profession))
return true;
if (item.template.item_class_res.isEmpty() == false)
if (item.template.item_class_res.contains(base) == false && item.template.item_class_res.contains(profession) == false)
return true;
return false;
}
public static Boolean ValidDiscipline(Item item, EnumSet<mbEnums.DisciplineType> discs) {
// Early exit if no entry
if (item.template.item_disc_req.isEmpty() && item.template.item_disc_res.isEmpty())
return true;
EnumSet<mbEnums.DisciplineType> workSet = EnumSet.copyOf(discs);
if (item.template.item_disc_req.isEmpty() == false) {
workSet.retainAll(item.template.item_disc_req);
if (workSet.isEmpty() == false)
return true;
}
if (item.template.item_disc_res.isEmpty() == false) {
workSet.retainAll(item.template.item_disc_res);
if (workSet.isEmpty() == false)
return true;
}
return false;
}
public static Boolean canCharacterEquip(Item item, AbstractCharacter character) {
return ValidRace(item, character.absRace) && ValidClass(item, character.absBaseClass, character.absPromotionClass) && ValidDiscipline(item, character.absDisciplines);
}
public static boolean validForSkills(Item item, ConcurrentHashMap<String, CharacterSkill> skills) {
CharacterSkill characterSkill;
if (item.template.item_skill_required.isEmpty())
return true;
for (String skillRequired : item.template.item_skill_required.keySet()) {
int required_value = item.template.item_skill_required.get(skillRequired);
characterSkill = skills.get(skillRequired);
if (characterSkill == null)
return false;
if (characterSkill.getModifiedAmountBeforeMods() > required_value)
return true;
}
return false;
}
public static boolean isTwoHanded(Item item) {
if (!item.template.item_type.equals(mbEnums.ItemType.WEAPON))
return false;
return item.template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
}
public static boolean isTwoHanded(ItemTemplate template) {
if (!template.item_type.equals(mbEnums.ItemType.WEAPON))
return false;
return template.item_eq_slots_and.contains(EnumSet.of(mbEnums.EquipSlotType.LHELD, mbEnums.EquipSlotType.RHELD));
}
public static boolean isShield(Item item) {
if (item.template.item_skill_required.containsKey("Block"))
return true;
return false;
}
public static boolean isShield(ItemTemplate template) {
if (template.item_skill_required.containsKey("Block"))
return true;
return false;
}
public static boolean validForSlot(mbEnums.EquipSlotType slot, ConcurrentHashMap<mbEnums.EquipSlotType, Item> equipped, Item item) {
boolean validSlot = false;
if (equipped == null)
return false;
//Item not valid for slot
if (item.template.item_eq_slots_or.contains(slot) == false)
return false;
// Slot is taken
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
return false;
// Two handed weapons take up two slots
if ((isTwoHanded(item)) &&
((slot == mbEnums.EquipSlotType.LHELD && equipped.get(mbEnums.EquipSlotType.RHELD) != null) ||
(slot == mbEnums.EquipSlotType.RHELD && equipped.get(mbEnums.EquipSlotType.LHELD) != null)))
return false;
if (item.template.item_type.equals(mbEnums.ItemType.WEAPON))
if (equipped.get(slot) != null && equipped.get(slot).equals(item) == false)
return false;
return true;
}
public static boolean canEquip(mbEnums.EquipSlotType slot, CharacterItemManager itemManager, AbstractCharacter abstractCharacter, Item item) {
if (itemManager == null || abstractCharacter == null)
return false;
// Early exit for mobiles and NPCS.
// Perhaps not needed now that mobs have skills.
if (EnumSet.of(mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(abstractCharacter.getObjectType()))
return false;
if (!validForSlot(slot, itemManager.getEquipped(), item))
return false;
if (!validForSkills(item, abstractCharacter.getSkills()))
return false;
if (canCharacterEquip(item, abstractCharacter) == false)
return false;
//players can't wear 0 value items.
return item.template.item_value != 0 || Kit.IsNoobGear(item.templateID);
}
public static boolean MakeItemForPlayer(int templateID, PlayerCharacter reciever, int amount) {
boolean itemWorked = false;
Item item = new Item(templateID);
item.ownerID = reciever.getObjectUUID();
item.ownerType = mbEnums.OwnerType.PlayerCharacter;
item.containerType = mbEnums.ItemContainerType.INVENTORY;
item.numberOfItems = amount;
try {
item = DbManager.ItemQueries.PERSIST(item);
itemWorked = true;
} catch (Exception e) {
Logger.error(e);
}
if (!itemWorked)
return false;
reciever.charItemManager.addItemToInventory(item);
reciever.charItemManager.updateInventory();
return true;
}
public static void applyPrefixOrSuffix(Item item, String powerAction) {
AbstractPowerAction abstractPowerAction = PowersManager.getPowerActionByIDString(powerAction);
if (abstractPowerAction == null)
return;
abstractPowerAction.applyEffectForItem(item, 0);
item.getEffectNames().add(powerAction);
}
public static int validate(WorkOrder workOrder) {
int validation_result = 0;
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
return 30; //30: That person cannot carry that item
if (!workOrder.vendor.getItemModTable().contains((template.modTable)))
return 59; //59: This hireling does not have this formula
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
return 10; //18: You can't really afford that
// Forge must be protected in order to access warehouse.
if (ForgeManager.calcProductionCost(workOrder).size() > 1)
if (!workOrder.vendor.building.protectionState.equals(mbEnums.ProtectionState.PROTECTED))
return 193; //193: Production denied: This building must be protected to gain access to warehouse
return validation_result;
}
}