📄 maplemap.java
字号:
}
/**
* Nonranged. Repeat to source according to parameter.
*
* @param source
* @param packet
* @param repeatToSource
*/
public void broadcastMessage(MapleCharacter source, MaplePacket packet, boolean repeatToSource) {
broadcastMessage(repeatToSource ? null : source, packet, Double.POSITIVE_INFINITY, source.getPosition());
}
/**
* Ranged and repeat according to parameters.
*
* @param source
* @param packet
* @param repeatToSource
* @param ranged
*/
public void broadcastMessage(MapleCharacter source, MaplePacket packet, boolean repeatToSource, boolean ranged) {
broadcastMessage(repeatToSource ? null : source, packet, ranged ? MapleCharacter.MAX_VIEW_RANGE_SQ
: Double.POSITIVE_INFINITY, source.getPosition());
}
/**
* Always ranged from Point.
*
* @param packet
* @param rangedFrom
*/
public void broadcastMessage(MaplePacket packet, Point rangedFrom) {
broadcastMessage(null, packet, MapleCharacter.MAX_VIEW_RANGE_SQ, rangedFrom);
}
/**
* Always ranged from point. Does not repeat to source.
*
* @param source
* @param packet
* @param rangedFrom
*/
public void broadcastMessage(MapleCharacter source, MaplePacket packet, Point rangedFrom) {
broadcastMessage(source, packet, MapleCharacter.MAX_VIEW_RANGE_SQ, rangedFrom);
}
private void broadcastMessage(MapleCharacter source, MaplePacket packet, double rangeSq, Point rangedFrom) {
synchronized (characters) {
for (MapleCharacter chr : characters) {
if (chr != source) {
if (rangeSq < Double.POSITIVE_INFINITY) {
if (rangedFrom.distanceSq(chr.getPosition()) <= rangeSq) {
chr.getClient().getSession().write(packet);
}
} else {
chr.getClient().getSession().write(packet);
}
}
}
}
}
private boolean isNonRangedType (MapleMapObjectType type) {
switch (type) {
case NPC:
case PLAYER:
case MIST:
return true;
}
return false;
}
private void sendObjectPlacement(MapleClient mapleClient) {
for (MapleMapObject o : mapobjects.values()) {
if (isNonRangedType(o.getType())) {
o.sendSpawnData(mapleClient);
} else if (o.getType() == MapleMapObjectType.MONSTER) {
updateMonsterController((MapleMonster) o);
}
}
MapleCharacter chr = mapleClient.getPlayer();
if (chr != null) {
for (MapleMapObject o : getMapObjectsInRange(chr.getPosition(), MapleCharacter.MAX_VIEW_RANGE_SQ,
rangedMapobjectTypes)) {
o.sendSpawnData(chr.getClient());
chr.addVisibleMapObject(o);
}
} else {
log.info("sendObjectPlacement invoked with null char");
}
}
public List<MapleMapObject> getMapObjectsInRange(Point from, double rangeSq, List<MapleMapObjectType> types) {
List<MapleMapObject> ret = new LinkedList<MapleMapObject>();
for (MapleMapObject l : mapobjects.values()) {
if (types.contains(l.getType())) {
if (from.distanceSq(l.getPosition()) <= rangeSq) {
ret.add(l);
}
}
}
return ret;
}
public List<MapleMapObject> getMapObjectsInBox(Rectangle box, List<MapleMapObjectType> types) {
List<MapleMapObject> ret = new LinkedList<MapleMapObject>();
synchronized (mapobjects) {
for (MapleMapObject l : mapobjects.values()) {
if (types.contains(l.getType())) {
if (box.contains(l.getPosition())) {
ret.add(l);
}
}
}
}
return ret;
}
public void addPortal(MaplePortal myPortal) {
portals.put(myPortal.getId(), myPortal);
}
public MaplePortal getPortal(String portalname) {
for (MaplePortal port : portals.values()) {
if (port.getName().equals(portalname)) {
return port;
}
}
return null;
}
public MaplePortal getPortal(int portalid) {
return portals.get(portalid);
}
public void setFootholds(MapleFootholdTree footholds) {
this.footholds = footholds;
}
public MapleFootholdTree getFootholds() {
return footholds;
}
/**
* not threadsafe, please synchronize yourself
*
* @param monster
*/
public void addMonsterSpawn(MapleMonster monster, int mobTime) {
Point newpos = calcPointBelow(monster.getPosition());
newpos.y -= 1;
SpawnPoint sp = new SpawnPoint(monster, newpos, mobTime);
monsterSpawn.add(sp);
if (sp.shouldSpawn()) {
sp.spawnMonster(this);
}
}
public float getMonsterRate() {
return monsterRate;
}
public Collection<MapleCharacter> getCharacters() {
return Collections.unmodifiableCollection(this.characters);
}
public MapleCharacter getCharacterById(int id) {
for (MapleCharacter c : this.characters) {
if (c.getId() == id)
return c;
}
return null;
}
private void updateMapObjectVisibility(MapleCharacter chr, MapleMapObject mo) {
if (!chr.isMapObjectVisible(mo)) { // monster entered view range
if (mo.getPosition().distanceSq(chr.getPosition()) <= MapleCharacter.MAX_VIEW_RANGE_SQ) {
chr.addVisibleMapObject(mo);
mo.sendSpawnData(chr.getClient());
}
} else { // monster left view range
if (mo.getPosition().distanceSq(chr.getPosition()) > MapleCharacter.MAX_VIEW_RANGE_SQ) {
chr.removeVisibleMapObject(mo);
mo.sendDestroyData(chr.getClient());
}
}
}
public void moveMonster(MapleMonster monster, Point reportedPos) {
monster.setPosition(reportedPos);
synchronized (characters) {
for (MapleCharacter chr : characters) {
updateMapObjectVisibility(chr, monster);
}
}
}
public void movePlayer(MapleCharacter player, Point newPosition) {
player.setPosition(newPosition);
Collection<MapleMapObject> visibleObjects = player.getVisibleMapObjects();
MapleMapObject[] visibleObjectsNow = visibleObjects.toArray(new MapleMapObject[visibleObjects.size()]);
for (MapleMapObject mo : visibleObjectsNow) {
if (mapobjects.get(mo.getObjectId()) == mo) {
updateMapObjectVisibility(player, mo);
} else {
player.removeVisibleMapObject(mo);
}
}
for (MapleMapObject mo : getMapObjectsInRange(player.getPosition(), MapleCharacter.MAX_VIEW_RANGE_SQ,
rangedMapobjectTypes)) {
if (!player.isMapObjectVisible(mo)) {
mo.sendSpawnData(player.getClient());
player.addVisibleMapObject(mo);
}
}
}
public MaplePortal findClosestSpawnpoint(Point from) {
MaplePortal closest = null;
double shortestDistance = Double.POSITIVE_INFINITY;
for (MaplePortal portal : portals.values()) {
double distance = portal.getPosition().distanceSq(from);
if (portal.getType() >= 0 && portal.getType() <= 2 && distance < shortestDistance) {
closest = portal;
shortestDistance = distance;
}
}
return closest;
}
public void spawnDebug(MessageCallback mc) {
mc.dropMessage("Spawndebug...");
synchronized (mapobjects) {
mc.dropMessage("Mapobjects in map: " + mapobjects.size() + " \"spawnedMonstersOnMap\": " +
spawnedMonstersOnMap + " spawnpoints: " + monsterSpawn.size() +
" maxRegularSpawn: " + getMaxRegularSpawn());
int numMonsters = 0;
for (MapleMapObject mo : mapobjects.values()) {
if (mo instanceof MapleMonster) {
numMonsters++;
}
}
mc.dropMessage("actual monsters: " + numMonsters);
}
}
private int getMaxRegularSpawn() {
return (int) (monsterSpawn.size() / monsterRate);
}
public Collection<MaplePortal> getPortals() {
return Collections.unmodifiableCollection(portals.values());
}
public String getMapName() {
return mapName;
}
public void setMapName(String mapName) {
this.mapName = mapName;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
private class ExpireMapItemJob implements Runnable {
private MapleMapItem mapitem;
public ExpireMapItemJob(MapleMapItem mapitem) {
this.mapitem = mapitem;
}
@Override
public void run() {
if (mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
synchronized (mapitem) {
if (mapitem.isPickedUp())
return;
MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0),
mapitem.getPosition());
MapleMap.this.removeMapObject(mapitem);
mapitem.setPickedUp(true);
}
}
}
}
private class RespawnWorker implements Runnable {
@Override
public void run() {
int playersOnMap = characters.size();
if (playersOnMap == 0) {
return;
}
int ispawnedMonstersOnMap = spawnedMonstersOnMap.get();
int numShouldSpawn = (int) Math.round(Math.random() * ((2 + playersOnMap / 1.5 + (getMaxRegularSpawn() - ispawnedMonstersOnMap) / 4.0)));
if (numShouldSpawn + ispawnedMonstersOnMap > getMaxRegularSpawn()) {
numShouldSpawn = getMaxRegularSpawn() - ispawnedMonstersOnMap;
}
if (numShouldSpawn <= 0) {
return;
}
// k find that many monsters that need respawning and respawn them �.o
List<SpawnPoint> randomSpawn = new ArrayList<SpawnPoint>(monsterSpawn);
Collections.shuffle(randomSpawn);
int spawned = 0;
for (SpawnPoint spawnPoint : randomSpawn) {
if (spawnPoint.shouldSpawn()) {
spawnPoint.spawnMonster(MapleMap.this);
spawned++;
}
if (spawned >= numShouldSpawn) {
break;
}
}
}
}
private static interface DelayedPacketCreation {
void sendPackets(MapleClient c);
}
private static interface SpawnCondition {
boolean canSpawn(MapleCharacter chr);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -