package org.pokenet.server.feature;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Calendar;
import java.util.Random;
import java.util.StringTokenizer;
import org.pokenet.server.battle.mechanics.statuses.field.FieldEffect;
import org.pokenet.server.battle.mechanics.statuses.field.HailEffect;
import org.pokenet.server.battle.mechanics.statuses.field.RainEffect;
import org.pokenet.server.battle.mechanics.statuses.field.SandstormEffect;
/**
* Handles game time and weather
* @author shadowkanji
*
*/
public class TimeService implements Runnable {
private boolean m_isRunning;
private long m_lastWeatherUpdate;
private int m_forcedWeather=0;
private Thread m_thread;
private static int m_hour;
private static int m_minutes;
private static int m_day = 0;
private static Weather m_weather;
/*
* NOTE: HAIL = SNOW
*/
public enum Weather { NORMAL, RAIN, HAIL, SANDSTORM, FOG }
/**
* Default constructor
*/
public TimeService() {
/*
* Generate random weather
*/
int weather = new Random().nextInt(4);
switch(weather) {
case 0:
m_weather = Weather.NORMAL;
break;
case 1:
m_weather = Weather.RAIN;
break;
case 2:
m_weather = Weather.HAIL;
break;
case 3:
m_weather = Weather.FOG;
break;
case 4:
m_weather = Weather.SANDSTORM;
break;
default:
m_weather = Weather.NORMAL;
}
m_lastWeatherUpdate = System.currentTimeMillis();
m_thread = new Thread(this);
}
/**
* Called by m_thread.start()
*/
public void run() {
try {
/*
* Parses time from a common server.
* The webpage should just have text (no html tags) in the form:
* DAY HOUR MINUTES
* where day is a number from 0 - 6
*/
URL url = new URL("http://pokedev.org/time.php");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
StringTokenizer s = new StringTokenizer(in.readLine());
m_day = Integer.parseInt(s.nextToken());
m_hour = Integer.parseInt(s.nextToken());
m_minutes = Integer.parseInt(s.nextToken());
in.close();
} catch (Exception e) {
System.out.println("ERROR: Cannot reach time server, reverting to local time");
/* Can't reach website, base time on local */
Calendar cal = Calendar.getInstance();
m_hour = cal.get(Calendar.HOUR_OF_DAY);
m_minutes = 0;
m_day = 0;
}
while(m_isRunning) {
//Update the time. Time moves 4 times faster.
m_minutes = m_minutes == 59 ? 0 : m_minutes + 1;
if(m_minutes == 0) {
if(m_hour == 23) {
incrementDay();
m_hour = 0;
} else {
m_hour += 1;
}
}
m_hour = m_hour == 23 ? 0 : m_hour + 1;
//Check if weather should be updated
if(System.currentTimeMillis() - m_lastWeatherUpdate >= 3600000) {
generateWeather();
m_lastWeatherUpdate = System.currentTimeMillis();
}
try {
Thread.sleep(60000);
} catch (Exception e) {}
}
System.out.println("INFO: Time Service stopped");
}
/**
* Increments the day on the server
*/
public void incrementDay() {
m_day = m_day == 6 ? 0 : m_day + 1;
}
/**
* Starts this Time Service
*/
public void start() {
m_isRunning = true;
m_thread.start();
System.out.println("INFO: Time Service started");
}
/**
* Stops this Time Service
*/
public void stop() {
m_isRunning = false;
}
/**
* Generates a new weather status
*/
private void generateWeather() {
/*
* Generate random weather
*/
int weather = m_forcedWeather;
if(weather == 9)
weather = new Random().nextInt(4);
switch(weather) {
case 0:
m_weather = Weather.NORMAL;
break;
case 1:
m_weather = Weather.RAIN;
break;
case 2:
m_weather = Weather.HAIL;
break;
case 3:
m_weather = Weather.FOG;
break;
case 4:
m_weather = Weather.SANDSTORM;
break;
default:
m_weather = Weather.NORMAL;
}
}
/**
* Returns the field effect based on current weather
* @return
*/
public static FieldEffect getWeatherEffect() {
switch(m_weather) {
case NORMAL:
return null;
case RAIN:
return new RainEffect();
case HAIL:
return new HailEffect();
case SANDSTORM:
return new SandstormEffect();
case FOG:
return null;
default:
return null;
}
}
/**
* Returns a string representation of the current time, e.g. 1201
* @return
*/
public static String getTime() {
return "" + (m_hour < 10 ? "0" + m_hour : m_hour) + (m_minutes < 10 ? "0" + m_minutes : m_minutes);
}
/**
* Returns the hour of the day (game time)
* @return
*/
public static int getHourOfDay() {
return m_hour;
}
/**
* Returns the current minute (game time)
* @return
*/
public static int getMinuteOfDay() {
return m_minutes;
}
/**
* Returns true if it is night time
* @return
*/
public static boolean isNight() {
return m_hour >= 20 || m_hour < 6;
}
/**
* Returns the current Weather.
* @return
*/
public int getForcedWeather() {
return m_forcedWeather;
}
/**
* Sets the weather.
* 0: Weather.NORMAL;
* 1: Weather.RAIN;
* 2: Weather.HAIL;
* 3: Weather.FOG;
* 9: Weather.RANDOM;
* @return
*/
public void setForcedWeather(int mForcedWeather) {
m_forcedWeather = mForcedWeather;
m_lastWeatherUpdate = 0;
}
/**
* Returns the id of the weather
* @return
*/
public static int getWeatherId() {
switch(m_weather) {
case NORMAL:
return 0;
case RAIN:
return 1;
case HAIL:
return 2;
case SANDSTORM:
return 3;
case FOG:
return 4;
default:
return 0;
}
}
}