final_realms_fluffos_v1/
final_realms_fluffos_v1/bin/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/ChangeLog.old/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/Win32/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/simuls/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/clone/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/command/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/data/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/etc/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/master/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/log/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/compiler/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/efuns/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/operators/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/u/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/tmp/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/windows/
final_realms_fluffos_v1/lib/baseobs/guilds/
final_realms_fluffos_v1/lib/baseobs/misc/
final_realms_fluffos_v1/lib/baseobs/races/shadows/
final_realms_fluffos_v1/lib/cmds/god/
final_realms_fluffos_v1/lib/cmds/handlers/
final_realms_fluffos_v1/lib/cmds/handlers/cmds/
final_realms_fluffos_v1/lib/d/heaven/
final_realms_fluffos_v1/lib/d/heaven/heaven/ave/
final_realms_fluffos_v1/lib/d/mudlib/
final_realms_fluffos_v1/lib/d/newbie/
final_realms_fluffos_v1/lib/d/newbie/docs/
final_realms_fluffos_v1/lib/d/newbie/drow/armour/
final_realms_fluffos_v1/lib/d/newbie/drow/items/
final_realms_fluffos_v1/lib/d/newbie/drow/mobs/
final_realms_fluffos_v1/lib/d/newbie/drow/oldmobs/
final_realms_fluffos_v1/lib/d/newbie/drow/weapons/
final_realms_fluffos_v1/lib/d/newbie/duergar/weapons/
final_realms_fluffos_v1/lib/d/newbie/dwarf/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/cafe/
final_realms_fluffos_v1/lib/d/newbie/elf/chars/equip/
final_realms_fluffos_v1/lib/d/newbie/elf/items/armours/
final_realms_fluffos_v1/lib/d/newbie/elf/items/obj/
final_realms_fluffos_v1/lib/d/newbie/elf/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/quick_fix/
final_realms_fluffos_v1/lib/d/newbie/gnome/armour/
final_realms_fluffos_v1/lib/d/newbie/gnome/buildings/
final_realms_fluffos_v1/lib/d/newbie/gnome/items/
final_realms_fluffos_v1/lib/d/newbie/gnome/npcs/clones/
final_realms_fluffos_v1/lib/d/newbie/gnome/rooms/northrooms/
final_realms_fluffos_v1/lib/d/newbie/gnome/weapons/
final_realms_fluffos_v1/lib/d/newbie/goblin/armour/
final_realms_fluffos_v1/lib/d/newbie/goblin/items/
final_realms_fluffos_v1/lib/d/newbie/grads/log/
final_realms_fluffos_v1/lib/d/newbie/grads/npcs/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/cave1/
final_realms_fluffos_v1/lib/d/newbie/grads/temp/
final_realms_fluffos_v1/lib/d/newbie/guests/weapons/
final_realms_fluffos_v1/lib/d/newbie/half-elf/items/
final_realms_fluffos_v1/lib/d/newbie/half-elf/newroomss/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/castle/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/drows/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/savannah/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/secret/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/town/
final_realms_fluffos_v1/lib/d/newbie/halfling/
final_realms_fluffos_v1/lib/d/newbie/halfling/misc/
final_realms_fluffos_v1/lib/d/newbie/halfling/rooms/cave/
final_realms_fluffos_v1/lib/d/newbie/human/
final_realms_fluffos_v1/lib/d/newbie/human/armour/
final_realms_fluffos_v1/lib/d/newbie/human/monsters/
final_realms_fluffos_v1/lib/d/newbie/human/obj/
final_realms_fluffos_v1/lib/d/newbie/human/weapons/
final_realms_fluffos_v1/lib/d/newbie/lizard/armour/
final_realms_fluffos_v1/lib/d/newbie/lizard/items/
final_realms_fluffos_v1/lib/d/newbie/lizard/underwater/
final_realms_fluffos_v1/lib/d/newbie/lizard/weapons/
final_realms_fluffos_v1/lib/d/newbie/logs/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/rooms/
final_realms_fluffos_v1/lib/d/newbie/newelf/
final_realms_fluffos_v1/lib/d/newbie/newelf/chars/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/recopied/
final_realms_fluffos_v1/lib/d/newbie/newelf/obj/
final_realms_fluffos_v1/lib/d/newbie/newelf/quest_docs./
final_realms_fluffos_v1/lib/d/newbie/newken/
final_realms_fluffos_v1/lib/d/newbie/newken/chars/
final_realms_fluffos_v1/lib/d/newbie/newken/misc/
final_realms_fluffos_v1/lib/d/newbie/newken/npcs/
final_realms_fluffos_v1/lib/d/newbie/newken/obj/
final_realms_fluffos_v1/lib/d/newbie/newliz/
final_realms_fluffos_v1/lib/d/newbie/newliz/cave/
final_realms_fluffos_v1/lib/d/newbie/newliz/npcs/
final_realms_fluffos_v1/lib/d/newbie/orc/items/misc/
final_realms_fluffos_v1/lib/d/newbie/orc/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/orc/tower/
final_realms_fluffos_v1/lib/d/vehicle/
final_realms_fluffos_v1/lib/doc/
final_realms_fluffos_v1/lib/doc/driver/
final_realms_fluffos_v1/lib/doc/driver/concepts/
final_realms_fluffos_v1/lib/doc/driver/driver/
final_realms_fluffos_v1/lib/doc/driver/efuns/arrays/
final_realms_fluffos_v1/lib/doc/driver/efuns/bitstrings/
final_realms_fluffos_v1/lib/doc/driver/efuns/communication/
final_realms_fluffos_v1/lib/doc/driver/efuns/core/
final_realms_fluffos_v1/lib/doc/driver/efuns/debugging/
final_realms_fluffos_v1/lib/doc/driver/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/driver/efuns/interactive/
final_realms_fluffos_v1/lib/doc/driver/efuns/mappings/
final_realms_fluffos_v1/lib/doc/driver/efuns/objects/
final_realms_fluffos_v1/lib/doc/driver/efuns/security/
final_realms_fluffos_v1/lib/doc/driver/efuns/strings/
final_realms_fluffos_v1/lib/doc/driver/efuns/system/
final_realms_fluffos_v1/lib/doc/driver/efuns/types/
final_realms_fluffos_v1/lib/doc/driver/lpc/constructs/
final_realms_fluffos_v1/lib/doc/driver/lpc/types/
final_realms_fluffos_v1/lib/doc/driver/platforms/
final_realms_fluffos_v1/lib/doc/lpc/
final_realms_fluffos_v1/lib/doc/mail/
final_realms_fluffos_v1/lib/doc/man/
final_realms_fluffos_v1/lib/doc/man/html/
final_realms_fluffos_v1/lib/doc/man/html/applies/
final_realms_fluffos_v1/lib/doc/man/html/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/html/driver/
final_realms_fluffos_v1/lib/doc/man/html/efuns/
final_realms_fluffos_v1/lib/doc/man/html/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/html/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/html/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/html/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/html/efuns/general/
final_realms_fluffos_v1/lib/doc/man/html/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/
final_realms_fluffos_v1/lib/doc/man/local/applies/
final_realms_fluffos_v1/lib/doc/man/local/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/local/applies/master/
final_realms_fluffos_v1/lib/doc/man/local/concepts/
final_realms_fluffos_v1/lib/doc/man/local/defines/
final_realms_fluffos_v1/lib/doc/man/local/driver/
final_realms_fluffos_v1/lib/doc/man/local/efuns/
final_realms_fluffos_v1/lib/doc/man/local/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/local/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/local/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/local/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/local/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/local/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/local/efuns/general/
final_realms_fluffos_v1/lib/doc/man/local/efuns/interactive/
final_realms_fluffos_v1/lib/doc/man/local/efuns/internals/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/local/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/objects/
final_realms_fluffos_v1/lib/doc/man/local/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/efuns/sockets/
final_realms_fluffos_v1/lib/doc/man/local/efuns/strings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/system/
final_realms_fluffos_v1/lib/doc/man/local/historical/
final_realms_fluffos_v1/lib/doc/man/local/lfun/QC/
final_realms_fluffos_v1/lib/doc/man/local/lfun/events/
final_realms_fluffos_v1/lib/doc/man/local/lfun/monster/
final_realms_fluffos_v1/lib/doc/man/local/lfun/properties/
final_realms_fluffos_v1/lib/doc/man/local/lpc/
final_realms_fluffos_v1/lib/doc/man/local/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/local/lpc/types/
final_realms_fluffos_v1/lib/doc/man/local/standards/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/basic/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/intermediate/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/concepts/
final_realms_fluffos_v1/lib/doc/man/mudos/driver/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/general/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mixed/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/types/
final_realms_fluffos_v1/lib/doc/races/
final_realms_fluffos_v1/lib/doc/races/old_race/
final_realms_fluffos_v1/lib/global/virtual/
final_realms_fluffos_v1/lib/global/wiz_backup/
final_realms_fluffos_v1/lib/net/config/
final_realms_fluffos_v1/lib/net/daemon/chars/
final_realms_fluffos_v1/lib/net/inherit/
final_realms_fluffos_v1/lib/net/intermud3/
final_realms_fluffos_v1/lib/net/intermud3/cmds/
final_realms_fluffos_v1/lib/net/intermud3/save/
final_realms_fluffos_v1/lib/net/intermud3/services/
final_realms_fluffos_v1/lib/net/obj/
final_realms_fluffos_v1/lib/net/old/
final_realms_fluffos_v1/lib/net/old/intermud/
final_realms_fluffos_v1/lib/net/old/intermud/adm/
final_realms_fluffos_v1/lib/net/old/intermud/services/
final_realms_fluffos_v1/lib/net/old/intermud/udp/
final_realms_fluffos_v1/lib/net/virtual/
final_realms_fluffos_v1/lib/obj/b_day/
final_realms_fluffos_v1/lib/obj/chars/
final_realms_fluffos_v1/lib/obj/handlers/lists/
final_realms_fluffos_v1/lib/obj/handlers/useless/
final_realms_fluffos_v1/lib/obj/monsters/
final_realms_fluffos_v1/lib/obj/roomgen/
final_realms_fluffos_v1/lib/obj/soul/
final_realms_fluffos_v1/lib/obj/vegetation/
final_realms_fluffos_v1/lib/obj/weapons/oldsys/
final_realms_fluffos_v1/lib/open/
final_realms_fluffos_v1/lib/players/g/
final_realms_fluffos_v1/lib/releasefiles/d/heaven/
final_realms_fluffos_v1/lib/releasefiles/d/mudlib/
final_realms_fluffos_v1/lib/releasefiles/d/newbie/
final_realms_fluffos_v1/lib/releasefiles/doc/
final_realms_fluffos_v1/lib/releasefiles/players/g/
final_realms_fluffos_v1/lib/releasefiles/save/
final_realms_fluffos_v1/lib/releasefiles/save/environ/
final_realms_fluffos_v1/lib/releasefiles/save/roomgen/
final_realms_fluffos_v1/lib/releasefiles/secure/
final_realms_fluffos_v1/lib/releasefiles/w/
final_realms_fluffos_v1/lib/releasefiles/w/god/
final_realms_fluffos_v1/lib/room/
final_realms_fluffos_v1/lib/save/
final_realms_fluffos_v1/lib/save/environ/
final_realms_fluffos_v1/lib/save/roomgen/
final_realms_fluffos_v1/lib/scripts/
final_realms_fluffos_v1/lib/secure/crerem/
final_realms_fluffos_v1/lib/secure/dom/
final_realms_fluffos_v1/lib/secure/log/
final_realms_fluffos_v1/lib/secure/misc/
final_realms_fluffos_v1/lib/std/adnd/
final_realms_fluffos_v1/lib/std/commands/shadows/
final_realms_fluffos_v1/lib/std/creator/
final_realms_fluffos_v1/lib/std/curses/
final_realms_fluffos_v1/lib/std/curses/old_sys/
final_realms_fluffos_v1/lib/std/curses/shadows/
final_realms_fluffos_v1/lib/std/dom/
final_realms_fluffos_v1/lib/std/effects/
final_realms_fluffos_v1/lib/std/effects/healing/
final_realms_fluffos_v1/lib/std/effects/other/
final_realms_fluffos_v1/lib/std/effects/poisons/
final_realms_fluffos_v1/lib/std/environ/
final_realms_fluffos_v1/lib/std/guilds/
final_realms_fluffos_v1/lib/std/guilds/priests/samples/
final_realms_fluffos_v1/lib/std/guilds/wizards/
final_realms_fluffos_v1/lib/std/living/baldy/
final_realms_fluffos_v1/lib/std/living/divstuff/
final_realms_fluffos_v1/lib/std/paran/
final_realms_fluffos_v1/lib/std/poisons/
final_realms_fluffos_v1/lib/std/poisons/shadows/
final_realms_fluffos_v1/lib/std/poisons/weapons/
final_realms_fluffos_v1/lib/std/race_groups/
final_realms_fluffos_v1/lib/std/room/
final_realms_fluffos_v1/lib/std/room/old/
final_realms_fluffos_v1/lib/std/rooms/
final_realms_fluffos_v1/lib/std/shadows/
final_realms_fluffos_v1/lib/std/shadows/test_shad/
final_realms_fluffos_v1/lib/std/socket/
final_realms_fluffos_v1/lib/std/spells/
final_realms_fluffos_v1/lib/std/vaults/
final_realms_fluffos_v1/lib/tmp/
final_realms_fluffos_v1/lib/w/
final_realms_fluffos_v1/lib/w/god/
final_realms_fluffos_v1/old/
final_realms_fluffos_v1/win32/
inherit "std/object";
 
