#include #include #include #include "weather.h" #include "game_time.h" int area = DEFAULT_AREA; int pseudoseed; int temp; int prec, prec_type; static int pseudorand(void); static int pseudorandom(int); /* We'll add more areas when we find more tables. * * Nighttime should actually subtract 3d10 from temperature, * at least in mordor, perhaps in other wasteland/desertlike * areas too. */ struct Area_Weather aw[] = { { "Forodwaith (Northern Waste)", {{ -25,50, 5 }, { -25,45, 2 }, { -10,35, 5 }, { 0, 30, 30 }, { 5, 35, 5 }, { 10, 35, 30 }, { 10, 40, 40 }, { 10, 50, 30 }, { 5, 40, 5 }, { 0, 35, 30 }, { -5, 30, 5 }, { -10,25, 2 }}, }, { "Nan Angmar", {{ -20, 35, 40 }, { -20, 35, 40 }, { -20, 35, 40 }, { 0, 35, 40 }, { 35, 10, 15 }, { 40, 20, 15 }, { 50, 15, 25 }, { 55, 10, 25 }, { 50, 27, 25 }, { 35, 15, 40 }, { 20, 15, 40 }, { 15, 5, 40 }}, }, { "Gundalok", {{ 10, 22, 15 }, { 15, 17, 15 }, { 35, 10, 40 }, { 40, 20, 25 }, { 40, 20, 25 }, { 70, 10, 25 }, { 70, 10, 25 }, { 75, 10, 25 }, { 70, 10, 25 }, { 60, 10, 25 }, { 45, 15, 25 }, { 20, 20, 40 }}, }, { "Northern Misty Mts: Foothills", {{ 15, 15, 40 }, { 15, 15, 60 }, { 15, 15, 60 }, { 20, 15, 40 }, { 25, 15, 40 }, { 25, 20, 25 }, { 30, 20, 25 }, { 40, 20, 25 }, { 45, 20, 15 }, { 40, 20, 25 }, { 35, 15, 40 }, { 25, 15, 40 }}, }, { "Rhudaur", {{ 5, 20, 40 }, { 5, 20, 40 }, { 15, 20, 40 }, { 30, 20, 25 }, { 50, 15, 25 }, { 65, 10, 15 }, { 65, 10, 25 }, { 65, 10, 25 }, { 60, 10, 25 }, { 45, 15, 40 }, { 30, 15, 25 }, { 15, 15, 40 }}, }, { "Arthedain: The North Downs", {{ 20, 20, 45 }, { 10, 15, 40 }, { 15, 20, 30 }, { 25, 20, 40 }, { 35, 20, 40 }, { 40, 20, 40 }, { 50, 20, 40 }, { 50, 25, 50 }, { 50, 25, 50 }, { 50, 20, 45 }, { 40, 20, 50 }, { 30, 20, 45 }}, }, { "Southern Anduin Valley", {{ 25, 20, 15 }, { 30, 20, 15 }, { 30, 20, 25 }, { 45, 20, 25 }, { 55, 20, 25 }, { 60, 20, 15 }, { 65, 20, 15 }, { 65, 20, 15 }, { 55, 20, 25 }, { 45, 20, 40 }, { 35, 20, 25 }, { 30, 20, 15 }}, }, { "Arthedain", {{ 10, 22, 15 }, { 10, 22, 15 }, { 28, 12, 40 }, { 38, 17, 25 }, { 60, 10, 25 }, { 70, 10, 15 }, { 70, 10, 25 }, { 70, 10, 25 }, { 67, 10, 25 }, { 50, 17, 25 }, { 30, 20, 25 }, { 12, 23, 40 }}, }, { "Arthedain: Hills of Evendim", {{ 15, 15, 35 }, { 10, 15, 30 }, { 15, 15, 40 }, { 20, 15, 30 }, { 30, 15, 25 }, { 35, 15, 30 }, { 45, 15, 35 }, { 60, 15, 35 }, { 60, 15, 40 }, { 40, 35, 35 }, { 35, 25, 35 }, { 25, 20, 45 }}, }, { "The Shire", {{ 25, 15, 45 }, { 15, 20, 55 }, { 20, 15, 45 }, { 30, 20, 45 }, { 35, 25, 45 }, { 50, 15, 50 }, { 60, 15, 45 }, { 65, 15, 50 }, { 65, 15, 55 }, { 55, 20, 50 }, { 45, 20, 55 }, { 35, 20, 45 }}, }, { "Mirkwood", {{ 10, 35, 30 }, { 10, 30, 5 }, { 20, 30, 30 }, { 30, 30, 40 }, { 40, 25, 30 }, { 50, 20, 40 }, { 50, 15, 60 }, { 55, 30, 60 }, { 55, 25, 30 }, { 45, 20, 40 }, { 35, 25, 30 }, { 20, 25, 30 }}, }, { "Rhovanion: Lowlands", {{ 10, 20, 30 }, { 5, 30, 5 }, { 15, 30, 5 }, { 25, 30, 30 }, { 30, 30, 30 }, { 45, 20, 40 }, { 50, 30, 60 }, { 55, 35, 40 }, { 55, 30, 30 }, { 30, 35, 30 }, { 25, 35, 30 }, { 15, 30, 30 }}, }, { "Rhovanion: Highlands", {{ -10,40, 30 }, { -15,40, 30 }, { -5, 35, 40 }, { 5, 35, 40 }, { 15, 35, 30 }, { 25, 35, 40 }, { 25, 40, 40 }, { 25, 50, 40 }, { 20, 45, 30 }, { 15, 40, 30 }, { 10, 40, 5 }, { 0, 40, 5 }}, }, { "Wold & the Downs", {{ 20, 25, 25 }, { 15, 25, 25 }, { 25, 20, 25 }, { 30, 20, 25 }, { 35, 20, 25 }, { 40, 20, 20 }, { 50, 20, 15 }, { 60, 20, 15 }, { 65, 20, 20 }, { 60, 15, 25 }, { 50, 15, 25 }, { 40, 15, 25 }}, }, { "Cardolan: Highlands", {{ 20, 15, 25 }, { 20, 20, 15 }, { 25, 20, 25 }, { 35, 20, 25 }, { 35, 25, 25 }, { 45, 25, 25 }, { 50, 30, 5 }, { 65, 25, 15 }, { 55, 25, 25 }, { 40, 30, 40 }, { 30, 25, 15 }, { 20, 20, 25 }}, }, { "Cardolan: Mintyrnath", {{ 20, 15, 15 }, { 25, 15, 15 }, { 25, 20, 40 }, { 40, 15, 25 }, { 40, 20, 25 }, { 50, 20, 15 }, { 55, 30, 5 }, { 70, 20, 15 }, { 55, 30, 25 }, { 40, 35, 40 }, { 30, 30, 15 }, { 20, 25, 15 }}, }, { "Cardolan: Minhiriath", {{ 25, 15, 15 }, { 25, 20, 25 }, { 30, 20, 40 }, { 45, 15, 25 }, { 45, 20, 25 }, { 50, 25, 15 }, { 55, 25, 15 }, { 65, 20, 15 }, { 55, 25, 25 }, { 45, 25, 40 }, { 35, 25, 15 }, { 25, 20, 15 }}, }, { "Fangorn Forest", {{ 35, 20, 25 }, { 30, 20, 25 }, { 35, 20, 25 }, { 40, 20, 25 }, { 45, 15, 40 }, { 50, 10, 40 }, { 60, 10, 25 }, { 65, 10, 25 }, { 70, 10, 15 }, { 60, 15, 25 }, { 55, 10, 25 }, { 40, 20, 25 }}, }, { "Southern Misty Mts: Foothills", {{ 20, 20, 20 }, { 15, 20, 20 }, { 20, 20, 20 }, { 25, 20, 40 }, { 35, 15, 40 }, { 40, 20, 20 }, { 50, 20, 20 }, { 55, 20, 5 }, { 60, 15, 5 }, { 50, 20, 20 }, { 50, 15, 20 }, { 45, 15, 20 }}, }, { "Dunland: Gwaitho Plain", {{ 30, 20, 25 }, { 25, 20, 25 }, { 30, 20, 25 }, { 35, 20, 25 }, { 40, 15, 40 }, { 45, 15, 25 }, { 55, 20, 25 }, { 60, 20, 5 }, { 65, 15, 5 }, { 60, 15, 25 }, { 50, 15, 25 }, { 40, 15, 25 }}, }, { "Dunland: Dunnish Highlands", {{ 25, 20, 25 }, { 20, 20, 40 }, { 25, 15, 40 }, { 30, 15, 25 }, { 40, 10, 40 }, { 45, 15, 25 }, { 55, 15, 25 }, { 60, 15, 25 }, { 65, 10, 5 }, { 55, 15, 25 }, { 45, 20, 40 }, { 35, 20, 40 }}, }, { "Ost-in-Edhil", {{ 30, 15, 20 }, { 25, 20, 20 }, { 30, 20, 20 }, { 35, 20, 20 }, { 40, 15, 40 }, { 45, 15, 20 }, { 55, 20, 5 }, { 60, 20, 5 }, { 65, 15, 3 }, { 60, 15, 5 }, { 55, 15, 5 }, { 50, 15, 5 }}, }, { "Redhorn Pass", {{ 10, 15, 60 }, { 15, 15, 60 }, { 15, 15, 40 }, { 20, 15, 40 }, { 25, 15, 40 }, { 25, 20, 20 }, { 30, 20, 20 }, { 40, 20, 20 }, { 45, 20, 5 }, { 40, 20, 20 }, { 35, 15, 20 }, { 20, 15, 40 }} }, { "Rohan (Northern)", {{ 25, 20, 25 }, { 20, 20, 25 }, { 25, 20, 25 }, { 30, 20, 25 }, { 35, 15, 40 }, { 40, 15, 40 }, { 50, 15, 25 }, { 55, 15, 25 }, { 60, 15, 15 }, { 55, 15, 15 }, { 50, 10, 25 }, { 40, 15, 25 }}, }, { "Rohan (Southern)", {{ 30, 20, 25 }, { 25, 20, 25 }, { 30, 20, 25 }, { 35, 20, 25 }, { 40, 15, 40 }, { 45, 15, 40 }, { 55, 15, 25 }, { 60, 15, 25 }, { 65, 10, 25 }, { 60, 10, 40 }, { 50, 10, 25 }, { 40, 15, 25 }}, }, { "Northern Ithilien", {{ 20, 15, 40 }, { 10, 30, 45 }, { 15, 30, 40 }, { 25, 30, 40 }, { 35, 30, 35 }, { 50, 20, 30 }, { 60, 20, 25 }, { 65, 25, 20 }, { 60, 20, 10 }, { 50, 25, 25 }, { 40, 20, 30 }, { 30, 20, 25 }}, }, { "Mordor: Udûn", {{ 35, 15, 10 }, { 40, 15, 15 }, { 40, 15, 15 }, { 40, 20, 18 }, { 45, 20, 15 }, { 50, 30, 12 }, { 70, 15, 5 }, { 70, 20, 4 }, { 70, 40, 3 }, { 50, 30, 5 }, { 40, 25, 8 }, { 30, 25, 13 }}, }, { "Mordor: Devastation/The Grip", {{ 30, 15, 6 }, { 35, 15, 6 }, { 35, 15, 8 }, { 35, 25, 10 }, { 40, 20, 8 }, { 45, 30, 7 }, { 65, 20, 3 }, { 75, 20, 2 }, { 80, 35, 2 }, { 65, 15, 5 }, { 45, 15, 6 }, { 35, 20, 10 }}, }, { "Mordor: Gwathiraug", {{ 30, 10, 10 }, { 35, 15, 20 }, { 40, 15, 20 }, { 40, 25, 25 }, { 40, 20, 15 }, { 45, 30, 10 }, { 50, 30, 5 }, { 65, 25, 5 }, { 70, 40, 5 }, { 45, 30, 8 }, { 35, 25, 10 }, { 25, 20, 15 }}, }, { "Mordor: Gaer-Durlith", {{ 40, 15, 2 }, { 45, 15, 3 }, { 45, 15, 3 }, { 50, 15, 4 }, { 50, 20, 3 }, { 55, 30, 3 }, { 75, 15, 1 }, { 80, 25, 1 }, { 90, 30, 1 }, { 75, 20, 2 }, { 50, 15, 3 }, { 25, 25, 3 }}, }, { "Mordor: Morgul Vale", {{ 30, 15, 35 }, { 30, 20, 40 }, { 35, 20, 35 }, { 45, 15, 35 }, { 55, 15, 30 }, { 60, 15, 25 }, { 60, 20, 20 }, { 60, 25, 20 }, { 60, 20, 15 }, { 55, 15, 25 }, { 45, 15, 30 }, { 35, 15, 30 }}, }, { "South Gondor: Mountains", {{ 20, 20, 15 }, { 25, 20, 15 }, { 25, 20, 25 }, { 40, 20, 25 }, { 50, 20, 25 }, { 55, 20, 15 }, { 60, 20, 15 }, { 60, 20, 15 }, { 50, 20, 25 }, { 40, 20, 40 }, { 30, 20, 25 }, { 25, 20, 15 }}, }, { "South Gondor: Inland Vales", {{ 25, 20, 15 }, { 30, 20, 15 }, { 30, 20, 25 }, { 45, 20, 25 }, { 55, 20, 25 }, { 60, 20, 15 }, { 65, 20, 15 }, { 65, 20, 15 }, { 55, 20, 25 }, { 45, 20, 40 }, { 35, 20, 25 }, { 30, 20, 15 }}, }, { "South Gondor: Coastlands", {{ 35, 15, 15 }, { 40, 15, 15 }, { 45, 10, 25 }, { 55, 15, 25 }, { 60, 15, 25 }, { 65, 15, 15 }, { 70, 15, 15 }, { 70, 15, 15 }, { 60, 15, 25 }, { 55, 15, 40 }, { 45, 15, 25 }, { 40, 15, 25 }}, } }; /* Who can understand those idiotic but stupid farenheit degrees? */ int farenheit_to_celcius(int f) { return ((f - 32) * 10) / 18; } int celcius_to_farenheit(int c) { return ((c * 18) / 10) + 32; } static int pseudorand() { pseudoseed = ((pseudoseed * 997775) ^ 0xaaaaaaaa); return pseudoseed; } static int pseudorandom(int n) { return (rand() >> 8) % n; } /* Todo: Winds, wind speed, direction, cloud cover, mist, ... */ /* Todo: Special weather (like the storms of Cardolan etc.) */ /* Todo: Lower temperature at nighttime */ void todays_weather() { int m; unsigned int saveseed; /* We need to save a good random seed for dice throwing... */ saveseed = rand(); pseudoseed = 54001 * query_year_day() * query_year() * (area + 1); srand(pseudorand()); m = query_month(); /* Festival? Into which month it belongs? */ if (m == -1) m = query_festival_month(); m--; #if 0 fprintf(stderr, "%s (%d), month %d: %d %d %d\n", aw[area].area_name, area, m, aw[area].w_types[m].temp_base, aw[area].w_types[m].temp_var, aw[area].w_types[m].prec_chance); #endif temp = aw[area].w_types[m].temp_base + pseudorandom(aw[area].w_types[m].temp_var); if (aw[area].w_types[m].prec_chance >= pseudorandom(100)) { prec = 1; prec_type = (temp < 32); } else prec = 0; /* Get the good seed back - ain't we random today */ srand(saveseed); } static char wdesc[512]; char * weather_desc() { todays_weather(); if (prec) sprintf(wdesc, "Weather: Temperature %d°F (%d°C), Precipitation (%s)", temp, farenheit_to_celcius(temp), prec_type ? "Snow/Fleet" : "Water"); else sprintf(wdesc, "Weather: temperature %d°F (%d°C)", temp, farenheit_to_celcius(temp)); return wdesc; }