/**************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefiting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************
* 1stMud ROM Derivative (c) 2001-2004 by Markanth *
* http://www.firstmud.com/ <markanth@firstmud.com> *
* By using this code you have agreed to follow the term of *
* the 1stMud license in ../doc/1stMud/LICENSE *
***************************************************************************/
#include "merc.h"
#include "olc.h"
#include "interp.h"
#include "recycle.h"
Proto (void get_weather_echo, (WeatherData *));
void
init_area_weather ()
{
AreaData *pArea;
logf ("Initializing weather data...");
for (pArea = area_first; pArea; pArea = pArea->next)
{
int cf;
cf = pArea->weather.climate_temp - 2;
pArea->weather.temp =
number_range (-mud_info.weath_unit, mud_info.weath_unit) +
cf * number_range (0, mud_info.weath_unit);
pArea->weather.temp_vector =
cf + number_range (-mud_info.rand_factor, mud_info.rand_factor);
cf = pArea->weather.climate_precip - 2;
pArea->weather.precip =
number_range (-mud_info.weath_unit, mud_info.weath_unit) +
cf * number_range (0, mud_info.weath_unit);
pArea->weather.precip_vector =
cf + number_range (-mud_info.rand_factor, mud_info.rand_factor);
cf = pArea->weather.climate_wind - 2;
pArea->weather.wind =
number_range (-mud_info.weath_unit, mud_info.weath_unit) +
cf * number_range (0, mud_info.weath_unit);
pArea->weather.wind_vector =
cf + number_range (-mud_info.rand_factor, mud_info.rand_factor);
}
return;
}
void
adjust_vectors (WeatherData * weather)
{
double dT, dP, dW;
if (!weather)
{
bug ("NULL weather data.");
return;
}
dT = 0;
dP = 0;
dW = 0;
dT += number_range (-mud_info.rand_factor, mud_info.rand_factor);
dP += number_range (-mud_info.rand_factor, mud_info.rand_factor);
dW += number_range (-mud_info.rand_factor, mud_info.rand_factor);
dT += mud_info.climate_factor *
(((weather->climate_temp - 2) * mud_info.weath_unit) -
(weather->temp)) / mud_info.weath_unit;
dP += mud_info.climate_factor *
(((weather->climate_precip - 2) * mud_info.weath_unit) -
(weather->precip)) / mud_info.weath_unit;
dW += mud_info.climate_factor *
(((weather->climate_wind - 2) * mud_info.weath_unit) -
(weather->wind)) / mud_info.weath_unit;
weather->temp_vector += (int) dT;
weather->precip_vector += (int) dP;
weather->wind_vector += (int) dW;
weather->temp_vector = Range (-mud_info.max_vector,
weather->temp_vector, mud_info.max_vector);
weather->precip_vector =
Range (-mud_info.max_vector, weather->precip_vector, mud_info.max_vector);
weather->wind_vector =
Range (-mud_info.max_vector, weather->wind_vector, mud_info.max_vector);
return;
}
void
weather_update ()
{
AreaData *pArea;
Descriptor *d;
int limit;
limit = 3 * mud_info.weath_unit;
for (pArea = area_first; pArea; pArea = pArea->next)
{
pArea->weather.temp += pArea->weather.temp_vector;
pArea->weather.precip += pArea->weather.precip_vector;
pArea->weather.wind += pArea->weather.wind_vector;
pArea->weather.temp = Range (-limit, pArea->weather.temp, limit);
pArea->weather.precip = Range (-limit, pArea->weather.precip, limit);
pArea->weather.wind = Range (-limit, pArea->weather.wind, limit);
get_weather_echo (&pArea->weather);
}
for (pArea = area_first; pArea; pArea = pArea->next)
{
adjust_vectors (&pArea->weather);
}
for (d = descriptor_first; d; d = d->next)
{
WeatherData *weath;
if (d->connected == CON_PLAYING &&
IsOutside (d->character) && IsAwake (d->character))
{
weath = &d->character->in_room->area->weather;
if (NullStr (weath->echo))
continue;
d_printlnf (d, "%s%s{x", weath->echo_color, weath->echo);
}
}
return;
}
void
get_weather_echo (WeatherData * weath)
{
int n;
int temp, precip, wind;
int dT, dP, dW;
int tindex, pindex, windex;
replace_str (&weath->echo, "");
replace_str (&weath->echo_color, "{x");
n = number_bits (2);
temp = weath->temp;
precip = weath->precip;
wind = weath->wind;
dT = weath->temp_vector;
dP = weath->precip_vector;
dW = weath->wind_vector;
tindex = (temp + 3 * mud_info.weath_unit - 1) / mud_info.weath_unit;
pindex = (precip + 3 * mud_info.weath_unit - 1) / mud_info.weath_unit;
windex = (wind + 3 * mud_info.weath_unit - 1) / mud_info.weath_unit;
switch (pindex)
{
case 0:
if (precip - dP > -2 * mud_info.weath_unit)
{
char *echo_strings[4] = {
"The clouds disappear.",
"The clouds disappear.",
"The sky begins to break through " "the clouds.",
"The clouds are slowly " "evaporating."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
break;
case 1:
if (precip - dP <= -2 * mud_info.weath_unit)
{
char *echo_strings[4] = {
"The sky is getting cloudy.",
"The sky is getting cloudy.",
"Light clouds cast a haze over " "the sky.",
"Billows of clouds spread through " "the sky."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{D");
}
break;
case 2:
if (precip - dP > 0)
{
if (tindex > 1)
{
char *echo_strings[4] = {
"The rain stops.",
"The rain stops.",
"The rainstorm tapers " "off.",
"The rain's intensity " "breaks."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{C");
}
else
{
char *echo_strings[4] = {
"The snow stops.",
"The snow stops.",
"The snow showers taper " "off.",
"The snow flakes disappear " "from the sky."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
}
break;
case 3:
if (precip - dP <= 0)
{
if (tindex > 1)
{
char *echo_strings[4] = {
"It starts to rain.",
"It starts to rain.",
"A droplet of rain falls " "upon you.",
"The rain begins to " "patter."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{C");
}
else
{
char *echo_strings[4] = {
"It starts to snow.",
"It starts to snow.",
"Crystal flakes begin to " "fall from the " "sky.",
"Snow flakes drift down " "from the clouds."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
}
else if (tindex < 2 && temp - dT > -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The temperature drops and the rain " "becomes a light snow.",
"The temperature drops and the rain " "becomes a light snow.",
"Flurries form as the rain freezes.",
"Large snow flakes begin to fall " "with the rain."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
else if (tindex > 1 && temp - dT <= -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The snow flurries are gradually " "replaced by pockets of rain.",
"The snow flurries are gradually " "replaced by pockets of rain.",
"The falling snow turns to a cold drizzle.",
"The snow turns to rain as the air warms."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{C");
}
break;
case 4:
if (precip - dP > 2 * mud_info.weath_unit)
{
if (tindex > 1)
{
char *echo_strings[4] = {
"The lightning has stopped.",
"The lightning has stopped.",
"The sky settles, and the " "thunder surrenders.",
"The lightning bursts fade as " "the storm weakens."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{D");
}
}
else if (tindex < 2 && temp - dT > -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The cold rain turns to snow.",
"The cold rain turns to snow.",
"Snow flakes begin to fall " "amidst the rain.",
"The driving rain begins to freeze."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
else if (tindex > 1 && temp - dT <= -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The snow becomes a freezing rain.",
"The snow becomes a freezing rain.",
"A cold rain beats down on you " "as the snow begins to melt.",
"The snow is slowly replaced by a heavy " "rain."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{C");
}
break;
case 5:
if (precip - dP <= 2 * mud_info.weath_unit)
{
if (tindex > 1)
{
char *echo_strings[4] = {
"Lightning flashes in the " "sky.",
"Lightning flashes in the " "sky.",
"A flash of lightning splits " "the sky.",
"The sky flashes, and the " "ground trembles with " "thunder."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{Y");
}
}
else if (tindex > 1 && temp - dT <= -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The sky rumbles with thunder as " "the snow changes to rain.",
"The sky rumbles with thunder as " "the snow changes to rain.",
"The falling turns to freezing rain " "amidst flashes of "
"lightning.",
"The falling snow begins to melt as " "thunder crashes overhead."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{W");
}
else if (tindex < 2 && temp - dT > -mud_info.weath_unit)
{
char *echo_strings[4] = {
"The lightning stops as the rainstorm "
"becomes a blinding " "blizzard.",
"The lightning stops as the rainstorm "
"becomes a blinding " "blizzard.",
"The thunder dies off as the "
"pounding rain turns to " "heavy snow.",
"The cold rain turns to snow and " "the lightning stops."
};
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{C");
}
break;
default:
bug ("echo_weather: invalid precip index");
weath->precip = 0;
break;
}
return;
}
void
get_time_echo (WeatherData * weath)
{
int n;
int pindex;
n = number_bits (2);
pindex =
(weath->precip + 3 * mud_info.weath_unit - 1) / mud_info.weath_unit;
replace_str (&weath->echo, "");
replace_str (&weath->echo_color, "{w");
switch (time_info.hour)
{
case 5:
{
char *echo_strings[4] = {
"The day has begun.",
"The day has begun.",
"The sky slowly begins to glow.",
"The sun slowly embarks upon a new day."
};
time_info.sunlight = SUN_RISE;
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{Y");
break;
}
case 6:
{
char *echo_strings[4] = {
"The sun rises in the east.",
"The sun rises in the east.",
"The hazy sun rises over the horizon.",
"Day breaks as the sun lifts into the sky."
};
time_info.sunlight = SUN_LIGHT;
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{y");
break;
}
case 12:
{
if (pindex > 0)
{
replace_str (&weath->echo, "It's noon.");
}
else
{
char *echo_strings[2] = {
"The intensity of the sun " "heralds the noon hour.",
"The sun's bright rays beat down " "upon your shoulders."
};
replace_str (&weath->echo, echo_strings[n % 2]);
}
time_info.sunlight = SUN_LIGHT;
replace_str (&weath->echo_color, "{W");
break;
}
case 19:
{
char *echo_strings[4] = {
"The sun slowly disappears in the west.",
"The reddish sun sets past the horizon.",
"The sky turns a reddish orange as the sun " "ends its journey.",
"The sun's radiance dims as it sinks in the " "sky."
};
time_info.sunlight = SUN_SET;
replace_str (&weath->echo, echo_strings[n]);
replace_str (&weath->echo_color, "{R");
break;
}
case 20:
{
if (pindex > 0)
{
char *echo_strings[2] = {
"The night begins.",
"Twilight descends around you."
};
replace_str (&weath->echo, echo_strings[n % 2]);
}
else
{
char *echo_strings[2] = {
"The moon's gentle glow diffuses " "through the night sky.",
"The night sky gleams with " "glittering starlight."
};
replace_str (&weath->echo, echo_strings[n % 2]);
}
time_info.sunlight = SUN_DARK;
replace_str (&weath->echo_color, "{b");
break;
}
}
return;
}
Olc_Fun (aedit_climate)
{
char arg[MAX_INPUT_LENGTH];
AreaData *area;
GetEdit (ch, AreaData, area);
argument = one_argument (argument, arg);
if (NullStr (arg))
{
chprintlnf (ch, "%s:", area->name);
chprintlnf (ch, "\tTemperature:\t%s",
temp_settings[area->weather.climate_temp]);
chprintlnf (ch, "\tPrecipitation:\t%s",
precip_settings[area->weather.climate_precip]);
chprintlnf (ch, "\tWind:\t\t%s",
wind_settings[area->weather.climate_wind]);
chprintlnf (ch, "Weather variables range from "
"%d to %d.", -3 * mud_info.weath_unit,
3 * mud_info.weath_unit);
chprintlnf (ch, "Weather vectors range from "
"%d to %d.", -1 * mud_info.max_vector, mud_info.max_vector);
chprintlnf (ch,
"The maximum a vector can " "change in one update is %d.",
mud_info.rand_factor + 2 * mud_info.climate_factor +
3 * mud_info.weath_unit);
cmd_syntax (ch, NULL, n_fun, "temp <number>", "precip <number>",
"wind <number>", NULL);
return false;
}
else if (!str_cmp (arg, "temp"))
{
int i;
argument = one_argument (argument, arg);
for (i = 0; i < MAX_CLIMATE; i++)
{
if (str_cmp (arg, temp_settings[i]))
continue;
area->weather.climate_temp = i;
olc_msg (ch, n_fun, "The climate temperature "
"for %s is now %s.", area->name, temp_settings[i]);
return true;
}
if (i == MAX_CLIMATE)
{
chprintlnf (ch, "Possible temperature settings:");
for (i = 0; i < MAX_CLIMATE; i++)
{
chprintlnf (ch, "\t%s", temp_settings[i]);
}
}
return false;
}
else if (!str_cmp (arg, "precip"))
{
int i;
argument = one_argument (argument, arg);
for (i = 0; i < MAX_CLIMATE; i++)
{
if (str_cmp (arg, precip_settings[i]))
continue;
area->weather.climate_precip = i;
olc_msg (ch, n_fun, "The climate precipitation "
"for %s is now %s.", area->name, precip_settings[i]);
return true;
}
if (i == MAX_CLIMATE)
{
chprintlnf (ch, "Possible precipitation settings:");
for (i = 0; i < MAX_CLIMATE; i++)
{
chprintlnf (ch, "\t%s", precip_settings[i]);
}
}
return false;
}
else if (!str_cmp (arg, "wind"))
{
int i;
argument = one_argument (argument, arg);
for (i = 0; i < MAX_CLIMATE; i++)
{
if (str_cmp (arg, wind_settings[i]))
continue;
area->weather.climate_wind = i;
olc_msg (ch, n_fun, "The climate wind for %s "
"is now %s.", area->name, wind_settings[i]);
return true;
}
if (i == MAX_CLIMATE)
{
chprintlnf (ch, "Possible wind settings:");
for (i = 0; i < MAX_CLIMATE; i++)
{
chprintlnf (ch, "\t%s", wind_settings[i]);
}
}
return false;
}
else
{
cmd_syntax (ch, NULL, n_fun, "temp <number>", "precip <number>",
"wind <number>", NULL);
return false;
}
}
void
time_update ()
{
AreaData *pArea;
Descriptor *d;
WeatherData *weath;
switch (++time_info.hour)
{
case 5:
case 6:
case HOURS_IN_DAY / 2:
case 19:
case 20:
for (pArea = area_first; pArea; pArea = pArea->next)
{
get_time_echo (&pArea->weather);
}
for (d = descriptor_first; d; d = d->next)
{
if (d->connected == CON_PLAYING &&
IsOutside (d->character) && IsAwake (d->character))
{
weath = &d->character->in_room->area->weather;
if (NullStr (weath->echo))
continue;
d_printlnf (d, "%s%s{x", weath->echo_color, weath->echo);
}
}
break;
case HOURS_IN_DAY:
time_info.hour = 0;
time_info.day++;
if (time_info.day % 10 == 0)
rw_time_data (act_write);
break;
}
if (time_info.day >= DAYS_IN_MONTH)
{
time_info.day = 0;
time_info.month++;
}
if (time_info.month >= MONTHS_IN_YEAR)
{
time_info.month = 0;
time_info.year++;
}
return;
}