Merge branch 'master' of github.com:tbamud/tbamud

This commit is contained in:
welcor 2024-06-20 22:48:59 +02:00
commit ed9e5e1c5a
4 changed files with 320 additions and 235 deletions

71
.gitignore vendored
View file

@ -13,3 +13,74 @@ src/util/depend
build/* build/*
!build/create_solution.bat !build/create_solution.bat
!build/README.md !build/README.md
# Do not commit files from players
lib/plrfiles/A-E/*
lib/plrfiles/F-J/*
lib/plrfiles/K-O/*
lib/plrfiles/P-T/*
lib/plrfiles/U-Z/*
lib/plrfiles/ZZZ/*
lib/plrfiles/index
# but do commit the placeholders
!lib/plrfiles/A-E/00
!lib/plrfiles/F-J/00
!lib/plrfiles/K-O/00
!lib/plrfiles/P-T/00
!lib/plrfiles/U-Z/00
!lib/plrfiles/ZZZ/00
# or vars
lib/plrvars/A-E/*
lib/plrvars/F-J/*
lib/plrvars/K-O/*
lib/plrvars/P-T/*
lib/plrvars/U-Z/*
lib/plrvars/ZZZ/*
lib/plrvars/index
# except the placeholders
!lib/plrvars/A-E/00
!lib/plrvars/F-J/00
!lib/plrvars/K-O/00
!lib/plrvars/P-T/00
!lib/plrvars/U-Z/00
!lib/plrvars/ZZZ/00
# or objects
lib/plrobjs/A-E/*
lib/plrobjs/F-J/*
lib/plrobjs/K-O/*
lib/plrobjs/P-T/*
lib/plrobjs/U-Z/*
lib/plrobjs/ZZZ/*
lib/plrobjs/index
# except the placeholders
!lib/plrobjs/A-E/00
!lib/plrobjs/F-J/00
!lib/plrobjs/K-O/00
!lib/plrobjs/P-T/00
!lib/plrobjs/U-Z/00
!lib/plrobjs/ZZZ/00
# also not autogenerated config file
/lib/etc/config
# or the list of last logins
/lib/etc/last
# or mail
lib/etc/plrmail
# test object files, etc
src/test/depend
src/test/*.o
src/test/testfile
# ide etc.
.vscode
.project
.settings
.cproject

View file

@ -257,6 +257,9 @@ http://tbamud.com
All donated areas have been added to the latest version of tbaMUD. If you All donated areas have been added to the latest version of tbaMUD. If you
wish to donate some of your own work stop by the Builder Academy. wish to donate some of your own work stop by the Builder Academy.
https://github.com/rds1983 has generated maps of all the existing areas,
and they can be found here: https://mudmapbuilder.github.io/
2.3. I have questions about tbaMUD. Where should I go? 2.3. I have questions about tbaMUD. Where should I go?
Stop by The Builder Academy at tbamud.com 9091 or the website at: Stop by The Builder Academy at tbamud.com 9091 or the website at:

View file

@ -51,7 +51,7 @@ static void perform_mortal_where(struct char_data *ch, char *arg);
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur); static void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur);
/* Subcommands */ /* Subcommands */
/* For show_obj_to_char 'mode'. /-- arbitrary */ /* For show_obj_to_char 'mode'. /-- arbitrary */
#define SHOW_OBJ_LONG 0 #define SHOW_OBJ_LONG 0
#define SHOW_OBJ_SHORT 1 #define SHOW_OBJ_SHORT 1
#define SHOW_OBJ_ACTION 2 #define SHOW_OBJ_ACTION 2
@ -125,7 +125,7 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description); snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description);
page_string(ch->desc, notebuf, TRUE); page_string(ch->desc, notebuf, TRUE);
} else } else
send_to_char(ch, "It's blank.\r\n"); send_to_char(ch, "It's blank.\r\n");
return; return;
case ITEM_DRINKCON: case ITEM_DRINKCON:
@ -225,14 +225,14 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
byte percent; byte percent;
const char *text; const char *text;
} diagnosis[] = { } diagnosis[] = {
{ 100, "is in excellent condition." }, { 100, "is in excellent condition." },
{ 90, "has a few scratches." }, { 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." }, { 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." }, { 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." }, { 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." }, { 15, "looks pretty hurt." },
{ 0, "is in awful condition." }, { 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." }, { -1, "is bleeding awfully from big wounds." },
}; };
int percent, ar_index; int percent, ar_index;
const char *pers = PERS(i, ch); const char *pers = PERS(i, ch);
@ -240,7 +240,7 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
if (GET_MAX_HIT(i) > 0) if (GET_MAX_HIT(i) > 0)
percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i); percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i);
else else
percent = -1; /* How could MAX_HIT be < 1?? */ percent = -1; /* How could MAX_HIT be < 1?? */
for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++) for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++)
if (percent >= diagnosis[ar_index].percent) if (percent >= diagnosis[ar_index].percent)
@ -269,12 +269,12 @@ static void look_at_char(struct char_data *i, struct char_data *ch)
found = TRUE; found = TRUE;
if (found) { if (found) {
send_to_char(ch, "\r\n"); /* act() does capitalization. */ send_to_char(ch, "\r\n"); /* act() does capitalization. */
act("$n is using:", FALSE, i, 0, ch, TO_VICT); act("$n is using:", FALSE, i, 0, ch, TO_VICT);
for (j = 0; j < NUM_WEARS; j++) for (j = 0; j < NUM_WEARS; j++)
if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) { if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) {
send_to_char(ch, "%s", wear_where[j]); send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT); show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
} }
} }
if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) { if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) {
@ -300,7 +300,7 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) { if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
if (IS_NPC(i)) if (IS_NPC(i))
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i)); send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) { if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next) if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i)))); send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
@ -312,12 +312,12 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GROUP(i)) { if (GROUP(i)) {
if (GROUP(i) == GROUP(ch)) if (GROUP(i) == GROUP(ch))
send_to_char(ch, "(%s%s%s) ", CBGRN(ch, C_NRM), send_to_char(ch, "(%s%s%s) ", CBGRN(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group", GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM)); CCNRM(ch, C_NRM));
else else
send_to_char(ch, "(%s%s%s) ", CBRED(ch, C_NRM), send_to_char(ch, "(%s%s%s) ", CBRED(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group", GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM)); CCNRM(ch, C_NRM));
} }
if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) { if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) {
@ -326,9 +326,9 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) { if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) {
if (IS_EVIL(i)) if (IS_EVIL(i))
send_to_char(ch, "(Red Aura) "); send_to_char(ch, "(Red Aura) ");
else if (IS_GOOD(i)) else if (IS_GOOD(i))
send_to_char(ch, "(Blue Aura) "); send_to_char(ch, "(Blue Aura) ");
} }
send_to_char(ch, "%s", i->player.long_descr); send_to_char(ch, "%s", i->player.long_descr);
@ -361,24 +361,24 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GET_POS(i) != POS_FIGHTING) { if (GET_POS(i) != POS_FIGHTING) {
if (!SITTING(i)) if (!SITTING(i))
send_to_char(ch, "%s", positions[(int) GET_POS(i)]); send_to_char(ch, "%s", positions[(int) GET_POS(i)]);
else { else {
furniture = SITTING(i); furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ? send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
"sleeping" : (GET_POS(i) == POS_RESTING ? "resting" : "sitting")), "sleeping" : (GET_POS(i) == POS_RESTING ? "resting" : "sitting")),
OBJS(furniture, ch)); OBJS(furniture, ch));
} }
} else { } else {
if (FIGHTING(i)) { if (FIGHTING(i)) {
send_to_char(ch, " is here, fighting "); send_to_char(ch, " is here, fighting ");
if (FIGHTING(i) == ch) if (FIGHTING(i) == ch)
send_to_char(ch, "YOU!"); send_to_char(ch, "YOU!");
else { else {
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i))) if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch)); send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else else
send_to_char(ch, "someone who has already left!"); send_to_char(ch, "someone who has already left!");
} }
} else /* NIL fighting pointer */ } else /* NIL fighting pointer */
send_to_char(ch, " is here struggling with thin air."); send_to_char(ch, " is here struggling with thin air.");
} }
@ -402,13 +402,13 @@ static void list_char_to_char(struct char_data *list, struct char_data *ch)
if (ch != i) { if (ch != i) {
/* hide npcs whose description starts with a '.' from non-holylighted people - Idea from Elaseth of TBA */ /* hide npcs whose description starts with a '.' from non-holylighted people - Idea from Elaseth of TBA */
if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) && if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) &&
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.') IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
continue; continue;
send_to_char(ch, "%s", CCYEL(ch, C_NRM)); send_to_char(ch, "%s", CCYEL(ch, C_NRM));
if (CAN_SEE(ch, i)) if (CAN_SEE(ch, i))
list_one_char(i, ch); list_one_char(i, ch);
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) && else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) &&
AFF_FLAGGED(i, AFF_INFRAVISION)) AFF_FLAGGED(i, AFF_INFRAVISION))
send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n"); send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n");
send_to_char(ch, "%s", CCNRM(ch, C_NRM)); send_to_char(ch, "%s", CCNRM(ch, C_NRM));
} }
@ -425,12 +425,12 @@ static void do_auto_exits(struct char_data *ch)
continue; continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS) if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS)
continue; continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT)) if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue; continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED)) if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM)); send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN)) else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN))
send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM)); send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else else
send_to_char(ch, "\t(%s\t) ", autoexits[door]); send_to_char(ch, "\t(%s\t) ", autoexits[door]);
slen++; slen++;
@ -521,23 +521,25 @@ void look_at_room(struct char_data *ch, int ignore_brief)
} }
else else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name); send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief || send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
}
send_to_char(ch, "%s", world[IN_ROOM(ch)].description); if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
}
/*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
do_auto_exits(ch);
/*now list characters &objects */ /*autoexits */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE); if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
list_char_to_char(world[IN_ROOM(ch)].people, ch); do_auto_exits(ch);
/*now list characters &objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch);
} }
static void look_in_direction(struct char_data *ch, int dir) static void look_in_direction(struct char_data *ch, int dir)
@ -565,35 +567,35 @@ static void look_in_obj(struct char_data *ch, char *arg)
if (!*arg) if (!*arg)
send_to_char(ch, "Look in what?\r\n"); send_to_char(ch, "Look in what?\r\n");
else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM |
FIND_OBJ_EQUIP, ch, &dummy, &obj))) { FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg); send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg);
} else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) && } else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) && (GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER)) (GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
send_to_char(ch, "There's nothing inside that!\r\n"); send_to_char(ch, "There's nothing inside that!\r\n");
else { else {
if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) { if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
if (OBJVAL_FLAGGED(obj, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE))) if (OBJVAL_FLAGGED(obj, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE)))
send_to_char(ch, "It is closed.\r\n"); send_to_char(ch, "It is closed.\r\n");
else { else {
send_to_char(ch, "%s", fname(obj->name)); send_to_char(ch, "%s", fname(obj->name));
switch (bits) { switch (bits) {
case FIND_OBJ_INV: case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n"); send_to_char(ch, " (carried): \r\n");
break; break;
case FIND_OBJ_ROOM: case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n"); send_to_char(ch, " (here): \r\n");
break; break;
case FIND_OBJ_EQUIP: case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n"); send_to_char(ch, " (used): \r\n");
break; break;
} }
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE); list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
} }
} else { /* item must be a fountain or drink container */ } else { /* item must be a fountain or drink container */
if ((GET_OBJ_VAL(obj, 1) == 0) && (GET_OBJ_VAL(obj, 0) != -1)) if ((GET_OBJ_VAL(obj, 1) == 0) && (GET_OBJ_VAL(obj, 0) != -1))
send_to_char(ch, "It is empty.\r\n"); send_to_char(ch, "It is empty.\r\n");
else { else {
if (GET_OBJ_VAL(obj, 0) < 0) if (GET_OBJ_VAL(obj, 0) < 0)
{ {
@ -601,14 +603,15 @@ static void look_in_obj(struct char_data *ch, char *arg)
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2)); sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's full of a %s liquid.\r\n", buf2); send_to_char(ch, "It's full of a %s liquid.\r\n", buf2);
} }
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0)) else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */ send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else { else
{
char buf2[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0); amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2)); sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2); send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
} }
} }
} }
} }
@ -645,14 +648,14 @@ static void look_at_target(struct char_data *ch, char *arg)
} }
bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP | bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP |
FIND_CHAR_ROOM, ch, &found_char, &found_obj); FIND_CHAR_ROOM, ch, &found_char, &found_obj);
/* Is the target a character? */ /* Is the target a character? */
if (found_char != NULL) { if (found_char != NULL) {
look_at_char(found_char, ch); look_at_char(found_char, ch);
if (ch != found_char) { if (ch != found_char) {
if (CAN_SEE(found_char, ch)) if (CAN_SEE(found_char, ch))
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT); act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT); act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT);
} }
return; return;
@ -674,16 +677,16 @@ static void look_at_target(struct char_data *ch, char *arg)
for (j = 0; j < NUM_WEARS && !found; j++) for (j = 0; j < NUM_WEARS && !found; j++)
if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j))) if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j)))
if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) { if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc); send_to_char(ch, "%s", desc);
found = TRUE; found = TRUE;
} }
/* Does the argument match an extra desc in the char's inventory? */ /* Does the argument match an extra desc in the char's inventory? */
for (obj = ch->carrying; obj && !found; obj = obj->next_content) { for (obj = ch->carrying; obj && !found; obj = obj->next_content) {
if (CAN_SEE_OBJ(ch, obj)) if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) { if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc); send_to_char(ch, "%s", desc);
found = TRUE; found = TRUE;
} }
} }
@ -691,8 +694,8 @@ static void look_at_target(struct char_data *ch, char *arg)
for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content) for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content)
if (CAN_SEE_OBJ(ch, obj)) if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) { if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc); send_to_char(ch, "%s", desc);
found = TRUE; found = TRUE;
} }
/* If an object was found back in generic_find */ /* If an object was found back in generic_find */
@ -722,7 +725,7 @@ ACMD(do_look)
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n"); send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) { else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
send_to_char(ch, "It is pitch black...\r\n"); send_to_char(ch, "It is pitch black...\r\n");
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */ list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
} else { } else {
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
@ -730,12 +733,12 @@ ACMD(do_look)
if (subcmd == SCMD_READ) { if (subcmd == SCMD_READ) {
if (!*arg) if (!*arg)
send_to_char(ch, "Read what?\r\n"); send_to_char(ch, "Read what?\r\n");
else else
look_at_target(ch, strcpy(tempsave, arg)); look_at_target(ch, strcpy(tempsave, arg));
return; return;
} }
if (!*arg) /* "look" alone, without an argument at all */ if (!*arg) /* "look" alone, without an argument at all */
look_at_room(ch, 1); look_at_room(ch, 1);
else if (is_abbrev(arg, "in")) else if (is_abbrev(arg, "in"))
look_in_obj(ch, arg2); look_in_obj(ch, arg2);
@ -775,15 +778,15 @@ ACMD(do_examine)
} }
/* look_at_target() eats the number. */ /* look_at_target() eats the number. */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */ look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM | generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM |
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object); FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
if (tmp_object) { if (tmp_object) {
if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) || if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) || (GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) { (GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
send_to_char(ch, "When you look inside, you see:\r\n"); send_to_char(ch, "When you look inside, you see:\r\n");
look_in_obj(ch, arg); look_in_obj(ch, arg);
} }
@ -815,18 +818,18 @@ ACMD(do_score)
send_to_char(ch, "\r\n"); send_to_char(ch, "\r\n");
send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n", send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n",
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch), GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch)); GET_MOVE(ch), GET_MAX_MOVE(ch));
send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n", send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n",
compute_armor_class(ch), GET_ALIGNMENT(ch)); compute_armor_class(ch), GET_ALIGNMENT(ch));
send_to_char(ch, "You have %d exp, %d gold coins, and %d questpoints.\r\n", send_to_char(ch, "You have %d exp, %d gold coins, and %d questpoints.\r\n",
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch)); GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
if (GET_LEVEL(ch) < LVL_IMMORT) if (GET_LEVEL(ch) < LVL_IMMORT)
send_to_char(ch, "You need %d exp to reach your next level.\r\n", send_to_char(ch, "You need %d exp to reach your next level.\r\n",
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch)); level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
send_to_char(ch, "You have earned %d quest points.\r\n", GET_QUESTPOINTS(ch)); send_to_char(ch, "You have earned %d quest points.\r\n", GET_QUESTPOINTS(ch));
send_to_char(ch, "You have completed %d quest%s, ", send_to_char(ch, "You have completed %d quest%s, ",
@ -845,13 +848,13 @@ ACMD(do_score)
} }
playing_time = *real_time_passed((time(0) - ch->player.time.logon) + playing_time = *real_time_passed((time(0) - ch->player.time.logon) +
ch->player.time.played, 0); ch->player.time.played, 0);
send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n", send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n",
playing_time.day, playing_time.day == 1 ? "" : "s", playing_time.day, playing_time.day == 1 ? "" : "s",
playing_time.hours, playing_time.hours == 1 ? "" : "s"); playing_time.hours, playing_time.hours == 1 ? "" : "s");
send_to_char(ch, "This ranks you as %s %s (level %d).\r\n", send_to_char(ch, "This ranks you as %s %s (level %d).\r\n",
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch)); GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
switch (GET_POS(ch)) { switch (GET_POS(ch)) {
case POS_DEAD: case POS_DEAD:
@ -982,8 +985,8 @@ ACMD(do_time)
weekday = ((35 * time_info.month) + day) % 7; weekday = ((35 * time_info.month) + day) % 7;
send_to_char(ch, "It is %d o'clock %s, on %s.\r\n", send_to_char(ch, "It is %d o'clock %s, on %s.\r\n",
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12), (time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]); time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
/* Peter Ajamian supplied the following as a fix for a bug introduced in the /* Peter Ajamian supplied the following as a fix for a bug introduced in the
* ordinal display that caused 11, 12, and 13 to be incorrectly displayed as * ordinal display that caused 11, 12, and 13 to be incorrectly displayed as
@ -1005,7 +1008,7 @@ ACMD(do_time)
} }
} }
send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n", send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n",
day, suf, month_name[time_info.month], time_info.year); day, suf, month_name[time_info.month], time_info.year);
} }
ACMD(do_weather) ACMD(do_weather)
@ -1020,8 +1023,8 @@ ACMD(do_weather)
if (OUTSIDE(ch)) if (OUTSIDE(ch))
{ {
send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky], send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky],
weather_info.change >= 0 ? "you feel a warm wind from south" : weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due"); "your foot tells you bad weather is due");
if (GET_LEVEL(ch) >= LVL_GOD) if (GET_LEVEL(ch) >= LVL_GOD)
send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n", send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n",
weather_info.pressure, weather_info.pressure,
@ -1379,7 +1382,7 @@ ACMD(do_users)
host_search[0] = name_search[0] = '\0'; host_search[0] = name_search[0] = '\0';
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */ strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
while (*buf) { while (*buf) {
char buf1[MAX_INPUT_LENGTH]; char buf1[MAX_INPUT_LENGTH];
@ -1389,49 +1392,49 @@ ACMD(do_users)
switch (mode) { switch (mode) {
case 'o': case 'o':
case 'k': case 'k':
outlaws = 1; outlaws = 1;
playing = 1; playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break; break;
case 'p': case 'p':
playing = 1; playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break; break;
case 'd': case 'd':
deadweight = 1; deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break; break;
case 'l': case 'l':
playing = 1; playing = 1;
half_chop(buf1, arg, buf); half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high); sscanf(arg, "%d-%d", &low, &high);
break; break;
case 'n': case 'n':
playing = 1; playing = 1;
half_chop(buf1, name_search, buf); half_chop(buf1, name_search, buf);
break; break;
case 'h': case 'h':
playing = 1; playing = 1;
half_chop(buf1, host_search, buf); half_chop(buf1, host_search, buf);
break; break;
case 'c': case 'c':
playing = 1; playing = 1;
half_chop(buf1, arg, buf); half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg); showclass = find_class_bitvector(arg);
break; break;
default: default:
send_to_char(ch, "%s", USERS_FORMAT); send_to_char(ch, "%s", USERS_FORMAT);
return; return;
} /* end of switch */ } /* end of switch */
} else { /* endif */ } else { /* endif */
send_to_char(ch, "%s", USERS_FORMAT); send_to_char(ch, "%s", USERS_FORMAT);
return; return;
} }
} /* end while (parser) */ } /* end while (parser) */
send_to_char(ch, send_to_char(ch,
"Num Class Name State Idl Login\t* Site\r\n" "Num Class Name State Idl Login\t* Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n"); "--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
one_argument(argument, arg); one_argument(argument, arg);
@ -1453,7 +1456,7 @@ ACMD(do_users)
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high) if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue; continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) &&
!PLR_FLAGGED(tch, PLR_THIEF)) !PLR_FLAGGED(tch, PLR_THIEF))
continue; continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch)))) if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue; continue;
@ -1461,11 +1464,11 @@ ACMD(do_users)
continue; continue;
if (d->original) if (d->original)
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original), sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original)); CLASS_ABBR(d->original));
else else
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character), sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character)); CLASS_ABBR(d->character));
} else } else
strcpy(classname, " - "); strcpy(classname, " - ");
@ -1478,15 +1481,15 @@ ACMD(do_users)
if (d->character && STATE(d) == CON_PLAYING) if (d->character && STATE(d) == CON_PLAYING)
sprintf(idletime, "%5d", d->character->char_specials.timer * sprintf(idletime, "%5d", d->character->char_specials.timer *
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN); SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
else else
strcpy(idletime, " "); strcpy(idletime, " ");
sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname, sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname,
d->original && d->original->player.name ? d->original->player.name : d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name : d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED", "UNDEFINED",
state, idletime, timestr); state, idletime, timestr);
if (*d->host) if (*d->host)
sprintf(line + strlen(line), "[%s]\r\n", d->host); sprintf(line + strlen(line), "[%s]\r\n", d->host);
@ -1576,23 +1579,23 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
send_to_char(ch, "Players in %s\tn.\r\n--------------------\r\n", zone_table[j].name); send_to_char(ch, "Players in %s\tn.\r\n--------------------\r\n", zone_table[j].name);
for (d = descriptor_list; d; d = d->next) { for (d = descriptor_list; d; d = d->next) {
if (STATE(d) != CON_PLAYING || d->character == ch) if (STATE(d) != CON_PLAYING || d->character == ch)
continue; continue;
if ((i = (d->original ? d->original : d->character)) == NULL) if ((i = (d->original ? d->original : d->character)) == NULL)
continue; continue;
if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i)) if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i))
continue; continue;
if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone) if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone)
continue; continue;
send_to_char(ch, "%-20s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM); send_to_char(ch, "%-20s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
} }
} else { /* print only FIRST char, not all. */ } else { /* print only FIRST char, not all. */
for (i = character_list; i; i = i->next) { for (i = character_list; i; i = i->next) {
if (IN_ROOM(i) == NOWHERE || i == ch) if (IN_ROOM(i) == NOWHERE || i == ch)
continue; continue;
if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone) if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone)
continue; continue;
if (!isname(arg, i->player.name)) if (!isname(arg, i->player.name))
continue; continue;
send_to_char(ch, "%-25s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM); send_to_char(ch, "%-25s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
return; return;
} }
@ -1601,7 +1604,7 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
} }
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch, static void print_object_location(int num, struct obj_data *obj, struct char_data *ch,
int recur) int recur)
{ {
if (num > 0) if (num > 0)
send_to_char(ch, "O%3d. %-25s%s - ", num, obj->short_description, QNRM); send_to_char(ch, "O%3d. %-25s%s - ", num, obj->short_description, QNRM);
@ -1666,7 +1669,7 @@ static void perform_immort_where(struct char_data *ch, char *arg)
else else
send_to_char(ch, "[TRIGS] "); send_to_char(ch, "[TRIGS] ");
} }
send_to_char(ch, "%s\r\n", QNRM); send_to_char(ch, "%s\r\n", QNRM);
} }
for (num = 0, k = object_list; k; k = k->next) for (num = 0, k = object_list; k; k = k->next)
if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) { if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
@ -1735,7 +1738,7 @@ ACMD(do_levels)
for (i = min_lev; i < max_lev; i++) { for (i = min_lev; i < max_lev; i++) {
nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", (int)i, nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", (int)i,
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1); level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
if (len + nlen >= sizeof(buf)) if (len + nlen >= sizeof(buf))
break; break;
len += nlen; len += nlen;
@ -1759,7 +1762,7 @@ ACMD(do_levels)
if (len < sizeof(buf) && max_lev == LVL_IMMORT) if (len < sizeof(buf) && max_lev == LVL_IMMORT)
snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n", snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n",
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT)); LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
page_string(ch->desc, buf, TRUE); page_string(ch->desc, buf, TRUE);
} }
@ -1949,14 +1952,14 @@ ACMD(do_toggle)
else else
sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */ sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */
if (GET_LEVEL(ch) == LVL_IMPL) { if (GET_LEVEL(ch) == LVL_IMPL) {
send_to_char(ch, send_to_char(ch,
" SlowNameserver: %-3s " " SlowNameserver: %-3s "
" " " "
" Trackthru Doors: %-3s\r\n", " Trackthru Doors: %-3s\r\n",
ONOFF(CONFIG_NS_IS_SLOW), ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS)); ONOFF(CONFIG_TRACK_T_DOORS));
} }
if (GET_LEVEL(ch) >= LVL_IMMORT) { if (GET_LEVEL(ch) >= LVL_IMMORT) {

View file

@ -12,7 +12,6 @@
#include "conf.h" #include "conf.h"
#include "sysdep.h" #include "sysdep.h"
#define NOWHERE -1 /* nil reference for room-database */ #define NOWHERE -1 /* nil reference for room-database */
/* The cardinal directions: used as index to room_data.dir_option[] */ /* The cardinal directions: used as index to room_data.dir_option[] */
@ -22,14 +21,17 @@
#define WEST 3 #define WEST 3
#define UP 4 #define UP 4
#define DOWN 5 #define DOWN 5
#define NORTHWEST 6
#define NORTHEAST 7
#define SOUTHEAST 8
#define SOUTHWEST 9
#define NUM_OF_DIRS 6 #define NUM_OF_DIRS 10
#define CREATE(result, type, number) do {\ #define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\ if (!((result) = (type *) calloc ((number), sizeof(type))))\
{ perror("malloc failure"); abort(); } } while(0) { perror("malloc failure"); abort(); } } while(0)
/* Exit info: used in room_data.dir_option.exit_info */ /* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /* Exit is a door */ #define EX_ISDOOR (1 << 0) /* Exit is a door */
#define EX_CLOSED (1 << 1) /* The door is closed */ #define EX_CLOSED (1 << 1) /* The door is closed */
@ -45,7 +47,7 @@ typedef unsigned short int ush_int;
typedef char bool; typedef char bool;
typedef char byte; typedef char byte;
typedef sh_int room_num; typedef int room_num;
typedef sh_int obj_num; typedef sh_int obj_num;
@ -133,13 +135,14 @@ struct room_data {
struct room_data *world = NULL; /* array of rooms */ struct room_data *world = NULL; /* array of rooms */
int top_of_world = 0; /* ref to top element of world */ int top_of_world = 0; /* ref to top element of world */
int rec_count = 0;
/* local functions */ /* local functions */
char *fread_string(FILE * fl, char *error); char *fread_string(FILE * fl, char *error);
void setup_dir(FILE * fl, int room, int dir); void setup_dir(FILE * fl, int room, int dir);
void index_boot(char *name); void index_boot(int cnt, char **name);
void discrete_load(FILE * fl); void discrete_load(FILE * fl);
void parse_room(FILE * fl, int virtual_nr); void parse_room(FILE * fl, int virtual_nr);
void parse_mobile(FILE * mob_f, int nr); void parse_mobile(FILE * mob_f, int nr);
@ -150,7 +153,7 @@ void write_output(void);
char *dir_names[] = char *dir_names[] =
{"North", "East", "South", "West", "Up", "Down"}; {"North", "East", "South", "West", "Up", "Down","North West","North East","South East","South West"};
/************************************************************************* /*************************************************************************
@ -160,14 +163,12 @@ char *dir_names[] =
/* body of the booting system */ /* body of the booting system */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s <world-file-name>\n", argv[0]); fprintf(stderr, "Usage: %s <world-file-name(s)>\n", argv[0]);
exit(1); exit(1);
} }
index_boot(argv[1]);
log("Renumbering rooms."); index_boot(argc,argv);
renum_world();
log("Writing output."); log("Writing output.");
write_output(); write_output();
@ -176,6 +177,21 @@ int main(int argc, char **argv)
return (0); return (0);
} }
/* Since the world is loaded into memory by index
* and not room number, we need to search through
* all rooms and return the correct one. This is
* used to generate door information (ie: the name)
*/
struct room_data* findRoom(int nr)
{
int i;
for (i=0;i<rec_count;i++)
if (world[i].number==nr)
return &world[i];
return NULL;
}
void write_output(void) void write_output(void)
{ {
@ -184,11 +200,22 @@ void write_output(void)
char buf[128]; char buf[128];
register int door, found; register int door, found;
for (i = 0; i <= top_of_world; i++) { for (i=0;i<rec_count;i++) {
//print the record number, but no linefeed.
fprintf(stderr, "Record: %d ",i);
if (world[i].name == NULL) {
//linefeed the prior record since we're skipping this one.
log("");
//the name is blank, which means, most likely, the record is bad as well.
continue;
}
sprintf(buf, "Writing %d.html", world[i].number); sprintf(buf, "Writing %d.html", world[i].number);
log(buf); log(buf);
sprintf(buf, "%d.html", world[i].number); //for some reason, if you use %d with sprintf it rolls over like its 16bit,
//but only if you use the buffer with fopen.
//using %ld and casting to long solves this in case someone really wants
//to use negative room numbers.
sprintf(buf, "%ld.html",(long)world[i].number);
if (!(fl = fopen(buf, "w"))) { if (!(fl = fopen(buf, "w"))) {
perror("opening output file"); perror("opening output file");
exit(1); exit(1);
@ -203,12 +230,16 @@ void write_output(void)
found = 0; found = 0;
for (door = 0; door < NUM_OF_DIRS; door++) for (door = 0; door < NUM_OF_DIRS; door++)
if (world[i].dir_option[door] && if (world[i].dir_option[door] &&
world[i].dir_option[door]->to_room != NOWHERE) { world[i].dir_option[door]->to_room != NOWHERE) {
found = 1; found = 1;
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n", //this call gets a pointer to the room referenced by the to_room for the door.
world[world[i].dir_option[door]->to_room].number, //This fixes a lot of issues introduced with the whole 'renumbering rooms' call
dir_names[door], //and the binary search that didn't work well.
world[world[i].dir_option[door]->to_room].name); struct room_data* to_room = findRoom(world[i].dir_option[door]->to_room);
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
to_room->number,
dir_names[door],
to_room->name);
} }
if (!found) if (!found)
fprintf(fl, "None!"); fprintf(fl, "None!");
@ -231,19 +262,35 @@ int count_hash_records(FILE * fl)
void index_boot(char *name) void index_boot(int cnt, char **names)
{ {
FILE *db_file; FILE *db_file;
int rec_count = 0;
if (!(db_file = fopen(name, "r"))) { //throw first entry away as that is the executable.
perror("error opening world file"); for (int i=1;i<cnt;i++) {
exit(1); if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
//have to loop through files twice.
//once to get total record count
//second time to load them
rec_count += count_hash_records(db_file);
fclose(db_file);
} }
rec_count = count_hash_records(db_file); sprintf(buf,"Total records: %d\n",rec_count);
log(buf);
//now that we know how many records in total
//we can create the memory structure
CREATE(world, struct room_data, rec_count); CREATE(world, struct room_data, rec_count);
rewind(db_file); //now loop through files and load them
discrete_load(db_file); for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
discrete_load(db_file);
}
} }
@ -257,6 +304,9 @@ void discrete_load(FILE * fl)
fprintf(stderr, "Format error after room #%d\n", nr); fprintf(stderr, "Format error after room #%d\n", nr);
exit(1); exit(1);
} }
if (*line == 'T') //Toss triggers. THey currently break this util.
continue;
if (*line == '$') if (*line == '$')
return; return;
@ -394,22 +444,6 @@ void setup_dir(FILE * fl, int room, int dir)
} }
/* resolve all vnums into rnums in the world */
void renum_world(void)
{
register int room, door;
for (room = 0; room <= top_of_world; room++)
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[room].dir_option[door])
if (world[room].dir_option[door]->to_room != NOWHERE)
world[room].dir_option[door]->to_room =
real_room(world[room].dir_option[door]->to_room,
world[room].number);
}
/************************************************************************* /*************************************************************************
* procedures for resetting, both play-time and boot-time * * procedures for resetting, both play-time and boot-time *
*********************************************************************** */ *********************************************************************** */
@ -464,32 +498,6 @@ char *fread_string(FILE * fl, char *error)
/* returns the real number of the room with given virtual number */
int real_room(int virtual, int reference)
{
int bot, top, mid;
bot = 0;
top = top_of_world;
/* perform binary search on world-table */
for (;;) {
mid = (bot + top) / 2;
if ((world + mid)->number == virtual)
return (mid);
if (bot >= top) {
fprintf(stderr, "Room %d does not exist in database (referenced in room %d)\n", virtual, reference);
return (-1);
}
if ((world + mid)->number > virtual)
top = mid - 1;
else
bot = mid + 1;
}
}
/* get_line reads the next non-blank line off of the input stream. /* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input. Lines which begin * The newline character is removed from the input. Lines which begin
* with '*' are considered to be comments. * with '*' are considered to be comments.