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:
ronancpl
2017-11-29 00:57:50 -02:00
parent 46924812b0
commit 85a81b9bf9
163 changed files with 17125 additions and 14961 deletions
+2 -2
View File
@@ -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;
+18 -10
View File
@@ -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);
}
}
+2 -4
View File
@@ -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
-1
View File
@@ -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;
+56 -24
View File
@@ -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();
+1 -2
View File
@@ -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;
}
+13 -6
View File
@@ -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;
+2 -1
View File
@@ -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;
+6 -7
View File
@@ -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;