#include "climate.h"
#define FILE_NAME "/save/environ/weather"
#define HOME "/obj/handlers/weather_room.c"
#define MAX_DIST 100
#define YEAR 168
#define DAY 60
#define SPEED 60
 
/*
 * 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.
 *
 * Complaints complaints.  Ok, I might comment some of it.
 */
 
mixed *coldarr,
      *cloudarr,
      *rainarr;

static mapping my_obs;
 
int div,
    year,
    timeofyear,
    mooncycle,
    moonoff,
    timeofday;

mixed * global_climate;   /* some more stuff - anjou@nanvaent */
    
 
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);
string season_string(object env);
string daynight_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");
// taniwha. will this let it read it's own save file ?
  seteuid((string)master()->creator_file(file_name(this_object())));
/*
 * The default arrays, we use offsets from these to determine the weather
 * The reason for haveing 3 of them is to average the effect, so in effect
 * extremes are possible but more unlikely.  By adding more or taking
 * some of these arrays away you can generate greater or lesser swings
 * of weather in your mud.
 */
  cloudarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) });
  rainarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) });
  coldarr = ({ ({ 0,0 }), ({ 50,50 }), ({ -50,-50 }) });
  my_obs = ([ ]);
 
  restore_object(FILE_NAME,1);

  /* defaults for GLOBAL CLIMATE -> anjou@nanvaent 
   * for C_TEMP, C_CLOUD and C_RAIN. First value is C_OFFSET, then C_WEIGHT
   * [e.g.  global_climate = ({ ({0,10}), ({0,10}), ({0,10}), })]
   *
   * default_weight() is default weight.
   */
  if (!global_climate) global_climate = ({ 0,0,0 });

  /* ***************************************** */
  

  call_out("update_low",SPEED);
  move("bing");
}
 
