pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/* calendar/weatehr routines Copyright (C)1993 Valentin Popescu */
#define CALENDAR_C

#include <strings.h>
#include "kernel.h"
#include "config.h"
#include "lflags.h"
#include "sflags.h"
#include "calendar.h"
#include "sendsys.h"
#include "bprintf.h"
#include "parse.h"
#include "utils.h"
#include "rooms.h"

CALENDAR calendar;
int temp_seed;
char old_weather;

static void _update_calendar (void);
static Boolean cold_weather (int loc);
static Boolean hot_weather (int loc);
static Boolean night_weather (void);
static void advance_weather (void);
static void announce_weather (void);
static void tell_weather (int user);

char *Weather[] =
{
  "sunny",
  "rainy",
  "cloudy",
  "clearing",
  "stormy"
};

char *c_seasons[] =
{
  "spring",
  "summer",
  "autumn",
  "winter"
};

char *c_modifiers[] =
{
  "an early-",
  "a ",
  "a late-"
};

char *c_day[] =
{
  "morning",
  "day",
  "afternoon",
  "evening",
  "night"
};

void init_calendar (void)
{
  calendar.season = 0;
  calendar.daytime = 0;
  calendar.daycount = 0;
  calendar.modifier = 1;
}

void update_calendar (void)
{
  _update_calendar ();
/*  compute_environment ();*/ /* Called from on_timer .. should be enough */
}

PRIVATE void _update_calendar (void)
{
  /* start with day, work up to season */
  
#ifdef MALLOC_DEBUG
  mnem_writestats ();
#endif
  
  
  if (calendar.daytime != NIGHT)
    calendar.daytime++;
  else
    calendar.daytime = MORNING;	/* new day */
  
  switch (calendar.daytime) {
  case MORNING:
      broad_realtime ("The sky lightens as the sun rises slowly in the east.\n");
      break;
  case EVENING:
      broad_realtime ("The sun begins to sink below the western horizon.\n");
      break;
  case NIGHT:
      broad_realtime ("The sun sets and darkness befalls the realm.\n");
      break;
  default:;
  }
  
  if (calendar.daytime)
    return;
  
  /* day has ended.. make a new random seed */
  temp_seed = 0;
  if (randperc () < 50)
    temp_seed += randperc () % 7;
  else
    temp_seed -= randperc () % 7;
  
  if (calendar.daycount != MONTH_DAYCOUNT)
    calendar.daycount++;
  else
    calendar.daycount = 0;
  
  if (calendar.daycount)
    return;
  
  /* 1 modifier has ended */
  
  
  if (calendar.modifier != LATE_SEASON)
    calendar.modifier++;
  else
    calendar.modifier = EARLY_SEASON;
  
  if (calendar.modifier)
    return;
  
  /* one season has ended */
  
  if (calendar.season != WINTER)
    calendar.season++;
  else
    calendar.season = SPRING;
  
  switch (calendar.season) {
  case WINTER:
      broad_realtime ("A brisk wind cuts through you as winter arrives.\n");
      break;
  case SUMMER:
      broad_realtime ("The summer Solstice arrives as the days seem longer.\n");
      break;
  case SPRING:
      broad_realtime ("The air fills with the songs of birds as spring "
		      "arrives.\n");
      break;
  case AUTUMN:
      broad_realtime ("The air cools and the leaves change colour as autumn "
		      "arrives.\n");
      break;
  }
  
  if (calendar.season)
    return;
  
  /* one year done! */
  
  calendar.season = SPRING;
  calendar.daytime = MORNING;
  calendar.daycount = 0;
  calendar.modifier = EARLY_SEASON;
}

void compute_environment (void)
{
  int temp;
/*  Boolean sign = False;*/
  temp = 0;
  
  if (randperc () < 20)
    return;
   /* sign = True;*/
  
  if (calendar.daytime == NIGHT)
    calendar.light = False;
  else
    calendar.light = True;
  
  /* using celsius temperatures */
  switch (calendar.season) {
    case SPRING:
      switch (calendar.modifier) {
      case EARLY_SEASON:
	  temp = SPRING_E_SEASON;
	  break;
      case MID_SEASON:
	  temp = SPRING_M_SEASON;
	  break;
      case LATE_SEASON:
	  temp = SPRING_L_SEASON;
	  break;
      }
      break;
    case SUMMER:
      switch (calendar.modifier) {
      case EARLY_SEASON:
	  temp = SUMMER_E_SEASON;
	  break;
      case MID_SEASON:
	  temp = SUMMER_M_SEASON;
	  break;
      case LATE_SEASON:
	  temp = SUMMER_L_SEASON;
	  break;
      }
      break;
    case AUTUMN:
      switch (calendar.modifier) {
      case EARLY_SEASON:
	  temp = AUTUMN_E_SEASON;
	  break;
      case MID_SEASON:
	  temp = AUTUMN_M_SEASON;
	  break;
      case LATE_SEASON:
	  temp = AUTUMN_L_SEASON;
	  break;
      }
      break;
    case WINTER:
      switch (calendar.modifier) {
      case EARLY_SEASON:
	  temp = WINTER_E_SEASON;
	  break;
      case MID_SEASON:
	  temp = WINTER_M_SEASON;
	  break;
      case LATE_SEASON:
	  temp = WINTER_L_SEASON;
	  break;
      }
      break;
  }
  
  /* adjust for time of day */
  
  switch (calendar.daytime) {
  case MORNING:
      temp T_MORNING;
      break;
  case DAY:
      temp T_DAY;
      break;
  case AFTERNOON:
      temp T_AFTERNOON;
      break;
  case EVENING:
      break;
  case NIGHT:
      temp T_NIGHT;
      break;
  }
  
  temp += temp_seed;
  
  
  /* if it is raining, change temp a bit */
  
  if (the_world->w_weather == RAIN || the_world->w_weather == STORMY)
    temp T_RAIN;
  
  
  calendar.temp = temp;
}


