64 lines
1.8 KiB
Ruby
64 lines
1.8 KiB
Ruby
class Weather
|
|
def self.get_weather(zone, hash = hash(get_seed))
|
|
total = 0
|
|
APP_DATA[zone][:weather].each do |arr|
|
|
name, rate = arr
|
|
if (total += rate) > hash
|
|
return name
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.forecast(zone, seed = get_seed, count = 10)
|
|
res = []
|
|
prev_hash = hash(seed - 1)
|
|
prev_weather = get_weather(zone, prev_hash)
|
|
count.times do |_|
|
|
curr_hash = hash(seed)
|
|
curr_weather = get_weather(zone, curr_hash)
|
|
res.push({ zone: zone, prev_weather: prev_weather, curr_weather: curr_weather, weather_name: get_weather_name(curr_weather), seed: seed, time: Time.at(seed * 1400000.0 / 1000) })
|
|
prev_hash = curr_hash
|
|
prev_weather = curr_weather
|
|
seed += 1
|
|
end
|
|
res
|
|
end
|
|
|
|
def self.round_to_last_weather_time(time)
|
|
last_hour = time.hour / 8 * 8
|
|
time.change(hour: last_hour)
|
|
end
|
|
|
|
def self.get_weather_name(name)
|
|
case name
|
|
when "fair" then "Fair Skies"
|
|
when "showers" then "Showers"
|
|
when "gales" then "Gales"
|
|
when "blizzards" then "Blizzards"
|
|
when "heat" then "Heat"
|
|
when "thunder" then "Thunderstorms"
|
|
when "gloom" then "Gloom"
|
|
when "snow" then "Snow"
|
|
when "fog" then "Fog"
|
|
when "umbral_wind" then "Umbral Wind"
|
|
else "Unknown Weather"
|
|
end
|
|
end
|
|
|
|
|
|
def self.get_seed
|
|
(Time.now.utc.to_i * 1000 / 1400000.0).floor
|
|
end
|
|
|
|
def self.hash(seed = get_seed)
|
|
base = (seed / 3).floor * 100 + ((seed + 1) % 3) * 8
|
|
# Ruby has no other convenient way to convert a signed integer into an unsigned one
|
|
step1 = [ ((base << 11) ^ base) ].pack("L").unpack("L").first
|
|
step2 = [ (([ (step1 >> 8) ].pack("L").unpack("L").first.to_i ^ step1)) ].pack("L").unpack("L").first.to_i
|
|
step2 % 100
|
|
end
|
|
|
|
def self.unsigned_right(input, by)
|
|
input << by & 0xFF00 | input >> by & 0xFF
|
|
end
|
|
end
|