Merge branch 'pr/427'
This commit is contained in:
+380
-53
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -31,6 +31,7 @@ public enum SavedLocationType {
|
||||
EVENT,
|
||||
BOSSPQ,
|
||||
HAPPYVILLE,
|
||||
MONSTER_CARNIVAL,
|
||||
DEVELOPER;
|
||||
|
||||
public static SavedLocationType fromString(String Str) {
|
||||
|
||||
Reference in New Issue
Block a user