/*
 * set-up function returns default fluctuation of weather
 * 1 is for wild fluctuation, 10 steady (Anjou)
 */
int default_weight()
{
/* let's put the default here for safe keeping :-> ANJOU */
#define DEFAULT_WEIGHT 10 
  return DEFAULT_WEIGHT;
}


/* have this move here to get it to my weather room ;) (Sleaze) */
int move(string arg) {
  ::move(HOME);
}

/*
 * The object asks to be told about weather events
 */
void notify_me(object ob) {
  my_obs[ob]++;
}

/*
 * The object tells us it is really bored by these damn stupid weather events/
 */
void unnotify_me(object ob) {
  if (--my_obs[ob] <= 0)
    my_obs = m_delete(my_obs, ob);
}

/* Debug, sort of usefulish */
mixed *query_cold() { return coldarr; }
mixed *query_rain() { return rainarr; }
mixed *query_cloud() { return cloudarr; }

/* Moon cycle and the string we would give if the moon was up */
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];
}

/*
 * This is the routine used to caculate the distance between 2 3-d points.
 * Messy...  So, I did it the easy way :)  It isn't a perfect alorithm
 * for this but it suits our purposes. (and is a lot quicker than any
 * other algorithm)
 */
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;
}

/* Four seasons of course. */
int query_season() { return timeofyear/(YEAR/4); }

