[Circle] [long] [code] Room affections

From: The Arrow (pt94jpi@student.hk-r.se)
Date: 08/07/96


Now that room affections have been dragged into the light (by some 
strange coincidence by me :), here are my solution to room affections 
with a timer (including the fabled 'wall of fog' spell :) on a clean 3.0 
patchlevel 11:

(Warning: This isn't a pretty patch, but this is what I did, and it works! :)

In the file db.c, after the line:
   int top_of_world = 0;		/* ref to top element of world	 */
add this line:
   struct raff_node *raff_list = NULL;  /* list of room affections */

In the file utils.h, after the line:
  #define ROOM_FLAGS(loc) (world[(loc)].room_flags)
add the following two lines:
  #define ROOM_AFFECTIONS(loc)    (world[(loc)].room_affections)
  #define ROOM_AFFECTED(loc, aff) (IS_SET(ROOM_AFFECTIONS(loc), (aff)))

in the file structs.h, after the room_direction_data structure,
add the followin structure:
struct raff_node {
	room_num room;        /* location in the world[] array of the room */
	int      timer;       /* how many ticks this affection lasts */
	long     affection;   /* which affection does this room have */
	int      spell;       /* the spell number */

	struct raff_node *next; /* link to the next node */
};

also in the structs.h file, at the end of the room_data structure,
add the followin line:
	long  room_affections;    /* bitvector for spells/skills */

At the top of the file structs.h, after the room flag defines, this lines
was added:
  /* Room affections */
  #define RAFF_FOG        (1 << 0)

In the file constants.h, after the room_bits[] array, add this array:
const char *room_affections[] = {
	"FOG",
	"\n"
};

And in the spell_wear_off_msg[] array, before the "!UNUSED!" line, add:
	"The fog seams to clear out.",


Now to the file act.informative.c, in the function look_at_room() 
(preferably after the AFF_BLIND check) add:
	if (ROOM_AFFECTED(ch->in_room, RAFF_FOG)) {
		/* NOTE: you might wish to change so that wizards,
		 * or the use of some 'see through fog' makes you see 
		 * through the fog
		 */
		send_to_char("Your view is obscured by a thick fog.\r\n", ch);
		return;
	}


In act.wizard.c, the function do_stat_room(), at the top add the following:
	extern char *room_affections[];

and after it prints out spec-func and room flags add:
  sprintbit((long) rm->room_affections, room_affections, buf2);
  sprintf(buf, "Room affections: %s\r\n", buf2);
  send_to_char(buf, ch);


In class.c, somewhere in the init_spell_levels() function, add this line:
  spell_level(SPELL_WALL_OF_FOG, CLASS_CLERIC, 20);


In the spells.h file, at the top, after
  #define MAG_MANUAL	(1 << 10)
add this line:
  #define MAG_ROOM     (1 << 11)

and after
  /* Insert new spells here, up to MAX_SPELLS */
add this line:
  #define SPELL_WALL_OF_FOG      52

also, after the mag_creations() prototypem add this prototype:
  void mag_room(int level, struct char_data * ch, int spellnum);


In the file spell_parser.c, replace the first "!UNUSED!" after 
"waterwalk" with: "wall of fog"

In the call_magic() function, before the calls of manual spells, add:
  if (IS_SET(SINFO.routines, MAG_ROOM))
    mag_room(level, caster, spellnum);

and somewhere in the mag_assign_spells() function add:
	spello(SPELL_WALL_OF_FOG, 50, 25, 5, POS_STANDING,
		 TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_ROOM);


In the file magic.c, in the function affect_update(), at the top add:
	extern struct raff_node *raff_list;
	struct raff_node *raff, *next_raff, *temp;
and at the end of the function add:
	/* update the room affections */
	for (raff = raff_list; raff; raff = next_raff) {
		next_raff = raff->next;

		raff->timer--;

		if (raff->timer <= 0) {
			/* this room affection has expired */
			send_to_room(spell_wear_off_msg[raff->spell],
				raff->room);
			send_to_room("\r\n", raff->room);

			/* remove the affection */
			REMOVE_BIT(world[(int)raff->room].room_affections,
				raff->affection);
			REMOVE_FROM_LIST(raff, raff_list, next)
			free(raff);
		}
	}


aaand finaly, this function should be added at the bottom of magic.c
void mag_room(int level, struct char_data * ch, int spellnum)
{
	long aff; /* what affection */
	int ticks; /* how many ticks this spell lasts */
	char *to_char = NULL;
	char *to_room = NULL;
	struct raff_node *raff;

	extern struct raff_node *raff_list;

	aff = ticks =0;

	if (ch == NULL)
		return;
	level = MAX(MIN(level, LVL_IMPL), 1);

	switch (spellnum) {
	case SPELL_WALL_OF_FOG:
		to_char = "You create a fog out of nowhere.";
		to_room = "%n creates a fog out of nowhere.";
		aff = RAFF_FOG;
		ticks = 1; /* this spell lasts one tick */
		break;

	/* add more room spells here */

	default:
		sprintf(buf, "SYSERR: unknown spellnum %d " \
		"passed to mag_unaffects", spellnum);
		log(buf);
		break;
	}

	/* create, initialize, and link a room-affection node */
	CREATE(raff, struct raff_node, 1);
	raff->room = ch->in_room;
	raff->timer = ticks;
	raff->affection = aff;
	raff->spell = spellnum;
	raff->next = raff_list;
	raff_list = raff;

	/* set the affection */
	SET_BIT(ROOM_AFFECTIONS(raff->room), aff);

	if (to_char == NULL)
		send_to_char(NOEFFECT, ch);
	else
		act(to_char, TRUE, ch, 0, 0, TO_CHAR);

	if (to_room != NULL)
		act(to_room, TRUE, ch, 0, 0, TO_ROOM);
	else if (to_char != NULL)
		act(to_char, TRUE, ch, 0, 0, TO_ROOM);
}



If there is any problems, well, I might be able to answer them... :)

Btw, if there is someone who wants it, I could put together some code so 
that you can define room affections in the world files.

Hope this helps someone out there... :)

/ Joachim

---------------------------------------------------------------------
  The Arrow              Moses@PTMUD   sargasso.fukt.hk-r.se 4000

  Joachim Pileborg       Email: pt94jpi@student.hk-r.se
  Svarvarevägen 5
  37230 Ronneby          http://www.rby.hk-r.se/~pt94jpi/pt94jpi.html
  SWEDEN
---------------------------------------------------------------------


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



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