VanaTime 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,36 +11,35 @@
11
11
  # minutes to an hour. I don't know who originally discovered the following, but,
12
12
  # the following information can be used to set an "epoch" for Vana'diel time
13
13
  # compared to Earth time:
14
-
14
+ #
15
15
  # Earth time: 2002/06/23 15:00:00 GMT
16
16
  # Vana'diel time: 0898/02/01 00:00:00
17
-
17
+ #
18
18
  # Using that, you can take any given Earth time, subtract the starting Earth
19
19
  # date to set time to "0", and then multiply that by 25 to convert to Vana'diel
20
20
  # time.
21
-
22
21
  module FFXI
23
- module Constants
24
- MINUTE = 60
25
- HOUR = MINUTE * 60
26
- DAY = HOUR * 24
22
+ module Constants
23
+ MINUTE = 60
24
+ HOUR = MINUTE * 60
25
+ DAY = HOUR * 24
27
26
 
28
- MS_SECOND = 1000
29
- MS_DAY = DAY * MS_SECOND
30
- MS_HOUR = HOUR * MS_SECOND
31
- MS_MINUTE = MINUTE * MS_SECOND
27
+ MS_SECOND = 1000
28
+ MS_DAY = DAY * MS_SECOND
29
+ MS_HOUR = HOUR * MS_SECOND
30
+ MS_MINUTE = MINUTE * MS_SECOND
32
31
 
33
- # correct for the game time calculations anyways
34
- MS_MONTH = 30 * MS_DAY
35
- MS_YEAR = 360 * MS_DAY
32
+ # correct for the game time calculations anyways
33
+ MS_MONTH = 30 * MS_DAY
34
+ MS_YEAR = 360 * MS_DAY
36
35
 
37
- MS_GAME_DAY = (MS_DAY / 25)
36
+ MS_GAME_DAY = (MS_DAY / 25)
38
37
 
39
- BASIS_DATE = Time.utc(2002,6,23,15,0,0,0)
40
- MOON_DATE = Time.utc(2004,1,25,2,31,12,0)
38
+ BASIS_DATE = Time.utc(2002,6,23,15,0,0,0)
39
+ MOON_DATE = Time.utc(2004,1,25,2,31,12,0)
41
40
 
42
- MS_BASIS_VANA = ((898 * 360 + 30) * MS_DAY).to_f
43
- MS_BASIS_DATE = BASIS_DATE.to_f * MS_SECOND
44
- MS_MOON_DATE = MOON_DATE.to_f * MS_SECOND
45
- end
41
+ MS_BASIS_VANA = ((898 * 360 + 30) * MS_DAY).to_f
42
+ MS_BASIS_DATE = BASIS_DATE.to_f * MS_SECOND
43
+ MS_MOON_DATE = MOON_DATE.to_f * MS_SECOND
44
+ end
46
45
  end
@@ -1,54 +1,57 @@
1
1
  module FFXI
2
- class VanaDay
3
- include FFXI::Constants
4
- include Observable
5
-
6
- VANA_DAYS = ["Firesday", "Earthsday", "Watersday", "Windsday", "Iceday",
7
- "Lightningday", "Lightsday", "Darksday"]
8
- DAY_ELEMENTS = ["Fire", "Earth", "Water", "Wind", "Ice", "Thunder",
9
- "Light", "Darkness"]
10
-
11
- def initialize(vana_time=VanaTime.now)
12
- self.vana_time = vana_time.to_f
13
- end
14
-
15
- def vana_time=(vt)
16
- if vt != @vana_time
17
- @vana_time = vt
18
-
19
- set_day
20
- end
21
- end
22
-
23
- attr_reader :element, :weakness
24
- attr_reader :vana_time
25
-
26
- def to_i
27
- @day.to_i
28
- end
2
+ class VanaDay < Util::RubyBean
3
+ include FFXI::Constants
4
+
5
+ VANA_DAYS = ["Firesday", "Earthsday", "Watersday", "Windsday", "Iceday",
6
+ "Lightningday", "Lightsday", "Darksday"]
7
+ DAY_ELEMENTS = ["Fire", "Earth", "Water", "Wind", "Ice", "Thunder",
8
+ "Light", "Darkness"]
9
+
10
+ property :day, :day_element, :day_weakness, :day_strength
11
+ property :day_string, :day_html
12
+
13
+ alias element day_element
14
+ alias weakness day_weakness
15
+ alias strength day_strength
16
+ alias to_s day_string
17
+ alias to_html day_html
18
+
19
+ def initialize(opts={})
20
+ super()
21
+ add_listener(opts[:listener]) if opts[:listener]
22
+ update_vana_time opts[:vana_time] if opts[:vana_time]
23
+ end
29
24
 
