Conditional Buffs & M. Magnet & Loot Patch + Exp Split + Duey Rework

Fixed Monster Magnet skill when used on bosses disconnecting the caster.
Improved conditional buff system, no longer updating buffs that are not supposed to toggle.
Added party hunting in the conditional buffs system.
Refactored usage of DB by Duey. Registered Duey items now make use of the same table as the other inventory items.
Fixed non-encapsulated unlocking in reactor class.
Fixed stylish NPCs disconnecting players when trying to display empty styles list.
Fixed a deadlock case within recently implemented update buff effects (conditional buffs mechanic).
Fixed AOE mobskills not behaving well for fixed mobs (those shouldn't take into account attribute "facingLeft").
Fixed non-flipping mobs having attribute "facingLeft" updated according to controller position.
Revised aggro system no longer having bosses expire player chase.
Fixed chalkboard being depleted upon use.
Refactored MapleMapFactory, looking for normalization of the Factory design pattern the class was intended to make use at its conception.
Added MP replenishing system for mobs, gains based on its level.
Fixed indisponibility of one-of-a-kind loots due to the killer's team already having one sample each.
Reworked the EXP split system within the source. New behavior is expected to be GMS-like.
Adjusted interaction within the NPC Nein Spirit's Baby Dragon area. Only players who interacts with quests within can access the area now. One player at a time, with a timeout timer.
Fixed check of level requisites for expeditions.
This commit is contained in:
ronancpl
2019-06-15 15:10:56 -03:00
parent 04b11e2518
commit a39a210c1f
54 changed files with 1217 additions and 866 deletions
+162
View File
@@ -0,0 +1,162 @@
/*
This file is part of the HeavenMS MapleStory Server
Copyleft (L) 2016 - 2018 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 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 constants.ServerConstants;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
import scripting.event.EventInstanceManager;
import server.TimerManager;
public class MapleMapManager {
private int channel, world;
private EventInstanceManager event;
private Map<Integer, MapleMap> maps = new HashMap<>();
private ScheduledFuture<?> updateTask;
private ReadLock mapsRLock;
private WriteLock mapsWLock;
public MapleMapManager(EventInstanceManager eim, int world, int channel) {
this.world = world;
this.channel = channel;
this.event = eim;
ReentrantReadWriteLock rrwl = new MonitoredReentrantReadWriteLock(MonitoredLockType.MAP_MANAGER);
this.mapsRLock = rrwl.readLock();
this.mapsWLock = rrwl.writeLock();
updateTask = TimerManager.getInstance().register(new Runnable() {
@Override
public void run() {
updateMaps();
}
}, ServerConstants.RESPAWN_INTERVAL);
}
public MapleMap resetMap(int mapid) {
mapsWLock.lock();
try {
maps.remove(mapid);
} finally {
mapsWLock.unlock();
}
return getMap(mapid);
}
private synchronized MapleMap loadMapFromWz(int mapid, boolean cache) {
MapleMap map;
if (cache) {
mapsRLock.lock();
try {
map = maps.get(mapid);
} finally {
mapsRLock.unlock();
}
if (map != null) {
return map;
}
}
map = MapleMapFactory.loadMapFromWz(mapid, world, channel, event);
if (cache) {
mapsWLock.lock();
try {
maps.put(mapid, map);
} finally {
mapsWLock.unlock();
}
}
return map;
}
public MapleMap getMap(int mapid) {
MapleMap map;
mapsRLock.lock();
try {
map = maps.get(mapid);
} finally {
mapsRLock.unlock();
}
return (map != null) ? map : loadMapFromWz(mapid, true);
}
public MapleMap getDisposableMap(int mapid) {
return loadMapFromWz(mapid, false);
}
public boolean isMapLoaded(int mapId) {
mapsRLock.lock();
try {
return maps.containsKey(mapId);
} finally {
mapsRLock.unlock();
}
}
public Map<Integer, MapleMap> getMaps() {
mapsRLock.lock();
try {
return new HashMap<>(maps);
} finally {
mapsRLock.unlock();
}
}
private void updateMaps() {
for (MapleMap map : getMaps().values()) {
map.respawn();
map.mobMpRecovery();
}
}
public void dispose() {
if (updateTask != null) {
updateTask.cancel(false);
updateTask = null;
}
for (MapleMap map : getMaps().values()) {
map.dispose();
}
this.event = null;
}
public static float getMapRecoveryRate(int mapid) {
return MapleMapFactory.getMapRecoveryRate(mapid);
}
}