aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/game/GameTime.java
blob: 9c2348ace0f33849773238514b2078f53a509c0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package ru.olamedia.game;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import ru.olamedia.astronomy.SunCalendar;

public class GameTime {
	public double longitude = 56.803698;
	public double latitude = 60.635262;
	public double gameSpeed = 60;// 1 real second is 60 seconds at game
	private static double daysInYear = 365.242;
	private static double minute = 60;
	@SuppressWarnings("unused")
	private static double hour = 3600;
	private static double day = 24 * 3600;
	@SuppressWarnings("unused")
	private static double month = (daysInYear / 12) * 24 * 3600;

	public GregorianCalendar earthCalendar;
	public SunCalendar sunCalendar;
	public double gameStart;
	public double yearStart;
	public double gameTime;
	public double gameYearTime;
	public double sunlightFactor = 0f;
	public int lastSunLight = 0;
	public float[] clearColors = new float[] { 0.0f, 0.0f, 0.0f };
	public boolean spaceLightIsInvalid = true;
	public boolean receivedLightIsInvalid = true;
	public double sunrise;
	public double sunset; //
	public double sunHA; //
	public double sunEA; //
	public double sunTC; //

	public static double getSystemTime() {
		return System.currentTimeMillis() / (double) (1000);
	}

	public void init() {
		earthCalendar = new GregorianCalendar();
		earthCalendar.setTimeZone(TimeZone.getTimeZone("Asia/Yekaterinburg")); // FIX
																				// Timezone
																				// for
																				// latlon
		sunCalendar = new SunCalendar(earthCalendar, longitude, latitude);
		gameSpeed = day / (1 * minute);

		gameStart = getTime();

		yearStart = gameStart - (gameStart % daysInYear);
		updateGameTime();
	}

	public double getTime() {
		return getSystemTime() / gameSpeed;
	}

	public Date getGameDate() {
		return new Date((long) gameTime);
	}

	public void updateGameTime() {
		gameTime = (getTime() - gameStart) * gameSpeed * gameSpeed;
	}

	public String getDateTimeString() {
		return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date((long) (gameTime * 1000)));
	}

	private static float addComponent(float a, float b) {
		return a + b;
	}

	private static float mulComponent(float a, float b) {
		return a * b;
	}

	public float[] getClearColor() {
		float sunAngularDiameter = 32;
		float sunRenderDistance = 700;
		@SuppressWarnings("unused")
		float sunRenderDiameter = (float) ((float) 2 * sunRenderDistance * Math.tan(sunAngularDiameter / 2));

		sunRenderDiameter /= 15;

		float[] spaceColors = new float[] { 0.03f, 0.03f, 0.05f }; // a little
																	// blue
		
		clearColors = new float[] { 0.0f, 0.0f, 0.0f };

		double crossAngle = sunCalendar.getHourAngle();
		@SuppressWarnings("unused")
		int elevationAngle = (int) sunCalendar.radToDeg(sunCalendar.getElevationAngle());

		sunlightFactor = 0f;
		if ((crossAngle > -120 && crossAngle < -70) || (crossAngle > 70 && crossAngle < 120)) {
			sunlightFactor = (float) 1f - (Math.abs(crossAngle) - 70) / 50;
		}
		if (crossAngle >= -70 && crossAngle <= 70) {
			sunlightFactor = (float) 1f;
		}
		int sunlight = (int) Math.round(15 * sunlightFactor);
		if (sunlight != lastSunLight) {
			spaceLightIsInvalid = true;
			receivedLightIsInvalid = true;
		}
		float[] sunSkyColors = new float[] { 0.5f, 0.7f, 1f };
		for (int i = 0; i < 3; i++) {
			clearColors[i] = addComponent(sunSkyColors[i] * (float) sunlightFactor, spaceColors[i]);
		}
		float lightness = clearColors[0] + clearColors[1] + clearColors[2];
		float[] sunRedColorsAdd = new float[] { 0.3f, 0.1f, 0.0f };
		for (int i = 0; i < 3; i++) {
			if (sunlightFactor < 0.5f && sunlightFactor > 0.0f) {
				float redFactor = (float) (1 - Math.abs(1 - sunlightFactor * 4));
				clearColors[i] = addComponent(clearColors[i], (float) sunRedColorsAdd[i] * redFactor);
			}
			clearColors[i] = mulComponent(clearColors[i], (float) sunlightFactor);
		}
		// fix lightness
		float newLightness = clearColors[0] + clearColors[1] + clearColors[2];
		for (int i = 0; i < 3; i++) {
			clearColors[i] = clearColors[i] * lightness / newLightness;
		}
		return clearColors;
	}

	public void tick() {
		updateGameTime();
		// earthCalendar.setTimeInMillis((long) gameTime * 1000);
		if (sunCalendar != null) {
			sunCalendar.setTimeInMillis((long) gameTime * 1000);
			sunCalendar.update();
			sunrise = Math.floor(sunCalendar.getSunrise() * 1000) / 1000;
			sunset = Math.floor(sunCalendar.getSunset() * 1000) / 1000;
			sunHA = sunCalendar.getHourAngle();
			sunEA = Math.floor(sunCalendar.getElevationAngle() * 1000) / 1000;
			sunTC = Math.floor(sunCalendar.getTimeCorrectionFactor() * 1000) / 1000;
		}
	}
}