30
- def to_s
31
- VANA_DAYS[@day]
32
- end
25
+ def update_vana_time(vt)
26
+ @vana_time = vt.to_f
27
+ set_day
28
+ end
33
29
 
34
- def to_html
35
- "<b><font color=\"#{@element.color}\">#{VANA_DAYS[@day]}</font></b>"
36
- end
30
+ def update_earth_time(time)
31
+ update_vana_time FFXI::Common.earth_to_vana(time)
32
+ end
37
33
 
38
- private
34
+ attr_reader :vana_time
39
35
 
40
- def set_day
41
- day = (@vana_time.to_f % (8 * MS_DAY)) / (MS_DAY)
36
+ def to_i
37
+ day.to_i
38
+ end
42
39
 
43
- if day != @day
44
- @day = day
45
- @element = FFXI::ElementFactory.send DAY_ELEMENTS[@day]
46
- @weakness = FFXI::ElementFactory.send(@element.weakness)
40
+ def to_f
41
+ day.to_f
42
+ end
47
43
 
48
- changed
49
- notify_observers("day", self)
50
- end
51
- end
44
+ private
52
45
 
46
+ def set_day
47
+ self.day = (@vana_time.to_f % (8 * MS_DAY)) / (MS_DAY)
48
+ self.day_element = FFXI::ElementFactory.send DAY_ELEMENTS[day]
49
+ self.day_weakness = FFXI::ElementFactory.send(day_element.weakness)
50
+ self.day_strength = FFXI::ElementFactory.send(day_element.strength)
51
+ self.day_string = VANA_DAYS[day]
52
+ self.day_html =
53
+ "<b><font color=\"#{day_element.color}\">#{VANA_DAYS[day]}</font></b>"
53
54
  end
55
+
56
+ end
54
57
  end
@@ -1,49 +1,54 @@
1
1
  module FFXI
2
- module ElementFactory
3
- Element = Struct.new(:name, :strength, :weakness, :color, :enfeeble,
4
- :attribute, :ninjutsu, :avatar)
2
+ module ElementFactory
3
+ Element = Struct.new(:name, :direction, :strength, :weakness, :color,
4
+ :enfeeble, :attribute, :ninjutsu, :avatar)
5
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"]
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
+ ELEMENT_DIRECTION = ["North-West", "East", "South-East", "South",
13
+ "South-West", "West"]
12
14
 
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"]]
15
+ SPECIAL_ELEMENTS = ["Light", "Darkness"]
16
+ SPECIAL_ELEMENT_COLORS = ["gray", "black"]
17
+ SPECIAL_ELEMENT_ENFEEBLE = ["Dia", "Bio"]
18
+ SPECIAL_ELEMENT_ATTRIBUTE = ["CHR", nil]
19
+ SPECIAL_ELEMENT_AVATAR = ["Carbuncle", ["Fenrir", "Diabolos"]]
20
+ SPECIAL_ELEMENT_DIRECTION = ["North-East", "North"]
18
21
 
