Background addition

This commit is contained in:
kinther 2025-12-14 14:26:09 -08:00
parent 2e1d7816f6
commit 4f2e68a369
13 changed files with 202 additions and 41 deletions

View file

@ -1237,6 +1237,7 @@ static void do_stat_character(struct char_data *ch, struct char_data *k)
}
send_to_char(ch, "D-Desc:\r\n %s", k->player.description ? k->player.description : "<None>\r\n");
send_to_char(ch, "Background:\r\n %s", k->player.background ? k->player.background : "<None>\r\n");
if (!IS_NPC(k)) {
char buf1[64], buf2[64];

View file

@ -589,10 +589,12 @@ void destroy_db(void)
free(mob_proto[cnt].player.name);
if (mob_proto[cnt].player.short_descr)
free(mob_proto[cnt].player.short_descr);
if (mob_proto[cnt].player.long_descr)
free(mob_proto[cnt].player.long_descr);
if (mob_proto[cnt].player.description)
free(mob_proto[cnt].player.description);
if (mob_proto[cnt].player.long_descr)
free(mob_proto[cnt].player.long_descr);
if (mob_proto[cnt].player.description)
free(mob_proto[cnt].player.description);
if (mob_proto[cnt].player.background)
free(mob_proto[cnt].player.background);
/* free script proto list */
free_proto_script(&mob_proto[cnt], MOB_TRIGGER);
@ -1776,6 +1778,33 @@ void parse_mobile(FILE *mob_f, int nr)
*tmpptr = LOWER(*tmpptr);
mob_proto[i].player.long_descr = fread_string(mob_f, buf2);
mob_proto[i].player.description = fread_string(mob_f, buf2);
mob_proto[i].player.background = NULL;
/* Optional background block signaled by a leading 'B' marker */
{
int letter;
do {
letter = fgetc(mob_f);
if (letter == EOF)
break;
} while (letter == '\n' || letter == '\r');
if (letter == 'B') {
mob_proto[i].player.background = fread_string(mob_f, buf2);
/* consume trailing newlines before numeric section */
do {
letter = fgetc(mob_f);
if (letter == EOF)
break;
} while (letter == '\n' || letter == '\r');
if (letter != EOF)
ungetc(letter, mob_f);
} else if (letter != EOF)
ungetc(letter, mob_f);
}
/* Numeric data */
if (!get_line(mob_f, line)) {
@ -3393,6 +3422,8 @@ void free_char(struct char_data *ch)
free(ch->player.long_descr);
if (ch->player.description)
free(ch->player.description);
if (ch->player.background)
free(ch->player.background);
for (i = 0; i < NUM_HIST; i++)
if (GET_HISTORY(ch, i))
free_history(ch, i);
@ -3413,6 +3444,8 @@ void free_char(struct char_data *ch)
free(ch->player.long_descr);
if (ch->player.description && ch->player.description != mob_proto[i].player.description)
free(ch->player.description);
if (ch->player.background && ch->player.background != mob_proto[i].player.background)
free(ch->player.background);
/* free script proto list if it's not the prototype */
if (ch->proto_script && ch->proto_script != mob_proto[i].proto_script)
free_proto_script(ch, MOB_TRIGGER);
@ -3655,6 +3688,7 @@ void init_char(struct char_data *ch)
ch->player.short_descr = NULL;
ch->player.long_descr = NULL;
ch->player.description = NULL;
ch->player.background = NULL;
GET_NUM_QUESTS(ch) = 0;
ch->player_specials->saved.completed_quests = NULL;

View file

@ -948,6 +948,8 @@ ACMD(do_mtransform)
tmpmob.player.long_descr = strdup(m->player.long_descr);
if(m->player.description)
tmpmob.player.description = strdup(m->player.description);
if(m->player.background)
tmpmob.player.background = strdup(m->player.background);
tmpmob.script_id = ch->script_id;
tmpmob.affected = ch->affected;

View file

@ -123,6 +123,10 @@ static void extract_mobile_all(mob_vnum vnum)
if (ch->player.description && ch->player.description != mob_proto[i].player.description)
free(ch->player.description);
ch->player.description = NULL;
if (ch->player.background && ch->player.background != mob_proto[i].player.background)
free(ch->player.background);
ch->player.background = NULL;
/* free script proto list if it's not the prototype */
if (ch->proto_script && ch->proto_script != mob_proto[i].proto_script)
@ -201,6 +205,8 @@ int copy_mobile_strings(struct char_data *t, struct char_data *f)
t->player.long_descr = strdup(f->player.long_descr);
if (f->player.description)
t->player.description = strdup(f->player.description);
if (f->player.background)
t->player.background = strdup(f->player.background);
return TRUE;
}
@ -214,6 +220,8 @@ int update_mobile_strings(struct char_data *t, struct char_data *f)
t->player.long_descr = f->player.long_descr;
if (f->player.description)
t->player.description = f->player.description;
if (f->player.background)
t->player.background = f->player.background;
return TRUE;
}
@ -227,6 +235,8 @@ int free_mobile_strings(struct char_data *mob)
free(mob->player.long_descr);
if (mob->player.description)
free(mob->player.description);
if (mob->player.background)
free(mob->player.background);
return TRUE;
}
@ -253,6 +263,8 @@ int free_mobile(struct char_data *mob)
free(mob->player.long_descr);
if (mob->player.description && mob->player.description != mob_proto[i].player.description)
free(mob->player.description);
if (mob->player.background && mob->player.background != mob_proto[i].player.background)
free(mob->player.background);
/* 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);
@ -377,12 +389,18 @@ 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 buf[MAX_STRING_LENGTH];
ldesc[MAX_STRING_LENGTH - 1] = '\0';
ddesc[MAX_STRING_LENGTH - 1] = '\0';
bdesc[MAX_STRING_LENGTH - 1] = '\0';
strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1));
strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1));
if (GET_BDESC(mob))
strip_cr(strncpy(bdesc, GET_BDESC(mob), MAX_STRING_LENGTH - 1));
else
bdesc[0] = '\0';
int n = snprintf(buf, MAX_STRING_LENGTH,
"#%d\n"
@ -390,13 +408,16 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
"%s%c\n"
"%s%c\n"
"%s%c\n"
"%s%c\n"
"B\n"
"%s%c\n",
mvnum,
GET_NAME(mob), STRING_TERMINATOR,
GET_KEYWORDS(mob), STRING_TERMINATOR,
GET_SDESC(mob), STRING_TERMINATOR,
ldesc, STRING_TERMINATOR,
ddesc, STRING_TERMINATOR);
ddesc, STRING_TERMINATOR,
bdesc, STRING_TERMINATOR);
if (n >= MAX_STRING_LENGTH) {
mudlog(BRF, LVL_BUILDER, TRUE,

View file

@ -34,6 +34,7 @@ int write_mobile_mobprog(mob_vnum mvnum, struct char_data *mob, FILE *fd);
#define GET_SDESC(mob) ((mob)->player.short_descr)
#define GET_LDESC(mob) ((mob)->player.long_descr)
#define GET_DDESC(mob) ((mob)->player.description)
#define GET_BDESC(mob) ((mob)->player.background)
#define GET_ATTACK(mob) ((mob)->mob_specials.attack_type)
#endif /* _GENMOB_H_ */

