LONG: Weather code (woo hoo!)

From: Ryan A.J. Biggs (ae744@freenet.toronto.on.ca)
Date: 07/10/96


Weather Code.....

weather.c
----snip here-----
/* ************************************************************************
*   File: weather.c                                     Part of CircleMUD *
*  Usage: functions handling time and the weather                         *
*                                                                         *
*  All rights reserved.  See license.doc for complete information.        *
*                                                                         *
*  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
*  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
************************************************************************ */

#include "conf.h"
#include "sysdep.h"


#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "handler.h"
#include "interpreter.h"
#include "db.h"

extern struct time_info_data time_info;

void weather_and_time(int mode);
void another_hour(int mode);
void weather_change(void);


void weather_and_time(int mode)
{
  another_hour(mode);
  if (mode)
    weather_change();
}


void another_hour(int mode)
{
  time_info.hours++;

  if (mode) {
    switch (time_info.hours) {
    case 5:
      weather_info.sunlight = SUN_RISE;
      send_to_outdoor("The sun rises in the east.\r\n");
      break;
    case 6:
      weather_info.sunlight = SUN_LIGHT;
      send_to_outdoor("The day has begun.\r\n");
      break;
    case 19:
      weather_info.sunlight = SUN_SET;
      send_to_outdoor("The sun slowly disappears in the west.\r\n");
      break;
    case 20:
      weather_info.sunlight = SUN_DARK;
      send_to_outdoor("The night has begun.\r\n");
      break;
    default:
      break;
    }
  }
  if (time_info.hours > 23) {	/* Changed by HHS due to bug ??? */
    time_info.hours -= 24;
    time_info.day++;

    if (time_info.day > 34) {
      time_info.day = 0;
      time_info.month++;

      if (time_info.month > 18) {
	time_info.month = 0;
	time_info.year++;
      }
    }
  }
}