/* change calendar settings */
A_COMMAND(calendarcom)
{
  register int t;
  
  if (EMPTY (item1))
    {
      bprintf ("Usage: calendar [newsetting]\n");
      return;
    }
  
  /* change weather */
  
  
  for (t = SUNNY; t != (STORMY+1); t++)
    if (strncasecmp (Weather[t], item1, strlen (item1)) == 0)
      {
	the_world->w_weather = t;
	send_msg (DEST_ALL, MODE_QUIET | MODE_BRACKET, LVL_APPREN,
		  LVL_MAX, NOBODY, NOBODY,
		  "%s has changed weather to %s",
		  pname (mynum), Weather[t]);
	
	compute_environment ();
	return;
      }
  
  /* change season */
  
  for (t = SPRING; t != (WINTER + 1); t++)
    if (strncasecmp (c_seasons[t], item1, strlen (item1)) == 0)
      {
	calendar.season = t;
	sendf (DEST_ALL, "Season changed to %s.\n", c_seasons[t]);
	send_msg (DEST_ALL, MODE_QUIET | MODE_BRACKET, LVL_APPREN,
		  LVL_MAX, NOBODY, NOBODY,
		  "%s has changed season to %s",
		  pname (mynum), c_seasons[t]);
	compute_environment ();
	return;
      }
  
  /* change daytime */
  
  for (t = MORNING; t != (NIGHT + 1); t++)
    if (strncasecmp (c_day[t], item1, strlen (item1)) == 0)
      {
	calendar.daytime = t;
	sendf (DEST_ALL, "Daytime changed to %s.\n", c_day[t]);
	send_msg (DEST_ALL, MODE_QUIET | MODE_BRACKET, LVL_APPREN,
		  LVL_MAX, NOBODY, NOBODY,
		  "%s has changed daytime to %s",
		  pname (mynum), c_day[t]);
	compute_environment ();
	return;
      }
  
  bprintf ("Don't know how to modify that in the calendar.\n");
  return;
}


/* send a message to anyone subject to RealTime */


void broad_realtime (char *txt)
{
  register int t;
  
  for (t = 0; t < max_players; t++)
  {
      if (EMPTY (pname (t)))
	continue;
      if (!is_in_game(t))
        continue;
      if (!ltstflg (ploc (t), LFL_REALTIME) || ststflg (t, SFL_QUIET) || ststflg(t,SFL_NOWEATHER))
	continue;
      sendf (t, txt);
  }
  
  return;
}



void weather (void)
{
  advance_weather ();
  announce_weather ();
}

static void advance_weather (void)
{
  int t;
  
  old_weather = the_world->w_weather;
  
  switch (old_weather)
    {
    case SUNNY:
      if (randperc () < 30)
	return;			/* more sunny    */
      the_world->w_weather = CLOUDY;	/* clouds        */
      break;
    case CLOUDY:
      t = randperc ();
      if (t < 15)
	return;			/* more rain     */
      if (t < 30)
	the_world->w_weather = STORMY;	/* storm         */
      else
	the_world->w_weather = RAINY;	/* rain          */
      break;
    case RAINY:
      if (randperc () > 60)
	return;			/* more rain     */
      the_world->w_weather = CLEARING;	/* clearing      */
      break;
    case STORMY:
      if (randperc () < 25)
	return;			/* more storm    */
      the_world->w_weather = CLEARING;	/* clearing      */
      break;
    case CLEARING:
      t = randperc ();
      if (t < 20)
	return;			/* more clearing */
      if (t < 50)
	the_world->w_weather = RAINY;	/* rain          */
      else
	the_world->w_weather = SUNNY;	/* sunny         */
    }
}


/* sends a message to all users (calls tell_weather) */
static void announce_weather ()
{
  register int t;

  if (the_world->w_weather == old_weather)
    return;			/* no change */
  
  for (t = 0; t < max_players; t++)
  {
      if (is_in_game (t))
        if (!ststflg(t,SFL_NOWEATHER))
	  tell_weather (t);
  }
}

