Merge branch 'pr/427'

This commit is contained in:
ronancpl
2019-03-12 21:20:40 -03:00
63 changed files with 4824 additions and 2482 deletions
+380 -53
View File
@@ -84,18 +84,21 @@ import server.life.MapleNPC;
import server.life.MonsterDropEntry;
import server.life.MonsterGlobalDropEntry;
import server.life.SpawnPoint;
import server.partyquest.MonsterCarnival;
import server.partyquest.MonsterCarnivalParty;
//import server.partyquest.Pyramid;
import scripting.event.EventInstanceManager;
import server.life.MaplePlayerNPC;
import server.life.MobSkill;
import server.life.MobSkillFactory;
import server.life.MonsterListener;
import server.partyquest.GuardianSpawnPoint;
import server.partyquest.MapleCarnivalFactory;
import server.partyquest.MapleCarnivalFactory.MCSkill;
import tools.FilePrinter;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.Randomizer;
public class MapleMap {
private static final List<MapleMapObjectType> rangedMapobjectTypes = Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.ITEM, MapleMapObjectType.NPC, MapleMapObjectType.MONSTER, MapleMapObjectType.DOOR, MapleMapObjectType.SUMMON, MapleMapObjectType.REACTOR);
private static final Map<Integer, Pair<Integer, Integer>> dropBoundsCache = new HashMap<>(100);
@@ -275,7 +278,9 @@ public class MapleMap {
}
public MapleMap getReturnMap() {
if(returnMapId == 999999999) return this;
if (returnMapId == 999999999) {
return this;
}
return getChannelServer().getMapFactory().getMap(returnMapId);
}
@@ -538,8 +543,11 @@ public class MapleMap {
}
public Point calcDropPos(Point initial, Point fallback) {
if(initial.x < xLimits.left) initial.x = xLimits.left;
else if(initial.x > xLimits.right) initial.x = xLimits.right;
if (initial.x < xLimits.left) {
initial.x = xLimits.left;
} else if(initial.x > xLimits.right) {
initial.x = xLimits.right;
}
Point ret = calcPointBelow(new Point(initial.x, initial.y - 85));
if (ret == null) {
@@ -559,8 +567,8 @@ public class MapleMap {
}
/**
* Fetches angle relative between spawn and door points
* where 3 O'Clock is 0 and 12 O'Clock is 270 degrees
* Fetches angle relative between spawn and door points where 3 O'Clock is 0
* and 12 O'Clock is 270 degrees
*
* @param spawnPoint
* @param doorPoint
@@ -574,10 +582,11 @@ public class MapleMap {
double inRads = Math.atan2(dy, dx);
// We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 O'clock
if (inRads < 0)
if (inRads < 0) {
inRads = Math.abs(inRads);
else
} else {
inRads = 2 * Math.PI - inRads;
}
return Math.toDegrees(inRads);
}
@@ -650,7 +659,9 @@ public class MapleMap {
mesos = (int) (mesos * chr.getBuffedValue(MapleBuffStat.MESOUP).doubleValue() / 100.0);
}
mesos = mesos * chr.getMesoRate();
if(mesos <= 0) mesos = Integer.MAX_VALUE;
if (mesos <= 0) {
mesos = Integer.MAX_VALUE;
}
spawnMesoDrop(mesos, calcDropPos(pos, mob.getPosition()), mob, chr, false, droptype);
}
@@ -713,7 +724,9 @@ public class MapleMap {
chRate *= (stati.getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0);
}
if(useBaseRate) chRate = 1;
if (useBaseRate) {
chRate = 1;
}
final MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance();
final List<MonsterGlobalDropEntry> globalEntry = mi.getRelevantGlobalDrops(this.getId());
@@ -773,7 +786,9 @@ public class MapleMap {
private void startItemMonitor() {
chrWLock.lock();
try {
if(itemMonitor != null) return;
if (itemMonitor != null) {
return;
}
itemMonitor = TimerManager.getInstance().register(new Runnable() {
@Override
@@ -806,7 +821,9 @@ public class MapleMap {
objectRLock.unlock();
}
if(tryClean) cleanItemMonitor();
if (tryClean) {
cleanItemMonitor();
}
}
}, ServerConstants.ITEM_MONITOR_TIME, ServerConstants.ITEM_MONITOR_TIME);
@@ -861,7 +878,9 @@ public class MapleMap {
try {
mapobj = registeredDrops.remove(0).get();
while(mapobj == null) {
if(registeredDrops.isEmpty()) break;
if (registeredDrops.isEmpty()) {
break;
}
mapobj = registeredDrops.remove(0).get();
}
} finally {
@@ -1004,7 +1023,9 @@ public class MapleMap {
if(mdrop.getOwnerId() == charid) {
mdrop.lockItem();
try {
if(mdrop.isPickedUp()) return;
if (mdrop.isPickedUp()) {
return;
}
mdrop.setPartyOwnerId(partyid);
@@ -1197,7 +1218,9 @@ public class MapleMap {
int count = 0;
for(MapleCharacter mc: getAllPlayers()) {
if(mc.isAlive()) count++;
if (mc.isAlive()) {
count++;
}
}
return count;
@@ -1233,7 +1256,9 @@ public class MapleMap {
public List<MapleMonster> getMonsters() {
List<MapleMonster> mobs = new ArrayList<>();
for (MapleMapObject object : this.getMapObjects()) {
if(object instanceof MapleMonster) mobs.add((MapleMonster)object);
if (object instanceof MapleMonster) {
mobs.add((MapleMonster)object);
}
}
return mobs;
}
@@ -1276,7 +1301,9 @@ public class MapleMap {
}
public void killMonster(final MapleMonster monster, final MapleCharacter chr, final boolean withDrops, int animation) {
if(monster == null) return;
if (monster == null) {
return;
}
if (chr == null) {
if(removeKilledMonsterObject(monster)) {
@@ -1288,12 +1315,18 @@ public class MapleMap {
if (monster.getStats().getLevel() >= chr.getLevel() + 30 && !chr.isGM()) {
AutobanFactory.GENERAL.alert(chr, " for killing a " + monster.getName() + " which is over 30 levels higher.");
}
/*if (chr.getQuest(MapleQuest.getInstance(29400)).getStatus().equals(MapleQuestStatus.Status.STARTED)) {
if (chr.getLevel() >= 120 && monster.getStats().getLevel() >= 120) {
//FIX MEDAL SHET
} else if (monster.getStats().getLevel() >= chr.getLevel()) {
}
}*/
if (monster.getCP() > 0 && chr.getMap().isCPQMap()) {
chr.gainCP(monster.getCP());
}
int buff = monster.getBuffToGive();
if (buff > -1) {
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
@@ -1307,13 +1340,7 @@ public class MapleMap {
}
}
}
if (monster.getCP() > 0 && chr.getCarnival() != null) {
chr.getCarnivalParty().addCP(chr, monster.getCP());
chr.announce(MaplePacketCreator.updateCP(chr.getCP(), chr.getObtainedCP()));
broadcastMessage(MaplePacketCreator.updatePartyCP(chr.getCarnivalParty()));
//they drop items too ):
}
if (monster.getId() >= 8800003 && monster.getId() <= 8800010) {
boolean makeZakReal = true;
Collection<MapleMapObject> objects = getMapObjects();
@@ -1389,7 +1416,9 @@ public class MapleMap {
for (MapleMonster mob : mobList) {
if (mob.getId() == mobId) {
MapleCharacter chr = mapChars.get(mob.getHighestDamagerId());
if(chr == null) chr = defaultChr;
if (chr == null) {
chr = defaultChr;
}
this.killMonster(mob, chr, true);
}
@@ -1788,7 +1817,9 @@ public class MapleMap {
public void spawnRevives(final MapleMonster monster) {
monster.setMap(this);
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
if (getEventInstance() != null) {
getEventInstance().registerMonster(monster);
}
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
@Override
@@ -1890,7 +1921,9 @@ public class MapleMap {
monster.changeDifficulty(difficulty, isPq);
monster.setMap(this);
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
if (getEventInstance() != null) {
getEventInstance().registerMonster(monster);
}
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
@Override
@@ -1901,6 +1934,22 @@ public class MapleMap {
monster.aggroUpdateController();
if ((monster.getTeam() == 1 || monster.getTeam() == 0) && (isCPQMap() || isCPQMap2())) {
List<MCSkill> teamS = null;
if (monster.getTeam() == 0) {
teamS = redTeamBuffs;
} else if (monster.getTeam() == 1) {
teamS = blueTeamBuffs;
}
if (teamS != null) {
for (MCSkill skil : teamS) {
if (skil != null) {
skil.getSkill().applyEffect(null, monster, false, null);
}
}
}
}
if (monster.hasBossHPBar()) {
broadcastBossHpMessage(monster, monster.hashCode(), monster.makeBossHPBarPacket(), monster.getPosition());
}
@@ -1932,9 +1981,13 @@ public class MapleMap {
monster.setMap(this);
Point spos = new Point(pos.x, pos.y - 1);
spos = calcPointBelow(spos);
if(spos == null) return;
if (spos == null) {
return;
}
if(getEventInstance() != null) getEventInstance().registerMonster(monster);
if (getEventInstance() != null) {
getEventInstance().registerMonster(monster);
}
spos.y--;
monster.setPosition(spos);
@@ -2008,7 +2061,9 @@ public class MapleMap {
}
c.announce(MaplePacketCreator.spawnPortal(door.getFrom().getId(), door.getTo().getId(), door.toPosition()));
if(!door.inTown()) c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false));
if (!door.inTown()) {
c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false));
}
}
c.announce(MaplePacketCreator.enableActions());
@@ -2153,7 +2208,9 @@ public class MapleMap {
// spawns item instances of all defined item ids on a list
public final void spawnItemDropList(List<Integer> list, int minCopies, int maxCopies, final MapleMapObject dropper, final MapleCharacter owner, Point pos, final boolean ffaDrop, final boolean playerDrop) {
int copies = (maxCopies - minCopies) + 1;
if(copies < 1) return;
if(copies < 1) {
return;
}
Collections.shuffle(list);
@@ -2166,8 +2223,7 @@ public class MapleMap {
for(int i = 0; i < list.size(); i++) {
if(list.get(i) == 0) {
spawnMesoDrop(owner != null ? 10 * owner.getMesoRate() : 10, calcDropPos(dropPos, pos), dropper, owner, playerDrop, (byte) (ffaDrop ? 2 : 0));
}
else {
} else {
final Item drop;
int randomedId = list.get(i);
@@ -2280,7 +2336,9 @@ public class MapleMap {
private void addPartyMemberInternal(MapleCharacter chr) {
int partyid = chr.getPartyId();
if(partyid == -1) return;
if (partyid == -1) {
return;
}
Set<Integer> partyEntry = mapParty.get(partyid);
if(partyEntry == null) {
@@ -2295,12 +2353,17 @@ public class MapleMap {
private void removePartyMemberInternal(MapleCharacter chr) {
int partyid = chr.getPartyId();
if(partyid == -1) return;
if (partyid == -1) {
return;
}
Set<Integer> partyEntry = mapParty.get(partyid);
if(partyEntry != null) {
if(partyEntry.size() > 1) partyEntry.remove(chr.getId());
else mapParty.remove(partyid);
if (partyEntry.size() > 1) {
partyEntry.remove(chr.getId());
} else {
mapParty.remove(partyid);
}
}
}
@@ -2441,7 +2504,9 @@ public class MapleMap {
}, travelTime);
} else if (MapleMiniDungeonInfo.isDungeonMap(mapid)) {
MapleMiniDungeon mmd = chr.getClient().getChannelServer().getMiniDungeon(mapid);
if(mmd != null) mmd.registerPlayer(chr);
if (mmd != null) {
mmd.registerPlayer(chr);
}
}
MaplePet[] pets = chr.getPets();
@@ -2454,6 +2519,23 @@ public class MapleMap {
}
}
if (chr.getMonsterCarnival() != null) {
chr.getClient().announce(MaplePacketCreator.getClock(chr.getMonsterCarnival().getTimeLeftSeconds()));
if (isCPQMap()) {
int team = -1;
int oposition = -1;
if (chr.getTeam() == 0) {
team = 0;
oposition = 1;
}
if (chr.getTeam() == 1) {
team = 1;
oposition = 0;
}
chr.getClient().announce(MaplePacketCreator.startMonsterCarnival(chr, team, oposition));
}
}
chr.removeSandboxItems();
if (chr.getChalkboard() != null) {
@@ -2537,19 +2619,16 @@ public class MapleMap {
chr.announce(MaplePacketCreator.rollSnowBall(true, 0, null, null));
}
MonsterCarnival carnival = chr.getCarnival();
MonsterCarnivalParty cparty = chr.getCarnivalParty();
if (carnival != null && cparty != null && (mapid == 980000101 || mapid == 980000201 || mapid == 980000301 || mapid == 980000401 || mapid == 980000501 || mapid == 980000601)) {
chr.getClient().announce(MaplePacketCreator.getClock((int) (carnival.getTimeLeft() / 1000)));
chr.getClient().announce(MaplePacketCreator.startCPQ(chr, carnival.oppositeTeam(cparty)));
}
if (hasClock()) {
Calendar cal = Calendar.getInstance();
chr.getClient().announce((MaplePacketCreator.getClockTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND))));
}
if (hasBoat() > 0) {
if(hasBoat() == 1) chr.getClient().announce((MaplePacketCreator.boatPacket(true)));
else chr.getClient().announce(MaplePacketCreator.boatPacket(false));
if (hasBoat() == 1) {
chr.getClient().announce((MaplePacketCreator.boatPacket(true)));
} else {
chr.getClient().announce(MaplePacketCreator.boatPacket(false));
}
}
chr.receivePartyMemberHP();
@@ -3222,6 +3301,10 @@ public class MapleMap {
public boolean hasClock() {
return clock;
}
public void addClock(int seconds) {
broadcastMessage(MaplePacketCreator.getClock(seconds));
}
public void setTown(boolean isTown) {
this.town = isTown;
@@ -3324,6 +3407,7 @@ public class MapleMap {
}
private class MobLootEntry implements Runnable {
private byte droptype;
private int mobpos;
private int chRate;
@@ -3434,7 +3518,9 @@ public class MapleMap {
}
public void instanceMapRespawn() {
if(!allowSummons) return;
if (!allowSummons) {
return;
}
final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd
if (numShouldSpawn > 0) {
@@ -3454,7 +3540,9 @@ public class MapleMap {
}
public void instanceMapForceRespawn() {
if(!allowSummons) return;
if (!allowSummons) {
return;
}
final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd
if (numShouldSpawn > 0) {
@@ -3537,7 +3625,9 @@ public class MapleMap {
}
public void respawn() {
if(!allowSummons) return;
if (!allowSummons) {
return;
}
int numPlayers;
chrRLock.lock();
@@ -3996,7 +4086,9 @@ public class MapleMap {
public boolean isHorntailDefeated() { // all parts of dead horntail can be found here?
for(int i = 8810010; i <= 8810017; i++) {
if(getMonsterById(i) == null) return false;
if (getMonsterById(i) == null) {
return false;
}
}
return true;
@@ -4100,6 +4192,241 @@ public class MapleMap {
}
}
private final List<Point> takenSpawns = new LinkedList<>();
private final List<GuardianSpawnPoint> guardianSpawns = new LinkedList<>();
private final List<MCSkill> blueTeamBuffs = new ArrayList();
private final List<MCSkill> redTeamBuffs = new ArrayList();
private List<Integer> skillIds = new ArrayList();
private List<Pair<Integer, Integer>> mobsToSpawn = new ArrayList();
public List<MCSkill> getBlueTeamBuffs() {
return blueTeamBuffs;
}
public List<MCSkill> getRedTeamBuffs() {
return redTeamBuffs;
}
public void clearBuffList() {
redTeamBuffs.clear();
blueTeamBuffs.clear();
}
public List<MapleMapObject> getAllPlayer() {
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
}
public boolean isCPQMap() {
switch (this.getId()) {
case 980000101:
case 980000201:
case 980000301:
case 980000401:
case 980000501:
case 980000601:
case 980031100:
case 980032100:
case 980033100:
return true;
}
return false;
}
public boolean isCPQMap2() {
switch (this.getId()) {
case 980031100:
case 980032100:
case 980033100:
return true;
}
return false;
}
public boolean isCPQLobby() {
switch (this.getId()) {
case 980000100:
case 980000200:
case 980000300:
case 980000400:
case 980000500:
case 980000600:
return true;
}
return false;
}
public boolean isBlueCPQMap() {
switch (this.getId()) {
case 980000501:
case 980000601:
case 980031200:
case 980032200:
case 980033200:
return true;
}
return false;
}
public boolean isPurpleCPQMap() {
switch (this.getId()) {
case 980000301:
case 980000401:
case 980031200:
case 980032200:
case 980033200:
return true;
}
return false;
}
public Point getRandomSP(int team) {
if (takenSpawns.size() > 0) {
for (SpawnPoint sp : monsterSpawn) {
for (Point pt : takenSpawns) {
if ((sp.getPosition().x == pt.x && sp.getPosition().y == pt.y) || (sp.getTeam() != team && !this.isBlueCPQMap())) {
continue;
} else {
takenSpawns.add(pt);
return sp.getPosition();
}
}
}
} else {
for (SpawnPoint sp : monsterSpawn) {
if (sp.getTeam() == team || this.isBlueCPQMap()) {
takenSpawns.add(sp.getPosition());
return sp.getPosition();
}
}
}
return null;
}
public GuardianSpawnPoint getRandomGuardianSpawn(int team) {
boolean alltaken = false;
for (GuardianSpawnPoint a : this.guardianSpawns) {
if (!a.isTaken()) {
alltaken = false;
break;
}
}
if (alltaken) {
return null;
}
if (this.guardianSpawns.size() > 0) {
while (true) {
for (GuardianSpawnPoint gsp : this.guardianSpawns) {
if (!gsp.isTaken() && Math.random() < 0.3 && (gsp.getTeam() == -1 || gsp.getTeam() == team)) {
return gsp;
}
}
}
}
return null;
}
public void addGuardianSpawnPoint(GuardianSpawnPoint a) {
this.guardianSpawns.add(a);
}
public int spawnGuardian(int team, int num) {
try {
if (team == 0 && redTeamBuffs.size() >= 4 || team == 1 && blueTeamBuffs.size() >= 4) {
return 2;
}
final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num);
if (team == 0 && redTeamBuffs.contains(skil)) {
return 0;
} else if (team == 1 && blueTeamBuffs.contains(skil)) {
return 0;
}
GuardianSpawnPoint pt = this.getRandomGuardianSpawn(team);
if (pt == null) {
return -1;
}
int reactorID = 9980000 + team;
MapleReactor reactor = new MapleReactor(MapleReactorFactory.getReactorS(reactorID), reactorID);
pt.setTaken(true);
reactor.setPosition(pt.getPosition());
reactor.setName(team + "" + num); //lol
reactor.resetReactorActions(0);
this.spawnReactor(reactor);
reactor.setGuardian(pt);
this.buffMonsters(team, skil);
getReactorByOid(reactor.getObjectId()).hitReactor(((MapleCharacter) this.getAllPlayer().get(0)).getClient());
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
public void buffMonsters(int team, MCSkill skil) {
if (team == 0) {
redTeamBuffs.add(skil);
} else if (team == 1) {
blueTeamBuffs.add(skil);
}
for (MapleMapObject mmo : this.mapobjects.values()) {
if (mmo.getType() == MapleMapObjectType.MONSTER) {
MapleMonster mob = (MapleMonster) mmo;
if (mob.getTeam() == team) {
if (skil != null) {
skil.getSkill().applyEffect(null, mob, false, null);
}
}
}
}
}
public final List<Integer> getSkillIds() {
return skillIds;
}
public final void addSkillId(int z) {
this.skillIds.add(z);
}
public final void addMobSpawn(int mobId, int spendCP) {
this.mobsToSpawn.add(new Pair<Integer, Integer>(mobId, spendCP));
}
public final List<Pair<Integer, Integer>> getMobsToSpawn() {
return mobsToSpawn;
}
public boolean isCPQWinnerMap() {
switch (this.getId()) {
case 980000103:
case 980000203:
case 980000303:
case 980000403:
case 980000503:
case 980000603:
case 980031300:
case 980032300:
case 980033300:
return true;
}
return false;
}
public boolean isCPQLoserMap() {
switch (this.getId()) {
case 980000104:
case 980000204:
case 980000304:
case 980000404:
case 980000504:
case 980000604:
case 980031400:
case 980032400:
case 980033400:
return true;
}
return false;
}
public void dispose() {
for(MapleMonster mm : this.getMonsters()) {
mm.dispose();
@@ -4140,4 +4467,4 @@ public class MapleMap {
chrWLock.unlock();
}
}
}
}
+75 -40
View File
@@ -48,12 +48,14 @@ import server.life.MapleMonster;
import server.life.MaplePlayerNPC;
import server.life.MaplePlayerNPCFactory;
import scripting.event.EventInstanceManager;
import server.partyquest.GuardianSpawnPoint;
import tools.DatabaseConnection;
import tools.StringUtil;
public class MapleMapFactory {
private static Map<Integer, Float> mapRecoveryRate = new HashMap<>();
private MapleDataProvider source;
private MapleData nameData;
private EventInstanceManager event;
@@ -68,12 +70,12 @@ public class MapleMapFactory {
this.world = world;
this.channel = channel;
this.event = eim;
ReentrantReadWriteLock rrwl = new MonitoredReentrantReadWriteLock(MonitoredLockType.MAP_FACTORY);
this.mapsRLock = rrwl.readLock();
this.mapsWLock = rrwl.writeLock();
}
public MapleMap resetMap(int mapid) {
mapsWLock.lock();
try {
@@ -81,14 +83,23 @@ public class MapleMapFactory {
} finally {
mapsWLock.unlock();
}
return getMap(mapid);
}
private void loadLifeFromWz(MapleMap map, MapleData mapData) {
for (MapleData life : mapData.getChildByPath("life")) {
life.getName();
String id = MapleDataTool.getString(life.getChildByPath("id"));
String type = MapleDataTool.getString(life.getChildByPath("type"));
int team = MapleDataTool.getInt("team", life, -1);
if (map.isCPQMap2() && type.equals("m")) {
if((Integer.parseInt(life.getName()) % 2) == 0) {
team = 0;
} else {
team = 1;
}
}
int cy = MapleDataTool.getInt(life.getChildByPath("cy"));
MapleData dF = life.getChildByPath("f");
int f = (dF != null) ? MapleDataTool.getInt(dF) : 0;
@@ -99,12 +110,11 @@ public class MapleMapFactory {
int y = MapleDataTool.getInt(life.getChildByPath("y"));
int hide = MapleDataTool.getInt("hide", life, 0);
int mobTime = MapleDataTool.getInt("mobTime", life, 0);
int team = MapleDataTool.getInt("team", life, -1);
loadLifeRaw(map, Integer.parseInt(id), type, cy, f, fh, rx0, rx1, x, y, hide, mobTime, team);
}
}
private void loadLifeFromDb(MapleMap map) {
try {
Connection con = DatabaseConnection.getConnection();
@@ -113,7 +123,7 @@ public class MapleMapFactory {
ps.setInt(2, map.getWorld());
ResultSet rs = ps.executeQuery();
while(rs.next()) {
while (rs.next()) {
int id = rs.getInt("life");
String type = rs.getString("type");
int cy = rs.getInt("cy");
@@ -137,12 +147,12 @@ public class MapleMapFactory {
sqle.printStackTrace();
}
}
private void loadLifeRaw(MapleMap map, int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide, int mobTime, int team) {
AbstractLoadedMapleLife myLife = loadLife(id, type, cy, f, fh, rx0, rx1, x, y, hide);
if (myLife instanceof MapleMonster) {
MapleMonster monster = (MapleMonster) myLife;
if (mobTime == -1) { //does not respawn, force spawn once
map.spawnMonster(monster);
} else {
@@ -155,10 +165,10 @@ public class MapleMapFactory {
map.addMapObject(myLife);
}
}
private synchronized MapleMap loadMapFromWz(int mapid, Integer omapid) {
MapleMap map;
mapsRLock.lock();
try {
map = maps.get(omapid);
@@ -169,7 +179,7 @@ public class MapleMapFactory {
if (map != null) {
return map;
}
String mapName = getMapName(mapid);
MapleData mapData = source.getData(mapName); // source.getData issue with giving nulls in rare ocasions found thanks to MedicOP
MapleData infoData = mapData.getChildByPath("info");
@@ -209,9 +219,9 @@ public class MapleMapFactory {
bounds[0] = MapleDataTool.getInt(infoData.getChildByPath("VRTop"));
bounds[1] = MapleDataTool.getInt(infoData.getChildByPath("VRBottom"));
if(bounds[0] == bounds[1]) { // old-style baked map
if (bounds[0] == bounds[1]) { // old-style baked map
MapleData minimapData = mapData.getChildByPath("miniMap");
if(minimapData != null) {
if (minimapData != null) {
bounds[0] = MapleDataTool.getInt(minimapData.getChildByPath("centerX")) * -1;
bounds[1] = MapleDataTool.getInt(minimapData.getChildByPath("centerY")) * -1;
bounds[2] = MapleDataTool.getInt(minimapData.getChildByPath("height"));
@@ -272,7 +282,7 @@ public class MapleMapFactory {
map.addMapleArea(new Rectangle(x1, y1, (x2 - x1), (y2 - y1)));
}
}
if(event == null) {
if (event == null) {
try {
Connection con = DatabaseConnection.getConnection();
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM playernpcs WHERE map = ? AND world = ?")) {
@@ -288,23 +298,47 @@ public class MapleMapFactory {
} catch (SQLException e) {
e.printStackTrace();
}
List<MaplePlayerNPC> dnpcs = MaplePlayerNPCFactory.getDeveloperNpcsFromMapid(mapid);
if(dnpcs != null) {
for(MaplePlayerNPC dnpc : dnpcs) {
if (dnpcs != null) {
for (MaplePlayerNPC dnpc : dnpcs) {
map.addPlayerNPCMapObject(dnpc);
}
}
}
loadLifeFromWz(map, mapData);
loadLifeFromDb(map);
if (map.isCPQMap()) {
MapleData mcData = mapData.getChildByPath("monsterCarnival");
if (mcData != null) {
MapleData guardianGenData = mcData.getChildByPath("guardianGenPos");
for (MapleData node : guardianGenData.getChildren()) {
GuardianSpawnPoint pt = new GuardianSpawnPoint(new Point(MapleDataTool.getIntConvert("x", node), MapleDataTool.getIntConvert("y", node)));
pt.setTeam(MapleDataTool.getIntConvert("team", node, -1));
pt.setTaken(false);
map.addGuardianSpawnPoint(pt);
}
}
if (mcData.getChildByPath("skill") != null) {
for (MapleData area : mcData.getChildByPath("skill")) {
map.addSkillId(MapleDataTool.getInt(area));
}
}
if (mcData.getChildByPath("mob") != null) {
for (MapleData area : mcData.getChildByPath("mob")) {
map.addMobSpawn(MapleDataTool.getInt(area.getChildByPath("id")), MapleDataTool.getInt(area.getChildByPath("spendCP")));
}
}
}
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);
MapleReactor newReactor = loadReactor(reactor, id, (byte) MapleDataTool.getInt(reactor.getChildByPath("f"), 0));
map.spawnReactor(newReactor);
}
}
@@ -313,7 +347,7 @@ public class MapleMapFactory {
map.setMapName(MapleDataTool.getString("mapName", nameData.getChildByPath(getMapStringName(omapid)), ""));
map.setStreetName(MapleDataTool.getString("streetName", nameData.getChildByPath(getMapStringName(omapid)), ""));
} catch (Exception e) {
if(omapid / 1000 != 1020) { // explorer job introducion scenes
if (omapid / 1000 != 1020) { // explorer job introducion scenes
e.printStackTrace();
System.err.println("Not found mapid " + omapid);
}
@@ -332,13 +366,13 @@ public class MapleMapFactory {
map.setTimeLimit(MapleDataTool.getIntConvert("timeLimit", infoData, -1));
map.setFieldType(MapleDataTool.getIntConvert("fieldType", infoData, 0));
map.setMobCapacity(MapleDataTool.getIntConvert("fixedMobCapacity", infoData, 500));//Is there a map that contains more than 500 mobs?
MapleData recData = infoData.getChildByPath("recovery");
if(recData != null) {
if (recData != null) {
float recoveryRate = MapleDataTool.getFloat(recData);
mapRecoveryRate.put(mapid, recoveryRate);
}
HashMap<Integer, Integer> backTypes = new HashMap<>();
try {
for (MapleData layer : mapData.getChildByPath("back")) { // yolo
@@ -351,7 +385,7 @@ public class MapleMapFactory {
e.printStackTrace();
// swallow cause I'm cool
}
map.setBackgroundTypes(backTypes);
map.generateMapDropRangeCache();
@@ -361,21 +395,21 @@ public class MapleMapFactory {
} finally {
mapsWLock.unlock();
}
return map;
}
public MapleMap getMap(int mapid) {
Integer omapid = Integer.valueOf(mapid);
MapleMap map;
mapsRLock.lock();
try {
map = maps.get(omapid);
} finally {
mapsRLock.unlock();
}
return (map != null) ? map : loadMapFromWz(mapid, omapid);
}
@@ -387,7 +421,7 @@ public class MapleMapFactory {
mapsRLock.unlock();
}
}
private AbstractLoadedMapleLife loadLife(int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide) {
AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(id, type);
myLife.setCy(cy);
@@ -402,10 +436,11 @@ public class MapleMapFactory {
return myLife;
}
private MapleReactor loadReactor(MapleData reactor, String id) {
private MapleReactor loadReactor(MapleData reactor, String id, final byte FacingDirection) {
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.setFacingDirection(FacingDirection);
myReactor.setPosition(new Point(x, y));
myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000);
myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), ""));
@@ -442,7 +477,7 @@ public class MapleMapFactory {
} else if (mapid >= 677000000 && mapid < 677100000) {
builder.append("Episode1GL");
} else if (mapid >= 670000000 && mapid < 682000000) {
if((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) {
if ((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) {
builder.append("etc");
} else {
builder.append("weddingGL");
@@ -452,7 +487,7 @@ public class MapleMapFactory {
} else if (mapid >= 683000000 && mapid < 684000000) {
builder.append("event");
} else if (mapid >= 800000000 && mapid < 900000000) {
if((mapid >= 889100000 && mapid < 889200000)) {
if ((mapid >= 889100000 && mapid < 889200000)) {
builder.append("etc");
} else {
builder.append("jp");
@@ -480,17 +515,17 @@ public class MapleMapFactory {
mapsRLock.unlock();
}
}
public void dispose() {
Collection<MapleMap> mapValues = getMaps().values();
for(MapleMap map: mapValues) {
for (MapleMap map : mapValues) {
map.dispose();
}
this.event = null;
}
public static float getMapRecoveryRate(int mapid) {
Float recRate = mapRecoveryRate.get(mapid);
return recRate != null ? recRate : 1.0f;
+81 -50
View File
@@ -1,27 +1,28 @@
/*
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 OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <[email protected]>
Matthias Butz <[email protected]>
Jan Christian Meyer <[email protected]>
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.maps;
import client.MapleClient;
import client.status.MonsterStatus;
import constants.ServerConstants;
import java.awt.Rectangle;
@@ -36,6 +37,7 @@ import server.TimerManager;
import tools.MaplePacketCreator;
import tools.Pair;
import net.server.audit.locks.MonitoredLockType;
import server.partyquest.GuardianSpawnPoint;
/**
*
@@ -43,6 +45,7 @@ import net.server.audit.locks.MonitoredLockType;
* @author Ronan
*/
public class MapleReactor extends AbstractMapleMapObject {
private int rid;
private MapleReactorStats stats;
private byte state;
@@ -54,28 +57,30 @@ public class MapleReactor extends AbstractMapleMapObject {
private boolean shouldCollect;
private boolean attackHit;
private ScheduledFuture<?> timeoutTask = null;
private GuardianSpawnPoint guardian = null;
private byte facingDirection = 0;
private Lock reactorLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR, true);
private Lock hitLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR_HIT, true);
public MapleReactor(MapleReactorStats stats, int rid) {
this.evstate = (byte)0;
this.evstate = (byte) 0;
this.stats = stats;
this.rid = rid;
this.alive = true;
}
public void setShouldCollect(boolean collect) {
this.shouldCollect = collect;
}
public boolean getShouldCollect() {
return shouldCollect;
}
public void lockReactor() {
reactorLock.lock();
}
public void unlockReactor() {
reactorLock.unlock();
}
@@ -83,19 +88,19 @@ public class MapleReactor extends AbstractMapleMapObject {
public void setState(byte state) {
this.state = state;
}
public byte getState() {
return state;
}
public void setEventState(byte substate) {
this.evstate = substate;
}
public byte getEventState() {
return evstate;
}
public MapleReactorStats getStats() {
return stats;
}
@@ -120,7 +125,7 @@ public class MapleReactor extends AbstractMapleMapObject {
public int getReactorType() {
return stats.getType(state);
}
public boolean isRecentHitFromAttack() {
return attackHit;
}
@@ -140,7 +145,7 @@ public class MapleReactor extends AbstractMapleMapObject {
public boolean isAlive() {
return alive;
}
public boolean isActive() {
return alive && stats.getType(state) != -1;
}
@@ -172,10 +177,12 @@ public class MapleReactor extends AbstractMapleMapObject {
cancelReactorTimeout();
setShouldCollect(true);
refreshReactorTimeout();
if(map != null) map.searchItemReactors(this);
if (map != null) {
map.searchItemReactors(this);
}
}
public void forceHitReactor(final byte newState) {
this.lockReactor();
try {
@@ -185,10 +192,12 @@ public class MapleReactor extends AbstractMapleMapObject {
this.unlockReactor();
}
}
private void tryForceHitReactor(final byte newState) { // weak hit state signal, if already changed reactor state before timeout then drop this
if(!this.reactorLock.tryLock()) return;
if (!this.reactorLock.tryLock()) {
return;
}
try {
this.resetReactorActions(newState);
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0));
@@ -196,19 +205,19 @@ public class MapleReactor extends AbstractMapleMapObject {
this.reactorLock.unlock();
}
}
public void cancelReactorTimeout() {
if (timeoutTask != null) {
timeoutTask.cancel(false);
timeoutTask = null;
}
}
private void refreshReactorTimeout() {
int timeOut = stats.getTimeout(state);
if(timeOut > -1) {
if (timeOut > -1) {
final byte nextState = stats.getTimeoutState(state);
timeoutTask = TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
@@ -218,7 +227,7 @@ public class MapleReactor extends AbstractMapleMapObject {
}, timeOut);
}
}
public void delayedHitReactor(final MapleClient c, long delay) {
TimerManager.getInstance().schedule(new Runnable() {
@Override
@@ -231,20 +240,22 @@ public class MapleReactor extends AbstractMapleMapObject {
public void hitReactor(MapleClient c) {
hitReactor(false, 0, (short) 0, 0, c);
}
public void hitReactor(boolean wHit, int charPos, short stance, int skillid, MapleClient c) {
try {
if(!this.isActive()) {
if (!this.isActive()) {
return;
}
if(hitLock.tryLock()) {
if (hitLock.tryLock()) {
this.lockReactor();
try {
cancelReactorTimeout();
attackHit = wHit;
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state));
if (ServerConstants.USE_DEBUG == true) {
c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state));
}
ReactorScriptManager.getInstance().onHit(c, this);
int reactorType = stats.getType(state);
@@ -253,7 +264,9 @@ public class MapleReactor extends AbstractMapleMapObject {
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;
if (!activeSkills.contains(skillid)) {
continue;
}
}
state = stats.getNextState(state, b);
if (stats.getNextState(state, b) == -1) {//end of reactor
@@ -276,7 +289,7 @@ public class MapleReactor extends AbstractMapleMapObject {
setShouldCollect(true); // refresh collectability on item drop-based reactors
refreshReactorTimeout();
if(stats.getType(state) == 100) {
if (stats.getType(state) == 100) {
map.searchItemReactors(this);
}
}
@@ -286,21 +299,23 @@ public class MapleReactor extends AbstractMapleMapObject {
} else {
state++;
map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance));
ReactorScriptManager.getInstance().act(c, this);
if (this.getId() != 9980000 && this.getId() != 9980001) {
ReactorScriptManager.getInstance().act(c, this);
}
setShouldCollect(true);
refreshReactorTimeout();
if(stats.getType(state) == 100) {
if (stats.getType(state) == 100) {
map.searchItemReactors(this);
}
}
} finally {
this.unlockReactor();
}
hitLock.unlock();
}
} catch(Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
}
@@ -316,4 +331,20 @@ public class MapleReactor extends AbstractMapleMapObject {
public void setName(String name) {
this.name = name;
}
public GuardianSpawnPoint getGuardian() {
return guardian;
}
public void setGuardian(GuardianSpawnPoint guardian) {
this.guardian = guardian;
}
public final void setFacingDirection(final byte facingDirection) {
this.facingDirection = facingDirection;
}
public final byte getFacingDirection() {
return facingDirection;
}
}
+55
View File
@@ -38,6 +38,61 @@ 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 final MapleReactorStats getReactorS(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));
}
if (stats == null) {
stats = new MapleReactorStats();
reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11));
if (reactorData == null) {
return stats;
}
boolean canTouch = MapleDataTool.getInt("info/activateByTouch", reactorData, 0) > 0;
boolean areaSet = false;
boolean foundState = false;
for (byte i = 0; true; i++) {
MapleData reactorD = reactorData.getChildByPath(String.valueOf(i));
if (reactorD == null) {
break;
}
MapleData reactorInfoData_ = reactorD.getChildByPath("event");
if (reactorInfoData_ != null && reactorInfoData_.getChildByPath("0") != null) {
MapleData reactorInfoData = reactorInfoData_.getChildByPath("0");
Pair<Integer, Integer> reactItem = null;
int type = MapleDataTool.getIntConvert("type", reactorInfoData);
if (type == 100) { //reactor waits for item
reactItem = new Pair<Integer, Integer>(MapleDataTool.getIntConvert("0", reactorInfoData), MapleDataTool.getIntConvert("1", reactorInfoData, 1));
if (!areaSet) { //only set area of effect for item-triggered reactors once
stats.setTL(MapleDataTool.getPoint("lt", reactorInfoData));
stats.setBR(MapleDataTool.getPoint("rb", reactorInfoData));
areaSet = true;
}
}
foundState = true;
stats.addState(i, type, reactItem, (byte) MapleDataTool.getIntConvert("state", reactorInfoData), MapleDataTool.getIntConvert("timeOut", reactorInfoData_, -1), (byte) (canTouch ? 2 : (MapleDataTool.getIntConvert("2", reactorInfoData, 0) > 0 || reactorInfoData.getChildByPath("clickArea") != null || type == 9 ? 1 : 0)));
} else {
stats.addState(i, 999, null, (byte) (foundState ? -1 : (i + 1)), 0, (byte) 0);
}
}
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;
}
public static MapleReactorStats getReactor(int rid) {
MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid));
if (stats == null) {
+7
View File
@@ -22,6 +22,7 @@
package server.maps;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -58,6 +59,12 @@ public class MapleReactorStats {
if(timeOut > -1) timeoutInfo.put(state, timeOut);
}
public void addState(byte state, int type, Pair<Integer, Integer> reactItem, byte nextState, int timeOut, byte canTouch) {
List<StateData> data = new ArrayList<>();
data.add(new StateData(type, reactItem, null, nextState));
stateInfo.put(state, data);
}
public int getTimeout(byte state) {
Integer i = timeoutInfo.get(state);
return (i == null) ? -1 : i;
+1
View File
@@ -31,6 +31,7 @@ public enum SavedLocationType {
EVENT,
BOSSPQ,
HAPPYVILLE,
MONSTER_CARNIVAL,
DEVELOPER;
public static SavedLocationType fromString(String Str) {