Adding a command in ROM 2.4

Posted by Mapleleaf on Fri 07 Oct 2005 12:57 AM — 16 posts, 57,293 views.

Canada #0
Hi all,

I'm trying to learn a little, and this is supposed to be really easy, but I can't get it to work. I have rom 2.4b6 from this site, running on WinXP, and I would like to do something which sounds fairly straightforward... adding the scan command, which is already included in a file in the src folder.

So, I've looked at the command instructions in doc, and tried to follow them... but no dice. I added a line in interp.c (tried to follow how they did it for the "where" command), did the same for merc.h, and copied the scan.c file into act_info.c. However, when I run rom.exe, it works without error, but doesn't seem to recognize that a command has been added. Typing "scan" in game just gives me "Huh?".

If someone could give me a walkthrough in adding this command, it would be very much appreciated. I know it's a lot to ask, but I'm new to all this.

Thanks!
USA #1
Did you compile?
Canada #2
I didn't see that mentioned in the help document for it... I take it that compiling is necessary? I'll get cygwin and read through the help for compiling.
USA #3
Yes, it is required for code changes.
Canada #4
Alright, I got cygwin, successfully used the makefile. Then I went and tried to split up scan.c the best I could, according to the instructions. I tried to recompile, but I ended up with a whole bunch of errors in act_info.c.

I wish I could give more information about what I did, but it involved a lot of guesswork. Could someone briefly tell me what parts to put where? Thanks.
USA #5
Hm, act_info.c should be fine. You put the one function (do_scan) in act_info.c, what else is there?
Canada #6
This is everything other than the copyright notice:

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"

char *const distance[4]=
{
"right here.", "nearby to the %s.", "not far %s.", "off in the distance %s."
};

void scan_list args((ROOM_INDEX_DATA *scan_room, CHAR_DATA *ch,
sh_int depth, sh_int door));
void scan_char args((CHAR_DATA *victim, CHAR_DATA *ch,
sh_int depth, sh_int door));
void do_scan(CHAR_DATA *ch, char *argument)
{
extern char *const dir_name[];
char arg1[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *scan_room;
EXIT_DATA *pExit;
sh_int door, depth;

argument = one_argument(argument, arg1);

if (arg1[0] == '\0')
{
act("$n looks all around.", ch, NULL, NULL, TO_ROOM);
send_to_char("Looking around you see:\n\r", ch);
scan_list(ch->in_room, ch, 0, -1);

for (door=0;door<6;door++)
{
if ((pExit = ch ->in_room->exit[door]) != NULL)
scan_list(pExit->u1.to_room, ch, 1, door);
}
return;
}
else if (!str_cmp(arg1, "n") || !str_cmp(arg1, "north")) door = 0;
else if (!str_cmp(arg1, "e") || !str_cmp(arg1, "east")) door = 1;
else if (!str_cmp(arg1, "s") || !str_cmp(arg1, "south")) door = 2;
else if (!str_cmp(arg1, "w") || !str_cmp(arg1, "west")) door = 3;
else if (!str_cmp(arg1, "u") || !str_cmp(arg1, "up" )) door = 4;
else if (!str_cmp(arg1, "d") || !str_cmp(arg1, "down")) door = 5;
else { send_to_char("Which way do you want to scan?\n\r", ch); return; }

act("You peer intently $T.", ch, NULL, dir_name[door], TO_CHAR);
act("$n peers intently $T.", ch, NULL, dir_name[door], TO_ROOM);
sprintf(buf, "Looking %s you see:\n\r", dir_name[door]);

scan_room = ch->in_room;

for (depth = 1; depth < 4; depth++)
{
if ((pExit = scan_room->exit[door]) != NULL)
{
scan_room = pExit->u1.to_room;
scan_list(pExit->u1.to_room, ch, depth, door);
}
}
return;
}

void scan_list(ROOM_INDEX_DATA *scan_room, CHAR_DATA *ch, sh_int depth,
sh_int door)
{
CHAR_DATA *rch;

if (scan_room == NULL) return;
for (rch=scan_room->people; rch != NULL; rch=rch->next_in_room)
{
if (rch == ch) continue;
if (!IS_NPC(rch) && rch->invis_level > get_trust(ch)) continue;
if (can_see(ch, rch)) scan_char(rch, ch, depth, door);
}
return;
}

void scan_char(CHAR_DATA *victim, CHAR_DATA *ch, sh_int depth, sh_int door)
{
extern char *const dir_name[];
extern char *const distance[];
char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];

buf[0] = '\0';

strcat(buf, PERS(victim, ch));
strcat(buf, ", ");
sprintf(buf2, distance[depth], dir_name[door]);
strcat(buf, buf2);
strcat(buf, "\n\r");

send_to_char(buf, ch);
return;
}
USA #7
You don't need those includes in act_info.c, the do_scan function goes at the bottom of the file, and the rest goes near the top.
Canada #8
Alright, so I just copy and paste

char *const distance[4]=
{
"right here.", "nearby to the %s.", "not far %s.", "off in the distance %s."
};

void scan_list args((ROOM_INDEX_DATA *scan_room, CHAR_DATA *ch,
sh_int depth, sh_int door));
void scan_char args((CHAR_DATA *victim, CHAR_DATA *ch,
sh_int depth, sh_int door));

at the top of act_info.c, and everything below that goes at the bottom?

What about merc.h?
USA #9
Yes, that's correct, make sure you put the top code in the right place at the top.

What about it? act_info.c should already have the required includes.
Canada #10
This is what the help doc for commands says...

=== How to Add a Command

(1) Add a line for the command in 'cmd_table' in 'interp.c'.

(2) Add a 'DECLARE_DO_FUN' line for the command function to 'merc.h'.

(3) Write the function and put it into an appropriate 'act_*.c' file.

(4) Write a help section for the function. See 'help.are' for the format of
help entries. We suggest you start your own file of customized help rather
than adding into 'help.are'. This will make it easier for you to upgrade
to future releases of Merc (which will have upgraded 'help.are' files).
Merc supports as many help files as you want.

That's ALL there is to it!
Canada #11
Ok, I tried that, and now it's giving me errors in scan.c:

scan.o: In function 'do_scan':
/src/scan.c:49: multiple definition of '_do_scan'
act_info.c:2770: first defined here

It does the same thing for '_scan_char', '_scan_list', and '_distance'.
USA #12
You don't need scan.c if you already put it in act_info.c, just one or the other.
Canada #13
Zeno, you're AWESOME! Thanks so much!

Just as an aside, how could I just have used scan.c without copying it all over?
USA #14
You should have just been able to put scan.c in the Makefile, compiled and it would have worked.
Canada #15
That's great, thanks a lot for the help.