/* Relatively useless ionformation, but hey you might want it! */
int query_time_of_year() { return timeofyear; }
int query_time_of_day() { return timeofday; }

/*
 * Return 0 if it is night or non zero if it is day.   It returns how
 * "dayish" it is.
 */
int query_day(object env) {
  int bing, bit;
 
  if (!env) {
    env = find_object("/d/ss/daggerford/ladyluck");
    if (!env)
      call_other("/d/ss/daggerford/ladyluck", "??");
    env = find_object("/d/ss/daggerford/ladyluck");
  }
/* make it change over the mud... but not very quickly... */
  bing = timeofday - (DAY/4) -
         (distance((mixed *)env->query_co_ord(), ({ 0, 0, 0, }))/100);
  if (bing<0) bing += DAY;
/*
 * Create the break point for each day.  Depends on time of year, and length
 * of year.
 */
  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;
/* This is why query_day returns an obscure number */
  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? */
}
 
/* The rain/cloud/temperature weather string is concatenated here */
string weather_string(object env) {
  return temperature_string(env)+" "+season_string(env)+
    daynight_string(env)+" with "+cloud_string(env)+
    rain_string(env);
}

/*
 * Used by the player object to create nicer messages for weather changeing.
 * Returns the current type of rain.  ({ 0, 0 }) is no rain.
 * ({ 1, intensity }) is rain.
 * ({ 2, intensity }) is hail.
 * ({ 3, intensity }) is snow.
 */
