📄 maplemap.java
字号:
logMsg.append(dropPos.toString());
logMsg.append(" on map ");
logMsg.append(mapid);
idrop.log(logMsg.toString(),false);
final MapleMapItem mdrop = new MapleMapItem(idrop, dropPos, monster, dropOwner);
final MapleMapObject dropMonster = monster;
final MapleCharacter dropChar = dropOwner;
final TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
public void run() {
spawnAndAddRangedMapObject(mdrop, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
c.getSession().write(MaplePacketCreator.dropItemFromMapObject(drop, mdrop.getObjectId(), dropMonster
.getObjectId(), isBoss ? 0 : dropChar.getId(), dropMonster.getPosition(), dropPos, (byte) 1));
}
});
tMan.schedule(new ExpireMapItemJob(mdrop), 60000);
}
}, monster.getAnimationTime("die1"));
}
}
}
}
public boolean damageMonster(MapleCharacter chr, MapleMonster monster, int damage) {
// double checking to potentially avoid synchronisation overhead
if (monster.isAlive()) {
boolean killMonster = false;
synchronized (monster) {
if (!monster.isAlive())
return false;
if (damage > 0) {
monster.damage(chr, damage, true);
if (!monster.isAlive()) { // monster just died
killMonster = true;
}
}
}
// the monster is dead, as damageMonster returns immediately for dead monsters this makes
// this block implicitly synchronized for ONE monster
if (killMonster) {
killMonster (monster, chr, true);
}
return true;
}
return false;
}
public void killMonster (MapleMonster monster, MapleCharacter chr, boolean withDrops) {
spawnedMonstersOnMap.decrementAndGet();
monster.setHp(0);
broadcastMessage(MaplePacketCreator.killMonster(monster.getObjectId(), true), monster.getPosition());
removeMapObject(monster);
MapleCharacter dropOwner = monster.killBy(chr);
if (withDrops) {
if (dropOwner == null) {
dropOwner = chr;
}
dropFromMonster(dropOwner, monster);
}
}
/**
* Automagically finds a new controller for the given monster from the chars on the map...
*
* @param monster
*/
private void updateMonsterController(MapleMonster monster) {
synchronized (monster) {
if (!monster.isAlive()) {
return;
}
if (monster.getController() != null) {
// monster has a controller already, check if he's still on this map
if (monster.getController().getMap() != this) {
log.warn("Monstercontroller wasn't on same map");
monster.getController().stopControllingMonster(monster);
} else {
// controller is on the map, monster has an controller, everything is fine
return;
}
}
int mincontrolled = -1;
MapleCharacter newController = null;
synchronized (characters) {
for (MapleCharacter chr : characters) {
if (!chr.isHidden() && (chr.getControlledMonsters().size() < mincontrolled || mincontrolled == -1)) {
if (!chr.getName().equals("FaekChar")) { // TODO remove me for production release
mincontrolled = chr.getControlledMonsters().size();
newController = chr;
}
}
}
}
if (newController != null) // was a new controller found? (if not no one is on the map)
{
newController.controlMonster(monster, false);
}
}
}
public Collection<MapleMapObject> getMapObjects() {
return Collections.unmodifiableCollection(mapobjects.values());
}
public boolean containsNPC(int npcid) {
synchronized (mapobjects) {
for (MapleMapObject obj : mapobjects.values()) {
if (obj.getType() == MapleMapObjectType.NPC) {
if (((MapleNPC) obj).getId() == npcid) {
return true;
}
}
}
}
return false;
}
public MapleMapObject getMapObject(int oid) {
return mapobjects.get(oid);
}
/**
* returns a monster with the given oid, if no such monster exists returns null
*
* @param oid
* @return
*/
public MapleMonster getMonsterByOid(int oid) {
MapleMapObject mmo = getMapObject(oid);
if (mmo == null) {
return null;
}
if (mmo.getType() == MapleMapObjectType.MONSTER) {
return (MapleMonster) mmo;
}
return null;
}
public void spawnMonsterOnGroudBelow(MapleMonster mob, Point pos) {
Point spos = new Point(pos.x, pos.y - 1);
spos = calcPointBelow(spos);
spos.y -= 1;
mob.setPosition(spos);
spawnMonster(mob);
}
public void spawnMonster(final MapleMonster monster) {
monster.setMap(this);
synchronized (this.mapobjects) {
spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
c.getSession().write(MaplePacketCreator.spawnMonster(monster, true));
}
});
updateMonsterController(monster);
}
spawnedMonstersOnMap.incrementAndGet();
}
public void spawnDoor(final MapleDoor door) {
synchronized (this.mapobjects) {
spawnAndAddRangedMapObject(door, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
c.getSession().write(MaplePacketCreator.spawnDoor(door.getOwner().getId(), door.getTargetPosition(), false));
if (door.getOwner().getParty() != null && (door.getOwner() == c.getPlayer() || door.getOwner().getParty().containsMembers(new MaplePartyCharacter(c.getPlayer())))) {
c.getSession().write(MaplePacketCreator.partyPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition()));
}
c.getSession().write(MaplePacketCreator.spawnPortal(door.getTown().getId(), door.getTarget().getId(), door.getTargetPosition()));
c.getSession().write(MaplePacketCreator.enableActions());
}
}, new SpawnCondition() {
public boolean canSpawn(MapleCharacter chr) {
return chr.getMapId() == door.getTarget().getId() ||
chr == door.getOwner() && chr.getParty() == null;
}
});
}
}
public void spawnSummon(final MapleSummon summon) {
spawnAndAddRangedMapObject(summon, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
int skilLlevel = summon.getOwner().getSkillLevel(SkillFactory.getSkill(summon.getSkill()));
c.getSession().write(MaplePacketCreator.spawnSpecialMapObject(summon.getOwner(), summon.getSkill(), skilLlevel, summon.getPosition(), summon.getMovementType(), true));
}
});
}
public void spawnMist (final MapleMist mist, final int duration, boolean poison) {
addMapObject(mist);
broadcastMessage(mist.makeSpawnData());
TimerManager tMan = TimerManager.getInstance();
final ScheduledFuture<?> poisonSchedule;
if (poison) {
Runnable poisonTask = new Runnable() {
@Override
public void run() {
List<MapleMapObject> affectedMonsters = getMapObjectsInBox(mist.getBox(), Collections.singletonList(MapleMapObjectType.MONSTER));
for (MapleMapObject mo : affectedMonsters) {
if (mist.makeChanceResult()) {
MonsterStatusEffect poisonEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), mist.getSourceSkill(), false);
((MapleMonster) mo).applyStatus(mist.getOwner(), poisonEffect, true, duration);
}
}
}
};
poisonSchedule = tMan.register(poisonTask, 2000, 2500);
} else {
poisonSchedule = null;
}
tMan.schedule(new Runnable() {
@Override
public void run() {
removeMapObject(mist);
if (poisonSchedule != null) {
poisonSchedule.cancel(false);
}
broadcastMessage(mist.makeDestroyData());
}
}, duration);
}
public void spawnItemDrop(final MapleMapObject dropper, final MapleCharacter owner, final IItem item, Point pos, final boolean ffaDrop, final boolean expire) {
TimerManager tMan = TimerManager.getInstance();
final Point droppos = calcDropPos(pos, pos);
final MapleMapItem drop = new MapleMapItem(item, droppos, dropper, owner);
spawnAndAddRangedMapObject(drop, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
c.getSession().write(MaplePacketCreator.dropItemFromMapObject(item.getItemId(), drop.getObjectId(), 0, ffaDrop ? 0 : owner.getId(),
dropper.getPosition(), droppos, (byte) 1));
}
});
broadcastMessage(MaplePacketCreator.dropItemFromMapObject(item.getItemId(), drop.getObjectId(), 0, ffaDrop ? 0
: owner.getId(), dropper.getPosition(), droppos, (byte) 0), drop.getPosition());
if (expire) {
tMan.schedule(new ExpireMapItemJob(drop), 60000);
}
}
public void spawnMesoDrop(final int meso, final int displayMeso, Point position, final MapleMapObject dropper, final MapleCharacter owner, final boolean ffaLoot) {
TimerManager tMan = TimerManager.getInstance();
final Point droppos = calcDropPos(position, position);
final MapleMapItem mdrop = new MapleMapItem(meso, displayMeso, droppos, dropper, owner);
spawnAndAddRangedMapObject(mdrop, new DelayedPacketCreation() {
public void sendPackets(MapleClient c) {
c.getSession().write(MaplePacketCreator.dropMesoFromMapObject(displayMeso, mdrop.getObjectId(), dropper.getObjectId(),
ffaLoot ? 0 : owner.getId(), dropper.getPosition(), droppos, (byte) 1));
}
});
tMan.schedule(new ExpireMapItemJob(mdrop), 60000);
}
/**
* Adds a player to this map and sends nescessary data
*
* @param chr
*/
public void addPlayer(MapleCharacter chr) {
//log.warn("[dc] [level2] Player {} enters map {}", new Object[] { chr.getName(), mapid });
synchronized (characters) {
this.characters.add(chr);
}
synchronized (this.mapobjects) {
if (!chr.isHidden()) {
broadcastMessage(chr, (MaplePacketCreator.spawnPlayerMapobject(chr)), false);
}
sendObjectPlacement(chr.getClient());
// spawn self
chr.getClient().getSession().write(MaplePacketCreator.spawnPlayerMapobject(chr));
this.mapobjects.put(Integer.valueOf(chr.getObjectId()), chr);
}
if (chr.getPlayerShop() != null) {
addMapObject(chr.getPlayerShop());
}
MapleStatEffect summonStat = chr.getStatForBuff(MapleBuffStat.SUMMON);
if (summonStat != null) {
MapleSummon summon = chr.getSummons().get(summonStat.getSourceId());
summon.setPosition(chr.getPosition());
summon.sendSpawnData(chr.getClient());
chr.addVisibleMapObject(summon);
addMapObject(summon);
}
chr.receivePartyMemberHP();
}
public void removePlayer(MapleCharacter chr) {
//log.warn("[dc] [level2] Player {} leaves map {}", new Object[] { chr.getName(), mapid });
synchronized (characters) {
characters.remove(chr);
}
removeMapObject(Integer.valueOf(chr.getObjectId()));
broadcastMessage(MaplePacketCreator.removePlayerFromMap(chr.getId()));
for (MapleMonster monster : chr.getControlledMonsters()) {
monster.setController(null);
monster.setControllerHasAggro(false);
monster.setControllerKnowsAboutAggro(false);
updateMonsterController(monster);
}
for (MapleSummon summon : chr.getSummons().values()) {
if (summon.isPuppet()) {
chr.cancelBuffStats(MapleBuffStat.PUPPET);
} else {
removeMapObject(summon);
}
}
}
/**
* Broadcasts the given packet to everyone on the map but the source. source = null Broadcasts to everyone
*
* @param source
* @param packet
*/
// public void broadcastMessage(MapleCharacter source, MaplePacket packet) {
// synchronized (characters) {
// for (MapleCharacter chr : characters) {
// if (chr != source) {
// chr.getClient().getSession().write(packet);
// }
// }
// }
// }
/**
* Broadcast a message to everyone in the map
*
* @param packet
*/
public void broadcastMessage(MaplePacket packet) {
broadcastMessage(null, packet, Double.POSITIVE_INFINITY, null);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -