VanaTime 1.2.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/Manifest +4 -0
- data/README +78 -21
- data/VanaTime.gemspec +5 -5
- data/lib/Vana/common.rb +86 -0
- data/lib/Vana/constants.rb +4 -0
- data/lib/Vana/day.rb +28 -26
- data/lib/Vana/element.rb +49 -0
- data/lib/Vana/moon.rb +88 -71
- data/lib/Vana/moon_countdown.rb +67 -0
- data/lib/Vana/time.rb +67 -53
- data/lib/Vana/time_manager.rb +82 -0
- data/lib/vana_time.rb +7 -1
- metadata +43 -32
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
VanaTime
|
1
|
+
VanaTime 2.0.0 README
|
2
2
|
=====================
|
3
3
|
|
4
|
-
This document was last updated on
|
4
|
+
This document was last updated on Sat Sep 8 13:41:50 EDT 2007.
|
5
5
|
|
6
6
|
|
7
7
|
Introduction to VanaTime
|
@@ -16,14 +16,48 @@ VanaTime is a work in progress and the API may change from time to time...
|
|
16
16
|
you may want to use explicit versioning in any code depending on it.
|
17
17
|
|
18
18
|
|
19
|
+
FFXI::TimeManager
|
20
|
+
=================
|
21
|
+
|
22
|
+
This will probably be the only class you end up using. It wraps everything
|
23
|
+
else up in a convenient callback system that keeps things in sync, only
|
24
|
+
does updates when necessary, and fires off your code on events. Huzzah! Here's
|
25
|
+
a quick example text clock:
|
26
|
+
|
27
|
+
include FFXI::Constants
|
28
|
+
tm = FFXI::TimeManager.now
|
29
|
+
tm.callback(MS_SECOND) {|time| puts "Vana'diel Time: #{time}" }
|
30
|
+
loop {tm.earth_time=(Time.now) ; sleep 0.04}
|
31
|
+
|
32
|
+
If you want to manage existing VanaTime, VanaDay, and VanaMoon objects you
|
33
|
+
can create a blank TimeManager and call manage on them:
|
34
|
+
|
35
|
+
tm = FFXI::TimeManager.new
|
36
|
+
tm.manage(time, day, moon)
|
37
|
+
|
38
|
+
The following are the supported events for adding callbacks:
|
39
|
+
|
40
|
+
MS_SECOND
|
41
|
+
MS_MINUTE
|
42
|
+
MS_HOUR
|
43
|
+
MS_DAY
|
44
|
+
MS_MONTH
|
45
|
+
MS_YEAR
|
46
|
+
day (of the week, fires off seperately from MS_DAY)
|
47
|
+
moon_days
|
48
|
+
moon_percent
|
49
|
+
moon_phase
|
50
|
+
next_optimal_phase
|
51
|
+
next_phase_countdown
|
52
|
+
optimal_phase_countdown
|
53
|
+
|
19
54
|
FFXI::VanaTime API
|
20
55
|
==================
|
21
56
|
|
22
57
|
* new(Time)
|
23
|
-
accepts a Time object to initialize a new VanaTime
|
24
|
-
time if no Time object is passed
|
58
|
+
accepts a Time object to initialize a new VanaTime
|
25
59
|
* now
|
26
|
-
|
60
|
+
calls new with Time.now
|
27
61
|
* at(VanaTime)
|
28
62
|
accepts a VanaTime object, int, or float representing vana time to
|
29
63
|
initialize a new VanaTime object
|
@@ -38,20 +72,26 @@ FFXI::VanaTime API
|
|
38
72
|
returns a float with the internal representation of vana time without
|
39
73
|
losing any accuracy
|
40
74
|
* year
|
75
|
+
* year_start
|
41
76
|
* month
|
77
|
+
* month_start
|
42
78
|
* date
|
79
|
+
* date_start
|
80
|
+
* tomorrow
|
43
81
|
* hour
|
82
|
+
* hour_start
|
44
83
|
* minute
|
84
|
+
* minute_start
|
45
85
|
* second
|
86
|
+
* second_start
|
46
87
|
these methods return various times, what we're interested in
|
47
88
|
* to_s
|
48
89
|
returns a string in the format:
|
49
90
|
YYYY-MM-DD hh:mm:ss
|
50
|
-
*
|
51
|
-
returns
|
52
|
-
*
|
53
|
-
returns
|
54
|
-
|
91
|
+
* time_string
|
92
|
+
returns just the time portion of to_s
|
93
|
+
* date_string
|
94
|
+
returns just the date portion of to_s
|
55
95
|
|
56
96
|
FFXI::VanaDay API
|
57
97
|
=================
|
@@ -65,19 +105,32 @@ FFXI::VanaDay API
|
|
65
105
|
returns a base zero number representing the day of the week
|
66
106
|
* to_s
|
67
107
|
returns the name of the day of the week
|
68
|
-
*
|
69
|
-
returns the
|
70
|
-
*
|
71
|
-
returns
|
72
|
-
*
|
73
|
-
returns
|
108
|
+
* to_html
|
109
|
+
returns the day's name in a font tag with the day's color
|
110
|
+
* element
|
111
|
+
returns an Element object with the current day's element
|
112
|
+
* weakness
|
113
|
+
returns an Element object with the current day's elemental weakness
|
114
|
+
|
115
|
+
FFXI::ElementFactory::Element
|
116
|
+
=============================
|
74
117
|
|
118
|
+
* name
|
119
|
+
* strength
|
120
|
+
* weakness
|
121
|
+
* color
|
122
|
+
* enfeeble
|
123
|
+
* attribute
|
124
|
+
* ninjutsu
|
125
|
+
* avatar
|
75
126
|
|
76
127
|
FFXI::VanaMoon API
|
77
128
|
==================
|
78
129
|
|
79
130
|
* new(Time)
|
80
|
-
Unlike VanaDay, VanaMoon is initialized with
|
131
|
+
Unlike VanaDay, VanaMoon is initialized with earth time
|
132
|
+
* now
|
133
|
+
calls new with the current time
|
81
134
|
* to_i
|
82
135
|
returns a number representing the exact position along the progression
|
83
136
|
of moon phases
|
@@ -87,17 +140,21 @@ FFXI::VanaMoon API
|
|
87
140
|
returns the name of the current moon phase
|
88
141
|
* to_s
|
89
142
|
returns a string in the format: moon_percent.abs phase_name
|
143
|
+
* next_phase
|
144
|
+
returns the name of the next moon phase
|
145
|
+
* optimal_phase
|
146
|
+
returns the name of the next optimal moon phase
|
147
|
+
|
148
|
+
FFXI::VanaMoonCountdown API
|
149
|
+
===========================
|
150
|
+
|
90
151
|
* to_next_array
|
91
152
|
returns an array containing the days, hours, minutes, and seconds until
|
92
153
|
the next moon phase
|
93
154
|
* to_next
|
94
155
|
returns a formatted countdown until the next moon phase
|
95
|
-
* next_phase
|
96
|
-
returns the name of the next moon phase
|
97
156
|
* to_optimal_array
|
98
157
|
returns an array containing the days, hours, minutes, and seconds until
|
99
158
|
the next optimal moon phase
|
100
159
|
* to_optimal
|
101
160
|
returns a formatted countdown until the next optimal moon phase
|
102
|
-
* optimal_phase
|
103
|
-
returns the name of the next optimal moon phase
|
data/VanaTime.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Vanatime-
|
2
|
+
# Gem::Specification for Vanatime-2.0.0
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{VanaTime}
|
7
|
-
s.version = "
|
8
|
-
s.date = %q{2007-09-
|
7
|
+
s.version = "2.0.0"
|
8
|
+
s.date = %q{2007-09-08}
|
9
9
|
s.summary = %q{A library for converting realtime to vanadiel time}
|
10
10
|
s.email = %q{ttilley@gmail.com}
|
11
11
|
s.homepage = %q{http://vanatime.rubyforge.org/}
|
@@ -13,13 +13,13 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = %q{A library for converting realtime to vanadiel time}
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.authors = ["Travis Tilley"]
|
16
|
-
s.files = ["README", "Manifest", "LICENSE", "lib/vana_time.rb", "lib/Vana/time.rb", "lib/Vana/moon.rb", "lib/Vana/day.rb", "lib/Vana/constants.rb", "CHANGELOG", "VanaTime.gemspec"]
|
16
|
+
s.files = ["README", "Manifest", "LICENSE", "lib/vana_time.rb", "lib/Vana/time_manager.rb", "lib/Vana/time.rb", "lib/Vana/moon_countdown.rb", "lib/Vana/moon.rb", "lib/Vana/element.rb", "lib/Vana/day.rb", "lib/Vana/constants.rb", "lib/Vana/common.rb", "CHANGELOG", "VanaTime.gemspec"]
|
17
17
|
end
|
18
18
|
|
19
19
|
|
20
20
|
# # Original Rakefile source (requires the Echoe gem):
|
21
21
|
#
|
22
|
-
# version = "
|
22
|
+
# version = "2.0.0"
|
23
23
|
#
|
24
24
|
# ENV['RUBY_FLAGS'] = ""
|
25
25
|
#
|
data/lib/Vana/common.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module FFXI
|
2
|
+
module Common
|
3
|
+
include FFXI::Constants
|
4
|
+
|
5
|
+
def self.vana_to_earth(vana_time)
|
6
|
+
(((vana_time.to_f - ((898 * 360 + 30) * MS_DAY.to_f)) / 25) +
|
7
|
+
MS_BASIS_DATE.to_f) / MS_SECOND
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.earth_to_vana(earth_time)
|
11
|
+
((898 * 360 + 30) * MS_DAY) + ((earth_time.to_f * MS_SECOND) -
|
12
|
+
MS_BASIS_DATE) * 25
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def start_of_period(vana_time, period)
|
18
|
+
vana_time.to_f - (vana_time.to_f % period )
|
19
|
+
end
|
20
|
+
|
21
|
+
def end_of_period(vana_time, period)
|
22
|
+
start_of_period(vana_time, period) + period
|
23
|
+
end
|
24
|
+
|
25
|
+
def period_has_passed_since(period, since, vana_time)
|
26
|
+
if since.nil?
|
27
|
+
true
|
28
|
+
else
|
29
|
+
elapsed = vana_time.to_f - since.to_f
|
30
|
+
|
31
|
+
if elapsed < 0
|
32
|
+
# if we're going -back- in time, we need to measure from the END of
|
33
|
+
# the period instead of the start.
|
34
|
+
elapsed = (since.to_f + period) - vana_time.to_f
|
35
|
+
end
|
36
|
+
|
37
|
+
elapsed >= period
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def second_has_passed_since(since, vana_time)
|
42
|
+
period_has_passed_since(MS_SECOND, since, vana_time)
|
43
|
+
end
|
44
|
+
|
45
|
+
def minute_has_passed_since(since, vana_time)
|
46
|
+
period_has_passed_since(MS_MINUTE, since, vana_time)
|
47
|
+
end
|
48
|
+
|
49
|
+
def hour_has_passed_since(since, vana_time)
|
50
|
+
period_has_passed_since(MS_HOUR, since, vana_time)
|
51
|
+
end
|
52
|
+
|
53
|
+
def day_has_passed_since(since, vana_time)
|
54
|
+
period_has_passed_since(MS_DAY, since, vana_time)
|
55
|
+
end
|
56
|
+
|
57
|
+
def month_has_passed_since(since, vana_time)
|
58
|
+
period_has_passed_since(MS_MONTH, since, vana_time)
|
59
|
+
end
|
60
|
+
|
61
|
+
def year_has_passed_since(since, vana_time)
|
62
|
+
period_has_passed_since(MS_YEAR, since, vana_time)
|
63
|
+
end
|
64
|
+
|
65
|
+
def countdown(time)
|
66
|
+
day_left = time.to_f / MS_DAY
|
67
|
+
hour_left = (day_left.to_f - day_left.floor) * 24
|
68
|
+
min_left = (hour_left.to_f - hour_left.floor) * 60
|
69
|
+
sec_left = (min_left.to_f - min_left.floor) * 60
|
70
|
+
|
71
|
+
[day_left.floor, hour_left.floor, min_left.floor, sec_left.floor]
|
72
|
+
end
|
73
|
+
|
74
|
+
def format_countdown(countdown)
|
75
|
+
formatted = String.new
|
76
|
+
countdown[0..2].each do |part|
|
77
|
+
if (part > 0)
|
78
|
+
formatted += "%02d" % part
|
79
|
+
formatted += ":"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
formatted += "%02d" % countdown[3]
|
83
|
+
formatted
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/Vana/constants.rb
CHANGED
@@ -30,6 +30,10 @@ module FFXI
|
|
30
30
|
MS_HOUR = HOUR * MS_SECOND
|
31
31
|
MS_MINUTE = MINUTE * MS_SECOND
|
32
32
|
|
33
|
+
# correct for the game time calculations anyways
|
34
|
+
MS_MONTH = 30 * MS_DAY
|
35
|
+
MS_YEAR = 360 * MS_DAY
|
36
|
+
|
33
37
|
MS_GAME_DAY = (MS_DAY / 25)
|
34
38
|
|
35
39
|
BASIS_DATE = Time.utc(2002,6,23,15,0,0,0)
|
data/lib/Vana/day.rb
CHANGED
@@ -1,52 +1,54 @@
|
|
1
1
|
module FFXI
|
2
2
|
class VanaDay
|
3
3
|
include FFXI::Constants
|
4
|
+
include Observable
|
4
5
|
|
5
6
|
VANA_DAYS = ["Firesday", "Earthsday", "Watersday", "Windsday", "Iceday",
|
6
7
|
"Lightningday", "Lightsday", "Darksday"]
|
7
|
-
|
8
|
-
|
9
|
-
"Darkness", "Light"]
|
8
|
+
DAY_ELEMENTS = ["Fire", "Earth", "Water", "Wind", "Ice", "Thunder",
|
9
|
+
"Light", "Darkness"]
|
10
10
|
|
11
11
|
def initialize(vana_time=VanaTime.now)
|
12
|
-
self.vana_time = vana_time
|
12
|
+
self.vana_time = vana_time.to_f
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@vana_time = vana_time
|
15
|
+
def vana_time=(vt)
|
16
|
+
if vt != @vana_time
|
17
|
+
@vana_time = vt
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
if @vana_day.nil?
|
23
|
-
@vana_day = vana_day
|
24
|
-
elsif @vana_day != vana_day
|
25
|
-
@vana_day = vana_day
|
26
|
-
@vana_day_start = nil
|
27
|
-
@vana_day_tomorrow = nil
|
19
|
+
set_day
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
23
|
+
attr_reader :element, :weakness
|
24
|
+
attr_reader :vana_time
|
25
|
+
|
31
26
|
def to_i
|
32
|
-
@
|
27
|
+
@day.to_i
|
33
28
|
end
|
34
29
|
|
35
30
|
def to_s
|
36
|
-
VANA_DAYS[@
|
31
|
+
VANA_DAYS[@day]
|
37
32
|
end
|
38
33
|
|
39
|
-
def
|
40
|
-
|
34
|
+
def to_html
|
35
|
+
"<b><font color=\"#{@element.color}\">#{VANA_DAYS[@day]}</font></b>"
|
41
36
|
end
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
38
|
+
private
|
39
|
+
|
40
|
+
def set_day
|
41
|
+
day = (@vana_time.to_f % (8 * MS_DAY)) / (MS_DAY)
|
42
|
+
|
43
|
+
if day != @day
|
44
|
+
@day = day
|
45
|
+
@element = FFXI::ElementFactory.send DAY_ELEMENTS[@day]
|
46
|
+
@weakness = FFXI::ElementFactory.send(@element.weakness)
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
changed
|
49
|
+
notify_observers("day", self)
|
50
|
+
end
|
50
51
|
end
|
52
|
+
|
51
53
|
end
|
52
54
|
end
|
data/lib/Vana/element.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module FFXI
|
2
|
+
module ElementFactory
|
3
|
+
Element = Struct.new(:name, :strength, :weakness, :color, :enfeeble,
|
4
|
+
:attribute, :ninjutsu, :avatar)
|
5
|
+
|
6
|
+
ELEMENTS = ["Fire", "Ice", "Wind", "Earth", "Thunder", "Water"]
|
7
|
+
ELEMENT_COLORS = ["red", "aqua", "green", "yellow", "purple", "blue"]
|
8
|
+
ELEMENT_ENFEEBLE = ["Burn", "Frost", "Choke", "Rasp", "Shock", "Drown"]
|
9
|
+
ELEMENT_ATTRIBUTE = ["STR", "INT", "AGI", "VIT", "DEX", "MND"]
|
10
|
+
ELEMENT_NINJUTSU = ["Katon", "Hyoton", "Huton", "Doton", "Raiton", "Suiton"]
|
11
|
+
ELEMENT_AVATAR = ["Ifrit", "Shiva", "Garuda", "Titan", "Ramuh", "Leviathan"]
|
12
|
+
|
13
|
+
SPECIAL_ELEMENTS = ["Light", "Darkness"]
|
14
|
+
SPECIAL_ELEMENT_COLORS = ["gray", "black"]
|
15
|
+
SPECIAL_ELEMENT_ENFEEBLE = ["Dia", "Bio"]
|
16
|
+
SPECIAL_ELEMENT_ATTRIBUTE = ["CHR", nil]
|
17
|
+
SPECIAL_ELEMENT_AVATAR = ["Carbuncle", ["Fenrir", "Diabolos"]]
|
18
|
+
|
19
|
+
def self.method_missing(name, *args)
|
20
|
+
element = name.to_s.capitalize
|
21
|
+
|
22
|
+
if SPECIAL_ELEMENTS.include? element
|
23
|
+
index = SPECIAL_ELEMENTS.index element
|
24
|
+
opposed = SPECIAL_ELEMENTS[(index - 1) % 2]
|
25
|
+
color = SPECIAL_ELEMENT_COLORS[index]
|
26
|
+
enfeeble = SPECIAL_ELEMENT_ENFEEBLE[index]
|
27
|
+
attribute = SPECIAL_ELEMENT_ATTRIBUTE[index]
|
28
|
+
avatar = SPECIAL_ELEMENT_AVATAR[index]
|
29
|
+
|
30
|
+
Element.new(element, opposed, opposed, color, enfeeble, attribute, nil,
|
31
|
+
avatar)
|
32
|
+
elsif ELEMENTS.include? element
|
33
|
+
index = ELEMENTS.index element
|
34
|
+
weakness = ELEMENTS[(index - 1) % 6]
|
35
|
+
strength = ELEMENTS[(index + 1) % 6]
|
36
|
+
color = ELEMENT_COLORS[index]
|
37
|
+
enfeeble = ELEMENT_ENFEEBLE[index]
|
38
|
+
attribute = ELEMENT_ATTRIBUTE[index]
|
39
|
+
ninjutsu = ELEMENT_NINJUTSU[index]
|
40
|
+
avatar = ELEMENT_AVATAR[index]
|
41
|
+
|
42
|
+
Element.new(element, strength, weakness, color, enfeeble, attribute,
|
43
|
+
ninjutsu, avatar)
|
44
|
+
else
|
45
|
+
raise "Unknown element"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/Vana/moon.rb
CHANGED
@@ -1,17 +1,88 @@
|
|
1
1
|
module FFXI
|
2
2
|
class VanaMoon
|
3
3
|
include FFXI::Constants
|
4
|
+
include FFXI::Common
|
5
|
+
include Observable
|
4
6
|
|
5
7
|
MOON_PHASES = ["Full", "Waning Gibbous", "Last Quarter", "Waning Crescent",
|
6
8
|
"New Moon", "Waxing Crescent", "First Quarter", "Waxing Gibbous"]
|
7
9
|
|
8
|
-
def initialize(time =
|
9
|
-
|
10
|
+
def initialize(time = nil)
|
11
|
+
self.earth_time = time if ! time.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.now
|
15
|
+
self.new(Time.now)
|
16
|
+
end
|
17
|
+
|
18
|
+
def earth_time=(time)
|
19
|
+
raise "Input needs to be a Time object" if ! time.is_a? Time
|
20
|
+
if time != @earth_time
|
21
|
+
@earth_time = time
|
22
|
+
|
23
|
+
set_moon_days
|
24
|
+
set_percent
|
25
|
+
set_phase
|
26
|
+
set_optimal
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :moon_days, :next_phase_target, :optimal_phase_target
|
31
|
+
attr_reader :earth_time
|
32
|
+
|
33
|
+
def to_i
|
34
|
+
@moon_percent
|
35
|
+
end
|
36
|
+
|
37
|
+
def percent
|
38
|
+
"#{@moon_percent.abs}%"
|
39
|
+
end
|
40
|
+
|
41
|
+
def phase
|
42
|
+
MOON_PHASES[@moon_phase]
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
"#{percent} #{phase}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def next_phase
|
50
|
+
MOON_PHASES[(@moon_phase + 1) % 8]
|
51
|
+
end
|
52
|
+
|
53
|
+
def optimal_phase
|
54
|
+
MOON_PHASES[@next_optimal_phase]
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def set_moon_days
|
60
|
+
old_moon_days = @moon_days
|
61
|
+
|
10
62
|
# Each lunar cycle takes exactly 84 game days
|
11
63
|
# (3 days, 8 hours, 38 minutes, 24 seconds)
|
12
|
-
@moon_days = ((
|
64
|
+
@moon_days = (((@earth_time.to_f * 1000).to_i -
|
65
|
+
MS_MOON_DATE.to_i) / MS_GAME_DAY).floor % 84
|
66
|
+
|
67
|
+
if @moon_days != old_moon_days
|
68
|
+
changed
|
69
|
+
notify_observers("moon_days", self)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_percent
|
74
|
+
old_moon_percent = @moon_percent
|
75
|
+
|
13
76
|
@moon_percent = - ((42 - @moon_days).to_f / 42 * 100).round
|
14
|
-
|
77
|
+
|
78
|
+
if @moon_percent != old_moon_percent
|
79
|
+
changed
|
80
|
+
notify_observers("moon_percent", self)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_phase
|
85
|
+
old_phase = @moon_phase
|
15
86
|
|
16
87
|
case @moon_percent
|
17
88
|
when (-100..-94)
|
@@ -43,6 +114,15 @@ module FFXI
|
|
43
114
|
@next_phase_target = 80
|
44
115
|
end
|
45
116
|
|
117
|
+
if @moon_phase != old_phase
|
118
|
+
changed
|
119
|
+
notify_observers("moon_phase", self)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_optimal
|
124
|
+
old_optimal = @next_optimal_phase
|
125
|
+
|
46
126
|
case @moon_phase
|
47
127
|
when (0..3)
|
48
128
|
@next_optimal_phase = 4
|
@@ -52,75 +132,12 @@ module FFXI
|
|
52
132
|
@next_optimal_phase = 0
|
53
133
|
@optimal_phase_target = 80
|
54
134
|
end
|
55
|
-
end
|
56
|
-
|
57
|
-
attr_reader :elapsed_time, :moon_days
|
58
|
-
|
59
|
-
def to_i
|
60
|
-
@moon_percent
|
61
|
-
end
|
62
|
-
|
63
|
-
def percent
|
64
|
-
"#{@moon_percent.abs}%"
|
65
|
-
end
|
66
|
-
|
67
|
-
def phase
|
68
|
-
MOON_PHASES[@moon_phase]
|
69
|
-
end
|
70
|
-
|
71
|
-
def to_s
|
72
|
-
"#{percent} #{phase}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def to_next_array
|
76
|
-
countdown_to(@next_phase_target)
|
77
|
-
end
|
78
135
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
def next_phase
|
84
|
-
MOON_PHASES[(@moon_phase + 1) % 8]
|
85
|
-
end
|
86
|
-
|
87
|
-
def to_optimal_array
|
88
|
-
countdown_to(@optimal_phase_target)
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_optimal
|
92
|
-
format_countdown(to_optimal_array)
|
93
|
-
end
|
94
|
-
|
95
|
-
def optimal_phase
|
96
|
-
MOON_PHASES[@next_optimal_phase]
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
|
-
def countdown(time)
|
102
|
-
day_left = time.to_f / MS_DAY
|
103
|
-
hour_left = (day_left.to_f - day_left.floor) * 24
|
104
|
-
min_left = (hour_left.to_f - hour_left.floor) * 60
|
105
|
-
sec_left = (min_left.to_f - min_left.floor) * 60
|
106
|
-
|
107
|
-
[day_left.floor, hour_left.floor, min_left.floor, sec_left.floor]
|
108
|
-
end
|
109
|
-
|
110
|
-
def countdown_to(target)
|
111
|
-
countdown((target - @moon_days) * MS_GAME_DAY - @elapsed_time)
|
112
|
-
end
|
113
|
-
|
114
|
-
def format_countdown(countdown)
|
115
|
-
formatted = String.new
|
116
|
-
countdown[0..2].each do |part|
|
117
|
-
if (part > 0)
|
118
|
-
formatted += "%02d" % part
|
119
|
-
formatted += ":"
|
120
|
-
end
|
136
|
+
if @next_optimal_phase != old_optimal
|
137
|
+
changed
|
138
|
+
notify_observers("next_optimal_phase", self)
|
121
139
|
end
|
122
|
-
formatted += "%02d" % countdown[3]
|
123
|
-
formatted
|
124
140
|
end
|
141
|
+
|
125
142
|
end
|
126
143
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module FFXI
|
2
|
+
class VanaMoonCountdown
|
3
|
+
include FFXI::Constants
|
4
|
+
include FFXI::Common
|
5
|
+
include Observable
|
6
|
+
|
7
|
+
def initialize(moon)
|
8
|
+
self.moon = moon
|
9
|
+
end
|
10
|
+
|
11
|
+
def moon=(moon)
|
12
|
+
raise "Input needs to be a VanaMoon object" if ! moon.is_a? VanaMoon
|
13
|
+
@moon = moon
|
14
|
+
if @moon.earth_time != @earth_time
|
15
|
+
self.earth_time = @moon.earth_time
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def earth_time=(earth_time)
|
20
|
+
raise "Input needs to be a Time object" if ! earth_time.is_a? Time
|
21
|
+
|
22
|
+
if earth_time != @earth_time
|
23
|
+
@earth_time = earth_time
|
24
|
+
localtime = (@earth_time.to_f * 1000).to_i
|
25
|
+
@elapsed_time = (localtime - MS_MOON_DATE.to_i) % MS_GAME_DAY
|
26
|
+
|
27
|
+
set_countdowns
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :to_next_array, :to_optimal_array
|
32
|
+
attr_reader :elapsed_time, :earth_time
|
33
|
+
|
34
|
+
def to_next
|
35
|
+
format_countdown(@to_next_array)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_optimal
|
39
|
+
format_countdown(@to_optimal_array)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def set_countdowns
|
45
|
+
to_next_array = countdown_to(@moon.next_phase_target)
|
46
|
+
|
47
|
+
if to_next_array != @to_next_array
|
48
|
+
@to_next_array = to_next_array
|
49
|
+
changed
|
50
|
+
notify_observers("next_phase_countdown", self)
|
51
|
+
end
|
52
|
+
|
53
|
+
to_optimal_array = countdown_to(@moon.optimal_phase_target)
|
54
|
+
|
55
|
+
if to_optimal_array != @to_optimal_array
|
56
|
+
@to_optimal_array = to_optimal_array
|
57
|
+
changed
|
58
|
+
notify_observers("optimal_phase_countdown", self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def countdown_to(target)
|
63
|
+
countdown((target - @moon.moon_days) * MS_GAME_DAY - @elapsed_time)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/Vana/time.rb
CHANGED
@@ -1,50 +1,38 @@
|
|
1
1
|
module FFXI
|
2
2
|
class VanaTime
|
3
3
|
include FFXI::Constants
|
4
|
+
include FFXI::Common
|
5
|
+
include Observable
|
4
6
|
|
5
|
-
def initialize(time =
|
6
|
-
self.earth_time = time
|
7
|
+
def initialize(time = nil)
|
8
|
+
self.earth_time = time if ! time.nil?
|
7
9
|
end
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
if ! @vDay.nil?
|
13
|
-
@vDay.vana_time = @vana_time
|
14
|
-
end
|
11
|
+
def self.at(vt)
|
12
|
+
self.new(Time.at(FFXI::Common.vana_to_earth(vt)))
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
15
|
+
def self.now
|
16
|
+
self.new(Time.now)
|
18
17
|
end
|
19
18
|
|
20
19
|
def earth_time=(time)
|
21
20
|
raise "input needs to be a Time object" if ! time.is_a? Time
|
22
|
-
|
23
21
|
@earth_time = time
|
24
|
-
|
25
|
-
|
26
|
-
(ms_earth_time - MS_BASIS_DATE) * 25
|
27
|
-
|
28
|
-
update_instance_variables
|
22
|
+
vt = FFXI::Common.earth_to_vana(time)
|
23
|
+
set_instance_variables(vt)
|
29
24
|
end
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
(((vana_time.to_f - ((898 * 360 + 30) * MS_DAY.to_f)) / 25) +
|
35
|
-
MS_BASIS_DATE.to_f) / MS_SECOND
|
26
|
+
def vana_time=(vt)
|
27
|
+
@earth_time = Time.at(FFXI::Common.vana_to_earth(vt))
|
28
|
+
set_instance_variables(vt)
|
36
29
|
end
|
37
30
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.at(vana_time)
|
46
|
-
self.new(Time.at(self.vana_to_earth(vana_time)))
|
47
|
-
end
|
31
|
+
attr_reader :hour, :minute, :second
|
32
|
+
attr_reader :date, :month, :year, :tomorrow
|
33
|
+
attr_reader :hour_start, :minute_start, :second_start
|
34
|
+
attr_reader :date_start, :month_start, :year_start
|
35
|
+
attr_reader :vana_time, :earth_time
|
48
36
|
|
49
37
|
def to_i
|
50
38
|
@vana_time.to_i
|
@@ -54,46 +42,72 @@ module FFXI
|
|
54
42
|
@vana_time.to_f
|
55
43
|
end
|
56
44
|
|
57
|
-
def
|
58
|
-
|
45
|
+
def time_string
|
46
|
+
"#{"%02d" % hour}:#{"%02d" % minute}:#{"%02d" % second}"
|
59
47
|
end
|
60
48
|
|
61
|
-
def
|
62
|
-
|
49
|
+
def date_string
|
50
|
+
"#{year}-#{"%02d" % month}-#{"%02d" % date}"
|
63
51
|
end
|
64
52
|
|
65
|
-
def
|
66
|
-
|
53
|
+
def to_s
|
54
|
+
"#{date_string} #{time_string}"
|
67
55
|
end
|
68
56
|
|
69
|
-
|
70
|
-
|
71
|
-
|
57
|
+
private
|
58
|
+
|
59
|
+
def set_instance_variables(vt)
|
60
|
+
@vana_time = vt.to_f
|
72
61
|
|
73
|
-
|
74
|
-
|
62
|
+
set_year if year_has_passed_since(@year_start, @vana_time)
|
63
|
+
set_month if month_has_passed_since(@month_start, @vana_time)
|
64
|
+
set_date if day_has_passed_since(@date_start, @vana_time)
|
65
|
+
set_hour if hour_has_passed_since(@hour_start, @vana_time)
|
66
|
+
set_minute if minute_has_passed_since(@minute_start, @vana_time)
|
67
|
+
set_second if second_has_passed_since(@second_start, @vana_time)
|
75
68
|
end
|
76
69
|
|
77
|
-
def
|
78
|
-
@
|
70
|
+
def set_year
|
71
|
+
@year = (@vana_time.to_f / MS_YEAR).to_i
|
72
|
+
@year_start = start_of_period(@vana_time, MS_YEAR)
|
73
|
+
changed
|
74
|
+
notify_observers(MS_YEAR, self)
|
79
75
|
end
|
80
76
|
|
81
|
-
def
|
82
|
-
@
|
77
|
+
def set_month
|
78
|
+
@month = (((@vana_time.to_f % MS_YEAR) / MS_MONTH) + 1).to_i
|
79
|
+
@month_start = start_of_period(@vana_time, MS_MONTH)
|
80
|
+
changed
|
81
|
+
notify_observers(MS_MONTH, self)
|
83
82
|
end
|
84
83
|
|
85
|
-
def
|
86
|
-
@
|
84
|
+
def set_date
|
85
|
+
@date = (((@vana_time.to_f % MS_MONTH) / MS_DAY) + 1).to_i
|
86
|
+
@date_start = start_of_period(@vana_time, MS_DAY)
|
87
|
+
@tomorrow = @date_start.to_f + MS_DAY
|
88
|
+
changed
|
89
|
+
notify_observers(MS_DAY, self)
|
87
90
|
end
|
88
91
|
|
89
|
-
def
|
90
|
-
|
92
|
+
def set_hour
|
93
|
+
@hour = ((@vana_time % MS_DAY) / MS_HOUR).to_i
|
94
|
+
@hour_start = start_of_period(@vana_time, MS_HOUR)
|
95
|
+
changed
|
96
|
+
notify_observers(MS_HOUR, self)
|
91
97
|
end
|
92
98
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
99
|
+
def set_minute
|
100
|
+
@minute = ((@vana_time % MS_HOUR) / MS_MINUTE).to_i
|
101
|
+
@minute_start = start_of_period(@vana_time, MS_MINUTE)
|
102
|
+
changed
|
103
|
+
notify_observers(MS_MINUTE, self)
|
96
104
|
end
|
97
105
|
|
106
|
+
def set_second
|
107
|
+
@second = ((@vana_time % MS_MINUTE) / MS_SECOND).to_i
|
108
|
+
@second_start = start_of_period(@vana_time, MS_SECOND)
|
109
|
+
changed
|
110
|
+
notify_observers(MS_SECOND, self)
|
111
|
+
end
|
98
112
|
end
|
99
113
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module FFXI
|
2
|
+
class TimeManager
|
3
|
+
include FFXI::Constants
|
4
|
+
|
5
|
+
def initialize(earth_time=nil)
|
6
|
+
@callbacks = {}
|
7
|
+
setup(earth_time) if ! earth_time.nil?
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.now
|
11
|
+
self.new(Time.now)
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset
|
15
|
+
earth_time = @time.earth_time
|
16
|
+
setup(earth_time)
|
17
|
+
end
|
18
|
+
|
19
|
+
def manage(time, day, moon)
|
20
|
+
raise "time needs to be a VanaTime" if ! time.is_a? VanaTime
|
21
|
+
raise "day needs to be a VanaDay" if ! day.is_a? VanaDay
|
22
|
+
raise "moon needs to be a VanaMoon" if ! moon.is_a? VanaMoon
|
23
|
+
|
24
|
+
@time = time
|
25
|
+
@day = day
|
26
|
+
@moon = moon
|
27
|
+
@moon_countdown = VanaMoonCountdown.new(@moon)
|
28
|
+
|
29
|
+
observe
|
30
|
+
end
|
31
|
+
|
32
|
+
def earth_time=(earth_time)
|
33
|
+
raise "I don't have a VanaTime to update" if @time.nil?
|
34
|
+
raise "Input needs to be a Time object" if ! earth_time.is_a? Time
|
35
|
+
|
36
|
+
@time.earth_time=(earth_time)
|
37
|
+
end
|
38
|
+
|
39
|
+
def callback_proc(type, callback)
|
40
|
+
raise "callback needs to be a Proc/lambda" if ! callback.is_a? Proc
|
41
|
+
|
42
|
+
@callbacks[type] = [] if @callbacks[type].nil?
|
43
|
+
@callbacks[type] << callback
|
44
|
+
end
|
45
|
+
|
46
|
+
def callback(type, &block)
|
47
|
+
callback_proc(type, block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def update(type, updater)
|
51
|
+
case type
|
52
|
+
when MS_SECOND
|
53
|
+
@moon_countdown.earth_time = @time.earth_time
|
54
|
+
when MS_DAY
|
55
|
+
@day.vana_time = @time.to_f
|
56
|
+
@moon.earth_time = @time.earth_time
|
57
|
+
when "moon_days"
|
58
|
+
@moon_countdown.moon = @moon
|
59
|
+
end
|
60
|
+
|
61
|
+
@callbacks[type].each {|c| c.call(updater)} if ! @callbacks[type].nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def setup(time)
|
67
|
+
@time = VanaTime.new(time)
|
68
|
+
@day = VanaDay.new(@time.date_start)
|
69
|
+
@moon = VanaMoon.new(@time.earth_time)
|
70
|
+
@moon_countdown = VanaMoonCountdown.new(@moon)
|
71
|
+
|
72
|
+
observe
|
73
|
+
end
|
74
|
+
|
75
|
+
def observe
|
76
|
+
@time.add_observer(self)
|
77
|
+
@day.add_observer(self)
|
78
|
+
@moon.add_observer(self)
|
79
|
+
@moon_countdown.add_observer(self)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/vana_time.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
$:.unshift File.dirname(__FILE__)
|
2
2
|
|
3
|
+
require 'observer'
|
4
|
+
|
3
5
|
require 'Vana/constants'
|
6
|
+
require 'Vana/common'
|
7
|
+
require 'Vana/time'
|
8
|
+
require 'Vana/element'
|
4
9
|
require 'Vana/day'
|
5
10
|
require 'Vana/moon'
|
6
|
-
require 'Vana/
|
11
|
+
require 'Vana/moon_countdown'
|
12
|
+
require 'Vana/time_manager'
|
metadata
CHANGED
@@ -1,48 +1,59 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: VanaTime
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 2.0.0
|
7
|
+
date: 2007-09-08 00:00:00 -04:00
|
8
|
+
summary: A library for converting realtime to vanadiel time
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ttilley@gmail.com
|
2
12
|
homepage: http://vanatime.rubyforge.org/
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
13
|
+
rubyforge_project: vanatime
|
14
|
+
description: A library for converting realtime to vanadiel time
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
7
28
|
post_install_message:
|
8
|
-
|
29
|
+
authors:
|
30
|
+
- Travis Tilley
|
9
31
|
files:
|
10
32
|
- README
|
11
33
|
- Manifest
|
12
34
|
- LICENSE
|
13
35
|
- lib/vana_time.rb
|
36
|
+
- lib/Vana/time_manager.rb
|
14
37
|
- lib/Vana/time.rb
|
38
|
+
- lib/Vana/moon_countdown.rb
|
15
39
|
- lib/Vana/moon.rb
|
40
|
+
- lib/Vana/element.rb
|
16
41
|
- lib/Vana/day.rb
|
17
42
|
- lib/Vana/constants.rb
|
43
|
+
- lib/Vana/common.rb
|
18
44
|
- CHANGELOG
|
19
45
|
- VanaTime.gemspec
|
20
|
-
rubygems_version: 0.9.4
|
21
|
-
rdoc_options: []
|
22
|
-
signing_key:
|
23
|
-
cert_chain:
|
24
|
-
name: VanaTime
|
25
|
-
has_rdoc: true
|
26
|
-
platform: ruby
|
27
|
-
summary: A library for converting realtime to vanadiel time
|
28
|
-
default_executable:
|
29
|
-
bindir: bin
|
30
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
31
|
-
version:
|
32
|
-
requirements:
|
33
|
-
- - '>'
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: 0.0.0
|
36
|
-
require_paths:
|
37
|
-
- lib
|
38
|
-
specification_version: 1
|
39
46
|
test_files: []
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
- Travis Tilley
|
44
|
-
email: ttilley@gmail.com
|
47
|
+
|
48
|
+
rdoc_options: []
|
49
|
+
|
45
50
|
extra_rdoc_files: []
|
51
|
+
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
46
56
|
requirements: []
|
47
|
-
|
48
|
-
|
57
|
+
|
58
|
+
dependencies: []
|
59
|
+
|