source
Source for my MapleSolaxiaV2 (v83 MapleStory).
This commit is contained in:
465
src/server/CashShop.java
Normal file
465
src/server/CashShop.java
Normal file
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import constants.ItemConstants;
|
||||
|
||||
/*
|
||||
* @author Flav
|
||||
*/
|
||||
public class CashShop {
|
||||
public static class CashItem {
|
||||
|
||||
private int sn, itemId, price;
|
||||
private long period;
|
||||
private short count;
|
||||
private boolean onSale;
|
||||
|
||||
private CashItem(int sn, int itemId, int price, long period, short count, boolean onSale) {
|
||||
this.sn = sn;
|
||||
this.itemId = itemId;
|
||||
this.price = price;
|
||||
this.period = (period == 0 ? 90 : period);
|
||||
this.count = count;
|
||||
this.onSale = onSale;
|
||||
}
|
||||
|
||||
public int getSN() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public int getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public short getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public boolean isOnSale() {
|
||||
return onSale;
|
||||
}
|
||||
|
||||
public Item toItem() {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Item item;
|
||||
|
||||
int petid = -1;
|
||||
|
||||
if (ItemConstants.isPet(itemId))
|
||||
petid = MaplePet.createPet(itemId);
|
||||
|
||||
if (ii.getInventoryType(itemId).equals(MapleInventoryType.EQUIP)) {
|
||||
item = ii.getEquipById(itemId);
|
||||
} else {
|
||||
item = new Item(itemId, (byte) 0, count, petid);
|
||||
}
|
||||
|
||||
if (ItemConstants.EXPIRING_ITEMS)
|
||||
if(itemId == 5211048 || itemId == 5360042) { // 4 Hour 2X coupons, the period is 1, but we don't want them to last a day.
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 4));
|
||||
} else {
|
||||
item.setExpiration(System.currentTimeMillis() + (1000 * 60 * 60 * 24 * period));
|
||||
}
|
||||
item.setSN(sn);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
public static class SpecialCashItem {
|
||||
private int sn, modifier;
|
||||
private byte info; //?
|
||||
|
||||
public SpecialCashItem(int sn, int modifier, byte info) {
|
||||
this.sn = sn;
|
||||
this.modifier = modifier;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public int getSN() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public int getModifier() {
|
||||
return modifier;
|
||||
}
|
||||
|
||||
public byte getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CashItemFactory {
|
||||
|
||||
private static final Map<Integer, CashItem> items = new HashMap<>();
|
||||
private static final Map<Integer, List<Integer>> packages = new HashMap<>();
|
||||
private static final List<SpecialCashItem> specialcashitems = new ArrayList<>();
|
||||
|
||||
static {
|
||||
MapleDataProvider etc = MapleDataProviderFactory.getDataProvider(new File("wz/Etc.wz"));
|
||||
|
||||
for (MapleData item : etc.getData("Commodity.img").getChildren()) {
|
||||
int sn = MapleDataTool.getIntConvert("SN", item);
|
||||
int itemId = MapleDataTool.getIntConvert("ItemId", item);
|
||||
int price = MapleDataTool.getIntConvert("Price", item, 0);
|
||||
long period = MapleDataTool.getIntConvert("Period", item, 1);
|
||||
short count = (short) MapleDataTool.getIntConvert("Count", item, 1);
|
||||
boolean onSale = MapleDataTool.getIntConvert("OnSale", item, 0) == 1;
|
||||
items.put(sn, new CashItem(sn, itemId, price, period, count, onSale));
|
||||
}
|
||||
|
||||
for (MapleData cashPackage : etc.getData("CashPackage.img").getChildren()) {
|
||||
List<Integer> cPackage = new ArrayList<>();
|
||||
|
||||
for (MapleData item : cashPackage.getChildByPath("SN").getChildren()) {
|
||||
cPackage.add(Integer.parseInt(item.getData().toString()));
|
||||
}
|
||||
|
||||
packages.put(Integer.parseInt(cashPackage.getName()), cPackage);
|
||||
}
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM specialcashitems");
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
specialcashitems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info")));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) rs.close();
|
||||
if (ps != null) ps.close();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CashItem getItem(int sn) {
|
||||
return items.get(sn);
|
||||
}
|
||||
|
||||
public static List<Item> getPackage(int itemId) {
|
||||
List<Item> cashPackage = new ArrayList<>();
|
||||
|
||||
for (int sn : packages.get(itemId)) {
|
||||
cashPackage.add(getItem(sn).toItem());
|
||||
}
|
||||
|
||||
return cashPackage;
|
||||
}
|
||||
|
||||
public static boolean isPackage(int itemId) {
|
||||
return packages.containsKey(itemId);
|
||||
}
|
||||
|
||||
public static List<SpecialCashItem> getSpecialCashItems() {
|
||||
return specialcashitems;
|
||||
}
|
||||
|
||||
public static void reloadSpecialCashItems() {//Yay?
|
||||
specialcashitems.clear();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM specialcashitems");
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
specialcashitems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info")));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) rs.close();
|
||||
if (ps != null) ps.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private int accountId, characterId, nxCredit, maplePoint, nxPrepaid;
|
||||
private boolean opened;
|
||||
private ItemFactory factory;
|
||||
private List<Item> inventory = new ArrayList<>();
|
||||
private List<Integer> wishList = new ArrayList<>();
|
||||
private int notes = 0;
|
||||
|
||||
public CashShop(int accountId, int characterId, int jobType) throws SQLException {
|
||||
this.accountId = accountId;
|
||||
this.characterId = characterId;
|
||||
|
||||
if (jobType == 0) {
|
||||
factory = ItemFactory.CASH_EXPLORER;
|
||||
} else if (jobType == 1) {
|
||||
factory = ItemFactory.CASH_CYGNUS;
|
||||
} else if (jobType == 2) {
|
||||
factory = ItemFactory.CASH_ARAN;
|
||||
}
|
||||
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = con.prepareStatement("SELECT `nxCredit`, `maplePoint`, `nxPrepaid` FROM `accounts` WHERE `id` = ?");
|
||||
ps.setInt(1, accountId);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
if (rs.next()) {
|
||||
this.nxCredit = rs.getInt("nxCredit");
|
||||
this.maplePoint = rs.getInt("maplePoint");
|
||||
this.nxPrepaid = rs.getInt("nxPrepaid");
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
|
||||
for (Pair<Item, MapleInventoryType> item : factory.loadItems(accountId, false)) {
|
||||
inventory.add(item.getLeft());
|
||||
}
|
||||
|
||||
ps = con.prepareStatement("SELECT `sn` FROM `wishlists` WHERE `charid` = ?");
|
||||
ps.setInt(1, characterId);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
wishList.add(rs.getInt("sn"));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
} finally {
|
||||
if (ps != null) ps.close();
|
||||
if (rs != null) rs.close();
|
||||
}
|
||||
}
|
||||
|
||||
public int getCash(int type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return nxCredit;
|
||||
case 2:
|
||||
return maplePoint;
|
||||
case 4:
|
||||
return nxPrepaid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void gainCash(int type, int cash) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
nxCredit += cash;
|
||||
break;
|
||||
case 2:
|
||||
maplePoint += cash;
|
||||
break;
|
||||
case 4:
|
||||
nxPrepaid += cash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
public void open(boolean b) {
|
||||
opened = b;
|
||||
}
|
||||
|
||||
public List<Item> getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public Item findByCashId(int cashId) {
|
||||
boolean isRing = false;
|
||||
Equip equip = null;
|
||||
for (Item item : inventory) {
|
||||
if (item.getType() == 1) {
|
||||
equip = (Equip) item;
|
||||
isRing = equip.getRingId() > -1;
|
||||
}
|
||||
if ((item.getPetId() > -1 ? item.getPetId() : isRing ? equip.getRingId() : item.getCashId()) == cashId) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addToInventory(Item item) {
|
||||
inventory.add(item);
|
||||
}
|
||||
|
||||
public void removeFromInventory(Item item) {
|
||||
inventory.remove(item);
|
||||
}
|
||||
|
||||
public List<Integer> getWishList() {
|
||||
return wishList;
|
||||
}
|
||||
|
||||
public void clearWishList() {
|
||||
wishList.clear();
|
||||
}
|
||||
|
||||
public void addToWishList(int sn) {
|
||||
wishList.add(sn);
|
||||
}
|
||||
|
||||
public void gift(int recipient, String from, String message, int sn) {
|
||||
gift(recipient, from, message, sn, -1);
|
||||
}
|
||||
|
||||
public void gift(int recipient, String from, String message, int sn, int ringid) {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO `gifts` VALUES (DEFAULT, ?, ?, ?, ?, ?)");
|
||||
ps.setInt(1, recipient);
|
||||
ps.setString(2, from);
|
||||
ps.setString(3, message);
|
||||
ps.setInt(4, sn);
|
||||
ps.setInt(5, ringid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null) ps.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<Pair<Item, String>> loadGifts() {
|
||||
List<Pair<Item, String>> gifts = new ArrayList<>();
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
|
||||
try {
|
||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM `gifts` WHERE `to` = ?");
|
||||
ps.setInt(1, characterId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
notes++;
|
||||
CashItem cItem = CashItemFactory.getItem(rs.getInt("sn"));
|
||||
Item item = cItem.toItem();
|
||||
Equip equip = null;
|
||||
item.setGiftFrom(rs.getString("from"));
|
||||
if (item.getType() == MapleInventoryType.EQUIP.getType()) {
|
||||
equip = (Equip) item;
|
||||
equip.setRingId(rs.getInt("ringid"));
|
||||
gifts.add(new Pair<Item, String>(equip, rs.getString("message")));
|
||||
} else
|
||||
gifts.add(new Pair<>(item, rs.getString("message")));
|
||||
|
||||
if (CashItemFactory.isPackage(cItem.getItemId())) { //Packages never contains a ring
|
||||
for (Item packageItem : CashItemFactory.getPackage(cItem.getItemId())) {
|
||||
packageItem.setGiftFrom(rs.getString("from"));
|
||||
addToInventory(packageItem);
|
||||
}
|
||||
} else {
|
||||
addToInventory(equip == null ? item : equip);
|
||||
}
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
ps = con.prepareStatement("DELETE FROM `gifts` WHERE `to` = ?");
|
||||
ps.setInt(1, characterId);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
|
||||
return gifts;
|
||||
}
|
||||
|
||||
public int getAvailableNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void decreaseNotes() {
|
||||
notes--;
|
||||
}
|
||||
|
||||
public void save(Connection con) throws SQLException {
|
||||
PreparedStatement ps = con.prepareStatement("UPDATE `accounts` SET `nxCredit` = ?, `maplePoint` = ?, `nxPrepaid` = ? WHERE `id` = ?");
|
||||
ps.setInt(1, nxCredit);
|
||||
ps.setInt(2, maplePoint);
|
||||
ps.setInt(3, nxPrepaid);
|
||||
ps.setInt(4, accountId);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
List<Pair<Item, MapleInventoryType>> itemsWithType = new ArrayList<>();
|
||||
|
||||
for (Item item : inventory) {
|
||||
itemsWithType.add(new Pair<>(item, MapleItemInformationProvider.getInstance().getInventoryType(item.getItemId())));
|
||||
}
|
||||
|
||||
factory.saveItems(itemsWithType, accountId, con);
|
||||
ps = con.prepareStatement("DELETE FROM `wishlists` WHERE `charid` = ?");
|
||||
ps.setInt(1, characterId);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
ps = con.prepareStatement("INSERT INTO `wishlists` VALUES (DEFAULT, ?, ?)");
|
||||
ps.setInt(1, characterId);
|
||||
|
||||
for (int sn : wishList) {
|
||||
ps.setInt(2, sn);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
80
src/server/DueyPackages.java
Normal file
80
src/server/DueyPackages.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.inventory.Item;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class DueyPackages {
|
||||
private String sender = null;
|
||||
private Item item = null;
|
||||
private int mesos = 0;
|
||||
private int day;
|
||||
private int month;
|
||||
private int year;
|
||||
private int packageId = 0;
|
||||
|
||||
public DueyPackages(int pId, Item item) {
|
||||
this.item = item;
|
||||
packageId = pId;
|
||||
}
|
||||
|
||||
public DueyPackages(int pId) { // Meso only package.
|
||||
this.packageId = pId;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(String name) {
|
||||
sender = name;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public int getMesos() {
|
||||
return mesos;
|
||||
}
|
||||
|
||||
public void setMesos(int set) {
|
||||
mesos = set;
|
||||
}
|
||||
|
||||
public int getPackageId() {
|
||||
return packageId;
|
||||
}
|
||||
|
||||
public long sentTimeInMilliseconds() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(year, month, day);
|
||||
return cal.getTimeInMillis();
|
||||
}
|
||||
|
||||
public void setSentTime(String sentTime) {
|
||||
day = Integer.parseInt(sentTime.substring(0, 2));
|
||||
month = Integer.parseInt(sentTime.substring(3, 5));
|
||||
year = Integer.parseInt(sentTime.substring(6, 10));
|
||||
}
|
||||
}
|
||||
73
src/server/MTSItemInfo.java
Normal file
73
src/server/MTSItemInfo.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.inventory.Item;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Traitor
|
||||
*/
|
||||
public class MTSItemInfo {
|
||||
private int price;
|
||||
private Item item;
|
||||
private String seller;
|
||||
private int id;
|
||||
private int year, month, day = 1;
|
||||
|
||||
public MTSItemInfo(Item item, int price, int id, int cid, String seller, String date) {
|
||||
this.item = item;
|
||||
this.price = price;
|
||||
this.seller = seller;
|
||||
this.id = id;
|
||||
this.year = Integer.parseInt(date.substring(0, 4));
|
||||
this.month = Integer.parseInt(date.substring(5, 7));
|
||||
this.day = Integer.parseInt(date.substring(8, 10));
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public int getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public int getTaxes() {
|
||||
return 100 + price / 10;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getEndingDate() {
|
||||
Calendar now = Calendar.getInstance();
|
||||
now.set(year, month - 1, day);
|
||||
return now.getTimeInMillis();
|
||||
}
|
||||
|
||||
public String getSeller() {
|
||||
return seller;
|
||||
}
|
||||
}
|
||||
116
src/server/MakerItemFactory.java
Normal file
116
src/server/MakerItemFactory.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jay Estrella
|
||||
*/
|
||||
public class MakerItemFactory {
|
||||
private static Map<Integer, MakerItemCreateEntry> createCache = new HashMap<Integer, MakerItemCreateEntry>();
|
||||
|
||||
public static MakerItemCreateEntry getItemCreateEntry(int toCreate) {
|
||||
if (createCache.get(toCreate) != null) {
|
||||
return createCache.get(toCreate);
|
||||
} else {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT req_level, req_maker_level, req_meso, quantity FROM makercreatedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
int reqLevel = 0;
|
||||
int reqMakerLevel = 0;
|
||||
int cost = 0;
|
||||
int toGive = 0;
|
||||
if (rs.next()) {
|
||||
reqLevel = rs.getInt("req_level");
|
||||
reqMakerLevel = rs.getInt("req_maker_level");
|
||||
cost = rs.getInt("req_meso");
|
||||
toGive = rs.getInt("quantity");
|
||||
}
|
||||
ps.close();
|
||||
rs.close();
|
||||
MakerItemCreateEntry ret = new MakerItemCreateEntry(cost, reqLevel, reqMakerLevel, toGive);
|
||||
ps = con.prepareStatement("SELECT req_item, count FROM makerrecipedata WHERE itemid = ?");
|
||||
ps.setInt(1, toCreate);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
ret.addReqItem(rs.getInt("req_item"), rs.getInt("count"));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
createCache.put(toCreate, ret);
|
||||
} catch (SQLException sqle) {
|
||||
}
|
||||
}
|
||||
return createCache.get(toCreate);
|
||||
}
|
||||
|
||||
public static class MakerItemCreateEntry {
|
||||
private int reqLevel, reqMakerLevel;
|
||||
private int cost;
|
||||
private List<Pair<Integer, Integer>> reqItems = new ArrayList<Pair<Integer, Integer>>(); // itemId / amount
|
||||
private int toGive;
|
||||
|
||||
private MakerItemCreateEntry(int cost, int reqLevel, int reqMakerLevel, int toGive) {
|
||||
this.cost = cost;
|
||||
this.reqLevel = reqLevel;
|
||||
this.reqMakerLevel = reqMakerLevel;
|
||||
this.toGive = toGive;
|
||||
}
|
||||
|
||||
public int getRewardAmount() {
|
||||
return toGive;
|
||||
}
|
||||
|
||||
public List<Pair<Integer, Integer>> getReqItems() {
|
||||
return reqItems;
|
||||
}
|
||||
|
||||
public int getReqLevel() {
|
||||
return reqLevel;
|
||||
}
|
||||
|
||||
public int getReqSkillLevel() {
|
||||
return reqMakerLevel;
|
||||
}
|
||||
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
protected void addReqItem(int itemId, int amount) {
|
||||
reqItems.add(new Pair<Integer, Integer>(itemId, amount));
|
||||
}
|
||||
}
|
||||
}
|
||||
535
src/server/MapleInventoryManipulator.java
Normal file
535
src/server/MapleInventoryManipulator.java
Normal file
@@ -0,0 +1,535 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.ModifyInventory;
|
||||
import constants.ItemConstants;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleInventoryManipulator {
|
||||
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity) {
|
||||
return addById(c, itemId, quantity, null, -1, -1);
|
||||
}
|
||||
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity, long expiration) {
|
||||
return addById(c, itemId, quantity, null, -1, (byte) 0, expiration);
|
||||
}
|
||||
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, int petid) {
|
||||
return addById(c, itemId, quantity, owner, petid, -1);
|
||||
}
|
||||
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, int petid, long expiration) {
|
||||
return addById(c, itemId, quantity, owner, petid, (byte) 0, expiration);
|
||||
}
|
||||
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, int petid, byte flag, long expiration) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ii.getInventoryType(itemId);
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, itemId);
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(itemId);
|
||||
if (!ItemConstants.isRechargable(itemId)) {
|
||||
if (existing.size() > 0) { // first update all existing slots to slotMax
|
||||
Iterator<Item> i = existing.iterator();
|
||||
while (quantity > 0) {
|
||||
if (i.hasNext()) {
|
||||
Item eItem = (Item) i.next();
|
||||
short oldQ = eItem.getQuantity();
|
||||
if (oldQ < slotMax && (eItem.getOwner().equals(owner) || owner == null)) {
|
||||
short newQ = (short) Math.min(oldQ + quantity, slotMax);
|
||||
quantity -= (newQ - oldQ);
|
||||
eItem.setQuantity(newQ);
|
||||
eItem.setExpiration(expiration);
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, eItem))));
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (quantity > 0 || ItemConstants.isRechargable(itemId)) {
|
||||
short newQ = (short) Math.min(quantity, slotMax);
|
||||
if (newQ != 0) {
|
||||
quantity -= newQ;
|
||||
Item nItem = new Item(itemId, (short) 0, newQ, petid);
|
||||
nItem.setFlag(flag);
|
||||
nItem.setExpiration(expiration);
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
if (owner != null) {
|
||||
nItem.setOwner(owner);
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if ((ItemConstants.isRechargable(itemId)) && quantity == 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Item nItem = new Item(itemId, (short) 0, quantity, petid);
|
||||
nItem.setFlag(flag);
|
||||
nItem.setExpiration(expiration);
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
Item nEquip = ii.getEquipById(itemId);
|
||||
nEquip.setFlag(flag);
|
||||
nEquip.setExpiration(expiration);
|
||||
if (owner != null) {
|
||||
nEquip.setOwner(owner);
|
||||
}
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nEquip);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nEquip))));
|
||||
} else {
|
||||
throw new RuntimeException("Trying to create equip with non-one quantity");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean addFromDrop(MapleClient c, Item item, boolean show) {
|
||||
return addFromDrop(c, item, show, -1);
|
||||
}
|
||||
|
||||
public static boolean addFromDrop(MapleClient c, Item item, boolean show, int petId) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ii.getInventoryType(item.getItemId());
|
||||
if (ii.isPickupRestricted(item.getItemId()) && c.getPlayer().getItemQuantity(item.getItemId(), true) > 0) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.showItemUnavailable());
|
||||
return false;
|
||||
}
|
||||
short quantity = item.getQuantity();
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(item.getItemId());
|
||||
if (!ItemConstants.isRechargable(item.getItemId())) {
|
||||
if (existing.size() > 0) { // first update all existing slots to slotMax
|
||||
Iterator<Item> i = existing.iterator();
|
||||
while (quantity > 0) {
|
||||
if (i.hasNext()) {
|
||||
Item eItem = (Item) i.next();
|
||||
short oldQ = eItem.getQuantity();
|
||||
if (oldQ < slotMax && item.getOwner().equals(eItem.getOwner())) {
|
||||
short newQ = (short) Math.min(oldQ + quantity, slotMax);
|
||||
quantity -= (newQ - oldQ);
|
||||
eItem.setQuantity(newQ);
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, eItem))));
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (quantity > 0) {
|
||||
short newQ = (short) Math.min(quantity, slotMax);
|
||||
quantity -= newQ;
|
||||
Item nItem = new Item(item.getItemId(), (short) 0, newQ, petId);
|
||||
nItem.setExpiration(item.getExpiration());
|
||||
nItem.setOwner(item.getOwner());
|
||||
nItem.setFlag(item.getFlag());
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
item.setQuantity((short) (quantity + newQ));
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
}
|
||||
} else {
|
||||
Item nItem = new Item(item.getItemId(), (short) 0, quantity, petId);
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(item);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, item))));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (show) {
|
||||
c.announce(MaplePacketCreator.getShowItemGain(item.getItemId(), item.getQuantity()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean checkSpace(MapleClient c, int itemid, int quantity, String owner) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ii.getInventoryType(itemid);
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, itemid);
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(itemid);
|
||||
if (!ItemConstants.isRechargable(itemid)) {
|
||||
if (existing.size() > 0) // first update all existing slots to slotMax
|
||||
{
|
||||
for (Item eItem : existing) {
|
||||
short oldQ = eItem.getQuantity();
|
||||
if (oldQ < slotMax && owner.equals(eItem.getOwner())) {
|
||||
short newQ = (short) Math.min(oldQ + quantity, slotMax);
|
||||
quantity -= (newQ - oldQ);
|
||||
}
|
||||
if (quantity <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final int numSlotsNeeded;
|
||||
if (slotMax > 0) {
|
||||
numSlotsNeeded = (int) (Math.ceil(((double) quantity) / slotMax));
|
||||
} else if (ItemConstants.isRechargable(itemid)) {
|
||||
numSlotsNeeded = 1;
|
||||
} else {
|
||||
numSlotsNeeded = 1;
|
||||
}
|
||||
return !c.getPlayer().getInventory(type).isFull(numSlotsNeeded - 1);
|
||||
} else {
|
||||
return !c.getPlayer().getInventory(type).isFull();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop) {
|
||||
removeFromSlot(c, type, slot, quantity, fromDrop, false);
|
||||
}
|
||||
|
||||
public static void removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) {
|
||||
Item item = c.getPlayer().getInventory(type).getItem(slot);
|
||||
boolean allowZero = consume && ItemConstants.isRechargable(item.getItemId());
|
||||
c.getPlayer().getInventory(type).removeItem(slot, quantity, allowZero);
|
||||
if (item.getQuantity() == 0 && !allowZero) {
|
||||
c.announce(MaplePacketCreator.modifyInventory(fromDrop, Collections.singletonList(new ModifyInventory(3, item))));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.modifyInventory(fromDrop, Collections.singletonList(new ModifyInventory(1, item))));
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeById(MapleClient c, MapleInventoryType type, int itemId, int quantity, boolean fromDrop, boolean consume) {
|
||||
int removeQuantity = quantity;
|
||||
MapleInventory inv = c.getPlayer().getInventory(type);
|
||||
int slotLimit = type == MapleInventoryType.EQUIPPED ? 128 : inv.getSlotLimit();
|
||||
|
||||
for (short i = 0; i <= slotLimit; i++) {
|
||||
Item item = inv.getItem((short) (type == MapleInventoryType.EQUIPPED ? -i : i));
|
||||
if (item != null) {
|
||||
if (item.getItemId() == itemId || item.getCashId() == itemId) {
|
||||
if (removeQuantity <= item.getQuantity()) {
|
||||
removeFromSlot(c, type, item.getPosition(), (short) removeQuantity, fromDrop, consume);
|
||||
removeQuantity = 0;
|
||||
break;
|
||||
} else {
|
||||
removeQuantity -= item.getQuantity();
|
||||
removeFromSlot(c, type, item.getPosition(), item.getQuantity(), fromDrop, consume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeQuantity > 0) {
|
||||
throw new RuntimeException("[HACK] Not enough items available of Item:" + itemId + ", Quantity (After Quantity/Over Current Quantity): " + (quantity - removeQuantity) + "/" + quantity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void move(MapleClient c, MapleInventoryType type, short src, short dst) {
|
||||
if (src < 0 || dst < 0) {
|
||||
return;
|
||||
}
|
||||
if(dst > c.getPlayer().getInventory(type).getSlotLimit()) {
|
||||
return;
|
||||
}
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Item source = c.getPlayer().getInventory(type).getItem(src);
|
||||
Item initialTarget = c.getPlayer().getInventory(type).getItem(dst);
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
short olddstQ = -1;
|
||||
if (initialTarget != null) {
|
||||
olddstQ = initialTarget.getQuantity();
|
||||
}
|
||||
short oldsrcQ = source.getQuantity();
|
||||
short slotMax = ii.getSlotMax(c, source.getItemId());
|
||||
c.getPlayer().getInventory(type).move(src, dst, slotMax);
|
||||
final List<ModifyInventory> mods = new ArrayList<>();
|
||||
if (!type.equals(MapleInventoryType.EQUIP) && initialTarget != null && initialTarget.getItemId() == source.getItemId() && !ItemConstants.isRechargable(source.getItemId())) {
|
||||
if ((olddstQ + oldsrcQ) > slotMax) {
|
||||
mods.add(new ModifyInventory(1, source));
|
||||
mods.add(new ModifyInventory(1, initialTarget));
|
||||
} else {
|
||||
mods.add(new ModifyInventory(3, source));
|
||||
mods.add(new ModifyInventory(1, initialTarget));
|
||||
}
|
||||
} else {
|
||||
mods.add(new ModifyInventory(2, source, src));
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, mods));
|
||||
}
|
||||
|
||||
public static void equip(MapleClient c, short src, short dst) {
|
||||
Equip source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(src);
|
||||
if (source == null || !MapleItemInformationProvider.getInstance().canWearEquipment(c.getPlayer(), source, dst)) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
} else if ((((source.getItemId() >= 1902000 && source.getItemId() <= 1902002) || source.getItemId() == 1912000) && c.getPlayer().isCygnus()) || ((source.getItemId() >= 1902005 && source.getItemId() <= 1902007) || source.getItemId() == 1912005) && !c.getPlayer().isCygnus()) {// Adventurer taming equipment
|
||||
return;
|
||||
}
|
||||
boolean itemChanged = false;
|
||||
if (MapleItemInformationProvider.getInstance().isUntradeableOnEquip(source.getItemId())) {
|
||||
source.setFlag((byte) ItemConstants.UNTRADEABLE);
|
||||
itemChanged = true;
|
||||
}
|
||||
if (source.getRingId() > -1) {
|
||||
c.getPlayer().getRingById(source.getRingId()).equip();
|
||||
}
|
||||
if (dst == -6) { // unequip the overall
|
||||
Item top = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -5);
|
||||
if (top != null && isOverall(top.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -5, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -5) {
|
||||
final Item bottom = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -6);
|
||||
if (bottom != null && isOverall(source.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -6, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -10) {// check if weapon is two-handed
|
||||
Item weapon = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11);
|
||||
if (weapon != null && MapleItemInformationProvider.getInstance().isTwoHanded(weapon.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -11, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -11) {
|
||||
Item shield = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10);
|
||||
if (shield != null && MapleItemInformationProvider.getInstance().isTwoHanded(source.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -10, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
}
|
||||
}
|
||||
if (dst == -18) {
|
||||
if (c.getPlayer().getMount() != null) {
|
||||
c.getPlayer().getMount().setItemId(source.getItemId());
|
||||
}
|
||||
}
|
||||
if (source.getItemId() == 1122017) {
|
||||
c.getPlayer().equipPendantOfSpirit();
|
||||
}
|
||||
//1112413, 1112414, 1112405 (Lilin's Ring)
|
||||
source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(src);
|
||||
Equip target = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeSlot(src);
|
||||
if (target != null) {
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeSlot(dst);
|
||||
}
|
||||
|
||||
final List<ModifyInventory> mods = new ArrayList<>();
|
||||
if (itemChanged) {
|
||||
mods.add(new ModifyInventory(3, source));
|
||||
mods.add(new ModifyInventory(0, source.copy()));//to prevent crashes
|
||||
}
|
||||
|
||||
source.setPosition(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addFromDB(source);
|
||||
if (target != null) {
|
||||
target.setPosition(src);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).addFromDB(target);
|
||||
}
|
||||
if (c.getPlayer().getBuffedValue(MapleBuffStat.BOOSTER) != null && isWeapon(source.getItemId())) {
|
||||
c.getPlayer().cancelBuffStats(MapleBuffStat.BOOSTER);
|
||||
}
|
||||
|
||||
mods.add(new ModifyInventory(2, source, src));
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, mods));
|
||||
c.getPlayer().equipChanged();
|
||||
}
|
||||
|
||||
public static void unequip(MapleClient c, short src, short dst) {
|
||||
Equip source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(src);
|
||||
Equip target = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(dst);
|
||||
if (dst < 0) {
|
||||
return;
|
||||
}
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
if (target != null && src <= 0) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
return;
|
||||
}
|
||||
if (source.getItemId() == 1122017) {
|
||||
c.getPlayer().unequipPendantOfSpirit();
|
||||
}
|
||||
if (source.getRingId() > -1) {
|
||||
c.getPlayer().getRingById(source.getRingId()).unequip();
|
||||
}
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeSlot(src);
|
||||
if (target != null) {
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeSlot(dst);
|
||||
}
|
||||
source.setPosition(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).addFromDB(source);
|
||||
if (target != null) {
|
||||
target.setPosition(src);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addFromDB(target);
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(2, source, src))));
|
||||
c.getPlayer().equipChanged();
|
||||
}
|
||||
|
||||
public static void drop(MapleClient c, MapleInventoryType type, short src, short quantity) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
if (src < 0) {
|
||||
type = MapleInventoryType.EQUIPPED;
|
||||
}
|
||||
Item source = c.getPlayer().getInventory(type).getItem(src);
|
||||
|
||||
if (c.getPlayer().getTrade() != null || c.getPlayer().getMiniGame() != null || source == null) { //Only check needed would prob be merchants (to see if the player is in one)
|
||||
return;
|
||||
}
|
||||
int itemId = source.getItemId();
|
||||
if (itemId >= 5000000 && itemId <= 5000100) {
|
||||
return;
|
||||
}
|
||||
if (type == MapleInventoryType.EQUIPPED && itemId == 1122017) {
|
||||
c.getPlayer().unequipPendantOfSpirit();
|
||||
}
|
||||
if (c.getPlayer().getItemEffect() == itemId && source.getQuantity() == 1) {
|
||||
c.getPlayer().setItemEffect(0);
|
||||
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.itemEffect(c.getPlayer().getId(), 0));
|
||||
} else if (itemId == 5370000 || itemId == 5370001) {
|
||||
if (c.getPlayer().getItemQuantity(itemId, false) == 1) {
|
||||
c.getPlayer().setChalkboard(null);
|
||||
}
|
||||
}
|
||||
if ((!ItemConstants.isRechargable(itemId) && c.getPlayer().getItemQuantity(itemId, true) < quantity) || quantity < 0 || source == null) {
|
||||
return;
|
||||
}
|
||||
Point dropPos = new Point(c.getPlayer().getPosition());
|
||||
if (quantity < source.getQuantity() && !ItemConstants.isRechargable(itemId)) {
|
||||
Item target = source.copy();
|
||||
target.setQuantity(quantity);
|
||||
source.setQuantity((short) (source.getQuantity() - quantity));
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, source))));
|
||||
boolean weddingRing = source.getItemId() == 1112803 || source.getItemId() == 1112806 || source.getItemId() == 1112807 || source.getItemId() == 1112809;
|
||||
if (weddingRing) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
} else if (c.getPlayer().getMap().getEverlast()) {
|
||||
if (ii.isDropRestricted(target.getItemId()) || MapleItemInformationProvider.getInstance().isCash(target.getItemId())) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, false);
|
||||
}
|
||||
} else if (ii.isDropRestricted(target.getItemId()) || MapleItemInformationProvider.getInstance().isCash(target.getItemId())) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, true);
|
||||
}
|
||||
} else {
|
||||
c.getPlayer().getInventory(type).removeSlot(src);
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(3, source))));
|
||||
if (src < 0) {
|
||||
c.getPlayer().equipChanged();
|
||||
}
|
||||
if (c.getPlayer().getMap().getEverlast()) {
|
||||
if (ii.isDropRestricted(itemId) || ii.isCash(itemId)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, false);
|
||||
}
|
||||
} else if (ii.isDropRestricted(itemId) || ii.isCash(itemId)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOverall(int itemId) {
|
||||
return itemId / 10000 == 105;
|
||||
}
|
||||
|
||||
private static boolean isWeapon(int itemId) {
|
||||
return itemId >= 1302000 && itemId < 1492024;
|
||||
}
|
||||
}
|
||||
1498
src/server/MapleItemInformationProvider.java
Normal file
1498
src/server/MapleItemInformationProvider.java
Normal file
File diff suppressed because it is too large
Load Diff
341
src/server/MapleMiniGame.java
Normal file
341
src/server/MapleMiniGame.java
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleMiniGame extends AbstractMapleMapObject {
|
||||
private MapleCharacter owner;
|
||||
private MapleCharacter visitor;
|
||||
private String GameType = null;
|
||||
private int[] piece = new int[250];
|
||||
private List<Integer> list4x3 = new ArrayList<>();
|
||||
private List<Integer> list5x4 = new ArrayList<>();
|
||||
private List<Integer> list6x5 = new ArrayList<>();
|
||||
private String description;
|
||||
private int loser = 1;
|
||||
private int piecetype;
|
||||
private int firstslot = 0;
|
||||
private int visitorpoints = 0;
|
||||
private int ownerpoints = 0;
|
||||
private int matchestowin = 0;
|
||||
|
||||
public MapleMiniGame(MapleCharacter owner, String description) {
|
||||
this.owner = owner;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean hasFreeSlot() {
|
||||
return visitor == null;
|
||||
}
|
||||
|
||||
public boolean isOwner(MapleCharacter c) {
|
||||
return owner.equals(c);
|
||||
}
|
||||
|
||||
public void addVisitor(MapleCharacter challenger) {
|
||||
visitor = challenger;
|
||||
if (GameType.equals("omok")) {
|
||||
this.getOwner().getClient().announce(MaplePacketCreator.getMiniGameNewVisitor(challenger, 1));
|
||||
this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addOmokBox(owner, 2, 0));
|
||||
}
|
||||
if (GameType.equals("matchcard")) {
|
||||
this.getOwner().getClient().announce(MaplePacketCreator.getMatchCardNewVisitor(challenger, 1));
|
||||
this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(owner, 2, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeVisitor(MapleCharacter challenger) {
|
||||
if (visitor == challenger) {
|
||||
visitor = null;
|
||||
this.getOwner().getClient().announce(MaplePacketCreator.getMiniGameRemoveVisitor());
|
||||
if (GameType.equals("omok")) {
|
||||
this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addOmokBox(owner, 1, 0));
|
||||
}
|
||||
if (GameType.equals("matchcard")) {
|
||||
this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(owner, 1, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisitor(MapleCharacter challenger) {
|
||||
return visitor == challenger;
|
||||
}
|
||||
|
||||
public void broadcastToVisitor(final byte[] packet) {
|
||||
if (visitor != null) {
|
||||
visitor.getClient().announce(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFirstSlot(int type) {
|
||||
firstslot = type;
|
||||
}
|
||||
|
||||
public int getFirstSlot() {
|
||||
return firstslot;
|
||||
}
|
||||
|
||||
public void setOwnerPoints() {
|
||||
ownerpoints++;
|
||||
if (ownerpoints + visitorpoints == matchestowin) {
|
||||
if (ownerpoints == visitorpoints) {
|
||||
this.broadcast(MaplePacketCreator.getMatchCardTie(this));
|
||||
} else if (ownerpoints > visitorpoints) {
|
||||
this.broadcast(MaplePacketCreator.getMatchCardOwnerWin(this));
|
||||
} else {
|
||||
this.broadcast(MaplePacketCreator.getMatchCardVisitorWin(this));
|
||||
}
|
||||
ownerpoints = 0;
|
||||
visitorpoints = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisitorPoints() {
|
||||
visitorpoints++;
|
||||
if (ownerpoints + visitorpoints == matchestowin) {
|
||||
if (ownerpoints > visitorpoints) {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameOwnerWin(this));
|
||||
} else if (visitorpoints > ownerpoints) {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameVisitorWin(this));
|
||||
} else {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameTie(this));
|
||||
}
|
||||
ownerpoints = 0;
|
||||
visitorpoints = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMatchesToWin(int type) {
|
||||
matchestowin = type;
|
||||
}
|
||||
|
||||
public void setPieceType(int type) {
|
||||
piecetype = type;
|
||||
}
|
||||
|
||||
public int getPieceType() {
|
||||
return piecetype;
|
||||
}
|
||||
|
||||
public void setGameType(String game) {
|
||||
GameType = game;
|
||||
if (game.equals("matchcard")) {
|
||||
if (matchestowin == 6) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
list4x3.add(i);
|
||||
list4x3.add(i);
|
||||
}
|
||||
} else if (matchestowin == 10) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
list5x4.add(i);
|
||||
list5x4.add(i);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
list6x5.add(i);
|
||||
list6x5.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getGameType() {
|
||||
return GameType;
|
||||
}
|
||||
|
||||
public void shuffleList() {
|
||||
if (matchestowin == 6) {
|
||||
Collections.shuffle(list4x3);
|
||||
} else if (matchestowin == 10) {
|
||||
Collections.shuffle(list5x4);
|
||||
} else {
|
||||
Collections.shuffle(list6x5);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCardId(int slot) {
|
||||
int cardid;
|
||||
if (matchestowin == 6) {
|
||||
cardid = list4x3.get(slot - 1);
|
||||
} else if (matchestowin == 10) {
|
||||
cardid = list5x4.get(slot - 1);
|
||||
} else {
|
||||
cardid = list6x5.get(slot - 1);
|
||||
}
|
||||
return cardid;
|
||||
}
|
||||
|
||||
public int getMatchesToWin() {
|
||||
return matchestowin;
|
||||
}
|
||||
|
||||
public void setLoser(int type) {
|
||||
loser = type;
|
||||
}
|
||||
|
||||
public int getLoser() {
|
||||
return loser;
|
||||
}
|
||||
|
||||
public void broadcast(final byte[] packet) {
|
||||
if (owner.getClient() != null && owner.getClient().getSession() != null) {
|
||||
owner.getClient().announce(packet);
|
||||
}
|
||||
broadcastToVisitor(packet);
|
||||
}
|
||||
|
||||
public void chat(MapleClient c, String chat) {
|
||||
broadcast(MaplePacketCreator.getPlayerShopChat(c.getPlayer(), chat, isOwner(c.getPlayer())));
|
||||
}
|
||||
|
||||
public void sendOmok(MapleClient c, int type) {
|
||||
c.announce(MaplePacketCreator.getMiniGame(c, this, isOwner(c.getPlayer()), type));
|
||||
}
|
||||
|
||||
public void sendMatchCard(MapleClient c, int type) {
|
||||
c.announce(MaplePacketCreator.getMatchCard(c, this, isOwner(c.getPlayer()), type));
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public MapleCharacter getVisitor() {
|
||||
return visitor;
|
||||
}
|
||||
|
||||
public void setPiece(int move1, int move2, int type, MapleCharacter chr) {
|
||||
int slot = move2 * 15 + move1 + 1;
|
||||
if (piece[slot] == 0) {
|
||||
piece[slot] = type;
|
||||
this.broadcast(MaplePacketCreator.getMiniGameMoveOmok(this, move1, move2, type));
|
||||
for (int y = 0; y < 15; y++) {
|
||||
for (int x = 0; x < 11; x++) {
|
||||
if (searchCombo(x, y, type)) {
|
||||
if (this.isOwner(chr)) {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameOwnerWin(this));
|
||||
this.setLoser(0);
|
||||
} else {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameVisitorWin(this));
|
||||
this.setLoser(1);
|
||||
}
|
||||
for (int y2 = 0; y2 < 15; y2++) {
|
||||
for (int x2 = 0; x2 < 15; x2++) {
|
||||
int slot2 = (y2 * 15 + x2 + 1);
|
||||
piece[slot2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < 15; y++) {
|
||||
for (int x = 4; x < 15; x++) {
|
||||
if (searchCombo2(x, y, type)) {
|
||||
if (this.isOwner(chr)) {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameOwnerWin(this));
|
||||
this.setLoser(0);
|
||||
} else {
|
||||
this.broadcast(MaplePacketCreator.getMiniGameVisitorWin(this));
|
||||
this.setLoser(1);
|
||||
}
|
||||
for (int y2 = 0; y2 < 15; y2++) {
|
||||
for (int x2 = 0; x2 < 15; x2++) {
|
||||
int slot2 = (y2 * 15 + x2 + 1);
|
||||
piece[slot2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean searchCombo(int x, int y, int type) {
|
||||
int slot = y * 15 + x + 1;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (piece[slot + i] == type) {
|
||||
if (i == 4) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = 15; j < 17; j++) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (piece[slot + i * j] == type) {
|
||||
if (i == 4) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean searchCombo2(int x, int y, int type) {
|
||||
int slot = y * 15 + x + 1;
|
||||
for (int j = 14; j < 15; j++) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (piece[slot + i * j] == type) {
|
||||
if (i == 4) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.MINI_GAME;
|
||||
}
|
||||
}
|
||||
272
src/server/MaplePlayerShop.java
Normal file
272
src/server/MaplePlayerShop.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.SendOpcode;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.output.MaplePacketLittleEndianWriter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
private MapleCharacter owner;
|
||||
private MapleCharacter[] visitors = new MapleCharacter[3];
|
||||
private List<MaplePlayerShopItem> items = new ArrayList<>();
|
||||
private MapleCharacter[] slot = {null, null, null};
|
||||
private String description;
|
||||
private int boughtnumber = 0;
|
||||
private List<String> bannedList = new ArrayList<>();
|
||||
|
||||
public MaplePlayerShop(MapleCharacter owner, String description) {
|
||||
this.setPosition(owner.getPosition());
|
||||
this.owner = owner;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean hasFreeSlot() {
|
||||
return visitors[0] == null || visitors[1] == null || visitors[2] == null;
|
||||
}
|
||||
|
||||
public boolean isOwner(MapleCharacter c) {
|
||||
return owner.equals(c);
|
||||
}
|
||||
|
||||
public void addVisitor(MapleCharacter visitor) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] == null) {
|
||||
visitors[i] = visitor;
|
||||
if (this.getSlot(0) == null) {
|
||||
this.setSlot(visitor, 0);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 1));
|
||||
} else if (this.getSlot(1) == null) {
|
||||
this.setSlot(visitor, 1);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 2));
|
||||
} else if (this.getSlot(2) == null) {
|
||||
this.setSlot(visitor, 2);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, 3));
|
||||
visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(this.getOwner(), 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeVisitor(MapleCharacter visitor) {
|
||||
if (visitor == owner) {
|
||||
owner.getMap().removeMapObject(this);
|
||||
owner.setPlayerShop(null);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null && visitors[i].getId() == visitor.getId()) {
|
||||
int slot_ = visitor.getSlot();
|
||||
visitors[i] = null;
|
||||
this.setSlot(null, i);
|
||||
visitor.setSlot(-1);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopRemoveVisitor(slot_ + 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisitor(MapleCharacter visitor) {
|
||||
return visitors[0] == visitor || visitors[1] == visitor || visitors[2] == visitor;
|
||||
}
|
||||
|
||||
public void addItem(MaplePlayerShopItem item) {
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
public void removeItem(int item) {
|
||||
items.remove(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* no warnings for now o.op
|
||||
* @param c
|
||||
* @param item
|
||||
* @param quantity
|
||||
*/
|
||||
public void buy(MapleClient c, int item, short quantity) {
|
||||
if (isVisitor(c.getPlayer())) {
|
||||
MaplePlayerShopItem pItem = items.get(item);
|
||||
Item newItem = pItem.getItem().copy();
|
||||
newItem.setQuantity(newItem.getQuantity());
|
||||
if (quantity < 1 || pItem.getBundles() < 1 || newItem.getQuantity() > pItem.getBundles() || !pItem.isExist()) {
|
||||
return;
|
||||
} else if (newItem.getType() == 1 && newItem.getQuantity() > 1) {
|
||||
return;
|
||||
}
|
||||
synchronized (c.getPlayer()) {
|
||||
if (c.getPlayer().getMeso() >= (long) pItem.getPrice() * quantity) {
|
||||
if (MapleInventoryManipulator.addFromDrop(c, newItem, false)) {
|
||||
c.getPlayer().gainMeso(-pItem.getPrice() * quantity, true);
|
||||
owner.gainMeso(pItem.getPrice() * quantity, true);
|
||||
pItem.setBundles((short) (pItem.getBundles() - quantity));
|
||||
if (pItem.getBundles() < 1) {
|
||||
pItem.setDoesExist(false);
|
||||
if (++boughtnumber == items.size()) {
|
||||
owner.setPlayerShop(null);
|
||||
owner.getMap().broadcastMessage(MaplePacketCreator.removeCharBox(owner));
|
||||
this.removeVisitors();
|
||||
owner.dropMessage(1, "Your items are sold out, and therefore your shop is closed.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.getPlayer().dropMessage(1, "Your inventory is full. Please clean a slot before buying this item.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void broadcastToVisitors(final byte[] packet) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null) {
|
||||
visitors[i].getClient().announce(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeVisitors() {
|
||||
try {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null) {
|
||||
visitors[i].getClient().announce(MaplePacketCreator.shopErrorMessage(10, 1));
|
||||
removeVisitor(visitors[i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (owner != null) {
|
||||
removeVisitor(getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] shopErrorMessage(int error, int type) {
|
||||
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.PLAYER_INTERACTION.getValue());
|
||||
mplew.write(0x0A);
|
||||
mplew.write(type);
|
||||
mplew.write(error);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public void broadcast(final byte[] packet) {
|
||||
if (owner.getClient() != null && owner.getClient().getSession() != null) {
|
||||
owner.getClient().announce(packet);
|
||||
}
|
||||
broadcastToVisitors(packet);
|
||||
}
|
||||
|
||||
public void chat(MapleClient c, String chat) {
|
||||
byte s = 0;
|
||||
for (MapleCharacter mc : getVisitors()) {
|
||||
s++;
|
||||
if (mc != null) {
|
||||
if (mc.getName().equalsIgnoreCase(c.getPlayer().getName())) {
|
||||
break;
|
||||
}
|
||||
} else if (s == 3) {
|
||||
s = 0;
|
||||
}
|
||||
}
|
||||
broadcast(MaplePacketCreator.getPlayerShopChat(c.getPlayer(), chat, s));
|
||||
}
|
||||
|
||||
public void sendShop(MapleClient c) {
|
||||
c.announce(MaplePacketCreator.getPlayerShop(c, this, isOwner(c.getPlayer())));
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public MapleCharacter[] getVisitors() {
|
||||
return visitors;
|
||||
}
|
||||
|
||||
public MapleCharacter getSlot(int s) {
|
||||
return slot[s];
|
||||
}
|
||||
|
||||
private void setSlot(MapleCharacter person, int s) {
|
||||
slot[s] = person;
|
||||
if (person != null) {
|
||||
person.setSlot(s);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MaplePlayerShopItem> getItems() {
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void banPlayer(String name) {
|
||||
if (!bannedList.contains(name)) {
|
||||
bannedList.add(name);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null && visitors[i].getName().equals(name)) {
|
||||
visitors[i].getClient().announce(MaplePacketCreator.shopErrorMessage(5, 1));
|
||||
removeVisitor(visitors[i]);
|
||||
return; //I'm guessing this was the intended action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBanned(String name) {
|
||||
return bannedList.contains(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.removeCharBox(this.getOwner()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.addCharBox(this.getOwner(), 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.SHOP;
|
||||
}
|
||||
}
|
||||
66
src/server/MaplePlayerShopItem.java
Normal file
66
src/server/MaplePlayerShopItem.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.inventory.Item;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MaplePlayerShopItem {
|
||||
private Item item;
|
||||
private short bundles;
|
||||
private int price;
|
||||
private boolean doesExist;
|
||||
|
||||
public MaplePlayerShopItem(Item item, short bundles, int price) {
|
||||
this.item = item;
|
||||
this.bundles = bundles;
|
||||
this.price = price;
|
||||
this.doesExist = true;
|
||||
}
|
||||
|
||||
public void setDoesExist(boolean tf) {
|
||||
this.doesExist = tf;
|
||||
}
|
||||
|
||||
public boolean isExist() {
|
||||
return doesExist;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public short getBundles() {
|
||||
return bundles;
|
||||
}
|
||||
|
||||
public int getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setBundles(short bundles) {
|
||||
this.bundles = bundles;
|
||||
}
|
||||
}
|
||||
45
src/server/MaplePortal.java
Normal file
45
src/server/MaplePortal.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.awt.Point;
|
||||
import client.MapleClient;
|
||||
|
||||
public interface MaplePortal {
|
||||
public final int MAP_PORTAL = 2;
|
||||
public final int DOOR_PORTAL = 6;
|
||||
public static boolean OPEN = true;
|
||||
public static boolean CLOSED = false;
|
||||
int getType();
|
||||
int getId();
|
||||
Point getPosition();
|
||||
String getName();
|
||||
String getTarget();
|
||||
String getScriptName();
|
||||
void setScriptName(String newName);
|
||||
void setPortalStatus(boolean newStatus);
|
||||
boolean getPortalStatus();
|
||||
int getTargetMapId();
|
||||
void enterPortal(MapleClient c);
|
||||
void setPortalState(boolean state);
|
||||
boolean getPortalState();
|
||||
}
|
||||
271
src/server/MapleShop.java
Normal file
271
src/server/MapleShop.java
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import constants.ItemConstants;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleShop {
|
||||
private static final Set<Integer> rechargeableItems = new LinkedHashSet<>();
|
||||
private int id;
|
||||
private int npcId;
|
||||
private List<MapleShopItem> items;
|
||||
private int tokenvalue = 1000000000;
|
||||
private int token = 4000313;
|
||||
|
||||
static {
|
||||
for (int i = 2070000; i < 2070017; i++) {
|
||||
rechargeableItems.add(i);
|
||||
}
|
||||
rechargeableItems.add(2331000);//Blaze Capsule
|
||||
rechargeableItems.add(2332000);//Glaze Capsule
|
||||
rechargeableItems.add(2070018);
|
||||
rechargeableItems.remove(2070014); // doesn't exist
|
||||
for (int i = 2330000; i <= 2330005; i++) {
|
||||
rechargeableItems.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
private MapleShop(int id, int npcId) {
|
||||
this.id = id;
|
||||
this.npcId = npcId;
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
|
||||
private void addItem(MapleShopItem item) {
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
public void sendShop(MapleClient c) {
|
||||
c.getPlayer().setShop(this);
|
||||
c.announce(MaplePacketCreator.getNPCShop(c, getNpcId(), items));
|
||||
}
|
||||
|
||||
public void buy(MapleClient c, short slot, int itemId, short quantity) {
|
||||
MapleShopItem item = findBySlot(slot);
|
||||
if (item != null) {
|
||||
if (item.getItemId() != itemId) {
|
||||
System.out.println("Wrong slot number in shop " + id);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
if (item != null && item.getPrice() > 0) {
|
||||
if (c.getPlayer().getMeso() >= (long) item.getPrice() * quantity) {
|
||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||
if (!ItemConstants.isRechargable(itemId)) { //Pets can't be bought from shops
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
||||
c.getPlayer().gainMeso(-(item.getPrice() * quantity), false);
|
||||
} else {
|
||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||
quantity = slotMax;
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
||||
c.getPlayer().gainMeso(-item.getPrice(), false);
|
||||
}
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
||||
} else
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
|
||||
|
||||
} else
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 2));
|
||||
|
||||
} else if (item != null && item.getPitch() > 0) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= (long) item.getPitch() * quantity) {
|
||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||
if (!ItemConstants.isRechargable(itemId)) {
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
|
||||
} else {
|
||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||
quantity = slotMax;
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
|
||||
}
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
||||
} else
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
|
||||
}
|
||||
|
||||
} else if (c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token) != 0) {
|
||||
int amount = c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token);
|
||||
int value = amount * tokenvalue;
|
||||
int cost = item.getPrice() * quantity;
|
||||
if (c.getPlayer().getMeso() + value >= cost) {
|
||||
int cardreduce = value - cost;
|
||||
int diff = cardreduce + c.getPlayer().getMeso();
|
||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||
if (itemId >= 5000000 && itemId <= 5000100) {
|
||||
int petid = MaplePet.createPet(itemId);
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
|
||||
} else {
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
||||
}
|
||||
c.getPlayer().gainMeso(diff, false);
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
|
||||
}
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
||||
} else
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sell(MapleClient c, MapleInventoryType type, short slot, short quantity) {
|
||||
if (quantity == 0xFFFF || quantity == 0) {
|
||||
quantity = 1;
|
||||
}
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Item item = c.getPlayer().getInventory(type).getItem((short) slot);
|
||||
if (item == null){ //Basic check
|
||||
return;
|
||||
}
|
||||
if (ItemConstants.isRechargable(item.getItemId())) {
|
||||
quantity = item.getQuantity();
|
||||
}
|
||||
if (quantity < 0) {
|
||||
return;
|
||||
}
|
||||
short iQuant = item.getQuantity();
|
||||
if (iQuant == 0xFFFF) {
|
||||
iQuant = 1;
|
||||
}
|
||||
if (quantity <= iQuant && iQuant > 0) {
|
||||
MapleInventoryManipulator.removeFromSlot(c, type, (byte) slot, quantity, false);
|
||||
double price;
|
||||
if (ItemConstants.isRechargable(item.getItemId())) {
|
||||
price = ii.getWholePrice(item.getItemId()) / (double) ii.getSlotMax(c, item.getItemId());
|
||||
} else {
|
||||
price = ii.getPrice(item.getItemId());
|
||||
}
|
||||
int recvMesos = (int) Math.max(Math.ceil(price * quantity), 0);
|
||||
if (price != -1 && recvMesos > 0) {
|
||||
c.getPlayer().gainMeso(recvMesos, false);
|
||||
}
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0x8));
|
||||
}
|
||||
}
|
||||
|
||||
public void recharge(MapleClient c, short slot) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Item item = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot);
|
||||
if (item == null || !ItemConstants.isRechargable(item.getItemId())) {
|
||||
return;
|
||||
}
|
||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||
if (item.getQuantity() < 0) {
|
||||
return;
|
||||
}
|
||||
if (item.getQuantity() < slotMax) {
|
||||
int price = (int) Math.round(ii.getPrice(item.getItemId()) * (slotMax - item.getQuantity()));
|
||||
if (c.getPlayer().getMeso() >= price) {
|
||||
item.setQuantity(slotMax);
|
||||
c.getPlayer().forceUpdateItem(item);
|
||||
c.getPlayer().gainMeso(-price, false, true, false);
|
||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0x8));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You do not have enough mesos."));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MapleShopItem findBySlot(short slot) {
|
||||
return items.get(slot);
|
||||
}
|
||||
|
||||
public static MapleShop createFromDB(int id, boolean isShopId) {
|
||||
MapleShop ret = null;
|
||||
int shopId;
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps;
|
||||
if (isShopId) {
|
||||
ps = con.prepareStatement("SELECT * FROM shops WHERE shopid = ?");
|
||||
} else {
|
||||
ps = con.prepareStatement("SELECT * FROM shops WHERE npcid = ?");
|
||||
}
|
||||
ps.setInt(1, id);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
shopId = rs.getInt("shopid");
|
||||
ret = new MapleShop(shopId, rs.getInt("npcid"));
|
||||
rs.close();
|
||||
ps.close();
|
||||
} else {
|
||||
rs.close();
|
||||
ps.close();
|
||||
return null;
|
||||
}
|
||||
ps = con.prepareStatement("SELECT * FROM shopitems WHERE shopid = ? ORDER BY position DESC");
|
||||
ps.setInt(1, shopId);
|
||||
rs = ps.executeQuery();
|
||||
List<Integer> recharges = new ArrayList<>(rechargeableItems);
|
||||
while (rs.next()) {
|
||||
if (ItemConstants.isRechargable(rs.getInt("itemid"))) {
|
||||
MapleShopItem starItem = new MapleShopItem((short) 1, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch"));
|
||||
ret.addItem(starItem);
|
||||
if (rechargeableItems.contains(starItem.getItemId())) {
|
||||
recharges.remove(Integer.valueOf(starItem.getItemId()));
|
||||
}
|
||||
} else {
|
||||
ret.addItem(new MapleShopItem((short) 1000, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch")));
|
||||
}
|
||||
}
|
||||
for (Integer recharge : recharges) {
|
||||
ret.addItem(new MapleShopItem((short) 1000, recharge.intValue(), 0, 0));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getNpcId() {
|
||||
return npcId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
70
src/server/MapleShopFactory.java
Normal file
70
src/server/MapleShopFactory.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleShopFactory {
|
||||
private Map<Integer, MapleShop> shops = new HashMap<Integer, MapleShop>();
|
||||
private Map<Integer, MapleShop> npcShops = new HashMap<Integer, MapleShop>();
|
||||
private static MapleShopFactory instance = new MapleShopFactory();
|
||||
|
||||
public static MapleShopFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void reloadShops() {
|
||||
shops.clear();
|
||||
}
|
||||
|
||||
private MapleShop loadShop(int id, boolean isShopId) {
|
||||
MapleShop ret = MapleShop.createFromDB(id, isShopId);
|
||||
if (ret != null) {
|
||||
shops.put(ret.getId(), ret);
|
||||
npcShops.put(ret.getNpcId(), ret);
|
||||
} else if (isShopId) {
|
||||
shops.put(id, null);
|
||||
} else {
|
||||
npcShops.put(id, null);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MapleShop getShop(int shopId) {
|
||||
if (shops.containsKey(shopId)) {
|
||||
return shops.get(shopId);
|
||||
}
|
||||
return loadShop(shopId, true);
|
||||
}
|
||||
|
||||
public MapleShop getShopForNPC(int npcId) {
|
||||
if (npcShops.containsKey(npcId)) {
|
||||
npcShops.get(npcId);
|
||||
}
|
||||
return loadShop(npcId, false);
|
||||
}
|
||||
}
|
||||
56
src/server/MapleShopItem.java
Normal file
56
src/server/MapleShopItem.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleShopItem {
|
||||
private short buyable;
|
||||
private int itemId;
|
||||
private int price;
|
||||
private int pitch;
|
||||
|
||||
public MapleShopItem(short buyable, int itemId, int price, int pitch) {
|
||||
this.buyable = buyable;
|
||||
this.itemId = itemId;
|
||||
this.price = price;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public short getBuyable() {
|
||||
return buyable;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public int getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public int getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
}
|
||||
1485
src/server/MapleStatEffect.java
Normal file
1485
src/server/MapleStatEffect.java
Normal file
File diff suppressed because it is too large
Load Diff
234
src/server/MapleStorage.java
Normal file
234
src/server/MapleStorage.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleStorage {
|
||||
|
||||
private int id;
|
||||
private List<Item> items;
|
||||
private int meso;
|
||||
private byte slots;
|
||||
private Map<MapleInventoryType, List<Item>> typeItems = new HashMap<>();
|
||||
|
||||
private MapleStorage(int id, byte slots, int meso) {
|
||||
this.id = id;
|
||||
this.slots = slots;
|
||||
this.items = new LinkedList<>();
|
||||
this.meso = meso;
|
||||
}
|
||||
|
||||
private static MapleStorage create(int id, int world) {
|
||||
try {
|
||||
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO storages (accountid, world, slots, meso) VALUES (?, ?, 4, 0)")) {
|
||||
ps.setInt(1, id);
|
||||
ps.setInt(2, world);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return loadOrCreateFromDB(id, world);
|
||||
}
|
||||
|
||||
public static MapleStorage loadOrCreateFromDB(int id, int world) {
|
||||
MapleStorage ret = null;
|
||||
int storeId;
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT storageid, slots, meso FROM storages WHERE accountid = ? AND world = ?");
|
||||
ps.setInt(1, id);
|
||||
ps.setInt(2, world);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (!rs.next()) {
|
||||
rs.close();
|
||||
ps.close();
|
||||
return create(id, world);
|
||||
} else {
|
||||
storeId = rs.getInt("storageid");
|
||||
ret = new MapleStorage(storeId, (byte) rs.getInt("slots"), rs.getInt("meso"));
|
||||
rs.close();
|
||||
ps.close();
|
||||
for (Pair<Item, MapleInventoryType> item : ItemFactory.STORAGE.loadItems(ret.id, false)) {
|
||||
ret.items.add(item.getLeft());
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte getSlots() {
|
||||
return slots;
|
||||
}
|
||||
|
||||
public boolean gainSlots(int slots) {
|
||||
slots += this.slots;
|
||||
|
||||
if (slots <= 48) {
|
||||
this.slots = (byte) slots;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setSlots(byte set) {
|
||||
this.slots = set;
|
||||
}
|
||||
|
||||
public void saveToDB(Connection con) {
|
||||
try {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE storages SET slots = ?, meso = ? WHERE storageid = ?")) {
|
||||
ps.setInt(1, slots);
|
||||
ps.setInt(2, meso);
|
||||
ps.setInt(3, id);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
List<Pair<Item, MapleInventoryType>> itemsWithType = new ArrayList<>();
|
||||
|
||||
for (Item item : items) {
|
||||
itemsWithType.add(new Pair<>(item, MapleItemInformationProvider.getInstance().getInventoryType(item.getItemId())));
|
||||
}
|
||||
|
||||
ItemFactory.STORAGE.saveItems(itemsWithType, id, con);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItem(byte slot) {
|
||||
return items.get(slot);
|
||||
}
|
||||
|
||||
public Item takeOut(byte slot) {
|
||||
Item ret = items.remove(slot);
|
||||
MapleInventoryType type = MapleItemInformationProvider.getInstance().getInventoryType(ret.getItemId());
|
||||
typeItems.put(type, new ArrayList<>(filterItems(type)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void store(Item item) {
|
||||
items.add(item);
|
||||
MapleInventoryType type = MapleItemInformationProvider.getInstance().getInventoryType(item.getItemId());
|
||||
typeItems.put(type, new ArrayList<>(filterItems(type)));
|
||||
}
|
||||
|
||||
public List<Item> getItems() {
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
|
||||
private List<Item> filterItems(MapleInventoryType type) {
|
||||
List<Item> ret = new LinkedList<>();
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
for (Item item : items) {
|
||||
if (ii.getInventoryType(item.getItemId()) == type) {
|
||||
ret.add(item);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte getSlot(MapleInventoryType type, byte slot) {
|
||||
byte ret = 0;
|
||||
for (Item item : items) {
|
||||
if (item == typeItems.get(type).get(slot)) {
|
||||
return ret;
|
||||
}
|
||||
ret++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void sendStorage(MapleClient c, int npcId) {
|
||||
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Collections.sort(items, new Comparator<Item>() {
|
||||
@Override
|
||||
public int compare(Item o1, Item o2) {
|
||||
if (ii.getInventoryType(o1.getItemId()).getType() < ii.getInventoryType(o2.getItemId()).getType()) {
|
||||
return -1;
|
||||
} else if (ii.getInventoryType(o1.getItemId()) == ii.getInventoryType(o2.getItemId())) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
for (MapleInventoryType type : MapleInventoryType.values()) {
|
||||
typeItems.put(type, new ArrayList<>(items));
|
||||
}
|
||||
c.announce(MaplePacketCreator.getStorage(npcId, slots, items, meso));
|
||||
}
|
||||
|
||||
public void sendStored(MapleClient c, MapleInventoryType type) {
|
||||
c.announce(MaplePacketCreator.storeStorage(slots, type, typeItems.get(type)));
|
||||
}
|
||||
|
||||
public void sendTakenOut(MapleClient c, MapleInventoryType type) {
|
||||
c.announce(MaplePacketCreator.takeOutStorage(slots, type, typeItems.get(type)));
|
||||
}
|
||||
|
||||
public int getMeso() {
|
||||
return meso;
|
||||
}
|
||||
|
||||
public void setMeso(int meso) {
|
||||
if (meso < 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
this.meso = meso;
|
||||
}
|
||||
|
||||
public void sendMeso(MapleClient c) {
|
||||
c.announce(MaplePacketCreator.mesoStorage(slots, meso));
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return items.size() >= slots;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
typeItems.clear();
|
||||
}
|
||||
}
|
||||
308
src/server/MapleTrade.java
Normal file
308
src/server/MapleTrade.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import tools.LogHelper;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import constants.ItemConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleTrade {
|
||||
private MapleTrade partner = null;
|
||||
private List<Item> items = new ArrayList<>();
|
||||
private List<Item> exchangeItems;
|
||||
private int meso = 0;
|
||||
private int exchangeMeso;
|
||||
boolean locked = false;
|
||||
private MapleCharacter chr;
|
||||
private byte number;
|
||||
private boolean fullTrade = false;
|
||||
|
||||
public MapleTrade(byte number, MapleCharacter c) {
|
||||
chr = c;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
private static int getFee(int meso) {
|
||||
int fee = 0;
|
||||
if (meso >= 100000000) {
|
||||
fee = (int) Math.round(0.06 * meso);
|
||||
} else if (meso >= 25000000) {
|
||||
fee = meso / 20;
|
||||
} else if (meso >= 10000000) {
|
||||
fee = meso / 25;
|
||||
} else if (meso >= 5000000) {
|
||||
fee = (int) Math.round(.03 * meso);
|
||||
} else if (meso >= 1000000) {
|
||||
fee = (int) Math.round(.018 * meso);
|
||||
} else if (meso >= 100000) {
|
||||
fee = meso / 125;
|
||||
}
|
||||
return fee;
|
||||
}
|
||||
|
||||
private void lock() {
|
||||
locked = true;
|
||||
partner.getChr().getClient().announce(MaplePacketCreator.getTradeConfirmation());
|
||||
}
|
||||
|
||||
private void complete1() {
|
||||
exchangeItems = partner.getItems();
|
||||
exchangeMeso = partner.getMeso();
|
||||
}
|
||||
|
||||
private void complete2() {
|
||||
items.clear();
|
||||
meso = 0;
|
||||
for (Item item : exchangeItems) {
|
||||
if ((item.getFlag() & ItemConstants.KARMA) == ItemConstants.KARMA)
|
||||
item.setFlag((byte) (item.getFlag() ^ ItemConstants.KARMA)); //items with scissors of karma used on them are reset once traded
|
||||
else if (item.getType() == 2 && (item.getFlag() & ItemConstants.SPIKES) == ItemConstants.SPIKES)
|
||||
item.setFlag((byte) (item.getFlag() ^ ItemConstants.SPIKES));
|
||||
|
||||
MapleInventoryManipulator.addFromDrop(chr.getClient(), item, true);
|
||||
}
|
||||
if (exchangeMeso > 0) {
|
||||
chr.gainMeso(exchangeMeso - getFee(exchangeMeso), true, true, true);
|
||||
}
|
||||
exchangeMeso = 0;
|
||||
if (exchangeItems != null) {
|
||||
exchangeItems.clear();
|
||||
}
|
||||
chr.getClient().announce(MaplePacketCreator.getTradeCompletion(number));
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
for (Item item : items) {
|
||||
MapleInventoryManipulator.addFromDrop(chr.getClient(), item, true);
|
||||
}
|
||||
if (meso > 0) {
|
||||
chr.gainMeso(meso, true, true, true);
|
||||
}
|
||||
meso = 0;
|
||||
if (items != null) {
|
||||
items.clear();
|
||||
}
|
||||
exchangeMeso = 0;
|
||||
if (exchangeItems != null) {
|
||||
exchangeItems.clear();
|
||||
}
|
||||
chr.getClient().announce(MaplePacketCreator.getTradeCancel(number));
|
||||
}
|
||||
|
||||
private boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
private int getMeso() {
|
||||
return meso;
|
||||
}
|
||||
|
||||
public void setMeso(int meso) {
|
||||
if (locked) {
|
||||
throw new RuntimeException("Trade is locked.");
|
||||
}
|
||||
if (meso < 0) {
|
||||
System.out.println("[h4x] " + chr.getName() + " Trying to trade < 0 mesos");
|
||||
return;
|
||||
}
|
||||
if (chr.getMeso() >= meso) {
|
||||
chr.gainMeso(-meso, false, true, false);
|
||||
this.meso += meso;
|
||||
chr.getClient().announce(MaplePacketCreator.getTradeMesoSet((byte) 0, this.meso));
|
||||
if (partner != null) {
|
||||
partner.getChr().getClient().announce(MaplePacketCreator.getTradeMesoSet((byte) 1, this.meso));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
public void addItem(Item item) {
|
||||
items.add(item);
|
||||
chr.getClient().announce(MaplePacketCreator.getTradeItemAdd((byte) 0, item));
|
||||
if (partner != null) {
|
||||
partner.getChr().getClient().announce(MaplePacketCreator.getTradeItemAdd((byte) 1, item));
|
||||
}
|
||||
}
|
||||
|
||||
public void chat(String message) {
|
||||
chr.getClient().announce(MaplePacketCreator.getTradeChat(chr, message, true));
|
||||
if (partner != null) {
|
||||
partner.getChr().getClient().announce(MaplePacketCreator.getTradeChat(chr, message, false));
|
||||
}
|
||||
}
|
||||
|
||||
public MapleTrade getPartner() {
|
||||
return partner;
|
||||
}
|
||||
|
||||
public void setPartner(MapleTrade partner) {
|
||||
if (locked) {
|
||||
return;
|
||||
}
|
||||
this.partner = partner;
|
||||
}
|
||||
|
||||
public MapleCharacter getChr() {
|
||||
return chr;
|
||||
}
|
||||
|
||||
public List<Item> getItems() {
|
||||
return new LinkedList<>(items);
|
||||
}
|
||||
|
||||
public int getExchangeMesos(){
|
||||
return exchangeMeso;
|
||||
}
|
||||
|
||||
private boolean fitsInInventory() {
|
||||
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
|
||||
Map<MapleInventoryType, Integer> neededSlots = new LinkedHashMap<>();
|
||||
for (Item item : exchangeItems) {
|
||||
MapleInventoryType type = mii.getInventoryType(item.getItemId());
|
||||
if (neededSlots.get(type) == null) {
|
||||
neededSlots.put(type, 1);
|
||||
} else {
|
||||
neededSlots.put(type, neededSlots.get(type) + 1);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<MapleInventoryType, Integer> entry : neededSlots.entrySet()) {
|
||||
if (chr.getInventory(entry.getKey()).isFull(entry.getValue() - 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void completeTrade(MapleCharacter c) {
|
||||
c.getTrade().lock();
|
||||
MapleTrade local = c.getTrade();
|
||||
MapleTrade partner = local.getPartner();
|
||||
if (partner.isLocked()) {
|
||||
local.complete1();
|
||||
partner.complete1();
|
||||
if (!local.fitsInInventory() || !partner.fitsInInventory()) {
|
||||
cancelTrade(c);
|
||||
c.message("There is not enough inventory space to complete the trade.");
|
||||
partner.getChr().message("There is not enough inventory space to complete the trade.");
|
||||
return;
|
||||
}
|
||||
if (local.getChr().getLevel() < 15) {
|
||||
if (local.getChr().getMesosTraded() + local.exchangeMeso > 1000000) {
|
||||
cancelTrade(c);
|
||||
local.getChr().getClient().announce(MaplePacketCreator.serverNotice(1, "Characters under level 15 may not trade more than 1 million mesos per day."));
|
||||
return;
|
||||
} else {
|
||||
local.getChr().addMesosTraded(local.exchangeMeso);
|
||||
}
|
||||
} else if (c.getTrade().getChr().getLevel() < 15) {
|
||||
if (c.getMesosTraded() + c.getTrade().exchangeMeso > 1000000) {
|
||||
cancelTrade(c);
|
||||
c.getClient().announce(MaplePacketCreator.serverNotice(1, "Characters under level 15 may not trade more than 1 million mesos per day."));
|
||||
return;
|
||||
} else {
|
||||
c.addMesosTraded(local.exchangeMeso);
|
||||
}
|
||||
}
|
||||
LogHelper.logTrade(local, partner);
|
||||
local.complete2();
|
||||
partner.complete2();
|
||||
partner.getChr().setTrade(null);
|
||||
c.setTrade(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void cancelTrade(MapleCharacter c) {
|
||||
c.getTrade().cancel();
|
||||
if (c.getTrade().getPartner() != null) {
|
||||
c.getTrade().getPartner().cancel();
|
||||
c.getTrade().getPartner().getChr().setTrade(null);
|
||||
}
|
||||
c.setTrade(null);
|
||||
}
|
||||
|
||||
public static void startTrade(MapleCharacter c) {
|
||||
if (c.getTrade() == null) {
|
||||
c.setTrade(new MapleTrade((byte) 0, c));
|
||||
c.getClient().announce(MaplePacketCreator.getTradeStart(c.getClient(), c.getTrade(), (byte) 0));
|
||||
} else {
|
||||
c.message("You are already in a trade.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void inviteTrade(MapleCharacter c1, MapleCharacter c2) {
|
||||
if (c2.getTrade() == null) {
|
||||
c2.setTrade(new MapleTrade((byte) 1, c2));
|
||||
c2.getTrade().setPartner(c1.getTrade());
|
||||
c1.getTrade().setPartner(c2.getTrade());
|
||||
c2.getClient().announce(MaplePacketCreator.getTradeInvite(c1));
|
||||
} else {
|
||||
c1.message("The other player is already trading with someone else.");
|
||||
cancelTrade(c1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitTrade(MapleCharacter c1, MapleCharacter c2) {
|
||||
if (c1.getTrade() != null && c1.getTrade().getPartner() == c2.getTrade() && c2.getTrade() != null && c2.getTrade().getPartner() == c1.getTrade()) {
|
||||
c2.getClient().announce(MaplePacketCreator.getTradePartnerAdd(c1));
|
||||
c1.getClient().announce(MaplePacketCreator.getTradeStart(c1.getClient(), c1.getTrade(), (byte) 1));
|
||||
c1.getTrade().setFullTrade(true);
|
||||
c2.getTrade().setFullTrade(true);
|
||||
} else {
|
||||
c1.message("The other player has already closed the trade.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void declineTrade(MapleCharacter c) {
|
||||
MapleTrade trade = c.getTrade();
|
||||
if (trade != null) {
|
||||
if (trade.getPartner() != null) {
|
||||
MapleCharacter other = trade.getPartner().getChr();
|
||||
other.getTrade().cancel();
|
||||
other.setTrade(null);
|
||||
other.message(c.getName() + " has declined your trade request.");
|
||||
}
|
||||
trade.cancel();
|
||||
c.setTrade(null);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFullTrade() {
|
||||
return fullTrade;
|
||||
}
|
||||
|
||||
public void setFullTrade(boolean fullTrade) {
|
||||
this.fullTrade = fullTrade;
|
||||
}
|
||||
}
|
||||
68
src/server/PortalFactory.java
Normal file
68
src/server/PortalFactory.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataTool;
|
||||
import server.maps.MapleGenericPortal;
|
||||
import server.maps.MapleMapPortal;
|
||||
|
||||
public class PortalFactory {
|
||||
private int nextDoorPortal;
|
||||
|
||||
public PortalFactory() {
|
||||
nextDoorPortal = 0x80;
|
||||
}
|
||||
|
||||
public MaplePortal makePortal(int type, MapleData portal) {
|
||||
MapleGenericPortal ret = null;
|
||||
if (type == MaplePortal.MAP_PORTAL) {
|
||||
ret = new MapleMapPortal();
|
||||
} else {
|
||||
ret = new MapleGenericPortal(type);
|
||||
}
|
||||
loadPortal(ret, portal);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void loadPortal(MapleGenericPortal myPortal, MapleData portal) {
|
||||
myPortal.setName(MapleDataTool.getString(portal.getChildByPath("pn")));
|
||||
myPortal.setTarget(MapleDataTool.getString(portal.getChildByPath("tn")));
|
||||
myPortal.setTargetMapId(MapleDataTool.getInt(portal.getChildByPath("tm")));
|
||||
int x = MapleDataTool.getInt(portal.getChildByPath("x"));
|
||||
int y = MapleDataTool.getInt(portal.getChildByPath("y"));
|
||||
myPortal.setPosition(new Point(x, y));
|
||||
String script = MapleDataTool.getString("script", portal, null);
|
||||
if (script != null && script.equals("")) {
|
||||
script = null;
|
||||
}
|
||||
myPortal.setScriptName(script);
|
||||
if (myPortal.getType() == MaplePortal.DOOR_PORTAL) {
|
||||
myPortal.setId(nextDoorPortal);
|
||||
nextDoorPortal++;
|
||||
} else {
|
||||
myPortal.setId(Integer.parseInt(portal.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
149
src/server/TimerManager.java
Normal file
149
src/server/TimerManager.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import tools.FilePrinter;
|
||||
|
||||
public class TimerManager implements TimerManagerMBean {
|
||||
private static TimerManager instance = new TimerManager();
|
||||
private ScheduledThreadPoolExecutor ses;
|
||||
|
||||
private TimerManager() {
|
||||
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
try {
|
||||
mBeanServer.registerMBean(this, new ObjectName("server:type=TimerManger"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static TimerManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (ses != null && !ses.isShutdown() && !ses.isTerminated()) {
|
||||
return;
|
||||
}
|
||||
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(4, new ThreadFactory() {
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("TimerManager-Worker-" + threadNumber.getAndIncrement());
|
||||
return t;
|
||||
}
|
||||
});
|
||||
//this is a no-no, it actually does nothing..then why the fuck are you doing it?
|
||||
stpe.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
|
||||
stpe.setRemoveOnCancelPolicy(true);
|
||||
|
||||
stpe.setKeepAliveTime(5, TimeUnit.MINUTES);
|
||||
stpe.allowCoreThreadTimeOut(true);
|
||||
|
||||
ses = stpe;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
ses.shutdownNow();
|
||||
}
|
||||
|
||||
public Runnable purge() {//Yay?
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
ses.purge();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> register(Runnable r, long repeatTime, long delay) {
|
||||
return ses.scheduleAtFixedRate(new LoggingSaveRunnable(r), delay, repeatTime, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> register(Runnable r, long repeatTime) {
|
||||
return ses.scheduleAtFixedRate(new LoggingSaveRunnable(r), 0, repeatTime, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> schedule(Runnable r, long delay) {
|
||||
return ses.schedule(new LoggingSaveRunnable(r), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> scheduleAtTimestamp(Runnable r, long timestamp) {
|
||||
return schedule(r, timestamp - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getActiveCount() {
|
||||
return ses.getActiveCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCompletedTaskCount() {
|
||||
return ses.getCompletedTaskCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQueuedTasks() {
|
||||
return ses.getQueue().toArray().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTaskCount() {
|
||||
return ses.getTaskCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShutdown() {
|
||||
return ses.isShutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTerminated() {
|
||||
return ses.isTerminated();
|
||||
}
|
||||
|
||||
|
||||
private static class LoggingSaveRunnable implements Runnable {
|
||||
Runnable r;
|
||||
|
||||
public LoggingSaveRunnable(Runnable r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Throwable t) {
|
||||
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/server/TimerManagerMBean.java
Normal file
31
src/server/TimerManagerMBean.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server;
|
||||
|
||||
public interface TimerManagerMBean {
|
||||
public boolean isTerminated();
|
||||
public boolean isShutdown();
|
||||
public long getCompletedTaskCount();
|
||||
public long getActiveCount();
|
||||
public long getTaskCount();
|
||||
public int getQueuedTasks();
|
||||
}
|
||||
32
src/server/events/MapleEvents.java
Normal file
32
src/server/events/MapleEvents.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events;
|
||||
|
||||
/**
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleEvents {
|
||||
public MapleEvents() {
|
||||
|
||||
}
|
||||
}
|
||||
65
src/server/events/RescueGaga.java
Normal file
65
src/server/events/RescueGaga.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package server.events;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.SkillFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class RescueGaga extends MapleEvents {
|
||||
private byte fallen;
|
||||
private int completed;
|
||||
|
||||
public RescueGaga(int completed) {
|
||||
super();
|
||||
this.completed = completed;
|
||||
this.fallen = 0;
|
||||
}
|
||||
|
||||
public int fallAndGet() {
|
||||
fallen++;
|
||||
if (fallen > 3) {
|
||||
fallen = 0;
|
||||
return 4;
|
||||
}
|
||||
return fallen;
|
||||
}
|
||||
|
||||
public byte getFallen() {
|
||||
return fallen;
|
||||
}
|
||||
|
||||
public int getCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void complete() {
|
||||
completed++;
|
||||
}
|
||||
|
||||
public void giveSkill(MapleCharacter chr) {
|
||||
int skillid = 0;
|
||||
switch (chr.getJobType()) {
|
||||
case 0:
|
||||
skillid = 1013;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
skillid = 10001014;
|
||||
}
|
||||
long expiration = (System.currentTimeMillis() + (long) (3600 * 24 * 20 * 1000));//20 days
|
||||
if (completed < 20) {
|
||||
chr.changeSkillLevel(SkillFactory.getSkill(skillid), (byte) 1, 1, expiration);
|
||||
chr.changeSkillLevel(SkillFactory.getSkill(skillid + 1), (byte) 1, 1, expiration);
|
||||
chr.changeSkillLevel(SkillFactory.getSkill(skillid + 2), (byte) 1, 1, expiration);
|
||||
} else {
|
||||
chr.changeSkillLevel(SkillFactory.getSkill(skillid), (byte) 2, 2, chr.getSkillExpiration(skillid));
|
||||
}
|
||||
}
|
||||
}
|
||||
206
src/server/events/gm/MapleCoconut.java
Normal file
206
src/server/events/gm/MapleCoconut.java
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import server.TimerManager;
|
||||
import server.maps.MapleMap;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
//Make them better :)
|
||||
public class MapleCoconut extends MapleEvent {
|
||||
private MapleMap map = null;
|
||||
private int MapleScore = 0;
|
||||
private int StoryScore = 0;
|
||||
private int countBombing = 80;
|
||||
private int countFalling = 401;
|
||||
private int countStopped = 20;
|
||||
private List<MapleCoconuts> coconuts = new LinkedList<MapleCoconuts>();
|
||||
|
||||
public MapleCoconut(MapleMap map) {
|
||||
super(1, 50);
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public void startEvent() {
|
||||
map.startEvent();
|
||||
for (int i = 0; i < 506; i++) {
|
||||
coconuts.add(new MapleCoconuts(i));
|
||||
}
|
||||
map.broadcastMessage(MaplePacketCreator.hitCoconut(true, 0, 0));
|
||||
setCoconutsHittable(true);
|
||||
map.broadcastMessage(MaplePacketCreator.getClock(300));
|
||||
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (map.getId() == 109080000) {
|
||||
if (getMapleScore() == getStoryScore()) {
|
||||
bonusTime();
|
||||
} else if (getMapleScore() > getStoryScore()) {
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
if (chr.getTeam() == 0) {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/victory"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Victory"));
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/lose"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Failed"));
|
||||
}
|
||||
}
|
||||
warpOut();
|
||||
} else {
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
if (chr.getTeam() == 1) {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/victory"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Victory"));
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/lose"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Failed"));
|
||||
}
|
||||
}
|
||||
warpOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 300000);
|
||||
}
|
||||
|
||||
public void bonusTime() {
|
||||
map.broadcastMessage(MaplePacketCreator.getClock(120));
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (getMapleScore() == getStoryScore()) {
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/lose"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Failed"));
|
||||
}
|
||||
warpOut();
|
||||
} else if (getMapleScore() > getStoryScore()) {
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
if (chr.getTeam() == 0) {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/victory"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Victory"));
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/lose"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Failed"));
|
||||
}
|
||||
}
|
||||
warpOut();
|
||||
} else {
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
if (chr.getTeam() == 1) {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/victory"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Victory"));
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.showEffect("event/coconut/lose"));
|
||||
chr.getClient().announce(MaplePacketCreator.playSound("Coconut/Failed"));
|
||||
}
|
||||
}
|
||||
warpOut();
|
||||
}
|
||||
}
|
||||
}, 120000);
|
||||
|
||||
}
|
||||
|
||||
public void warpOut() {
|
||||
setCoconutsHittable(false);
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<MapleCharacter> chars = new ArrayList<>(map.getCharacters());
|
||||
|
||||
for (MapleCharacter chr : chars) {
|
||||
if ((getMapleScore() > getStoryScore() && chr.getTeam() == 0) || (getStoryScore() > getMapleScore() && chr.getTeam() == 1)) {
|
||||
chr.changeMap(109050000);
|
||||
} else {
|
||||
chr.changeMap(109050001);
|
||||
}
|
||||
}
|
||||
map.setCoconut(null);
|
||||
}
|
||||
}, 12000);
|
||||
}
|
||||
|
||||
public int getMapleScore() {
|
||||
return MapleScore;
|
||||
}
|
||||
|
||||
public int getStoryScore() {
|
||||
return StoryScore;
|
||||
}
|
||||
|
||||
public void addMapleScore() {
|
||||
this.MapleScore += 1;
|
||||
}
|
||||
|
||||
public void addStoryScore() {
|
||||
this.StoryScore += 1;
|
||||
}
|
||||
|
||||
public int getBombings() {
|
||||
return countBombing;
|
||||
}
|
||||
|
||||
public void bombCoconut() {
|
||||
countBombing--;
|
||||
}
|
||||
|
||||
public int getFalling() {
|
||||
return countFalling;
|
||||
}
|
||||
|
||||
public void fallCoconut() {
|
||||
countFalling--;
|
||||
}
|
||||
|
||||
public int getStopped() {
|
||||
return countStopped;
|
||||
}
|
||||
|
||||
public void stopCoconut() {
|
||||
countStopped--;
|
||||
}
|
||||
|
||||
public MapleCoconuts getCoconut(int id) {
|
||||
return coconuts.get(id);
|
||||
}
|
||||
|
||||
public List<MapleCoconuts> getAllCoconuts() {
|
||||
return coconuts;
|
||||
}
|
||||
|
||||
public void setCoconutsHittable(boolean hittable) {
|
||||
for (MapleCoconuts nut : coconuts) {
|
||||
nut.setHittable(hittable);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/server/events/gm/MapleCoconuts.java
Normal file
63
src/server/events/gm/MapleCoconuts.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleCoconuts {
|
||||
|
||||
private int id;
|
||||
private int hits = 0;
|
||||
private boolean hittable = false;
|
||||
private long hittime = System.currentTimeMillis();
|
||||
|
||||
public MapleCoconuts(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void hit() {
|
||||
this.hittime = System.currentTimeMillis() + 750;
|
||||
hits++;
|
||||
}
|
||||
|
||||
public int getHits() {
|
||||
return hits;
|
||||
}
|
||||
|
||||
public void resetHits() {
|
||||
hits = 0;
|
||||
}
|
||||
|
||||
public boolean isHittable() {
|
||||
return hittable;
|
||||
}
|
||||
|
||||
public void setHittable(boolean hittable) {
|
||||
this.hittable = hittable;
|
||||
}
|
||||
|
||||
public long getHitTime() {
|
||||
return hittime;
|
||||
}
|
||||
}
|
||||
53
src/server/events/gm/MapleEvent.java
Normal file
53
src/server/events/gm/MapleEvent.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleEvent {
|
||||
private int mapid;
|
||||
private int limit;
|
||||
|
||||
public MapleEvent(int mapid, int limit) {
|
||||
this.mapid = mapid;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public int getMapId() {
|
||||
return mapid;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void minusLimit() {
|
||||
this.limit--;
|
||||
}
|
||||
|
||||
public void addLimit() {
|
||||
this.limit++;
|
||||
}
|
||||
}
|
||||
133
src/server/events/gm/MapleFitness.java
Normal file
133
src/server/events/gm/MapleFitness.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleFitness {
|
||||
private MapleCharacter chr;
|
||||
private long time = 0;
|
||||
private long timeStarted = 0;
|
||||
private ScheduledFuture<?> schedule = null;
|
||||
private ScheduledFuture<?> schedulemsg = null;
|
||||
|
||||
public MapleFitness(final MapleCharacter chr) {
|
||||
this.chr = chr;
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (chr.getMapId() >= 109040000 && chr.getMapId() <= 109040004)
|
||||
chr.changeMap(chr.getMap().getReturnMap());
|
||||
}
|
||||
}, 900000);
|
||||
}
|
||||
|
||||
public void startFitness() {
|
||||
chr.getMap().startEvent();
|
||||
chr.getClient().announce(MaplePacketCreator.getClock(900));
|
||||
this.timeStarted = System.currentTimeMillis();
|
||||
this.time = 900000;
|
||||
checkAndMessage();
|
||||
|
||||
chr.getMap().getPortal("join00").setPortalStatus(true);
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The portal has now opened. Press the up arrow key at the portal to enter."));
|
||||
}
|
||||
|
||||
public boolean isTimerStarted() {
|
||||
return time > 0 && timeStarted > 0;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void resetTimes() {
|
||||
this.time = 0;
|
||||
this.timeStarted = 0;
|
||||
schedule.cancel(false);
|
||||
schedulemsg.cancel(false);
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return time - (System.currentTimeMillis() - timeStarted);
|
||||
}
|
||||
|
||||
public void checkAndMessage() {
|
||||
this.schedulemsg = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (chr.getFitness() == null) {
|
||||
resetTimes();
|
||||
}
|
||||
if (chr.getMap().getId() >= 109040000 && chr.getMap().getId() <= 109040004) {
|
||||
if (getTimeLeft() > 9000 && getTimeLeft() < 11000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "You have 10 sec left. Those of you unable to beat the game, we hope you beat it next time! Great job everyone!! See you later~"));
|
||||
} else if (getTimeLeft() > 99000 && getTimeLeft() < 101000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "Alright, you don't have much time remaining. Please hurry up a little!"));
|
||||
} else if (getTimeLeft() > 239000 && getTimeLeft() < 241000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The 4th stage is the last one for [The Maple Physical Fitness Test]. Please don't give up at the last minute and try your best. The reward is waiting for you at the very top!"));
|
||||
} else if (getTimeLeft() > 299000 && getTimeLeft() < 301000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The 3rd stage offers traps where you may see them, but you won't be able to step on them. Please be careful of them as you make your way up."));
|
||||
} else if (getTimeLeft() > 359000 && getTimeLeft() < 361000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "For those who have heavy lags, please make sure to move slowly to avoid falling all the way down because of lags."));
|
||||
} else if (getTimeLeft() > 499000 && getTimeLeft() < 501000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "Please remember that if you die during the event, you'll be eliminated from the game. If you're running out of HP, either take a potion or recover HP first before moving on."));
|
||||
} else if (getTimeLeft() > 599000 && getTimeLeft() < 601000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The most important thing you'll need to know to avoid the bananas thrown by the monkeys is *Timing* Timing is everything in this!"));
|
||||
} else if (getTimeLeft() > 659000 && getTimeLeft() < 661000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The 2nd stage offers monkeys throwing bananas. Please make sure to avoid them by moving along at just the right timing."));
|
||||
} else if (getTimeLeft() > 699000 && getTimeLeft() < 701000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "Please remember that if you die during the event, you'll be eliminated from the game. You still have plenty of time left, so either take a potion or recover HP first before moving on."));
|
||||
} else if (getTimeLeft() > 779000 && getTimeLeft() < 781000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "Everyone that clears [The Maple Physical Fitness Test] on time will be given an item, regardless of the order of finish, so just relax, take your time, and clear the 4 stages."));
|
||||
} else if (getTimeLeft() > 839000 && getTimeLeft() < 841000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "There may be a heavy lag due to many users at stage 1 all at once. It won't be difficult, so please make sure not to fall down because of heavy lag."));
|
||||
} else if (getTimeLeft() > 869000 && getTimeLeft() < 871000) {
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "[MapleStory Physical Fitness Test] consists of 4 stages, and if you happen to die during the game, you'll be eliminated from the game, so please be careful of that."));
|
||||
}
|
||||
} else {
|
||||
resetTimes();
|
||||
}
|
||||
}
|
||||
}, 5000, 29500);
|
||||
}
|
||||
// 14:30 [Notice][MapleStory Physical Fitness Test] consists of 4 stages, and if you happen to die during the game, you'll be eliminated from the game, so please be careful of that.
|
||||
// 14:00 [Notice]There may be a heavy lag due to many users at stage 1 all at once. It won't be difficult, so please make sure not to fall down because of heavy lag.
|
||||
// 13:00 [Notice]Everyone that clears [The Maple Physical Fitness Test] on time will be given an item, regardless of the order of finish, so just relax, take your time, and clear the 4 stages.
|
||||
// 11:40 [Notice]Please remember that if you die during the event, you'll be eliminated from the game. You still have plenty of time left, so either take a potion or recover HP first before moving on.
|
||||
// 11:00 [Notice]The 2nd stage offers monkeys throwing bananas. Please make sure to avoid them by moving along at just the right timing.
|
||||
// 10:00 [Notice]The most important thing you'll need to know to avoid the bananas thrown by the monkeys is *Timing* Timing is everything in this!
|
||||
// 8:20 [Notice]Please remember that if you die during the event, you'll be eliminated from the game. If you're running out of HP, either take a potion or recover HP first before moving on.
|
||||
// 6:00 [Notice]For those who have heavy lags, please make sure to move slowly to avoid falling all the way down because of lags.
|
||||
// 5:00 [Notice]The 3rd stage offers traps where you may see them, but you won't be able to step on them. Please be careful of them as you make your way up.
|
||||
// 4:00 [Notice]The 4th stage is the last one for [The Maple Physical Fitness Test]. Please don't give up at the last minute and try your best. The reward is waiting for you at the very top!
|
||||
// 1:40 [Notice]Alright, you don't have much time remaining. Please hurry up a little!
|
||||
// 0:10 [Notice]You have 10 sec left. Those of you unable to beat the game, we hope you beat it next time! Great job everyone!! See you later~
|
||||
}
|
||||
78
src/server/events/gm/MapleOla.java
Normal file
78
src/server/events/gm/MapleOla.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleOla {
|
||||
private MapleCharacter chr;
|
||||
private long time = 0;
|
||||
private long timeStarted = 0;
|
||||
private ScheduledFuture<?> schedule = null;
|
||||
|
||||
public MapleOla(final MapleCharacter chr) {
|
||||
this.chr = chr;
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (chr.getMapId() >= 109030001 && chr.getMapId() <= 109030303)
|
||||
chr.changeMap(chr.getMap().getReturnMap());
|
||||
resetTimes();
|
||||
}
|
||||
}, 360000);
|
||||
}
|
||||
|
||||
public void startOla() { // TODO: Messages
|
||||
chr.getMap().startEvent();
|
||||
chr.getClient().announce(MaplePacketCreator.getClock(360));
|
||||
this.timeStarted = System.currentTimeMillis();
|
||||
this.time = 360000;
|
||||
|
||||
chr.getMap().getPortal("join00").setPortalStatus(true);
|
||||
chr.getClient().announce(MaplePacketCreator.serverNotice(0, "The portal has now opened. Press the up arrow key at the portal to enter."));
|
||||
}
|
||||
|
||||
public boolean isTimerStarted() {
|
||||
return time > 0 && timeStarted > 0;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void resetTimes() {
|
||||
this.time = 0;
|
||||
this.timeStarted = 0;
|
||||
schedule.cancel(false);
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return time - (System.currentTimeMillis() - timeStarted);
|
||||
}
|
||||
}
|
||||
111
src/server/events/gm/MapleOxQuiz.java
Normal file
111
src/server/events/gm/MapleOxQuiz.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import tools.Randomizer;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import server.TimerManager;
|
||||
import server.maps.MapleMap;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author FloppyDisk
|
||||
*/
|
||||
public final class MapleOxQuiz {
|
||||
private int round = 1;
|
||||
private int question = 1;
|
||||
private MapleMap map = null;
|
||||
private int expGain = 200;
|
||||
private static MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Etc.wz"));
|
||||
|
||||
public MapleOxQuiz(MapleMap map) {
|
||||
this.map = map;
|
||||
this.round = Randomizer.nextInt(9);
|
||||
this.question = 1;
|
||||
}
|
||||
|
||||
private boolean isCorrectAnswer(MapleCharacter chr, int answer) {
|
||||
double x = chr.getPosition().getX();
|
||||
double y = chr.getPosition().getY();
|
||||
if ((x > -234 && y > -26 && answer == 0) || (x < -234 && y > -26 && answer == 1)) {
|
||||
chr.dropMessage("Correct!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendQuestion() {
|
||||
int gm = 0;
|
||||
for (MapleCharacter mc : map.getCharacters()) {
|
||||
if (mc.gmLevel() > 0) {
|
||||
gm++;
|
||||
}
|
||||
}
|
||||
final int number = gm;
|
||||
map.broadcastMessage(MaplePacketCreator.showOXQuiz(round, question, true));
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
map.broadcastMessage(MaplePacketCreator.showOXQuiz(round, question, true));
|
||||
List<MapleCharacter> chars = new ArrayList<>(map.getCharacters());
|
||||
|
||||
for (MapleCharacter chr : chars) {
|
||||
if (chr != null) // make sure they aren't null... maybe something can happen in 12 seconds.
|
||||
{
|
||||
if (!isCorrectAnswer(chr, getOXAnswer(round, question)) && !chr.isGM()) {
|
||||
chr.changeMap(chr.getMap().getReturnMap());
|
||||
} else {
|
||||
chr.gainExp(expGain, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
//do question
|
||||
if ((round == 1 && question == 29) || ((round == 2 || round == 3) && question == 17) || ((round == 4 || round == 8) && question == 12) || (round == 5 && question == 26) || (round == 9 && question == 44) || ((round == 6 || round == 7) && question == 16)) {
|
||||
question = 100;
|
||||
} else {
|
||||
question++;
|
||||
}
|
||||
//send question
|
||||
if (map.getCharacters().size() - number <= 2) {
|
||||
map.broadcastMessage(MaplePacketCreator.serverNotice(6, "The event has ended"));
|
||||
map.getPortal("join00").setPortalStatus(true);
|
||||
map.setOx(null);
|
||||
map.setOxQuiz(false);
|
||||
//prizes here
|
||||
return;
|
||||
}
|
||||
sendQuestion();
|
||||
}
|
||||
}, 30000); // Time to answer = 30 seconds ( Ox Quiz packet shows a 30 second timer.
|
||||
}
|
||||
|
||||
private static int getOXAnswer(int imgdir, int id) {
|
||||
return MapleDataTool.getInt(stringData.getData("OXQuiz.img").getChildByPath("" + imgdir + "").getChildByPath("" + id + "").getChildByPath("a"));
|
||||
}
|
||||
}
|
||||
165
src/server/events/gm/MapleSnowball.java
Normal file
165
src/server/events/gm/MapleSnowball.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.events.gm;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import server.TimerManager;
|
||||
import server.maps.MapleMap;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public class MapleSnowball {
|
||||
private MapleMap map;
|
||||
private int position = 0;
|
||||
private int hits = 3;
|
||||
private int snowmanhp = 1000;
|
||||
private boolean hittable = false;
|
||||
private int team;
|
||||
private boolean winner = false;
|
||||
List<MapleCharacter> characters = new LinkedList<MapleCharacter>();
|
||||
|
||||
public MapleSnowball(int team, MapleMap map) {
|
||||
this.map = map;
|
||||
this.team = team;
|
||||
|
||||
for (MapleCharacter chr : map.getCharacters()) {
|
||||
if (chr.getTeam() == team)
|
||||
characters.add(chr);
|
||||
}
|
||||
}
|
||||
|
||||
public void startEvent() {
|
||||
if (hittable == true) return;
|
||||
|
||||
for (MapleCharacter chr : characters) {
|
||||
if (chr != null) {
|
||||
chr.announce(MaplePacketCreator.rollSnowBall(false, 1, map.getSnowball(0), map.getSnowball(1)));
|
||||
chr.announce(MaplePacketCreator.getClock(600));
|
||||
}
|
||||
}
|
||||
hittable = true;
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (map.getSnowball(team).getPosition() > map.getSnowball(team == 0 ? 1 : 0).getPosition()) {
|
||||
for (MapleCharacter chr : characters) {
|
||||
if (chr != null)
|
||||
chr.announce(MaplePacketCreator.rollSnowBall(false, 3, map.getSnowball(0), map.getSnowball(0)));
|
||||
}
|
||||
winner = true;
|
||||
} else if (map.getSnowball(team == 0 ? 1 : 0).getPosition() > map.getSnowball(team).getPosition()) {
|
||||
for (MapleCharacter chr : characters) {
|
||||
if (chr != null)
|
||||
chr.announce(MaplePacketCreator.rollSnowBall(false, 4, map.getSnowball(0), map.getSnowball(0)));
|
||||
}
|
||||
winner = true;
|
||||
} //Else
|
||||
warpOut();
|
||||
}
|
||||
}, 600000);
|
||||
|
||||
}
|
||||
|
||||
public boolean isHittable() {
|
||||
return hittable;
|
||||
}
|
||||
|
||||
public void setHittable(boolean hit) {
|
||||
this.hittable = hit;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public int getSnowmanHP() {
|
||||
return snowmanhp;
|
||||
}
|
||||
|
||||
public void setSnowmanHP(int hp) {
|
||||
this.snowmanhp = hp;
|
||||
}
|
||||
|
||||
public void hit(int what, int damage) {
|
||||
if (what < 2)
|
||||
if (damage > 0)
|
||||
this.hits--;
|
||||
else {
|
||||
if (this.snowmanhp - damage < 0) {
|
||||
this.snowmanhp = 0;
|
||||
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setSnowmanHP(7500);
|
||||
message(5);
|
||||
}
|
||||
}, 10000);
|
||||
} else
|
||||
this.snowmanhp -= damage;
|
||||
map.broadcastMessage(MaplePacketCreator.rollSnowBall(false, 1, map.getSnowball(0), map.getSnowball(1)));
|
||||
}
|
||||
|
||||
if (this.hits == 0) {
|
||||
this.position += 1;
|
||||
if (this.position == 45)
|
||||
map.getSnowball(team == 0 ? 1 : 0).message(1);
|
||||
else if (this.position == 290)
|
||||
map.getSnowball(team == 0 ? 1 : 0).message(2);
|
||||
else if (this.position == 560)
|
||||
map.getSnowball(team == 0 ? 1 : 0).message(3);
|
||||
|
||||
this.hits = 3;
|
||||
map.broadcastMessage(MaplePacketCreator.rollSnowBall(false, 0, map.getSnowball(0), map.getSnowball(1)));
|
||||
map.broadcastMessage(MaplePacketCreator.rollSnowBall(false, 1, map.getSnowball(0), map.getSnowball(1)));
|
||||
}
|
||||
map.broadcastMessage(MaplePacketCreator.hitSnowBall(what, damage));
|
||||
}
|
||||
|
||||
public void message(int message) {
|
||||
for (MapleCharacter chr : characters) {
|
||||
if (chr != null)
|
||||
chr.announce(MaplePacketCreator.snowballMessage(team, message));
|
||||
}
|
||||
}
|
||||
|
||||
public void warpOut() {
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (winner == true)
|
||||
map.warpOutByTeam(team, 109050000);
|
||||
else
|
||||
map.warpOutByTeam(team, 109050001);
|
||||
|
||||
map.setSnowball(team, null);
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
}
|
||||
218
src/server/expeditions/MapleExpedition.java
Normal file
218
src/server/expeditions/MapleExpedition.java
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.expeditions;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import net.server.Server;
|
||||
import server.TimerManager;
|
||||
import server.life.MapleMonster;
|
||||
import server.maps.MapleMap;
|
||||
import tools.LogHelper;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
public class MapleExpedition {
|
||||
|
||||
private static final int [] EXPEDITION_BOSSES = {
|
||||
8800000,// - Zakum's first body
|
||||
8800001,// - Zakum's second body
|
||||
8800002,// - Zakum's third body
|
||||
8800003,// - Zakum's Arm 1
|
||||
8800004,// - Zakum's Arm 2
|
||||
8800005,// - Zakum's Arm 3
|
||||
8800006,// - Zakum's Arm 4
|
||||
8800007,// - Zakum's Arm 5
|
||||
8800008,// - Zakum's Arm 6
|
||||
8800009,// - Zakum's Arm 7
|
||||
8800010,// - Zakum's Arm 8
|
||||
8810000,// - Horntail's Left Head
|
||||
8810001,// - Horntail's Right Head
|
||||
8810002,// - Horntail's Head A
|
||||
8810003,// - Horntail's Head B
|
||||
8810004,// - Horntail's Head C
|
||||
8810005,// - Horntail's Left Hand
|
||||
8810006,// - Horntail's Right Hand
|
||||
8810007,// - Horntail's Wings
|
||||
8810008,// - Horntail's Legs
|
||||
8810009,// - Horntail's Tails
|
||||
9420546,// - Scarlion Boss
|
||||
9420547,// - Scarlion Boss
|
||||
9420548,// - Angry Scarlion Boss
|
||||
9420549,// - Furious Scarlion Boss
|
||||
9420541,// - Targa
|
||||
9420542,// - Targa
|
||||
9420543,// - Angry Targa
|
||||
9420544,// - Furious Targa
|
||||
};
|
||||
|
||||
private MapleCharacter leader;
|
||||
private MapleExpeditionType type;
|
||||
private boolean registering;
|
||||
private MapleMap startMap;
|
||||
private ArrayList<String> bossLogs;
|
||||
private ScheduledFuture<?> schedule;
|
||||
private List<MapleCharacter> members = new ArrayList<MapleCharacter>();
|
||||
private List<MapleCharacter> banned = new ArrayList<MapleCharacter>();
|
||||
private long startTime;
|
||||
|
||||
public MapleExpedition(MapleCharacter player, MapleExpeditionType met) {
|
||||
leader = player;
|
||||
members.add(leader);
|
||||
startMap = player.getMap();
|
||||
type = met;
|
||||
bossLogs = new ArrayList<String>();
|
||||
beginRegistration();
|
||||
}
|
||||
|
||||
private void beginRegistration() {
|
||||
registering = true;
|
||||
startMap.broadcastMessage(MaplePacketCreator.getClock(type.getRegistrationTime() * 60));
|
||||
startMap.broadcastMessage(MaplePacketCreator.serverNotice(6, leader.getName() + " has been declared the expedition captain. Please register for the expedition."));
|
||||
scheduleRegistrationEnd();
|
||||
}
|
||||
|
||||
private void scheduleRegistrationEnd() {
|
||||
final MapleExpedition exped = this;
|
||||
schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (registering){
|
||||
leader.getClient().getChannelServer().getExpeditions().remove(exped);
|
||||
startMap.broadcastMessage(MaplePacketCreator.serverNotice(6, "Time limit has been reached. Expedition has been disbanded."));
|
||||
}
|
||||
dispose(false);
|
||||
}
|
||||
}, type.getRegistrationTime() * 60 * 1000);
|
||||
}
|
||||
|
||||
public void dispose(boolean log){
|
||||
if (schedule != null){
|
||||
schedule.cancel(false);
|
||||
}
|
||||
if (log && !registering){
|
||||
LogHelper.logExpedition(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void start(){
|
||||
registering = false;
|
||||
startMap.broadcastMessage(MaplePacketCreator.removeClock());
|
||||
broadcastExped(MaplePacketCreator.serverNotice(6, "The expedition has started! The expedition leader is waiting inside!"));
|
||||
startTime = System.currentTimeMillis();
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.serverNotice(6, type.toString() + " Expedition started with leader: " + leader.getName()));
|
||||
}
|
||||
|
||||
public String addMember(MapleCharacter player) {
|
||||
if (!registering){
|
||||
return "Sorry, this expedition is already underway. Registration is closed!";
|
||||
}
|
||||
if (banned.contains(player)){
|
||||
return "Sorry, you've been banned from this expedition by #b" + leader.getName() + "#k.";
|
||||
}
|
||||
if (members.size() >= type.getMaxSize()){ //Would be a miracle if anybody ever saw this
|
||||
return "Sorry, this expedition is full!";
|
||||
}
|
||||
if (members.add(player)){
|
||||
broadcastExped(MaplePacketCreator.serverNotice(6, player.getName() + " has joined the expedition!"));
|
||||
return "You have registered for the expedition successfully!";
|
||||
}
|
||||
return "Sorry, something went really wrong. Report this on the forum with a screenshot!";
|
||||
}
|
||||
|
||||
private void broadcastExped(byte [] data){
|
||||
for (MapleCharacter member : members){
|
||||
member.getClient().announce(data);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeMember(MapleCharacter chr) {
|
||||
return members.remove(chr);
|
||||
}
|
||||
|
||||
public MapleExpeditionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<MapleCharacter> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
public MapleCharacter getLeader(){
|
||||
return leader;
|
||||
}
|
||||
|
||||
public boolean contains(MapleCharacter player) {
|
||||
for (MapleCharacter member : members){
|
||||
if (member.getId() == player.getId()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isLeader(MapleCharacter player) {
|
||||
return leader.equals(player);
|
||||
}
|
||||
|
||||
public boolean isRegistering(){
|
||||
return registering;
|
||||
}
|
||||
|
||||
public boolean isInProgress(){
|
||||
return !registering;
|
||||
}
|
||||
|
||||
public void ban(MapleCharacter player) {
|
||||
if (!banned.contains(player)) {
|
||||
banned.add(player);
|
||||
members.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
public long getStartTime(){
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public ArrayList<String> getBossLogs(){
|
||||
return bossLogs;
|
||||
}
|
||||
|
||||
public void monsterKilled(MapleCharacter chr, MapleMonster mob) {
|
||||
for (int i = 0; i < EXPEDITION_BOSSES.length; i++){
|
||||
if (mob.getId() == EXPEDITION_BOSSES[i]){ //If the monster killed was a boss
|
||||
String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date());
|
||||
bossLogs.add(">" + mob.getName() + " was killed after " + LogHelper.getTimeString(startTime) + " - " + timeStamp + "\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/server/expeditions/MapleExpeditionType.java
Normal file
75
src/server/expeditions/MapleExpeditionType.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.expeditions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public enum MapleExpeditionType {
|
||||
|
||||
BALROG_EASY(3, 30, 50, 255, 5),
|
||||
BALROG_NORMAL(6, 30, 50, 255, 5),
|
||||
SCARGA(3, 6, 100, 255, 5),
|
||||
ZAKUM(6, 30, 50, 255, 5),
|
||||
HORNTAIL(6, 30, 80, 255,5),
|
||||
CHAOS_ZAKUM(6, 30, 120, 255, 5),
|
||||
CHAOS_HORNTAIL(6, 30, 120, 255, 5),
|
||||
PINKBEAN(6, 30, 120, 255, 5),
|
||||
CWKPQ(6, 30, 100, 255, 5);
|
||||
|
||||
private int minSize;
|
||||
private int maxSize;
|
||||
private int minLevel;
|
||||
private int maxLevel;
|
||||
private int registrationTime;
|
||||
|
||||
private MapleExpeditionType(int minSize, int maxSize, int minLevel, int maxLevel, int minutes) {
|
||||
this.minSize = minSize;
|
||||
this.maxSize = maxSize;
|
||||
this.minLevel = minLevel;
|
||||
this.maxLevel = maxLevel;
|
||||
this.registrationTime = minutes;
|
||||
}
|
||||
|
||||
public int getMinSize() {
|
||||
return minSize;
|
||||
}
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
public int getMinLevel() {
|
||||
return minLevel;
|
||||
}
|
||||
|
||||
public int getMaxLevel() {
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
public int getRegistrationTime(){
|
||||
return registrationTime;
|
||||
}
|
||||
}
|
||||
104
src/server/gachapon/Ellinia.java
Normal file
104
src/server/gachapon/Ellinia.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class Ellinia extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int[] {
|
||||
//warriorEquips = {
|
||||
1082025, 1060028, 1051011, 1060016, 1051001,
|
||||
1422001, 1002025, 1082000, 1302002, 1412012,
|
||||
//magicianEquips = {
|
||||
1002013, 1002016, 1002017, 1002034, 1002035,
|
||||
1002036, 1002037, 1002038, 1002064, 1002065,
|
||||
1002072, 1002073, 1002074, 1002075, 1002102,
|
||||
1002103, 1002104, 1002105, 1002106, 1002141,
|
||||
1002142, 1002143, 1002144, 1002145, 1002151,
|
||||
1002152, 1002153, 1002154, 1002155, 1002215,
|
||||
1002216, 1002217, 1002218, 1002242, 1002243,
|
||||
1002244, 1002245, 1002246, 1002252, 1002253,
|
||||
1002254, 1002271, 1002272, 1002273, 1002274,
|
||||
1002363, 1002364, 1002365, 1002366, 1002398,
|
||||
1002399, 1002400, 1002401, 1002579, 1002773,
|
||||
1040004, 1040017, 1040018,
|
||||
1040019, 1040020, 1041015, 1041016, 1041017,
|
||||
1041018, 1041025, 1041026, 1041029, 1041030,
|
||||
1041031, 1041041, 1041042, 1041043, 1041051,
|
||||
1041052, 1041053, 1050001, 1050002, 1050003,
|
||||
1050008, 1050009, 1050010, 1050023, 1050024,
|
||||
1050025, 1050026, 1050027, 1050028, 1050029,
|
||||
1050030, 1050031, 1050035, 1050036, 1050037,
|
||||
1050038, 1050039, 1050045, 1050046, 1050047,
|
||||
1050048, 1050049, 1050053, 1050054, 1050055,
|
||||
1050056, 1050067, 1050068, 1050069, 1050070,
|
||||
1050072, 1050073, 1050074, 1050092, 1050093,
|
||||
1050094, 1050095, 1050102, 1050103, 1050104,
|
||||
1050105, 1051003, 1051004, 1051005, 1051023,
|
||||
1051024, 1051025, 1051026, 1051027, 1051030,
|
||||
1051031, 1051032, 1051033, 1051034, 1051044,
|
||||
1051045, 1051046, 1051047, 1051052, 1051053,
|
||||
1051054, 1051055, 1051056, 1051057, 1051058,
|
||||
1051094, 1051095, 1051096, 1051097, 1051101,
|
||||
1051102, 1051103, 1051104, 1052076,
|
||||
1060012, 1060013, 1060014, 1060015,
|
||||
1061010, 1061011, 1061012, 1061013, 1061021,
|
||||
1061022, 1061027, 1061028, 1061034, 1061035,
|
||||
1061036, 1061047, 1061048, 1061049, 1072006,
|
||||
1072019, 1072020, 1072021, 1072023, 1072024,
|
||||
1072044, 1072045, 1072072, 1072073, 1072074,
|
||||
1072075, 1072076, 1072077, 1072078, 1072089,
|
||||
1072090, 1072091, 1072114, 1072115, 1072116,
|
||||
1072117, 1072136, 1072137, 1072138, 1072139,
|
||||
1072140, 1072141, 1072142, 1072143, 1072157,
|
||||
1072158, 1072159, 1072160, 1072169, 1072177,
|
||||
1072178, 1072179, 1072206, 1072207, 1072208,
|
||||
1072209, 1072223, 1072224, 1072225, 1072226,
|
||||
1072268, 1082019, 1082020,
|
||||
1082021, 1082022, 1082026, 1082027, 1082028,
|
||||
1082051, 1082052, 1082053, 1082054, 1082055,
|
||||
1082056, 1082062, 1082063, 1082064, 1082080,
|
||||
1082081, 1082082, 1082086, 1082087, 1082088,
|
||||
1082098, 1082099, 1082100, 1082121, 1082122,
|
||||
1082123, 1082131, 1082132, 1082133, 1082134,
|
||||
1082151, 1082152, 1082153, 1082154, 1082164,
|
||||
1092021, 1092029, 1092057,
|
||||
1372000, 1372001, 1372002, 1372003, 1372004,
|
||||
1372007, 1372008, 1372009, 1372010, 1372011,
|
||||
1372012, 1372014, 1372015, 1372016, 1372032,
|
||||
1382000, 1382001, 1382002, 1382003, 1382004,
|
||||
1382005, 1382006, 1382007, 1382008, 1382010,
|
||||
1382011, 1382014, 1382015, 1382016, 1382017,
|
||||
1382018, 1382019, 1382035, 1382036, 1382037,
|
||||
1382041, 1382053, 1382054, 1382055, 1382056,
|
||||
1382060,
|
||||
//bowmanEquips = {
|
||||
1040003, 1462005, 1002157, 1002119, 1062002,
|
||||
1062004, 1041083, 1061082, 1082017, 1041061,
|
||||
//thiefEquips = {
|
||||
1002174, 1040063, 1072108, 1082044, 1061071,
|
||||
1060052, 1072029, 1472002, 1082031, 1060023,
|
||||
//pirateEquips = {
|
||||
1002625, 1002616, 1482005, 1052098, 1482003,
|
||||
1482001, 1492004, 1002622, 1492005, 1082195,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int [] { 1372035, 1372036, 1372037, 1372038, 1372039,
|
||||
1372040, 1372041, 1372042, 1382045, 1382046,
|
||||
1382047, 1382048, 1382049, 1382050, 1382051,
|
||||
1382052, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {1382059, 1382057, 1072362, 1002791, 1052161, 1082240};
|
||||
}
|
||||
|
||||
}
|
||||
47
src/server/gachapon/GachaponItems.java
Normal file
47
src/server/gachapon/GachaponItems.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public abstract class GachaponItems {
|
||||
|
||||
public abstract int [] getCommonItems();
|
||||
public abstract int [] getUncommonItems();
|
||||
public abstract int [] getRareItems();
|
||||
|
||||
public int[] getItems(int tier) {
|
||||
if (tier == 0){
|
||||
return getCommonItems();
|
||||
} else if (tier == 1){
|
||||
return getUncommonItems();
|
||||
} else if (tier == 2){
|
||||
return getRareItems();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
60
src/server/gachapon/Global.java
Normal file
60
src/server/gachapon/Global.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class Global extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int[] {
|
||||
/* Gloves */ 1082002, 1082147, 1082148, 1082146, 1082145, 1082150,
|
||||
/* Capes */ 1102040, 1102043, 1102087, 1102079, 1102080, 1102081, 1102082, 1102083, 1102053, 1102054,
|
||||
1102055, 1102056, 1102176, 1102177, 1102178, 1102179, 1102000, 1102001, 1102002, 1102003,
|
||||
1102004, 1102011, 1102012, 1102013, 1102014, 1102015, 1102016, 1102017, 1102018, 1102021,
|
||||
1102022, 1102023, 1102024, 1102026, 1102027, 1102028,
|
||||
/* Tube Eqp */ 1322026, 1322025, 1322024, 1322022, 1322021,
|
||||
/* Umbrellas */ 1302026, 1302027, 1302028, 1302017,
|
||||
/* Snowboards */ 1442017, 1442016, 1442014, 1442012,
|
||||
/* Skis */ 1432017, 1432016, 1432015,
|
||||
/* Beginner Eqp */ 1442018, 1422011,
|
||||
/* Potions */ 2000004, 2000005, 2001002, 2001001, 2020012, 2020013, 2020014, 2020015, 2022182, 2022245,
|
||||
2022284, 2022285, 2022439,
|
||||
/* Other Scrolls */ 2049000, 2049001, 2049002, 2041058, 2040727,
|
||||
/* 10% Scrolls */ 2041002, 2040402, 2040702, 2040805, 2040026, 2040031, 2040318, 2040323, 2040328, 2040419,
|
||||
2040422, 2040427, 2040534, 2040619, 2040622, 2040627, 2040825, 2040925, 2040928, 2040933,
|
||||
2040016,
|
||||
/* 60% Scrolls */ 2040001, 2040321, 2040425, 2040625, 2040931, 2048013, 2040025, 2040326, 2040532, 2040824,
|
||||
2048010, 2040029, 2040418, 2040618, 2040924, 2048011, 2040317, 2040421, 2040621, 2040927,
|
||||
2048012,
|
||||
/* 100% Scrolls */ 2040923, 2040027, 2040417, 2040617, 2040000, 2040202, 2040400, 2040512, 2040700, 2040803,
|
||||
2041000, 2041012, 2048000, 2040926, 2040316, 2040420, 2040620, 2040003, 2040207, 2040414,
|
||||
2040515, 2040703, 2040818, 2041003, 2041015, 2048003, 2040929, 2040319, 2040423, 2040623,
|
||||
2040102, 2040300, 2040500, 2040600, 2040706, 2040900, 2041006, 2041018, 2040024, 2040324,
|
||||
2040530, 2040823, 2040107, 2040312, 2040503, 2040614, 2040800, 2040918, 2041009, 2041021
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int[] {
|
||||
/* Capes */ 1102180,
|
||||
/* Potions */ 2022179, 2022273, 2022282, 2022283,
|
||||
/* Scrolls */ 2049003,
|
||||
/* Skis */ 1432018
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int[] {
|
||||
/* Gloves */ 1082149,
|
||||
/* Capes */ 1102041, 1102042, 1102084, 1102085,
|
||||
/* Scrolls */ 2049100, 2340000,
|
||||
/* Chairs */ 3010046, 3010047
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
40
src/server/gachapon/Henesys.java
Normal file
40
src/server/gachapon/Henesys.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class Henesys extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {
|
||||
/* Common Eqps */ 1432009, 1302022, 1322027, 1062000, 1002033, 1092022, 1302021, 1322009, 1002012, 1322012,
|
||||
/* Warrior Eqps */ 1312007, 1002093, 1051016, 1040030, 1060009, 1060000, 1082025, 1402002, 1092000, 1072041,
|
||||
/* Mage Equips */ 1051023, 1002035, 1061028, 1040019, 1002152, 1002155, 1041018, 1050031, 1002102, 1082028,
|
||||
/* Bowman Equips */ 1002010, 1002057, 1002112, 1002113, 1002114, 1002115, 1002116, 1002117, 1002118, 1002119,
|
||||
1002120, 1002121, 1002135, 1002136, 1002137, 1002138, 1002139, 1002156, 1002157, 1002158,
|
||||
1002159, 1002160, 1002161, 1002162, 1002163, 1002164, 1002165, 1002166, 1002167, 1002168,
|
||||
1002169, 1002170, 1002211, 1002212, 1002213, 1002214, 1002267, 1002268, 1002269, 1002270,
|
||||
1002275, 1002276, 1002277, 1002278, 1002286, 1002287, 1002288, 1002289, 1002402, 1002403,
|
||||
1002404, 1002405, 1002406, 1002407, 1002408, 1002580, 1002749
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int[] {
|
||||
/* 110 Equips */ 1002547
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int[] {
|
||||
/* Reverse Eqps */ 1002792,
|
||||
1462052, 1462053, 1462054, 1462055,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
121
src/server/gachapon/KerningCity.java
Normal file
121
src/server/gachapon/KerningCity.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class KerningCity extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {
|
||||
//warriorEquips = {
|
||||
1002023, 1082001, 1041084, 1060017, 1422008,
|
||||
1402018, 1060019, 1072047, 1040009, 1060060,
|
||||
//magicianEquips = {
|
||||
1050029, 1072045, 1050028, 1372001, 1051024,
|
||||
1061049, 1072091, 1041030, 1041042, 1002036,
|
||||
//bowmanEquips = {
|
||||
1072103, 1072034, 1072069, 1062004, 1082050,
|
||||
1040003, 1061064, 1040074, 1061051, 1040079,
|
||||
//thiefEquips = {
|
||||
1002107, 1002108, 1002109, 1002110, 1002111,
|
||||
1002122, 1002123, 1002124, 1002125, 1002126,
|
||||
1002127, 1002128, 1002129, 1002130, 1002131,
|
||||
1002146, 1002147, 1002148, 1002149, 1002150,
|
||||
1002171, 1002172, 1002173, 1002174, 1002175,
|
||||
1002176, 1002177, 1002178, 1002179, 1002180,
|
||||
1002181, 1002182, 1002183, 1002184, 1002185,
|
||||
1002207, 1002208, 1002209, 1002210, 1002247,
|
||||
1002248, 1002249, 1002281, 1002282, 1002283,
|
||||
1002284, 1002285, 1002323, 1002324, 1002325,
|
||||
1002326, 1002327, 1002328, 1002329, 1002330,
|
||||
1002380, 1002381, 1002382, 1002383, 1002550,
|
||||
1002577, 1002656, 1002750,
|
||||
1040031, 1040032, 1040033, 1040034, 1040035,
|
||||
1040042, 1040043, 1040044, 1040048, 1040049,
|
||||
1040050, 1040057, 1040058, 1040059, 1040060,
|
||||
1040061, 1040062, 1040063, 1040082, 1040083,
|
||||
1040084, 1040094, 1040095, 1040096, 1040097,
|
||||
1040098, 1040099, 1040100, 1040105, 1040106,
|
||||
1040107, 1040108, 1040109, 1040110, 1040115,
|
||||
1040116, 1040117, 1040118, 1041003, 1041036,
|
||||
1041037, 1041038, 1041039, 1041040, 1041044,
|
||||
1041045, 1041047, 1041048, 1041049, 1041050,
|
||||
1041057, 1041058, 1041059, 1041060, 1041074,
|
||||
1041075, 1041076, 1041077, 1041078, 1041079,
|
||||
1041080, 1041094, 1041095, 1041096, 1041100,
|
||||
1041101, 1041102, 1041103, 1041105, 1041106,
|
||||
1041107, 1041115, 1041116, 1041117, 1041118,
|
||||
1050096, 1050097, 1050098, 1050099, 1051006,
|
||||
1051007, 1051008, 1051009, 1051090, 1051091,
|
||||
1051092, 1051093, 1052072, 1052163,
|
||||
1060021, 1060022, 1060023, 1060024, 1060025,
|
||||
1060031, 1060032, 1060033, 1060037, 1060038,
|
||||
1060039, 1060043, 1060044, 1060045, 1060046,
|
||||
1060050, 1060051, 1060052, 1060071, 1060072,
|
||||
1060073, 1060083, 1060084, 1060085, 1060086,
|
||||
1060087, 1060088, 1060089, 1060093, 1060094,
|
||||
1060095, 1060097, 1060098, 1060099, 1060104,
|
||||
1060105, 1060106, 1060107, 1061003, 1061029,
|
||||
1061030, 1061031, 1061032, 1061033, 1061037,
|
||||
1061038, 1061040, 1061041, 1061042, 1061043,
|
||||
1061044, 1061045, 1061046, 1061053, 1061054,
|
||||
1061055, 1061056, 1061069, 1061070, 1061071,
|
||||
1061076, 1061077, 1061078, 1061079, 1061093,
|
||||
1061094, 1061095, 1061099, 1061100, 1061101,
|
||||
1061102, 1061104, 1061105, 1061106, 1061114,
|
||||
1061115, 1061116, 1061117, 1072022, 1072028,
|
||||
1072029, 1072030, 1072031, 1072032, 1072033,
|
||||
1072035, 1072036, 1072065, 1072066, 1072070,
|
||||
1072071, 1072084, 1072085, 1072086, 1072087,
|
||||
1072104, 1072105, 1072106, 1072107, 1072108,
|
||||
1072109, 1072110, 1072128, 1072129, 1072130,
|
||||
1072131, 1072150, 1072151, 1072152, 1072161,
|
||||
1072162, 1072163, 1072171, 1072172, 1072173,
|
||||
1072174, 1072192, 1072193, 1072194, 1072195,
|
||||
1072213, 1072214, 1072215, 1072216, 1072272,
|
||||
1072346, 1082029, 1082030,
|
||||
1082031, 1082032, 1082033, 1082034, 1082037,
|
||||
1082038, 1082039, 1082042, 1082043, 1082044,
|
||||
1082045, 1082046, 1082047, 1082065, 1082066,
|
||||
1082067, 1082074, 1082075, 1082076, 1082092,
|
||||
1082093, 1082094, 1082095, 1082096, 1082097,
|
||||
1082118, 1082119, 1082120, 1082135, 1082136,
|
||||
1082137, 1082138, 1082142, 1082143, 1082144,
|
||||
1082167, 1082242, 1092018, 1092019,
|
||||
1092020, 1302001,
|
||||
1312002, 1332000, 1332001, 1332002, 1332003,
|
||||
1332004, 1332011, 1332012, 1332013, 1332014,
|
||||
1332015, 1332018, 1332023, 1332024, 1332027,
|
||||
1332031, 1332050, 1332052, 1332054,
|
||||
1332067, 1332068, 1332069, 1332070, 1332071,
|
||||
1332072, 1332077,
|
||||
1472000, 1472001, 1472002,
|
||||
1472003, 1472004, 1472005, 1472006, 1472007,
|
||||
1472008, 1472009, 1472010, 1472011, 1472012,
|
||||
1472013, 1472014, 1472015, 1472016, 1472017,
|
||||
1472018, 1472019, 1472020, 1472021, 1472022,
|
||||
1472023, 1472024, 1472025, 1472026, 1472027,
|
||||
1472028, 1472029, 1472031, 1472033, 1472051,
|
||||
1472052,
|
||||
1472069, 1472072, 1472074,
|
||||
1472075,
|
||||
///pirateEquips = {
|
||||
1082192, 1072288, 1492003, 1052113, 1052104,
|
||||
1492002, 1052095, 1492001, 1002613, 1492004,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int[] {1472053, 1332064, 1092050, 1472054};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int[] {1472073, 1092049, 1002793, 1332079, 1072364, 1472062, 1332078, 1332080};
|
||||
}
|
||||
|
||||
}
|
||||
121
src/server/gachapon/MapleGachapon.java
Normal file
121
src/server/gachapon/MapleGachapon.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.gachapon;
|
||||
|
||||
import tools.Randomizer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
public class MapleGachapon {
|
||||
|
||||
private static final MapleGachapon instance = new MapleGachapon();
|
||||
|
||||
public enum Gachapon {
|
||||
|
||||
GLOBAL(-1, -1, -1, -1, new Global()),
|
||||
HENESYS(9100100, 90, 8, 2, new Henesys()),
|
||||
ELLINIA(9100101, 90, 8, 2, new Ellinia()),
|
||||
PERION(9100102, 90, 8, 2, new Perion()),
|
||||
KERNING_CITY(9100103, 90, 8, 2, new KerningCity()),
|
||||
SLEEPYWOOD(9100104, 90, 8, 2, new Sleepywood()),
|
||||
MUSHROOM_SHRINE(9100105, 90, 8, 2, new MushroomShrine()),
|
||||
SHOWA_SPA_MALE(9100106, 90, 8, 2, new ShowaSpaMale()),
|
||||
SHOWA_SPA_FEMALE(9100107, 90, 8, 2, new ShowaSpaFemale()),
|
||||
NEW_LEAF_CITY(9100109, 90, 8, 2, new NewLeafCity()),
|
||||
NAUTILUS_HARBOR(9100117, 90, 8, 2, new NautilusHarbor());
|
||||
|
||||
private GachaponItems gachapon;
|
||||
private int npcId;
|
||||
private int common;
|
||||
private int uncommon;
|
||||
private int rare;
|
||||
|
||||
private Gachapon(int npcid, int c, int u, int r, GachaponItems g) {
|
||||
npcId = npcid;
|
||||
gachapon = g;
|
||||
common = c;
|
||||
uncommon = u;
|
||||
rare = r;
|
||||
}
|
||||
|
||||
private int getTier() {
|
||||
int chance = Randomizer.nextInt(common + uncommon + rare) + 1;
|
||||
if (chance > common + uncommon) {
|
||||
return 2; //Rare
|
||||
} else if (chance > common) {
|
||||
return 1; //Uncommon
|
||||
}
|
||||
return 0; //Common
|
||||
}
|
||||
|
||||
public int [] getItems(int tier){
|
||||
return gachapon.getItems(tier);
|
||||
}
|
||||
|
||||
public int getItem(int tier) {
|
||||
int[] gacha = getItems(tier);
|
||||
int[] global = GLOBAL.getItems(tier);
|
||||
int chance = Randomizer.nextInt(gacha.length + global.length);
|
||||
return chance < gacha.length ? gacha[chance] : global[chance - gacha.length];
|
||||
}
|
||||
|
||||
public static Gachapon getByNpcId(int npcId) {
|
||||
for (Gachapon gacha : Gachapon.values()) {
|
||||
if (npcId == gacha.npcId) {
|
||||
return gacha;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleGachapon getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MapleGachaponItem process(int npcId) {
|
||||
Gachapon gacha = Gachapon.getByNpcId(npcId);
|
||||
int tier = gacha.getTier();
|
||||
int item = gacha.getItem(tier);
|
||||
return new MapleGachaponItem(tier, item);
|
||||
}
|
||||
|
||||
public class MapleGachaponItem {
|
||||
private int id;
|
||||
private int tier;
|
||||
|
||||
public MapleGachaponItem(int t, int i) {
|
||||
id = i;
|
||||
tier = t;
|
||||
}
|
||||
|
||||
public int getTier() {
|
||||
return tier;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/server/gachapon/MushroomShrine.java
Normal file
40
src/server/gachapon/MushroomShrine.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class MushroomShrine extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int []{
|
||||
1382011, 1332024, 1302022, 1302021, 1462006, 1402009, 1402010, 1322012, 1312013, 1472008,
|
||||
1432008, 1050100, 1051098,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
//All Scrolls
|
||||
return new int [] {
|
||||
2043015, 2043017, 2043019, 2044000, 2044001, 2044002, 2044004, 2044005, 2044010, 2044012,
|
||||
2044014, 2043200, 2043201, 2043202, 2043204, 2043205, 2043210, 2043212, 2043214, 2044200,
|
||||
2044201, 2044202, 2044204, 2044205, 2044210, 2044212, 2044214, 2044300, 2044301, 2044302,
|
||||
2044304, 2044305, 2044310, 2044312, 2044314, 2044400, 2044401, 2044402, 2044404, 2044405,
|
||||
2044410, 2044412, 2044414,
|
||||
2043800, 2043801, 2043802, 2043804, 2043805, 2043700, 2043701, 2043702, 2043704, 2043705,
|
||||
2044605, 2044604, 2044602, 2044601, 2044600, 2044505, 2044504, 2044502, 2044501, 2044500,
|
||||
2044700, 2044701, 2044702, 2044704, 2044705, 2043300, 2043301, 2043302, 2043304, 2043305,
|
||||
2044800, 2044801, 2044802, 2044803, 2044804, 2044805, 2044807, 2044809, 2044900, 2044901,
|
||||
2044902, 2044903, 2044904,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
}
|
||||
49
src/server/gachapon/NautilusHarbor.java
Normal file
49
src/server/gachapon/NautilusHarbor.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class NautilusHarbor extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int[] {
|
||||
/* Warrior Equips*/ 1060017, 1302008, 1002055, 1041064, 1072127, 1072047, 1072002, 1040028, 1072041, 1092000,
|
||||
/* Mage Equips */ 1050010, 1072006, 1061022, 1051003, 1072074, 1050008, 1082053, 1051026, 1382015, 1002013,
|
||||
/* Bowman Equips */ 1082048, 1041056, 1002157, 1462048, 1041054, 1061061, 1002161, 1002162, 1002158, 1002120,
|
||||
/* Thief Equips */ 1040061, 1072031, 1051009, 1072036, 1002182, 1060073, 1472013, 1472009, 1002184, 1061055,
|
||||
/* Pirate Equips */ 1002610, 1002616, 1002622, 1002628, 1002634, 1002640, 1002646, 1052095, 1052101, 1052107,
|
||||
1052113, 1052119, 1052125, 1052131, 1072285, 1072291, 1072297, 1072303, 1072309, 1072315,
|
||||
1082180, 1082186, 1082192, 1082198, 1082204, 1082210, 1482001, 1482003, 1482005, 1482007,
|
||||
1482009, 1482011, 1492000, 1492002, 1492004, 1492006, 1492008, 1492010, 1492012, 1002613,
|
||||
1002619, 1002625, 1002631, 1002637, 1002643, 1052098, 1052104, 1052110, 1052116, 1052122,
|
||||
1052128, 1072288, 1072294, 1072300, 1072306, 1072312, 1072318, 1072338, 1082183, 1082189,
|
||||
1082195, 1082201, 1082207, 1082213, 1482000, 1482002, 1482004, 1482006, 1482008, 1482010,
|
||||
1482012, 1492001, 1492003, 1492005, 1492007, 1492009, 1492011,
|
||||
/*KnucklerScrolls*/ 2044800, 2044801, 2044802, 2044803, 2044804, 2044805, 2044806, 2044807, 2044808, 2044809,
|
||||
/* Gun Scrolls */ 2044900, 2044901, 2044902, 2044903, 2044904,
|
||||
/* Bullets */ 2330005, 2330004
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int[] {
|
||||
/* Pirate Equips */ 1072321, 1082216, 1482013, 1002649, 1052134, 1492013,
|
||||
/* Mastery Books */ 2290097, 2290098, 2290099, 2290100, 2290101, 2290102, 2290103, 2290104, 2290105, 2290106,
|
||||
2290107, 2290108, 2290110, 2290111, 2290111, 2290113, 2290114, 2290115, 2290116, 2290117,
|
||||
2290118, 2290119, 2290120, 2290121, 2290122, 2290123, 2290124
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int[] {
|
||||
/* Pirate Equips */ 1082243, 1482024, 1002794, 1052164, 1072365,
|
||||
1482034, 1492025
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
66
src/server/gachapon/NewLeafCity.java
Normal file
66
src/server/gachapon/NewLeafCity.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class NewLeafCity extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int[] {
|
||||
/* Warrior Equips*/ 1002338, 1002339, 1002340, 1002377, 1002378, 1002379, 1002528, 1002529, 1002530, 1002531,
|
||||
1002532, 1040111, 1040112, 1040113, 1040120, 1040121, 1040122, 1041119, 1041120, 1041121,
|
||||
1041122, 1041123, 1041124, 1050080, 1050081, 1050082, 1050083, 1051077, 1051078, 1051079,
|
||||
1051080, 1060100, 1060101, 1060102, 1060109, 1060110, 1060111, 1061118, 1061119, 1061120,
|
||||
1061121, 1061122, 1061123, 1072196, 1072197, 1072198, 1072210, 1072211, 1072212, 1072220,
|
||||
1072221, 1072222, 1082114, 1082115, 1082116, 1082117, 1082128, 1082129, 1082130, 1082139,
|
||||
1082140, 1082141, 1092023, 1092024, 1092025, 1092026, 1092027, 1092028, 1092036, 1092037,
|
||||
1092038, 1092061, 1302018, 1302023, 1302056, 1312011, 1312015, 1312030, 1322020, 1322028,
|
||||
1322029, 1322045, 1402004, 1402005, 1402015, 1402016, 1402035,
|
||||
1412009, 1412010, 1412021, 1412040, 1422012, 1422013, 1422027, 1432010,
|
||||
1432011, 1432030, 1432056, 1442019, 1442020, 1442044,
|
||||
/* Mage Equips */ 1002271, 1002272, 1002273, 1002274, 1002363, 1002364, 1002365, 1002366, 1002398, 1002399,
|
||||
1002400, 1002401, 1050072, 1050073, 1050074, 1050092, 1050093, 1050094, 1050095, 1050102,
|
||||
1050103, 1050104, 1050105, 1051056, 1051057, 1051058, 1051094, 1051095, 1051096, 1051097,
|
||||
1051101, 1051102, 1051103, 1051104, 1072177, 1072178, 1072179, 1072206, 1072207, 1072208,
|
||||
1072209, 1072223, 1072224, 1072225, 1072226, 1082121, 1082122, 1082123, 1082131, 1082132,
|
||||
1082133, 1082134, 1082151, 1082152, 1082153, 1082154, 1372009, 1372010, 1372016, 1382008,
|
||||
1382010, 1382016, 1382035, 1382056, 1382060,
|
||||
/* Bowman Equips */ 1002275, 1002276, 1002277, 1002275, 1002278, 1002402, 1002403, 1002404, 1002405, 1002406,
|
||||
1002407, 1002408, 1050075, 1050076, 1050077, 1050078, 1050088, 1050089, 1050090, 1050091,
|
||||
1050106, 1050107, 1050108, 1002275, 1051066, 1051067, 1051068, 1051069, 1051082, 1051083,
|
||||
1051084, 1051085, 1051105, 1051106, 1051107, 1072182, 1072183, 1072184, 1072185, 1072203,
|
||||
1072204, 1072205, 1072227, 1072228, 1072229, 1082109, 1082110, 1082111, 1082112, 1082125,
|
||||
1082126, 1082127, 1082158, 1082159, 1082160, 1452012, 1452013, 1452014, 1452015, 1452017,
|
||||
1452019, 1452020, 1452021, 1452025, 1452026, 1452060, 1462010, 1452017, 1462011, 1462012,
|
||||
1462013, 1462015, 1462016, 1462017, 1462018, 1462021, 1462022, 1462049,
|
||||
/* Thief Equips */ 1002323, 1002324, 1002325, 1002326, 1002327, 1002328, 1002329, 1002330, 1002380, 1002381,
|
||||
1002382, 1002383, 1040108, 1040109, 1040110, 1040115, 1040117, 1040118, 1041105, 1041106,
|
||||
1041107, 1041115, 1041116, 1041117, 1041118, 1050096, 1050097, 1050098, 1050099, 1051090,
|
||||
1051091, 1051092, 1051093, 1060097, 1060098, 1060099, 1060104, 1060105, 1060106, 1060107,
|
||||
1061104, 1061105, 1061106, 1061114, 1061115, 1061116, 1061117, 1072172, 1072173, 1072174,
|
||||
1072192, 1072193, 1072194, 1072195, 1072213, 1072214, 1072215, 1072216, 1082118, 1082119,
|
||||
1082120, 1082135, 1082136, 1082137, 1082138, 1082143, 1082144, 1092050, 1332023, 1332027,
|
||||
1332052, 1332069, 1332072, 1472031, 1472033, 1472053,
|
||||
/* Pirate Equips */ 1002640, 1002643, 1002646, 1052125, 1052128, 1052131, 1072312, 1072315, 1072318, 1082207,
|
||||
1082210, 1082213, 1482010, 1482011, 1002640, 1482012, 1492010, 1492011, 1492012
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int[] {
|
||||
2022179
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int[] {
|
||||
2049100
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
137
src/server/gachapon/Perion.java
Normal file
137
src/server/gachapon/Perion.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class Perion extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {
|
||||
//warriorEquips = {
|
||||
1002002, 1002003, 1002004, 1002005, 1002007,
|
||||
1002009, 1002011, 1002021, 1002022, 1002023,
|
||||
1002024, 1002025, 1002027, 1002028, 1002029,
|
||||
1002030, 1002039, 1002040, 1002043, 1002044,
|
||||
1002045, 1002046, 1002047, 1002048, 1002049,
|
||||
1002050, 1002051, 1002052, 1002055, 1002056,
|
||||
1002058, 1002059, 1002084, 1002085, 1002086,
|
||||
1002087, 1002088, 1002091, 1002092, 1002093,
|
||||
1002094, 1002095, 1002098, 1002099, 1002100,
|
||||
1002101, 1002338, 1002339, 1002340, 1002377,
|
||||
1002378, 1002379, 1002528, 1002529, 1002530,
|
||||
1002531, 1002532, 1002551, 1002578,
|
||||
1002790, 1040000, 1040009, 1040012, 1040015,
|
||||
1040016, 1040021, 1040026, 1040028, 1040029,
|
||||
1040030, 1040037, 1040038, 1040039, 1040040,
|
||||
1040041, 1040085, 1040086, 1040087, 1040088,
|
||||
1040089, 1040090, 1040091, 1040092, 1040093,
|
||||
1040102, 1040103, 1040104, 1040111, 1040112,
|
||||
1040113, 1040120, 1040121, 1040122, 1041014,
|
||||
1041019, 1041020, 1041021, 1041022, 1041023,
|
||||
1041024, 1041064, 1041084, 1041085, 1041086,
|
||||
1041087, 1041088, 1041089, 1041091, 1041092,
|
||||
1041093, 1041097, 1041098, 1041099, 1041119,
|
||||
1041120, 1041121, 1041122, 1041123, 1041124,
|
||||
1050000, 1050005, 1050006, 1050007, 1050011,
|
||||
1050021, 1050022, 1050080, 1050081, 1050082,
|
||||
1050083, 1051000, 1051001, 1051010, 1051011,
|
||||
1051012, 1051013, 1051014, 1051015, 1051016,
|
||||
1051077, 1051078, 1051079, 1051080, 1052075,
|
||||
1052160, 1060000, 1060008, 1060009,
|
||||
1060010, 1060011, 1060016, 1060017, 1060018,
|
||||
1060019, 1060020, 1060027, 1060028, 1060029,
|
||||
1060030, 1060060, 1060074, 1060075, 1060076,
|
||||
1060077, 1060078, 1060079, 1060080, 1060081,
|
||||
1060082, 1060090, 1060091, 1060092, 1060100,
|
||||
1060101, 1060102, 1060109, 1060110, 1060111,
|
||||
1061014, 1061015, 1061016, 1061017, 1061018,
|
||||
1061019, 1061020, 1061023, 1061083, 1061084,
|
||||
1061085, 1061086, 1061087, 1061088, 1061090,
|
||||
1061091, 1061092, 1061096, 1061097, 1061098,
|
||||
1061118, 1061119, 1061120, 1061121, 1061122,
|
||||
1061123, 1072000, 1072002, 1072003, 1072007,
|
||||
1072009, 1072011, 1072039, 1072040, 1072041,
|
||||
1072046, 1072047, 1072050, 1072051, 1072052,
|
||||
1072053, 1072112, 1072113, 1072126, 1072127,
|
||||
1072132, 1072133, 1072134, 1072135, 1072147,
|
||||
1072148, 1072149, 1072154, 1072155, 1072156,
|
||||
1072168, 1072196, 1072197, 1072198, 1072210,
|
||||
1072211, 1072212, 1072220, 1072221, 1072222,
|
||||
1072273, 1082000, 1082001,
|
||||
1082003, 1082004, 1082005, 1082006, 1082007,
|
||||
1082008, 1082009, 1082010, 1082011, 1082023,
|
||||
1082024, 1082025, 1082035, 1082036, 1082059,
|
||||
1082060, 1082061, 1082103, 1082104, 1082105,
|
||||
1082114, 1082115, 1082116, 1082117, 1082128,
|
||||
1082129, 1082130, 1082139, 1082140, 1082141,
|
||||
1082168, 1082218, 1082239, 1092000,
|
||||
1092001, 1092002, 1092004, 1092005, 1092006,
|
||||
1092007, 1092009, 1092010, 1092011, 1092012,
|
||||
1092013, 1092014, 1092015, 1092016, 1092017,
|
||||
1092023, 1092024, 1092025, 1092026, 1092027,
|
||||
1092028, 1092036, 1092037, 1092038,
|
||||
1092060, 1092061, 1302002, 1302004, 1302005,
|
||||
1302008, 1302009, 1302010, 1302011, 1302012,
|
||||
1302015, 1302018, 1302019, 1302023, 1302037,
|
||||
1302056, 1302059, 1302068, 1302079,
|
||||
1312001, 1312003, 1312005,
|
||||
1312006, 1312007, 1312008, 1312009, 1312010,
|
||||
1312011, 1312015, 1312016, 1312030, 1312031,
|
||||
1322014, 1322015,
|
||||
1322016, 1322017, 1322018, 1322019, 1322020,
|
||||
1322028, 1322029, 1322045, 1322052, 1322059,
|
||||
1322062, 1402000,
|
||||
1402002, 1402003, 1402004, 1402005, 1402006,
|
||||
1402007, 1402008, 1402011, 1402012, 1402015,
|
||||
1402016, 1402017, 1402018, 1402035, 1402036,
|
||||
1412000, 1412002,
|
||||
1412003, 1412004, 1412005, 1412006, 1412007,
|
||||
1412008, 1412009, 1412010, 1412012, 1412021,
|
||||
1412026, 1412032, 1412040,
|
||||
1422001, 1422002, 1422003, 1422005,
|
||||
1422007, 1422008, 1422009, 1422010, 1422012,
|
||||
1422013, 1422027, 1422028, 1422030, 1422031,
|
||||
1422038, 1422044, 1432002, 1432003,
|
||||
1432004, 1432005, 1432006, 1432007, 1432010,
|
||||
1432011, 1432030, 1432038, 1432045,
|
||||
1432048, 1432056, 1442001, 1442002,
|
||||
1442003, 1442005, 1442006, 1442007, 1442008,
|
||||
1442009, 1442010, 1442019, 1442020, 1442044,
|
||||
1442045, 1442060, 1442067,
|
||||
//magicianEquips = {
|
||||
1002075, 1050035, 1002151, 1051023, 1072089,
|
||||
1072115, 1072076, 1040018, 1382017, 1072072,
|
||||
//bowmanEquips = {
|
||||
1040011, 1041061, 1040076, 1040003, 1072059,
|
||||
1082017, 1002114, 1041066, 1060057, 1040007,
|
||||
//thiefEquips = {
|
||||
1072032, 1472011, 1082037, 1040059, 1040084,
|
||||
1040043, 1072085, 1040031, 1332031, 1082075,
|
||||
//pirateEquips = {
|
||||
1482001, 1492002, 1052113, 1002616, 1072294,
|
||||
1492004, 1482006, 1082192, 1082189, 1082195,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
//All Scrolls
|
||||
return new int [] {
|
||||
2043000, 2043001, 2043002, 2043004, 2043005, 2043006, 2043007, 2043008, 2043009, 2043010,
|
||||
2043015, 2043017, 2043019, 2044000, 2044001, 2044002, 2044004, 2044005, 2044010, 2044012,
|
||||
2044014, 2043200, 2043201, 2043202, 2043204, 2043205, 2043210, 2043212, 2043214, 2044200,
|
||||
2044201, 2044202, 2044204, 2044205, 2044210, 2044212, 2044214, 2044300, 2044301, 2044302,
|
||||
2044304, 2044305, 2044310, 2044312, 2044314, 2044400, 2044401, 2044402, 2044404, 2044405,
|
||||
2044410, 2044412, 2044414,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {1402037, 1402049, 1072361, 1402048, 1402049, 1402050, 1402051};
|
||||
}
|
||||
|
||||
}
|
||||
25
src/server/gachapon/ShowaSpaFemale.java
Normal file
25
src/server/gachapon/ShowaSpaFemale.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class ShowaSpaFemale extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {1022082, 1022060};
|
||||
}
|
||||
|
||||
}
|
||||
25
src/server/gachapon/ShowaSpaMale.java
Normal file
25
src/server/gachapon/ShowaSpaMale.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class ShowaSpaMale extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {1022082, 1022060};
|
||||
}
|
||||
|
||||
}
|
||||
106
src/server/gachapon/Sleepywood.java
Normal file
106
src/server/gachapon/Sleepywood.java
Normal file
@@ -0,0 +1,106 @@
|
||||
package server.gachapon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public class Sleepywood extends GachaponItems {
|
||||
|
||||
@Override
|
||||
public int[] getCommonItems() {
|
||||
return new int [] {
|
||||
//warriorEquips = {
|
||||
1002022, 1002024, 1002028, 1002029, 1002030,
|
||||
1002045, 1002046, 1002084, 1002085, 1002086,
|
||||
1002091, 1002094, 1002095, 1002100, 1002101,
|
||||
1040087, 1040088, 1040089, 1040090, 1040091,
|
||||
1040092, 1040093, 1040102, 1040103, 1040104,
|
||||
1041087, 1041088, 1041089, 1041091, 1041092,
|
||||
1041093, 1041097, 1041098, 1041099, 1060076,
|
||||
1060077, 1060078, 1060079, 1060080, 1060081,
|
||||
1060082, 1060090, 1060091, 1060092, 1061086,
|
||||
1061087, 1061088, 1061090, 1061091, 1061092,
|
||||
1061096, 1061097, 1061098, 1072132, 1072133,
|
||||
1072134, 1072135, 1072147, 1072148, 1072149,
|
||||
1072154, 1072155, 1072156, 1082009, 1082010,
|
||||
1082011, 1082059, 1082060, 1082061, 1082103,
|
||||
1082104, 1082105, 1082218, 1092004, 1092009,
|
||||
1092010, 1092011, 1092015, 1092016, 1092017,
|
||||
1302010, 1302011, 1302012, 1302015, 1302019,
|
||||
1302037, 1302079, 1312008, 1312009,
|
||||
1312010, 1322017, 1322018, 1322019, 1322059,
|
||||
1402003, 1402011, 1402012, 1402017, 1412003,
|
||||
1412007, 1412008, 1412032, 1422005, 1422009,
|
||||
1422010, 1432004, 1432006, 1432007, 1432045,
|
||||
1442005, 1442008, 1442010, 1442060,
|
||||
//magicianEquips = {
|
||||
1002215, 1002216, 1002217, 1002218, 1002242,
|
||||
1002243, 1002244, 1002245, 1002246, 1002252,
|
||||
1002253, 1002254, 1050045, 1050046, 1050047,
|
||||
1050048, 1050049, 1050053, 1050054, 1050055,
|
||||
1050056, 1050067, 1050068, 1050069, 1050070,
|
||||
1051030, 1051031, 1051032, 1051033, 1051034,
|
||||
1051044, 1051045, 1051046, 1051047, 1051052,
|
||||
1051053, 1051054, 1051055, 1072136, 1072137,
|
||||
1072138, 1072139, 1072140, 1072141, 1072142,
|
||||
1072143, 1072157, 1072158, 1072159, 1072160,
|
||||
1082080, 1082081, 1082082, 1082086, 1082087,
|
||||
1082088, 1082098, 1082099, 1082100, 1372007,
|
||||
1372008, 1372011, 1372014, 1372015, 1372035,
|
||||
1372036, 1372037, 1372038, 1382001, 1382006,
|
||||
1382007, 1382011, 1382014, 1382041,
|
||||
//bowmanEquips = {
|
||||
1002211, 1002212, 1002213, 1002214, 1002267,
|
||||
1002268, 1002269, 1002270, 1002286, 1002287,
|
||||
1002288, 1002289, 1002749, 1050051, 1050052,
|
||||
1050058, 1050059, 1050060, 1050061, 1050062,
|
||||
1050063, 1050064, 1051037, 1051038, 1051039,
|
||||
1051041, 1051042, 1051043, 1051062, 1051063,
|
||||
1051064, 1051065, 1072122, 1072123, 1072124,
|
||||
1072125, 1072144, 1072145, 1072146, 1072164,
|
||||
1072165, 1072166, 1072167, 1072345, 1082083,
|
||||
1082084, 1082085, 1082089, 1082090, 1082091,
|
||||
1082106, 1082107, 1082108, 1452004, 1452008,
|
||||
1452009, 1452010, 1452011, 1452018, 1452023,
|
||||
1452052, 1462006, 1462007, 1462008, 1462009,
|
||||
1462046,
|
||||
//thiefEquips = {
|
||||
1002207, 1002208, 1002209, 1002210, 1002247,
|
||||
1002248, 1002249, 1002281, 1002282, 1002283,
|
||||
1002284, 1002285, 1002656, 1002750, 1040094,
|
||||
1040095, 1040096, 1040097, 1040098, 1040099,
|
||||
1040100, 1040105, 1040106, 1040107, 1041077,
|
||||
1041078, 1041079, 1041080, 1041094, 1041095,
|
||||
1041096, 1041100, 1041101, 1041102, 1041103,
|
||||
1060083, 1060084, 1060085, 1060086, 1060087,
|
||||
1060088, 1060089, 1060093, 1060094, 1060095,
|
||||
1061076, 1061077, 1061078, 1061079, 1061093,
|
||||
1061094, 1061095, 1061099, 1061100, 1061101,
|
||||
1061102, 1072128, 1072129, 1072130, 1072131,
|
||||
1072150, 1072151, 1072152, 1072161, 1072162,
|
||||
1072163, 1072346, 1082065, 1082066, 1082067,
|
||||
1082092, 1082093, 1082094, 1082095, 1082096,
|
||||
1082097, 1332003, 1332015, 1332018, 1332024,
|
||||
1332054, 1332064, 1472018, 1472019, 1472020,
|
||||
1472021, 1472022, 1472023, 1472024, 1472025,
|
||||
1472026, 1472027, 1472028, 1472029, 1472054,
|
||||
1472062,
|
||||
//pirateEquips = {
|
||||
1002631, 1002634, 1002637, 1052116, 1052119,
|
||||
1052122, 1072303, 1072306, 1072309, 1082198,
|
||||
1082201, 1082204, 1482007, 1482008, 1482009,
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getUncommonItems() {
|
||||
return new int [] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRareItems() {
|
||||
return new int [] {1302068, 2070007, 1022082, 1022058};
|
||||
}
|
||||
|
||||
}
|
||||
106
src/server/life/AbstractLoadedMapleLife.java
Normal file
106
src/server/life/AbstractLoadedMapleLife.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import server.maps.AbstractAnimatedMapleMapObject;
|
||||
|
||||
public abstract class AbstractLoadedMapleLife extends AbstractAnimatedMapleMapObject {
|
||||
private final int id;
|
||||
private int f;
|
||||
private boolean hide;
|
||||
private int fh;
|
||||
private int start_fh;
|
||||
private int cy;
|
||||
private int rx0;
|
||||
private int rx1;
|
||||
|
||||
public AbstractLoadedMapleLife(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public AbstractLoadedMapleLife(AbstractLoadedMapleLife life) {
|
||||
this(life.getId());
|
||||
this.f = life.f;
|
||||
this.hide = life.hide;
|
||||
this.fh = life.fh;
|
||||
this.start_fh = life.fh;
|
||||
this.cy = life.cy;
|
||||
this.rx0 = life.rx0;
|
||||
this.rx1 = life.rx1;
|
||||
}
|
||||
|
||||
public int getF() {
|
||||
return f;
|
||||
}
|
||||
|
||||
public void setF(int f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return hide;
|
||||
}
|
||||
|
||||
public void setHide(boolean hide) {
|
||||
this.hide = hide;
|
||||
}
|
||||
|
||||
public int getFh() {
|
||||
return fh;
|
||||
}
|
||||
|
||||
public void setFh(int fh) {
|
||||
this.fh = fh;
|
||||
}
|
||||
|
||||
public int getStartFh() {
|
||||
return start_fh;
|
||||
}
|
||||
|
||||
public int getCy() {
|
||||
return cy;
|
||||
}
|
||||
|
||||
public void setCy(int cy) {
|
||||
this.cy = cy;
|
||||
}
|
||||
|
||||
public int getRx0() {
|
||||
return rx0;
|
||||
}
|
||||
|
||||
public void setRx0(int rx0) {
|
||||
this.rx0 = rx0;
|
||||
}
|
||||
|
||||
public int getRx1() {
|
||||
return rx1;
|
||||
}
|
||||
|
||||
public void setRx1(int rx1) {
|
||||
this.rx1 = rx1;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
46
src/server/life/Element.java
Normal file
46
src/server/life/Element.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
public enum Element {
|
||||
NEUTRAL, FIRE, ICE, LIGHTING, POISON, HOLY, DARK;
|
||||
|
||||
public static Element getFromChar(char c) {
|
||||
switch (Character.toUpperCase(c)) {
|
||||
case 'F':
|
||||
return FIRE;
|
||||
case 'I':
|
||||
return ICE;
|
||||
case 'L':
|
||||
return LIGHTING;
|
||||
case 'S':
|
||||
return POISON;
|
||||
case 'H':
|
||||
return HOLY;
|
||||
case 'D':
|
||||
return DARK;
|
||||
case 'P':
|
||||
return NEUTRAL;
|
||||
}
|
||||
throw new IllegalArgumentException("unknown elemnt char " + c);
|
||||
}
|
||||
}
|
||||
41
src/server/life/ElementalEffectiveness.java
Normal file
41
src/server/life/ElementalEffectiveness.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
public enum ElementalEffectiveness {
|
||||
NORMAL, IMMUNE, STRONG, WEAK, NEUTRAL;
|
||||
|
||||
public static ElementalEffectiveness getByNumber(int num) {
|
||||
switch (num) {
|
||||
case 1:
|
||||
return IMMUNE;
|
||||
case 2:
|
||||
return STRONG;
|
||||
case 3:
|
||||
return WEAK;
|
||||
case 4:
|
||||
return NEUTRAL;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unkown effectiveness: " + num);
|
||||
}
|
||||
}
|
||||
}
|
||||
236
src/server/life/MapleLifeFactory.java
Normal file
236
src/server/life/MapleLifeFactory.java
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import provider.wz.MapleDataType;
|
||||
import tools.Pair;
|
||||
import tools.StringUtil;
|
||||
|
||||
public class MapleLifeFactory {
|
||||
|
||||
private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Mob.wz"));
|
||||
private final static MapleDataProvider stringDataWZ = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz"));
|
||||
private static MapleData mobStringData = stringDataWZ.getData("Mob.img");
|
||||
private static MapleData npcStringData = stringDataWZ.getData("Npc.img");
|
||||
private static Map<Integer, MapleMonsterStats> monsterStats = new HashMap<>();
|
||||
|
||||
public static AbstractLoadedMapleLife getLife(int id, String type) {
|
||||
if (type.equalsIgnoreCase("n")) {
|
||||
return getNPC(id);
|
||||
} else if (type.equalsIgnoreCase("m")) {
|
||||
return getMonster(id);
|
||||
} else {
|
||||
System.out.println("Unknown Life type: " + type);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleMonster getMonster(int mid) {
|
||||
MapleMonsterStats stats = monsterStats.get(Integer.valueOf(mid));
|
||||
if (stats == null) {
|
||||
MapleData monsterData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(mid) + ".img", '0', 11));
|
||||
if (monsterData == null) {
|
||||
return null;
|
||||
}
|
||||
MapleData monsterInfoData = monsterData.getChildByPath("info");
|
||||
stats = new MapleMonsterStats();
|
||||
stats.setHp(MapleDataTool.getIntConvert("maxHP", monsterInfoData));
|
||||
stats.setFriendly(MapleDataTool.getIntConvert("damagedByMob", monsterInfoData, 0) == 1);
|
||||
stats.setPADamage(MapleDataTool.getIntConvert("PADamage", monsterInfoData));
|
||||
stats.setPDDamage(MapleDataTool.getIntConvert("PDDamage", monsterInfoData));
|
||||
stats.setMADamage(MapleDataTool.getIntConvert("MADamage", monsterInfoData));
|
||||
stats.setMDDamage(MapleDataTool.getIntConvert("MDDamage", monsterInfoData));
|
||||
stats.setMp(MapleDataTool.getIntConvert("maxMP", monsterInfoData, 0));
|
||||
stats.setExp(MapleDataTool.getIntConvert("exp", monsterInfoData, 0));
|
||||
stats.setLevel(MapleDataTool.getIntConvert("level", monsterInfoData));
|
||||
stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", monsterInfoData, 0));
|
||||
stats.setBoss(MapleDataTool.getIntConvert("boss", monsterInfoData, 0) > 0);
|
||||
stats.setExplosiveReward(MapleDataTool.getIntConvert("explosiveReward", monsterInfoData, 0) > 0);
|
||||
stats.setFfaLoot(MapleDataTool.getIntConvert("publicReward", monsterInfoData, 0) > 0);
|
||||
stats.setUndead(MapleDataTool.getIntConvert("undead", monsterInfoData, 0) > 0);
|
||||
stats.setName(MapleDataTool.getString(mid + "/name", mobStringData, "MISSINGNO"));
|
||||
stats.setBuffToGive(MapleDataTool.getIntConvert("buff", monsterInfoData, -1));
|
||||
stats.setCP(MapleDataTool.getIntConvert("getCP", monsterInfoData, 0));
|
||||
stats.setRemoveOnMiss(MapleDataTool.getIntConvert("removeOnMiss", monsterInfoData, 0) > 0);
|
||||
|
||||
MapleData special = monsterInfoData.getChildByPath("coolDamage");
|
||||
if (special != null) {
|
||||
int coolDmg = MapleDataTool.getIntConvert("coolDamage", monsterInfoData);
|
||||
int coolProb = MapleDataTool.getIntConvert("coolDamageProb", monsterInfoData, 0);
|
||||
stats.setCool(new Pair<>(coolDmg, coolProb));
|
||||
}
|
||||
special = monsterInfoData.getChildByPath("loseItem");
|
||||
if (special != null) {
|
||||
for (MapleData liData : special.getChildren()) {
|
||||
stats.addLoseItem(new loseItem(MapleDataTool.getInt(liData.getChildByPath("id")), (byte) MapleDataTool.getInt(liData.getChildByPath("prop")), (byte) MapleDataTool.getInt(liData.getChildByPath("x"))));
|
||||
}
|
||||
}
|
||||
special = monsterInfoData.getChildByPath("selfDestruction");
|
||||
if (special != null) {
|
||||
stats.setSelfDestruction(new selfDestruction((byte) MapleDataTool.getInt(special.getChildByPath("action")), MapleDataTool.getIntConvert("removeAfter", special, -1), MapleDataTool.getIntConvert("hp", special, -1)));
|
||||
}
|
||||
MapleData firstAttackData = monsterInfoData.getChildByPath("firstAttack");
|
||||
int firstAttack = 0;
|
||||
if (firstAttackData != null) {
|
||||
if (firstAttackData.getType() == MapleDataType.FLOAT) {
|
||||
firstAttack = Math.round(MapleDataTool.getFloat(firstAttackData));
|
||||
} else {
|
||||
firstAttack = MapleDataTool.getInt(firstAttackData);
|
||||
}
|
||||
}
|
||||
stats.setFirstAttack(firstAttack > 0);
|
||||
stats.setDropPeriod(MapleDataTool.getIntConvert("dropItemPeriod", monsterInfoData, 0) * 10000);
|
||||
|
||||
stats.setTagColor(MapleDataTool.getIntConvert("hpTagColor", monsterInfoData, 0));
|
||||
stats.setTagBgColor(MapleDataTool.getIntConvert("hpTagBgcolor", monsterInfoData, 0));
|
||||
|
||||
for (MapleData idata : monsterData) {
|
||||
if (!idata.getName().equals("info")) {
|
||||
int delay = 0;
|
||||
for (MapleData pic : idata.getChildren()) {
|
||||
delay += MapleDataTool.getIntConvert("delay", pic, 0);
|
||||
}
|
||||
stats.setAnimationTime(idata.getName(), delay);
|
||||
}
|
||||
}
|
||||
MapleData reviveInfo = monsterInfoData.getChildByPath("revive");
|
||||
if (reviveInfo != null) {
|
||||
List<Integer> revives = new LinkedList<>();
|
||||
for (MapleData data_ : reviveInfo) {
|
||||
revives.add(MapleDataTool.getInt(data_));
|
||||
}
|
||||
stats.setRevives(revives);
|
||||
}
|
||||
decodeElementalString(stats, MapleDataTool.getString("elemAttr", monsterInfoData, ""));
|
||||
MapleData monsterSkillData = monsterInfoData.getChildByPath("skill");
|
||||
if (monsterSkillData != null) {
|
||||
int i = 0;
|
||||
List<Pair<Integer, Integer>> skills = new ArrayList<>();
|
||||
while (monsterSkillData.getChildByPath(Integer.toString(i)) != null) {
|
||||
skills.add(new Pair<>(Integer.valueOf(MapleDataTool.getInt(i + "/skill", monsterSkillData, 0)), Integer.valueOf(MapleDataTool.getInt(i + "/level", monsterSkillData, 0))));
|
||||
i++;
|
||||
}
|
||||
stats.setSkills(skills);
|
||||
}
|
||||
MapleData banishData = monsterInfoData.getChildByPath("ban");
|
||||
if (banishData != null) {
|
||||
stats.setBanishInfo(new BanishInfo(MapleDataTool.getString("banMsg", banishData), MapleDataTool.getInt("banMap/0/field", banishData, -1), MapleDataTool.getString("banMap/0/portal", banishData, "sp")));
|
||||
}
|
||||
monsterStats.put(Integer.valueOf(mid), stats);
|
||||
}
|
||||
MapleMonster ret = new MapleMonster(mid, stats);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void decodeElementalString(MapleMonsterStats stats, String elemAttr) {
|
||||
for (int i = 0; i < elemAttr.length(); i += 2) {
|
||||
stats.setEffectiveness(Element.getFromChar(elemAttr.charAt(i)), ElementalEffectiveness.getByNumber(Integer.valueOf(String.valueOf(elemAttr.charAt(i + 1)))));
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleNPC getNPC(int nid) {
|
||||
return new MapleNPC(nid, new MapleNPCStats(MapleDataTool.getString(nid + "/name", npcStringData, "MISSINGNO")));
|
||||
}
|
||||
|
||||
public static class BanishInfo {
|
||||
|
||||
private int map;
|
||||
private String portal, msg;
|
||||
|
||||
public BanishInfo(String msg, int map, String portal) {
|
||||
this.msg = msg;
|
||||
this.map = map;
|
||||
this.portal = portal;
|
||||
}
|
||||
|
||||
public int getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public String getPortal() {
|
||||
return portal;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
public static class loseItem {
|
||||
|
||||
private int id;
|
||||
private byte chance, x;
|
||||
|
||||
private loseItem(int id, byte chance, byte x) {
|
||||
this.id = id;
|
||||
this.chance = chance;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public byte getX() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public static class selfDestruction {
|
||||
|
||||
private byte action;
|
||||
private int removeAfter;
|
||||
private int hp;
|
||||
|
||||
private selfDestruction(byte action, int removeAfter, int hp) {
|
||||
this.action = action;
|
||||
this.removeAfter = removeAfter;
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public byte getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public int removeAfter() {
|
||||
return removeAfter;
|
||||
}
|
||||
}
|
||||
}
|
||||
954
src/server/life/MapleMonster.java
Normal file
954
src/server/life/MapleMonster.java
Normal file
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.status.MonsterStatus;
|
||||
import client.status.MonsterStatusEffect;
|
||||
import constants.ServerConstants;
|
||||
import constants.skills.FPMage;
|
||||
import constants.skills.Hermit;
|
||||
import constants.skills.ILMage;
|
||||
import constants.skills.NightLord;
|
||||
import constants.skills.NightWalker;
|
||||
import constants.skills.Shadower;
|
||||
import constants.skills.SuperGM;
|
||||
import java.awt.Point;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import server.TimerManager;
|
||||
import server.life.MapleLifeFactory.BanishInfo;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
|
||||
public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
private MapleMonsterStats stats;
|
||||
private int hp, mp;
|
||||
private WeakReference<MapleCharacter> controller = new WeakReference<>(null);
|
||||
private boolean controllerHasAggro, controllerKnowsAboutAggro;
|
||||
private EventInstanceManager eventInstance = null;
|
||||
private Collection<MonsterListener> listeners = new LinkedList<>();
|
||||
private EnumMap<MonsterStatus, MonsterStatusEffect> stati = new EnumMap<>(MonsterStatus.class);
|
||||
private ArrayList<MonsterStatus> alreadyBuffed = new ArrayList<MonsterStatus>();
|
||||
private MapleMap map;
|
||||
private int VenomMultiplier = 0;
|
||||
private boolean fake = false;
|
||||
private boolean dropsDisabled = false;
|
||||
private List<Pair<Integer, Integer>> usedSkills = new ArrayList<>();
|
||||
private Map<Pair<Integer, Integer>, Integer> skillsUsed = new HashMap<>();
|
||||
private List<Integer> stolenItems = new ArrayList<>();
|
||||
private int team;
|
||||
private final HashMap<Integer, AtomicInteger> takenDamage = new HashMap<>();
|
||||
|
||||
public ReentrantLock monsterLock = new ReentrantLock();
|
||||
|
||||
public MapleMonster(int id, MapleMonsterStats stats) {
|
||||
super(id);
|
||||
initWithStats(stats);
|
||||
}
|
||||
|
||||
public MapleMonster(MapleMonster monster) {
|
||||
super(monster);
|
||||
initWithStats(monster.stats);
|
||||
}
|
||||
|
||||
private void initWithStats(MapleMonsterStats stats) {
|
||||
setStance(5);
|
||||
this.stats = stats;
|
||||
hp = stats.getHp();
|
||||
mp = stats.getMp();
|
||||
}
|
||||
|
||||
public void disableDrops() {
|
||||
this.dropsDisabled = true;
|
||||
}
|
||||
|
||||
public boolean dropsDisabled() {
|
||||
return dropsDisabled;
|
||||
}
|
||||
|
||||
public void setMap(MapleMap map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public void setHp(int hp) {
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public int getMaxHp() {
|
||||
return stats.getHp();
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
}
|
||||
|
||||
public void setMp(int mp) {
|
||||
if (mp < 0) {
|
||||
mp = 0;
|
||||
}
|
||||
this.mp = mp;
|
||||
}
|
||||
|
||||
public int getMaxMp() {
|
||||
return stats.getMp();
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return stats.getExp();
|
||||
}
|
||||
|
||||
int getLevel() {
|
||||
return stats.getLevel();
|
||||
}
|
||||
|
||||
public int getCP() {
|
||||
return stats.getCP();
|
||||
}
|
||||
|
||||
public int getTeam() {
|
||||
return team;
|
||||
}
|
||||
|
||||
public void setTeam(int team) {
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
public int getVenomMulti() {
|
||||
return this.VenomMultiplier;
|
||||
}
|
||||
|
||||
public void setVenomMulti(int multiplier) {
|
||||
this.VenomMultiplier = multiplier;
|
||||
}
|
||||
|
||||
public MapleMonsterStats getStats() {
|
||||
return stats;
|
||||
}
|
||||
|
||||
public boolean isBoss() {
|
||||
return stats.isBoss() || isHT();
|
||||
}
|
||||
|
||||
public int getAnimationTime(String name) {
|
||||
return stats.getAnimationTime(name);
|
||||
}
|
||||
|
||||
private List<Integer> getRevives() {
|
||||
return stats.getRevives();
|
||||
}
|
||||
|
||||
private byte getTagColor() {
|
||||
return stats.getTagColor();
|
||||
}
|
||||
|
||||
private byte getTagBgColor() {
|
||||
return stats.getTagBgColor();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param from the player that dealt the damage
|
||||
* @param damage
|
||||
*/
|
||||
public synchronized void damage(MapleCharacter from, int damage) { // may be pointless synchronization
|
||||
if (!isAlive()) {
|
||||
return;
|
||||
}
|
||||
int trueDamage = Math.min(hp, damage); // since magic happens otherwise B^)
|
||||
|
||||
if(ServerConstants.USE_DEBUG == true && from != null) from.dropMessage(5, "Hitted MOB " + this.getId());
|
||||
|
||||
hp -= damage;
|
||||
if (takenDamage.containsKey(from.getId())) {
|
||||
takenDamage.get(from.getId()).addAndGet(trueDamage);
|
||||
} else {
|
||||
takenDamage.put(from.getId(), new AtomicInteger(trueDamage));
|
||||
}
|
||||
|
||||
if (hasBossHPBar()) {
|
||||
from.getMap().broadcastMessage(makeBossHPBarPacket(), getPosition());
|
||||
} else if (!isBoss()) {
|
||||
int remainingHP = (int) Math.max(1, hp * 100f / getMaxHp());
|
||||
byte[] packet = MaplePacketCreator.showMonsterHP(getObjectId(), remainingHP);
|
||||
if (from.getParty() != null) {
|
||||
for (MaplePartyCharacter mpc : from.getParty().getMembers()) {
|
||||
MapleCharacter member = from.getMap().getCharacterById(mpc.getId()); // god bless
|
||||
if (member != null) {
|
||||
member.announce(packet.clone()); // clone it just in case of crypto
|
||||
}
|
||||
}
|
||||
} else {
|
||||
from.announce(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void heal(int hp, int mp) {
|
||||
int hp2Heal = getHp() + hp;
|
||||
int mp2Heal = getMp() + mp;
|
||||
if (hp2Heal >= getMaxHp()) {
|
||||
hp2Heal = getMaxHp();
|
||||
}
|
||||
if (mp2Heal >= getMaxMp()) {
|
||||
mp2Heal = getMaxMp();
|
||||
}
|
||||
setHp(hp2Heal);
|
||||
setMp(mp2Heal);
|
||||
getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp));
|
||||
}
|
||||
|
||||
public boolean isAttackedBy(MapleCharacter chr) {
|
||||
return takenDamage.containsKey(chr.getId());
|
||||
}
|
||||
|
||||
private void distributeExperienceToParty(int pid, int exp, int killer, Map<Integer, Integer> expDist) {
|
||||
LinkedList<MapleCharacter> members = new LinkedList<>();
|
||||
|
||||
map.getCharacterReadLock().lock();
|
||||
Collection<MapleCharacter> chrs = map.getCharacters();
|
||||
try {
|
||||
for (MapleCharacter mc : chrs) {
|
||||
if (mc.getPartyId() == pid) {
|
||||
members.add(mc);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
map.getCharacterReadLock().unlock();
|
||||
}
|
||||
|
||||
final int minLevel = getLevel() - 5;
|
||||
|
||||
int partyLevel = 0;
|
||||
int leechMinLevel = 0;
|
||||
|
||||
for (MapleCharacter mc : members) {
|
||||
if (mc.getLevel() >= minLevel) {
|
||||
leechMinLevel = Math.min(mc.getLevel() - 5, minLevel);
|
||||
}
|
||||
}
|
||||
|
||||
int leechCount = 0;
|
||||
for (MapleCharacter mc : members) {
|
||||
if (mc.getLevel() >= leechMinLevel) {
|
||||
partyLevel += mc.getLevel();
|
||||
leechCount++;
|
||||
}
|
||||
}
|
||||
|
||||
final int mostDamageCid = getHighestDamagerId();
|
||||
|
||||
for (MapleCharacter mc : members) {
|
||||
int id = mc.getId();
|
||||
int level = mc.getLevel();
|
||||
if (expDist.containsKey(id)
|
||||
|| level >= leechMinLevel) {
|
||||
boolean isKiller = killer == id;
|
||||
boolean mostDamage = mostDamageCid == id;
|
||||
int xp = (int) (exp * 0.80f * level / partyLevel);
|
||||
if (mostDamage) {
|
||||
xp += (exp * 0.20f);
|
||||
}
|
||||
giveExpToCharacter(mc, xp, isKiller, leechCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void distributeExperience(int killerId) {
|
||||
if (isAlive()) {
|
||||
return;
|
||||
}
|
||||
int exp = getExp();
|
||||
int totalHealth = getMaxHp();
|
||||
Map<Integer, Integer> expDist = new HashMap<>();
|
||||
Map<Integer, Integer> partyExp = new HashMap<>();
|
||||
// 80% of pool is split amongst all the damagers
|
||||
for (Entry<Integer, AtomicInteger> damage : takenDamage.entrySet()) {
|
||||
expDist.put(damage.getKey(), (int) (0.80f * exp * damage.getValue().get() / totalHealth));
|
||||
}
|
||||
map.getCharacterReadLock().lock(); // avoid concurrent mod
|
||||
Collection<MapleCharacter> chrs = map.getCharacters();
|
||||
try {
|
||||
for (MapleCharacter mc : chrs) {
|
||||
if (expDist.containsKey(mc.getId())) {
|
||||
boolean isKiller = mc.getId() == killerId;
|
||||
int xp = expDist.get(mc.getId());
|
||||
if (isKiller) {
|
||||
xp += exp / 5;
|
||||
}
|
||||
MapleParty p = mc.getParty();
|
||||
if (p != null) {
|
||||
int pID = p.getId();
|
||||
int pXP = xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
|
||||
partyExp.put(pID, pXP);
|
||||
} else {
|
||||
giveExpToCharacter(mc, xp, isKiller, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
map.getCharacterReadLock().unlock();
|
||||
}
|
||||
for (Entry<Integer, Integer> party : partyExp.entrySet()) {
|
||||
distributeExperienceToParty(party.getKey(), party.getValue(), killerId, expDist);
|
||||
}
|
||||
}
|
||||
|
||||
public void giveExpToCharacter(MapleCharacter attacker, int exp, boolean isKiller, int numExpSharers) {
|
||||
if (isKiller) {
|
||||
if (eventInstance != null) {
|
||||
eventInstance.monsterKilled(attacker, this);
|
||||
}
|
||||
}
|
||||
final int partyModifier = numExpSharers > 1 ? (110 + (5 * (numExpSharers - 2))) : 0;
|
||||
|
||||
int partyExp = 0;
|
||||
|
||||
if (attacker.getHp() > 0) {
|
||||
int personalExp = exp * attacker.getExpRate();
|
||||
|
||||
if (exp > 0) {
|
||||
if (partyModifier > 0) {
|
||||
partyExp = (int) (personalExp * ServerConstants.PARTY_EXPERIENCE_MOD * partyModifier / 1000f);
|
||||
}
|
||||
Integer holySymbol = attacker.getBuffedValue(MapleBuffStat.HOLY_SYMBOL);
|
||||
boolean GMHolySymbol = attacker.getBuffSource(MapleBuffStat.HOLY_SYMBOL) == SuperGM.HOLY_SYMBOL;
|
||||
if (holySymbol != null) {
|
||||
if (numExpSharers == 1 && !GMHolySymbol) {
|
||||
personalExp *= 1.0 + (holySymbol.doubleValue() / 500.0);
|
||||
} else {
|
||||
personalExp *= 1.0 + (holySymbol.doubleValue() / 100.0);
|
||||
}
|
||||
}
|
||||
if (stati.containsKey(MonsterStatus.SHOWDOWN)) {
|
||||
personalExp *= (stati.get(MonsterStatus.SHOWDOWN).getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0);
|
||||
}
|
||||
}
|
||||
if (exp < 0) {//O.O ><
|
||||
personalExp = Integer.MAX_VALUE;
|
||||
}
|
||||
attacker.gainExp(personalExp, partyExp, true, false, isKiller);
|
||||
attacker.mobKilled(getId());
|
||||
attacker.increaseEquipExp(personalExp);//better place
|
||||
}
|
||||
}
|
||||
|
||||
public MapleCharacter killBy(MapleCharacter killer) {
|
||||
distributeExperience(killer != null ? killer.getId() : 0);
|
||||
|
||||
if (getController() != null) { // this can/should only happen when a hidden gm attacks the monster
|
||||
getController().getClient().announce(MaplePacketCreator.stopControllingMonster(this.getObjectId()));
|
||||
getController().stopControllingMonster(this);
|
||||
}
|
||||
|
||||
final List<Integer> toSpawn = this.getRevives(); // this doesn't work (?)
|
||||
if (toSpawn != null) {
|
||||
final MapleMap reviveMap = killer.getMap();
|
||||
if (toSpawn.contains(9300216) && reviveMap.getId() > 925000000 && reviveMap.getId() < 926000000) {
|
||||
reviveMap.broadcastMessage(MaplePacketCreator.playSound("Dojang/clear"));
|
||||
reviveMap.broadcastMessage(MaplePacketCreator.showEffect("dojang/end/clear"));
|
||||
}
|
||||
Pair<Integer, String> timeMob = reviveMap.getTimeMob();
|
||||
if (timeMob != null) {
|
||||
if (toSpawn.contains(timeMob.getLeft())) {
|
||||
reviveMap.broadcastMessage(MaplePacketCreator.serverNotice(6, timeMob.getRight()));
|
||||
}
|
||||
|
||||
if (timeMob.getLeft() == 9300338 && (reviveMap.getId() >= 922240100 && reviveMap.getId() <= 922240119)) {
|
||||
if (!reviveMap.containsNPC(9001108)) {
|
||||
MapleNPC npc = MapleLifeFactory.getNPC(9001108);
|
||||
npc.setPosition(new Point(172, 9));
|
||||
npc.setCy(9);
|
||||
npc.setRx0(172 + 50);
|
||||
npc.setRx1(172 - 50);
|
||||
npc.setFh(27);
|
||||
reviveMap.addMapObject(npc);
|
||||
reviveMap.broadcastMessage(MaplePacketCreator.spawnNPC(npc));
|
||||
} else {
|
||||
reviveMap.toggleHiddenNPC(9001108);
|
||||
}
|
||||
}
|
||||
}
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Integer mid : toSpawn) {
|
||||
final MapleMonster mob = MapleLifeFactory.getMonster(mid);
|
||||
mob.setPosition(getPosition());
|
||||
if (dropsDisabled()) {
|
||||
mob.disableDrops();
|
||||
}
|
||||
reviveMap.spawnMonster(mob);
|
||||
}
|
||||
}
|
||||
}, getAnimationTime("die1"));
|
||||
}
|
||||
if (eventInstance != null) {
|
||||
if (!this.getStats().isFriendly()) {
|
||||
eventInstance.monsterKilled(this);
|
||||
}
|
||||
}
|
||||
// idk V just a troll
|
||||
for (MonsterListener listener : listeners.toArray(new MonsterListener[listeners.size()])) {
|
||||
listener.monsterKilled(getAnimationTime("die1"));
|
||||
}
|
||||
|
||||
MapleCharacter looter = map.getCharacterById(getHighestDamagerId());
|
||||
|
||||
return looter != null ? looter : killer;
|
||||
}
|
||||
|
||||
// should only really be used to determine drop owner
|
||||
private int getHighestDamagerId() {
|
||||
int curId = 0;
|
||||
int curDmg = 0;
|
||||
|
||||
for (Entry<Integer, AtomicInteger> damage : takenDamage.entrySet()) {
|
||||
curId = damage.getValue().get() >= curDmg ? damage.getKey() : curId;
|
||||
curDmg = damage.getKey() == curId ? damage.getValue().get() : curDmg;
|
||||
}
|
||||
|
||||
return curId;
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return this.hp > 0;
|
||||
}
|
||||
|
||||
public MapleCharacter getController() {
|
||||
return controller.get();
|
||||
}
|
||||
|
||||
public void setController(MapleCharacter controller) {
|
||||
this.controller = new WeakReference<>(controller);
|
||||
}
|
||||
|
||||
public void switchController(MapleCharacter newController, boolean immediateAggro) {
|
||||
MapleCharacter controllers = getController();
|
||||
if (controllers == newController) {
|
||||
return;
|
||||
}
|
||||
if (controllers != null) {
|
||||
controllers.stopControllingMonster(this);
|
||||
controllers.getClient().announce(MaplePacketCreator.stopControllingMonster(getObjectId()));
|
||||
}
|
||||
newController.controlMonster(this, immediateAggro);
|
||||
setController(newController);
|
||||
if (immediateAggro) {
|
||||
setControllerHasAggro(true);
|
||||
}
|
||||
setControllerKnowsAboutAggro(false);
|
||||
}
|
||||
|
||||
public void addListener(MonsterListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public boolean isControllerHasAggro() {
|
||||
return fake ? false : controllerHasAggro;
|
||||
}
|
||||
|
||||
public void setControllerHasAggro(boolean controllerHasAggro) {
|
||||
if (fake) {
|
||||
return;
|
||||
}
|
||||
this.controllerHasAggro = controllerHasAggro;
|
||||
}
|
||||
|
||||
public boolean isControllerKnowsAboutAggro() {
|
||||
return fake ? false : controllerKnowsAboutAggro;
|
||||
}
|
||||
|
||||
public void setControllerKnowsAboutAggro(boolean controllerKnowsAboutAggro) {
|
||||
if (fake) {
|
||||
return;
|
||||
}
|
||||
this.controllerKnowsAboutAggro = controllerKnowsAboutAggro;
|
||||
}
|
||||
|
||||
public byte[] makeBossHPBarPacket() {
|
||||
return MaplePacketCreator.showBossHP(getId(), getHp(), getMaxHp(), getTagColor(), getTagBgColor());
|
||||
}
|
||||
|
||||
public boolean hasBossHPBar() {
|
||||
return (isBoss() && getTagColor() > 0) || isHT();
|
||||
}
|
||||
|
||||
private boolean isHT() {
|
||||
return getId() == 8810018;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient c) {
|
||||
if (!isAlive()) {
|
||||
return;
|
||||
}
|
||||
if (isFake()) {
|
||||
c.announce(MaplePacketCreator.spawnFakeMonster(this, 0));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.spawnMonster(this, false));
|
||||
}
|
||||
if (stati.size() > 0) {
|
||||
for (final MonsterStatusEffect mse : this.stati.values()) {
|
||||
c.announce(MaplePacketCreator.applyMonsterStatus(getObjectId(), mse, null));
|
||||
}
|
||||
}
|
||||
if (hasBossHPBar()) {
|
||||
if (this.getMap().countMonster(8810026) > 0 && this.getMap().getId() == 240060200) {
|
||||
this.getMap().killAllMonsters();
|
||||
return;
|
||||
}
|
||||
c.announce(makeBossHPBarPacket());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.killMonster(getObjectId(), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.MONSTER;
|
||||
}
|
||||
|
||||
public void setEventInstance(EventInstanceManager eventInstance) {
|
||||
this.eventInstance = eventInstance;
|
||||
}
|
||||
|
||||
public EventInstanceManager getEventInstance() {
|
||||
return eventInstance;
|
||||
}
|
||||
|
||||
public boolean isMobile() {
|
||||
return stats.isMobile();
|
||||
}
|
||||
|
||||
public ElementalEffectiveness getEffectiveness(Element e) {
|
||||
if (stati.size() > 0 && stati.get(MonsterStatus.DOOM) != null) {
|
||||
return ElementalEffectiveness.NORMAL; // like blue snails
|
||||
}
|
||||
return stats.getEffectiveness(e);
|
||||
}
|
||||
|
||||
public boolean applyStatus(MapleCharacter from, final MonsterStatusEffect status, boolean poison, long duration) {
|
||||
return applyStatus(from, status, poison, duration, false);
|
||||
}
|
||||
|
||||
public boolean applyStatus(MapleCharacter from, final MonsterStatusEffect status, boolean poison, long duration, boolean venom) {
|
||||
switch (stats.getEffectiveness(status.getSkill().getElement())) {
|
||||
case IMMUNE:
|
||||
case STRONG:
|
||||
case NEUTRAL:
|
||||
return false;
|
||||
case NORMAL:
|
||||
case WEAK:
|
||||
break;
|
||||
default: {
|
||||
System.out.println("Unknown elemental effectiveness: " + stats.getEffectiveness(status.getSkill().getElement()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (status.getSkill().getId() == FPMage.ELEMENT_COMPOSITION) { // fp compo
|
||||
ElementalEffectiveness effectiveness = stats.getEffectiveness(Element.POISON);
|
||||
if (effectiveness == ElementalEffectiveness.IMMUNE || effectiveness == ElementalEffectiveness.STRONG) {
|
||||
return false;
|
||||
}
|
||||
} else if (status.getSkill().getId() == ILMage.ELEMENT_COMPOSITION) { // il compo
|
||||
ElementalEffectiveness effectiveness = stats.getEffectiveness(Element.ICE);
|
||||
if (effectiveness == ElementalEffectiveness.IMMUNE || effectiveness == ElementalEffectiveness.STRONG) {
|
||||
return false;
|
||||
}
|
||||
} else if (status.getSkill().getId() == NightLord.VENOMOUS_STAR || status.getSkill().getId() == Shadower.VENOMOUS_STAB || status.getSkill().getId() == NightWalker.VENOM) {// venom
|
||||
if (stats.getEffectiveness(Element.POISON) == ElementalEffectiveness.WEAK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (poison && getHp() <= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Map<MonsterStatus, Integer> statis = status.getStati();
|
||||
if (stats.isBoss()) {
|
||||
if (!(statis.containsKey(MonsterStatus.SPEED)
|
||||
&& statis.containsKey(MonsterStatus.NINJA_AMBUSH)
|
||||
&& statis.containsKey(MonsterStatus.WATK))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (MonsterStatus stat : statis.keySet()) {
|
||||
final MonsterStatusEffect oldEffect = stati.get(stat);
|
||||
if (oldEffect != null) {
|
||||
oldEffect.removeActiveStatus(stat);
|
||||
if (oldEffect.getStati().isEmpty()) {
|
||||
oldEffect.cancelTask();
|
||||
oldEffect.cancelDamageSchedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimerManager timerManager = TimerManager.getInstance();
|
||||
final Runnable cancelTask = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAlive()) {
|
||||
byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), status.getStati());
|
||||
map.broadcastMessage(packet, getPosition());
|
||||
if (getController() != null && !getController().isMapObjectVisible(MapleMonster.this)) {
|
||||
getController().getClient().announce(packet);
|
||||
}
|
||||
}
|
||||
for (MonsterStatus stat : status.getStati().keySet()) {
|
||||
stati.remove(stat);
|
||||
}
|
||||
setVenomMulti(0);
|
||||
status.cancelDamageSchedule();
|
||||
}
|
||||
};
|
||||
if (poison) {
|
||||
int poisonLevel = from.getSkillLevel(status.getSkill());
|
||||
int poisonDamage = Math.min(Short.MAX_VALUE, (int) (getMaxHp() / (70.0 - poisonLevel) + 0.999));
|
||||
status.setValue(MonsterStatus.POISON, Integer.valueOf(poisonDamage));
|
||||
status.setDamageSchedule(timerManager.register(new DamageTask(poisonDamage, from, status, cancelTask, 0), 1000, 1000));
|
||||
} else if (venom) {
|
||||
if (from.getJob() == MapleJob.NIGHTLORD || from.getJob() == MapleJob.SHADOWER || from.getJob().isA(MapleJob.NIGHTWALKER3)) {
|
||||
int poisonLevel, matk, id = from.getJob().getId();
|
||||
int skill = (id == 412 ? NightLord.VENOMOUS_STAR : (id == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM));
|
||||
poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skill));
|
||||
if (poisonLevel <= 0) {
|
||||
return false;
|
||||
}
|
||||
matk = SkillFactory.getSkill(skill).getEffect(poisonLevel).getMatk();
|
||||
int luk = from.getLuk();
|
||||
int maxDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.2 * luk * matk));
|
||||
int minDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.1 * luk * matk));
|
||||
int gap = maxDmg - minDmg;
|
||||
if (gap == 0) {
|
||||
gap = 1;
|
||||
}
|
||||
int poisonDamage = 0;
|
||||
for (int i = 0; i < getVenomMulti(); i++) {
|
||||
poisonDamage += (Randomizer.nextInt(gap) + minDmg);
|
||||
}
|
||||
poisonDamage = Math.min(Short.MAX_VALUE, poisonDamage);
|
||||
status.setValue(MonsterStatus.VENOMOUS_WEAPON, Integer.valueOf(poisonDamage));
|
||||
status.setDamageSchedule(timerManager.register(new DamageTask(poisonDamage, from, status, cancelTask, 0), 1000, 1000));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (status.getSkill().getId() == Hermit.SHADOW_WEB || status.getSkill().getId() == NightWalker.SHADOW_WEB) { //Shadow Web
|
||||
status.setDamageSchedule(timerManager.schedule(new DamageTask((int) (getMaxHp() / 50.0 + 0.999), from, status, cancelTask, 1), 3500));
|
||||
} else if (status.getSkill().getId() == 4121004 || status.getSkill().getId() == 4221004) { // Ninja Ambush
|
||||
final Skill skill = SkillFactory.getSkill(status.getSkill().getId());
|
||||
final byte level = from.getSkillLevel(skill);
|
||||
final int damage = (int) ((from.getStr() + from.getLuk()) * (1.5 + (level * 0.05)) * skill.getEffect(level).getDamage());
|
||||
/*if (getHp() - damage <= 1) { make hp 1 betch
|
||||
damage = getHp() - (getHp() - 1);
|
||||
}*/
|
||||
|
||||
status.setValue(MonsterStatus.NINJA_AMBUSH, Integer.valueOf(damage));
|
||||
status.setDamageSchedule(timerManager.register(new DamageTask(damage, from, status, cancelTask, 2), 1000, 1000));
|
||||
}
|
||||
for (MonsterStatus stat : status.getStati().keySet()) {
|
||||
stati.put(stat, status);
|
||||
alreadyBuffed.add(stat);
|
||||
}
|
||||
int animationTime = status.getSkill().getAnimationTime();
|
||||
byte[] packet = MaplePacketCreator.applyMonsterStatus(getObjectId(), status, null);
|
||||
map.broadcastMessage(packet, getPosition());
|
||||
if (getController() != null && !getController().isMapObjectVisible(this)) {
|
||||
getController().getClient().announce(packet);
|
||||
}
|
||||
status.setCancelTask(timerManager.schedule(cancelTask, duration + animationTime));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void applyMonsterBuff(final Map<MonsterStatus, Integer> stats, final int x, int skillId, long duration, MobSkill skill, final List<Integer> reflection) {
|
||||
TimerManager timerManager = TimerManager.getInstance();
|
||||
final Runnable cancelTask = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAlive()) {
|
||||
byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), stats);
|
||||
map.broadcastMessage(packet, getPosition());
|
||||
if (getController() != null && !getController().isMapObjectVisible(MapleMonster.this)) {
|
||||
getController().getClient().announce(packet);
|
||||
}
|
||||
for (final MonsterStatus stat : stats.keySet()) {
|
||||
stati.remove(stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
final MonsterStatusEffect effect = new MonsterStatusEffect(stats, null, skill, true);
|
||||
byte[] packet = MaplePacketCreator.applyMonsterStatus(getObjectId(), effect, reflection);
|
||||
map.broadcastMessage(packet, getPosition());
|
||||
for (MonsterStatus stat : stats.keySet()) {
|
||||
stati.put(stat, effect);
|
||||
alreadyBuffed.add(stat);
|
||||
}
|
||||
if (getController() != null && !getController().isMapObjectVisible(this)) {
|
||||
getController().getClient().announce(packet);
|
||||
}
|
||||
effect.setCancelTask(timerManager.schedule(cancelTask, duration));
|
||||
}
|
||||
|
||||
public void debuffMob(int skillid) {
|
||||
//skillid is not going to be used for now until I get warrior debuff working
|
||||
MonsterStatus[] stats = {MonsterStatus.WEAPON_ATTACK_UP, MonsterStatus.WEAPON_DEFENSE_UP, MonsterStatus.MAGIC_ATTACK_UP, MonsterStatus.MAGIC_DEFENSE_UP};
|
||||
for (int i = 0; i < stats.length; i++) {
|
||||
if (isBuffed(stats[i])) {
|
||||
final MonsterStatusEffect oldEffect = stati.get(stats[i]);
|
||||
byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), oldEffect.getStati());
|
||||
map.broadcastMessage(packet, getPosition());
|
||||
if (getController() != null && !getController().isMapObjectVisible(MapleMonster.this)) {
|
||||
getController().getClient().announce(packet);
|
||||
}
|
||||
stati.remove(stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBuffed(MonsterStatus status) {
|
||||
return stati.containsKey(status);
|
||||
}
|
||||
|
||||
public void setFake(boolean fake) {
|
||||
this.fake = fake;
|
||||
}
|
||||
|
||||
public boolean isFake() {
|
||||
return fake;
|
||||
}
|
||||
|
||||
public MapleMap getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<Pair<Integer, Integer>> getSkills() {
|
||||
return stats.getSkills();
|
||||
}
|
||||
|
||||
public boolean hasSkill(int skillId, int level) {
|
||||
return stats.hasSkill(skillId, level);
|
||||
}
|
||||
|
||||
public boolean canUseSkill(MobSkill toUse) {
|
||||
if (toUse == null) {
|
||||
return false;
|
||||
}
|
||||
for (Pair<Integer, Integer> skill : usedSkills) {
|
||||
if (skill.getLeft() == toUse.getSkillId() && skill.getRight() == toUse.getSkillLevel()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (toUse.getLimit() > 0) {
|
||||
if (this.skillsUsed.containsKey(new Pair<>(toUse.getSkillId(), toUse.getSkillLevel()))) {
|
||||
int times = this.skillsUsed.get(new Pair<>(toUse.getSkillId(), toUse.getSkillLevel()));
|
||||
if (times >= toUse.getLimit()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toUse.getSkillId() == 200) {
|
||||
Collection<MapleMapObject> mmo = getMap().getMapObjects();
|
||||
int i = 0;
|
||||
for (MapleMapObject mo : mmo) {
|
||||
if (mo.getType() == MapleMapObjectType.MONSTER) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (i > 100) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void usedSkill(final int skillId, final int level, long cooltime) {
|
||||
this.usedSkills.add(new Pair<>(skillId, level));
|
||||
if (this.skillsUsed.containsKey(new Pair<>(skillId, level))) {
|
||||
int times = this.skillsUsed.get(new Pair<>(skillId, level)) + 1;
|
||||
this.skillsUsed.remove(new Pair<>(skillId, level));
|
||||
this.skillsUsed.put(new Pair<>(skillId, level), times);
|
||||
} else {
|
||||
this.skillsUsed.put(new Pair<>(skillId, level), 1);
|
||||
}
|
||||
final MapleMonster mons = this;
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
tMan.schedule(
|
||||
new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mons.clearSkill(skillId, level);
|
||||
}
|
||||
}, cooltime);
|
||||
}
|
||||
|
||||
public void clearSkill(int skillId, int level) {
|
||||
int index = -1;
|
||||
for (Pair<Integer, Integer> skill : usedSkills) {
|
||||
if (skill.getLeft() == skillId && skill.getRight() == level) {
|
||||
index = usedSkills.indexOf(skill);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index != -1) {
|
||||
usedSkills.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNoSkills() {
|
||||
return this.stats.getNoSkills();
|
||||
}
|
||||
|
||||
public boolean isFirstAttack() {
|
||||
return this.stats.isFirstAttack();
|
||||
}
|
||||
|
||||
public int getBuffToGive() {
|
||||
return this.stats.getBuffToGive();
|
||||
}
|
||||
|
||||
private final class DamageTask implements Runnable {
|
||||
|
||||
private final int dealDamage;
|
||||
private final MapleCharacter chr;
|
||||
private final MonsterStatusEffect status;
|
||||
private final Runnable cancelTask;
|
||||
private final int type;
|
||||
private final MapleMap map;
|
||||
|
||||
private DamageTask(int dealDamage, MapleCharacter chr, MonsterStatusEffect status, Runnable cancelTask, int type) {
|
||||
this.dealDamage = dealDamage;
|
||||
this.chr = chr;
|
||||
this.status = status;
|
||||
this.cancelTask = cancelTask;
|
||||
this.type = type;
|
||||
this.map = chr.getMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int damage = dealDamage;
|
||||
if (damage >= hp) {
|
||||
damage = hp - 1;
|
||||
if (type == 1 || type == 2) {
|
||||
map.broadcastMessage(MaplePacketCreator.damageMonster(getObjectId(), damage), getPosition());
|
||||
cancelTask.run();
|
||||
status.getCancelTask().cancel(false);
|
||||
}
|
||||
}
|
||||
if (hp > 1 && damage > 0) {
|
||||
damage(chr, damage);
|
||||
if (type == 1) {
|
||||
map.broadcastMessage(MaplePacketCreator.damageMonster(getObjectId(), damage), getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return stats.getName();
|
||||
}
|
||||
|
||||
public void addStolen(int itemId) {
|
||||
stolenItems.add(itemId);
|
||||
}
|
||||
|
||||
public List<Integer> getStolen() {
|
||||
return stolenItems;
|
||||
}
|
||||
|
||||
public void setTempEffectiveness(Element e, ElementalEffectiveness ee, long milli) {
|
||||
final Element fE = e;
|
||||
final ElementalEffectiveness fEE = stats.getEffectiveness(e);
|
||||
if (!stats.getEffectiveness(e).equals(ElementalEffectiveness.WEAK)) {
|
||||
stats.setEffectiveness(e, ee);
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
stats.removeEffectiveness(fE);
|
||||
stats.setEffectiveness(fE, fEE);
|
||||
}
|
||||
}, milli);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<MonsterStatus> alreadyBuffedStats() {
|
||||
return Collections.unmodifiableCollection(alreadyBuffed);
|
||||
}
|
||||
|
||||
public BanishInfo getBanish() {
|
||||
return stats.getBanishInfo();
|
||||
}
|
||||
|
||||
public void setBoss(boolean boss) {
|
||||
this.stats.setBoss(boss);
|
||||
}
|
||||
|
||||
public int getDropPeriodTime() {
|
||||
return stats.getDropPeriod();
|
||||
}
|
||||
|
||||
public int getPADamage() {
|
||||
return stats.getPADamage();
|
||||
}
|
||||
|
||||
public Map<MonsterStatus, MonsterStatusEffect> getStati() {
|
||||
return stati;
|
||||
}
|
||||
}
|
||||
171
src/server/life/MapleMonsterInformationProvider.java
Normal file
171
src/server/life/MapleMonsterInformationProvider.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
|
||||
public class MapleMonsterInformationProvider {
|
||||
// Author : LightPepsi
|
||||
|
||||
private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider();
|
||||
private final Map<Integer, List<MonsterDropEntry>> drops = new HashMap<>();
|
||||
private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList<>();
|
||||
|
||||
protected MapleMonsterInformationProvider() {
|
||||
retrieveGlobal();
|
||||
}
|
||||
|
||||
public static MapleMonsterInformationProvider getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public final List<MonsterGlobalDropEntry> getGlobalDrop() {
|
||||
return globaldrops;
|
||||
}
|
||||
|
||||
private void retrieveGlobal() {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
final Connection con = DatabaseConnection.getConnection();
|
||||
ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0");
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
globaldrops.add(
|
||||
new MonsterGlobalDropEntry(
|
||||
rs.getInt("itemid"),
|
||||
rs.getInt("chance"),
|
||||
rs.getInt("continent"),
|
||||
rs.getByte("dropType"),
|
||||
rs.getInt("minimum_quantity"),
|
||||
rs.getInt("maximum_quantity"),
|
||||
rs.getShort("questid")));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Error retrieving drop" + e);
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final List<MonsterDropEntry> retrieveDrop(final int monsterId) {
|
||||
if (drops.containsKey(monsterId)) {
|
||||
return drops.get(monsterId);
|
||||
}
|
||||
final List<MonsterDropEntry> ret = new LinkedList<>();
|
||||
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM drop_data WHERE dropperid = ?");
|
||||
ps.setInt(1, monsterId);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
ret.add(
|
||||
new MonsterDropEntry(
|
||||
rs.getInt("itemid"),
|
||||
rs.getInt("chance"),
|
||||
rs.getInt("minimum_quantity"),
|
||||
rs.getInt("maximum_quantity"),
|
||||
rs.getShort("questid")));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
return ret;
|
||||
} finally {
|
||||
try {
|
||||
if (ps != null) {
|
||||
ps.close();
|
||||
}
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
} catch (SQLException ignore) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
drops.put(monsterId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ArrayList<Pair<Integer, String>> getMobsIDsFromName(String search)
|
||||
{
|
||||
MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz"));
|
||||
ArrayList<Pair<Integer, String>> retMobs = new ArrayList<Pair<Integer, String>>();
|
||||
MapleData data = dataProvider.getData("Mob.img");
|
||||
List<Pair<Integer, String>> mobPairList = new LinkedList<Pair<Integer, String>>();
|
||||
for (MapleData mobIdData : data.getChildren()) {
|
||||
int mobIdFromData = Integer.parseInt(mobIdData.getName());
|
||||
String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME");
|
||||
mobPairList.add(new Pair<Integer, String>(mobIdFromData, mobNameFromData));
|
||||
}
|
||||
for (Pair<Integer, String> mobPair : mobPairList) {
|
||||
if (mobPair.getRight().toLowerCase().contains(search.toLowerCase())) {
|
||||
retMobs.add(mobPair);
|
||||
}
|
||||
}
|
||||
return retMobs;
|
||||
}
|
||||
|
||||
public static String getMobNameFromID(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return MapleLifeFactory.getMonster(id).getName();
|
||||
} catch (Exception e)
|
||||
{
|
||||
return null; //nonexistant mob
|
||||
}
|
||||
}
|
||||
|
||||
public final void clearDrops() {
|
||||
drops.clear();
|
||||
globaldrops.clear();
|
||||
retrieveGlobal();
|
||||
}
|
||||
}
|
||||
327
src/server/life/MapleMonsterStats.java
Normal file
327
src/server/life/MapleMonsterStats.java
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import server.life.MapleLifeFactory.BanishInfo;
|
||||
import server.life.MapleLifeFactory.loseItem;
|
||||
import server.life.MapleLifeFactory.selfDestruction;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
* @author Frz
|
||||
*/
|
||||
public class MapleMonsterStats {
|
||||
private int exp, hp, mp, level, PADamage, PDDamage, MADamage, MDDamage, dropPeriod, cp, buffToGive, removeAfter;
|
||||
private boolean boss, undead, ffaLoot, isExplosiveReward, firstAttack, removeOnMiss;
|
||||
private String name;
|
||||
private Map<String, Integer> animationTimes = new HashMap<String, Integer>();
|
||||
private Map<Element, ElementalEffectiveness> resistance = new HashMap<Element, ElementalEffectiveness>();
|
||||
private List<Integer> revives = Collections.emptyList();
|
||||
private byte tagColor, tagBgColor;
|
||||
private List<Pair<Integer, Integer>> skills = new ArrayList<Pair<Integer, Integer>>();
|
||||
private Pair<Integer, Integer> cool = null;
|
||||
private BanishInfo banish = null;
|
||||
private List<loseItem> loseItem = null;
|
||||
private selfDestruction selfDestruction = null;
|
||||
private boolean friendly;
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
public void setExp(int exp) {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public void setHp(int hp) {
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
}
|
||||
|
||||
public void setMp(int mp) {
|
||||
this.mp = mp;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int removeAfter() {
|
||||
return removeAfter;
|
||||
}
|
||||
|
||||
public void setRemoveAfter(int removeAfter) {
|
||||
this.removeAfter = removeAfter;
|
||||
}
|
||||
|
||||
public int getDropPeriod() {
|
||||
return dropPeriod;
|
||||
}
|
||||
|
||||
public void setDropPeriod(int dropPeriod) {
|
||||
this.dropPeriod = dropPeriod;
|
||||
}
|
||||
|
||||
public void setBoss(boolean boss) {
|
||||
this.boss = boss;
|
||||
}
|
||||
|
||||
public boolean isBoss() {
|
||||
return boss;
|
||||
}
|
||||
|
||||
public void setFfaLoot(boolean ffaLoot) {
|
||||
this.ffaLoot = ffaLoot;
|
||||
}
|
||||
|
||||
public boolean isFfaLoot() {
|
||||
return ffaLoot;
|
||||
}
|
||||
|
||||
public void setAnimationTime(String name, int delay) {
|
||||
animationTimes.put(name, delay);
|
||||
}
|
||||
|
||||
public int getAnimationTime(String name) {
|
||||
Integer ret = animationTimes.get(name);
|
||||
if (ret == null) {
|
||||
return 500;
|
||||
}
|
||||
return ret.intValue();
|
||||
}
|
||||
|
||||
public boolean isMobile() {
|
||||
return animationTimes.containsKey("move") || animationTimes.containsKey("fly");
|
||||
}
|
||||
|
||||
public List<Integer> getRevives() {
|
||||
return revives;
|
||||
}
|
||||
|
||||
public void setRevives(List<Integer> revives) {
|
||||
this.revives = revives;
|
||||
}
|
||||
|
||||
public void setUndead(boolean undead) {
|
||||
this.undead = undead;
|
||||
}
|
||||
|
||||
public boolean getUndead() {
|
||||
return undead;
|
||||
}
|
||||
|
||||
public void setEffectiveness(Element e, ElementalEffectiveness ee) {
|
||||
resistance.put(e, ee);
|
||||
}
|
||||
|
||||
public ElementalEffectiveness getEffectiveness(Element e) {
|
||||
ElementalEffectiveness elementalEffectiveness = resistance.get(e);
|
||||
if (elementalEffectiveness == null) {
|
||||
return ElementalEffectiveness.NORMAL;
|
||||
} else {
|
||||
return elementalEffectiveness;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public byte getTagColor() {
|
||||
return tagColor;
|
||||
}
|
||||
|
||||
public void setTagColor(int tagColor) {
|
||||
this.tagColor = (byte) tagColor;
|
||||
}
|
||||
|
||||
public byte getTagBgColor() {
|
||||
return tagBgColor;
|
||||
}
|
||||
|
||||
public void setTagBgColor(int tagBgColor) {
|
||||
this.tagBgColor = (byte) tagBgColor;
|
||||
}
|
||||
|
||||
public void setSkills(List<Pair<Integer, Integer>> skills) {
|
||||
for (Pair<Integer, Integer> skill : skills) {
|
||||
this.skills.add(skill);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Pair<Integer, Integer>> getSkills() {
|
||||
return Collections.unmodifiableList(this.skills);
|
||||
}
|
||||
|
||||
public int getNoSkills() {
|
||||
return this.skills.size();
|
||||
}
|
||||
|
||||
public boolean hasSkill(int skillId, int level) {
|
||||
for (Pair<Integer, Integer> skill : skills) {
|
||||
if (skill.getLeft() == skillId && skill.getRight() == level) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setFirstAttack(boolean firstAttack) {
|
||||
this.firstAttack = firstAttack;
|
||||
}
|
||||
|
||||
public boolean isFirstAttack() {
|
||||
return firstAttack;
|
||||
}
|
||||
|
||||
public void setBuffToGive(int buff) {
|
||||
this.buffToGive = buff;
|
||||
}
|
||||
|
||||
public int getBuffToGive() {
|
||||
return buffToGive;
|
||||
}
|
||||
|
||||
void removeEffectiveness(Element e) {
|
||||
resistance.remove(e);
|
||||
}
|
||||
|
||||
public BanishInfo getBanishInfo() {
|
||||
return banish;
|
||||
}
|
||||
|
||||
public void setBanishInfo(BanishInfo banish) {
|
||||
this.banish = banish;
|
||||
}
|
||||
|
||||
public int getPADamage() {
|
||||
return PADamage;
|
||||
}
|
||||
|
||||
public void setPADamage(int PADamage) {
|
||||
this.PADamage = PADamage;
|
||||
}
|
||||
|
||||
public int getCP() {
|
||||
return cp;
|
||||
}
|
||||
|
||||
public void setCP(int cp) {
|
||||
this.cp = cp;
|
||||
}
|
||||
|
||||
public List<loseItem> loseItem() {
|
||||
return loseItem;
|
||||
}
|
||||
|
||||
public void addLoseItem(loseItem li) {
|
||||
if (loseItem == null) {
|
||||
loseItem = new LinkedList<loseItem>();
|
||||
}
|
||||
loseItem.add(li);
|
||||
}
|
||||
|
||||
public selfDestruction selfDestruction() {
|
||||
return selfDestruction;
|
||||
}
|
||||
|
||||
public void setSelfDestruction(selfDestruction sd) {
|
||||
this.selfDestruction = sd;
|
||||
}
|
||||
|
||||
public void setExplosiveReward(boolean isExplosiveReward) {
|
||||
this.isExplosiveReward = isExplosiveReward;
|
||||
}
|
||||
|
||||
public boolean isExplosiveReward() {
|
||||
return isExplosiveReward;
|
||||
}
|
||||
|
||||
public void setRemoveOnMiss(boolean removeOnMiss) {
|
||||
this.removeOnMiss = removeOnMiss;
|
||||
}
|
||||
|
||||
public boolean removeOnMiss() {
|
||||
return removeOnMiss;
|
||||
}
|
||||
|
||||
public void setCool(Pair<Integer, Integer> cool) {
|
||||
this.cool = cool;
|
||||
}
|
||||
|
||||
public Pair<Integer, Integer> getCool() {
|
||||
return cool;
|
||||
}
|
||||
|
||||
public int getPDDamage() {
|
||||
return PDDamage;
|
||||
}
|
||||
|
||||
public int getMADamage() {
|
||||
return MADamage;
|
||||
}
|
||||
|
||||
public int getMDDamage() {
|
||||
return MDDamage;
|
||||
}
|
||||
|
||||
public boolean isFriendly() {
|
||||
return friendly;
|
||||
}
|
||||
|
||||
public void setFriendly(boolean value) {
|
||||
this.friendly = value;
|
||||
}
|
||||
|
||||
public void setPDDamage(int PDDamage) {
|
||||
this.PDDamage = PDDamage;
|
||||
}
|
||||
|
||||
public void setMADamage(int MADamage) {
|
||||
this.MADamage = MADamage;
|
||||
}
|
||||
|
||||
public void setMDDamage(int MDDamage) {
|
||||
this.MDDamage = MDDamage;
|
||||
}
|
||||
}
|
||||
68
src/server/life/MapleNPC.java
Normal file
68
src/server/life/MapleNPC.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import client.MapleClient;
|
||||
import server.MapleShopFactory;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
public class MapleNPC extends AbstractLoadedMapleLife {
|
||||
private MapleNPCStats stats;
|
||||
|
||||
public MapleNPC(int id, MapleNPCStats stats) {
|
||||
super(id);
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
public boolean hasShop() {
|
||||
return MapleShopFactory.getInstance().getShopForNPC(getId()) != null;
|
||||
}
|
||||
|
||||
public void sendShop(MapleClient c) {
|
||||
MapleShopFactory.getInstance().getShopForNPC(getId()).sendShop(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
if (this.getId() > 9010010 && this.getId() < 9010014) {
|
||||
client.announce(MaplePacketCreator.spawnNPCRequestController(this, false));
|
||||
} else {
|
||||
client.announce(MaplePacketCreator.spawnNPC(this));
|
||||
client.announce(MaplePacketCreator.spawnNPCRequestController(this, true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.removeNPC(getObjectId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.NPC;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return stats.getName();
|
||||
}
|
||||
}
|
||||
42
src/server/life/MapleNPCStats.java
Normal file
42
src/server/life/MapleNPCStats.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleNPCStats {
|
||||
private String name;
|
||||
|
||||
public MapleNPCStats(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
77
src/server/life/MobAttackInfo.java
Normal file
77
src/server/life/MobAttackInfo.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Danny (Leifde)
|
||||
*/
|
||||
public class MobAttackInfo {
|
||||
private boolean isDeadlyAttack;
|
||||
private int mpBurn;
|
||||
private int diseaseSkill;
|
||||
private int diseaseLevel;
|
||||
private int mpCon;
|
||||
|
||||
public MobAttackInfo(int mobId, int attackId) {
|
||||
}
|
||||
|
||||
public void setDeadlyAttack(boolean isDeadlyAttack) {
|
||||
this.isDeadlyAttack = isDeadlyAttack;
|
||||
}
|
||||
|
||||
public boolean isDeadlyAttack() {
|
||||
return isDeadlyAttack;
|
||||
}
|
||||
|
||||
public void setMpBurn(int mpBurn) {
|
||||
this.mpBurn = mpBurn;
|
||||
}
|
||||
|
||||
public int getMpBurn() {
|
||||
return mpBurn;
|
||||
}
|
||||
|
||||
public void setDiseaseSkill(int diseaseSkill) {
|
||||
this.diseaseSkill = diseaseSkill;
|
||||
}
|
||||
|
||||
public int getDiseaseSkill() {
|
||||
return diseaseSkill;
|
||||
}
|
||||
|
||||
public void setDiseaseLevel(int diseaseLevel) {
|
||||
this.diseaseLevel = diseaseLevel;
|
||||
}
|
||||
|
||||
public int getDiseaseLevel() {
|
||||
return diseaseLevel;
|
||||
}
|
||||
|
||||
public void setMpCon(int mpCon) {
|
||||
this.mpCon = mpCon;
|
||||
}
|
||||
|
||||
public int getMpCon() {
|
||||
return mpCon;
|
||||
}
|
||||
}
|
||||
79
src/server/life/MobAttackInfoFactory.java
Normal file
79
src/server/life/MobAttackInfoFactory.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import tools.StringUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Danny (Leifde)
|
||||
*/
|
||||
public class MobAttackInfoFactory {
|
||||
private static Map<String, MobAttackInfo> mobAttacks = new HashMap<String, MobAttackInfo>();
|
||||
private static MapleDataProvider dataSource = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Mob.wz"));
|
||||
|
||||
public static MobAttackInfo getMobAttackInfo(MapleMonster mob, int attack) {
|
||||
MobAttackInfo ret = mobAttacks.get(mob.getId() + "" + attack);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
synchronized (mobAttacks) {
|
||||
ret = mobAttacks.get(mob.getId() + "" + attack);
|
||||
if (ret == null) {
|
||||
MapleData mobData = dataSource.getData(StringUtil.getLeftPaddedStr(Integer.toString(mob.getId()) + ".img", '0', 11));
|
||||
if (mobData != null) {
|
||||
// MapleData infoData = mobData.getChildByPath("info");
|
||||
String linkedmob = MapleDataTool.getString("link", mobData, "");
|
||||
if (!linkedmob.equals("")) {
|
||||
mobData = dataSource.getData(StringUtil.getLeftPaddedStr(linkedmob + ".img", '0', 11));
|
||||
}
|
||||
MapleData attackData = mobData.getChildByPath("attack" + (attack + 1) + "/info");
|
||||
|
||||
if (attackData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MapleData deadlyAttack = attackData.getChildByPath("deadlyAttack");
|
||||
int mpBurn = MapleDataTool.getInt("mpBurn", attackData, 0);
|
||||
int disease = MapleDataTool.getInt("disease", attackData, 0);
|
||||
int level = MapleDataTool.getInt("level", attackData, 0);
|
||||
int mpCon = MapleDataTool.getInt("conMP", attackData, 0);
|
||||
ret = new MobAttackInfo(mob.getId(), attack);
|
||||
ret.setDeadlyAttack(deadlyAttack != null);
|
||||
ret.setMpBurn(mpBurn);
|
||||
ret.setDiseaseSkill(disease);
|
||||
ret.setDiseaseLevel(level);
|
||||
ret.setMpCon(mpCon);
|
||||
}
|
||||
mobAttacks.put(mob.getId() + "" + attack, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
386
src/server/life/MobSkill.java
Normal file
386
src/server/life/MobSkill.java
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleDisease;
|
||||
import client.status.MonsterStatus;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import tools.Randomizer;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import server.maps.MapleMist;
|
||||
import tools.ArrayMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Danny (Leifde)
|
||||
*/
|
||||
public class MobSkill {
|
||||
private int skillId, skillLevel, mpCon;
|
||||
private List<Integer> toSummon = new ArrayList<Integer>();
|
||||
private int spawnEffect, hp, x, y;
|
||||
private long duration, cooltime;
|
||||
private float prop;
|
||||
private Point lt, rb;
|
||||
private int limit;
|
||||
|
||||
public MobSkill(int skillId, int level) {
|
||||
this.skillId = skillId;
|
||||
this.skillLevel = level;
|
||||
}
|
||||
|
||||
public void setMpCon(int mpCon) {
|
||||
this.mpCon = mpCon;
|
||||
}
|
||||
|
||||
public void addSummons(List<Integer> toSummon) {
|
||||
for (Integer summon : toSummon) {
|
||||
this.toSummon.add(summon);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpawnEffect(int spawnEffect) {
|
||||
this.spawnEffect = spawnEffect;
|
||||
}
|
||||
|
||||
public void setHp(int hp) {
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public void setCoolTime(long cooltime) {
|
||||
this.cooltime = cooltime;
|
||||
}
|
||||
|
||||
public void setProp(float prop) {
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
public void setLtRb(Point lt, Point rb) {
|
||||
this.lt = lt;
|
||||
this.rb = rb;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public void applyEffect(MapleCharacter player, MapleMonster monster, boolean skill) {
|
||||
MapleDisease disease = null;
|
||||
Map<MonsterStatus, Integer> stats = new ArrayMap<MonsterStatus, Integer>();
|
||||
List<Integer> reflection = new LinkedList<Integer>();
|
||||
switch (skillId) {
|
||||
case 100:
|
||||
case 110:
|
||||
case 150:
|
||||
stats.put(MonsterStatus.WEAPON_ATTACK_UP, Integer.valueOf(x));
|
||||
break;
|
||||
case 101:
|
||||
case 111:
|
||||
case 151:
|
||||
stats.put(MonsterStatus.MAGIC_ATTACK_UP, Integer.valueOf(x));
|
||||
break;
|
||||
case 102:
|
||||
case 112:
|
||||
case 152:
|
||||
stats.put(MonsterStatus.WEAPON_DEFENSE_UP, Integer.valueOf(x));
|
||||
break;
|
||||
case 103:
|
||||
case 113:
|
||||
case 153:
|
||||
stats.put(MonsterStatus.MAGIC_DEFENSE_UP, Integer.valueOf(x));
|
||||
break;
|
||||
case 114:
|
||||
if (lt != null && rb != null && skill) {
|
||||
List<MapleMapObject> objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER);
|
||||
final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random());
|
||||
for (MapleMapObject mons : objects) {
|
||||
((MapleMonster) mons).heal(hps, getY());
|
||||
}
|
||||
} else {
|
||||
monster.heal(getX(), getY());
|
||||
}
|
||||
break;
|
||||
case 120:
|
||||
disease = MapleDisease.SEAL;
|
||||
break;
|
||||
case 121:
|
||||
disease = MapleDisease.DARKNESS;
|
||||
break;
|
||||
case 122:
|
||||
disease = MapleDisease.WEAKEN;
|
||||
break;
|
||||
case 123:
|
||||
disease = MapleDisease.STUN;
|
||||
break;
|
||||
case 124:
|
||||
disease = MapleDisease.CURSE;
|
||||
break;
|
||||
case 125:
|
||||
disease = MapleDisease.POISON;
|
||||
break;
|
||||
case 126: // Slow
|
||||
disease = MapleDisease.SLOW;
|
||||
break;
|
||||
case 127:
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleCharacter character : getPlayersInRange(monster, player)) {
|
||||
character.dispel();
|
||||
}
|
||||
} else {
|
||||
player.dispel();
|
||||
}
|
||||
break;
|
||||
case 128: // Seduce
|
||||
disease = MapleDisease.SEDUCE;
|
||||
break;
|
||||
case 129: // Banish
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleCharacter chr : getPlayersInRange(monster, player)) {
|
||||
chr.changeMapBanish(monster.getBanish().getMap(), monster.getBanish().getPortal(), monster.getBanish().getMsg());
|
||||
}
|
||||
} else {
|
||||
player.changeMapBanish(monster.getBanish().getMap(), monster.getBanish().getPortal(), monster.getBanish().getMsg());
|
||||
}
|
||||
break;
|
||||
case 131: // Mist
|
||||
monster.getMap().spawnMist(new MapleMist(calculateBoundingBox(monster.getPosition(), true), monster, this), x * 10, false, false, false);
|
||||
break;
|
||||
case 132:
|
||||
disease = MapleDisease.CONFUSE;
|
||||
break;
|
||||
case 133: // zombify
|
||||
break;
|
||||
case 140:
|
||||
if (makeChanceResult() && !monster.isBuffed(MonsterStatus.MAGIC_IMMUNITY)) {
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
|
||||
}
|
||||
break;
|
||||
case 141:
|
||||
if (makeChanceResult() && !monster.isBuffed(MonsterStatus.WEAPON_IMMUNITY)) {
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
|
||||
}
|
||||
break;
|
||||
case 143: // Weapon Reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 144: // Magic Reflect
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 145: // Weapon / Magic reflect
|
||||
stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
|
||||
stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
|
||||
stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
|
||||
stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
|
||||
reflection.add(x);
|
||||
break;
|
||||
case 154: // accuracy up
|
||||
case 155: // avoid up
|
||||
case 156: // speed up
|
||||
break;
|
||||
case 200:
|
||||
if (monster.getMap().getSpawnedMonstersOnMap() < 80) {
|
||||
for (Integer mobId : getSummons()) {
|
||||
MapleMonster toSpawn = MapleLifeFactory.getMonster(mobId);
|
||||
toSpawn.setPosition(monster.getPosition());
|
||||
int ypos, xpos;
|
||||
xpos = (int) monster.getPosition().getX();
|
||||
ypos = (int) monster.getPosition().getY();
|
||||
switch (mobId) {
|
||||
case 8500003: // Pap bomb high
|
||||
toSpawn.setFh((int) Math.ceil(Math.random() * 19.0));
|
||||
ypos = -590;
|
||||
break;
|
||||
case 8500004: // Pap bomb
|
||||
xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
|
||||
if (ypos != -590) {
|
||||
ypos = (int) monster.getPosition().getY();
|
||||
}
|
||||
break;
|
||||
case 8510100: //Pianus bomb
|
||||
if (Math.ceil(Math.random() * 5) == 1) {
|
||||
ypos = 78;
|
||||
xpos = (int) Randomizer.nextInt(5) + (Randomizer.nextInt(2) == 1 ? 180 : 0);
|
||||
} else {
|
||||
xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (monster.getMap().getId()) {
|
||||
case 220080001: //Pap map
|
||||
if (xpos < -890) {
|
||||
xpos = (int) (Math.ceil(Math.random() * 150) - 890);
|
||||
} else if (xpos > 230) {
|
||||
xpos = (int) (230 - Math.ceil(Math.random() * 150));
|
||||
}
|
||||
break;
|
||||
case 230040420: // Pianus map
|
||||
if (xpos < -239) {
|
||||
xpos = (int) (Math.ceil(Math.random() * 150) - 239);
|
||||
} else if (xpos > 371) {
|
||||
xpos = (int) (371 - Math.ceil(Math.random() * 150));
|
||||
}
|
||||
break;
|
||||
}
|
||||
toSpawn.setPosition(new Point(xpos, ypos));
|
||||
if (toSpawn.getId() == 8500004) {
|
||||
monster.getMap().spawnFakeMonster(toSpawn);
|
||||
} else {
|
||||
monster.getMap().spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unhandeled Mob skill: " + skillId);
|
||||
break;
|
||||
}
|
||||
if (stats.size() > 0) {
|
||||
if (lt != null && rb != null && skill) {
|
||||
for (MapleMapObject mons : getObjectsInRange(monster, MapleMapObjectType.MONSTER)) {
|
||||
((MapleMonster) mons).applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
|
||||
}
|
||||
} else {
|
||||
monster.applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
|
||||
}
|
||||
}
|
||||
if (disease != null) {
|
||||
if (lt != null && rb != null && skill) {
|
||||
int i = 0;
|
||||
for (MapleCharacter character : getPlayersInRange(monster, player)) {
|
||||
if (!character.isActiveBuffedValue(2321005)) {
|
||||
if (disease.equals(MapleDisease.SEDUCE)) {
|
||||
if (i < 10) {
|
||||
character.giveDebuff(MapleDisease.SEDUCE, this);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
character.giveDebuff(disease, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.giveDebuff(disease, this);
|
||||
}
|
||||
}
|
||||
monster.usedSkill(skillId, skillLevel, cooltime);
|
||||
monster.setMp(monster.getMp() - getMpCon());
|
||||
}
|
||||
|
||||
private List<MapleCharacter> getPlayersInRange(MapleMonster monster, MapleCharacter player) {
|
||||
List<MapleCharacter> players = new ArrayList<MapleCharacter>();
|
||||
players.add(player);
|
||||
return monster.getMap().getPlayersInRange(calculateBoundingBox(monster.getPosition(), monster.isFacingLeft()), players);
|
||||
}
|
||||
|
||||
public int getSkillId() {
|
||||
return skillId;
|
||||
}
|
||||
|
||||
public int getSkillLevel() {
|
||||
return skillLevel;
|
||||
}
|
||||
|
||||
public int getMpCon() {
|
||||
return mpCon;
|
||||
}
|
||||
|
||||
public List<Integer> getSummons() {
|
||||
return Collections.unmodifiableList(toSummon);
|
||||
}
|
||||
|
||||
public int getSpawnEffect() {
|
||||
return spawnEffect;
|
||||
}
|
||||
|
||||
public int getHP() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public long getCoolTime() {
|
||||
return cooltime;
|
||||
}
|
||||
|
||||
public Point getLt() {
|
||||
return lt;
|
||||
}
|
||||
|
||||
public Point getRb() {
|
||||
return rb;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public boolean makeChanceResult() {
|
||||
return prop == 1.0 || Math.random() < prop;
|
||||
}
|
||||
|
||||
private Rectangle calculateBoundingBox(Point posFrom, boolean facingLeft) {
|
||||
int multiplier = facingLeft ? 1 : -1;
|
||||
Point mylt = new Point(lt.x * multiplier + posFrom.x, lt.y + posFrom.y);
|
||||
Point myrb = new Point(rb.x * multiplier + posFrom.x, rb.y + posFrom.y);
|
||||
return new Rectangle(mylt.x, mylt.y, myrb.x - mylt.x, myrb.y - mylt.y);
|
||||
}
|
||||
|
||||
private List<MapleMapObject> getObjectsInRange(MapleMonster monster, MapleMapObjectType objectType) {
|
||||
List<MapleMapObjectType> objectTypes = new ArrayList<MapleMapObjectType>();
|
||||
objectTypes.add(objectType);
|
||||
return monster.getMap().getMapObjectsInBox(calculateBoundingBox(monster.getPosition(), monster.isFacingLeft()), objectTypes);
|
||||
}
|
||||
}
|
||||
109
src/server/life/MobSkillFactory.java
Normal file
109
src/server/life/MobSkillFactory.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Danny (Leifde)
|
||||
*/
|
||||
public class MobSkillFactory {
|
||||
|
||||
private static Map<String, MobSkill> mobSkills = new HashMap<String, MobSkill>();
|
||||
private final static MapleDataProvider dataSource = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz"));
|
||||
private static MapleData skillRoot = dataSource.getData("MobSkill.img");
|
||||
private static ReentrantReadWriteLock dataLock = new ReentrantReadWriteLock();
|
||||
|
||||
public static MobSkill getMobSkill(final int skillId, final int level) {
|
||||
final String key = skillId + "" + level;
|
||||
dataLock.readLock().lock();
|
||||
try {
|
||||
MobSkill ret = mobSkills.get(key);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
} finally {
|
||||
dataLock.readLock().unlock();
|
||||
}
|
||||
dataLock.writeLock().lock();
|
||||
try {
|
||||
MobSkill ret;
|
||||
ret = mobSkills.get(key);
|
||||
if (ret == null) {
|
||||
MapleData skillData = skillRoot.getChildByPath(skillId + "/level/" + level);
|
||||
if (skillData != null) {
|
||||
int mpCon = MapleDataTool.getInt(skillData.getChildByPath("mpCon"), 0);
|
||||
List<Integer> toSummon = new ArrayList<Integer>();
|
||||
for (int i = 0; i > -1; i++) {
|
||||
if (skillData.getChildByPath(String.valueOf(i)) == null) {
|
||||
break;
|
||||
}
|
||||
toSummon.add(Integer.valueOf(MapleDataTool.getInt(skillData.getChildByPath(String.valueOf(i)), 0)));
|
||||
}
|
||||
int effect = MapleDataTool.getInt("summonEffect", skillData, 0);
|
||||
int hp = MapleDataTool.getInt("hp", skillData, 100);
|
||||
int x = MapleDataTool.getInt("x", skillData, 1);
|
||||
int y = MapleDataTool.getInt("y", skillData, 1);
|
||||
long duration = MapleDataTool.getInt("time", skillData, 0) * 1000;
|
||||
long cooltime = MapleDataTool.getInt("interval", skillData, 0) * 1000;
|
||||
int iprop = MapleDataTool.getInt("prop", skillData, 100);
|
||||
float prop = iprop / 100;
|
||||
int limit = MapleDataTool.getInt("limit", skillData, 0);
|
||||
MapleData ltd = skillData.getChildByPath("lt");
|
||||
Point lt = null;
|
||||
Point rb = null;
|
||||
if (ltd != null) {
|
||||
lt = (Point) ltd.getData();
|
||||
rb = (Point) skillData.getChildByPath("rb").getData();
|
||||
}
|
||||
ret = new MobSkill(skillId, level);
|
||||
ret.addSummons(toSummon);
|
||||
ret.setCoolTime(cooltime);
|
||||
ret.setDuration(duration);
|
||||
ret.setHp(hp);
|
||||
ret.setMpCon(mpCon);
|
||||
ret.setSpawnEffect(effect);
|
||||
ret.setX(x);
|
||||
ret.setY(y);
|
||||
ret.setProp(prop);
|
||||
ret.setLimit(limit);
|
||||
ret.setLtRb(lt, rb);
|
||||
}
|
||||
mobSkills.put(skillId + "" + level, ret);
|
||||
}
|
||||
return ret;
|
||||
} finally {
|
||||
dataLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/server/life/MonsterDropEntry.java
Normal file
38
src/server/life/MonsterDropEntry.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LightPepsi
|
||||
*/
|
||||
|
||||
public class MonsterDropEntry {
|
||||
public MonsterDropEntry(int itemId, int chance, int Minimum, int Maximum, short questid) {
|
||||
this.itemId = itemId;
|
||||
this.chance = chance;
|
||||
this.questid = questid;
|
||||
this.Minimum = Minimum;
|
||||
this.Maximum = Maximum;
|
||||
}
|
||||
public short questid;
|
||||
public int itemId, chance, Minimum, Maximum;
|
||||
}
|
||||
39
src/server/life/MonsterGlobalDropEntry.java
Normal file
39
src/server/life/MonsterGlobalDropEntry.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LightPepsi
|
||||
*/
|
||||
public class MonsterGlobalDropEntry {
|
||||
public MonsterGlobalDropEntry(int itemId, int chance, int continent, byte dropType, int Minimum, int Maximum, short questid) {
|
||||
this.itemId = itemId;
|
||||
this.chance = chance;
|
||||
this.dropType = dropType;
|
||||
this.questid = questid;
|
||||
this.Minimum = Minimum;
|
||||
this.Maximum = Maximum;
|
||||
}
|
||||
public byte dropType;
|
||||
public int itemId, chance, Minimum, Maximum;
|
||||
public short questid;
|
||||
}
|
||||
6
src/server/life/MonsterListener.java
Normal file
6
src/server/life/MonsterListener.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package server.life;
|
||||
|
||||
public interface MonsterListener {
|
||||
|
||||
public void monsterKilled(int aniTime);
|
||||
}
|
||||
101
src/server/life/SpawnPoint.java
Normal file
101
src/server/life/SpawnPoint.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.life;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.awt.Point;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class SpawnPoint {
|
||||
|
||||
private int monster, mobTime, team, fh, f;
|
||||
private Point pos;
|
||||
private long nextPossibleSpawn;
|
||||
private int mobInterval = 5000;
|
||||
private AtomicInteger spawnedMonsters = new AtomicInteger(0);
|
||||
private boolean immobile;
|
||||
|
||||
public SpawnPoint(final MapleMonster monster, Point pos, boolean immobile, int mobTime, int mobInterval, int team) {
|
||||
this.monster = monster.getId();
|
||||
this.pos = new Point(pos);
|
||||
this.mobTime = mobTime;
|
||||
this.team = team;
|
||||
this.fh = monster.getFh();
|
||||
this.f = monster.getF();
|
||||
this.immobile = immobile;
|
||||
this.mobInterval = mobInterval;
|
||||
this.nextPossibleSpawn = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean shouldSpawn() {
|
||||
if (mobTime < 0 || ((mobTime != 0 || immobile) && spawnedMonsters.get() > 0) || spawnedMonsters.get() > 2) {//lol
|
||||
return false;
|
||||
}
|
||||
|
||||
return nextPossibleSpawn <= System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean shouldForceSpawn() {
|
||||
if (mobTime < 0 || ((mobTime != 0 || immobile) && spawnedMonsters.get() > 0) || spawnedMonsters.get() > 2) {//lol
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public MapleMonster getMonster() {
|
||||
MapleMonster mob = new MapleMonster(MapleLifeFactory.getMonster(monster));
|
||||
mob.setPosition(new Point(pos));
|
||||
mob.setTeam(team);
|
||||
mob.setFh(fh);
|
||||
mob.setF(f);
|
||||
spawnedMonsters.incrementAndGet();
|
||||
mob.addListener(new MonsterListener() {
|
||||
@Override
|
||||
public void monsterKilled(int aniTime) {
|
||||
nextPossibleSpawn = System.currentTimeMillis();
|
||||
if (mobTime > 0) {
|
||||
nextPossibleSpawn += mobTime * 1000;
|
||||
} else {
|
||||
nextPossibleSpawn += aniTime;
|
||||
}
|
||||
spawnedMonsters.decrementAndGet();
|
||||
}
|
||||
});
|
||||
if (mobTime == 0) {
|
||||
nextPossibleSpawn = System.currentTimeMillis() + mobInterval;
|
||||
}
|
||||
return mob;
|
||||
}
|
||||
|
||||
public Point getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public final int getF() {
|
||||
return f;
|
||||
}
|
||||
|
||||
public final int getFh() {
|
||||
return fh;
|
||||
}
|
||||
}
|
||||
38
src/server/maps/AbstractAnimatedMapleMapObject.java
Normal file
38
src/server/maps/AbstractAnimatedMapleMapObject.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public abstract class AbstractAnimatedMapleMapObject extends AbstractMapleMapObject implements AnimatedMapleMapObject {
|
||||
private int stance;
|
||||
|
||||
public int getStance() {
|
||||
return stance;
|
||||
}
|
||||
|
||||
public void setStance(int stance) {
|
||||
this.stance = stance;
|
||||
}
|
||||
|
||||
public boolean isFacingLeft() {
|
||||
return Math.abs(stance) % 2 == 1;
|
||||
}
|
||||
}
|
||||
58
src/server/maps/AbstractMapleMapObject.java
Normal file
58
src/server/maps/AbstractMapleMapObject.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
public abstract class AbstractMapleMapObject implements MapleMapObject {
|
||||
private Point position = new Point();
|
||||
private int objectId;
|
||||
|
||||
@Override
|
||||
public abstract MapleMapObjectType getType();
|
||||
|
||||
@Override
|
||||
public Point getPosition() {
|
||||
return new Point(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(Point position) {
|
||||
this.position.x = position.x;
|
||||
this.position.y = position.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectId() {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectId(int id) {
|
||||
this.objectId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullifyPosition() {
|
||||
this.position = null;
|
||||
}
|
||||
}
|
||||
28
src/server/maps/AnimatedMapleMapObject.java
Normal file
28
src/server/maps/AnimatedMapleMapObject.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public interface AnimatedMapleMapObject extends MapleMapObject {
|
||||
int getStance();
|
||||
void setStance(int stance);
|
||||
boolean isFacingLeft();
|
||||
}
|
||||
69
src/server/maps/FieldLimit.java
Normal file
69
src/server/maps/FieldLimit.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author AngelSL
|
||||
*/
|
||||
public enum FieldLimit {
|
||||
JUMP(0x01),
|
||||
MOVEMENTSKILLS(0x02),
|
||||
SUMMON(0x04),
|
||||
DOOR(0x08),
|
||||
CHANGECHANNEL(0x10),
|
||||
//NO_NOTES(0x20),
|
||||
CANNOTVIPROCK(0x40),
|
||||
CANNOTMINIGAME(0x80),
|
||||
//SPECIFIC_PORTAL_SCROLL_LIMIT(0x100), // APQ and a couple quest maps have this
|
||||
CANNOTUSEMOUNTS(0x200),
|
||||
//STAT_CHANGE_ITEM_CONSUME_LIMIT(0x400), // Monster carnival?
|
||||
//PARTY_BOSS_CHANGE_LIMIT(0x800), // Monster carnival?
|
||||
CANNOTUSEPOTION(0x1000),
|
||||
//WEDDING_INVITATION_LIMIT(0x2000), // No notes
|
||||
//CASH_WEATHER_CONSUME_LIMIT(0x4000),
|
||||
//NO_PET(0x8000), // Ariant colosseum-related?
|
||||
//ANTI_MACRO_LIMIT(0x10000), // No notes
|
||||
CANNOTJUMPDOWN(0x20000);
|
||||
//SUMMON_NPC_LIMIT(0x40000); // Seems to .. disable Rush if 0x2 is set
|
||||
|
||||
//......... EVEN MORE LIMITS ............
|
||||
//SUMMON_NPC_LIMIT(0x40000),
|
||||
//NO_EXP_DECREASE(0x80000),
|
||||
//NO_DAMAGE_ON_FALLING(0x100000),
|
||||
//PARCEL_OPEN_LIMIT(0x200000),
|
||||
//DROP_LIMIT(0x400000),
|
||||
//ROCKETBOOSTER_LIMIT(0x800000) //lol we don't even have mechanics <3
|
||||
|
||||
private long i;
|
||||
|
||||
private FieldLimit(long i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return i;
|
||||
}
|
||||
|
||||
public boolean check(int fieldlimit) {
|
||||
return (fieldlimit & i) == i;
|
||||
}
|
||||
}
|
||||
459
src/server/maps/HiredMerchant.java
Normal file
459
src/server/maps/HiredMerchant.java
Normal file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import com.mysql.jdbc.Statement;
|
||||
import constants.ItemConstants;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MaplePlayerShopItem;
|
||||
import server.TimerManager;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author XoticStory
|
||||
*/
|
||||
public class HiredMerchant extends AbstractMapleMapObject {
|
||||
|
||||
private int ownerId, itemId, mesos = 0;
|
||||
private int channel, world;
|
||||
private long start;
|
||||
private String ownerName = "";
|
||||
private String description = "";
|
||||
private MapleCharacter[] visitors = new MapleCharacter[3];
|
||||
private List<MaplePlayerShopItem> items = new LinkedList<>();
|
||||
private List<Pair<String, Byte>> messages = new LinkedList<>();
|
||||
private List<SoldItem> sold = new LinkedList<>();
|
||||
private boolean open;
|
||||
public ScheduledFuture<?> schedule = null;
|
||||
private MapleMap map;
|
||||
|
||||
public HiredMerchant(final MapleCharacter owner, int itemId, String desc) {
|
||||
this.setPosition(owner.getPosition());
|
||||
this.start = System.currentTimeMillis();
|
||||
this.ownerId = owner.getId();
|
||||
this.channel = owner.getClient().getChannel();
|
||||
this.world = owner.getWorld();
|
||||
this.itemId = itemId;
|
||||
this.ownerName = owner.getName();
|
||||
this.description = desc;
|
||||
this.map = owner.getMap();
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HiredMerchant.this.forceClose();
|
||||
Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
|
||||
}
|
||||
}, 1000 * 60 * 60 * 24);
|
||||
}
|
||||
|
||||
public void broadcastToVisitors(final byte[] packet) {
|
||||
for (MapleCharacter visitor : visitors) {
|
||||
if (visitor != null) {
|
||||
visitor.getClient().announce(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addVisitor(MapleCharacter visitor) {
|
||||
int i = this.getFreeSlot();
|
||||
if (i > -1) {
|
||||
visitors[i] = visitor;
|
||||
broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorAdd(visitor, i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeVisitor(MapleCharacter visitor) {
|
||||
int slot = getVisitorSlot(visitor);
|
||||
if (slot < 0){ //Not found
|
||||
return;
|
||||
}
|
||||
if (visitors[slot] != null && visitors[slot].getId() == visitor.getId()) {
|
||||
visitors[slot] = null;
|
||||
if (slot != -1) {
|
||||
broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorLeave(slot + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getVisitorSlot(MapleCharacter visitor) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null && visitors[i].getId() == visitor.getId()){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1; //Actually 0 because of the +1's.
|
||||
}
|
||||
|
||||
public void removeAllVisitors(String message) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] != null) {
|
||||
visitors[i].setHiredMerchant(null);
|
||||
visitors[i].getClient().announce(MaplePacketCreator.leaveHiredMerchant(i + 1, 0x11));
|
||||
if (message.length() > 0) {
|
||||
visitors[i].dropMessage(1, message);
|
||||
}
|
||||
visitors[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void buy(MapleClient c, int item, short quantity) {
|
||||
MaplePlayerShopItem pItem = items.get(item);
|
||||
synchronized (items) {
|
||||
Item newItem = pItem.getItem().copy();
|
||||
newItem.setQuantity((short) ((pItem.getItem().getQuantity() * quantity)));
|
||||
if ((newItem.getFlag() & ItemConstants.KARMA) == ItemConstants.KARMA) {
|
||||
newItem.setFlag((byte) (newItem.getFlag() ^ ItemConstants.KARMA));
|
||||
}
|
||||
if (newItem.getType() == 2 && (newItem.getFlag() & ItemConstants.SPIKES) == ItemConstants.SPIKES) {
|
||||
newItem.setFlag((byte) (newItem.getFlag() ^ ItemConstants.SPIKES));
|
||||
}
|
||||
if (quantity < 1 || pItem.getBundles() < 1 || !pItem.isExist() || pItem.getBundles() < quantity) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
} else if (newItem.getType() == 1 && newItem.getQuantity() > 1) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
} else if (!pItem.isExist()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
int price = pItem.getPrice() * quantity;
|
||||
if (c.getPlayer().getMeso() >= price) {
|
||||
if (MapleInventoryManipulator.addFromDrop(c, newItem, true)) {
|
||||
c.getPlayer().gainMeso(-price, false);
|
||||
sold.add(new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price));
|
||||
pItem.setBundles((short) (pItem.getBundles() - quantity));
|
||||
if (pItem.getBundles() < 1) {
|
||||
pItem.setDoesExist(false);
|
||||
}
|
||||
MapleCharacter owner = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterByName(ownerName);
|
||||
if (owner != null) {
|
||||
owner.addMerchantMesos(price);
|
||||
} else {
|
||||
try {
|
||||
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET MerchantMesos = MerchantMesos + " + price + " WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setInt(1, ownerId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.getPlayer().dropMessage(1, "Your inventory is full. Please clean a slot before buying this item.");
|
||||
}
|
||||
} else {
|
||||
c.getPlayer().dropMessage(1, "You do not have enough mesos.");
|
||||
}
|
||||
try {
|
||||
this.saveItems(false);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void forceClose() {
|
||||
if (schedule != null) {
|
||||
schedule.cancel(false);
|
||||
}
|
||||
try {
|
||||
saveItems(true);
|
||||
items.clear();
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
//Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(getOwnerId()));
|
||||
|
||||
map.removeMapObject(this);
|
||||
|
||||
MapleCharacter player = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
|
||||
if(player != null) {
|
||||
player.setHasMerchant(false);
|
||||
} else {
|
||||
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setInt(1, ownerId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
map = null;
|
||||
schedule = null;
|
||||
}
|
||||
|
||||
public void closeShop(MapleClient c, boolean timeout) {
|
||||
map.removeMapObject(this);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(ownerId));
|
||||
c.getChannelServer().removeHiredMerchant(ownerId);
|
||||
try {
|
||||
MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterById(ownerId);
|
||||
if(player != null) {
|
||||
player.setHasMerchant(false);
|
||||
} else {
|
||||
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setInt(1, ownerId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
if (check(c.getPlayer(), getItems()) && !timeout) {
|
||||
for (MaplePlayerShopItem mpsi : getItems()) {
|
||||
if (mpsi.isExist() && (mpsi.getItem().getType() == MapleInventoryType.EQUIP.getType())) {
|
||||
MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
|
||||
} else if (mpsi.isExist()) {
|
||||
MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), null, -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
|
||||
}
|
||||
}
|
||||
items.clear();
|
||||
}
|
||||
try {
|
||||
this.saveItems(timeout);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
items.clear();
|
||||
|
||||
} catch (Exception e) {
|
||||
}
|
||||
schedule.cancel(false);
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return ownerName;
|
||||
}
|
||||
|
||||
public void clearItems() {
|
||||
items.clear();
|
||||
}
|
||||
|
||||
public int getOwnerId() {
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public MapleCharacter[] getVisitors() {
|
||||
return visitors;
|
||||
}
|
||||
|
||||
public List<MaplePlayerShopItem> getItems() {
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
|
||||
public void addItem(MaplePlayerShopItem item) {
|
||||
items.add(item);
|
||||
try {
|
||||
this.saveItems(false);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromSlot(int slot) {
|
||||
items.remove(slot);
|
||||
try {
|
||||
this.saveItems(false);
|
||||
} catch (SQLException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getFreeSlot() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(boolean set) {
|
||||
this.open = set;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public boolean isOwner(MapleCharacter chr) {
|
||||
return chr.getId() == ownerId;
|
||||
}
|
||||
|
||||
public void saveItems(boolean shutdown) throws SQLException {
|
||||
List<Pair<Item, MapleInventoryType>> itemsWithType = new ArrayList<>();
|
||||
|
||||
for (MaplePlayerShopItem pItems : items) {
|
||||
Item newItem = pItems.getItem();
|
||||
if (shutdown) {
|
||||
newItem.setQuantity((short) (pItems.getItem().getQuantity() * pItems.getBundles()));
|
||||
} else {
|
||||
newItem.setQuantity(pItems.getItem().getQuantity());
|
||||
}
|
||||
if (pItems.getBundles() > 0) {
|
||||
itemsWithType.add(new Pair<>(newItem, MapleInventoryType.getByType(newItem.getType())));
|
||||
}
|
||||
}
|
||||
|
||||
ItemFactory.MERCHANT.saveItems(itemsWithType, this.ownerId, DatabaseConnection.getConnection());
|
||||
}
|
||||
|
||||
private static boolean check(MapleCharacter chr, List<MaplePlayerShopItem> items) {
|
||||
byte eq = 0, use = 0, setup = 0, etc = 0, cash = 0;
|
||||
List<MapleInventoryType> li = new LinkedList<>();
|
||||
for (MaplePlayerShopItem item : items) {
|
||||
final MapleInventoryType invtype = MapleItemInformationProvider.getInstance().getInventoryType(item.getItem().getItemId());
|
||||
if (!li.contains(invtype)) {
|
||||
li.add(invtype);
|
||||
}
|
||||
if (invtype == MapleInventoryType.EQUIP) {
|
||||
eq++;
|
||||
} else if (invtype == MapleInventoryType.USE) {
|
||||
use++;
|
||||
} else if (invtype == MapleInventoryType.SETUP) {
|
||||
setup++;
|
||||
} else if (invtype == MapleInventoryType.ETC) {
|
||||
etc++;
|
||||
} else if (invtype == MapleInventoryType.CASH) {
|
||||
cash++;
|
||||
}
|
||||
}
|
||||
for (MapleInventoryType mit : li) {
|
||||
if (mit == MapleInventoryType.EQUIP) {
|
||||
if (chr.getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() <= eq) {
|
||||
return false;
|
||||
}
|
||||
} else if (mit == MapleInventoryType.USE) {
|
||||
if (chr.getInventory(MapleInventoryType.USE).getNumFreeSlot() <= use) {
|
||||
return false;
|
||||
}
|
||||
} else if (mit == MapleInventoryType.SETUP) {
|
||||
if (chr.getInventory(MapleInventoryType.SETUP).getNumFreeSlot() <= setup) {
|
||||
return false;
|
||||
}
|
||||
} else if (mit == MapleInventoryType.ETC) {
|
||||
if (chr.getInventory(MapleInventoryType.ETC).getNumFreeSlot() <= etc) {
|
||||
return false;
|
||||
}
|
||||
} else if (mit == MapleInventoryType.CASH) {
|
||||
if (chr.getInventory(MapleInventoryType.CASH).getNumFreeSlot() <= cash) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public int getTimeLeft() {
|
||||
return (int) ((System.currentTimeMillis() - start) / 1000);
|
||||
}
|
||||
|
||||
public List<Pair<String, Byte>> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public int getMapId() {
|
||||
return map.getId();
|
||||
}
|
||||
|
||||
public List<SoldItem> getSold() {
|
||||
return sold;
|
||||
}
|
||||
|
||||
public int getMesos() {
|
||||
return mesos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.HIRED_MERCHANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.spawnHiredMerchant(this));
|
||||
}
|
||||
|
||||
public class SoldItem {
|
||||
|
||||
int itemid, mesos;
|
||||
short quantity;
|
||||
String buyer;
|
||||
|
||||
public SoldItem(String buyer, int itemid, short quantity, int mesos) {
|
||||
this.buyer = buyer;
|
||||
this.itemid = itemid;
|
||||
this.quantity = quantity;
|
||||
this.mesos = mesos;
|
||||
}
|
||||
|
||||
public String getBuyer() {
|
||||
return buyer;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemid;
|
||||
}
|
||||
|
||||
public short getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public int getMesos() {
|
||||
return mesos;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/server/maps/MapMonitor.java
Normal file
55
src/server/maps/MapMonitor.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import server.MaplePortal;
|
||||
import server.TimerManager;
|
||||
|
||||
public class MapMonitor {
|
||||
private ScheduledFuture<?> monitorSchedule;
|
||||
private MapleMap map;
|
||||
private MaplePortal portal;
|
||||
|
||||
public MapMonitor(final MapleMap map, String portal) {
|
||||
this.map = map;
|
||||
this.portal = map.getPortal(portal);
|
||||
this.monitorSchedule = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (map.getCharacters().size() < 1) {
|
||||
cancelAction();
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
private void cancelAction() {
|
||||
monitorSchedule.cancel(false);
|
||||
map.killAllMonsters();
|
||||
map.clearDrops();
|
||||
if (portal != null) {
|
||||
portal.setPortalStatus(MaplePortal.OPEN);
|
||||
}
|
||||
map.resetReactors();
|
||||
}
|
||||
}
|
||||
157
src/server/maps/MapleDoor.java
Normal file
157
src/server/maps/MapleDoor.java
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import server.MaplePortal;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleDoor extends AbstractMapleMapObject {
|
||||
private MapleCharacter owner;
|
||||
private MapleMap town;
|
||||
private MaplePortal townPortal;
|
||||
private MapleMap target;
|
||||
private Point targetPosition;
|
||||
|
||||
public MapleDoor(MapleCharacter owner, Point targetPosition) {
|
||||
super();
|
||||
this.owner = owner;
|
||||
this.target = owner.getMap();
|
||||
this.targetPosition = targetPosition;
|
||||
setPosition(this.targetPosition);
|
||||
this.town = this.target.getReturnMap();
|
||||
this.townPortal = getFreePortal();
|
||||
}
|
||||
|
||||
public MapleDoor(MapleDoor origDoor) {
|
||||
super();
|
||||
this.owner = origDoor.owner;
|
||||
this.town = origDoor.town;
|
||||
this.townPortal = origDoor.townPortal;
|
||||
this.target = origDoor.target;
|
||||
this.targetPosition = origDoor.targetPosition;
|
||||
this.townPortal = origDoor.townPortal;
|
||||
setPosition(this.townPortal.getPosition());
|
||||
}
|
||||
|
||||
private MaplePortal getFreePortal() {
|
||||
List<MaplePortal> freePortals = new ArrayList<MaplePortal>();
|
||||
for (MaplePortal port : town.getPortals()) {
|
||||
if (port.getType() == 6) {
|
||||
freePortals.add(port);
|
||||
}
|
||||
}
|
||||
Collections.sort(freePortals, new Comparator<MaplePortal>() {
|
||||
public int compare(MaplePortal o1, MaplePortal o2) {
|
||||
if (o1.getId() < o2.getId()) {
|
||||
return -1;
|
||||
} else if (o1.getId() == o2.getId()) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
for (MapleMapObject obj : town.getMapObjects()) {
|
||||
if (obj instanceof MapleDoor) {
|
||||
MapleDoor door = (MapleDoor) obj;
|
||||
if (door.getOwner().getParty() != null && door.getOwner().getParty().containsMembers(door.getOwner().getMPC())) {
|
||||
freePortals.remove(door.getTownPortal());
|
||||
}
|
||||
}
|
||||
}
|
||||
return freePortals.iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() && owner.getParty() == null) {
|
||||
client.announce(MaplePacketCreator.spawnDoor(owner.getId(), town.getId() == client.getPlayer().getMapId() ? townPortal.getPosition() : targetPosition, true));
|
||||
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
|
||||
client.announce(MaplePacketCreator.partyPortal(town.getId(), target.getId(), targetPosition));
|
||||
}
|
||||
}
|
||||
if (owner.getId() != client.getPlayer().getId()) {
|
||||
client.announce(MaplePacketCreator.spawnPortal(town.getId(), target.getId(), targetPosition));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() || owner.getParty() != null && owner.getParty().containsMembers(client.getPlayer().getMPC())) {
|
||||
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
|
||||
client.announce(MaplePacketCreator.partyPortal(999999999, 999999999, new Point(-1, -1)));
|
||||
}
|
||||
client.announce(MaplePacketCreator.removeDoor(owner.getId(), false));
|
||||
client.announce(MaplePacketCreator.removeDoor(owner.getId(), true));
|
||||
}
|
||||
}
|
||||
|
||||
public void warp(MapleCharacter chr, boolean toTown) {
|
||||
if (chr == owner || owner.getParty() != null && owner.getParty().containsMembers(chr.getMPC())) {
|
||||
if (!toTown) {
|
||||
chr.changeMap(target, targetPosition);
|
||||
} else {
|
||||
chr.changeMap(town, townPortal);
|
||||
}
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public MapleMap getTown() {
|
||||
return town;
|
||||
}
|
||||
|
||||
public MaplePortal getTownPortal() {
|
||||
return townPortal;
|
||||
}
|
||||
|
||||
public MapleMap getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public Point getTargetPosition() {
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.DOOR;
|
||||
}
|
||||
|
||||
}
|
||||
65
src/server/maps/MapleDragon.java
Normal file
65
src/server/maps/MapleDragon.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
|
||||
|
||||
|
||||
public class MapleDragon extends AbstractAnimatedMapleMapObject {
|
||||
|
||||
private MapleCharacter owner;
|
||||
|
||||
public MapleDragon(MapleCharacter chr) {
|
||||
super();
|
||||
this.owner = chr;
|
||||
this.setPosition(chr.getPosition());
|
||||
this.setStance(chr.getStance());
|
||||
sendSpawnData(chr.getClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.DRAGON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient c) {
|
||||
c.announce(MaplePacketCreator.spawnDragon(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectId() {
|
||||
return owner.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient c) {
|
||||
c.announce(MaplePacketCreator.removeDragon(owner.getId()));
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
102
src/server/maps/MapleFoothold.java
Normal file
102
src/server/maps/MapleFoothold.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleFoothold implements Comparable<MapleFoothold> {
|
||||
private Point p1;
|
||||
private Point p2;
|
||||
private int id;
|
||||
private int next, prev;
|
||||
|
||||
public MapleFoothold(Point p1, Point p2, int id) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isWall() {
|
||||
return p1.x == p2.x;
|
||||
}
|
||||
|
||||
public int getX1() {
|
||||
return p1.x;
|
||||
}
|
||||
|
||||
public int getX2() {
|
||||
return p2.x;
|
||||
}
|
||||
|
||||
public int getY1() {
|
||||
return p1.y;
|
||||
}
|
||||
|
||||
public int getY2() {
|
||||
return p2.y;
|
||||
}
|
||||
|
||||
// XXX may need more precision
|
||||
public int calculateFooting(int x) {
|
||||
if (p1.y == p2.y) {
|
||||
return p2.y; // y at both ends is the same
|
||||
}
|
||||
int slope = (p1.y - p2.y) / (p1.x - p2.x);
|
||||
int intercept = p1.y - (slope * p1.x);
|
||||
return (slope * x) + intercept;
|
||||
}
|
||||
|
||||
public int compareTo(MapleFoothold o) {
|
||||
MapleFoothold other = o;
|
||||
if (p2.y < other.getY1()) {
|
||||
return -1;
|
||||
} else if (p1.y > other.getY2()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(int next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public int getPrev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public void setPrev(int prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
}
|
||||
220
src/server/maps/MapleFootholdTree.java
Normal file
220
src/server/maps/MapleFootholdTree.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleFootholdTree {
|
||||
private MapleFootholdTree nw = null;
|
||||
private MapleFootholdTree ne = null;
|
||||
private MapleFootholdTree sw = null;
|
||||
private MapleFootholdTree se = null;
|
||||
private List<MapleFoothold> footholds = new LinkedList<MapleFoothold>();
|
||||
private Point p1;
|
||||
private Point p2;
|
||||
private Point center;
|
||||
private int depth = 0;
|
||||
private static int maxDepth = 8;
|
||||
private int maxDropX;
|
||||
private int minDropX;
|
||||
|
||||
public MapleFootholdTree(Point p1, Point p2) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
center = new Point((p2.x - p1.x) / 2, (p2.y - p1.y) / 2);
|
||||
}
|
||||
|
||||
public MapleFootholdTree(Point p1, Point p2, int depth) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
this.depth = depth;
|
||||
center = new Point((p2.x - p1.x) / 2, (p2.y - p1.y) / 2);
|
||||
}
|
||||
|
||||
public void insert(MapleFoothold f) {
|
||||
if (depth == 0) {
|
||||
if (f.getX1() > maxDropX) {
|
||||
maxDropX = f.getX1();
|
||||
}
|
||||
if (f.getX1() < minDropX) {
|
||||
minDropX = f.getX1();
|
||||
}
|
||||
if (f.getX2() > maxDropX) {
|
||||
maxDropX = f.getX2();
|
||||
}
|
||||
if (f.getX2() < minDropX) {
|
||||
minDropX = f.getX2();
|
||||
}
|
||||
}
|
||||
if (depth == maxDepth ||
|
||||
(f.getX1() >= p1.x && f.getX2() <= p2.x &&
|
||||
f.getY1() >= p1.y && f.getY2() <= p2.y)) {
|
||||
footholds.add(f);
|
||||
} else {
|
||||
if (nw == null) {
|
||||
nw = new MapleFootholdTree(p1, center, depth + 1);
|
||||
ne = new MapleFootholdTree(new Point(center.x, p1.y), new Point(p2.x, center.y), depth + 1);
|
||||
sw = new MapleFootholdTree(new Point(p1.x, center.y), new Point(center.x, p2.y), depth + 1);
|
||||
se = new MapleFootholdTree(center, p2, depth + 1);
|
||||
}
|
||||
if (f.getX2() <= center.x && f.getY2() <= center.y) {
|
||||
nw.insert(f);
|
||||
} else if (f.getX1() > center.x && f.getY2() <= center.y) {
|
||||
ne.insert(f);
|
||||
} else if (f.getX2() <= center.x && f.getY1() > center.y) {
|
||||
sw.insert(f);
|
||||
} else {
|
||||
se.insert(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<MapleFoothold> getRelevants(Point p) {
|
||||
return getRelevants(p, new LinkedList<MapleFoothold>());
|
||||
}
|
||||
|
||||
private List<MapleFoothold> getRelevants(Point p, List<MapleFoothold> list) {
|
||||
list.addAll(footholds);
|
||||
if (nw != null) {
|
||||
if (p.x <= center.x && p.y <= center.y) {
|
||||
nw.getRelevants(p, list);
|
||||
} else if (p.x > center.x && p.y <= center.y) {
|
||||
ne.getRelevants(p, list);
|
||||
} else if (p.x <= center.x && p.y > center.y) {
|
||||
sw.getRelevants(p, list);
|
||||
} else {
|
||||
se.getRelevants(p, list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private MapleFoothold findWallR(Point p1, Point p2) {
|
||||
MapleFoothold ret;
|
||||
for (MapleFoothold f : footholds) {
|
||||
if (f.isWall() && f.getX1() >= p1.x && f.getX1() <= p2.x &&
|
||||
f.getY1() >= p1.y && f.getY2() <= p1.y) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
if (nw != null) {
|
||||
if (p1.x <= center.x && p1.y <= center.y) {
|
||||
ret = nw.findWallR(p1, p2);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if ((p1.x > center.x || p2.x > center.x) && p1.y <= center.y) {
|
||||
ret = ne.findWallR(p1, p2);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (p1.x <= center.x && p1.y > center.y) {
|
||||
ret = sw.findWallR(p1, p2);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if ((p1.x > center.x || p2.x > center.x) && p1.y > center.y) {
|
||||
ret = se.findWallR(p1, p2);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MapleFoothold findWall(Point p1, Point p2) {
|
||||
if (p1.y != p2.y) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return findWallR(p1, p2);
|
||||
}
|
||||
|
||||
public MapleFoothold findBelow(Point p) {
|
||||
List<MapleFoothold> relevants = getRelevants(p);
|
||||
List<MapleFoothold> xMatches = new LinkedList<MapleFoothold>();
|
||||
for (MapleFoothold fh : relevants) {
|
||||
if (fh.getX1() <= p.x && fh.getX2() >= p.x) {
|
||||
xMatches.add(fh);
|
||||
}
|
||||
}
|
||||
Collections.sort(xMatches);
|
||||
for (MapleFoothold fh : xMatches) {
|
||||
if (!fh.isWall() && fh.getY1() != fh.getY2()) {
|
||||
int calcY;
|
||||
double s1 = Math.abs(fh.getY2() - fh.getY1());
|
||||
double s2 = Math.abs(fh.getX2() - fh.getX1());
|
||||
double s4 = Math.abs(p.x - fh.getX1());
|
||||
double alpha = Math.atan(s2 / s1);
|
||||
double beta = Math.atan(s1 / s2);
|
||||
double s5 = Math.cos(alpha) * (s4 / Math.cos(beta));
|
||||
if (fh.getY2() < fh.getY1()) {
|
||||
calcY = fh.getY1() - (int) s5;
|
||||
} else {
|
||||
calcY = fh.getY1() + (int) s5;
|
||||
}
|
||||
if (calcY >= p.y) {
|
||||
return fh;
|
||||
}
|
||||
} else if (!fh.isWall()) {
|
||||
if (fh.getY1() >= p.y) {
|
||||
return fh;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getX1() {
|
||||
return p1.x;
|
||||
}
|
||||
|
||||
public int getX2() {
|
||||
return p2.x;
|
||||
}
|
||||
|
||||
public int getY1() {
|
||||
return p1.y;
|
||||
}
|
||||
|
||||
public int getY2() {
|
||||
return p2.y;
|
||||
}
|
||||
|
||||
public int getMaxDropX() {
|
||||
return maxDropX;
|
||||
}
|
||||
|
||||
public int getMinDropX() {
|
||||
return minDropX;
|
||||
}
|
||||
}
|
||||
144
src/server/maps/MapleGenericPortal.java
Normal file
144
src/server/maps/MapleGenericPortal.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleClient;
|
||||
import java.awt.Point;
|
||||
import scripting.portal.PortalScriptManager;
|
||||
import server.MaplePortal;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
public class MapleGenericPortal implements MaplePortal {
|
||||
|
||||
private String name;
|
||||
private String target;
|
||||
private Point position;
|
||||
private int targetmap;
|
||||
private int type;
|
||||
private boolean status = true;
|
||||
private int id;
|
||||
private String scriptName;
|
||||
private boolean portalState;
|
||||
|
||||
public MapleGenericPortal(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPortalStatus(boolean newStatus) {
|
||||
this.status = newStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getPortalStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetMapId() {
|
||||
return targetmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setPosition(Point position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void setTargetMapId(int targetmapid) {
|
||||
this.targetmap = targetmapid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterPortal(MapleClient c) {
|
||||
boolean changed = false;
|
||||
if (getScriptName() != null) {
|
||||
changed = PortalScriptManager.getInstance().executePortalScript(this, c);
|
||||
} else if (getTargetMapId() != 999999999) {
|
||||
MapleMap to = c.getPlayer().getEventInstance() == null ? c.getChannelServer().getMapFactory().getMap(getTargetMapId()) : c.getPlayer().getEventInstance().getMapInstance(getTargetMapId());
|
||||
MaplePortal pto = to.getPortal(getTarget());
|
||||
if (pto == null) {// fallback for missing portals - no real life case anymore - intresting for not implemented areas
|
||||
pto = to.getPortal(0);
|
||||
}
|
||||
c.getPlayer().changeMap(to, pto); //late resolving makes this harder but prevents us from loading the whole world at once
|
||||
changed = true;
|
||||
}
|
||||
if (!changed) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPortalState(boolean state) {
|
||||
this.portalState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getPortalState() {
|
||||
return portalState;
|
||||
}
|
||||
}
|
||||
2382
src/server/maps/MapleMap.java
Normal file
2382
src/server/maps/MapleMap.java
Normal file
File diff suppressed because it is too large
Load Diff
48
src/server/maps/MapleMapEffect.java
Normal file
48
src/server/maps/MapleMapEffect.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleClient;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
public class MapleMapEffect {
|
||||
private String msg;
|
||||
private int itemId;
|
||||
private boolean active = true;
|
||||
|
||||
public MapleMapEffect(String msg, int itemId) {
|
||||
this.msg = msg;
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public final byte[] makeDestroyData() {
|
||||
return MaplePacketCreator.removeMapEffect();
|
||||
}
|
||||
|
||||
public final byte[] makeStartData() {
|
||||
return MaplePacketCreator.startMapEffect(msg, itemId, active);
|
||||
}
|
||||
|
||||
public void sendStartData(MapleClient client) {
|
||||
client.announce(makeStartData());
|
||||
}
|
||||
}
|
||||
301
src/server/maps/MapleMapFactory.java
Normal file
301
src/server/maps/MapleMapFactory.java
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataTool;
|
||||
import server.PortalFactory;
|
||||
import server.life.AbstractLoadedMapleLife;
|
||||
import server.life.MapleLifeFactory;
|
||||
import server.life.MapleMonster;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.StringUtil;
|
||||
|
||||
public class MapleMapFactory {
|
||||
|
||||
private MapleDataProvider source;
|
||||
private MapleData nameData;
|
||||
private Map<Integer, MapleMap> maps = new HashMap<>();
|
||||
private int channel, world;
|
||||
|
||||
public MapleMapFactory(MapleDataProvider source, MapleDataProvider stringSource, int world, int channel) {
|
||||
this.source = source;
|
||||
this.nameData = stringSource.getData("Map.img");
|
||||
this.world = world;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public MapleMap getMap(int mapid) {
|
||||
Integer omapid = Integer.valueOf(mapid);
|
||||
MapleMap map = maps.get(omapid);
|
||||
if (map == null) {
|
||||
synchronized (this) {
|
||||
map = maps.get(omapid);
|
||||
if (map != null) {
|
||||
return map;
|
||||
}
|
||||
String mapName = getMapName(mapid);
|
||||
MapleData mapData = source.getData(mapName);
|
||||
String link = MapleDataTool.getString(mapData.getChildByPath("info/link"), "");
|
||||
if (!link.equals("")) { //nexon made hundreds of dojo maps so to reduce the size they added links.
|
||||
mapName = getMapName(Integer.parseInt(link));
|
||||
mapData = source.getData(mapName);
|
||||
}
|
||||
float monsterRate = 0;
|
||||
MapleData mobRate = mapData.getChildByPath("info/mobRate");
|
||||
if (mobRate != null) {
|
||||
monsterRate = ((Float) mobRate.getData()).floatValue();
|
||||
}
|
||||
map = new MapleMap(mapid, world, channel, MapleDataTool.getInt("info/returnMap", mapData), monsterRate);
|
||||
|
||||
String onFirstEnter = MapleDataTool.getString(mapData.getChildByPath("info/onFirstUserEnter"), String.valueOf(mapid));
|
||||
map.setOnFirstUserEnter(onFirstEnter.equals("") ? String.valueOf(mapid) : onFirstEnter);
|
||||
|
||||
String onEnter = MapleDataTool.getString(mapData.getChildByPath("info/onUserEnter"), String.valueOf(mapid));
|
||||
map.setOnUserEnter(onEnter.equals("") ? String.valueOf(mapid) : onEnter);
|
||||
|
||||
map.setFieldLimit(MapleDataTool.getInt(mapData.getChildByPath("info/fieldLimit"), 0));
|
||||
map.setMobInterval((short) MapleDataTool.getInt(mapData.getChildByPath("info/createMobInterval"), 5000));
|
||||
PortalFactory portalFactory = new PortalFactory();
|
||||
for (MapleData portal : mapData.getChildByPath("portal")) {
|
||||
map.addPortal(portalFactory.makePortal(MapleDataTool.getInt(portal.getChildByPath("pt")), portal));
|
||||
}
|
||||
MapleData timeMob = mapData.getChildByPath("info/timeMob");
|
||||
if (timeMob != null) {
|
||||
map.timeMob(MapleDataTool.getInt(timeMob.getChildByPath("id")),
|
||||
MapleDataTool.getString(timeMob.getChildByPath("message")));
|
||||
}
|
||||
|
||||
List<MapleFoothold> allFootholds = new LinkedList<>();
|
||||
Point lBound = new Point();
|
||||
Point uBound = new Point();
|
||||
for (MapleData footRoot : mapData.getChildByPath("foothold")) {
|
||||
for (MapleData footCat : footRoot) {
|
||||
for (MapleData footHold : footCat) {
|
||||
int x1 = MapleDataTool.getInt(footHold.getChildByPath("x1"));
|
||||
int y1 = MapleDataTool.getInt(footHold.getChildByPath("y1"));
|
||||
int x2 = MapleDataTool.getInt(footHold.getChildByPath("x2"));
|
||||
int y2 = MapleDataTool.getInt(footHold.getChildByPath("y2"));
|
||||
MapleFoothold fh = new MapleFoothold(new Point(x1, y1), new Point(x2, y2), Integer.parseInt(footHold.getName()));
|
||||
fh.setPrev(MapleDataTool.getInt(footHold.getChildByPath("prev")));
|
||||
fh.setNext(MapleDataTool.getInt(footHold.getChildByPath("next")));
|
||||
if (fh.getX1() < lBound.x) {
|
||||
lBound.x = fh.getX1();
|
||||
}
|
||||
if (fh.getX2() > uBound.x) {
|
||||
uBound.x = fh.getX2();
|
||||
}
|
||||
if (fh.getY1() < lBound.y) {
|
||||
lBound.y = fh.getY1();
|
||||
}
|
||||
if (fh.getY2() > uBound.y) {
|
||||
uBound.y = fh.getY2();
|
||||
}
|
||||
allFootholds.add(fh);
|
||||
}
|
||||
}
|
||||
}
|
||||
MapleFootholdTree fTree = new MapleFootholdTree(lBound, uBound);
|
||||
for (MapleFoothold fh : allFootholds) {
|
||||
fTree.insert(fh);
|
||||
}
|
||||
map.setFootholds(fTree);
|
||||
if (mapData.getChildByPath("area") != null) {
|
||||
for (MapleData area : mapData.getChildByPath("area")) {
|
||||
int x1 = MapleDataTool.getInt(area.getChildByPath("x1"));
|
||||
int y1 = MapleDataTool.getInt(area.getChildByPath("y1"));
|
||||
int x2 = MapleDataTool.getInt(area.getChildByPath("x2"));
|
||||
int y2 = MapleDataTool.getInt(area.getChildByPath("y2"));
|
||||
map.addMapleArea(new Rectangle(x1, y1, (x2 - x1), (y2 - y1)));
|
||||
}
|
||||
}
|
||||
try { try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM playernpcs WHERE map = ?")) {
|
||||
ps.setInt(1, omapid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
map.addMapObject(new PlayerNPCs(rs));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
for (MapleData life : mapData.getChildByPath("life")) {
|
||||
String id = MapleDataTool.getString(life.getChildByPath("id"));
|
||||
String type = MapleDataTool.getString(life.getChildByPath("type"));
|
||||
if (id.equals("9001105")) {
|
||||
id = "9001108";//soz
|
||||
}
|
||||
AbstractLoadedMapleLife myLife = loadLife(life, id, type);
|
||||
if (myLife instanceof MapleMonster) {
|
||||
MapleMonster monster = (MapleMonster) myLife;
|
||||
int mobTime = MapleDataTool.getInt("mobTime", life, 0);
|
||||
int team = MapleDataTool.getInt("team", life, -1);
|
||||
if (mobTime == -1) { //does not respawn, force spawn once
|
||||
map.spawnMonster(monster);
|
||||
} else {
|
||||
map.addMonsterSpawn(monster, mobTime, team);
|
||||
}
|
||||
} else {
|
||||
map.addMapObject(myLife);
|
||||
}
|
||||
}
|
||||
if (mapData.getChildByPath("reactor") != null) {
|
||||
for (MapleData reactor : mapData.getChildByPath("reactor")) {
|
||||
String id = MapleDataTool.getString(reactor.getChildByPath("id"));
|
||||
if (id != null) {
|
||||
MapleReactor newReactor = loadReactor(reactor, id);
|
||||
map.spawnReactor(newReactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
map.setMapName(MapleDataTool.getString("mapName", nameData.getChildByPath(getMapStringName(omapid)), ""));
|
||||
map.setStreetName(MapleDataTool.getString("streetName", nameData.getChildByPath(getMapStringName(omapid)), ""));
|
||||
} catch (Exception e) {
|
||||
map.setMapName("");
|
||||
map.setStreetName("");
|
||||
}
|
||||
|
||||
map.setClock(mapData.getChildByPath("clock") != null);
|
||||
map.setEverlast(mapData.getChildByPath("everlast") != null);
|
||||
map.setTown(mapData.getChildByPath("info/town") != null);
|
||||
map.setHPDec(MapleDataTool.getIntConvert("info/decHP", mapData, 0));
|
||||
map.setHPDecProtect(MapleDataTool.getIntConvert("info/protectItem", mapData, 0));
|
||||
map.setForcedReturnMap(MapleDataTool.getInt(mapData.getChildByPath("info/forcedReturn"), 999999999));
|
||||
map.setBoat(mapData.getChildByPath("shipObj") != null);
|
||||
map.setTimeLimit(MapleDataTool.getIntConvert("timeLimit", mapData.getChildByPath("info"), -1));
|
||||
map.setFieldType(MapleDataTool.getIntConvert("info/fieldType", mapData, 0));
|
||||
map.setMobCapacity(MapleDataTool.getIntConvert("fixedMobCapacity", mapData.getChildByPath("info"), 500));//Is there a map that contains more than 500 mobs?
|
||||
|
||||
HashMap<Integer, Integer> backTypes = new HashMap<>();
|
||||
try {
|
||||
for (MapleData layer : mapData.getChildByPath("back")) { // yolo
|
||||
int layerNum = Integer.parseInt(layer.getName());
|
||||
int type = MapleDataTool.getInt(layer.getChildByPath("type"), 0);
|
||||
|
||||
backTypes.put(layerNum, type);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// swallow cause I'm cool
|
||||
}
|
||||
map.setBackgroundTypes(backTypes);
|
||||
|
||||
maps.put(omapid, map);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public boolean isMapLoaded(int mapId) {
|
||||
return maps.containsKey(mapId);
|
||||
}
|
||||
|
||||
private AbstractLoadedMapleLife loadLife(MapleData life, String id, String type) {
|
||||
AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(Integer.parseInt(id), type);
|
||||
myLife.setCy(MapleDataTool.getInt(life.getChildByPath("cy")));
|
||||
MapleData dF = life.getChildByPath("f");
|
||||
if (dF != null) {
|
||||
myLife.setF(MapleDataTool.getInt(dF));
|
||||
}
|
||||
myLife.setFh(MapleDataTool.getInt(life.getChildByPath("fh")));
|
||||
myLife.setRx0(MapleDataTool.getInt(life.getChildByPath("rx0")));
|
||||
myLife.setRx1(MapleDataTool.getInt(life.getChildByPath("rx1")));
|
||||
int x = MapleDataTool.getInt(life.getChildByPath("x"));
|
||||
int y = MapleDataTool.getInt(life.getChildByPath("y"));
|
||||
myLife.setPosition(new Point(x, y));
|
||||
int hide = MapleDataTool.getInt("hide", life, 0);
|
||||
if (hide == 1) {
|
||||
myLife.setHide(true);
|
||||
}
|
||||
return myLife;
|
||||
}
|
||||
|
||||
private MapleReactor loadReactor(MapleData reactor, String id) {
|
||||
MapleReactor myReactor = new MapleReactor(MapleReactorFactory.getReactor(Integer.parseInt(id)), Integer.parseInt(id));
|
||||
int x = MapleDataTool.getInt(reactor.getChildByPath("x"));
|
||||
int y = MapleDataTool.getInt(reactor.getChildByPath("y"));
|
||||
myReactor.setPosition(new Point(x, y));
|
||||
myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000);
|
||||
myReactor.setState((byte) 0);
|
||||
myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
|
||||
return myReactor;
|
||||
}
|
||||
|
||||
private String getMapName(int mapid) {
|
||||
String mapName = StringUtil.getLeftPaddedStr(Integer.toString(mapid), '0', 9);
|
||||
StringBuilder builder = new StringBuilder("Map/Map");
|
||||
int area = mapid / 100000000;
|
||||
builder.append(area);
|
||||
builder.append("/");
|
||||
builder.append(mapName);
|
||||
builder.append(".img");
|
||||
mapName = builder.toString();
|
||||
return mapName;
|
||||
}
|
||||
|
||||
private String getMapStringName(int mapid) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (mapid < 100000000) {
|
||||
builder.append("maple");
|
||||
} else if (mapid >= 100000000 && mapid < 200000000) {
|
||||
builder.append("victoria");
|
||||
} else if (mapid >= 200000000 && mapid < 300000000) {
|
||||
builder.append("ossyria");
|
||||
} else if (mapid >= 540000000 && mapid < 551030200) {
|
||||
builder.append("singapore");
|
||||
} else if (mapid >= 600000000 && mapid < 620000000) {
|
||||
builder.append("MasteriaGL");
|
||||
} else if (mapid >= 670000000 && mapid < 682000000) {
|
||||
builder.append("weddingGL");
|
||||
} else if (mapid >= 682000000 && mapid < 683000000) {
|
||||
builder.append("HalloweenGL");
|
||||
} else if (mapid >= 800000000 && mapid < 900000000) {
|
||||
builder.append("jp");
|
||||
} else {
|
||||
builder.append("etc");
|
||||
}
|
||||
builder.append("/").append(mapid);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public void setChannel(int channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public void setWorld(int world) {
|
||||
this.channel = world;
|
||||
}
|
||||
|
||||
public Map<Integer, MapleMap> getMaps() {
|
||||
return maps;
|
||||
}
|
||||
}
|
||||
138
src/server/maps/MapleMapItem.java
Normal file
138
src/server/maps/MapleMapItem.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import java.awt.Point;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
public class MapleMapItem extends AbstractMapleMapObject {
|
||||
|
||||
protected Item item;
|
||||
protected MapleMapObject dropper;
|
||||
protected int character_ownerid, meso, questid = -1;
|
||||
protected byte type;
|
||||
protected boolean pickedUp = false, playerDrop;
|
||||
protected long dropTime;
|
||||
public ReentrantLock itemLock = new ReentrantLock();
|
||||
|
||||
public MapleMapItem(Item item, Point position, MapleMapObject dropper, MapleCharacter owner, byte type, boolean playerDrop) {
|
||||
setPosition(position);
|
||||
this.item = item;
|
||||
this.dropper = dropper;
|
||||
this.character_ownerid = owner.getId();
|
||||
this.meso = 0;
|
||||
this.type = type;
|
||||
this.playerDrop = playerDrop;
|
||||
}
|
||||
|
||||
public MapleMapItem(Item item, Point position, MapleMapObject dropper, MapleCharacter owner, byte type, boolean playerDrop, int questid) {
|
||||
setPosition(position);
|
||||
this.item = item;
|
||||
this.dropper = dropper;
|
||||
this.character_ownerid = owner.getParty() == null ? owner.getId() : owner.getPartyId();
|
||||
this.meso = 0;
|
||||
this.type = type;
|
||||
this.playerDrop = playerDrop;
|
||||
this.questid = questid;
|
||||
}
|
||||
|
||||
public MapleMapItem(int meso, Point position, MapleMapObject dropper, MapleCharacter owner, byte type, boolean playerDrop) {
|
||||
setPosition(position);
|
||||
this.item = null;
|
||||
this.dropper = dropper;
|
||||
this.character_ownerid = owner.getParty() == null ? owner.getId() : owner.getPartyId();
|
||||
this.meso = meso;
|
||||
this.type = type;
|
||||
this.playerDrop = playerDrop;
|
||||
}
|
||||
|
||||
public final Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public final int getQuest() {
|
||||
return questid;
|
||||
}
|
||||
|
||||
public final int getItemId() {
|
||||
if (getMeso() > 0) {
|
||||
return meso;
|
||||
}
|
||||
return item.getItemId();
|
||||
}
|
||||
|
||||
public final MapleMapObject getDropper() {
|
||||
return dropper;
|
||||
}
|
||||
|
||||
public final int getOwner() {
|
||||
return character_ownerid;
|
||||
}
|
||||
|
||||
public final int getMeso() {
|
||||
return meso;
|
||||
}
|
||||
|
||||
public final boolean isPlayerDrop() {
|
||||
return playerDrop;
|
||||
}
|
||||
|
||||
public final boolean isPickedUp() {
|
||||
return pickedUp;
|
||||
}
|
||||
|
||||
public void setPickedUp(final boolean pickedUp) {
|
||||
this.pickedUp = pickedUp;
|
||||
}
|
||||
|
||||
public long getDropTime() {
|
||||
return dropTime;
|
||||
}
|
||||
|
||||
public void setDropTime(long time) {
|
||||
this.dropTime = time;
|
||||
}
|
||||
|
||||
public byte getDropType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(final MapleClient client) {
|
||||
if (questid <= 0 || (client.getPlayer().getQuestStatus(questid) == 1 && client.getPlayer().needQuestItem(questid, item.getItemId()))) {
|
||||
client.announce(MaplePacketCreator.dropItemFromMapObject(this, null, getPosition(), (byte) 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(final MapleClient client) {
|
||||
client.announce(MaplePacketCreator.removeItemFromMap(getObjectId(), 1, 0));
|
||||
}
|
||||
}
|
||||
36
src/server/maps/MapleMapObject.java
Normal file
36
src/server/maps/MapleMapObject.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import client.MapleClient;
|
||||
|
||||
public interface MapleMapObject {
|
||||
public int getObjectId();
|
||||
public void setObjectId(int id);
|
||||
public MapleMapObjectType getType();
|
||||
public Point getPosition();
|
||||
public void setPosition(Point position);
|
||||
public void sendSpawnData(MapleClient client);
|
||||
public void sendDestroyData(MapleClient client);
|
||||
public void nullifyPosition();
|
||||
}
|
||||
26
src/server/maps/MapleMapObjectType.java
Normal file
26
src/server/maps/MapleMapObjectType.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public enum MapleMapObjectType {
|
||||
NPC, MONSTER, ITEM, PLAYER, DOOR, SUMMON, SHOP, MINI_GAME, MIST, REACTOR, HIRED_MERCHANT, PLAYER_NPC, DRAGON;
|
||||
}
|
||||
30
src/server/maps/MapleMapPortal.java
Normal file
30
src/server/maps/MapleMapPortal.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import server.MaplePortal;
|
||||
|
||||
public class MapleMapPortal extends MapleGenericPortal {
|
||||
public MapleMapPortal() {
|
||||
super(MaplePortal.MAP_PORTAL);
|
||||
}
|
||||
}
|
||||
86
src/server/maps/MapleMiniDungeon.java
Normal file
86
src/server/maps/MapleMiniDungeon.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package server.maps;
|
||||
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author SharpAceX(Alan)
|
||||
*/
|
||||
|
||||
public enum MapleMiniDungeon {
|
||||
|
||||
//http://bbb.hidden-street.net/search_finder/mini%20dungeon
|
||||
|
||||
CAVE_OF_MUSHROOMS(105050100, 105050101, 30),
|
||||
GOLEM_CASTLE_RUINS(105040304, 105040320, 34),
|
||||
HILL_OF_SANDSTORMS(260020600, 260020630, 30),
|
||||
HENESYS_PIG_FARM(100020000, 100020100, 30),
|
||||
DRAKES_BLUE_CAVE(105090311, 105090320, 30),
|
||||
DRUMMER_BUNNYS_LAIR(221023400, 221023401, 30),
|
||||
THE_ROUND_TABLE_OF_KENTARUS(240020500, 240020512, 30),
|
||||
THE_RESTORING_MEMORY(240040511, 240040800, 19),
|
||||
NEWT_SECURED_ZONE(240040520, 240040900, 19),
|
||||
PILLAGE_OF_TREASURE_ISLAND(251010402, 251010410, 30),
|
||||
;
|
||||
|
||||
private int baseId;
|
||||
private int dungeonId;
|
||||
private int dungeons;
|
||||
|
||||
private MapleMiniDungeon(int baseId, int dungeonId, int dungeons) {
|
||||
this.baseId = baseId;
|
||||
this.dungeonId = dungeonId;
|
||||
this.dungeons = dungeons;
|
||||
}
|
||||
|
||||
public int getBase() {
|
||||
return baseId;
|
||||
}
|
||||
|
||||
public int getDungeonId() {
|
||||
return dungeonId;
|
||||
}
|
||||
|
||||
public int getDungeons() {
|
||||
return dungeons;
|
||||
}
|
||||
|
||||
public static boolean isDungeonMap(int map){
|
||||
for (MapleMiniDungeon dungeon : MapleMiniDungeon.values()){
|
||||
if (map >= dungeon.getDungeonId() && map <= dungeon.getDungeonId() + dungeon.getDungeons()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static MapleMiniDungeon getDungeon(int map){
|
||||
for (MapleMiniDungeon dungeon : MapleMiniDungeon.values()){
|
||||
if (map >= dungeon.getDungeonId() && map <= dungeon.getDungeonId() + dungeon.getDungeons()){
|
||||
return dungeon;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
166
src/server/maps/MapleMist.java
Normal file
166
src/server/maps/MapleMist.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import constants.skills.BlazeWizard;
|
||||
import constants.skills.Evan;
|
||||
import constants.skills.FPMage;
|
||||
import constants.skills.NightWalker;
|
||||
import constants.skills.Shadower;
|
||||
import server.MapleStatEffect;
|
||||
import server.life.MapleMonster;
|
||||
import server.life.MobSkill;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LaiLaiNoob
|
||||
*/
|
||||
public class MapleMist extends AbstractMapleMapObject {
|
||||
private Rectangle mistPosition;
|
||||
private MapleCharacter owner = null;
|
||||
private MapleMonster mob = null;
|
||||
private MapleStatEffect source;
|
||||
private MobSkill skill;
|
||||
private boolean isMobMist, isPoisonMist, isRecoveryMist;
|
||||
private int skillDelay;
|
||||
|
||||
public MapleMist(Rectangle mistPosition, MapleMonster mob, MobSkill skill) {
|
||||
this.mistPosition = mistPosition;
|
||||
this.mob = mob;
|
||||
this.skill = skill;
|
||||
isMobMist = true;
|
||||
isPoisonMist = true;
|
||||
isRecoveryMist = false;
|
||||
skillDelay = 0;
|
||||
}
|
||||
|
||||
public MapleMist(Rectangle mistPosition, MapleCharacter owner, MapleStatEffect source) {
|
||||
this.mistPosition = mistPosition;
|
||||
this.owner = owner;
|
||||
this.source = source;
|
||||
this.skillDelay = 8;
|
||||
this.isMobMist = false;
|
||||
this.isRecoveryMist = false;
|
||||
this.isPoisonMist = false;
|
||||
switch (source.getSourceId()) {
|
||||
case Evan.RECOVERY_AURA:
|
||||
isRecoveryMist = true;
|
||||
break;
|
||||
case Shadower.SMOKE_SCREEN: // Smoke Screen
|
||||
isPoisonMist = false;
|
||||
break;
|
||||
case FPMage.POISON_MIST: // FP mist
|
||||
case BlazeWizard.FLAME_GEAR: // Flame Gear
|
||||
case NightWalker.POISON_BOMB: // Poison Bomb
|
||||
isPoisonMist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.MIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getPosition() {
|
||||
return mistPosition.getLocation();
|
||||
}
|
||||
|
||||
public Skill getSourceSkill() {
|
||||
return SkillFactory.getSkill(source.getSourceId());
|
||||
}
|
||||
|
||||
public boolean isMobMist() {
|
||||
return isMobMist;
|
||||
}
|
||||
|
||||
public boolean isPoisonMist() {
|
||||
return isPoisonMist;
|
||||
}
|
||||
|
||||
public boolean isRecoveryMist() {
|
||||
return isRecoveryMist;
|
||||
}
|
||||
|
||||
public int getSkillDelay() {
|
||||
return skillDelay;
|
||||
}
|
||||
|
||||
public MapleMonster getMobOwner() {
|
||||
return mob;
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public Rectangle getBox() {
|
||||
return mistPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(Point position) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public final byte[] makeDestroyData() {
|
||||
return MaplePacketCreator.removeMist(getObjectId());
|
||||
}
|
||||
|
||||
public final byte[] makeSpawnData() {
|
||||
if (owner != null) {
|
||||
return MaplePacketCreator.spawnMist(getObjectId(), owner.getId(), getSourceSkill().getId(), owner.getSkillLevel(SkillFactory.getSkill(source.getSourceId())), this);
|
||||
}
|
||||
return MaplePacketCreator.spawnMist(getObjectId(), mob.getId(), skill.getSkillId(), skill.getSkillLevel(), this);
|
||||
}
|
||||
|
||||
public final byte[] makeFakeSpawnData(int level) {
|
||||
if (owner != null) {
|
||||
return MaplePacketCreator.spawnMist(getObjectId(), owner.getId(), getSourceSkill().getId(), level, this);
|
||||
}
|
||||
return MaplePacketCreator.spawnMist(getObjectId(), mob.getId(), skill.getSkillId(), skill.getSkillLevel(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
client.announce(makeSpawnData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(makeDestroyData());
|
||||
}
|
||||
|
||||
public boolean makeChanceResult() {
|
||||
return source.makeChanceResult();
|
||||
}
|
||||
}
|
||||
204
src/server/maps/MapleReactor.java
Normal file
204
src/server/maps/MapleReactor.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleClient;
|
||||
import constants.ServerConstants;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
|
||||
import scripting.reactor.ReactorScriptManager;
|
||||
import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lerk
|
||||
*/
|
||||
public class MapleReactor extends AbstractMapleMapObject {
|
||||
private int rid;
|
||||
private MapleReactorStats stats;
|
||||
private byte state;
|
||||
private int delay;
|
||||
private MapleMap map;
|
||||
private String name;
|
||||
private boolean timerActive;
|
||||
private boolean alive;
|
||||
|
||||
public MapleReactor(MapleReactorStats stats, int rid) {
|
||||
this.stats = stats;
|
||||
this.rid = rid;
|
||||
alive = true;
|
||||
}
|
||||
|
||||
public void setTimerActive(boolean active) {
|
||||
this.timerActive = active;
|
||||
}
|
||||
|
||||
public boolean isTimerActive() {
|
||||
return timerActive;
|
||||
}
|
||||
|
||||
public void setState(byte state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public byte getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return rid;
|
||||
}
|
||||
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.REACTOR;
|
||||
}
|
||||
|
||||
public int getReactorType() {
|
||||
return stats.getType(state);
|
||||
}
|
||||
|
||||
public void setMap(MapleMap map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public MapleMap getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public Pair<Integer, Integer> getReactItem(byte index) {
|
||||
return stats.getReactItem(state, index);
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return alive;
|
||||
}
|
||||
|
||||
public void setAlive(boolean alive) {
|
||||
this.alive = alive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(makeDestroyData());
|
||||
}
|
||||
|
||||
public final byte[] makeDestroyData() {
|
||||
return MaplePacketCreator.destroyReactor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
client.announce(makeSpawnData());
|
||||
}
|
||||
|
||||
public final byte[] makeSpawnData() {
|
||||
return MaplePacketCreator.spawnReactor(this);
|
||||
}
|
||||
|
||||
public void forceHitReactor(final byte newState) {
|
||||
setState((byte) newState);
|
||||
setTimerActive(false);
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
}
|
||||
|
||||
public void delayedHitReactor(final MapleClient c, long delay) {
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hitReactor(c);
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
||||
public void hitReactor(MapleClient c) {
|
||||
hitReactor(0, (short) 0, 0, c);
|
||||
}
|
||||
|
||||
public synchronized void hitReactor(int charPos, short stance, int skillid, MapleClient c) {
|
||||
try {
|
||||
if(!this.isAlive()) {
|
||||
return;
|
||||
}
|
||||
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId());
|
||||
if (stats.getType(state) < 999 && stats.getType(state) != -1) {//type 2 = only hit from right (kerning swamp plants), 00 is air left 02 is ground left
|
||||
if (!(stats.getType(state) == 2 && (charPos == 0 || charPos == 2))) { //get next state
|
||||
for (byte b = 0; b < stats.getStateSize(state); b++) {//YAY?
|
||||
List<Integer> activeSkills = stats.getActiveSkills(state, b);
|
||||
if (activeSkills != null) {
|
||||
if (!activeSkills.contains(skillid)) continue;
|
||||
}
|
||||
state = stats.getNextState(state, b);
|
||||
if (stats.getNextState(state, b) == -1) {//end of reactor
|
||||
if (stats.getType(state) < 100) {//reactor broken
|
||||
if (delay > 0) {
|
||||
map.destroyReactor(getObjectId());
|
||||
} else {//trigger as normal
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
}
|
||||
} else {//item-triggered on final step
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
}
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
} else { //reactor not broken yet
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
if (state == stats.getNextState(state, b)) {//current state = next state, looping reactor
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state++;
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
|
||||
ReactorScriptManager.getInstance().act(c, this);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle getArea() {
|
||||
return new Rectangle(getPosition().x + stats.getTL().x, getPosition().y + stats.getTL().y, stats.getBR().x - stats.getTL().x, stats.getBR().y - stats.getTL().y);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
112
src/server/maps/MapleReactorFactory.java
Normal file
112
src/server/maps/MapleReactorFactory.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import server.maps.MapleReactorStats.StateData;
|
||||
import tools.Pair;
|
||||
import tools.StringUtil;
|
||||
|
||||
public class MapleReactorFactory {
|
||||
private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Reactor.wz"));
|
||||
private static Map<Integer, MapleReactorStats> reactorStats = new HashMap<Integer, MapleReactorStats>();
|
||||
|
||||
public static MapleReactorStats getReactor(int rid) {
|
||||
MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid));
|
||||
if (stats == null) {
|
||||
int infoId = rid;
|
||||
MapleData reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
|
||||
MapleData link = reactorData.getChildByPath("info/link");
|
||||
if (link != null) {
|
||||
infoId = MapleDataTool.getIntConvert("info/link", reactorData);
|
||||
stats = reactorStats.get(Integer.valueOf(infoId));
|
||||
}
|
||||
MapleData activateOnTouch = reactorData.getChildByPath("info/activateByTouch");
|
||||
boolean loadArea = false;
|
||||
if (activateOnTouch != null) {
|
||||
loadArea = MapleDataTool.getInt("info/activateByTouch", reactorData, 0) != 0;
|
||||
}
|
||||
if (stats == null) {
|
||||
reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
|
||||
MapleData reactorInfoData = reactorData.getChildByPath("0");
|
||||
stats = new MapleReactorStats();
|
||||
List<StateData> statedatas = new ArrayList<StateData>();
|
||||
if (reactorInfoData != null) {
|
||||
boolean areaSet = false;
|
||||
byte i = 0;
|
||||
while (reactorInfoData != null) {
|
||||
MapleData eventData = reactorInfoData.getChildByPath("event");
|
||||
if (eventData != null) {
|
||||
for (MapleData fknexon : eventData.getChildren()) {
|
||||
if (fknexon.getName().equals("timeOut")) continue;
|
||||
Pair<Integer, Integer> reactItem = null;
|
||||
int type = MapleDataTool.getIntConvert("type", fknexon);
|
||||
if (type == 100) { //reactor waits for item
|
||||
reactItem = new Pair<Integer, Integer>(MapleDataTool.getIntConvert("0", fknexon), MapleDataTool.getIntConvert("1", fknexon));
|
||||
if (!areaSet || loadArea) { //only set area of effect for item-triggered reactors once
|
||||
stats.setTL(MapleDataTool.getPoint("lt", fknexon));
|
||||
stats.setBR(MapleDataTool.getPoint("rb", fknexon));
|
||||
areaSet = true;
|
||||
}
|
||||
}
|
||||
MapleData activeSkillID = fknexon.getChildByPath("activeSkillID");
|
||||
List<Integer> skillids = null;
|
||||
if (activeSkillID != null) {
|
||||
skillids = new ArrayList<Integer>();
|
||||
for (MapleData skill : activeSkillID.getChildren()) {
|
||||
skillids.add(MapleDataTool.getInt(skill));
|
||||
}
|
||||
}
|
||||
byte nextState = (byte) MapleDataTool.getIntConvert("state", fknexon);
|
||||
statedatas.add(new StateData(type, reactItem, skillids, nextState));
|
||||
}
|
||||
stats.addState(i, statedatas);
|
||||
}
|
||||
i++;
|
||||
reactorInfoData = reactorData.getChildByPath(Byte.toString(i));
|
||||
statedatas = new ArrayList<StateData>();
|
||||
}
|
||||
} else //sit there and look pretty; likely a reactor such as Zakum/Papulatus doors that shows if player can enter
|
||||
{
|
||||
statedatas.add(new StateData(999, null, null, (byte) 0));
|
||||
stats.addState((byte) 0, statedatas);
|
||||
}
|
||||
reactorStats.put(Integer.valueOf(infoId), stats);
|
||||
if (rid != infoId) {
|
||||
reactorStats.put(Integer.valueOf(rid), stats);
|
||||
}
|
||||
} else // stats exist at infoId but not rid; add to map
|
||||
{
|
||||
reactorStats.put(Integer.valueOf(rid), stats);
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
129
src/server/maps/MapleReactorStats.java
Normal file
129
src/server/maps/MapleReactorStats.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
* @author Lerk
|
||||
*/
|
||||
public class MapleReactorStats {
|
||||
private Point tl;
|
||||
private Point br;
|
||||
private Map<Byte, List<StateData>> stateInfo = new HashMap<Byte, List<StateData>>();
|
||||
|
||||
public void setTL(Point tl) {
|
||||
this.tl = tl;
|
||||
}
|
||||
|
||||
public void setBR(Point br) {
|
||||
this.br = br;
|
||||
}
|
||||
|
||||
public Point getTL() {
|
||||
return tl;
|
||||
}
|
||||
|
||||
public Point getBR() {
|
||||
return br;
|
||||
}
|
||||
|
||||
public void addState(byte state, List<StateData> data) {
|
||||
stateInfo.put(state, data);
|
||||
}
|
||||
|
||||
public byte getStateSize(byte state) {
|
||||
return (byte) stateInfo.get(state).size();
|
||||
}
|
||||
|
||||
public byte getNextState(byte state, byte index) {
|
||||
if (stateInfo.get(state) == null || stateInfo.get(state).size() < (index + 1)) return -1;
|
||||
StateData nextState = stateInfo.get(state).get(index);
|
||||
if (nextState != null) {
|
||||
return nextState.getNextState();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Integer> getActiveSkills(byte state, byte index) {
|
||||
StateData nextState = stateInfo.get(state).get(index);
|
||||
if (nextState != null) {
|
||||
return nextState.getActiveSkills();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getType(byte state) {
|
||||
List<StateData> list = stateInfo.get(state);
|
||||
if (list != null) {
|
||||
return list.get(0).getType();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<Integer, Integer> getReactItem(byte state, byte index) {
|
||||
StateData nextState = stateInfo.get(state).get(index);
|
||||
if (nextState != null) {
|
||||
return nextState.getReactItem();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class StateData {
|
||||
private int type;
|
||||
private Pair<Integer, Integer> reactItem;
|
||||
private List<Integer> activeSkills;
|
||||
private byte nextState;
|
||||
|
||||
public StateData(int type, Pair<Integer, Integer> reactItem, List<Integer> activeSkills, byte nextState) {
|
||||
this.type = type;
|
||||
this.reactItem = reactItem;
|
||||
this.activeSkills = activeSkills;
|
||||
this.nextState = nextState;
|
||||
}
|
||||
|
||||
private int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
private byte getNextState() {
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private Pair<Integer, Integer> getReactItem() {
|
||||
return reactItem;
|
||||
}
|
||||
|
||||
private List<Integer> getActiveSkills() {
|
||||
return activeSkills;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/server/maps/MapleSummon.java
Normal file
101
src/server/maps/MapleSummon.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.SkillFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jan
|
||||
*/
|
||||
public class MapleSummon extends AbstractAnimatedMapleMapObject {
|
||||
private MapleCharacter owner;
|
||||
private byte skillLevel;
|
||||
private int skill, hp;
|
||||
private SummonMovementType movementType;
|
||||
|
||||
public MapleSummon(MapleCharacter owner, int skill, Point pos, SummonMovementType movementType) {
|
||||
this.owner = owner;
|
||||
this.skill = skill;
|
||||
this.skillLevel = owner.getSkillLevel(SkillFactory.getSkill(skill));
|
||||
if (skillLevel == 0) throw new RuntimeException();
|
||||
|
||||
this.movementType = movementType;
|
||||
setPosition(pos);
|
||||
}
|
||||
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
if (this != null) client.announce(MaplePacketCreator.spawnSummon(this, false));
|
||||
|
||||
}
|
||||
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.removeSummon(this, true));
|
||||
}
|
||||
|
||||
public MapleCharacter getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public int getSkill() {
|
||||
return skill;
|
||||
}
|
||||
|
||||
public int getHP() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public void addHP(int delta) {
|
||||
this.hp += delta;
|
||||
}
|
||||
|
||||
public SummonMovementType getMovementType() {
|
||||
return movementType;
|
||||
}
|
||||
|
||||
public boolean isStationary() {
|
||||
return (skill == 3111002 || skill == 3211002 || skill == 5211001 || skill == 13111004);
|
||||
}
|
||||
|
||||
public byte getSkillLevel() {
|
||||
return skillLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.SUMMON;
|
||||
}
|
||||
|
||||
public final boolean isPuppet() {
|
||||
switch (skill) {
|
||||
case 3111002:
|
||||
case 3211002:
|
||||
case 13111004:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
78
src/server/maps/MapleTVEffect.java
Normal file
78
src/server/maps/MapleTVEffect.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.server.Server;
|
||||
import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/*
|
||||
* MapleTVEffect
|
||||
* @author MrXotic
|
||||
*/
|
||||
public class MapleTVEffect {
|
||||
|
||||
private static boolean ACTIVE;
|
||||
|
||||
private List<String> message = new ArrayList<>(5);
|
||||
private MapleCharacter user;
|
||||
private int type;
|
||||
private MapleCharacter partner;
|
||||
|
||||
public MapleTVEffect(MapleCharacter u, MapleCharacter p, List<String> msg, int t) {
|
||||
this.message = msg;
|
||||
this.user = u;
|
||||
this.type = t;
|
||||
this.partner = p;
|
||||
broadcastTV(true);
|
||||
}
|
||||
|
||||
public static boolean isActive(){
|
||||
return ACTIVE;
|
||||
}
|
||||
|
||||
private void broadcastTV(boolean activity) {
|
||||
Server server = Server.getInstance();
|
||||
ACTIVE = activity;
|
||||
if (ACTIVE) {
|
||||
server.broadcastMessage(MaplePacketCreator.enableTV());
|
||||
server.broadcastMessage(MaplePacketCreator.sendTV(user, message, type <= 2 ? type : type - 3, partner));
|
||||
int delay = 15000;
|
||||
if (type == 4) {
|
||||
delay = 30000;
|
||||
} else if (type == 5) {
|
||||
delay = 60000;
|
||||
}
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
broadcastTV(false);
|
||||
}
|
||||
}, delay);
|
||||
} else {
|
||||
server.broadcastMessage(MaplePacketCreator.removeTV());
|
||||
}
|
||||
}
|
||||
}
|
||||
124
src/server/maps/PlayerNPCs.java
Normal file
124
src/server/maps/PlayerNPCs.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import client.MapleClient;
|
||||
import java.sql.SQLException;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author XoticStory
|
||||
*/
|
||||
public class PlayerNPCs extends AbstractMapleMapObject {
|
||||
private Map<Short, Integer> equips = new HashMap<Short, Integer>();
|
||||
private int npcId, face, hair;
|
||||
private byte skin;
|
||||
private String name = "";
|
||||
private int FH, RX0, RX1, CY;
|
||||
|
||||
public PlayerNPCs(ResultSet rs) {
|
||||
try {
|
||||
CY = rs.getInt("cy");
|
||||
name = rs.getString("name");
|
||||
hair = rs.getInt("hair");
|
||||
face = rs.getInt("face");
|
||||
skin = rs.getByte("skin");
|
||||
FH = rs.getInt("Foothold");
|
||||
RX0 = rs.getInt("rx0");
|
||||
RX1 = rs.getInt("rx1");
|
||||
npcId = rs.getInt("ScriptId");
|
||||
setPosition(new Point(rs.getInt("x"), CY));
|
||||
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT equippos, equipid FROM playernpcs_equip WHERE NpcId = ?");
|
||||
ps.setInt(1, rs.getInt("id"));
|
||||
ResultSet rs2 = ps.executeQuery();
|
||||
while (rs2.next()) {
|
||||
equips.put(rs2.getShort("equippos"), rs2.getInt("equipid"));
|
||||
}
|
||||
rs2.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Short, Integer> getEquips() {
|
||||
return equips;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return npcId;
|
||||
}
|
||||
|
||||
public int getFH() {
|
||||
return FH;
|
||||
}
|
||||
|
||||
public int getRX0() {
|
||||
return RX0;
|
||||
}
|
||||
|
||||
public int getRX1() {
|
||||
return RX1;
|
||||
}
|
||||
|
||||
public int getCY() {
|
||||
return CY;
|
||||
}
|
||||
|
||||
public byte getSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
public int getHair() {
|
||||
return hair;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDestroyData(MapleClient client) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleMapObjectType getType() {
|
||||
return MapleMapObjectType.PLAYER_NPC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
client.announce(MaplePacketCreator.spawnPlayerNPC(this));
|
||||
client.announce(MaplePacketCreator.getPlayerNPC(this));
|
||||
}
|
||||
}
|
||||
32
src/server/maps/ReactorDropEntry.java
Normal file
32
src/server/maps/ReactorDropEntry.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 ~ 2010 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public class ReactorDropEntry {
|
||||
|
||||
public ReactorDropEntry(int itemId, int chance, int questId) {
|
||||
this.itemId = itemId;
|
||||
this.chance = chance;
|
||||
this.questid = questId;
|
||||
}
|
||||
public int itemId, chance, questid;
|
||||
public int assignedRangeStart, assignedRangeLength;
|
||||
}
|
||||
39
src/server/maps/SavedLocation.java
Normal file
39
src/server/maps/SavedLocation.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public class SavedLocation {
|
||||
private int mapid = 102000000, portal;
|
||||
|
||||
public SavedLocation(int mapid, int portal) {
|
||||
this.mapid = mapid;
|
||||
this.portal = portal;
|
||||
}
|
||||
|
||||
public int getMapId() {
|
||||
return mapid;
|
||||
}
|
||||
|
||||
public int getPortal() {
|
||||
return portal;
|
||||
}
|
||||
}
|
||||
37
src/server/maps/SavedLocationType.java
Normal file
37
src/server/maps/SavedLocationType.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public enum SavedLocationType {
|
||||
FREE_MARKET,
|
||||
EVENT,
|
||||
WORLDTOUR,
|
||||
FLORINA,
|
||||
INTRO,
|
||||
SUNDAY_MARKET,
|
||||
MIRROR,
|
||||
DOJO;
|
||||
|
||||
public static SavedLocationType fromString(String Str) {
|
||||
return valueOf(Str);
|
||||
}
|
||||
}
|
||||
35
src/server/maps/SummonMovementType.java
Normal file
35
src/server/maps/SummonMovementType.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.maps;
|
||||
|
||||
public enum SummonMovementType {
|
||||
STATIONARY(0), FOLLOW(1), CIRCLE_FOLLOW(3);
|
||||
private final int val;
|
||||
|
||||
private SummonMovementType(int val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
62
src/server/movement/AbsoluteLifeMovement.java
Normal file
62
src/server/movement/AbsoluteLifeMovement.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class AbsoluteLifeMovement extends AbstractLifeMovement {
|
||||
private Point pixelsPerSecond;
|
||||
private int unk;
|
||||
|
||||
public AbsoluteLifeMovement(int type, Point position, int duration, int newstate) {
|
||||
super(type, position, duration, newstate);
|
||||
}
|
||||
|
||||
public Point getPixelsPerSecond() {
|
||||
return pixelsPerSecond;
|
||||
}
|
||||
|
||||
public void setPixelsPerSecond(Point wobble) {
|
||||
this.pixelsPerSecond = wobble;
|
||||
}
|
||||
|
||||
public int getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public void setUnk(int unk) {
|
||||
this.unk = unk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(getType());
|
||||
lew.writeShort(getPosition().x);
|
||||
lew.writeShort(getPosition().y);
|
||||
lew.writeShort(pixelsPerSecond.x);
|
||||
lew.writeShort(pixelsPerSecond.y);
|
||||
lew.writeShort(unk);
|
||||
lew.write(getNewstate());
|
||||
lew.writeShort(getDuration());
|
||||
}
|
||||
}
|
||||
58
src/server/movement/AbstractLifeMovement.java
Normal file
58
src/server/movement/AbstractLifeMovement.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
public abstract class AbstractLifeMovement implements LifeMovement {
|
||||
private Point position;
|
||||
private int duration;
|
||||
private int newstate, type;
|
||||
|
||||
public AbstractLifeMovement(int type, Point position, int duration, int newstate) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.position = position;
|
||||
this.duration = duration;
|
||||
this.newstate = newstate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewstate() {
|
||||
return newstate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
52
src/server/movement/ChairMovement.java
Normal file
52
src/server/movement/ChairMovement.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class ChairMovement extends AbstractLifeMovement {
|
||||
private int unk;
|
||||
|
||||
public ChairMovement(int type, Point position, int duration, int newstate) {
|
||||
super(type, position, duration, newstate);
|
||||
}
|
||||
|
||||
public int getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public void setUnk(int unk) {
|
||||
this.unk = unk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(getType());
|
||||
lew.writeShort(getPosition().x);
|
||||
lew.writeShort(getPosition().y);
|
||||
lew.writeShort(unk);
|
||||
lew.write(getNewstate());
|
||||
lew.writeShort(getDuration());
|
||||
}
|
||||
}
|
||||
|
||||
44
src/server/movement/ChangeEquip.java
Normal file
44
src/server/movement/ChangeEquip.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class ChangeEquip implements LifeMovementFragment {
|
||||
private int wui;
|
||||
|
||||
public ChangeEquip(int wui) {
|
||||
this.wui = wui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(10);
|
||||
lew.write(wui);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getPosition() {
|
||||
return new Point(0, 0);
|
||||
}
|
||||
}
|
||||
72
src/server/movement/JumpDownMovement.java
Normal file
72
src/server/movement/JumpDownMovement.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class JumpDownMovement extends AbstractLifeMovement {
|
||||
private Point pixelsPerSecond;
|
||||
private int unk;
|
||||
private int fh;
|
||||
|
||||
public JumpDownMovement(int type, Point position, int duration, int newstate) {
|
||||
super(type, position, duration, newstate);
|
||||
}
|
||||
|
||||
public Point getPixelsPerSecond() {
|
||||
return pixelsPerSecond;
|
||||
}
|
||||
|
||||
public void setPixelsPerSecond(Point wobble) {
|
||||
this.pixelsPerSecond = wobble;
|
||||
}
|
||||
|
||||
public int getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public void setUnk(int unk) {
|
||||
this.unk = unk;
|
||||
}
|
||||
|
||||
public int getFH() {
|
||||
return fh;
|
||||
}
|
||||
|
||||
public void setFH(int fh) {
|
||||
this.fh = fh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(getType());
|
||||
lew.writeShort(getPosition().x);
|
||||
lew.writeShort(getPosition().y);
|
||||
lew.writeShort(pixelsPerSecond.x);
|
||||
lew.writeShort(pixelsPerSecond.y);
|
||||
lew.writeShort(unk);
|
||||
lew.writeShort(fh);
|
||||
lew.write(getNewstate());
|
||||
lew.writeShort(getDuration());
|
||||
}
|
||||
}
|
||||
31
src/server/movement/LifeMovement.java
Normal file
31
src/server/movement/LifeMovement.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
public interface LifeMovement extends LifeMovementFragment {
|
||||
Point getPosition();
|
||||
int getNewstate();
|
||||
int getDuration();
|
||||
int getType();
|
||||
}
|
||||
30
src/server/movement/LifeMovementFragment.java
Normal file
30
src/server/movement/LifeMovementFragment.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public interface LifeMovementFragment {
|
||||
void serialize(LittleEndianWriter lew);
|
||||
Point getPosition();
|
||||
}
|
||||
40
src/server/movement/RelativeLifeMovement.java
Normal file
40
src/server/movement/RelativeLifeMovement.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class RelativeLifeMovement extends AbstractLifeMovement {
|
||||
public RelativeLifeMovement(int type, Point position, int duration, int newstate) {
|
||||
super(type, position, duration, newstate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(getType());
|
||||
lew.writeShort(getPosition().x);
|
||||
lew.writeShort(getPosition().y);
|
||||
lew.write(getNewstate());
|
||||
lew.writeShort(getDuration());
|
||||
}
|
||||
}
|
||||
41
src/server/movement/TeleportMovement.java
Normal file
41
src/server/movement/TeleportMovement.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3
|
||||
as published by the Free Software Foundation. You may not use, modify
|
||||
or distribute this program under any other version of the
|
||||
GNU Affero General Public License.
|
||||
|
||||
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 server.movement;
|
||||
|
||||
import java.awt.Point;
|
||||
import tools.data.output.LittleEndianWriter;
|
||||
|
||||
public class TeleportMovement extends AbsoluteLifeMovement {
|
||||
|
||||
public TeleportMovement(int type, Point position, int newstate) {
|
||||
super(type, position, 0, newstate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianWriter lew) {
|
||||
lew.write(getType());
|
||||
lew.writeShort(getPosition().x);
|
||||
lew.writeShort(getPosition().y);
|
||||
lew.writeShort(getPixelsPerSecond().x);
|
||||
lew.writeShort(getPixelsPerSecond().y);
|
||||
lew.write(getNewstate());
|
||||
}
|
||||
}
|
||||
172
src/server/partyquest/MonsterCarnival.java
Normal file
172
src/server/partyquest/MonsterCarnival.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 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 version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
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 server.partyquest;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import server.TimerManager;
|
||||
import server.maps.MapleMap;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93 - LOST MOTIVATION >=(
|
||||
*/
|
||||
public class MonsterCarnival {
|
||||
private MonsterCarnivalParty red, blue;
|
||||
private MapleMap map;
|
||||
private int room;
|
||||
private long time = 0;
|
||||
private long timeStarted = 0;
|
||||
private ScheduledFuture<?> schedule = null;
|
||||
|
||||
public MonsterCarnival(int room, byte channel, MonsterCarnivalParty red1, MonsterCarnivalParty blue1) {
|
||||
//this.map = Channel.getInstance(channel).getMapFactory().getMap(980000001 + (room * 100));
|
||||
this.room = room;
|
||||
this.red = red1;
|
||||
this.blue = blue1;
|
||||
this.timeStarted = System.currentTimeMillis();
|
||||
this.time = 600000;
|
||||
map.broadcastMessage(MaplePacketCreator.getClock((int) (time / 1000)));
|
||||
|
||||
for (MapleCharacter chr : red.getMembers())
|
||||
chr.setCarnival(this);
|
||||
for (MapleCharacter chr : blue.getMembers())
|
||||
chr.setCarnival(this);
|
||||
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (red.getTotalCP() > blue.getTotalCP()) {
|
||||
red.setWinner(true);
|
||||
blue.setWinner(false);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
} else if (blue.getTotalCP() > red.getTotalCP()) {
|
||||
red.setWinner(false);
|
||||
blue.setWinner(true);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
} else {
|
||||
red.setWinner(false);
|
||||
blue.setWinner(false);
|
||||
red.displayMatchResult();
|
||||
blue.displayMatchResult();
|
||||
}
|
||||
saveResults();
|
||||
warpOut();
|
||||
}
|
||||
|
||||
}, time);
|
||||
/* if (room == 0) {
|
||||
MapleData data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Map.wz")).getData("Map/Map9" + (980000001 + (room * 100)) + ".img").getChildByPath("monsterCarnival");
|
||||
if (data != null) {
|
||||
for (MapleData p : data.getChildByPath("mobGenPos").getChildren()) {
|
||||
MapleData team = p.getChildByPath("team");
|
||||
if (team != null) {
|
||||
if (team.getData().equals(0))
|
||||
redmonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
else
|
||||
bluemonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
} else
|
||||
monsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
}
|
||||
for (MapleData p : data.getChildByPath("guardianGenPos").getChildren()) {
|
||||
MapleData team = p.getChildByPath("team");
|
||||
if (team != null) {
|
||||
if (team.getData().equals(0))
|
||||
redreactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
else
|
||||
bluereactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
} else
|
||||
reactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y"))));
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return time - (System.currentTimeMillis() - timeStarted);
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty getPartyRed() {
|
||||
return red;
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty getPartyBlue() {
|
||||
return blue;
|
||||
}
|
||||
|
||||
public MonsterCarnivalParty oppositeTeam(MonsterCarnivalParty team) {
|
||||
if (team == red)
|
||||
return blue;
|
||||
else
|
||||
return red;
|
||||
}
|
||||
|
||||
public void playerLeft(MapleCharacter chr) {
|
||||
map.broadcastMessage(chr, MaplePacketCreator.leaveCPQ(chr));
|
||||
}
|
||||
|
||||
private void warpOut() {
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
red.warpOut();
|
||||
blue.warpOut();
|
||||
}
|
||||
}, 12000);
|
||||
}
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
public void saveResults() {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try {
|
||||
PreparedStatement ps = con.prepareStatement("INSERT INTO carnivalresults VALUES (?,?,?,?)");
|
||||
for (MapleCharacter chr : red.getMembers()) {
|
||||
ps.setInt(1, chr.getId());
|
||||
ps.setInt(2, chr.getCP());
|
||||
ps.setInt(3, red.getTotalCP());
|
||||
ps.setInt(4, red.isWinner() ? 1 : 0);
|
||||
ps.execute();
|
||||
}
|
||||
for (MapleCharacter chr : blue.getMembers()) {
|
||||
ps.setInt(1, chr.getId());
|
||||
ps.setInt(2, chr.getCP());
|
||||
ps.setInt(3, blue.getTotalCP());
|
||||
ps.setInt(4, blue.isWinner() ? 1 : 0);
|
||||
ps.execute();
|
||||
}
|
||||
ps.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user