package org.pokenet.server.backend.map;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Random;
import org.pokenet.server.backend.DataLoader;
import org.pokenet.server.backend.entity.Char;
import org.pokenet.server.backend.entity.HMObject;
import org.pokenet.server.backend.entity.NonPlayerChar;
import org.pokenet.server.backend.entity.PlayerChar;
import org.pokenet.server.backend.entity.PlayerChar.Language;
import org.pokenet.server.backend.entity.Positionable.Direction;
import org.pokenet.server.battle.DataService;
import org.pokenet.server.battle.Pokemon;
import org.pokenet.server.battle.impl.NpcBattleLauncher;
import org.pokenet.server.feature.TimeService;
import org.pokenet.server.feature.TimeService.Weather;
import org.pokenet.server.network.TcpProtocolHandler;
import org.pokenet.server.network.message.ChatMessage;
import org.pokenet.server.network.message.PokenetMessage;
import org.pokenet.server.network.message.ChatMessage.ChatMessageType;
import tiled.core.Map;
import tiled.core.TileLayer;
/**
* Represents a map in the game world
* @author shadowkanji
*
*/
public class ServerMap {
public enum PvPType { DISABLED, ENABLED, ENFORCED }
//Stores the width, heigth, x, y and offsets of this map
private int m_width;
private int m_heigth;
private int m_x;
private int m_y;
private int m_xOffsetModifier;
private int m_yOffsetModifier;
private PvPType m_pvpType = PvPType.ENABLED;
private ServerMapMatrix m_mapMatrix;
private Weather m_forcedWeather = null;
//Players and NPCs
private HashMap<String, PlayerChar> m_players;
private ArrayList<NonPlayerChar> m_npcs;
private ArrayList<WarpTile> m_warps;
private ArrayList<MapItem> m_items;
//The following stores information for day, night and water wild pokemon
private HashMap<String, int[]> m_dayPokemonLevels;
private HashMap<String, Integer> m_dayPokemonChances;
private HashMap<String, int[]> m_nightPokemonLevels;
private HashMap<String, Integer> m_nightPokemonChances;
private HashMap<String, int[]> m_waterPokemonLevels;
private HashMap<String, Integer> m_waterPokemonChances;
private HashMap<String, int[]> m_fishPokemonLevels;
private HashMap<String, Integer> m_fishPokemonChances;
private int m_wildProbability;
//The following stores collision information
private ServerTileLayer m_blocked = null;
private ServerTileLayer m_surf = null;
private ServerTileLayer m_grass = null;
private ServerTileLayer m_ledgesDown = null;
private ServerTileLayer m_ledgesLeft = null;
private ServerTileLayer m_ledgesRight = null;
//Misc
private Random m_random = DataService.getBattleMechanics().getRandom();
/**
* Default constructor
* @param map
* @param x
* @param y
*/
public ServerMap(Map map, int x, int y) {
m_x = x;
m_y = y;
m_heigth = map.getHeight();
m_width = map.getWidth();
/*
* Store all the map layers
*/
for(int i = 0; i < map.getTotalLayers(); i++) {
if(map.getLayer(i).getName().equalsIgnoreCase("Grass")) {
m_grass = new ServerTileLayer((TileLayer) map.getLayer(i));
} else if(map.getLayer(i).getName().equalsIgnoreCase("Collisions")) {
m_blocked = new ServerTileLayer((TileLayer) map.getLayer(i));
} else if(map.getLayer(i).getName().equalsIgnoreCase("LedgesLeft")) {
m_ledgesLeft = new ServerTileLayer((TileLayer) map.getLayer(i));
} else if(map.getLayer(i).getName().equalsIgnoreCase("LedgesRight")) {
m_ledgesRight = new ServerTileLayer((TileLayer) map.getLayer(i));
} else if(map.getLayer(i).getName().equalsIgnoreCase("LedgesDown")) {
m_ledgesDown = new ServerTileLayer((TileLayer) map.getLayer(i));
} else if(map.getLayer(i).getName().equalsIgnoreCase("Water")) {
m_surf = new ServerTileLayer((TileLayer) map.getLayer(i));
}
}
m_players = new HashMap<String, PlayerChar>();
m_npcs = new ArrayList<NonPlayerChar>();
/*
* Load pvp settings
*/
try {
String type = map.getProperties().getProperty("pvp");
if(type.equalsIgnoreCase("disabled")) {
m_pvpType = PvPType.DISABLED;
} else if(type.equalsIgnoreCase("enabled")) {
m_pvpType = PvPType.ENABLED;
} else {
m_pvpType = PvPType.ENFORCED;
}
} catch (Exception e) {
m_pvpType = PvPType.ENABLED;
}
/*
* Add enforced weather if any
*/
try {
if(x < -30) {
if(x != -49 || y != -3) {
m_forcedWeather = Weather.NORMAL;
}
else if(x!= -36 || y != -49) {
m_forcedWeather = Weather.NORMAL;
}
} else if(map.getProperties().getProperty("forcedWeather") != null &&
!map.getProperties().getProperty("forcedWeather").equalsIgnoreCase("")) {
m_forcedWeather = Weather.valueOf(map.getProperties().getProperty("forcedWeather"));
}
} catch (Exception e) {
m_forcedWeather = null;
}
/*
* Load offsets
*/
try {
m_xOffsetModifier = Integer.parseInt(map.getProperties().getProperty("xOffsetModifier"));
} catch (Exception e) {
m_xOffsetModifier = 0;
}
try {
m_yOffsetModifier = Integer.parseInt(map.getProperties().getProperty("yOffsetModifier"));
} catch (Exception e) {
m_yOffsetModifier = 0;
}
/*
* Load wild pokemon
*/
try {
if(!map.getProperties().getProperty("wildProbabilty").equalsIgnoreCase("")) {
m_wildProbability = Integer.parseInt(map.getProperties().getProperty("wildProbabilty"));
} else {
m_wildProbability = 28;
}
} catch (Exception e) {
m_wildProbability = 28;
}
String[] species;
String[] levels;
//Daytime Pokemon
try {
if(!map.getProperties().getProperty("dayPokemonChances").equalsIgnoreCase("")) {
species = map.getProperties().getProperty("dayPokemonChances").split(";");
levels = map.getProperties().getProperty("dayPokemonLevels").split(";");
if (!species[0].equals("") && !levels[0].equals("") && species.length == levels.length) {
m_dayPokemonChances = new HashMap<String, Integer>();
m_dayPokemonLevels = new HashMap<String, int[]> ();
for (int i = 0; i < species.length; i++) {
String[] speciesInfo = species[i].split(",");
m_dayPokemonChances.put(speciesInfo[0], Integer.parseInt(speciesInfo[1]));
String[] levelInfo = levels[i].split("-");
m_dayPokemonLevels.put(speciesInfo[0], new int[] {
Integer.parseInt(levelInfo[0]),
Integer.parseInt(levelInfo[1]) });
}
}
}
} catch (Exception e) {
m_dayPokemonChances = null;
m_dayPokemonLevels = null;
species = new String[] { "" };
levels = new String[] { "" };
}
//Nocturnal Pokemon
try {
if(!map.getProperties().getProperty("nightPokemonChances").equalsIgnoreCase("")) {
species = map.getProperties().getProperty("nightPokemonChances").split(";");
levels = map.getProperties().getProperty("nightPokemonLevels").split(";");
if (!species[0].equals("") && !levels[0].equals("") && species.length == levels.length) {
m_nightPokemonChances = new HashMap<String, Integer>();
m_nightPokemonLevels = new HashMap<String, int[]> ();
for (int i = 0; i < species.length; i++) {
String[] speciesInfo = species[i].split(",");
m_nightPokemonChances.put(speciesInfo[0], Integer.parseInt(speciesInfo[1]));
String[] levelInfo = levels[i].split("-");
m_nightPokemonLevels.put(speciesInfo[0], new int[] {
Integer.parseInt(levelInfo[0]),
Integer.parseInt(levelInfo[1]) });
}
}
}
} catch (Exception e) {
m_nightPokemonChances = null;
m_nightPokemonLevels = null;
species = new String[] { "" };
levels = new String[] { "" };
}
//Surf Pokemon
try {
if(!map.getProperties().getProperty("waterPokemonChances").equalsIgnoreCase("")) {
species = map.getProperties().getProperty("waterPokemonChances").split(";");
levels = map.getProperties().getProperty("waterPokemonLevels").split(";");
if (!species[0].equals("") && !levels[0].equals("") && species.length == levels.length) {
m_waterPokemonChances = new HashMap<String, Integer>();
m_waterPokemonLevels = new HashMap<String, int[]> ();
for (int i = 0; i < species.length; i++) {
String[] speciesInfo = species[i].split(",");
m_waterPokemonChances.put(speciesInfo[0], Integer.parseInt(speciesInfo[1]));
String[] levelInfo = levels[i].split("-");
m_waterPokemonLevels.put(speciesInfo[0], new int[] {
Integer.parseInt(levelInfo[0]),
Integer.parseInt(levelInfo[1]) });
}
}
}
} catch (Exception e) {
m_waterPokemonChances = null;
m_waterPokemonLevels = null;
species = new String[] { "" };
levels = new String[] { "" };
}
//Fish Pokemon
try {
if(!map.getProperties().getProperty("fishPokemonChances").equalsIgnoreCase("")) {
species = map.getProperties().getProperty("fishPokemonChances").split(";");
levels = map.getProperties().getProperty("fishPokemonLevels").split(";");
if (!species[0].equals("") && !levels[0].equals("") && species.length == levels.length) {
m_fishPokemonChances = new HashMap<String, Integer>();
m_fishPokemonLevels = new HashMap<String, int[]> ();
for (int i = 0; i < species.length; i++) {
String[] speciesInfo = species[i].split(",");
m_fishPokemonChances.put(speciesInfo[0], Integer.parseInt(speciesInfo[1]));
String[] levelInfo = levels[i].split("-");
m_fishPokemonLevels.put(speciesInfo[0], new int[] {
Integer.parseInt(levelInfo[0]),
Integer.parseInt(levelInfo[1]) });
}
}
}
} catch (Exception e) {
m_fishPokemonChances = null;
m_fishPokemonLevels = null;
species = new String[] { "" };
levels = new String[] { "" };
}
}
/**
* Loads all npc and warp tile data
*/
public void loadData() {
/*
* Load all npcs and warptiles
*/
File f = new File("res/npc/" + m_x + "." + m_y + ".txt");
if(f.exists()) {
try {
@SuppressWarnings("unused")
DataLoader d = new DataLoader(f, this);
} catch (Exception e) {
}
}
}
/**
* Sends a chat message to everyone of the same language
* @param message
* @param l
*/
public void sendChatMessage(String message, Language l) {
synchronized(m_players) {
Collection<PlayerChar> list = m_players.values();
for(PlayerChar p: list) {
if(p.getLanguage() == l) {
TcpProtocolHandler.writeMessage(
p.getTcpSession(),
new ChatMessage(ChatMessageType.LOCAL, message));
}
}
}
}
/**
* Returns the pvp type of the map
* @return
*/
public PvPType getPvPType() {
return m_pvpType;
}
/**
* Adds a warp tile to the map
* @param w
*/
public void addWarp(WarpTile w) {
if(m_warps == null)
m_warps = new ArrayList<WarpTile>();
m_warps.add(w);
}
/**
* Adds an item to the map
* @param x
* @param y
* @param id
*/
public void addItem(int x, int y, int id) {
m_items.add(new MapItem(x, y, id));
}
/**
* Allows a player to pick up an item
* @param p
*/
public void pickupItem(PlayerChar p) {
}
/**
* Returns true if this map has a forced weather
* @return
*/
public boolean isWeatherForced() {
return m_forcedWeather != null;
}
/**
* Returns the enforced weather on this map
* @return
*/
public Weather getWeather() {
return m_forcedWeather;
}
/**
* Sets forced weather
* @param w
*/
public void setWeather(Weather w) {
m_forcedWeather = w;
}
/**
* Removes forced weather
*/
public void removeWeather() {
m_forcedWeather = null;
}
/**
* Returns the weather id for the enforced weather on this map
* @return
*/
public int getWeatherId() {
if(m_forcedWeather != null) {
switch(m_forcedWeather) {
case NORMAL:
return 0;
case RAIN:
return 1;
case HAIL:
return 2;
case SANDSTORM:
return 3;
case FOG:
return 4;
default:
return 0;
}
} else
return 0;
}
/**
* Sets the map matrix
* @param matrix
*/
public void setMapMatrix(ServerMapMatrix matrix) {
m_mapMatrix = matrix;
}
/**
* Adds a player to this map and notifies all other clients on the map.
* @param player
*/
public void addChar(Char c) {
if(c instanceof PlayerChar) {
m_players.put(c.getName(), (PlayerChar) c);
} else if(c instanceof NonPlayerChar || c instanceof HMObject) {
//Set the id of the npc
c.setId(-1 - m_npcs.size());
m_npcs.add((NonPlayerChar) c);
}
synchronized(m_players) {
for(PlayerChar p : m_players.values()) {
if(c.getId() != p.getId()) {
String name = c.getName();
if(c instanceof NonPlayerChar) {
name = "!NPC!";
}
p.getTcpSession().write("ma" + name + "," +
c.getId() + "," + c.getSprite() + "," + c.getX() + "," + c.getY() + "," +
(c.getFacing() == Direction.Down ? "D" :
c.getFacing() == Direction.Up ? "U" :
c.getFacing() == Direction.Left ? "L" :
"R"));
}
}
}
}
/**
* Adds a char and sets their x y based on a 32 by 32 pixel grid.
* Allows easier adding of NPCs as the x,y can easily be counted via Tiled
* @param c
* @param tileX
* @param tileY
*/
public void addChar(Char c, int tileX, int tileY) {
this.addChar(c);
c.setX(tileX * 32);
c.setY((tileY * 32) - 8);
}
/**
* Returns the x co-ordinate of this servermap in the map matrix
* @return
*/
public int getX() {
return m_x;
}
/**
* Returns the y co-ordinate of this servermap in the map matrix
* @return
*/
public int getY() {
return m_y;
}
/**
* Returns the width of this map
* @return
*/
public int getWidth() {
return m_width;
}
/**
* Returns the height of this map
* @return
*/
public int getHeight() {
return m_heigth;
}
/**
* Returns the x offset of this map
* @return
*/
public int getXOffsetModifier() {
return m_xOffsetModifier;
}
/**
* Returns the y offset of this map
* @return
*/
public int getYOffsetModifier() {
return m_yOffsetModifier;
}
/**
* Removes a char from this map
* @param c
*/
public void removeChar(Char c) {
if(c instanceof PlayerChar) {
synchronized(m_players) {
m_players.remove(c.getName());
}
} else if(c instanceof NonPlayerChar) {
m_npcs.remove((NonPlayerChar) c);
m_npcs.trimToSize();
}
synchronized(m_players) {
for(PlayerChar p : m_players.values()) {
p.getTcpSession().write("mr" + c.getId());
}
}
}
/**
* Allows a player to talk to the npc in front of them, if any
* @param p
*/
public void talkToNpc(PlayerChar p) {
int x = 0, y = 0;
switch(p.getFacing()) {
case Up:
x = p.getX();
y = p.getY() - 32;
break;
case Down:
x = p.getX();
y = p.getY() + 32;
break;
case Left:
x = p.getX() - 32;
y = p.getY();
break;
case Right:
x = p.getX() + 32;
y = p.getY();
break;
default:
break;
}
for(int i = 0; i < m_npcs.size(); i++) {
if(m_npcs.get(i).getX() == x && m_npcs.get(i).getY() == y) {
if (!(m_npcs.get(i) instanceof HMObject))
p.setTalking(true);
m_npcs.get(i).talkToPlayer(p);
break;
}
}
}
/**
* Returns true if there is an obstacle
* @param x
* @param y
* @param d
* @return
*/
private boolean isBlocked(int x, int y, Direction d) {
if (m_blocked.getTileAt(x, y) == '1')
return true;
if(m_npcs.size() < 4) {
for(int i = 0; i < m_npcs.size(); i++) {
if(m_npcs.get(i).getX() == (x * 32) && m_npcs.get(i).getY() == ((y * 32) - 8))
return true;
}
} else {
for(int i = 0; i <= m_npcs.size() / 2; i++) {
if(m_npcs.get(i).getX() == (x * 32) && m_npcs.get(i).getY() == ((y * 32) - 8))
return true;
else if(m_npcs.get(m_npcs.size() - 1 - i).getX() == (x * 32) &&
m_npcs.get(m_npcs.size() - 1 - i).getY() == ((y * 32) - 8))
return true;
}
}
if(m_ledgesRight != null && m_ledgesRight.getTileAt(x, y) == '1') {
if(d != Direction.Right)
return true;
}
if(m_ledgesLeft != null && m_ledgesLeft.getTileAt(x, y) == '1') {
if(d != Direction.Left)
return true;
}
if(m_ledgesDown != null && m_ledgesDown.getTileAt(x, y) == '1') {
if(d != Direction.Down)
return true;
}
return false;
}
/**
* Returns true if the char was warped
* @param x
* @param y
* @param c
* @return
*/
private boolean isWarped(int x, int y, Char c) {
if(m_warps != null) {
for(int i = 0; i < m_warps.size(); i++) {
if(m_warps.get(i).getX() == x && m_warps.get(i).getY() == y) {
m_warps.get(i).warp(c);
return true;
}
}
}
return false;
}
/**
* Returns true if a fishing attempt was deemed successful(Will the player pull up any pogey or find nothing?)
* @param c
* @param d
* @param rod
*/
public boolean caughtFish(PlayerChar c, Direction d, int rod) {
int failureRate = 75;
//Subtract the rod's power from the failure rate.
failureRate -= rod;
//If that tile is a water tile, determine if you pulled anything, if not, autofail(You can't fish on dry land)
if(facingWater(c, d)) { //If facing water
c.setFishing(true);
if((int)(Math.random()* 101) > failureRate) {
return true;
} else {
return false;
}
} else {
c.getTcpSession().write("Ff"); // Tell the player he can't fish on land
}
return false;
}
/**
* Returns true if the player is facing water
* @param c
* @param newX
* @param newY
* @return
*/
public boolean facingWater(PlayerChar c, Direction d) {
int playerX = c.getX();
int playerY = c.getY();
int newX = 0;
int newY = 0;
//Determine what tile the player is facing
switch(d) {
case Up:
newX = playerX / 32;
newY = ((playerY + 8) - 32) / 32;
break;
case Down:
newX = playerX / 32;
newY = ((playerY + 8) + 32) / 32;
break;
case Left:
newX = (playerX - 32) / 32;
newY = (playerY + 8) / 32;
break;
case Right:
newX = (playerX + 32) / 32;
newY = (playerY + 8) / 32;
break;
}
if(m_surf != null && m_surf.getTileAt(newX, newY) == '1') { //If facing water
return true;
}
return false;
}
/**
* Returns true if the char is able to move
* @param c
* @param d
*/
public boolean moveChar(Char c, Direction d) {
int playerX = c.getX();
int playerY = c.getY();
int newX;
int newY;
switch(d) {
case Up:
newX = playerX / 32;
newY = ((playerY + 8) - 32) / 32;
if (playerY >= 1) {
if (!isBlocked(newX, newY, Direction.Up)) {
if(m_surf != null && m_surf.getTileAt(newX, newY) == '1') {
if(c.isSurfing()) {
return true;
} else {
if(c instanceof PlayerChar) {
PlayerChar p = (PlayerChar) c;
if(p.canSurf()) {
p.setSurfing(true);
return true;
} else {
return false;
}
}
}
} else {
if(c.isSurfing())
c.setSurfing(false);
if(!isWarped(newX, newY, c))
return true;
}
}
} else {
ServerMap newMap = m_mapMatrix.getMapByGamePosition(m_x, m_y - 1);
if (newMap != null) {
m_mapMatrix.moveBetweenMaps(c, this, newMap);
}
}
break;
case Down:
newX = playerX / 32;
newY = ((playerY + 8) + 32) / 32;
if (playerY + 40 < m_heigth * 32) {
if (!isBlocked(newX, newY, Direction.Down)) {
if(m_surf != null && m_surf.getTileAt(newX, newY) == '1') {
if(c.isSurfing()) {
return true;
} else {
if(c instanceof PlayerChar) {
PlayerChar p = (PlayerChar) c;
if(p.canSurf()) {
p.setSurfing(true);
return true;
} else {
return false;
}
}
}
} else {
if(c.isSurfing())
c.setSurfing(false);
if(!isWarped(newX, newY, c))
return true;
}
}
} else {
ServerMap newMap = m_mapMatrix.getMapByGamePosition(m_x, m_y + 1);
if (newMap != null) {
m_mapMatrix.moveBetweenMaps(c, this, newMap);
}
}
break;
case Left:
newX = (playerX - 32) / 32;
newY = (playerY + 8) / 32;
if (playerX >= 32) {
if (!isBlocked(newX, newY, Direction.Left)) {
if(m_surf != null && m_surf.getTileAt(newX, newY) == '1') {
if(c.isSurfing()) {
return true;
} else {
if(c instanceof PlayerChar) {
PlayerChar p = (PlayerChar) c;
if(p.canSurf()) {
p.setSurfing(true);
return true;
} else {
return false;
}
}
}
} else {
if(c.isSurfing())
c.setSurfing(false);
if(!isWarped(newX, newY, c))
return true;
}
}
} else {
ServerMap newMap = m_mapMatrix.getMapByGamePosition(m_x - 1, m_y);
if (newMap != null) {
m_mapMatrix.moveBetweenMaps(c, this, newMap);
}
}
break;
case Right:
newX = (playerX + 32) / 32;
newY = (playerY + 8) / 32;
if (playerX + 32 < m_width * 32) {
if (!isBlocked(newX, newY, Direction.Right)) {
if(m_surf != null && m_surf.getTileAt(newX, newY) == '1') {
if(c.isSurfing()) {
return true;
} else {
if(c instanceof PlayerChar) {
PlayerChar p = (PlayerChar) c;
if(p.canSurf()) {
p.setSurfing(true);
return true;
} else {
return false;
}
}
}
} else {
if(c.isSurfing())
c.setSurfing(false);
if(!isWarped(newX, newY, c))
return true;
}
}
} else {
ServerMap newMap = m_mapMatrix.getMapByGamePosition(m_x + 1, m_y);
if (newMap != null) {
m_mapMatrix.moveBetweenMaps(c, this, newMap);
}
}
break;
}
return false;
}
/**
* Starts an npc battle with the player if the player was challenged
* @param p
* @return
*/
public boolean isNpcBattle(PlayerChar p) {
NonPlayerChar n = null;
for(int i = 0; i < m_npcs.size(); i++) {
n = m_npcs.get(i);
if(n != null && n.isTrainer() && !n.isGymLeader()) {
/*
* For the npc to be able to challenge the player, the must be on the same
* axis as the player, the x axis or the y axis
*/
if(n.getX() == p.getX()) {
/* Same column */
if(n.getY() > p.getY()) {
/* NPC is above the player */
if(n.getFacing() == Direction.Up && n.canSee(p)) {
NpcBattleLauncher l = new NpcBattleLauncher(n, p);
l.start();
return true;
}
} else {
/* NPC is below the player */
if(n.getFacing() == Direction.Down && n.canSee(p)) {
NpcBattleLauncher l = new NpcBattleLauncher(n, p);
l.start();
return true;
}
}
} else if(n.getY() == p.getY()) {
/* Same row */
if(n.getX() > p.getX()) {
/* NPC is right of the player */
if(n.getFacing() == Direction.Left && n.canSee(p)) {
NpcBattleLauncher l = new NpcBattleLauncher(n, p);
l.start();
return true;
}
} else {
/* NPC is left of the player */
if(n.getFacing() == Direction.Right && n.canSee(p)) {
NpcBattleLauncher l = new NpcBattleLauncher(n, p);
l.start();
return true;
}
}
}
}
}
return false;
}
/**
* Returns true if a wild pokemon was encountered.
* @return
*/
public boolean isWildBattle(int x, int y, PlayerChar p) {
if (m_random.nextInt(2874) < m_wildProbability * 16) {
if(p.isSurfing()) {
if(m_waterPokemonChances != null && m_waterPokemonLevels != null)
return true;
} else {
if (m_grass != null && m_grass.getTileAt(x / 32, (y + 8) / 32) == '1')
if((m_dayPokemonChances != null && m_dayPokemonLevels != null) ||
(m_nightPokemonChances != null && m_nightPokemonLevels != null))
return true;
}
}
return false;
}
/**
* Returns a wild pokemon.
* Different players have different chances of encountering rarer Pokemon.
* @return
*/
public Pokemon getWildPokemon(PlayerChar player) {
int [] range;
String species;
if(player.isSurfing()) {
//Generate a Pokemon from the water
species = getWildSpeciesWater();
range = m_waterPokemonLevels.get(species);
return Pokemon.getRandomPokemon(species, (m_random.nextInt((range[1] - range[0]) + 1)) + range[0]);
}
else if(player.isFishing()) {
//Generate a pokemon caught by fishing
species = getWildSpeciesFish();
range = m_fishPokemonLevels.get(species);
return Pokemon.getRandomPokemon(species, (m_random.nextInt((range[1] - range[0]) + 1)) + range[0]);
}
else {
if(TimeService.isNight()) {
//Generate a nocturnal Pokemon
species = getWildSpeciesNight();
range = m_nightPokemonLevels.get(species);
return Pokemon.getRandomPokemon(species, (m_random.nextInt((range[1] - range[0]) + 1)) + range[0]);
} else {
//Generate a day Pokemon
species = getWildSpeciesDay();
range = m_dayPokemonLevels.get(species);
return Pokemon.getRandomPokemon(species, (m_random.nextInt((range[1] - range[0]) + 1)) + range[0]);
}
}
}
/**
* Returns a wild species for day
* @return
*/
private String getWildSpeciesDay() {
ArrayList<String> potentialSpecies = new ArrayList<String>();
do {
for (String species : m_dayPokemonChances.keySet()) {
if (m_random.nextInt(101) < m_dayPokemonChances.get(species))
potentialSpecies.add(species);
}
} while (potentialSpecies.size() <= 0);
return potentialSpecies.get(m_random.nextInt(potentialSpecies.size()));
}
/**
* Returns a wild species for night
* @return
*/
private String getWildSpeciesNight() {
ArrayList<String> potentialSpecies = new ArrayList<String>();
do {
for (String species : m_nightPokemonChances.keySet()) {
if (m_random.nextInt(101) < m_nightPokemonChances.get(species))
potentialSpecies.add(species);
}
} while (potentialSpecies.size() <= 0);
return potentialSpecies.get(m_random.nextInt(potentialSpecies.size()));
}
/**
* Returns a wild species for water
* @return
*/
private String getWildSpeciesWater() {
ArrayList<String> potentialSpecies = new ArrayList<String>();
do {
for (String species : m_waterPokemonChances.keySet()) {
if (m_random.nextInt(101) < m_waterPokemonChances.get(species))
potentialSpecies.add(species);
}
} while (potentialSpecies.size() <= 0);
return potentialSpecies.get(m_random.nextInt(potentialSpecies.size()));
}
/**
* Returns a wild species for fishing
* @return
*/
private String getWildSpeciesFish() {
ArrayList<String> potentialSpecies = new ArrayList<String>();
do {
for (String species : m_fishPokemonChances.keySet()) {
if (m_random.nextInt(101) < m_fishPokemonChances.get(species))
potentialSpecies.add(species);
}
} while (potentialSpecies.size() <= 0);
return potentialSpecies.get(m_random.nextInt(potentialSpecies.size()));
}
/**
* Sends a packet to all players on the map
* @param message
*/
public void sendToAll(PokenetMessage m) {
synchronized(m_players) {
Collection<PlayerChar> list = m_players.values();
for(PlayerChar p: list) {
TcpProtocolHandler.writeMessage(p.getTcpSession(), m);
}
}
}
/**
* Returns the arraylist of players
* @return
*/
public HashMap<String, PlayerChar> getPlayers() {
return m_players;
}
/**
* Returns the arraylist of npcs
* @return
*/
public ArrayList<NonPlayerChar> getNpcs() {
return m_npcs;
}
/**
* Sends a movement packet to everyone
* @param moveMessage
* @param char1
*/
public void sendMovementToAll(Direction d, Char c) {
if(c instanceof PlayerChar) {
/*
* If a player, send movement to everyone but themselves
* Movement for themself is sent over TCP
*/
PlayerChar p = (PlayerChar) c;
synchronized(m_players) {
Collection<PlayerChar> list = m_players.values();
for(PlayerChar pl: list) {
if(p != pl) {
pl.queueOtherPlayerMovement(d, c.getId());
}
}
}
} else {
/*
* Else, send the movement to everyone
*/
synchronized(m_players) {
Collection<PlayerChar> list = m_players.values();
for(PlayerChar pl: list) {
pl.queueOtherPlayerMovement(d, c.getId());
}
}
}
}
}