/* OrpheusMS: MapleStory Private Server based on OdinMS Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net> Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package scripting.npc; import client.Equip; import client.IItem; import client.ISkill; import client.ItemFactory; import java.sql.PreparedStatement; import java.sql.ResultSet; import constants.ExpTable; import constants.ServerConstants; import client.MapleCharacter; import client.MapleClient; import client.MapleInventory; import client.MapleInventoryType; import client.MapleJob; import client.MaplePet; import client.MapleSkinColor; import client.MapleStat; import client.SkillFactory; import tools.Randomizer; import java.io.File; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; import net.server.Channel; import tools.DatabaseConnection; import net.server.MapleParty; import net.server.MaplePartyCharacter; import net.server.Server; import net.server.guild.MapleAlliance; import net.server.guild.MapleGuild; import provider.MapleData; import provider.MapleDataProviderFactory; import scripting.AbstractPlayerInteraction; import server.MapleInventoryManipulator; import server.MapleItemInformationProvider; import server.MapleShopFactory; import server.MapleStatEffect; import server.events.gm.MapleEvent; import server.expeditions.MapleExpedition; import server.maps.MapleMap; import server.maps.MapleMapFactory; import server.partyquest.Pyramid; import server.partyquest.Pyramid.PyramidMode; import server.quest.MapleQuest; import tools.MaplePacketCreator; /** * * @author Matze */ public class NPCConversationManager extends AbstractPlayerInteraction { private int npc; private String getText; public NPCConversationManager(MapleClient c, int npc) { super(c); this.npc = npc; } public int getNpc() { return npc; } public void dispose() { NPCScriptManager.getInstance().dispose(this); } public void sendNext(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", (byte) 0)); } public void sendPrev(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", (byte) 0)); } public void sendNextPrev(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", (byte) 0)); } public void sendOk(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", (byte) 0)); } public void sendYesNo(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 1, text, "", (byte) 0)); } public void sendAcceptDecline(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", (byte) 0)); } public void sendSimple(String text) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 4, text, "", (byte) 0)); } public void sendNext(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", speaker)); } public void sendPrev(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", speaker)); } public void sendNextPrev(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", speaker)); } public void sendOk(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", speaker)); } public void sendYesNo(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 1, text, "", speaker)); } public void sendAcceptDecline(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", speaker)); } public void sendSimple(String text, byte speaker) { getClient().announce(MaplePacketCreator.getNPCTalk(npc, (byte) 4, text, "", speaker)); } public void sendStyle(String text, int styles[]) { getClient().announce(MaplePacketCreator.getNPCTalkStyle(npc, text, styles)); } public void sendGetNumber(String text, int def, int min, int max) { getClient().announce(MaplePacketCreator.getNPCTalkNum(npc, text, def, min, max)); } public void sendGetText(String text) { getClient().announce(MaplePacketCreator.getNPCTalkText(npc, text, "")); } /* * 0 = ariant colliseum 1 = Dojo 2 = Carnival 1 3 = Carnival 2 4 = Ghost * Ship PQ? 5 = Pyramid PQ 6 = Kerning Subway */ public void sendDimensionalMirror(String text) { getClient().announce(MaplePacketCreator.getDimensionalMirror(text)); } public void setGetText(String text) { this.getText = text; } public String getText() { return this.getText; } public int getJobId() { return getPlayer().getJob().getId(); } public void startQuest(short id) { try { MapleQuest.getInstance(id).forceStart(getPlayer(), npc); } catch (NullPointerException ex) { } } public void completeQuest(short id) { try { MapleQuest.getInstance(id).forceComplete(getPlayer(), npc); } catch (NullPointerException ex) { } } public int getMeso() { return getPlayer().getMeso(); } public void gainMeso(int gain) { getPlayer().gainMeso(gain, true, false, true); } public void gainExp(int gain) { getPlayer().gainExp(gain, true, true); } public int getLevel() { return getPlayer().getLevel(); } public void showEffect(String effect) { getPlayer().getMap().broadcastMessage(MaplePacketCreator.environmentChange(effect, 3)); } public void playSound(String sound) { getPlayer().getMap().broadcastMessage(MaplePacketCreator.environmentChange(sound, 4)); } public void setHair(int hair) { getPlayer().setHair(hair); getPlayer().updateSingleStat(MapleStat.HAIR, hair); getPlayer().equipChanged(); } public void setFace(int face) { getPlayer().setFace(face); getPlayer().updateSingleStat(MapleStat.FACE, face); getPlayer().equipChanged(); } public void setSkin(int color) { getPlayer().setSkinColor(MapleSkinColor.getById(color)); getPlayer().updateSingleStat(MapleStat.SKIN, color); getPlayer().equipChanged(); } public int itemQuantity(int itemid) { return getPlayer().getInventory(MapleItemInformationProvider.getInstance().getInventoryType(itemid)).countById(itemid); } public void displayGuildRanks() { MapleGuild.displayGuildRanks(getClient(), npc); } @Override public MapleParty getParty() { return getPlayer().getParty(); } @Override public void resetMap(int mapid) { getClient().getChannelServer().getMapFactory().getMap(mapid).resetReactors(); } public void gainCloseness(int closeness) { for (MaplePet pet : getPlayer().getPets()) { if (pet.getCloseness() > 30000) { pet.setCloseness(30000); return; } pet.gainCloseness(closeness); while (pet.getCloseness() > ExpTable.getClosenessNeededForLevel(pet.getLevel())) { pet.setLevel((byte) (pet.getLevel() + 1)); byte index = getPlayer().getPetIndex(pet); getClient().announce(MaplePacketCreator.showOwnPetLevelUp(index)); getPlayer().getMap().broadcastMessage(getPlayer(), MaplePacketCreator.showPetLevelUp(getPlayer(), index)); } IItem petz = getPlayer().getInventory(MapleInventoryType.CASH).getItem(pet.getPosition()); getPlayer().getClient().announce(MaplePacketCreator.updateSlot(petz)); } } public String getName() { return getPlayer().getName(); } public int getGender() { return getPlayer().getGender(); } public void changeJobById(int a) { getPlayer().changeJob(MapleJob.getById(a)); } public void addRandomItem(int id) { MapleItemInformationProvider i = MapleItemInformationProvider.getInstance(); MapleInventoryManipulator.addFromDrop(getClient(), i.randomizeStats((Equip) i.getEquipById(id)), true); } public MapleJob getJobName(int id) { return MapleJob.getById(id); } public MapleStatEffect getItemEffect(int itemId) { return MapleItemInformationProvider.getInstance().getItemEffect(itemId); } public void resetStats() { getPlayer().resetStats(); } public void maxMastery() { for (MapleData skill_ : MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz")).getData("Skill.img").getChildren()) { try { ISkill skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName())); getPlayer().changeSkillLevel(skill, (byte) skill.getMaxLevel(), skill.getMaxLevel(), -1); } catch (NumberFormatException nfe) { break; } catch (NullPointerException npe) { continue; } } } public void processGachapon(int[] id, boolean remote) { int[] gacMap = {100000000, 101000000, 102000000, 103000000, 105040300, 800000000, 809000101, 809000201, 600000000, 120000000}; int itemid = id[Randomizer.nextInt(id.length)]; addRandomItem(itemid); if (!remote) { gainItem(5220000, (short) -1); } sendNext("You have obtained a #b#t" + itemid + "##k."); if (ServerConstants.BROADCAST_GACHAPON_ITEMS) { getClient().getChannelServer().broadcastPacket(MaplePacketCreator.gachaponMessage(getPlayer().getInventory(MapleInventoryType.getByType((byte) (itemid / 1000000))).findById(itemid), c.getChannelServer().getMapFactory().getMap(gacMap[(getNpc() != 9100117 && getNpc() != 9100109) ? (getNpc() - 9100100) : getNpc() == 9100109 ? 8 : 9]).getMapName(), getPlayer())); } } public void disbandAlliance(MapleClient c, int allianceId) { PreparedStatement ps = null; try { ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM `alliance` WHERE id = ?"); ps.setInt(1, allianceId); ps.executeUpdate(); ps.close(); Server.getInstance().allianceMessage(c.getPlayer().getGuild().getAllianceId(), MaplePacketCreator.disbandAlliance(allianceId), -1, -1); Server.getInstance().disbandAlliance(allianceId); } catch (SQLException sqle) { sqle.printStackTrace(); } finally { try { if (ps != null && !ps.isClosed()) { ps.close(); } } catch (SQLException ex) { } } } public boolean canBeUsedAllianceName(String name) { if (name.contains(" ") || name.length() > 12) { return false; } try { PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT name FROM alliance WHERE name = ?"); ps.setString(1, name); ResultSet rs = ps.executeQuery(); if (rs.next()) { ps.close(); rs.close(); return false; } ps.close(); rs.close(); return true; } catch (SQLException e) { e.printStackTrace(); return false; } } public static MapleAlliance createAlliance(MapleCharacter chr1, MapleCharacter chr2, String name) { int id = 0; int guild1 = chr1.getGuildId(); int guild2 = chr2.getGuildId(); try { PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO `alliance` (`name`, `guild1`, `guild2`) VALUES (?, ?, ?)", PreparedStatement.RETURN_GENERATED_KEYS); ps.setString(1, name); ps.setInt(2, guild1); ps.setInt(3, guild2); ps.executeUpdate(); ResultSet rs = ps.getGeneratedKeys(); rs.next(); id = rs.getInt(1); rs.close(); ps.close(); } catch (SQLException e) { e.printStackTrace(); return null; } MapleAlliance alliance = new MapleAlliance(name, id, guild1, guild2); try { Server.getInstance().setGuildAllianceId(guild1, id); Server.getInstance().setGuildAllianceId(guild2, id); chr1.setAllianceRank(1); chr1.saveGuildStatus(); chr2.setAllianceRank(2); chr2.saveGuildStatus(); Server.getInstance().addAlliance(id, alliance); Server.getInstance().allianceMessage(id, MaplePacketCreator.makeNewAlliance(alliance, chr1.getClient()), -1, -1); } catch (Exception e) { return null; } return alliance; } public List<MapleCharacter> getPartyMembers() { if (getPlayer().getParty() == null) { return null; } List<MapleCharacter> chars = new LinkedList<MapleCharacter>(); for (Channel channel : Server.getInstance().getChannelsFromWorld(getPlayer().getWorld())) { for (MapleCharacter chr : channel.getPartyMembers(getPlayer().getParty())) { if (chr != null) { chars.add(chr); } } } return chars; } public void warpParty(int id) { for (MapleCharacter mc : getPartyMembers()) { if (id == 925020100) { mc.setDojoParty(true); } mc.changeMap(getWarpMap(id)); } } public boolean hasMerchant() { return getPlayer().hasMerchant(); } public boolean hasMerchantItems() { try { if (!ItemFactory.MERCHANT.loadItems(getPlayer().getId(), false).isEmpty()) { return true; } } catch (SQLException e) { return false; } if (getPlayer().getMerchantMeso() == 0) { return false; } else { return true; } } public void showFredrick() { c.announce(MaplePacketCreator.getFredrick(getPlayer())); } public int partyMembersInMap() { int inMap = 0; for (MapleCharacter char2 : getPlayer().getMap().getCharacters()) { if (char2.getParty() == getPlayer().getParty()) { inMap++; } } return inMap; } public MapleEvent getEvent() { return c.getChannelServer().getEvent(); } public void divideTeams() { if (getEvent() != null) { getPlayer().setTeam(getEvent().getLimit() % 2); // muhaha :D } } public MapleExpedition createExpedition(String type, byte min) { MapleParty party = getPlayer().getParty(); if (party == null || party.getMembers().size() < min) return null; return new MapleExpedition(getPlayer()); } public boolean createPyramid(String mode, boolean party) {// lol PyramidMode mod = PyramidMode.valueOf(mode); MapleParty partyz = getPlayer().getParty(); MapleMapFactory mf = c.getChannelServer().getMapFactory(); MapleMap map = null; int mapid = 926010100; if (party) { mapid += 10000; } mapid += (mod.getMode() * 1000); for (byte b = 0; b < 5; b++) {// They cannot warp to the next map before // the timer ends (: map = mf.getMap(mapid + b); if (map.getCharacters().size() > 0) { map = null; continue; } else { break; } } if (map == null) { return false; } if (!party) { partyz = new MapleParty(-1, new MaplePartyCharacter(getPlayer())); } Pyramid py = new Pyramid(partyz, mod, map.getId()); getPlayer().setPartyQuest(py); py.warp(mapid); dispose(); return true; } public void openShop(int id) { dispose(); MapleShopFactory.getInstance().getShop(id).sendShop(c); } public void warp(int id) { dispose(); getPlayer().changeMap(id); } public void warp(int id, int portal) { dispose(); getPlayer().changeMap(id, portal); } public String getServerName() { return ServerConstants.SERVER_NAME; } public int getWorld() { return getPlayer().getWorld(); } public String listEquips() { StringBuilder sb = new StringBuilder(); MapleInventory mi = getPlayer().getInventory(MapleInventoryType.EQUIP); for (IItem i : mi.list()) { sb.append("#L" + i.getPosition() + "##v" + i.getItemId() + "##l"); } return sb.toString(); } public boolean hasItem(int itemid) { return getPlayer().haveItem(itemid); } public boolean hasItem(int itemid, int quantity) { return (getPlayer().getItemQuantity(itemid, false) > quantity); } public int getItemId(byte slot) { return getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(slot).getItemId(); } public void setItemOwner(byte slot) { MapleInventory equip = getPlayer().getInventory(MapleInventoryType.EQUIP); Equip eu = (Equip) equip.getItem(slot); eu.setOwner(getName()); } public void makeItemEpic(byte slot) { MapleInventory equip = getPlayer().getInventory(MapleInventoryType.EQUIP); Equip eu = (Equip) equip.getItem(slot); eu.setStr(Short.MAX_VALUE); eu.setDex(Short.MAX_VALUE); eu.setInt(Short.MAX_VALUE); eu.setLuk(Short.MAX_VALUE); eu.setAcc(Short.MAX_VALUE); eu.setAvoid(Short.MAX_VALUE); eu.setWatk(Short.MAX_VALUE); eu.setWdef(Short.MAX_VALUE); eu.setMatk(Short.MAX_VALUE); eu.setMdef(Short.MAX_VALUE); eu.setHp(Short.MAX_VALUE); eu.setMp(Short.MAX_VALUE); eu.setJump(Short.MAX_VALUE); eu.setSpeed(Short.MAX_VALUE); eu.setOwner(getName()); getPlayer().equipChanged(); } public void modifyItem(byte slot, String stat, short value) { MapleInventory equip = getPlayer().getInventory(MapleInventoryType.EQUIP); Equip eu = (Equip) equip.getItem(slot); if (stat.equalsIgnoreCase("str") || stat.equalsIgnoreCase("strength")) { eu.setStr(value); } else if (stat.equalsIgnoreCase("dex") || stat.equalsIgnoreCase("dexterity")) { eu.setDex(value); } else if (stat.equalsIgnoreCase("int") || stat.equalsIgnoreCase("intellect")) { eu.setInt(value); } else if (stat.equalsIgnoreCase("luk") || stat.equalsIgnoreCase("luck")) { eu.setLuk(value); } else if (stat.equalsIgnoreCase("hp") || stat.equalsIgnoreCase("maxhp")) { eu.setHp(value); } else if (stat.equalsIgnoreCase("mp") || stat.equalsIgnoreCase("maxmp")) { eu.setMp(value); } else if (stat.equalsIgnoreCase("acc") || stat.equalsIgnoreCase("accuracy")) { eu.setAcc(value); } else if (stat.equalsIgnoreCase("avoid") || stat.equalsIgnoreCase("avoidability")) { eu.setAvoid(value); } else if (stat.equalsIgnoreCase("watk") || stat.equalsIgnoreCase("wattack")) { eu.setWatk(value); } else if (stat.equalsIgnoreCase("matk") || stat.equalsIgnoreCase("mattack")) { eu.setMatk(value); } else if (stat.equalsIgnoreCase("wdef") || stat.equalsIgnoreCase("wdefense")) { eu.setWdef(value); } else if (stat.equalsIgnoreCase("mdef") || stat.equalsIgnoreCase("mdefense")) { eu.setMdef(value); } else if (stat.equalsIgnoreCase("jump")) { eu.setJump(value); } else if (stat.equalsIgnoreCase("speed")) { eu.setSpeed(value); } else if (stat.equalsIgnoreCase("upgrades")) { eu.setUpgradeSlots(value); } getPlayer().equipChanged(); } }