mixed *query_type_rain(object env) {
  int ind, cloud, rain;

  cloud = cloud_index(env);
  if (cloud <= 0)
    return ({ 0, 0 });
  rain = rain_index(env);
  if (cloud - rain <= 0)
    return ({ 0, 0 });
  ind = temperature_index(env)/(100/7);
  if (ind < 2)
    return ({ 1, cloud-rain });
  if (ind == 2)
    return ({ 2, cloud-rain });
  return ({ 3, cloud-rain });
}

/* So is it raining where you are? */
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;
}
 
/* Maybe its hailing instead? */
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;
}
 
/* Nahhh, must be snowing */
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 = rain_index(env);
    if (cloud-rain<=0)
      return 0;
    return cloud-rain;
  }
  return 0;
}
 
/*
 * A nice string tells us how heavy and what temperature the rain/hail/snow
 * is.
 */
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;
/* hmmm -> surely u mean FOUR pinkfish? - ok ill add "torrential" instead */
  return "\n"+capitalize(tempstr1 + ({ "very light",
                      "light",
                      "medium",
                      "heavy",
                      "very heavy",
              "torrential", }) [cloud]+tempstr2);
}
 
/* String for seasons.  Santino 01/97 */

string season_string(object env) {
  int my_season;
  my_season = query_season();

  return ({ "spring ", /* 0 */
        "summer ", /* 1 */
        "autumn ", /* 2 */
        "winter " })[my_season]; /* 3 */
}

