/*
* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010
* 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 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 javastory.channel.maps;
import java.awt.Point;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.google.common.collect.Lists;
import javastory.channel.ChannelCharacter;
import javastory.channel.ChannelClient;
import javastory.channel.PartyMember;
import javastory.channel.server.Portal;
import javastory.tools.packets.ChannelPackets;
public class Door extends AbstractGameMapObject {
private final ChannelCharacter owner;
private final GameMap town;
private Portal townPortal;
private final GameMap target;
private final Point targetPosition;
public Door(final ChannelCharacter owner, final Point targetPosition) {
super();
this.owner = owner;
this.target = owner.getMap();
this.targetPosition = targetPosition;
this.setPosition(this.targetPosition);
this.town = this.target.getReturnMap();
this.townPortal = this.getFreePortal();
}
public Door(final Door 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;
this.setPosition(this.townPortal.getPosition());
}
private Portal getFreePortal() {
final List<Portal> freePortals = Lists.newArrayList();
for (final Portal port : this.town.getPortals()) {
if (port.getType() == 6) {
freePortals.add(port);
}
}
Collections.sort(freePortals, new Comparator<Portal>() {
@Override
public final int compare(final Portal o1, final Portal o2) {
if (o1.getId() < o2.getId()) {
return -1;
} else if (o1.getId() == o2.getId()) {
return 0;
} else {
return 1;
}
}
});
for (final GameMapObject obj : this.town.getAllDoor()) {
final Door door = (Door) obj;
final ChannelCharacter doorOwner = door.getOwner();
final PartyMember doorOwnerMember = doorOwner.getPartyMembership();
if (doorOwnerMember != null) {
freePortals.remove(door.getTownPortal());
}
}
return freePortals.iterator().next();
}
@Override
public final void sendSpawnData(final ChannelClient client) {
final ChannelCharacter clientPlayer = client.getPlayer();
final boolean isInDoorMap = this.target.getId() == clientPlayer.getMapId();
final boolean isOwner = this.owner == clientPlayer;
final PartyMember ownerMember = this.owner.getPartyMembership();
final PartyMember clientMember = clientPlayer.getPartyMembership();
final Point doorPosition = this.town.getId() == clientPlayer.getMapId() ? this.townPortal.getPosition() : this.targetPosition;
if (isInDoorMap) {
client.write(ChannelPackets.spawnDoor(this.owner.getId(), doorPosition, true));
if (isOwner && ownerMember == null) {
client.write(ChannelPackets.spawnPortal(this.town.getId(), this.target.getId(), this.targetPosition));
} else if (ownerMember != null && clientMember.getPartyId() == ownerMember.getPartyId()) {
client.write(ChannelPackets.partyPortal(this.town.getId(), this.target.getId(), this.targetPosition));
}
}
}
@Override
public final void sendDestroyData(final ChannelClient client) {
final ChannelCharacter clientPlayer = client.getPlayer();
final boolean isInDoorMap = this.target.getId() == clientPlayer.getMapId();
final PartyMember ownerMember = this.owner.getPartyMembership();
final PartyMember clientMember = clientPlayer.getPartyMembership();
if (isInDoorMap) {
if (ownerMember == null || ownerMember.getPartyId() == clientMember.getPartyId()) {
client.write(ChannelPackets.partyPortal(999999999, 999999999, new Point(-1, -1)));
}
client.write(ChannelPackets.removeDoor(this.owner.getId(), false));
client.write(ChannelPackets.removeDoor(this.owner.getId(), true));
}
}
public final void warp(final ChannelCharacter chr, final boolean toTown) {
final PartyMember ownerMember = this.owner.getPartyMembership();
final PartyMember clientMember = chr.getPartyMembership();
final boolean isSameParty = ownerMember != null && clientMember != null && ownerMember.getPartyId() == clientMember.getPartyId();
final boolean isOwner = this.owner == chr;
if (isOwner || isSameParty) {
if (!toTown) {
chr.changeMap(this.target, this.targetPosition);
} else {
chr.changeMap(this.town, this.townPortal);
}
} else {
chr.getClient().write(ChannelPackets.enableActions());
}
}
public final ChannelCharacter getOwner() {
return this.owner;
}
public final GameMap getTown() {
return this.town;
}
public final Portal getTownPortal() {
return this.townPortal;
}
public final GameMap getTarget() {
return this.target;
}
public final Point getTargetPosition() {
return this.targetPosition;
}
@Override
public final GameMapObjectType getType() {
return GameMapObjectType.DOOR;
}
}