19
- def self.method_missing(name, *args)
20
- element = name.to_s.capitalize
22
+ def self.method_missing(name, *args)
23
+ element = name.to_s.capitalize
21
24
 
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]
25
+ if SPECIAL_ELEMENTS.include? element
26
+ index = SPECIAL_ELEMENTS.index element
27
+ direction = SPECIAL_ELEMENTS_DIRECTION[index]
28
+ opposed = SPECIAL_ELEMENTS[(index - 1) % 2]
29
+ color = SPECIAL_ELEMENT_COLORS[index]
30
+ enfeeble = SPECIAL_ELEMENT_ENFEEBLE[index]
31
+ attribute = SPECIAL_ELEMENT_ATTRIBUTE[index]
32
+ avatar = SPECIAL_ELEMENT_AVATAR[index]
29
33
 
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]
34
+ Element.new(element, direction, opposed, opposed, color, enfeeble,
35
+ attribute, nil, avatar)
36
+ elsif ELEMENTS.include? element
37
+ index = ELEMENTS.index element
38
+ direction = ELEMENT_DIRECTION[index]
39
+ weakness = ELEMENTS[(index - 1) % 6]
40
+ strength = ELEMENTS[(index + 1) % 6]
41
+ color = ELEMENT_COLORS[index]
42
+ enfeeble = ELEMENT_ENFEEBLE[index]
43
+ attribute = ELEMENT_ATTRIBUTE[index]
44
+ ninjutsu = ELEMENT_NINJUTSU[index]
45
+ avatar = ELEMENT_AVATAR[index]
41
46
 
42
- Element.new(element, strength, weakness, color, enfeeble, attribute,
43
- ninjutsu, avatar)
44
- else
45
- raise "Unknown element"
46
- end
47
- end
47
+ Element.new(element, direction, strength, weakness, color, enfeeble,
48
+ attribute, ninjutsu, avatar)
49
+ else
50
+ raise "Unknown element"
51
+ end
48
52
  end
53
+ end
49
54
  end
@@ -1,143 +1,135 @@
1
1
  module FFXI
2
- class VanaMoon
3
- include FFXI::Constants
4
- include FFXI::Common
5
- include Observable
6
-
7
- MOON_PHASES = ["Full", "Waning Gibbous", "Last Quarter", "Waning Crescent",
8
- "New Moon", "Waxing Crescent", "First Quarter", "Waxing Gibbous"]
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
-
62
- # Each lunar cycle takes exactly 84 game days
63
- # (3 days, 8 hours, 38 minutes, 24 seconds)
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
-
76
- @moon_percent = - ((42 - @moon_days).to_f / 42 * 100).round
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
86
-
87
- case @moon_percent
88
- when (-100..-94)
89
- @moon_phase = 0
90
- @next_phase_target = 3
91
- when (90..100)
92
- @moon_phase = 0
93
- @next_phase_target = 3 + 84
94
- when (-93..-62)
95
- @moon_phase = 1
96
- @next_phase_target = 17
97
- when (-61..-41)
98
- @moon_phase = 2
99
- @next_phase_target = 25
100
- when (-40..-11)
101
- @moon_phase = 3
102
- @next_phase_target = 38
103
- when (-10..6)
104
- @moon_phase = 4
105
- @next_phase_target = 45
106
- when (7..36)
107
- @moon_phase = 5
108
- @next_phase_target = 58
109
- when (37..56)
110
- @moon_phase = 6
111
- @next_phase_target = 66
112
- when (57..89)
113
- @moon_phase = 7
114
- @next_phase_target = 80
115
- end
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
-
126
- case @moon_phase
127
- when (0..3)
128
- @next_optimal_phase = 4
129
- @optimal_phase_target = 38
130
- @optimal_phase_target += 84 if (90..100).include? @moon_percent
131
- when (4..7)
132
- @next_optimal_phase = 0
133
- @optimal_phase_target = 80
134
- end
135
-
136
- if @next_optimal_phase != old_optimal
137
- changed
138
- notify_observers("next_optimal_phase", self)
139
- end
140
- end
2
+ class VanaMoon < Util::RubyBean
3
+ include FFXI::Constants
4
+ include FFXI::Common
5
+
6
+ MOON_PHASES = ["Full", "Waning Gibbous", "Last Quarter Moon",
7
+ "Waning Crescent", "New Moon", "Waxing Crescent", "First Quarter Moon",
8
+ "Waxing Gibbous"]
9
+ SHORT_MOON_PHASES = ["FM", "WNG", "LQM", "WNC", "NM", "WXC", "FQM", "WXG"]
10
+
11
+ property :moon_days, :moon_percent, :moon_percent_string
12
+ property :moon_phase, :moon_phase_name, :moon_phase_short_name
13
+ property :moon_string
14
+ property :next_phase_name, :next_phase_short_name
15
+ property :optimal_phase_name, :optimal_phase_short_name
16
+ property :next_phase_target, :optimal_phase_target
17
+
18
+ alias to_i moon_percent
19
+ alias percent moon_percent_string
20
+ alias phase moon_phase_name
21
+ alias to_s moon_string
22
+ alias next_phase next_phase_name
23
+ alias optimal_phase optimal_phase_name
24
+
25
+ def initialize(opts={})
26
+ super()
27
+ add_listener(opts[:listener]) if opts[:listener]
28
+
29
+ if opts[:vana_time].is_a? VanaTime
30
+ update_earth_time opts[:vana_time].earth_time
31
+ elsif opts[:earth_time]
32
+ update_earth_time opts[:earth_time]
33
+ end
34
+ end
35
+
36
+ def self.now(listener=nil)
37
+ opts = {:earth_time => Time.now}
38
+ opts[:listener] = listener if listener
39
+ self.new(opts)
40
+ end
41
+
42
+ def update_earth_time(time)
43
+ raise "Input needs to be a Time object" if ! time.is_a? Time
44
+
45
+ @earth_time = time
46
+ set_moon_days
47
+ set_percent
48
+ set_phase
49
+ set_moon_string
50
+ set_optimal
51
+ end
52
+
53
+ def update_vana_time(vt)
54
+ if vt.is_a? VanaTime
55
+ update_earth_time(vt.earth_time)
56
+ else
57
+ update_earth_time(FFXI::Common.vana_to_earth(vt))
58
+ end
59
+ end
60
+
61
+ attr_reader :earth_time
62
+
63
+ private
141
64
 
