// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.objects; import ch.claude_martin.enumbitset.EnumBitSet; import engine.Enum; import engine.gameManager.*; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.msg.CityDataMsg; import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.VendorDialogMsg; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.concurrent.ThreadLocalRandom; public class Contract extends AbstractGameObject { private final int contractID; private final String name; private final int mobbaseID; private final int classID; private final int extraRune; private final int iconID; public int equipmentSet = 0; public int inventorySet = 0; private int vendorID; private boolean isTrainer; private VendorDialog vendorDialog; private ArrayList npcMenuOptions = new ArrayList<>(); private ArrayList npcModTypeTable = new ArrayList<>(); private ArrayList npcModSuffixTable = new ArrayList<>(); private ArrayList itemModTable = new ArrayList<>(); private ArrayList sellInventory = new ArrayList<>(); private EnumBitSet allowedBuildings; private ArrayList buyItemType = new ArrayList<>(); private ArrayList buySkillToken = new ArrayList<>(); private ArrayList buyUnknownToken = new ArrayList<>(); /** * No Table ID Constructor */ public Contract(int contractID, String name, int mobbaseID, int classID, int dialogID, int iconID, int extraRune) { super(); this.contractID = contractID; this.name = name; this.mobbaseID = mobbaseID; this.classID = classID; this.iconID = iconID; this.extraRune = extraRune; this.vendorDialog = VendorDialog.getVendorDialog(dialogID); setBools(); } /** * Normal Constructor */ public Contract(int contractID, String name, int mobbaseID, int classID, int dialogID, int iconID, int extraRune, int newUUID) { super(newUUID); this.contractID = contractID; this.name = name; this.mobbaseID = mobbaseID; this.classID = classID; this.iconID = iconID; this.extraRune = extraRune; this.vendorDialog = VendorDialog.getVendorDialog(dialogID); setBools(); } /** * ResultSet Constructor */ public Contract(ResultSet rs) throws SQLException { super(rs); this.contractID = rs.getInt("contractID"); this.name = rs.getString("name"); this.mobbaseID = rs.getInt("mobbaseID"); this.classID = rs.getInt("classID"); this.extraRune = rs.getInt("extraRune"); this.vendorDialog = VendorDialog.getVendorDialog(rs.getInt("dialogID")); this.iconID = rs.getInt("iconID"); this.vendorID = rs.getInt("vendorID"); this.allowedBuildings = EnumBitSet.asEnumBitSet(rs.getLong("allowedBuildingTypeID"), Enum.BuildingGroup.class); switch(this.contractID){ case 866: //banker case 865: //siege engineer case 899: //alchemist this.allowedBuildings.add(Enum.BuildingGroup.TOL); } if(this.getName().toLowerCase().contains("sage")){ this.allowedBuildings.add(Enum.BuildingGroup.TOL); } this.equipmentSet = rs.getInt("equipSetID"); this.inventorySet = rs.getInt("inventorySet"); try { String menuoptions = rs.getString("menuoptions"); if (!menuoptions.isEmpty()) { String[] data = menuoptions.split(" "); for (String data1 : data) { this.npcMenuOptions.add(Integer.parseInt(data1)); } } String modtypetable = rs.getString("pTable"); if (!modtypetable.isEmpty()) { String[] data = modtypetable.split(" "); for (String data1 : data) { this.npcModTypeTable.add(Integer.parseInt(data1)); } } String suffix = rs.getString("sTable"); if (!suffix.isEmpty()) { String[] data1 = suffix.split(" "); for (String data11 : data1) { this.npcModSuffixTable.add(Integer.parseInt(data11)); } } String itemMod = rs.getString("itemModTable"); if (!itemMod.isEmpty()) { String[] data2 = itemMod.split(" "); for (byte i = 0; i < data2.length; i++) { this.itemModTable.add(Byte.parseByte(data2[i])); } } } catch (SQLException | NumberFormatException e) { Logger.error("Error when parsing mod tables"); } setBools(); } //Specify if trainer, merchant, banker, etc via classID private void setBools() { DbManager.ContractQueries.LOAD_CONTRACT_INVENTORY(this); DbManager.ContractQueries.LOAD_SELL_LIST_FOR_CONTRACT(this); this.isTrainer = this.classID > 2499 && this.classID < 3050 || this.classID == 2028; } /* * Getters */ public int getContractID() { return this.contractID; } public String getName() { return this.name; } public int getMobbaseID() { return this.mobbaseID; } public int getClassID() { return this.classID; } public int getExtraRune() { return this.extraRune; } public boolean isTrainer() { return this.isTrainer; } public int getIconID() { return this.iconID; } public int getVendorID() { return this.vendorID; } public VendorDialog getVendorDialog() { return this.vendorDialog; } public static VendorDialog HandleArenaMaster(int optionId, NPC npc, PlayerCharacter pc){ //1502043 pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); vd.getOptions().clear(); switch(optionId){ case 15020431: //if(pc.isBoxed){ // ChatManager.chatSystemInfo(pc, "You Cannot Join The Que, You Are Boxed"); //}else { if (ArenaManager.playerQueue.contains(pc)) { ChatManager.chatSystemInfo(pc, "You Are Already In The Arena Que"); } else { ArenaManager.joinQueue(pc); ChatManager.chatSystemInfo(pc, "You Have Joined The Arena Que"); } //} break; case 15020432: if(ArenaManager.playerQueue.contains(pc)) { ArenaManager.leaveQueue(pc); ChatManager.chatSystemInfo(pc, "You Have Left The Arena Que"); }else{ ChatManager.chatSystemInfo(pc, "You Are Not In The Arena Que"); } break; } MenuOption option1 = new MenuOption(15020431, "Join Arena Que", 15020431); vd.getOptions().add(option1); MenuOption option2 = new MenuOption(15020432, "Leave Arena Que", 15020432); vd.getOptions().add(option2); return vd; } public static VendorDialog HandleEnrollmentOfficer(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); //VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); vd.getOptions().clear(); switch(optionId) { default: if (pc.isBoxed) { MenuOption option1 = new MenuOption(15020401, "Unbox Character", 15020401); vd.getOptions().add(option1); } break; case 15020401: PlayerCharacter.unboxPlayer(pc); vd.getOptions().clear(); break; } return vd; } public static VendorDialog HandleGamblerOptions(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); vd.getOptions().clear(); MenuOption option1 = new MenuOption(15020441, "Gamble 1000", 15020441); vd.getOptions().add(option1); MenuOption option2 = new MenuOption(15020442, "Gamble 10,000", 15020442); vd.getOptions().add(option2); MenuOption option3 = new MenuOption(15020443, "Gamble 100,000", 15020443); vd.getOptions().add(option3); switch(optionId) { case 15020441: // gamble 1000 gamble(pc,1000); break; case 15020442: // gamble 10,000 gamble(pc,10000); break; case 15020443: // gamble 100,000 gamble(pc,100000); break; } return vd; } public static void gamble(PlayerCharacter pc, int amount){ if(!pc.timestamps.containsKey("NextSlot")) pc.timestamps.put("NextSlot",System.currentTimeMillis()); if(pc.timestamps.get("NextSlot") > System.currentTimeMillis()) return; pc.timestamps.put("NextSlot",System.currentTimeMillis() + 2000L); if(pc.charItemManager == null){ return; } int goldAmount = pc.charItemManager.getGoldInventory().getNumOfItems(); if(goldAmount < amount) { ChatManager.chatSystemInfo(pc, "You Cannot Afford This Wager"); return; } goldAmount -= amount; pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount); pc.charItemManager.updateInventory(); ChatManager.chatSystemInfo(pc, "You Attempt To Gamble " + amount + " ..."); int roll1 = ThreadLocalRandom.current().nextInt(1,7); int roll2 = ThreadLocalRandom.current().nextInt(1,7); int roll3 = ThreadLocalRandom.current().nextInt(1,7); ChatManager.chatSystemInfo(pc, "Gambler Has Rolled: " + roll1 + " " + roll2 + " " + roll3); int winnings = 0; if(roll1 == roll2 && roll1 == roll3) winnings = amount * roll1 * 10; if(winnings > 0) ChatManager.chatSystemInfo(pc, "You Have Won " + winnings + " Gold Coins!"); else ChatManager.chatSystemInfo(pc, "You Have Lost The Wager"); goldAmount += winnings; pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount); pc.charItemManager.updateInventory(); } public static boolean isClassTrainer(int id){ if(id >= 5 && id <= 30) return true; return false; } public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); vd.getOptions().clear(); Building building = npc.building; Bane bane = null; int updateBaneTime = 0; int updateBaneDay = 0; int updateBaneCap = 0; int treesInNation = 0; if(building != null) { City city = ZoneManager.getCityAtLocation(building.loc); if(city != null){ bane = city.getBane(); if(!city.getGuild().equals(pc.guild)) return vd; if(!GuildStatusController.isInnerCouncil(pc.getGuildStatus()) && !GuildStatusController.isGuildLeader(pc.getGuildStatus())){ return vd; } for(Guild sub : city.getGuild().getNation().getSubGuildList()){ if(sub.getOwnedCity() != null){ treesInNation += 1; } } } } if(bane == null){ return VendorDialog.getHostileVendorDialog(); } if(bane.timeSet && bane.capSet && bane.daySet){ vd.getOptions().clear(); return vd; } DateTime placement = bane.getPlacementDate(); vd.getOptions().clear(); switch(optionId){ default: if(!bane.daySet) { MenuOption option1 = new MenuOption(796, "Set Bane Day", 796); vd.getOptions().add(option1); } if(!bane.timeSet) { MenuOption option2 = new MenuOption(797, "Set Bane Time", 797); vd.getOptions().add(option2); } if(!bane.capSet) { MenuOption option3 = new MenuOption(797, "Set Bane Cap", 798); vd.getOptions().add(option3); } break; case 796: // set bane day DateTime dayOption1Date = placement.plusDays(3); MenuOption dayOption1 = new MenuOption(7961, dayOption1Date.toString("yyyy-MM-dd"), 7961); vd.getOptions().add(dayOption1); DateTime dayOption2Date = placement.plusDays(4); MenuOption dayOption2 = new MenuOption(7962, dayOption2Date.toString("yyyy-MM-dd"), 7962); vd.getOptions().add(dayOption2); DateTime dayOption3Date = placement.plusDays(5); MenuOption dayOption3 = new MenuOption(7963, dayOption3Date.toString("yyyy-MM-dd"), 7963); vd.getOptions().add(dayOption3); DateTime dayOption4Date = placement.plusDays(6); MenuOption dayOption4 = new MenuOption(7964, dayOption4Date.toString("yyyy-MM-dd"), 7964); vd.getOptions().add(dayOption4); DateTime dayOption5Date = placement.plusDays(7); MenuOption dayOption5 = new MenuOption(7965, dayOption5Date.toString("yyyy-MM-dd"), 7965); vd.getOptions().add(dayOption5); break; case 797: // set bane time MenuOption timeOption1 = new MenuOption(7971, "6:00 pm CST", 7971); vd.getOptions().add(timeOption1); MenuOption timeOption2 = new MenuOption(7972, "7:00 pm CST", 7972); vd.getOptions().add(timeOption2); MenuOption timeOption3 = new MenuOption(7973, "8:00 pm CST", 7973); vd.getOptions().add(timeOption3); MenuOption timeOption4 = new MenuOption(7974, "9:00 pm CST", 7974); vd.getOptions().add(timeOption4); MenuOption timeOption5 = new MenuOption(7975, "10:00 pm CST", 7975); vd.getOptions().add(timeOption5); break; case 798: // set bane cap if(treesInNation < 6) { MenuOption capOption1 = new MenuOption(7981, "10 Maximum Players", 7981); vd.getOptions().add(capOption1); } if(treesInNation < 11) { MenuOption capOption2 = new MenuOption(7982, "20 Maximum Players", 7982); vd.getOptions().add(capOption2); } MenuOption capOption3 = new MenuOption(7983, "30 Maximum Players", 7983); vd.getOptions().add(capOption3); MenuOption capOption4 = new MenuOption(7984, "40 Maximum Players", 7984); vd.getOptions().add(capOption4); MenuOption capOption5 = new MenuOption(7985, "Unlimited Players", 7985); vd.getOptions().add(capOption5); break; case 7961: //3 days after placement ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 3 Days From Placement Date"); updateBaneDay = 3; break; case 7962: //4 days after placement ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 4 Days From Placement Date"); updateBaneDay = 4; break; case 7963: //5 days after placement ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 5 Days From Placement Date"); updateBaneDay = 5; break; case 7964: //6 days after placement ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 6 Days From Placement Date"); updateBaneDay = 6; break; case 7965: //7 days after placement ErrorPopupMsg.sendErrorMsg(pc, "Bane Set 7 Days From Placement Date"); updateBaneDay = 7; break; case 7971: //6:00pm CST ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 6:00 pm CST"); updateBaneTime = 6; break; case 7972: //7:00pm CST ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 7:00 pm CST"); updateBaneTime = 7; break; case 7973: //8:00pm CST ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 8:00 pm CST"); updateBaneTime = 8; break; case 7974: //9:00pm CST ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 9:00 pm CST"); updateBaneTime = 9; break; case 7975: //10:00pm CST ErrorPopupMsg.sendErrorMsg(pc, "Bane Set For 10:00 pm CST"); updateBaneTime = 10; break; case 7981: //cap = 10 ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 10 Players On Each Side"); updateBaneCap = 10; break; case 7982: //cap = 20 ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 20 Players On Each Side"); updateBaneCap = 20; break; case 7983: //cap = 30 ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 30 Players On Each Side"); updateBaneCap = 30; break; case 7984: //cap = 40 ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To 40 Players On Each Side"); updateBaneCap = 40; break; case 7985: //cap = Unlimited ErrorPopupMsg.sendErrorMsg(pc, "Bane Cap Set To Unlimited Players On Each Side"); updateBaneCap = 9999; break; } if (updateBaneDay > 0) { if(DbManager.BaneQueries.SET_BANE_DAY_NEW(updateBaneDay,bane.getCityUUID())){ bane.daySet = true; if(bane.getLiveDate() == null) { bane.setLiveDate_NEW(bane.getPlacementDate().plusDays(updateBaneDay)); }else{ bane.setLiveDate_NEW(bane.getLiveDate().plusDays(updateBaneDay)); } } } if (updateBaneTime > 0) { if(DbManager.BaneQueries.SET_BANE_TIME_NEW(updateBaneTime,bane.getCityUUID())){ bane.timeSet = true; if(bane.getLiveDate() == null) { bane.setLiveDate_NEW(bane.getPlacementDate().withHourOfDay(12 + updateBaneTime)); }else{ bane.setLiveDate_NEW(bane.getLiveDate().withHourOfDay(12 + updateBaneTime)); } } bane.setLiveDate(DbManager.BaneQueries.getLiveDate(bane.getCityUUID())); } if (updateBaneCap > 0) { if(DbManager.BaneQueries.SET_BANE_CAP_NEW(updateBaneCap,bane.getCityUUID())){ bane.capSet = true; bane.capSize = updateBaneCap; } } if(updateBaneCap > 0 || updateBaneTime > 0 || updateBaneDay > 0) { bane.getSiegePhase(); for (PlayerCharacter playerCharacter : SessionManager.getAllActivePlayerCharacters()) { CityDataMsg cityDataMsg = new CityDataMsg(SessionManager.getSession(playerCharacter), false); cityDataMsg.updateMines(true); cityDataMsg.updateCities(true); Dispatch dispatch = Dispatch.borrow(playerCharacter, cityDataMsg); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } vd.getOptions().clear(); if(!bane.daySet) { MenuOption option1 = new MenuOption(796, "Set Bane Day", 796); vd.getOptions().add(option1); } if(!bane.timeSet) { MenuOption option2 = new MenuOption(797, "Set Bane Time", 797); vd.getOptions().add(option2); } if(!bane.capSet) { MenuOption option3 = new MenuOption(797, "Set Bane Cap", 798); vd.getOptions().add(option3); } } return vd; } public ArrayList getNPCMenuOptions() { return this.npcMenuOptions; } public ArrayList getNPCModTypeTable() { return this.npcModTypeTable; } public ArrayList getNpcModSuffixTable() { return npcModSuffixTable; } public ArrayList getItemModTable() { return itemModTable; } public ArrayList getSellInventory() { if(this.getObjectUUID() == 900){ //resource merchant for(MobEquipment me : this.sellInventory){ if(me.getItemBase().getType().equals(Enum.ItemType.RESOURCE)){ int amountResource = Warehouse.getSellStackSize(me.getItemBase().getUUID()); me.magicValue = amountResource * me.getItemBase().getBaseValue(); } else{ me.magicValue = 1000000; } } } if(this.getObjectUUID() == 1502050){ for(MobEquipment me : this.sellInventory){ me.magicValue = 1000000; } } if(this.getObjectUUID() == 1202){ //rune merchant for(MobEquipment me : this.sellInventory){ switch(me.getItemBase().getUUID()){ case 250001: //5 stats case 250010: case 250019: case 250028: case 250037: me.magicValue = 3000000; break; case 250002: //10 stats case 250011: case 250020: case 250029: case 250038: me.magicValue = 4000000; break; case 250003: //15 stats case 250012: case 250021: case 250030: case 250039: me.magicValue = 5000000; break; case 250004: //20 stats case 250013: case 250022: case 250031: case 250040: me.magicValue = 6000000; break; case 250005: //25 stats case 250014: case 250023: case 250032: case 250041: me.magicValue = 7000000; break; case 250006: //30 stats case 250015: case 250024: case 250033: case 250042: me.magicValue = 8000000; break; case 250007: //35 stats case 250016: case 250025: case 250034: case 250043: me.magicValue = 9000000; break; default: me.magicValue = 10000000; break; } } } if(this.getObjectUUID() == 1201){ //disc merchant for(MobEquipment me : this.sellInventory){ if(me.getItemBase().getName().equals("Prospector")){ me.magicValue = 500000; }else{ me.magicValue = 10000000; } } } if(this.getObjectUUID() == 1502041) {//noob helper{ for(MobEquipment me : this.sellInventory){ me.magicValue = 1; } } return this.sellInventory; } public int getPromotionClass() { if (this.classID < 2504 || this.classID > 2526) return 0; return this.classID; } public boolean isRuneMaster() { return (this.classID == 850); } public boolean isArtilleryCaptain() { return this.contractID == 839 || this.contractID == 842; } @Override public void updateDatabase() { DbManager.ContractQueries.updateDatabase(this); } public EnumBitSet getAllowedBuildings() { return allowedBuildings; } public ArrayList getBuyItemType() { return this.buyItemType; } public ArrayList getBuySkillToken() { return this.buySkillToken; } public ArrayList getBuyUnknownToken() { return this.buyUnknownToken; } public boolean canSlotinBuilding(Building building) { // Need a building to slot in a building! if (building == null) return false; // Can't slot in anything but a blueprinted building if (building.getBlueprintUUID() == 0) return false; // No buildings no slotting if (this.allowedBuildings.size() == 0) return false; // Binary match return (building.getBlueprint().getBuildingGroup().elementOf(this.allowedBuildings)); } public int getEquipmentSet() { return equipmentSet; } }