⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maplemap.java

📁 冒险岛私服Java版服务端(Odinms)源代码。学习JAVA开发的朋友
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	}

	/**
	 * 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 + -