/* sends the weather to a particular user */
static void tell_weather (int user)
{
  if (!ltstflg (ploc (user), LFL_OUTDOORS) || ststflg (user, SFL_QUIET))
    return;
  
  switch (the_world->w_weather) {
  case SUNNY:
      sendf (user, "The world around you brightens a bit as the %s comes out "
	     "of the clouds.\n",
	     night_weather ()? "moon" : "sun");
      break;
  case RAINY:
      if (cold_weather (ploc (user)))
	sendf (user, "A few light snow flurries tumble to the ground.\n");
      else
	sendf (user, "A light rain falls gently upon the land.\n");
      break;
  case STORMY:
      if (cold_weather (ploc (user)))
	sendf (user, "You trudge onward through the heavy snows.\n");
      else
	sendf (user, "There is a loud crash as the sky fills with lightning.\n");
      break;
  case CLEARING:
      sendf (user, "The clouds begin to dissipate%s\n",
	     night_weather ()? ", revealing a stunning night sky" : ".");
      break;
  case CLOUDY:
      sendf (user, "Dark storm clouds begin to roll in.\n");
      break;
  }
}

char test_temp (void)
{
  int t = ploc (mynum);
  
  if (cold_weather (t))
    return (ISCOLD);
  if (hot_weather(t)) 
    return(ISHOT); 

  return (ISNORMAL);
}

/* this function does not account for levels */
Boolean is_real_dark (void)
{
  if (calendar.daytime == NIGHT)
    return (True);
  return (False);
  
}

static Boolean night_weather ()
{
  if (calendar.daytime == 3 || calendar.daytime == 4)
    return (True);
  return (False);
}


/* Give a description of the weather when walking into a room. */
void show_weather ()
{
  if (!ltstflg (ploc (mynum), LFL_OUTDOORS))
      return;
  
  switch (the_world->w_weather) {
  case RAIN:
      if (cold_weather (ploc (mynum)))
	bprintf ("Snow flurries are falling gently from the sky.\n");
      else
	bprintf ("A gentle rain is falling, making the ground soft and muddy.\n");
      break;
  case STORMY:
      if (cold_weather (ploc (mynum)))
	bprintf ("You shiver as you trudge on through the blizzard.\n");
      else
	bprintf ("There are huge, dark storm clouds in the sky above.\n");
      break;
  default:;
  }
}


char *short_weather ()
{ int c = cold_weather (ploc (mynum));
  
  switch (the_world->w_weather) {
  case RAINY:
      return (c ? "It is snowing and" : "It is raining and");
      break;
  case STORMY:
      return (c ? "You are in a blizzard and the weather is" :
	      "It is storming and the weather is");
      break;
  case SUNNY:
      return ("The sky is clear and the weather is");
      break;
  case CLOUDY:
      return ("The sky is cloudy and the weather is");
      break;
  case CLEARING:
      return ("The sky is beginning to clear and the weather is");
      break;
  }
  return("The weather just IS.");
}


char *wthr_type  (int type)
{
  static char b[20];
  
  switch (type) {
  case 0:
      sprintf (b, "sunny");
      break;
  case 1:
      sprintf (b, "rainy");
      break;
  case 2:
      sprintf (b, "cloudy");
      break;
  case 3:
      sprintf (b, "clearing");
      break;
  case 4:
      sprintf (b, "stormy");
      break;
  }
  return (b);
}

static Boolean cold_weather (int loc)
{
  /* if COLD, weather doesn't count */
  if (check_temp(loc) == LFL_COLD)
    return (True);

  /* if REALTIME and less than 4 deg celsius, it is cold */
  if (ltstflg (loc, LFL_REALTIME) && calendar.temp < 4)
    return (True);
  
  return (False);
}

static Boolean hot_weather(int loc)
{
   if (check_temp(loc) == LFL_HOT)
     return True;

   if (ltstflg(loc, LFL_REALTIME) && calendar.temp > 26)
     return True;

   return False;
}

char * real_light_state (int loc)
{
  static char b[15];
  
  if (is_real_dark ())
    sprintf (b, "NightTime");
  else
    sprintf (b, "DayLight");
  return b;
}

char * real_temp_state (int loc)
{
  static char b[15];
  
  compute_environment ();

  if (check_temp(loc) == LFL_COLD)
    sprintf (b, "Very Cold");
  else if (check_temp(loc) == LFL_HOT)
    sprintf(b, "Very Hot");
  else
    {
      if (calendar.temp > 30)
	sprintf (b, "Very Hot");
      else if (calendar.temp > 24)
	sprintf (b, "Hot");
      else if (calendar.temp > 18)
	sprintf (b, "Warm");
      else if (calendar.temp > 10)
	sprintf (b, "Cool");
      else if (calendar.temp > 5)
	sprintf (b, "Cold");
      else if (calendar.temp > 0)
	sprintf (b, "Very Cold");
      else
        sprintf(b,"Freezing");
    }
  return b;
}