View file

@ -594,22 +594,31 @@ static int export_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];
ldesc[MAX_STRING_LENGTH - 1] = '\0';
ddesc[MAX_STRING_LENGTH - 1] = '\0';
bdesc[MAX_STRING_LENGTH - 1] = '\0';
strip_cr(strncpy(ldesc, GET_LDESC(mob), MAX_STRING_LENGTH - 1));
strip_cr(strncpy(ddesc, GET_DDESC(mob), MAX_STRING_LENGTH - 1));
if (GET_BDESC(mob))
strip_cr(strncpy(bdesc, GET_BDESC(mob), MAX_STRING_LENGTH - 1));
else
bdesc[0] = '\0';
fprintf(fd, "#QQ%02d\n"
"%s%c\n"
"%s%c\n"
"%s%c\n"
"%s%c\n"
"B\n"
"%s%c\n",
mvnum%100,
GET_KEYWORDS(mob), STRING_TERMINATOR,
GET_SDESC(mob), STRING_TERMINATOR,
ldesc, STRING_TERMINATOR,
ddesc, STRING_TERMINATOR
ddesc, STRING_TERMINATOR,
bdesc, STRING_TERMINATOR
);
fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n"

View file

@ -1803,6 +1803,41 @@ case CON_QCLASS:
}
}
if (!GET_BACKGROUND(d->character) || !*GET_BACKGROUND(d->character)) {
write_to_output(d,
"\r\nBefore stepping into Athas, share a bit of your character's background.\r\n"
"Guideline: aim for at least four lines that hint at where they came from,\r\n"
"who shaped them, and why they now walk the Tyr region. Touch on things like:\r\n"
" - The city-state, tribe, or caravan that claimed them.\r\n"
" - Mentors, slavers, or patrons who left a mark.\r\n"
" - A defining hardship, triumph, oath, or secret.\r\n"
" - The goal, vengeance, or hope that drives them back into the wastes.\r\n"
"\r\nExample 1:\r\n"
" Raised beneath the ziggurat of Tyr, I learned to barter gossip between\r\n"
" templars and gladiators just to stay alive. Freedom came when Kalak fell,\r\n"
" but the slave-scar on my shoulder still aches. I now search the desert\r\n"
" for the relic my clutch mates died protecting, hoping to buy their kin peace.\r\n"
"\r\nExample 2:\r\n"
" I rode caravan outrider routes from Balic until giants shattered our train.\r\n"
" Two nights buried in silt taught me to whisper with the wind and trust only\r\n"
" my erdlu. I hunt the warlord who sold us out, yet coin and company on the\r\n"
" road must come first.\r\n"
"\r\nExample 3:\r\n"
" Born outside Raam, I was tempered by obsidian shards and psionic murmurs.\r\n"
" A defiler ruined our oasis, so I swore to hound such spell-scars wherever\r\n"
" they bloom. Rumor of a hidden well near Tyr is the lone hope that guides me.\r\n"
"\r\nType your background now. Use '/s' on a blank line when you finish.\r\n"
"If you'd rather keep it secret, just save immediately and we'll note the mystery.\r\n\r\n");
d->backstr = NULL;
if (GET_BACKGROUND(d->character) && *GET_BACKGROUND(d->character))
d->backstr = strdup(GET_BACKGROUND(d->character));
d->str = &d->character->player.background;
d->max_str = PLR_DESC_LENGTH;
STATE(d) = CON_PLR_BACKGROUND;
send_editor_help(d);
return;
}
/* Proceed into the world */
load_result = enter_player_game(d);
send_to_char(d->character, "%s", CONFIG_WELC_MESSG);

