mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-26 06:06:33 +01:00
Update set commands, add exdescs to npc's
This commit is contained in:
parent
1a1767b97a
commit
b15702aa53
6 changed files with 777 additions and 1316 deletions
25
src/db.c
25
src/db.c
|
|
@ -1731,6 +1731,31 @@ static void parse_mobile_toml(toml_table_t *mob_tab)
|
|||
!str_cmp(fname(mob_proto[i].player.short_descr), "the"))
|
||||
*mob_proto[i].player.short_descr = LOWER(*mob_proto[i].player.short_descr);
|
||||
|
||||
arr = toml_array_in(mob_tab, "extra_desc");
|
||||
if (arr) {
|
||||
int n = toml_array_nelem(arr);
|
||||
for (j = 0; j < n; j++) {
|
||||
toml_table_t *ed_tab = toml_table_at(arr, j);
|
||||
struct extra_descr_data *new_descr;
|
||||
char *keyword, *description;
|
||||
if (!ed_tab)
|
||||
continue;
|
||||
keyword = toml_get_string_dup(ed_tab, "keyword");
|
||||
description = toml_get_string_dup(ed_tab, "description");
|
||||
if (!keyword || !description) {
|
||||
if (keyword) free(keyword);
|
||||
if (description) free(description);
|
||||
continue;
|
||||
}
|
||||
CREATE(new_descr, struct extra_descr_data, 1);
|
||||
new_descr->keyword = keyword;
|
||||
new_descr->description = description;
|
||||
ensure_newline_terminated(new_descr);
|
||||
new_descr->next = mob_proto[i].mob_specials.ex_description;
|
||||
mob_proto[i].mob_specials.ex_description = new_descr;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < AF_ARRAY_MAX; j++) {
|
||||
MOB_FLAGS(mob_proto + i)[j] = 0;
|
||||
AFF_FLAGS(mob_proto + i)[j] = 0;
|
||||
|
|
|
|||
32
src/genmob.c
32
src/genmob.c
|
|
@ -128,6 +128,11 @@ static void extract_mobile_all(mob_vnum vnum)
|
|||
if (ch->player.background && ch->player.background != mob_proto[i].player.background)
|
||||
free(ch->player.background);
|
||||
ch->player.background = NULL;
|
||||
|
||||
if (ch->mob_specials.ex_description &&
|
||||
ch->mob_specials.ex_description != mob_proto[i].mob_specials.ex_description)
|
||||
free_ex_descriptions(ch->mob_specials.ex_description);
|
||||
ch->mob_specials.ex_description = NULL;
|
||||
|
||||
/* free script proto list if it's not the prototype */
|
||||
if (ch->proto_script && ch->proto_script != mob_proto[i].proto_script)
|
||||
|
|
@ -208,6 +213,8 @@ int copy_mobile_strings(struct char_data *t, struct char_data *f)
|
|||
t->player.description = strdup(f->player.description);
|
||||
if (f->player.background)
|
||||
t->player.background = strdup(f->player.background);
|
||||
if (f->mob_specials.ex_description)
|
||||
copy_ex_descriptions(&t->mob_specials.ex_description, f->mob_specials.ex_description);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -223,6 +230,7 @@ int update_mobile_strings(struct char_data *t, struct char_data *f)
|
|||
t->player.description = f->player.description;
|
||||
if (f->player.background)
|
||||
t->player.background = f->player.background;
|
||||
t->mob_specials.ex_description = f->mob_specials.ex_description;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -238,6 +246,10 @@ int free_mobile_strings(struct char_data *mob)
|
|||
free(mob->player.description);
|
||||
if (mob->player.background)
|
||||
free(mob->player.background);
|
||||
if (mob->mob_specials.ex_description) {
|
||||
free_ex_descriptions(mob->mob_specials.ex_description);
|
||||
mob->mob_specials.ex_description = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -266,6 +278,9 @@ int free_mobile(struct char_data *mob)
|
|||
free(mob->player.description);
|
||||
if (mob->player.background && mob->player.background != mob_proto[i].player.background)
|
||||
free(mob->player.background);
|
||||
if (mob->mob_specials.ex_description &&
|
||||
mob->mob_specials.ex_description != mob_proto[i].mob_specials.ex_description)
|
||||
free_ex_descriptions(mob->mob_specials.ex_description);
|
||||
/* free script proto list if it's not the prototype */
|
||||
if (mob->proto_script && mob->proto_script != mob_proto[i].proto_script)
|
||||
free_proto_script(mob, MOB_TRIGGER);
|
||||
|
|
@ -407,6 +422,7 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
char ldesc[MAX_STRING_LENGTH];
|
||||
char ddesc[MAX_STRING_LENGTH];
|
||||
char bdesc[MAX_STRING_LENGTH];
|
||||
char edesc_buf[MAX_STRING_LENGTH];
|
||||
int has_bdesc = 0;
|
||||
|
||||
ldesc[MAX_STRING_LENGTH - 1] = '\0';
|
||||
|
|
@ -438,6 +454,22 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
if (has_bdesc)
|
||||
toml_write_kv_string_opt(fd, "background", bdesc);
|
||||
|
||||
if (mob->mob_specials.ex_description) {
|
||||
struct extra_descr_data *xdesc;
|
||||
for (xdesc = mob->mob_specials.ex_description; xdesc; xdesc = xdesc->next) {
|
||||
if (!xdesc->keyword || !xdesc->description || !*xdesc->keyword || !*xdesc->description) {
|
||||
mudlog(BRF, LVL_IMMORT, TRUE, "SYSERR: GenOLC: write_mobile_record: Corrupt ex_desc!");
|
||||
continue;
|
||||
}
|
||||
strncpy(edesc_buf, xdesc->description, sizeof(edesc_buf) - 1);
|
||||
edesc_buf[sizeof(edesc_buf) - 1] = '\0';
|
||||
strip_cr(edesc_buf);
|
||||
fprintf(fd, "\n[[mob.extra_desc]]\n");
|
||||
toml_write_kv_string(fd, "keyword", xdesc->keyword);
|
||||
toml_write_kv_string(fd, "description", edesc_buf);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fd, "flags = [%d, %d, %d, %d]\n",
|
||||
MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1],
|
||||
MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3]);
|
||||
|
|
|
|||
597
src/set.c
597
src/set.c
|
|
@ -50,7 +50,9 @@ static void rset_show_usage(struct char_data *ch)
|
|||
" rset add sector <sector>\r\n"
|
||||
" rset add flags <flag> [flag ...]\r\n"
|
||||
" rset add exit <direction> <room number>\r\n"
|
||||
" rset add exitdesc <direction> <text>\r\n"
|
||||
" rset add door <direction> <name of door>\r\n"
|
||||
" rset add doorflags <direction> <flag> [flag ...]\r\n"
|
||||
" rset add key <direction> <key number>\r\n"
|
||||
" rset add hidden <direction>\r\n"
|
||||
" rset add forage <object vnum> <dc check>\r\n"
|
||||
|
|
@ -100,7 +102,9 @@ static void rset_show_add_usage(struct char_data *ch)
|
|||
" rset add sector <sector>\r\n"
|
||||
" rset add flags <flag> [flag ...]\r\n"
|
||||
" rset add exit <direction> <room number>\r\n"
|
||||
" rset add exitdesc <direction> <text>\r\n"
|
||||
" rset add door <direction> <name of door>\r\n"
|
||||
" rset add doorflags <direction> <flag> [flag ...]\r\n"
|
||||
" rset add key <direction> <key number>\r\n"
|
||||
" rset add hidden <direction>\r\n"
|
||||
" rset add forage <object vnum> <dc check>\r\n"
|
||||
|
|
@ -116,7 +120,9 @@ static void rset_show_del_usage(struct char_data *ch)
|
|||
"Usage:\r\n"
|
||||
" rset del flags <flag> [flag ...]\r\n"
|
||||
" rset del exit <direction>\r\n"
|
||||
" rset del exitdesc <direction>\r\n"
|
||||
" rset del door <direction>\r\n"
|
||||
" rset del doorflags <direction> <flag> [flag ...]\r\n"
|
||||
" rset del key <direction>\r\n"
|
||||
" rset del hidden <direction>\r\n"
|
||||
" rset del forage <object vnum>\r\n"
|
||||
|
|
@ -208,10 +214,22 @@ static void rset_show_add_exit_usage(struct char_data *ch)
|
|||
" rset add exit n 101\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_add_exitdesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Adds a description to an existing exit.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" rset add exitdesc <direction> <text>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" rset add exitdesc n A narrow arch leads north.\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_add_door_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Adds a door to an existing exit.\r\n"
|
||||
"Adds a door keyword to an existing exit.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" rset add door <direction> <name of door>\r\n"
|
||||
|
|
@ -220,6 +238,26 @@ static void rset_show_add_door_usage(struct char_data *ch)
|
|||
" rset add door n door\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_add_doorflags_usage(struct char_data *ch)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (*exit_bits[count] != '\n')
|
||||
count++;
|
||||
|
||||
send_to_char(ch,
|
||||
"Adds door flags to an existing exit.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" rset add doorflags <direction> <flag> [flag ...]\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" rset add doorflags n closed locked\r\n"
|
||||
"\r\n"
|
||||
"Flags:\r\n");
|
||||
column_list(ch, 0, exit_bits, count, FALSE);
|
||||
}
|
||||
|
||||
static void rset_show_add_key_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
|
|
@ -280,6 +318,18 @@ static void rset_show_del_exit_usage(struct char_data *ch)
|
|||
" rset del exit n\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_del_exitdesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Deletes the description from an existing exit.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" rset del exitdesc <direction>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" rset del exitdesc n\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_del_door_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
|
|
@ -292,6 +342,26 @@ static void rset_show_del_door_usage(struct char_data *ch)
|
|||
" rset del door n\r\n");
|
||||
}
|
||||
|
||||
static void rset_show_del_doorflags_usage(struct char_data *ch)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (*exit_bits[count] != '\n')
|
||||
count++;
|
||||
|
||||
send_to_char(ch,
|
||||
"Deletes door flags from an existing exit.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" rset del doorflags <direction> <flag> [flag ...]\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" rset del doorflags n locked\r\n"
|
||||
"\r\n"
|
||||
"Flags:\r\n");
|
||||
column_list(ch, 0, exit_bits, count, FALSE);
|
||||
}
|
||||
|
||||
static void rset_show_del_key_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
|
|
@ -380,6 +450,17 @@ static int rset_find_dir(const char *arg)
|
|||
return dir;
|
||||
}
|
||||
|
||||
static int rset_find_exit_flag(const char *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; *exit_bits[i] != '\n'; i++)
|
||||
if (is_abbrev(arg, exit_bits[i]))
|
||||
return (1 << i);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void rset_mark_room_modified(room_rnum rnum)
|
||||
{
|
||||
if (rnum == NOWHERE || rnum < 0 || rnum > top_of_world)
|
||||
|
|
@ -436,6 +517,8 @@ static void rset_show_room(struct char_data *ch, struct room_data *room)
|
|||
exit->keyword ? exit->keyword : "None",
|
||||
keybuf,
|
||||
buf);
|
||||
if (exit->general_description && *exit->general_description)
|
||||
send_to_char(ch, " desc: %s\r\n", exit->general_description);
|
||||
count++;
|
||||
}
|
||||
if (!count)
|
||||
|
|
@ -831,6 +914,39 @@ ACMD(do_rset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "exitdesc")) {
|
||||
int dir;
|
||||
char *desc;
|
||||
|
||||
argument = one_argument(argument, arg3);
|
||||
skip_spaces(&argument);
|
||||
desc = argument;
|
||||
|
||||
if (!*arg3 || !*desc) {
|
||||
rset_show_add_exitdesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
dir = rset_find_dir(arg3);
|
||||
if (dir < 0) {
|
||||
send_to_char(ch, "Invalid direction.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!room->dir_option[dir] || room->dir_option[dir]->to_room == NOWHERE) {
|
||||
send_to_char(ch, "That exit does not exist.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
genolc_checkstring(ch->desc, desc);
|
||||
if (room->dir_option[dir]->general_description)
|
||||
free(room->dir_option[dir]->general_description);
|
||||
room->dir_option[dir]->general_description = str_udup(desc);
|
||||
rset_mark_room_modified(rnum);
|
||||
send_to_char(ch, "Exit description set for %s.\r\n", dirs[dir]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "door")) {
|
||||
int dir;
|
||||
char *door_name;
|
||||
|
|
@ -865,6 +981,56 @@ ACMD(do_rset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "doorflags")) {
|
||||
int dir;
|
||||
bool any = FALSE;
|
||||
|
||||
argument = one_argument(argument, arg3);
|
||||
if (!*arg3) {
|
||||
rset_show_add_doorflags_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
dir = rset_find_dir(arg3);
|
||||
if (dir < 0) {
|
||||
send_to_char(ch, "Invalid direction.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!room->dir_option[dir] || room->dir_option[dir]->to_room == NOWHERE) {
|
||||
send_to_char(ch, "That exit does not exist.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*argument) {
|
||||
rset_show_add_doorflags_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
while (*argument) {
|
||||
int flag;
|
||||
|
||||
argument = one_argument(argument, arg1);
|
||||
if (!*arg1)
|
||||
break;
|
||||
|
||||
flag = rset_find_exit_flag(arg1);
|
||||
if (flag < 0) {
|
||||
send_to_char(ch, "Unknown door flag: %s\r\n", arg1);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_BIT(room->dir_option[dir]->exit_info, flag);
|
||||
any = TRUE;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
rset_mark_room_modified(rnum);
|
||||
send_to_char(ch, "Door flags updated on %s.\r\n", dirs[dir]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "key")) {
|
||||
int dir;
|
||||
int key_vnum;
|
||||
|
|
@ -1088,6 +1254,36 @@ ACMD(do_rset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "exitdesc")) {
|
||||
int dir;
|
||||
|
||||
argument = one_argument(argument, arg3);
|
||||
if (!*arg3) {
|
||||
rset_show_del_exitdesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
dir = rset_find_dir(arg3);
|
||||
if (dir < 0) {
|
||||
send_to_char(ch, "Invalid direction.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!room->dir_option[dir] || room->dir_option[dir]->to_room == NOWHERE) {
|
||||
send_to_char(ch, "That exit does not exist.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (room->dir_option[dir]->general_description) {
|
||||
free(room->dir_option[dir]->general_description);
|
||||
room->dir_option[dir]->general_description = NULL;
|
||||
}
|
||||
|
||||
rset_mark_room_modified(rnum);
|
||||
send_to_char(ch, "Exit description removed from %s.\r\n", dirs[dir]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "door")) {
|
||||
int dir;
|
||||
|
||||
|
|
@ -1123,6 +1319,56 @@ ACMD(do_rset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "doorflags")) {
|
||||
int dir;
|
||||
bool any = FALSE;
|
||||
|
||||
argument = one_argument(argument, arg3);
|
||||
if (!*arg3) {
|
||||
rset_show_del_doorflags_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
dir = rset_find_dir(arg3);
|
||||
if (dir < 0) {
|
||||
send_to_char(ch, "Invalid direction.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!room->dir_option[dir] || room->dir_option[dir]->to_room == NOWHERE) {
|
||||
send_to_char(ch, "That exit does not exist.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*argument) {
|
||||
rset_show_del_doorflags_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
while (*argument) {
|
||||
int flag;
|
||||
|
||||
argument = one_argument(argument, arg1);
|
||||
if (!*arg1)
|
||||
break;
|
||||
|
||||
flag = rset_find_exit_flag(arg1);
|
||||
if (flag < 0) {
|
||||
send_to_char(ch, "Unknown door flag: %s\r\n", arg1);
|
||||
continue;
|
||||
}
|
||||
|
||||
REMOVE_BIT(room->dir_option[dir]->exit_info, flag);
|
||||
any = TRUE;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
rset_mark_room_modified(rnum);
|
||||
send_to_char(ch, "Door flags updated on %s.\r\n", dirs[dir]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "key")) {
|
||||
int dir;
|
||||
|
||||
|
|
@ -1309,6 +1555,7 @@ static void oset_show_usage(struct char_data *ch)
|
|||
" oset add weight <obj> <value>\r\n"
|
||||
" oset add cost <obj> <value>\r\n"
|
||||
" oset add oval <obj> <oval number> <value>\r\n"
|
||||
" oset add edesc <obj> <keyword> <description>\r\n"
|
||||
" oset del <obj> <field>\r\n"
|
||||
" oset clear <obj> force\r\n"
|
||||
" oset validate <obj>\r\n");
|
||||
|
|
@ -1329,7 +1576,8 @@ static void oset_show_add_usage(struct char_data *ch)
|
|||
" oset add wear <obj> <wear type> [wear types]\r\n"
|
||||
" oset add weight <obj> <value>\r\n"
|
||||
" oset add cost <obj> <value>\r\n"
|
||||
" oset add oval <obj> <oval number> <value>\r\n");
|
||||
" oset add oval <obj> <oval number> <value>\r\n"
|
||||
" oset add edesc <obj> <keyword> <description>\r\n");
|
||||
}
|
||||
|
||||
static void oset_show_add_keywords_usage(struct char_data *ch)
|
||||
|
|
@ -1442,6 +1690,18 @@ static void oset_show_add_oval_usage(struct char_data *ch)
|
|||
" oset add oval sword weapon_type slashing (for weapons)\r\n");
|
||||
}
|
||||
|
||||
static void oset_show_add_edesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Adds an extra description to the object.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" oset add edesc <obj> <keyword> <description>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" oset add edesc sword rune A rune is etched along the blade.\r\n");
|
||||
}
|
||||
|
||||
static void oset_show_del_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
|
|
@ -1452,6 +1712,7 @@ static void oset_show_del_usage(struct char_data *ch)
|
|||
" oset del <obj> flags <flags> [flags]\r\n"
|
||||
" oset del <obj> wear <wear type> [wear types]\r\n"
|
||||
" oset del <obj> oval <oval number|oval name>\r\n"
|
||||
" oset del <obj> edesc <keyword>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" oset del sword keywords sword\r\n"
|
||||
|
|
@ -1502,6 +1763,18 @@ static void oset_show_clear_usage(struct char_data *ch)
|
|||
" oset clear sword force\r\n");
|
||||
}
|
||||
|
||||
static void oset_show_del_edesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Deletes an extra description from the object.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" oset del <obj> edesc <keyword>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" oset del sword edesc rune\r\n");
|
||||
}
|
||||
|
||||
static struct obj_data *oset_get_target_obj_keyword(struct char_data *ch, char *keyword)
|
||||
{
|
||||
struct obj_data *obj;
|
||||
|
|
@ -1718,6 +1991,15 @@ static void oset_show_object(struct char_data *ch, struct obj_data *obj)
|
|||
const char *label = labels ? labels[i] : "Value";
|
||||
send_to_char(ch, " [%d] %s: %d\r\n", i, label, GET_OBJ_VAL(obj, i));
|
||||
}
|
||||
|
||||
send_to_char(ch, "Extra Descs:\r\n");
|
||||
i = 0;
|
||||
for (struct extra_descr_data *desc = obj->ex_description; desc; desc = desc->next) {
|
||||
send_to_char(ch, " %s\r\n", desc->keyword ? desc->keyword : "<None>");
|
||||
i++;
|
||||
}
|
||||
if (!i)
|
||||
send_to_char(ch, " None.\r\n");
|
||||
}
|
||||
|
||||
static void oset_desc_edit(struct char_data *ch, struct obj_data *obj)
|
||||
|
|
@ -1759,7 +2041,7 @@ static void oset_clear_object(struct obj_data *obj)
|
|||
GET_OBJ_COST(obj) = 0;
|
||||
GET_OBJ_COST_PER_DAY(obj) = 0;
|
||||
GET_OBJ_TIMER(obj) = 0;
|
||||
GET_OBJ_LEVEL(obj) = 0;
|
||||
GET_OBJ_LEVEL(obj) = 1;
|
||||
|
||||
memset(obj->obj_flags.extra_flags, 0, sizeof(obj->obj_flags.extra_flags));
|
||||
memset(obj->obj_flags.wear_flags, 0, sizeof(obj->obj_flags.wear_flags));
|
||||
|
|
@ -1809,6 +2091,33 @@ static void oset_validate_object(struct char_data *ch, struct obj_data *obj)
|
|||
errors++;
|
||||
}
|
||||
|
||||
if (GET_OBJ_LEVEL(obj) != 1) {
|
||||
send_to_char(ch, "Error: object level must be 1.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (GET_OBJ_TIMER(obj) != 0) {
|
||||
send_to_char(ch, "Error: object timer must be 0.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (GET_OBJ_COST_PER_DAY(obj) != 0) {
|
||||
send_to_char(ch, "Error: cost per day must be 0.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
for (struct extra_descr_data *desc = obj->ex_description; desc; desc = desc->next) {
|
||||
if (!desc->keyword || !*desc->keyword) {
|
||||
send_to_char(ch, "Error: extra description is missing a keyword.\r\n");
|
||||
errors++;
|
||||
}
|
||||
if (!desc->description || !*desc->description) {
|
||||
send_to_char(ch, "Error: extra description for %s is missing text.\r\n",
|
||||
desc->keyword ? desc->keyword : "<None>");
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!errors)
|
||||
send_to_char(ch, "Object validates cleanly.\r\n");
|
||||
else
|
||||
|
|
@ -2160,6 +2469,40 @@ ACMD(do_oset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "edesc")) {
|
||||
struct extra_descr_data *desc;
|
||||
char *keyword;
|
||||
char *edesc;
|
||||
|
||||
argument = one_argument(argument, arg3);
|
||||
argument = one_argument(argument, arg4);
|
||||
skip_spaces(&argument);
|
||||
keyword = arg4;
|
||||
edesc = argument;
|
||||
|
||||
if (!*arg3 || !*keyword || !*edesc) {
|
||||
oset_show_add_edesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
obj = oset_get_target_obj_keyword(ch, arg3);
|
||||
if (!obj) {
|
||||
send_to_char(ch, "You don't seem to have %s %s.\r\n", AN(arg3), arg3);
|
||||
return;
|
||||
}
|
||||
|
||||
genolc_checkstring(ch->desc, edesc);
|
||||
genolc_checkstring(ch->desc, keyword);
|
||||
|
||||
CREATE(desc, struct extra_descr_data, 1);
|
||||
desc->keyword = str_udup(keyword);
|
||||
desc->description = str_udup(edesc);
|
||||
desc->next = obj->ex_description;
|
||||
obj->ex_description = desc;
|
||||
send_to_char(ch, "Extra description added.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
oset_show_add_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2289,6 +2632,46 @@ ACMD(do_oset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg3, "edesc")) {
|
||||
struct extra_descr_data *desc;
|
||||
struct extra_descr_data *prev = NULL;
|
||||
|
||||
argument = one_argument(argument, arg4);
|
||||
if (!*arg4) {
|
||||
oset_show_del_edesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
obj = oset_get_target_obj_keyword(ch, arg2);
|
||||
if (!obj) {
|
||||
send_to_char(ch, "You don't seem to have %s %s.\r\n", AN(arg2), arg2);
|
||||
return;
|
||||
}
|
||||
|
||||
for (desc = obj->ex_description; desc; desc = desc->next) {
|
||||
if (desc->keyword && isname(arg4, desc->keyword))
|
||||
break;
|
||||
prev = desc;
|
||||
}
|
||||
|
||||
if (!desc) {
|
||||
send_to_char(ch, "No extra description found for %s.\r\n", arg4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
prev->next = desc->next;
|
||||
else
|
||||
obj->ex_description = desc->next;
|
||||
|
||||
if (desc->keyword)
|
||||
free(desc->keyword);
|
||||
if (desc->description)
|
||||
free(desc->description);
|
||||
free(desc);
|
||||
send_to_char(ch, "Extra description removed.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
oset_show_del_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2359,6 +2742,7 @@ static void mset_show_usage(struct char_data *ch)
|
|||
" mset add ldesc <npc> <text>\r\n"
|
||||
" mset add desc <npc> (enters editor)\r\n"
|
||||
" mset add background <npc> (enters editor)\r\n"
|
||||
" mset add edesc <npc> <keyword> <description>\r\n"
|
||||
" mset add attack <npc> <attack type>\r\n"
|
||||
" mset add sex <npc> <male/female/neutral>\r\n"
|
||||
" mset add species <npc> <species name>\r\n"
|
||||
|
|
@ -2441,6 +2825,18 @@ static void mset_show_add_background_usage(struct char_data *ch)
|
|||
" mset add background <npc>\r\n");
|
||||
}
|
||||
|
||||
static void mset_show_add_edesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Adds an extra description to the NPC.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" mset add edesc <npc> <keyword> <description>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" mset add edesc guard scar A jagged scar cuts across the cheek.\r\n");
|
||||
}
|
||||
|
||||
static void mset_show_add_attack_usage(struct char_data *ch)
|
||||
{
|
||||
const char *types[NUM_ATTACK_TYPES];
|
||||
|
|
@ -2597,6 +2993,7 @@ static void mset_show_del_usage(struct char_data *ch)
|
|||
" mset del <npc> ldesc\r\n"
|
||||
" mset del <npc> desc\r\n"
|
||||
" mset del <npc> background\r\n"
|
||||
" mset del <npc> edesc <keyword>\r\n"
|
||||
" mset del <npc> attack\r\n"
|
||||
" mset del <npc> sex\r\n"
|
||||
" mset del <npc> species\r\n"
|
||||
|
|
@ -2609,6 +3006,18 @@ static void mset_show_del_usage(struct char_data *ch)
|
|||
" mset del <npc> skinning <vnum>\r\n");
|
||||
}
|
||||
|
||||
static void mset_show_del_edesc_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
"Deletes an extra description from the NPC.\r\n"
|
||||
"\r\n"
|
||||
"Usage:\r\n"
|
||||
" mset del <npc> edesc <keyword>\r\n"
|
||||
"\r\n"
|
||||
"Examples:\r\n"
|
||||
" mset del guard edesc scar\r\n");
|
||||
}
|
||||
|
||||
static void mset_show_del_flags_usage(struct char_data *ch)
|
||||
{
|
||||
send_to_char(ch,
|
||||
|
|
@ -2754,6 +3163,19 @@ static void mset_update_proto_keywords(mob_rnum rnum, const char *value)
|
|||
free(old);
|
||||
}
|
||||
|
||||
static void mset_update_proto_edesc(mob_rnum rnum, struct extra_descr_data *old)
|
||||
{
|
||||
struct char_data *mob;
|
||||
|
||||
if (rnum < 0)
|
||||
return;
|
||||
|
||||
for (mob = character_list; mob; mob = mob->next) {
|
||||
if (GET_MOB_RNUM(mob) == rnum && mob->mob_specials.ex_description == old)
|
||||
mob->mob_specials.ex_description = mob_proto[rnum].mob_specials.ex_description;
|
||||
}
|
||||
}
|
||||
|
||||
static void mset_replace_string(struct char_data *mob, char **field, const char *value, const char *proto_field)
|
||||
{
|
||||
if (*field && (!proto_field || *field != proto_field))
|
||||
|
|
@ -2867,6 +3289,15 @@ static void mset_show_mob(struct char_data *ch, struct char_data *mob)
|
|||
} else {
|
||||
send_to_char(ch, " None.\r\n");
|
||||
}
|
||||
|
||||
send_to_char(ch, "Extra Descs:\r\n");
|
||||
i = 0;
|
||||
for (struct extra_descr_data *desc = mob->mob_specials.ex_description; desc; desc = desc->next) {
|
||||
send_to_char(ch, " %s\r\n", desc->keyword ? desc->keyword : "<None>");
|
||||
i++;
|
||||
}
|
||||
if (!i)
|
||||
send_to_char(ch, " None.\r\n");
|
||||
}
|
||||
|
||||
static void mset_desc_edit(struct char_data *ch, char **field, const char *label)
|
||||
|
|
@ -2933,6 +3364,33 @@ static void mset_validate_mob(struct char_data *ch, struct char_data *mob)
|
|||
errors++;
|
||||
}
|
||||
|
||||
for (struct extra_descr_data *desc = mob->mob_specials.ex_description; desc; desc = desc->next) {
|
||||
if (!desc->keyword || !*desc->keyword) {
|
||||
send_to_char(ch, "Error: extra description is missing a keyword.\r\n");
|
||||
errors++;
|
||||
}
|
||||
if (!desc->description || !*desc->description) {
|
||||
send_to_char(ch, "Error: extra description for %s is missing text.\r\n",
|
||||
desc->keyword ? desc->keyword : "<None>");
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_LEVEL(mob) != 1) {
|
||||
send_to_char(ch, "Error: level must be 1.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (GET_DEFAULT_POS(mob) != POS_STANDING) {
|
||||
send_to_char(ch, "Error: default position must be standing.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (GET_EXP(mob) != 0) {
|
||||
send_to_char(ch, "Error: EXP must be 0.\r\n");
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (!errors)
|
||||
send_to_char(ch, "NPC validates cleanly.\r\n");
|
||||
else
|
||||
|
|
@ -3165,6 +3623,46 @@ ACMD(do_mset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "edesc")) {
|
||||
struct extra_descr_data *desc;
|
||||
struct extra_descr_data *old;
|
||||
char *keyword;
|
||||
char *edesc;
|
||||
|
||||
argument = one_argument(argument, arg1);
|
||||
skip_spaces(&argument);
|
||||
keyword = arg1;
|
||||
edesc = argument;
|
||||
|
||||
if (!*keyword || !*edesc) {
|
||||
mset_show_add_edesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
genolc_checkstring(ch->desc, edesc);
|
||||
genolc_checkstring(ch->desc, keyword);
|
||||
|
||||
if (rnum != NOBODY) {
|
||||
old = mob_proto[rnum].mob_specials.ex_description;
|
||||
CREATE(desc, struct extra_descr_data, 1);
|
||||
desc->keyword = str_udup(keyword);
|
||||
desc->description = str_udup(edesc);
|
||||
desc->next = mob_proto[rnum].mob_specials.ex_description;
|
||||
mob_proto[rnum].mob_specials.ex_description = desc;
|
||||
mset_update_proto_edesc(rnum, old);
|
||||
mset_mark_mob_modified(vnum);
|
||||
} else {
|
||||
CREATE(desc, struct extra_descr_data, 1);
|
||||
desc->keyword = str_udup(keyword);
|
||||
desc->description = str_udup(edesc);
|
||||
desc->next = mob->mob_specials.ex_description;
|
||||
mob->mob_specials.ex_description = desc;
|
||||
}
|
||||
|
||||
send_to_char(ch, "Extra description added.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg2, "attack")) {
|
||||
int atype;
|
||||
|
||||
|
|
@ -3663,6 +4161,74 @@ ACMD(do_mset)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg3, "edesc")) {
|
||||
struct extra_descr_data *desc;
|
||||
struct extra_descr_data *prev = NULL;
|
||||
struct extra_descr_data *old;
|
||||
|
||||
argument = one_argument(argument, arg1);
|
||||
if (!*arg1) {
|
||||
mset_show_del_edesc_usage(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rnum != NOBODY) {
|
||||
old = mob_proto[rnum].mob_specials.ex_description;
|
||||
desc = mob_proto[rnum].mob_specials.ex_description;
|
||||
while (desc) {
|
||||
if (desc->keyword && isname(arg1, desc->keyword))
|
||||
break;
|
||||
prev = desc;
|
||||
desc = desc->next;
|
||||
}
|
||||
|
||||
if (!desc) {
|
||||
send_to_char(ch, "No extra description found for %s.\r\n", arg1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
prev->next = desc->next;
|
||||
else
|
||||
mob_proto[rnum].mob_specials.ex_description = desc->next;
|
||||
|
||||
if (desc->keyword)
|
||||
free(desc->keyword);
|
||||
if (desc->description)
|
||||
free(desc->description);
|
||||
free(desc);
|
||||
mset_update_proto_edesc(rnum, old);
|
||||
mset_mark_mob_modified(vnum);
|
||||
} else {
|
||||
desc = mob->mob_specials.ex_description;
|
||||
while (desc) {
|
||||
if (desc->keyword && isname(arg1, desc->keyword))
|
||||
break;
|
||||
prev = desc;
|
||||
desc = desc->next;
|
||||
}
|
||||
|
||||
if (!desc) {
|
||||
send_to_char(ch, "No extra description found for %s.\r\n", arg1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
prev->next = desc->next;
|
||||
else
|
||||
mob->mob_specials.ex_description = desc->next;
|
||||
|
||||
if (desc->keyword)
|
||||
free(desc->keyword);
|
||||
if (desc->description)
|
||||
free(desc->description);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
send_to_char(ch, "Extra description removed.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_abbrev(arg3, "attack")) {
|
||||
mob->mob_specials.attack_type = 0;
|
||||
if (rnum != NOBODY) {
|
||||
|
|
@ -3946,6 +4512,8 @@ ACMD(do_mset)
|
|||
}
|
||||
|
||||
if (rnum != NOBODY) {
|
||||
struct extra_descr_data *old_edesc = mob_proto[rnum].mob_specials.ex_description;
|
||||
|
||||
if (mob_proto[rnum].player.name)
|
||||
free(mob_proto[rnum].player.name);
|
||||
if (mob_proto[rnum].player.short_descr)
|
||||
|
|
@ -3956,17 +4524,25 @@ ACMD(do_mset)
|
|||
free(mob_proto[rnum].player.description);
|
||||
if (mob_proto[rnum].player.background)
|
||||
free(mob_proto[rnum].player.background);
|
||||
if (mob_proto[rnum].mob_specials.ex_description)
|
||||
free_ex_descriptions(mob_proto[rnum].mob_specials.ex_description);
|
||||
|
||||
mob_proto[rnum].player.name = strdup("An unfinished NPC");
|
||||
mob_proto[rnum].player.short_descr = strdup("the unfinished npc");
|
||||
mob_proto[rnum].player.long_descr = strdup("An unfinished npc stands here.\r\n");
|
||||
mob_proto[rnum].player.description = strdup("It looks unfinished.\r\n");
|
||||
mob_proto[rnum].player.background = strdup("No background has been recorded.\r\n");
|
||||
mob_proto[rnum].mob_specials.ex_description = NULL;
|
||||
mset_update_proto_edesc(rnum, old_edesc);
|
||||
|
||||
mob_proto[rnum].mob_specials.attack_type = 0;
|
||||
GET_SEX(&mob_proto[rnum]) = SEX_NEUTRAL;
|
||||
GET_CLASS(&mob_proto[rnum]) = CLASS_UNDEFINED;
|
||||
GET_SPECIES(&mob_proto[rnum]) = SPECIES_UNDEFINED;
|
||||
GET_LEVEL(&mob_proto[rnum]) = 1;
|
||||
GET_DEFAULT_POS(&mob_proto[rnum]) = POS_STANDING;
|
||||
GET_POS(&mob_proto[rnum]) = POS_STANDING;
|
||||
GET_EXP(&mob_proto[rnum]) = 0;
|
||||
|
||||
mset_set_stat_value(&mob_proto[rnum], ABIL_STR, 10, FALSE);
|
||||
mset_set_stat_value(&mob_proto[rnum], ABIL_DEX, 10, FALSE);
|
||||
|
|
@ -3997,11 +4573,19 @@ ACMD(do_mset)
|
|||
mset_replace_string(mob, &GET_LDESC(mob), "An unfinished npc stands here.\r\n", NULL);
|
||||
mset_replace_string(mob, &mob->player.description, "It looks unfinished.\r\n", NULL);
|
||||
mset_replace_string(mob, &mob->player.background, "No background has been recorded.\r\n", NULL);
|
||||
if (mob->mob_specials.ex_description) {
|
||||
free_ex_descriptions(mob->mob_specials.ex_description);
|
||||
mob->mob_specials.ex_description = NULL;
|
||||
}
|
||||
|
||||
mob->mob_specials.attack_type = 0;
|
||||
GET_SEX(mob) = SEX_NEUTRAL;
|
||||
GET_CLASS(mob) = CLASS_UNDEFINED;
|
||||
GET_SPECIES(mob) = SPECIES_UNDEFINED;
|
||||
GET_LEVEL(mob) = 1;
|
||||
GET_DEFAULT_POS(mob) = POS_STANDING;
|
||||
GET_POS(mob) = POS_STANDING;
|
||||
GET_EXP(mob) = 0;
|
||||
|
||||
mset_set_stat_value(mob, ABIL_STR, 10, TRUE);
|
||||
mset_set_stat_value(mob, ABIL_DEX, 10, TRUE);
|
||||
|
|
@ -4157,6 +4741,9 @@ ACMD(do_mcreate)
|
|||
init_mobile(newmob);
|
||||
|
||||
GET_LEVEL(newmob) = 1;
|
||||
GET_DEFAULT_POS(newmob) = POS_STANDING;
|
||||
GET_POS(newmob) = POS_STANDING;
|
||||
GET_EXP(newmob) = 0;
|
||||
|
||||
GET_NAME(newmob) = strdup("An unfinished NPC");
|
||||
GET_KEYWORDS(newmob) = strdup("unfinished npc");
|
||||
|
|
@ -4289,6 +4876,10 @@ ACMD(do_ocreate)
|
|||
CREATE(newobj, struct obj_data, 1);
|
||||
clear_object(newobj);
|
||||
|
||||
GET_OBJ_LEVEL(newobj) = 1;
|
||||
GET_OBJ_TIMER(newobj) = 0;
|
||||
GET_OBJ_COST_PER_DAY(newobj) = 0;
|
||||
|
||||
newobj->name = strdup("unfinished object");
|
||||
strlcpy(namebuf, GET_NAME(ch), sizeof(namebuf));
|
||||
snprintf(buf, sizeof(buf), "unfinished object made by %s", namebuf);
|
||||
|
|
|
|||
|
|
@ -1088,6 +1088,7 @@ struct mob_special_data
|
|||
byte attack_type; /**< The primary attack type (bite, sting, hit, etc.) */
|
||||
byte default_pos; /**< Default position (standing, sleeping, etc.) */
|
||||
byte skills[MAX_SKILLS]; /* NPC-specific skill proficiency (0-100) */
|
||||
struct extra_descr_data *ex_description; /**< Extra descriptions */
|
||||
};
|
||||
|
||||
/** An affect structure. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue