/* -------------------------------------------------------------------------------- This snippet will enable your mobiles to keep track of an instanced dialogue for each character. It's similar to mpstatus, but, again, instanced to each player character. As with any other snippet, I urge you to read it carefully and make sure you know how it works before installing it. -------------------------------------------------------------------------------- mob_prog.c ---------- Add this with your other defines. #define CHK_DIALOGUE (52) Modify the numerical value to suit your needs. Now, in the list of if-check keywords: "dialogue", //if dialogue $n == 2 - dialogue stage check Add this to the bottom of the last cmd_eval switch: (mine is right below the CHK_GRPSIZE case) case CHK_DIALOGUE: if (lval_char != NULL) { sh_int dlg; one_argument (line, buf); if (!is_number (buf)) dlg = 0; else dlg = atoi (buf); if (dlg < 0 || dlg > 24) return dlg = 0; lval = check_stage_char (mob, lval_char, dlg); } break; mob_cmds.c/h ------------ Add a table entry for the mpdialogue command and a DECLARE_DO_FUN() for it. merc.h ------ Add this with your other typedefs: typedef struct dialogue DIALOGUE; Add this structure anywhere: struct dialogue { DIALOGUE * next; bool valid; CHAR_DATA * victim; sh_int stage[25]; }; Add the following to struct char_data: DIALOGUE * dialogues; Finally, add the following prototypes: // dialogue.c int check_stage_char (CHAR_DATA * ch, CHAR_DATA * vch, int dlg); DIALOGUE * get_dialogue (CHAR_DATA * ch, CHAR_DATA * vch); DIALOGUE * new_dialogue (void); void free_dialogue (DIALOGUE * dialogue); -------------------------------------------------------------------------------- Now, add dialogue.c to your source directory and recompile. -------------------------------------------------------------------------------- This code is provided as-is without any warranty. It should work fine, but I'm not responsible if something goes wrong (as things always do with mprogs). Any credit or feedback is much appreciated, but not required. Enjoy! -- Midboss (eclipsing.souls@gmail.com) -------------------------------------------------------------------------------- Here is a sample program, using mpdialogue: if dialogue $n == 0 say Ok, we shall begin... mob dialogue $n 1 break endif if dialogue $n == 1 say This is the first stage.. mob dialogue $n 2 break endif if dialogue $n == 2 say This is the second stage.. mob dialogue $n 3 break endif if dialogue $n == 3 say This is the final stage.. mob dialogue $n clear break endif */ /*************************************************************************** * This code may be used freely within any non-commercial MUD, all I ask * * is that these comments remain in tact and that you give me any feedback * * or bug reports you come up with. Credit in a helpfile might be nice, * * too. -- Midboss (eclipsing.souls@gmail.com) * ***************************************************************************/ #include <sys/types.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include "merc.h" /* * Sets the 'stage' of an mobile's prog. Useful for quests and extended * dialogues via a 'talk' command. * * Syntax: mob dialogue <victim> <new stage|clear> [which] */ void do_mpdialogue (CHAR_DATA * ch, char *argument) { char arg[MIL], arg2[MIL]; CHAR_DATA *victim; DIALOGUE *dialogue; sh_int iDlg; argument = one_argument (argument, arg); argument = one_argument (argument, arg2); //If your MUD has o/rprogs installed, remove the NULL arg. if ((victim = get_char_room (ch, NULL, arg)) == NULL) return; if (argument[0] != '\0' && is_number (argument)) iDlg = atoi (argument); else iDlg = 0; if (iDlg < 0 || iDlg > 24) { bug ("MpDialogue: Bad dialogue from vnum %d.", IS_NPC (ch) ? ch->pIndexData->vnum : 0); return; } //Make sure there's an argument. if (arg2[0] == '\0') { bug ("MpDialogue: No argument from vnum %d.", IS_NPC (ch) ? ch->pIndexData->vnum : 0); return; } //mob dialogue [victim] clear if (!str_cmp (arg2, "clear")) { //No dialogue found. if ((dialogue = get_dialogue (ch, victim)) == NULL) { bug ("MpDialogue: No dialogue to clear from vnum %d.", IS_NPC (ch) ? ch->pIndexData->vnum : 0); return; } //Remove it. if (dialogue == ch->dialogues) ch->dialogues = dialogue->next; else { DIALOGUE *prev; for (prev = ch->dialogues; prev != NULL; prev = prev->next) if (prev->next == dialogue) { prev->next = dialogue->next; break; } } //Free the struct. free_dialogue (dialogue); return; } //mob dialogue [victim] ## else if (is_number (arg2)) { int stage = atoi (arg2); //Dialogue exists. if ((dialogue = get_dialogue (ch, victim)) != NULL) dialogue->stage[iDlg] = stage; //Create new dialogue. else { dialogue = new_dialogue (); dialogue->victim = victim; dialogue->stage[iDlg] = stage; dialogue->next = ch->dialogues; ch->dialogues = dialogue; } return; } else { bug ("MpDialogue: Bad argument from vnum %d.", IS_NPC (ch) ? ch->pIndexData->vnum : 0); return; } return; } /* * Checks a character's dialogue stage. */ int check_stage_char (CHAR_DATA * ch, CHAR_DATA * vch, int dlg) { DIALOGUE * dialogue; if ((dialogue = get_dialogue (ch, vch)) != NULL) return dialogue->stage[dlg]; return 0; } /* * Grabs player vch's dialogue from mobile ch's list. */ DIALOGUE *get_dialogue (CHAR_DATA * ch, CHAR_DATA * vch) { DIALOGUE * dialogue; for (dialogue = ch->dialogues; dialogue != NULL; dialogue = dialogue->next) if (dialogue->victim == vch) return dialogue; return NULL; } /* recycling stuff for mpdialogue */ DIALOGUE *dialogue_free; DIALOGUE *new_dialogue (void) { static DIALOGUE dialogue_zero; DIALOGUE *dialogue; if (dialogue_free == NULL) dialogue = alloc_perm (sizeof (*dialogue)); else { dialogue = dialogue_free; dialogue_free = dialogue_free->next; } *dialogue = dialogue_zero; VALIDATE (dialogue); dialogue->victim = NULL; bzero (dialogue->stage, sizeof(dialogue->stage)); return dialogue; } void free_dialogue (DIALOGUE * dialogue) { if (!IS_VALID (dialogue)) return; INVALIDATE (dialogue); dialogue->next = dialogue_free; dialogue_free = dialogue; }