View file

@ -191,6 +191,7 @@ static void medit_setup_new(struct descriptor_data *d)
GET_SDESC(mob) = strdup("the unfinished npc");
GET_LDESC(mob) = strdup("An unfinished npc stands here.\r\n");
GET_DDESC(mob) = strdup("It looks unfinished.\r\n");
GET_BACKGROUND(mob) = strdup("No background has been recorded.\r\n");
SCRIPT(mob) = NULL;
mob->proto_script = OLC_SCRIPT(d) = NULL;
@ -412,10 +413,12 @@ static void medit_disp_menu(struct descriptor_data *d)
{
struct char_data *mob;
char flags[MAX_STRING_LENGTH], flag2[MAX_STRING_LENGTH];
const char *background;
mob = OLC_MOB(d);
get_char_colors(d->character);
clear_screen(d);
background = GET_BACKGROUND(mob) ? GET_BACKGROUND(mob) : "<None>\r\n";
write_to_output(d,
"-- Mob Number: [%s%d%s]\r\n"
@ -442,11 +445,12 @@ static void medit_disp_menu(struct descriptor_data *d)
"%s8%s) Default : %s%s\r\n"
"%s9%s) Attack : %s%s\r\n"
"%s0%s) Stats Menu...\r\n"
"%s-%s) Skills Menu...\r\n"
"%s-%s) Skills Menu...\r\n"
"%sA%s) NPC Flags : %s%s\r\n"
"%sB%s) AFF Flags : %s%s\r\n"
"%sS%s) Script : %s%s\r\n"
"%sW%s) Copy mob\r\n"
"%sC%s) Background:-\r\n%s%s\r\n"
"%sS%s) Script : %s%s\r\n"
"%sW%s) Copy mob\r\n"
"%sX%s) Delete mob\r\n"
"%sQ%s) Quit\r\n"
"Enter choice : ",
@ -458,7 +462,8 @@ static void medit_disp_menu(struct descriptor_data *d)
grn, nrm,
grn, nrm, cyn, flags,
grn, nrm, cyn, flag2,
grn, nrm, cyn, OLC_SCRIPT(d) ?"Set.":"Not Set.",
grn, nrm, yel, background,
grn, nrm, cyn, OLC_SCRIPT(d) ?"Set.":"Not Set.",
grn, nrm,
grn, nrm,
grn, nrm
@ -686,6 +691,18 @@ void medit_parse(struct descriptor_data *d, char *arg)
OLC_MODE(d) = MEDIT_AFF_FLAGS;
medit_disp_aff_flags(d);
return;
case 'c':
case 'C':
OLC_MODE(d) = MEDIT_BACKGROUND;
send_editor_help(d);
write_to_output(d, "Enter mob background:\r\n\r\n");
if (OLC_MOB(d)->player.background) {
write_to_output(d, "%s", OLC_MOB(d)->player.background);
oldtext = strdup(OLC_MOB(d)->player.background);
}
string_write(d, &OLC_MOB(d)->player.background, MAX_MOB_DESC, 0, oldtext);
OLC_VAL(d) = 1;
return;
case 'w':
case 'W':
write_to_output(d, "Copy what mob? ");
@ -990,6 +1007,11 @@ void medit_parse(struct descriptor_data *d, char *arg)
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached D_DESC case!");
write_to_output(d, "Oops...\r\n");
break;
case MEDIT_BACKGROUND:
cleanup_olc(d, CLEANUP_ALL);
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached BACKGROUND case!");
write_to_output(d, "Oops...\r\n");
break;
case MEDIT_NPC_FLAGS:
if ((i = atoi(arg)) <= 0)
@ -1181,6 +1203,7 @@ void medit_string_cleanup(struct descriptor_data *d, int terminator)
switch (OLC_MODE(d)) {
case MEDIT_D_DESC:
case MEDIT_BACKGROUND:
default:
medit_disp_menu(d);
break;

View file

@ -32,6 +32,7 @@ static char *next_page(char *str, struct char_data *ch);
static int count_pages(char *str, struct char_data *ch);
static void playing_string_cleanup(struct descriptor_data *d, int action);
static void exdesc_string_cleanup(struct descriptor_data *d, int action);
static void background_string_cleanup(struct descriptor_data *d, int action);
/* Local (file scope) global variables */
/* @deprecated string_fields appears to be no longer be used.
@ -217,6 +218,7 @@ void string_add(struct descriptor_data *d, char *str)
{ CON_TEDIT , tedit_string_cleanup },
{ CON_TRIGEDIT, trigedit_string_cleanup },
{ CON_PLR_DESC , exdesc_string_cleanup },
{ CON_PLR_BACKGROUND , background_string_cleanup },
{ CON_PLAYING, playing_string_cleanup },
{ CON_HEDIT, hedit_string_cleanup },
{ CON_QEDIT , qedit_string_cleanup },
@ -302,6 +304,27 @@ static void exdesc_string_cleanup(struct descriptor_data *d, int action)
STATE(d) = CON_MENU;
}
static void background_string_cleanup(struct descriptor_data *d, int action)
{
if (d->character) {
if (!GET_BACKGROUND(d->character) || !*GET_BACKGROUND(d->character)) {
if (GET_BACKGROUND(d->character))
free(GET_BACKGROUND(d->character));
GET_BACKGROUND(d->character) = strdup("This character prefers to keep their past unspoken.\r\n");
if (action == STRINGADD_ABORT)
write_to_output(d, "Background entry canceled. We'll note that your past remains a mystery.\r\n");
else
write_to_output(d, "No background submitted. We'll note that your past remains a mystery.\r\n");
} else if (action == STRINGADD_ABORT)
write_to_output(d, "Background entry canceled.\r\n");
else
write_to_output(d, "Background saved.\r\n");
}
write_to_output(d, "%s", CONFIG_MENU);
STATE(d) = CON_MENU;
}
/* By Michael Buselli. Traverse down the string until the begining of the next
* page has been reached. Return NULL if this is the last page of the string. */
static char *next_page(char *str, struct char_data *ch)

View file

@ -258,38 +258,39 @@ extern const char *nrm, *grn, *cyn, *yel;
#define MEDIT_S_DESC 3
#define MEDIT_L_DESC 4
#define MEDIT_D_DESC 5
#define MEDIT_NPC_FLAGS 6
#define MEDIT_AFF_FLAGS 7
#define MEDIT_CONFIRM_SAVESTRING 8
#define MEDIT_STATS_MENU 9
#define MEDIT_SKILL_MENU 10
#define MEDIT_SKILL_EDIT 11
#define MEDIT_BACKGROUND 6
#define MEDIT_NPC_FLAGS 7
#define MEDIT_AFF_FLAGS 8
#define MEDIT_CONFIRM_SAVESTRING 9
#define MEDIT_STATS_MENU 10
#define MEDIT_SKILL_MENU 11
#define MEDIT_SKILL_EDIT 12
/* Numerical responses. */
#define MEDIT_NUMERICAL_RESPONSE 12
#define MEDIT_SEX 13
#define MEDIT_NUM_HP_DICE 14
#define MEDIT_SIZE_HP_DICE 15
#define MEDIT_ADD_HP 16
#define MEDIT_POS 17
#define MEDIT_DEFAULT_POS 18
#define MEDIT_ATTACK 19
#define MEDIT_LEVEL 20
#define MEDIT_ALIGNMENT 21
#define MEDIT_DELETE 22
#define MEDIT_COPY 23
#define MEDIT_STR 24
#define MEDIT_INT 25
#define MEDIT_WIS 26
#define MEDIT_DEX 27
#define MEDIT_CON 28
#define MEDIT_CHA 29
#define MEDIT_SAVE_STR 30
#define MEDIT_SAVE_DEX 31
#define MEDIT_SAVE_CON 32
#define MEDIT_SAVE_INT 33
#define MEDIT_SAVE_WIS 34
#define MEDIT_SAVE_CHA 35
#define MEDIT_NUMERICAL_RESPONSE 13
#define MEDIT_SEX 14
#define MEDIT_NUM_HP_DICE 15
#define MEDIT_SIZE_HP_DICE 16
#define MEDIT_ADD_HP 17
#define MEDIT_POS 18
#define MEDIT_DEFAULT_POS 19
#define MEDIT_ATTACK 20
#define MEDIT_LEVEL 21
#define MEDIT_ALIGNMENT 22
#define MEDIT_DELETE 23
#define MEDIT_COPY 24
#define MEDIT_STR 25
#define MEDIT_INT 26
#define MEDIT_WIS 27
#define MEDIT_DEX 28
#define MEDIT_CON 29
#define MEDIT_CHA 30
#define MEDIT_SAVE_STR 31
#define MEDIT_SAVE_DEX 32
#define MEDIT_SAVE_CON 33
#define MEDIT_SAVE_INT 34
#define MEDIT_SAVE_WIS 35
#define MEDIT_SAVE_CHA 36
/* Submodes of SEDIT connectedness. */
#define SEDIT_MAIN_MENU 0

View file

@ -334,7 +334,8 @@ int load_char(const char *name, struct char_data *ch)
break;
case 'B':
if (!strcmp(tag, "Badp")) GET_BAD_PWS(ch) = atoi(line);
if (!strcmp(tag, "Back")) ch->player.background = fread_string(fl, buf2);
else if (!strcmp(tag, "Badp")) GET_BAD_PWS(ch) = atoi(line);
else if (!strcmp(tag, "Bank")) GET_BANK_GOLD(ch) = atoi(line);
else if (!strcmp(tag, "Brth")) ch->player.time.birth = atol(line);
break;
@ -585,6 +586,11 @@ void save_char(struct char_data * ch)
strip_cr(buf);
fprintf(fl, "Desc:\n%s~\n", buf);
}
if (ch->player.background && *ch->player.background) {
strcpy(buf, ch->player.background);
strip_cr(buf);
fprintf(fl, "Back:\n%s~\n", buf);
}
if (POOFIN(ch)) fprintf(fl, "PfIn: %s\n", POOFIN(ch));
if (POOFOUT(ch)) fprintf(fl, "PfOt: %s\n", POOFOUT(ch));
if (GET_SEX(ch) != PFDEF_SEX) fprintf(fl, "Sex : %d\n", GET_SEX(ch));

View file

@ -338,6 +338,7 @@
#define CON_PREFEDIT 30 /**< OLC mode - preference edit */
#define CON_IBTEDIT 31 /**< OLC mode - idea/bug/typo edit */
#define CON_MSGEDIT 32 /**< OLC mode - message editor */
#define CON_PLR_BACKGROUND 33 /**< Entering a new character background */
#define CON_GET_PROTOCOL 33 /**< Used at log-in while attempting to get protocols > */
/* OLC States range - used by IS_IN_OLC and IS_PLAYING */
@ -880,6 +881,7 @@ struct char_player_data
char *short_descr; /**< PC / NPC short description */
char *long_descr; /**< PC / NPC long description */
char *description; /**< PC / NPC main descriptions */
char *background; /**< PC / NPC background / history text */
byte sex; /**< PC / NPC sex */
byte chclass; /**< PC / NPC class */
byte level; /**< PC / NPC level */

View file

@ -517,6 +517,9 @@ do \
/** Appearance-based description for displays (e.g. short look text). */
#define GET_SHORT_DESC(ch) ((ch)->player.short_descr)
/** Character background / history text. */
#define GET_BACKGROUND(ch) ((ch)->player.background)
/** Safe name for room messages. */
#define GET_DISPLAY_NAME(ch) (GET_NAME(ch) && *GET_NAME(ch) ? GET_NAME(ch) : "someone")