65
+ def set_moon_days
66
+ # Each lunar cycle takes exactly 84 game days
67
+ # (3 days, 8 hours, 38 minutes, 24 seconds)
68
+ self.moon_days = (((@earth_time.to_f * 1000).to_i -
69
+ MS_MOON_DATE.to_i) / MS_GAME_DAY).floor % 84
142
70
  end
71
+
72
+ def set_percent
73
+ self.moon_percent = - ((42 - moon_days).to_f / 42 * 100).round
74
+ self.moon_percent_string = "#{moon_percent.abs}%"
75
+ end
76
+
77
+ def set_phase
78
+ case moon_percent
79
+ when (-100..-94)
80
+ self.moon_phase = 0
81
+ self.next_phase_target = 3
82
+ when (90..100)
83
+ self.moon_phase = 0
84
+ self.next_phase_target = 3 + 84
85
+ when (-93..-62)
86
+ self.moon_phase = 1
87
+ self.next_phase_target = 17
88
+ when (-61..-41)
89
+ self.moon_phase = 2
90
+ self.next_phase_target = 25
91
+ when (-40..-11)
92
+ self.moon_phase = 3
93
+ self.next_phase_target = 38
94
+ when (-10..6)
95
+ self.moon_phase = 4
96
+ self.next_phase_target = 45
97
+ when (7..36)
98
+ self.moon_phase = 5
99
+ self.next_phase_target = 58
100
+ when (37..56)
101
+ self.moon_phase = 6
102
+ self.next_phase_target = 66
103
+ when (57..89)
104
+ self.moon_phase = 7
105
+ self.next_phase_target = 80
106
+ end
107
+
108
+ self.moon_phase_name = MOON_PHASES[moon_phase]
109
+ self.moon_phase_short_name = SHORT_MOON_PHASES[moon_phase]
110
+ self.next_phase_name = MOON_PHASES[(moon_phase + 1) % 8]
111
+ self.next_phase_short_name = MOON_PHASES[(moon_phase + 1) % 8]
112
+ end
113
+
114
+ def set_moon_string
115
+ self.moon_string = "#{moon_percent_string} #{moon_phase_name}"
116
+ end
117
+
118
+ def set_optimal
119
+ case moon_phase
120
+ when (0..3)
121
+ @next_optimal_phase = 4
122
+ opt = 38
123
+ opt += 84 if (90..100).include? moon_percent
124
+ self.optimal_phase_target = opt
125
+ when (4..7)
126
+ @next_optimal_phase = 0
127
+ self.optimal_phase_target = 80
128
+ end
129
+
130
+ self.optimal_phase_name = MOON_PHASES[@next_optimal_phase]
131
+ self.optimal_phase_short_name = SHORT_MOON_PHASES[@next_optimal_phase]
132
+ end
133
+
134
+ end
143
135
  end