inherit "std/object"; #include "climate.h" #define FILE_NAME "/save/environ/weather" #define HOME "/obj/handlers/weather_room" #define MAX_DIST 100 #define YEAR 60 #define DAY 60 #define SPEED 40 /* * hmmmmm. ok well cloud cover... * wind speed... * hmmm. what would be a nice way of doing that? and climate... * * well we could do something like having the cloud cover sort of follow the low * or we could change the low scheme. I dont belive in global patterns, ie the * whole mud having the same weather. but nearby rooms should have very similar * weather. */ mixed *coldarr, *cloudarr, *rainarr; int timeofyear, mooncycle, moonoff, timeofday, intensity; int distance(mixed *co_ord1,mixed *co_ord); int cloud_index(object env); int rain_index(object env); int temperature_index(object env); string cloud_string(object env); string rain_string(object env); string temperature_string(object env); void setup() { set_name("weather"); set_short("weather controller extrodinare"); set_long("The weather controller, at least this one is always right!\n"); cloudarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) }); rainarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) }); coldarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) }); intensity = 100; restore_object(FILE_NAME); call_out("update_low",SPEED); move("bing"); } /* have this move here to get it to my weather room ;) */ move(arg) { ::move(HOME); } mixed *query_cold() { return coldarr; } mixed *query_rain() { return rainarr; } mixed *query_cloud() { return cloudarr; } int query_moon() { return mooncycle; } string query_moon_string(object env) { int bing; bing = timeofday - (DAY/4) - (distance((mixed *)env->query_co_ord(), ({ 0, 0, 0, }))/100); if (bing<0) bing += DAY; if ((moonoff+(DAY/2)<bing) && (bing<DAY-moonoff)) return 0; /* the moon is not up... */ return ({ "full moon", "waning three quarter moon", "waning half moon", "waning quarter moon", "waning cresent moon", /* from here */ "new moon", "waxing cresent moon", /* to here you cannot see at night... ! */ "waxing quarter moon", "waxing half moon", "waxing three quarter moon" })[mooncycle]; } int distance(mixed *co_ord1, mixed *co_ord2) { int off; if (!pointerp(co_ord1) || !pointerp(co_ord2)) return 0; if (co_ord1[0]>co_ord2[0]) off = co_ord1[0] - co_ord2[0]; else off = co_ord2[0] - co_ord1[0]; if (co_ord1[1]>co_ord2[1]) off += co_ord1[1] - co_ord2[1]; else off += co_ord2[1] - co_ord1[1]; return off; } int query_season() { return timeofyear/15; } int query_time_of_year() { return timeofyear; } int query_time_of_day() { return timeofday; } int query_day(object env) { int bing, bit; if (!env) { env = find_object("/d/am/am/mendedrum"); if (!env) call_other("/d/am/am/mendeddrum", "??"); env = find_object("/d/am/am/mendeddrum"); } /* make it change... but not very quickly... */ bing = timeofday - (DAY/4) - (distance((mixed *)env->query_co_ord(), ({ 0, 0, 0, }))/100); if (bing<0) bing += DAY; bit = (DAY/2)-(timeofyear-(YEAR/2))/(YEAR/10); if (bing>bit) return 0; if (bit < 10) return bit; return -(bing - bit); } /* * returns a percentage of light.... 100 being full sunlight... * down */ int query_darkness(object env) { int bing, per, i; /* so thats the day.... we should make the light fade towards night * though.... Hmmm. */ per = -cloud_index(env); if (per <-100) per = -100; if (per > 100) per = 100; if ((i=query_day(env))) { i *= 20; if (i>100) i = 100; return 50+(per+100)*150*i/20000; } bing = timeofday - (DAY/4) - (distance((mixed *)env->query_co_ord(), ({ 0, 0, 0, }))/100); if (bing<0) bing += DAY; if ((moonoff+(DAY/2)<bing) && (bing<DAY-moonoff)) return 15+(per+100)*30/200; if (timeofday<0) timeofday += DAY; i = mooncycle -5; if (i<0) i = -i; return 30+(per+100)*14*i/200; /* lit up by the light of the moon... tell them about it? */ } string weather_string(object env) { return temperature_string(env)+" with "+cloud_string(env)+ rain_string(env); } int query_raining(object env) { int cloud,rain; if (temperature_index(env)/(100/7)<2) { cloud = cloud_index(env); if (cloud<=0) return 0; rain = rain_index(env); if (cloud-rain<=0) return 0; return cloud-rain; } return 0; } int query_hailing(object env) { int cloud, rain; if (temperature_index(env)/(100/7)==2) { cloud = cloud_index(env); if (cloud <=0) return 0; rain = rain_index(env); if (cloud-rain <=0) return 0; return cloud-rain; } return 0; } int query_snowing(object env) { int cloud,rain; if ((temperature_index(env)/(100/7))>=3) { cloud = cloud_index(env); if (cloud<=0) return 0; rain = cloud_index(env); if (cloud-rain<=0) return 0; return cloud-rain; } return 0; } string rain_string(object env) { int cloud, rain, temp; string tempstr1,tempstr2; cloud = cloud_index(env); rain = rain_index(env); if (cloud<=0) return ""; if (cloud-rain<=0) return ""; temp = temperature_index(env)/(100/7); if (temp>3) temp = 3; if (temp<-3) temp = -3; tempstr1 = ({ "very hot ", "hot ", "warm ", "nice ", "cold ", "", "" })[temp+3]; tempstr2 = ({ " rain", " rain", " rain", " rain", " rain", " hail", " snow" })[temp+3]; cloud = (cloud-rain) / 20; if (cloud>5) cloud = 5; return "\n"+capitalize(tempstr1 + ({ "very light", "light", "medium", "heavy", "very heavy" }) [cloud]+tempstr2); } string temperature_string(object env) { int inten; inten = temperature_index(env); inten /= 10; if (inten>10) inten = 10; if (inten<-10) inten = -10; return ({ "Its one of those baking eggs on the pavement days", /* -10 */ "So hot that the sun feels like its right next door", /* -9 */ "Damn hot", /* -8 */ "Very hot", /* -7 */ "Hot", /* -6 */ "Hot", /* -5 */ "Reasonably hot", /* -4 */ "Very warm", /* -3 */ "Warm", /* -2 */ "Pleasantly warm", /* -1 */ "Average temerature", /* 0 */ "A little chilly", /* 1 */ "A slight nip in the air", /* 2 */ "Chilly", /* 3 */ "Very chilly", /* 4 */ "Cold", /* 5 */ "Cold", /* 6 */ "Very cold", /* 7 */ "Damn cold", /* 8 */ "Incredibly cold", /* 9 */ "Freezing cold" })[inten+10]; /* 10 */ } string cloud_string(object env) { int off; off = cloud_index(env) / 20; if (off>5) off = 5; if (off<-5) off = -5; return ({ "a beatifully clear sky", /* -5 */ "a few high level sirius clouds", /* -4 */ "scattered puffy clouds", /* -3 */ "very thin complete cloud cover", /* -2 */ "light cloud cover", /* -1 */ "medium cloud cover", /* 0 */ "dense cloud cover", /* 1 */ "packed cloud cover", /* 2 */ "packed cloud cover", /* 3 */ "heavy black clouds", /* 4 */ "thick heavy clouds", /* 5 */ })[off+5]; } int temperature_index(object env) { int off,i; mixed clim, *co_ord; for (i=0;i<sizeof(coldarr);i++) off += (distance((mixed *)env->query_co_ord(), coldarr[i]) % (MAX_DIST*2)); off = off / sizeof(coldarr); if ((clim = (mixed *)env->query_property("climate"))) off += clim[C_TEMP]; if (off>MAX_DIST) off = (MAX_DIST*2) - off; off -= (MAX_DIST/2); off = 0 - off; co_ord = (mixed *)env->query_co_ord(); if (!co_ord) co_ord = ({ 0, 0, 0 }); return (off + (timeofyear - (YEAR/2)) + (timeofday - (DAY/2)) + co_ord[2]); } int cloud_index(object env) { int off; mixed *clim; int i; for (i=0;i<sizeof(cloudarr);i++) off += (distance((mixed *)env->query_co_ord(), cloudarr[i]) % (MAX_DIST*2)); off = off / sizeof(cloudarr); if ((clim = (mixed *)env->query_property("climate"))) off += clim[C_CLOUD]; if (off>MAX_DIST) off = (MAX_DIST*2) - off; off -= (MAX_DIST/2); off = 0-off; return (off + (timeofyear - (YEAR/2))); } int rain_index(object env) { int off; mixed *clim; int i; for (i=0;i<sizeof(rainarr);i++) off += (distance((mixed *)env->query_co_ord(), rainarr[i]) % (MAX_DIST*2)); off = off / sizeof(rainarr); if ((clim = (mixed *)env->query_property("climate"))) off += clim[C_RAIN]; if (off>MAX_DIST) off = (MAX_DIST*2) - off; off -= MAX_DIST/2; off = 0-off; return off; } void update_low() { int i; timeofday++; if (timeofday>DAY) { timeofday = 0; timeofyear++; mooncycle++; if (mooncycle %2) { moonoff += 1; moonoff = moonoff % (DAY/2); } timeofyear = timeofyear % YEAR; mooncycle = mooncycle % 10; save_object(FILE_NAME); } for (i=0;i<sizeof(rainarr);i++) { rainarr[i][0] += random(3)-1; rainarr[i][0] = rainarr[i][0] % (MAX_DIST*2); rainarr[i][1] += random(3)-1; rainarr[i][1] = rainarr[i][1] % (MAX_DIST*2); } for (i=0;i<sizeof(cloudarr);i++) { cloudarr[i][0] += random(3)-1; cloudarr[i][0] = cloudarr[i][0] % (MAX_DIST*2); cloudarr[i][1] += random(3)-1; cloudarr[i][1] = cloudarr[i][1] % (MAX_DIST*2); } for (i=0;i<sizeof(coldarr);i++) { coldarr[i][0] += random(3)-1; coldarr[i][0] = coldarr[i][0] % (MAX_DIST*2); coldarr[i][1] += random(3)-1; coldarr[i][1] = coldarr[i][1] % (MAX_DIST*2); } intensity += random(3)-1; if (intensity<50) intensity=50; if (intensity>300) intensity=300; call_out("update_low",SPEED); } void dest_me() { save_object(FILE_NAME); ::dest_me(); }