import Model from "./model.js";
/**
* A weather report for a single day, including temperature, wind, precipitation,
* sky conditions, sun/moon timing, and gameplay effect warnings. Here’s one presentation
* of all this information:
*
* “Temp: low 73° to high 98° (including windchill). Wind: 17 to 29 mph. Sky: Moderate
* drizzle today. Sun: Light from 5:04 to 20:24 (sunrise 5:33, sunset 19:55). Moon: 🌔
* waxing gibbous moon (light from 20:24 to 3:37). Effects: Extra water rations, shade,
* and inactivity at the height of the heat are needed to avoid heat stroke, heat
* exhaustion, or death.”
*
* @property {number} tempMin - Minimum temperature in °F (accounts for windchill).
* @property {number} tempMax - Maximum temperature in °F (accounts for windchill).
* @property {number} windMax - Maximum sustained wind speed in mph.
* @property {number} windGusts - Maximum wind gust speed in mph.
* @property {number} rain - Total rainfall in inches.
* @property {number} snowfall - Total snowfall in inches.
* @property {string} sky - WMO weather code description of sky conditions.
* @property {string} dawn - Dawn time in HH:MM format (local time).
* @property {string} sunrise - Sunrise time in HH:MM format (local time).
* @property {string} sunset - Sunset time in HH:MM format (local time).
* @property {string} dusk - Dusk time in HH:MM format (local time).
* @property {string} moonPhase - Moon phase emoji icon.
* @property {string} moonText - Moon phase description (e.g. "full moon (bright at night)").
* @property {string} moonLight - Moon illumination level description.
* @property {string} moonRise - Effective moonrise time in HH:MM format, bounded by dusk.
* @property {string} moonSet - Effective moonset time in HH:MM format, bounded by dawn.
*/
export default class Weather extends Model {
constructor({
tempMin,
tempMax,
windMax,
windGusts,
rain,
snowfall,
sky,
dawn,
sunrise,
sunset,
dusk,
moonPhase,
moonText,
moonLight,
moonRise,
moonSet,
} = {}) {
super({});
this.tempMin = tempMin;
this.tempMax = tempMax;
this.windMax = windMax;
this.windGusts = windGusts;
this.rain = rain;
this.snowfall = snowfall;
this.sky = sky;
this.dawn = dawn;
this.sunrise = sunrise;
this.sunset = sunset;
this.dusk = dusk;
this.moonPhase = moonPhase;
this.moonText = moonText;
this.moonLight = moonLight;
this.moonRise = moonRise;
this.moonSet = moonSet;
this._class = "Weather";
}
toString() {
let warning = [];
if (this.tempMin < 32) {
warning.push("Cold weather gear or shelter required to avoid frostbite or death");
} else if (this.tempMin < 45) {
warning.push("Cold weather gear or shelter required to avoid exhaustion");
} else if (this.tempMax > 97) {
warning.push(
"Extra water rations, shade, and inactivity at the height of the heat are needed to avoid heat stroke, heat exhaustion, or death",
);
} else if (this.tempMax > 80) {
warning.push(
"Warm weather limits strenuous outdoor activity and requires extra water rations to avoid exhaustion",
);
}
if (this.snowfall > 1) {
warning.push("Snow limits travel today");
}
if (warning.length === 0) {
warning.push("Nothing about the weather is dangerous or impedes travel today");
}
const arr = [];
if (this.tempMin < 32) {
arr.push(["Temp", `low ${this.tempMin}° to high ${this.tempMax}° (including windchill)`]);
} else {
arr.push(["Temp", `low ${this.tempMin}° to high ${this.tempMax}°`]);
}
arr.push(["Wind", `${this.windMax} to ${this.windGusts} mph`]);
// sky stuff
const a = [this.sky];
if (this.rain > 0.01) {
a.push(`rain ${this.rain} in`);
}
if (this.snowfall > 0.01) {
a.push(`snowfall ${this.snowfall} in`);
}
arr.push(["Sky", a.join(", ")]);
arr.push([
"Sun",
`Light from ${this.dawn} to ${this.dusk} (sunrise ${this.sunrise}, sunset ${this.sunset})`,
]);
// but if it’s dark out, moon rise and moon set don’t matter
arr.push([
"Moon",
`${this.moonPhase} ${this.moonText} (${this.moonLight} from ${this.moonRise} to ${this.moonSet})`,
]);
if (warning.length) {
arr.push(["Effects", warning.join(". ")]);
}
// get wind chill information, it's more significant
return "<p>" + arr.map((arr) => `<b>${arr[0]}:</b> ${arr[1]}`).join(". ") + ".</p>";
}
}