Attempt on Mystic Doors

Partially fixed Mystic Doors.
This commit is contained in:
ronancpl
2017-07-09 20:00:31 -03:00
parent b3734cbaf7
commit b7c0bb6c07
83 changed files with 443 additions and 241 deletions

View File

@@ -839,33 +839,30 @@ public class MapleStatEffect {
}
}
if (isMagicDoor() && !FieldLimit.DOOR.check(applyto.getMap().getFieldLimit())) { // Magic Door
int y = applyto.getFh();
if (y == 0) {
y = applyto.getPosition().y;
}
int y = applyto.getFh();
if (y == 0) {
y = applyto.getPosition().y;
}
Point doorPosition = new Point(applyto.getPosition().x, y);
MapleDoor door = new MapleDoor(applyto, doorPosition);
if (applyto.getParty() != null) {// out of town door
for (MaplePartyCharacter partyMembers : applyto.getParty().getMembers()) {
partyMembers.getPlayer().addDoor(door);
partyMembers.updateDoor(door);
MapleDoor door = new MapleDoor(applyto, doorPosition);
if(door.getOwnerId() != -1) {
if (applyto.getParty() != null) {
for (MaplePartyCharacter partyMember : applyto.getParty().getMembers()) {
partyMember.getPlayer().addDoor(door.getOwnerId(), door);
partyMember.addDoor(door.getOwnerId(), door);
}
applyto.silentPartyUpdate();
} else {
applyto.addDoor(door.getOwnerId(), door);
}
applyto.silentPartyUpdate();
door.getTarget().spawnDoor(door.getAreaDoor());
door.getTown().spawnDoor(door.getTownDoor());
} else {
applyto.addDoor(door);
}
applyto.getMap().spawnDoor(door);
door = new MapleDoor(door); //The town door
if (applyto.getParty() != null) {// update town doors
for (MaplePartyCharacter partyMembers : applyto.getParty().getMembers()) {
partyMembers.getPlayer().addDoor(door);
partyMembers.updateDoor(door);
}
applyto.silentPartyUpdate();
} else {
applyto.addDoor(door);
}
door.getTown().spawnDoor(door);
applyto.dropMessage(5, "There are no door portals available for the town at this moment. Try again later.");
applyto.cancelBuffStats(MapleBuffStat.SOULARROW); // cancel door buff
}
applyto.disableDoor();
} else if (isMist()) {
Rectangle bounds = calculateBoundingBox(sourceid == NightWalker.POISON_BOMB ? pos : applyfrom.getPosition(), applyfrom.isFacingLeft());
@@ -966,7 +963,7 @@ public class MapleStatEffect {
}
private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) {
if (!isMonsterRiding() && !isCouponBuff()) {
if (!isMonsterRiding() && !isCouponBuff() && !isMysticDoor()) { // last mystic door already dispelled if it has been used before.
applyto.cancelEffect(this, true, -1);
}
@@ -1295,6 +1292,10 @@ public class MapleStatEffect {
return MapleItemInformationProvider.getInstance().isRateCoupon(sourceid);
}
private boolean isMysticDoor() {
return skill && sourceid == Priest.MYSTIC_DOOR;
}
public boolean isMonsterRiding() {
return skill && (sourceid % 10000000 == 1004 || sourceid == Corsair.BATTLE_SHIP || sourceid == Beginner.SPACESHIP || sourceid == Noblesse.SPACESHIP
|| sourceid == Beginner.YETI_MOUNT1 || sourceid == Beginner.YETI_MOUNT2 || sourceid == Beginner.WITCH_BROOMSTICK || sourceid == Beginner.BALROG_MOUNT
@@ -1432,7 +1433,7 @@ public class MapleStatEffect {
public boolean hasNoIcon() {
return (sourceid == 3111002 || sourceid == 3211002 || + // puppet, puppet
sourceid == 3211005 || sourceid == 2311002 || + // golden eagle, mystic door
sourceid == 3211005 || + // golden eagle
sourceid == 2121005 || sourceid == 2221005 || + // elquines, ifrit
sourceid == 2321003 || sourceid == 3121006 || + // bahamut, phoenix
sourceid == 3221005 || sourceid == 3111005 || + // frostprey, silver hawk

View File

@@ -22,117 +22,77 @@
package server.maps;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import server.MaplePortal;
import tools.MaplePacketCreator;
import client.MapleCharacter;
import client.MapleClient;
/**
*
* @author Matze
* @author Matze, Ronan
*/
public class MapleDoor extends AbstractMapleMapObject {
private MapleCharacter owner;
public class MapleDoor {
private int ownerId;
private MapleMap town;
private MaplePortal townPortal;
private MapleMap target;
private Point targetPosition;
private MapleDoorObject townDoor;
private MapleDoorObject areaDoor;
public MapleDoor(MapleCharacter owner, Point targetPosition) {
super();
this.owner = owner;
this.ownerId = owner.getId();
this.target = owner.getMap();
this.targetPosition = targetPosition;
setPosition(this.targetPosition);
this.town = this.target.getReturnMap();
this.townPortal = getFreePortal();
}
public MapleDoor(MapleDoor origDoor) {
super();
this.owner = origDoor.owner;
this.town = origDoor.town;
this.townPortal = origDoor.townPortal;
this.target = origDoor.target;
this.targetPosition = origDoor.targetPosition;
this.townPortal = origDoor.townPortal;
setPosition(this.townPortal.getPosition());
}
private MaplePortal getFreePortal() {
List<MaplePortal> freePortals = new ArrayList<MaplePortal>();
for (MaplePortal port : town.getPortals()) {
if (port.getType() == 6) {
freePortals.add(port);
}
}
Collections.sort(freePortals, new Comparator<MaplePortal>() {
public int compare(MaplePortal o1, MaplePortal o2) {
if (o1.getId() < o2.getId()) {
return -1;
} else if (o1.getId() == o2.getId()) {
return 0;
} else {
return 1;
}
}
});
for (MapleMapObject obj : town.getMapObjects()) {
if (obj instanceof MapleDoor) {
MapleDoor door = (MapleDoor) obj;
if (door.getOwner().getParty() != null && door.getOwner().getParty().containsMembers(door.getOwner().getMPC())) {
freePortals.remove(door.getTownPortal());
}
}
}
return freePortals.iterator().next();
}
@Override
public void sendSpawnData(MapleClient client) {
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() && owner.getParty() == null) {
client.announce(MaplePacketCreator.spawnDoor(owner.getId(), town.getId() == client.getPlayer().getMapId() ? townPortal.getPosition() : targetPosition, true));
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
client.announce(MaplePacketCreator.partyPortal(town.getId(), target.getId(), targetPosition));
}
}
if (owner.getId() != client.getPlayer().getId()) {
client.announce(MaplePacketCreator.spawnPortal(town.getId(), target.getId(), targetPosition));
}
}
@Override
public void sendDestroyData(MapleClient client) {
if (target.getId() == client.getPlayer().getMapId() || owner == client.getPlayer() || owner.getParty() != null && owner.getParty().containsMembers(client.getPlayer().getMPC())) {
if (owner.getParty() != null && (owner == client.getPlayer() || owner.getParty().containsMembers(client.getPlayer().getMPC()))) {
client.announce(MaplePacketCreator.partyPortal(999999999, 999999999, new Point(-1, -1)));
}
client.announce(MaplePacketCreator.removeDoor(owner.getId(), false));
client.announce(MaplePacketCreator.removeDoor(owner.getId(), true));
}
}
public void warp(MapleCharacter chr, boolean toTown) {
if (chr == owner || owner.getParty() != null && owner.getParty().containsMembers(chr.getMPC())) {
if (!toTown) {
chr.changeMap(target, targetPosition);
} else {
chr.changeMap(town, townPortal);
}
this.townPortal = allocateFreePortal();
if(townPortal != null) {
this.areaDoor = new MapleDoorObject(ownerId, town, target, false, targetPosition, townPortal.getPosition());
this.townDoor = new MapleDoorObject(ownerId, target, town, true, townPortal.getPosition(), targetPosition);
this.areaDoor.setPairOid(this.townDoor.getObjectId());
this.townDoor.setPairOid(this.areaDoor.getObjectId());
} else {
chr.getClient().announce(MaplePacketCreator.enableActions());
this.ownerId = -1;
}
}
public MapleCharacter getOwner() {
return owner;
public void freeAllocatedPortal() {
if(townPortal != null) {
town.setDisposeDoorPortal(townPortal);
}
}
private MaplePortal allocateFreePortal() {
List<MaplePortal> availablePortals = town.getAvailableDoorPortals();
if(availablePortals.isEmpty() || !town.getNotUsingDoorPortal()) return null;
Collections.shuffle(availablePortals);
while(!availablePortals.isEmpty()) {
MaplePortal port = availablePortals.remove(0);
if(town.setUsingDoorPortal(port)) {
return port;
}
}
return null;
}
public int getOwnerId() {
return ownerId;
}
public MapleDoorObject getTownDoor() {
return townDoor;
}
public MapleDoorObject getAreaDoor() {
return areaDoor;
}
public MapleMap getTown() {
return town;
}
@@ -145,13 +105,4 @@ public class MapleDoor extends AbstractMapleMapObject {
return target;
}
public Point getTargetPosition() {
return targetPosition;
}
@Override
public MapleMapObjectType getType() {
return MapleMapObjectType.DOOR;
}
}

View File

@@ -0,0 +1,130 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This 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 client.MapleCharacter;
import java.awt.Point;
import tools.MaplePacketCreator;
import client.MapleClient;
/**
*
* @author Ronan
*/
public class MapleDoorObject extends AbstractMapleMapObject {
private int ownerId;
private int pairOid;
private boolean isTown;
private MapleMap from;
private MapleMap to;
private Point toPos;
public MapleDoorObject(int owner, MapleMap destination, MapleMap origin, boolean town, Point targetPosition, Point toPosition) {
super();
setPosition(targetPosition);
ownerId = owner;
isTown = town;
from = origin;
to = destination;
toPos = toPosition;
}
public void warp(MapleCharacter chr, boolean toTown) {
if (chr.getId() == ownerId || (chr.getParty() != null && chr.getParty().getMemberById(ownerId) != null)) {
chr.changeMap(to, toPos);
} else {
chr.getClient().announce(MaplePacketCreator.blockedMessage(6));
chr.getClient().announce(MaplePacketCreator.enableActions());
}
}
@Override
public void sendSpawnData(MapleClient client) {
if (from.getId() == client.getPlayer().getMapId()) {
client.announce(MaplePacketCreator.spawnPortal(this.getFrom().getId(), this.getTo().getId(), this.toPosition()));
if(!this.inTown()) client.announce(MaplePacketCreator.spawnDoor(this.getOwnerId(), this.getPosition(), true));
if (client.getPlayer().getParty() != null && (ownerId == client.getPlayer().getId() || client.getPlayer().getParty().getMemberById(ownerId) != null)) {
client.announce(MaplePacketCreator.partyPortal(this.getTown().getId(), this.getArea().getId(), this.getAreaPosition()));
}
}
}
@Override
public void sendDestroyData(MapleClient client) {
if (from.getId() == client.getPlayer().getMapId()) {
if (client.getPlayer().getParty() != null && (ownerId == client.getPlayer().getId() || client.getPlayer().getParty().getMemberById(ownerId) != null)) {
client.announce(MaplePacketCreator.partyPortal(999999999, 999999999, new Point(-1, -1)));
}
client.announce(MaplePacketCreator.removeDoor(ownerId, isTown));
}
}
public int getOwnerId() {
return ownerId;
}
public void setPairOid(int oid) {
this.pairOid = oid;
}
public int getPairOid() {
return pairOid;
}
public boolean inTown() {
return isTown;
}
public MapleMap getFrom() {
return from;
}
public MapleMap getTo() {
return to;
}
public MapleMap getTown() {
return isTown ? from : to;
}
public MapleMap getArea() {
return !isTown ? from : to;
}
public Point getAreaPosition() {
return !isTown ? getPosition() : toPos;
}
public Point toPosition() {
return toPos;
}
@Override
public MapleMapObjectType getType() {
return MapleMapObjectType.DOOR;
}
}

View File

@@ -45,6 +45,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -94,6 +96,7 @@ public class MapleMap {
private Map<Integer, MaplePortal> portals = new HashMap<>();
private Map<Integer, Integer> backgroundTypes = new HashMap<>();
private Map<String, Integer> environment = new LinkedHashMap<String, Integer>();
private Set<Integer> usedDoors = new HashSet<>();
private List<Rectangle> areas = new ArrayList<>();
private MapleFootholdTree footholds = null;
private int mapid;
@@ -1360,24 +1363,74 @@ public class MapleMap {
spawnReactor(reactor);
}
public void spawnDoor(final MapleDoor door) {
public void spawnDoor(final MapleDoorObject door) {
spawnAndAddRangedMapObject(door, new DelayedPacketCreation() {
@Override
public void sendPackets(MapleClient c) {
c.announce(MaplePacketCreator.spawnDoor(door.getOwner().getId(), door.getTargetPosition(), false));
if (door.getOwner().getParty() != null && (door.getOwner() == c.getPlayer() || door.getOwner().getParty().containsMembers(c.getPlayer().getMPC()))) {
c.announce(MaplePacketCreator.partyPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition()));
if (door.getFrom().getId() == c.getPlayer().getMapId()) {
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 (c.getPlayer().getParty() != null && (door.getOwnerId() == c.getPlayer().getId() || c.getPlayer().getParty().getMemberById(door.getOwnerId()) != null)) {
c.announce(MaplePacketCreator.partyPortal(door.getTown().getId(), door.getArea().getId(), door.getAreaPosition()));
}
}
c.announce(MaplePacketCreator.spawnPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition()));
c.announce(MaplePacketCreator.enableActions());
}
}, new SpawnCondition() {
@Override
public boolean canSpawn(MapleCharacter chr) {
return chr.getMapId() == door.getTarget().getId() || chr == door.getOwner() && chr.getParty() == null;
return chr.getMapId() == door.getFrom().getId();
}
});
}
public boolean setUsingDoorPortal(MaplePortal port) {
objectWLock.lock();
try {
if(usedDoors.contains(port.getId())) return false;
usedDoors.add(port.getId());
return true;
} finally {
objectWLock.unlock();
}
}
public void setDisposeDoorPortal(MaplePortal port) {
objectWLock.lock();
try {
usedDoors.remove(port.getId());
} finally {
objectWLock.unlock();
}
}
public boolean getNotUsingDoorPortal() {
objectRLock.lock();
try {
return usedDoors.isEmpty();
} finally {
objectRLock.unlock();
}
}
public List<MaplePortal> getAvailableDoorPortals() {
objectRLock.lock();
try {
List<MaplePortal> availablePortals = new ArrayList<>();
for (MaplePortal port : getPortals()) {
if (port.getType() == MaplePortal.DOOR_PORTAL && !usedDoors.contains(port.getId())) {
availablePortals.add(port);
}
}
return availablePortals;
} finally {
objectRLock.unlock();
}
}
public void spawnSummon(final MapleSummon summon) {
@@ -2095,7 +2148,7 @@ public class MapleMap {
}
private void updateMapObjectVisibility(MapleCharacter chr, MapleMapObject mo) {
if (!chr.isMapObjectVisible(mo)) { // monster entered view range
if (!chr.isMapObjectVisible(mo)) { // item entered view range
if (mo.getType() == MapleMapObjectType.SUMMON || mo.getPosition().distanceSq(chr.getPosition()) <= getRangedDistance()) {
chr.addVisibleMapObject(mo);
mo.sendSpawnData(chr.getClient());