Neo City + Revamped EllinPQ + New Release
Fixed Neo City area, now playable. Overhauled the EllinPQ mechanics, such as the "CLEAR" effect when passing maps, and some bug fixes along the way. Refactored a lot of out-of-place classes and properly renamed a few others through the project. Updated readme and licenses through the source, preparing the stage for the new release.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
This file is part of the MapleSolaxiaV2 Maple Story Server
|
||||
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
|
||||
Copyleft (L) 2017 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
@@ -16,7 +17,6 @@
|
||||
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.Collection;
|
||||
|
||||
@@ -274,7 +274,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
return takenDamage.containsKey(chr.getId());
|
||||
}
|
||||
|
||||
private void distributeExperienceToParty(int pid, int exp, int killer, Set<MapleCharacter> underleveled) {
|
||||
private void distributeExperienceToParty(int pid, int exp, int killer, Set<MapleCharacter> underleveled, int minThresholdLevel) {
|
||||
List<MapleCharacter> members = new LinkedList<>();
|
||||
MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid);
|
||||
if(pchar != null) {
|
||||
@@ -289,11 +289,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
int partyLevel = 0;
|
||||
int leechMinLevel = (ServerConstants.USE_ENFORCE_MOB_LEVEL_RANGE) ? getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN : 0; //NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
|
||||
int leechCount = 0;
|
||||
for (MapleCharacter mc : members) {
|
||||
if (mc.getLevel() >= leechMinLevel) {
|
||||
if (mc.getLevel() >= minThresholdLevel) { //NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
partyLevel += mc.getLevel();
|
||||
leechCount++;
|
||||
} else {
|
||||
@@ -306,7 +304,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
for (MapleCharacter mc : members) {
|
||||
int id = mc.getId();
|
||||
int level = mc.getLevel();
|
||||
if (level >= leechMinLevel) {
|
||||
if (level >= minThresholdLevel) {
|
||||
boolean isKiller = killer == id;
|
||||
boolean mostDamage = mostDamageCid == id;
|
||||
int xp = (int) ((0.80f * exp * level) / partyLevel);
|
||||
@@ -318,10 +316,20 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
}
|
||||
|
||||
private int calcThresholdLevel(boolean isPqMob) {
|
||||
if(isPqMob || !ServerConstants.USE_ENFORCE_MOB_LEVEL_RANGE) {
|
||||
return 0;
|
||||
} else {
|
||||
return getLevel() - (!isBoss() ? ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN : 2 * ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN);
|
||||
}
|
||||
}
|
||||
|
||||
public void distributeExperience(int killerId) {
|
||||
if (isAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int minThresholdLevel = calcThresholdLevel(this.getMap().getEventInstance() != null);
|
||||
int exp = getExp();
|
||||
long totalHealth = maxHpPlusHeal.get();
|
||||
Map<Integer, Integer> expDist = new HashMap<>();
|
||||
@@ -349,7 +357,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
long pXP = (long)xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
|
||||
partyExp.put(pID, (int)Math.min(pXP, Integer.MAX_VALUE));
|
||||
} else {
|
||||
if(!ServerConstants.USE_ENFORCE_MOB_LEVEL_RANGE || mc.getLevel() >= getLevel() - ServerConstants.MIN_UNDERLEVEL_TO_EXP_GAIN) {
|
||||
if(mc.getLevel() >= minThresholdLevel) {
|
||||
//NO EXP WILL BE GIVEN for those who are underleveled!
|
||||
giveExpToCharacter(mc, xp, isKiller, 1);
|
||||
} else {
|
||||
@@ -360,7 +368,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
for (Entry<Integer, Integer> party : partyExp.entrySet()) {
|
||||
distributeExperienceToParty(party.getKey(), party.getValue(), killerId, underleveled);
|
||||
distributeExperienceToParty(party.getKey(), party.getValue(), killerId, underleveled, minThresholdLevel);
|
||||
}
|
||||
|
||||
for(MapleCharacter mc : underleveled) {
|
||||
@@ -479,12 +487,12 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
return looter != null ? looter : killer;
|
||||
}
|
||||
|
||||
public void dispatchMonsterKilled() {
|
||||
public void dispatchMonsterKilled(boolean hasKiller) {
|
||||
if (getMap().getEventInstance() != null) {
|
||||
if (!this.getStats().isFriendly()) {
|
||||
getMap().getEventInstance().monsterKilled(this);
|
||||
getMap().getEventInstance().monsterKilled(this, hasKiller);
|
||||
} else {
|
||||
getMap().getEventInstance().friendlyKilled(this);
|
||||
getMap().getEventInstance().friendlyKilled(this, hasKiller);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <[email protected]>
|
||||
Matthias Butz <[email protected]>
|
||||
Jan Christian Meyer <[email protected]>
|
||||
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
|
||||
Copyleft (L) 2017 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
|
||||
@@ -41,7 +41,6 @@ import tools.locks.MonitoredReentrantLock;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MaplePlayerShopItem;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
@@ -262,9 +262,7 @@ public class MapleMap {
|
||||
MapleReactor mr = (MapleReactor) o;
|
||||
mr.lockReactor();
|
||||
try {
|
||||
mr.setState((byte) 1);
|
||||
mr.resetReactorActions();
|
||||
|
||||
mr.resetReactorActions(1);
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor((MapleReactor) o, 1));
|
||||
} finally {
|
||||
mr.unlockReactor();
|
||||
@@ -768,7 +766,7 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
private void spawnDrop(final Item idrop, final Point dropPos, final MapleMapObject dropper, final MapleCharacter chr, final byte droptype, final short questid) {
|
||||
final MapleMapItem mdrop = new MapleMapItem(idrop, dropPos, dropper, chr, droptype, false, questid);
|
||||
final MapleMapItem mdrop = new MapleMapItem(idrop, dropPos, dropper, chr, chr.getClient(), droptype, false, questid);
|
||||
mdrop.setDropTime(System.currentTimeMillis());
|
||||
spawnAndAddRangedMapObject(mdrop, new DelayedPacketCreation() {
|
||||
@Override
|
||||
@@ -785,7 +783,7 @@ public class MapleMap {
|
||||
|
||||
public final void spawnMesoDrop(final int meso, final Point position, final MapleMapObject dropper, final MapleCharacter owner, final boolean playerDrop, final byte droptype) {
|
||||
final Point droppos = calcDropPos(position, position);
|
||||
final MapleMapItem mdrop = new MapleMapItem(meso, droppos, dropper, owner, droptype, playerDrop);
|
||||
final MapleMapItem mdrop = new MapleMapItem(meso, droppos, dropper, owner, owner.getClient(), droptype, playerDrop);
|
||||
mdrop.setDropTime(System.currentTimeMillis());
|
||||
|
||||
spawnAndAddRangedMapObject(mdrop, new DelayedPacketCreation() {
|
||||
@@ -800,7 +798,7 @@ public class MapleMap {
|
||||
|
||||
public final void disappearingItemDrop(final MapleMapObject dropper, final MapleCharacter owner, final Item item, final Point pos) {
|
||||
final Point droppos = calcDropPos(pos, pos);
|
||||
final MapleMapItem drop = new MapleMapItem(item, droppos, dropper, owner, (byte) 1, false);
|
||||
final MapleMapItem drop = new MapleMapItem(item, droppos, dropper, owner, owner.getClient(), (byte) 1, false);
|
||||
broadcastMessage(MaplePacketCreator.dropItemFromMapObject(drop, dropper.getPosition(), droppos, (byte) 3), drop.getPosition());
|
||||
}
|
||||
|
||||
@@ -1024,7 +1022,7 @@ public class MapleMap {
|
||||
spawnedMonstersOnMap.decrementAndGet();
|
||||
monster.setHp(0);
|
||||
removeMapObject(monster);
|
||||
monster.dispatchMonsterKilled();
|
||||
monster.dispatchMonsterKilled(false);
|
||||
broadcastMessage(MaplePacketCreator.killMonster(monster.getObjectId(), animation), monster.getPosition());
|
||||
return;
|
||||
}
|
||||
@@ -1104,7 +1102,7 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
monster.dispatchMonsterKilled();
|
||||
monster.dispatchMonsterKilled(true);
|
||||
broadcastMessage(MaplePacketCreator.killMonster(monster.getObjectId(), animation), monster.getPosition());
|
||||
}
|
||||
|
||||
@@ -1202,26 +1200,29 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public void resetReactors() {
|
||||
List<MapleReactor> list = new ArrayList<>();
|
||||
|
||||
objectRLock.lock();
|
||||
try {
|
||||
for (MapleMapObject o : mapobjects.values()) {
|
||||
if (o.getType() == MapleMapObjectType.REACTOR) {
|
||||
final MapleReactor r = ((MapleReactor) o);
|
||||
|
||||
r.lockReactor();
|
||||
try {
|
||||
r.setState((byte) 0);
|
||||
r.resetReactorActions();
|
||||
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(r, 0));
|
||||
} finally {
|
||||
r.unlockReactor();
|
||||
}
|
||||
list.add(r);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
objectRLock.unlock();
|
||||
}
|
||||
|
||||
for (MapleReactor r : list) {
|
||||
r.lockReactor();
|
||||
try {
|
||||
r.resetReactorActions(0);
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(r, 0));
|
||||
} finally {
|
||||
r.unlockReactor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shuffleReactors() {
|
||||
@@ -1680,8 +1681,7 @@ public class MapleMap {
|
||||
private void respawnReactor(final MapleReactor reactor) {
|
||||
reactor.lockReactor();
|
||||
try {
|
||||
reactor.setState((byte) 0);
|
||||
reactor.resetReactorActions();
|
||||
reactor.resetReactorActions(0);
|
||||
reactor.setAlive(true);
|
||||
} finally {
|
||||
reactor.unlockReactor();
|
||||
@@ -1799,7 +1799,7 @@ public class MapleMap {
|
||||
|
||||
public final void spawnItemDrop(final MapleMapObject dropper, final MapleCharacter owner, final Item item, Point pos, final byte dropType, final boolean playerDrop) {
|
||||
final Point droppos = calcDropPos(pos, pos);
|
||||
final MapleMapItem mdrop = new MapleMapItem(item, droppos, dropper, owner, dropType, playerDrop);
|
||||
final MapleMapItem mdrop = new MapleMapItem(item, droppos, dropper, owner, owner.getClient(), dropType, playerDrop);
|
||||
mdrop.setDropTime(System.currentTimeMillis());
|
||||
|
||||
spawnAndAddRangedMapObject(mdrop, new DelayedPacketCreation() {
|
||||
@@ -1874,6 +1874,39 @@ public class MapleMap {
|
||||
}
|
||||
}
|
||||
|
||||
public void searchItemReactors(final MapleReactor react) {
|
||||
if (react.getReactorType() == 100) {
|
||||
Pair<Integer, Integer> reactProp = react.getReactItem(react.getEventState());
|
||||
int reactItem = reactProp.getLeft(), reactQty = reactProp.getRight();
|
||||
Rectangle reactArea = react.getArea();
|
||||
|
||||
List<MapleMapItem> list = new ArrayList<>();
|
||||
objectRLock.lock();
|
||||
try {
|
||||
for(MapleMapItem mmi : droppedItems.keySet()) {
|
||||
if(!mmi.isPickedUp()) {
|
||||
list.add(mmi);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
objectRLock.unlock();
|
||||
}
|
||||
|
||||
for(final MapleMapItem drop : list) {
|
||||
final Item item = drop.getItem();
|
||||
|
||||
if (reactItem == item.getItemId() && reactQty == item.getQuantity()) {
|
||||
if (reactArea.contains(drop.getPosition())) {
|
||||
MapleClient owner = drop.getOwnerClient();
|
||||
if(owner != null) {
|
||||
TimerManager.getInstance().schedule(new ActivateItemReactor(drop, react, owner), 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void changeEnvironment(String mapObj, int newState) {
|
||||
broadcastMessage(MaplePacketCreator.environmentChange(mapObj, newState));
|
||||
}
|
||||
@@ -2808,6 +2841,7 @@ public class MapleMap {
|
||||
if (mapitem.isPickedUp()) {
|
||||
return;
|
||||
}
|
||||
mapitem.setPickedUp(true);
|
||||
|
||||
reactor.setShouldCollect(false);
|
||||
MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition());
|
||||
@@ -2821,9 +2855,7 @@ public class MapleMap {
|
||||
public void run() {
|
||||
reactor.lockReactor();
|
||||
try {
|
||||
reactor.setState((byte) 0);
|
||||
reactor.resetReactorActions();
|
||||
|
||||
reactor.resetReactorActions(0);
|
||||
broadcastMessage(MaplePacketCreator.triggerReactor(reactor, 0));
|
||||
} finally {
|
||||
reactor.unlockReactor();
|
||||
|
||||
@@ -340,9 +340,8 @@ public class MapleMapFactory {
|
||||
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"), ""));
|
||||
myReactor.resetReactorActions();
|
||||
myReactor.resetReactorActions(0);
|
||||
return myReactor;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import tools.MaplePacketCreator;
|
||||
import tools.locks.MonitoredLockType;
|
||||
|
||||
public class MapleMapItem extends AbstractMapleMapObject {
|
||||
|
||||
protected MapleClient ownerClient;
|
||||
protected Item item;
|
||||
protected MapleMapObject dropper;
|
||||
protected int character_ownerid, meso, questid = -1;
|
||||
@@ -39,33 +39,36 @@ public class MapleMapItem extends AbstractMapleMapObject {
|
||||
protected long dropTime;
|
||||
private Lock itemLock = new MonitoredReentrantLock(MonitoredLockType.MAP_ITEM);
|
||||
|
||||
public MapleMapItem(Item item, Point position, MapleMapObject dropper, MapleCharacter owner, byte type, boolean playerDrop) {
|
||||
public MapleMapItem(Item item, Point position, MapleMapObject dropper, MapleCharacter owner, MapleClient ownerClient, byte type, boolean playerDrop) {
|
||||
setPosition(position);
|
||||
this.item = item;
|
||||
this.dropper = dropper;
|
||||
this.character_ownerid = owner.getId();
|
||||
this.ownerClient = owner.getClient();
|
||||
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) {
|
||||
public MapleMapItem(Item item, Point position, MapleMapObject dropper, MapleCharacter owner, MapleClient ownerClient, 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.ownerClient = owner.getClient();
|
||||
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) {
|
||||
public MapleMapItem(int meso, Point position, MapleMapObject dropper, MapleCharacter owner, MapleClient ownerClient, 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.ownerClient = owner.getClient();
|
||||
this.meso = meso;
|
||||
this.type = type;
|
||||
this.playerDrop = playerDrop;
|
||||
}
|
||||
@@ -90,6 +93,10 @@ public class MapleMapItem extends AbstractMapleMapObject {
|
||||
public final int getOwner() {
|
||||
return character_ownerid;
|
||||
}
|
||||
|
||||
public final MapleClient getOwnerClient() {
|
||||
return (ownerClient.isLoggedIn() && !ownerClient.getPlayer().isAwayFromWorld()) ? ownerClient : null;
|
||||
}
|
||||
|
||||
public final int getMeso() {
|
||||
return meso;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
This file is part of the MapleSolaxiaV2 Maple Story Server
|
||||
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
|
||||
Copyleft (L) 2017 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
|
||||
@@ -19,15 +19,13 @@
|
||||
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;
|
||||
package server.maps;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -19,7 +19,7 @@
|
||||
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;
|
||||
package server.maps;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import net.SendOpcode;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -19,7 +19,7 @@
|
||||
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;
|
||||
package server.maps;
|
||||
|
||||
import client.inventory.Item;
|
||||
|
||||
@@ -162,18 +162,19 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
return MaplePacketCreator.spawnReactor(this);
|
||||
}
|
||||
|
||||
public void resetReactorActions() {
|
||||
public void resetReactorActions(int newState) {
|
||||
setState((byte) newState);
|
||||
cancelReactorTimeout();
|
||||
setShouldCollect(true);
|
||||
refreshReactorTimeout();
|
||||
|
||||
if(map != null) map.searchItemReactors(this);
|
||||
}
|
||||
|
||||
public void forceHitReactor(final byte newState) {
|
||||
this.lockReactor();
|
||||
try {
|
||||
setState((byte) newState);
|
||||
this.resetReactorActions();
|
||||
|
||||
this.resetReactorActions(newState);
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
} finally {
|
||||
this.unlockReactor();
|
||||
@@ -184,9 +185,7 @@ public class MapleReactor extends AbstractMapleMapObject {
|
||||
if(!this.reactorLock.tryLock()) return;
|
||||
|
||||
try {
|
||||
setState((byte) newState);
|
||||
this.resetReactorActions();
|
||||
|
||||
this.resetReactorActions(newState);
|
||||
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
|
||||
} finally {
|
||||
this.unlockReactor();
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
/*
|
||||
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 file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
|
||||
Copyleft (L) 2017 RonanLana
|
||||
|
||||
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 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.
|
||||
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/>.
|
||||
*/
|
||||
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.quest.requirements;
|
||||
|
||||
import provider.MapleData;
|
||||
|
||||
Reference in New Issue
Block a user