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