/* Is it day or night? (for general weather string) Santino, 01/97 */

string daynight_string(object env) {
  int daynight;
  daynight = query_day(env);
  if(daynight > 0)
    daynight = 1;
  if(daynight < 0)
    daynight = 1;
  return ({ "night", /* 0 */
        "day" })[daynight]; /* 1 */
}

string temperature_string(object env) {
  int inten;
  inten = temperature_index(env);
  inten /= 10;
  if (inten>10)
    inten = 10;
  if (inten<-10)
    inten = -10;
  return ({ "It's a hellishly hot", /* -10 */
    "It's an unnaturally hot", /* -9 */
            "Damn hot", /* -8 */
            "Very hot", /* -7 */
            "Hot", /* -6 */
            "Hot", /* -5 */
            "Reasonably hot", /* -4 */
            "Very warm", /* -3 */
            "Warm", /* -2 */
            "Pleasantly warm", /* -1 */
            "Average temperature", /* 0 */
    "A slightly chilly", /* 1 */
    "A slightly nippy", /* 2 */
            "Chilly", /* 3 */
            "Very chilly", /* 4 */
            "Cold", /* 5 */
            "Cold", /* 6 */
            "Very cold", /* 7 */
            "Damn cold", /* 8 */
            "Incredibly cold", /* 9 */
            "Freezing cold" })[inten+10]; /* 10 */
}

/* Cloud string....  Makes a nice cloud message for you. */
string cloud_string(object env) {
  int off;
 
  off = cloud_index(env) / 20;
  if (off>5) off = 5;
  if (off<-5) off = -5;
  return ({ "a beautifully 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];
}
 
/*
 * Used by the temperature string and other things, returns a nice number
 * which is how HOT it currently is.
 * Returns a number from approximately -100 to 100.  Can get higher or lower
 * But the chance of this is really unlikely....
 */
int temperature_index(object env) {
  int off, i, div;
  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 (off>MAX_DIST) off = (MAX_DIST*2) - off;
  if ((clim = (mixed *)env->query_property("climate"))) {
    if (!pointerp(clim[C_TEMP])) {
      off += clim[C_TEMP];
      div = default_weight();
    } else {
      off += clim[C_TEMP][C_OFFSET];
      div = clim[C_TEMP][C_WEIGHT];
    }
  } else { /* ANJOU@NANVAENT */
    if (!pointerp(global_climate[C_TEMP])) {
      off += global_climate[C_TEMP];
      div = default_weight();
    } else {
      off += global_climate[C_TEMP][C_OFFSET];
      div = global_climate[C_TEMP][C_WEIGHT];
      if (!div) div = default_weight();
    }
  }
  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))/((YEAR/60)+1) +
         (timeofday - (DAY/2))/((DAY/30)+1) + co_ord[2]))*10)/div;
}
 
/*
 *  The range is the same as for the rain index.  Returns how cloudy it is.
 */