void weather_change(void)
{
  int diff, change;
  if (weather_info.humidity >= 50)
    diff = -1;
  else
    diff = 1;

  weather_info.change += (dice(1, 5) * diff + dice(1, 5) - dice(1, 5));

  weather_info.humidity += weather_info.change;

  weather_info.humidity = MAX(weather_info.humidity, 0);
  weather_info.humidity = MIN(weather_info.humidity, 100);

  change = 0;

  if ((time_info.month >= 0) && (time_info.month <= 4)) {
    switch (weather_info.sky) {
      case SKY_SUNNY:
        if (weather_info.humidity > 10)
          change = 2;
        break;
      case SKY_CLEAR:
        if (weather_info.humidity >40)
          change = 4;
        if (weather_info.humidity <= 10)
          change = 1;
        break;
      case SKY_PARTCLOUD:
        if (weather_info.humidity > 50)
          change = 6;
        if (weather_info.humidity <= 30)
          change = 3;
        break;
      case SKY_CLOUDY:
        if (weather_info.humidity > 60)
          change = 8;
        if (weather_info.humidity <= 40)
          change = 5;
        break;
      case SKY_SNOWING:
        if (weather_info.humidity > 85)
          change = 10;
        if (weather_info.humidity <= 50)
          change = 7;
        break;
      case SKY_SNOWSTORM:
        if (weather_info.humidity > 95)
          change = 12;
        if (weather_info.humidity <= 75)
          change = 9;
        break;
      case SKY_BLIZZARD:
        if (weather_info.humidity <= 90)
          change = 11;
        break;
      default:
        change = 0;
        weather_info.sky = SKY_PARTCLOUD;
        break;
    }
  } else if ((time_info.month >= 5) && (time_info.month <= 9)) {
    switch (weather_info.sky) {
      case SKY_HEATWAVE:
        if (weather_info.humidity > 5)
          change = 2;
      case SKY_SIZZLING:
        if (weather_info.humidity > 20)
          change = 4;
        if (weather_info.humidity <= 5)
          change = 1;
        break;
      case SKY_SUNNY:
        if (weather_info.humidity > 40)
          change = 6;
        if (weather_info.humidity <= 10)
          change = 3;
        break;
      case SKY_CLEAR:
        if (weather_info.humidity > 50)
          change = 8;
        if (weather_info.humidity <= 30)
          change = 5;
        break;
      case SKY_PARTCLOUD:
        if (weather_info.humidity > 60)
          change = 10;
        if (weather_info.humidity <= 40)
          change = 7;
        break;
      case SKY_CLOUDY:
        if (weather_info.humidity > 65)
          change = 12;
        if (weather_info.humidity <= 50)
          change = 9;
        break;
      case SKY_RAINING:
        if (weather_info.humidity > 85)
          change = 14;
        if (weather_info.humidity <= 55)
          change = 11;
        break;
      case SKY_POURING:
        if (weather_info.humidity > 95)
          change = 16;
        if (weather_info.humidity <= 75)
          change = 13;
        break;
      case SKY_THUNDERSTORM:
        if (weather_info.humidity > 99)
          change = 18;
        if (weather_info.humidity <= 90)
          change = 15;
        break;
      case SKY_TORNADO:
        if (weather_info.humidity <= 95)
          change = 17;
        break;
      default:
        change = 0;
        weather_info.sky = SKY_CLEAR;
        break;
    }
  } else if ((time_info.month >= 10) && (time_info.month <= 14)) {
    switch (weather_info.sky) {
      case SKY_HEATWAVE:
        if (weather_info.humidity > 10)
          change = 2;
      case SKY_SIZZLING:
        if (weather_info.humidity > 35)
          change = 4;
        if (weather_info.humidity <= 10)
          change = 1;
        break;
      case SKY_SUNNY:
        if (weather_info.humidity >70)
          change = 6;
        if (weather_info.humidity <= 25)
          change = 3;
        break;
      case SKY_CLEAR:
        if (weather_info.humidity > 80)
          change = 8;
        if (weather_info.humidity <= 60)
          change = 5;
        break;
      case SKY_PARTCLOUD:
        if (weather_info.humidity > 85)
          change = 10;
        if (weather_info.humidity <= 70)
          change = 7;
        break;
      case SKY_CLOUDY:
        if (weather_info.humidity > 90)
          change = 12;
        if (weather_info.humidity <= 75)
          change = 9;
        break;
      case SKY_RAINING:
        if (weather_info.humidity > 95)
          change = 14;
        if (weather_info.humidity <= 85)
          change = 11;
        break;
      case SKY_POURING:
        if (weather_info.humidity > 99)
          change = 16;
        if (weather_info.humidity <= 90)
          change = 13;
        break;
      case SKY_THUNDERSTORM:
        if (weather_info.humidity > 99)
            change = 18;
        if (weather_info.humidity <= 95)
          change = 15;
        break;
      case SKY_TORNADO:
        if (weather_info.humidity <= 99)
          change = 17;
        break;
      default:
        change = 0;
        weather_info.sky = SKY_CLEAR;
        break;
    }
  } else if ((time_info.month >= 15) && (time_info.month <= 19)) {
    switch (weather_info.sky) {
      case SKY_SUNNY:
        if (weather_info.humidity > 15)
          change = 2;
        break;
      case SKY_CLEAR:
        if (weather_info.humidity > 50)
          change = 4;
        if (weather_info.humidity <= 15)
          change = 1;
        break;
      case SKY_PARTCLOUD:
        if (weather_info.humidity > 65)
          change = 6;
        if (weather_info.humidity <= 40)
          change = 3;
        break;
      case SKY_CLOUDY:
        if (weather_info.humidity > 85)
          change = 8;
        if (weather_info.humidity <= 55)
          change = 5;
        break;
      case SKY_SNOWING:
        if (weather_info.humidity > 95)
          change = 10;
        if (weather_info.humidity <= 75)
          change = 7;
        break;
      case SKY_SNOWSTORM:
        if (weather_info.humidity > 99)
          change = 12;
        if (weather_info.humidity <= 90)
          change = 9;
        break;
      case SKY_BLIZZARD:
        if (weather_info.humidity <= 95)
          change = 11;
        break;
      default:
        change = 0;
        weather_info.sky = SKY_PARTCLOUD;
        break;
    }
  }
  if ((time_info.month >= 5) && (time_info.month <=14)) {
    switch (change) {
    case 0:
      break;
    case 1:
      send_to_outdoor("You begin to burn up as a heat wave starts.\r\n");
      weather_info.sky = SKY_HEATWAVE;
      break;
    case 2:
      send_to_outdoor("The heat wave lets up, but it is still hot.\r\n");
      weather_info.sky = SKY_SIZZLING;
      break;
    case 3:
      send_to_outdoor("The temperature starts to get significantly 
hotter.\r\n");
      weather_info.sky = SKY_SIZZLING;
      break;
    case 4:
      send_to_outdoor("The temperature gets cooler but is still hot 
out.\r\n");
      weather_info.sky = SKY_SUNNY;
      break;
    case 5:
      send_to_outdoor("It starts to get warmer out.\r\n");
      weather_info.sky = SKY_SUNNY;
      break;
    case 6:
      send_to_outdoor("It starts to get cooler, but the sky remains 
clear.\r\n");
      weather_info.sky = SKY_CLEAR;
      break;
    case 7:
      send_to_outdoor("The clouds blow off and you see the clear sky.\r\n");
      weather_info.sky = SKY_CLEAR;
      break;
    case 8:
      send_to_outdoor("Clouds starts to move in overhead.\r\n");
      weather_info.sky = SKY_PARTCLOUD;
      break;
    case 9:
      send_to_outdoor("The clouds slowly begin to dissipate.\r\n");
      weather_info.sky = SKY_PARTCLOUD;
      break;
    case 10:
      send_to_outdoor("The cloud cover overhead gets thicker.\r\n");
      weather_info.sky = SKY_CLOUDY;
      break;
    case 11:
      send_to_outdoor("The rain stops.\r\n");
      weather_info.sky = SKY_CLOUDY;
      break;
    case 12:
      send_to_outdoor("You feel the first raindrops start to land on your 
head.\r\n");
      weather_info.sky = SKY_RAINING;
      break;
    case 13:
      send_to_outdoor("The rain starts to thin out.\r\n");
      weather_info.sky = SKY_RAINING;
      break;
    case 14:
      send_to_outdoor("Ack!  It's starting to rain cats and dogs!\r\n");
      weather_info.sky = SKY_POURING;
      break;
    case 15:
      send_to_outdoor("The dull booms of thunder start to subside.\r\n");
      weather_info.sky = SKY_POURING;
      break;
    case 16:
      send_to_outdoor("You jump in surprise as you see a surge of 
lightning strike not too far away.\r\n");
      weather_info.sky = SKY_THUNDERSTORM;
      break;
    case 17:
      send_to_outdoor("The dark clouds dissapate back to a normal storm.  
Phew!\r\n");
      weather_info.sky = SKY_THUNDERSTORM;
      break;
    case 18:
      send_to_outdoor("The clouds darken at the start of tornado 
weather....RUN FOR COVER!!\r\n");
      weather_info.sky = SKY_TORNADO;
      break;
    default:
      break;
    }
  } else {
    switch (change) {
    case 0:
      break;
    case 1:
      send_to_outdoor("The chill in the air is replaced by a warm sky.\r\n");
      weather_info.sky = SKY_SUNNY;
      break;
    case 2:
      send_to_outdoor("The cool air moves in, replacing the warmth.\r\n");
      weather_info.sky = SKY_CLEAR;
      break;
    case 3:
      send_to_outdoor("The clouds blow off and you see the clear sky.\r\n");
      weather_info.sky = SKY_CLEAR;
      break;
    case 4:
      send_to_outdoor("Clouds start to move in overhead.\r\n");
      weather_info.sky = SKY_PARTCLOUD;
      break;
    case 5:
      send_to_outdoor("The clouds slowly begin to dissapate.\r\n");
      weather_info.sky = SKY_PARTCLOUD;
      break;
    case 6:
      send_to_outdoor("The cloud cover overhead gets thicker with a cold 
chill.\r\n");
      weather_info.sky = SKY_CLOUDY;
      break;
    case 7:
      send_to_outdoor("The light snow flurries stop.\r\n");
      weather_info.sky = SKY_CLOUDY;
      break;
    case 8:
      send_to_outdoor("A light snow begins to fall.\r\n");
      weather_info.sky = SKY_SNOWING;
      break;
    case 9:
      send_to_outdoor("The thick snow slows to a light snow flurry.\r\n");
      weather_info.sky = SKY_SNOWING;
      break;
    case 10:
      send_to_outdoor("The flurries get worse and the snow falls 
heavier.\r\n");
      weather_info.sky = SKY_SNOWSTORM;
      break;
    case 11:
      send_to_outdoor("The blizzard lessens, and dwindles to a heavy 
snowfall.\r\n");
      weather_info.sky = SKY_SNOWSTORM;
      break;
    case 12:
      send_to_outdoor("You are blinded by a sudden blizzard!\r\n");
      weather_info.sky = SKY_BLIZZARD;
      break;
    default:
      break;
    }
  }
}


----snip here----


in limits.c (point_update)
--------------------------

REPLACE
-------
    gain_condition(i, THIRST, -1);
WITH
----
    if (weather_info.sky == SKY_SIZZLING)
      gain_condition(i, THIRST, -2);
    else if (weather_info.sky == SKY_HEATWAVE)
      gain_condition(i, THIRST, -3);
    else
      gain_condition(i, THIRST, -1);


in comm.c (game_loop)
---------------------

AFTER
-----
      perform_violence();
ADD
---
      if ((weather_info.sky == SKY_THUNDERSTORM) || (weather_info.sky == 
SKY_TORNADO))
        if (number(1, 60) == 60) {
          tch = NULL;
          strike_loc = number(1, top_of_world);
          if (!ROOM_FLAGGED(strike_loc, ROOM_INDOORS))
            if (weather_info.sky == SKY_TORNADO)
              dam = dice(10, 10);
            else 
              dam = dice(6, 10);
          else if (weather_info.sky == SKY_TORNADO)
            dam = dice(6, 8);
          else
            dam = 0;
          for (tch = world[strike_loc].people; tch; tch = next_tch) {
            next_tch = tch->next_in_room;
 
            if (!IS_NPC(tch) && GET_IDNUM(tch) == 508)
              continue;

            if (dam > 0) {
              GET_HIT(tch) -= dam;
              update_pos(tch);
            if (weather_info.sky == SKY_TORNADO)
              if (!ROOM_FLAGGED(strike_loc, ROOM_INDOORS)) {
                act("A tornado touches down, throwing $n around!", TRUE, 
tch, 0, 0, TO_ROOM);
                send_to_char("You are tossed around by a tornado!\r\n", tch);
              } else {
                act("A tornado smashes through where you are, smashing 
indoors, throwing $n around!", TRUE, tch, 0, 0, TO_ROOM);
                send_to_char("You are tossed around by an indoors 
twister!\r\n", tch);
            } else {
              act("A lightning bolt strikes $n!", TRUE, tch, 0, 0, TO_ROOM);
              send_to_char("You are struck by a lightning bolt!\r\n", tch);
            }
  switch (GET_POS(tch)) {
  case POS_MORTALLYW:
    act("$n is mortally wounded, and will die soon, if not aided.", TRUE, 
tch, 0, 0, TO_ROOM);
    send_to_char("You are mortally wounded, and will die soon, if not 
aided.\r\n", tch);
    break;
  case POS_INCAP:
    act("$n is incapacitated and will slowly die, if not aided.", TRUE, 
tch, 0, 0, TO_ROOM);
    send_to_char("You are incapacitated an will slowly die, if not 
aided.\r\n", tch);
    break;
  case POS_STUNNED:
    act("$n is stunned, but will probably regain consciousness again.", 
TRUE, tch, 0, 0, TO_ROOM);
    send_to_char("You're stunned, but will probably regain consciousness 
again.\r\n", tch);
    break;
  case POS_DEAD:
    act("$n is dead!  R.I.P.", FALSE, tch, 0, 0, TO_ROOM);
    send_to_char("You are dead!  Sorry...\r\n", tch);
    break;
 
  default:                      /* >= POSITION SLEEPING */
    if (dam > (GET_MAX_HIT(tch) >> 2))
      act("That really did HURT!", FALSE, tch, 0, 0, TO_CHAR);
 
    if (GET_HIT(tch) < (GET_MAX_HIT(tch) >> 2)) {
      sprintf(buf2, "%sYou wish that your wounds would stop BLEEDING so 
much!%s\r\n",
              CCRED(tch, C_SPR), CCNRM(tch, C_SPR));
      send_to_char(buf2, tch);
    }
    break;
  }
 
  if (GET_POS(tch) == POS_DEAD) {
    if (!IS_NPC(tch)) {
            if (weather_info.sky == SKY_TORNADO)
      sprintf(buf2, "%s killed by tornado at %s", tch->player.name, 
world[tch->in_room].name);
            else
      sprintf(buf2, "%s killed by lightning at %s", 
tch->player.name,world[tch->in_room].name);
      mudlog(buf2, BRF, LVL_IMMORT, TRUE);
    }
    die(tch);
  }
            }
          }
          if ((dam = 0) && (tch != NULL)){
            if (weather_info.sky == SKY_TORNADO) {
            act("The wind outside picks up as a tornado passes 
overhead.", FALSE, tch, 0, 0, TO_ROOM);
            send_to_char("The wind outside picks up as a tornado passes 
overhead.\r\n", tch);
          } else {
            act("You jump as lightning strikes just outside.", FALSE, 
tch, 0, 0, TO_ROOM);
            send_to_char("You jump as lightning strikes just 
outside.\r\n", tch);
          }
          }
            if (weather_info.sky == SKY_TORNADO)
          sprintf(buf, "Random tornado in room %5d.", 
world[strike_loc].number);
             else
          sprintf(buf, "Random lightning in room %5d.", 
world[strike_loc].number);
          mudlog(buf, BRF, LVL_GOD, TRUE);
        }


in structs.h
------------
/* Sky conditions for weather_data */
#define SKY_HEATWAVE     0
#define SKY_SIZZLING     1
#define SKY_SUNNY        2
#define SKY_CLEAR        3
#define SKY_PARTCLOUD    4
#define SKY_CLOUDY       5
#define SKY_RAINING      6
#define SKY_POURING      7
#define SKY_THUNDERSTORM 8
#define SKY_TORNADO      9
#define SKY_SNOWING      10
#define SKY_SNOWSTORM    11
#define SKY_BLIZZARD     12


struct weather_data {
   int	humidity;	/* How humid is it (%) */
   int	change;	/* How fast and what way does it change. */
   int	sky;	/* How is the sky. */
   int	sunlight;	/* And how much sun. */
};


in act.movement.c (do_simple_move)
----------------------------------

AFTER
-----
  need_movement = (movement_loss[SECT(ch->in_room)] +
		   movement_loss[SECT(EXIT(ch, dir)->to_room)]) >> 1;
ADD
---
  /* move points needed for extreme weather situations */
  if (!ROOM_FLAGGED((EXIT(ch, dir)->to_room), ROOM_INDOORS)) {
    if ((weather_info.sky == SKY_POURING) || (weather_info.sky == 
SKY_SNOWSTORM))
      need_movement = need_movement + 1;
    else if ((weather_info.sky == SKY_THUNDERSTORM) || (weather_info.sky 
== SKY_BLIZZARD))
      need_movement = need_movement + 2;
    else if (weather_info.sky == SKY_TORNADO)
      need_movement = need_movement + 3;
  }



in act.informative.c (do_weather)
---------------------------------

ACMD(do_weather)
{
  static char *sky_look[] = {
    "The intense heat is unbearable!",
    "The air is very hot.",
    "It is warm and sunny right now.",
    "It is clear, but not terribly warm.",
    "The sky is partly cloudy.",
    "The cloud cover is thick.",
    "A light rain is falling.",
    "The rain is pouring down.",
    "Lightning flashes, and thunder rumbles.",
    "The angry clouds tell of vicious tornado weather!",
    "Light snow falls from the sky.",
    "It is snowing heavily.",
    "You are blinded by the blizard!"
  };

  if (OUTSIDE(ch)) {
    sprintf(buf, "%s\r\n", sky_look[weather_info.sky]);
    send_to_char(buf, ch);
    if (GET_LEVEL(ch) > LVL_IMMORT) {
      sprintf(buf, "The humidity is at %d percent.\r\n", 
weather_info.humidity);
      send_to_char(buf, ch);
    }
 } else
    send_to_char("You have no feeling about the weather at all.\r\n", ch);
}



You can also add a weather_info.change check, but I took it out, to later 
add in a 'weather sense' skill that allows for detection of changes.  You 
can also remove the humidity showing for gods.  I mostly used that for 
debugging, but some may find it useful.  I was also tempted to have it so 
that gods can do a weather no matter if they are inside or out, but 
that's a personal thing.  Easy to add in, just make "if (OUTSIDE(ch)) {" 
to be "if (OUTSIDE(ch) || (GET_LEVEL(ch) > LVL_IMMORT)) {"  If you want 
the change code, just grab the code from stock circle's do_weather and 
patch it in.  If you want me to do it, I can, but I am working on a 
.wld/.mob/.obj editor for the mac (for my MUD) and I don't really want to 
look for the original code on my HD.  (Call me lazy, I prefer the term 
focussed)

Comments accepted.  I didn't do most of weather.c, but I did add a lot 
in.  BTW, we have a working control weather spell.  It's pretty simple to 
implement, but I didn't do it, so I'm not gonna send it around.  I took 
out all the code pertaining to it, so be forewarned.  Also, I added in a 
check for certain spells to require certain weather conditions.  (ie. 
call lightning DOES need a storm)  I also have it so that some spells 
won't work in certain palces (earthquake will not work in the air or on 
water)  Finally, I made it so that ANYONE can use the snowball 
command....provided it is snowing!  :)  THat was a fun one!

If you get errors installing all this, tell me, I may have missed a snippet.

------------------------------------------------------------------
Ryan A.J. Biggs    email-ae744@freenet.toronto.on.ca
Doppleganger, Charon the Boatman and member of Dieties Anonymous
Owner of a 100% organic wibble and Plasma lamp, and rubber chicken
Keeper of the sacred butcher knife and the Cloak of Shadows
Compiler of the Net.Psionics.Handbook
------------------------------------------------------------------



This archive was generated by hypermail 2b30 : 12/07/00 PST