int cloud_index(object env) {
  int off;
  mixed *clim;
  int i;
 
  if(!sizeof(cloudarr)) return 0;
  for (i=0;i<sizeof(cloudarr);i++)
    off += (distance((mixed *)env->query_co_ord(), cloudarr[i]) % (MAX_DIST*2));
  off = off / sizeof(cloudarr);
  if (off>MAX_DIST) off = (MAX_DIST*2) - off;
  if ((clim = (mixed *)env->query_property("climate"))) {
    if (!pointerp(clim[C_CLOUD])) {
      off += clim[C_CLOUD];
      div = default_weight();
    } else {
      off += clim[C_CLOUD][C_OFFSET];
      div = clim[C_CLOUD][C_WEIGHT];
    }
  } else { /* ANJOU@NANVAENT */
    if (!pointerp(global_climate[C_CLOUD])) {
      off += global_climate[C_CLOUD];
      div = default_weight();
    } else {
      off += global_climate[C_CLOUD][C_OFFSET];
      div = global_climate[C_CLOUD][C_WEIGHT];
      if (!div) div = default_weight();
    }
  }
  off -= (MAX_DIST/2);
  off = 0-off;
  return ((off + (timeofyear - (YEAR/2))/((YEAR/60)+1))*10)/div;
}

/*
 * You guessed it....
 */
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 (off>MAX_DIST) off = (MAX_DIST*2) - off;
  if ((clim = (mixed *)env->query_property("climate"))) {
    if (!pointerp(clim[C_RAIN])) {
      off += clim[C_RAIN];
      div = default_weight();
    } else {
      off += clim[C_RAIN][C_OFFSET];
      div = clim[C_RAIN][C_WEIGHT];
    }
  } else { /* ANJOU@NANVAENT */
    if (!pointerp(global_climate[C_RAIN])) {
      off += global_climate[C_RAIN];
      div = default_weight();
    } else {
      off += global_climate[C_RAIN][C_OFFSET];
      div = global_climate[C_RAIN][C_WEIGHT];
      if (!div) div = default_weight();
    }
  }
  off -= MAX_DIST/2;
  off = 0-off;
  return (off*10)/div;
}
 
/* Updates the postion of all the arrays used to calculate weather. */
void update_low() {
  int i;
  object *obs;

/* Increase the time of day. */
  timeofday++;
  if (timeofday>DAY) {
/* Greater than time of day, inc time of year and moon cycle */
    timeofday = 0;
    timeofyear++;
    mooncycle++;
    if (mooncycle %2) {
      moonoff += 1;
      moonoff = moonoff % (DAY/2);
    }
    timeofyear = (i=timeofyear) % YEAR;
    if (i != timeofyear) /* New year */
      year++;
    mooncycle = mooncycle % 10;
    save_object(FILE_NAME,1);
  }
/* Update the rain arrays */
  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);
  }
/* Update the cloud arrays */
  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);
  }
/* Update the temperature arrays */
  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);
  }
  obs = m_indices(my_obs);
  for (i=0;i<sizeof(obs);i++)
    if (objectp(obs[i]))
      event(obs[i], "weather");
  call_out("update_low",SPEED);
}

void dest_me() {
  save_object(FILE_NAME,1);
  ::dest_me();
}


/*
 * Some nice functions to deal with global weather offsets & weights.
 * 
 * ANJOU@NANVAENT - please hack these to hell pf!
 *
 */
void save_weather() {  save_object(FILE_NAME,1); }

mixed * query_global_climate()
{
  return global_climate;
}

mixed * set_global_climate(mixed * clime)
{
  /* need root privs to set global climate */
  if (geteuid(this_player())=="Root") {
    global_climate = clime;
    save_weather();
  }
  return global_climate;
}

status check_valid_type(int type)
{
  if (type < C_TEMP || type > C_RAIN) return 0; else return 1;
}

mixed * adjust_global_offset(int type, int amount)
{
  mixed * temp_climate;
  if (!check_valid_type(type)) return global_climate;
  temp_climate = global_climate;
  temp_climate[type][C_OFFSET] += amount;
  return set_global_climate(temp_climate);
}

mixed * adjust_global_weight(int type, int amount)
{
  mixed * temp_climate;
  if (!check_valid_type(type)) return global_climate;
  temp_climate = global_climate;
  temp_climate[type][C_WEIGHT] += amount;
  return set_global_climate(temp_climate);
}

mapping olav() { return my_obs; }