[CODE][LONG]OasisOLC-Mobprogs v0.8

From: Nicholas S. Wourms (prospero@carol.net)
Date: 02/08/97


In all fairness, I felt it was time to realease the fixes for online
mobrogs.  Note that this is preliminary and I plan to release a completely
annotated and fully tested version this weekend.  I have recieved numerous
requests, so I am throwing it to the dogs, so to speak.  Be aware that this
may not be fully functional as I have not tested the snippet on a stock
mud.  If you do use this, neither I, nor the original author require
credit.  However, do not take credit for it yourself.  If you do give
credit, please do so for both of the following:
Desmond Daignault
Nicholas Wourms
If you are patient enough, a fully tested version(v0.9) should be out on
Saturday.  If you are brave enough to use it before then, please mail me
you results.  Also, any bugfixes/improvements would be greatly apprciated
and desired.  Finally, I know that this needs some major cleaning up and
stremlining, so if someone feels like doing that, be my guest.  As for me,
it works, and I will admit I was a little lazy.  I will try my best to
suppoert it, but I am not responsible if it trashes you mud.  

****README NOW****
Ok, here is the revised (and hopefuly working) snippet for adding Mobprogs
to OasisOLC.  You should be able to put this in fairly easy.  A few things
you must realize.  The more you have hacked up your code, the more likely
that you will run into problems, especially if you have greatly modified
OasisOLC.  IF YOU SEE A '#define BLAHHHH  nn' make sure the number you put
in for 'nn' is consecutive with the last number in the list of defines
before you edited it.  So I warn you now, Backup YOUR ENTIRE '/src'
directory AS WELL
AS YOUR ENTIRE '/lib/world/' directory.  Backup the latter often, for in
earlier versions of this snippet had a bug where it would 'eat' mobfiles.
Also you will need to know the following:

A)This code REQUIRES:
--Circle30bpl11
--OasisOLC
--Improved Editor
  **I know this code could be made to use the stock editor, but it
seriously makes life difficult.         You will see why when you see the
screen. 
--Mobprogs for Circle30bpl11

B)Bugs
***InFile Problem***
For some reason, I had trouble menuing the IN_FILE_PROG mobrprog trigger.
You will see what I mean when you install this.  What it does is it gets
displayed in the menu, but when you select its number, it writes the next
prog in the list instead.  On top of this, I am not sure, once the menuing
works, where it will look for the text file(what goes in the argument
section).  Read the doc from the ftp site for more info.  This would be
nice, because it provides an object oriented approach.

C)Future Fixes(for v1.x):
--Make the process completely menu oriented, eliminating most errors.
--Have the ability to make a mobprog file to use with IN_FILE_PROG
--Add Menu oriented help commands


NOTE:
::blah blah is the leading code before where you be editing
>>>>>>>>>>>>>Revise medit.c
----------------------------------------------------------------------------
-----------------------
>>Around line 35
::extern char *position_types[];                          /*. constants.c .*/
::extern char *genders[];                                 /*. constants.c .*/
extern char *mobprog_types[];                           /*. constants.c .*/

>>Around line 51
::#define GET_ATTACK(mob) ((mob)->mob_specials.attack_type)
::#define S_KEEPER(shop) ((shop)->keeper)
#define GET_MPROG(mob) (mob_index[(mob)->nr].mobprogs)
#define GET_MPROG_TYPE(mob) (mob_index[(mob)->nr].progtypes)

>>Around line 69
::void medit_disp_aff_flags(struct descriptor_data *d);
::void medit_disp_attack_types(struct descriptor_data *d);
void medit_disp_mprog(struct descriptor_data *d);
void medit_change_mprog(struct descriptor_data *d);
char* medit_get_mprog_type(struct mob_prog_data *mprog);

/*
NOTE:THE REST OF THE medit.c modifications is NOT drop-in code!!!!
     Ok, after this, my line nubers become off by 30 or so and you will
need to figure out how to 	modify the below through comparison with your code.

*/
>>Around line 75
/*-------------------------------------------------------------------*\
  utility functions
\*-------------------------------------------------------------------*/

void medit_setup_new(struct descriptor_data *d)
{ struct char_data *mob;

  /*. Alloc some mob shaped space .*/
  CREATE(mob, struct char_data, 1);


  init_mobile(mob);

  mob->player_specials = &dummy_mob;

  GET_MOB_RNUM(mob) = -1;
  /*. default strings .*/
  GET_ALIAS(mob) = strdup("mob unfinished");
  GET_SDESC(mob) = strdup("the unfinished mob");
  GET_LDESC(mob) = strdup("An unfinished mob stands here.\r\n");
  GET_DDESC(mob) = strdup("It looks, err, unfinished.\r\n");
  OLC_MPROGL(d)= NULL;                   
  OLC_MPROG(d)= NULL;
  GET_STR(mob) = 50;
  GET_DEX(mob) = 50;
  GET_AGI(mob) = 50;
  GET_INT(mob) = 50;
  GET_WIS(mob) = 50;
  GET_CON(mob) = 50;
  OLC_MOB(d) = mob;
  OLC_VAL(d) = 0;   /*. Has changed flag .*/
  medit_disp_menu(d);
}

/*-------------------------------------------------------------------*/

void medit_setup_existing(struct descriptor_data *d, int rmob_num)
{ struct char_data *mob;
  MPROG_DATA *temp;
  MPROG_DATA *head;

  /*. Alloc some mob shaped space .*/
  CREATE(mob, struct char_data, 1);
  copy_mobile(mob, mob_proto + rmob_num);
  if (GET_MPROG(mob))
      CREATE(OLC_MPROGL(d), MPROG_DATA, 1);
      head = OLC_MPROGL(d);
    for (temp = GET_MPROG(mob); temp;temp = temp->next) {
      OLC_MPROGL(d)->type = temp->type;
      OLC_MPROGL(d)->arglist = str_dup(temp->arglist);
      OLC_MPROGL(d)->comlist = str_dup(temp->comlist);
      if (temp->next) {
        CREATE(OLC_MPROGL(d)->next, MPROG_DATA, 1);
	OLC_MPROGL(d) = OLC_MPROGL(d)->next;
      }
    }
  OLC_MPROGL(d) = head;
  OLC_MPROG(d) = OLC_MPROGL(d);
  OLC_MOB(d) = mob;
  medit_disp_menu(d);
}

/*-------------------------------------------------------------------*/
/*. Save new/edited mob to memory .*/

#define ZCMD zone_table[zone].cmd[cmd_no]

void medit_save_internally(struct descriptor_data *d)
{
 .
 .
 .
       if(S_KEEPER(OLC_SHOP(dsc)) >= new_mob_num)
          S_KEEPER(OLC_SHOP(dsc))++;
  }
 GET_MPROG(OLC_MOB(d)) = OLC_MPROGL(d);
    if (OLC_MPROGL(d))
      GET_MPROG_TYPE(OLC_MOB(d)) = OLC_MPROGL(d)->type;
    else
      GET_MPROG_TYPE(OLC_MOB(d)) = 0;
    OLC_MPROGL(d) = NULL;
medit_save_to_disk(d);   
olc_add_to_save_list(zone_table[OLC_ZNUM(d)].number, OLC_SAVE_MOB);
}


/*-------------------------------------------------------------------*/
/*. Save ALL mobiles for a zone to their .mob file, mobs are all
    saved in Extended format, regardless of whether they have any
    extended fields.  Thanks to Samedi for ideas on this bit of code.*/

void medit_save_to_disk(struct descriptor_data *d)
{
  int i, rmob_num, zone, top;
  FILE *mob_file;
  MPROG_DATA *mob_prog;
  char fname[64];
  struct char_data *mob;
   
  zone = zone_table[OLC_ZNUM(d)].number;
  top = zone_table[OLC_ZNUM(d)].top;      
  mob_prog = mob_index[rmob_num].mobprogs;

  sprintf(fname, "%s/%i.mob", MOB_PREFIX, zone);
  
  if(!(mob_file = fopen(fname, "w")))
  { mudlog("SYSERR: OLC: Cannot open mob file!", BRF, LVL_BUILDER, TRUE);
    return;
  }
    
  /*. Seach database for mobs in this zone and save em .*/
  for(i = zone * 100; i <= top; i++)
  { rmob_num = real_mobile(i);

    if(rmob_num != -1)
    { if(fprintf(mob_file, "#%d\n", i) < 0)
      { mudlog("SYSERR: OLC: Cannot write mob file!\r\n", BRF, LVL_BUILDER,
TRUE);
        fclose(mob_file);
        return;
      }
      mob = (mob_proto + rmob_num);
      mob_prog = mob_index[rmob_num].mobprogs;


/* ADD THIS to the end of medit_save_to_disk */

      /*. Deal with Mob Progs .*/
      while(mob_prog) {
        strcpy(buf1, mob_prog->arglist);
        strip_string(buf1);
        strcpy(buf2, mob_prog->comlist);
        strip_string(buf2);
        fprintf(mob_file, "%s %s~\n%s", medit_get_mprog_type(mob_prog),
buf1, buf2);
        mob_prog=mob_prog->next;
        if (!mob_prog)
          fprintf(mob_file, "~\n|\n");
        else
          fprintf(mob_file, "~\n");
      }
    }
  }
}


/*-------------------------------------------------------------------*/
/*. Get Mob Prog Type.*/

char* medit_get_mprog_type(struct mob_prog_data *mprog) {

    switch (mprog->type) {
//      case IN_FILE_PROG:
//           return ">in_file_prog";
//           break;
      case ACT_PROG:
           return ">act_prog";
           break;
      case SPEECH_PROG:
           return ">speech_prog";
           break;
      case RAND_PROG:
           return ">rand_prog";
           break;
      case FIGHT_PROG:
           return ">fight_prog";
           break;
      case HITPRCNT_PROG:
           return ">hitprcnt_prog";
           break;
      case DEATH_PROG:
           return ">death_prog";
           break;
      case ENTRY_PROG:
           return ">entry_prog";
           break;
      case GREET_PROG:
           return ">greet_prog";
           break;
      case ALL_GREET_PROG:
           return ">all_greet_prog";
           break;
      case GIVE_PROG:
           return ">give_prog";
           break;
      case BRIBE_PROG:
           return ">bribe_prog";
           break;
   }
   return ">UNKNOWN";
}

/*-------------------------------------------------------------------*/
/*. Display Mob Progs .*/

void medit_disp_mprog(struct descriptor_data *d) {
  struct mob_prog_data *mprog = OLC_MPROGL(d);

  d->edit_number2 = 1;
  send_to_char("", d->character);
  while (mprog) {
    sprintf (buf, "%d) %s %s\r\n",
             d->edit_number2,
             medit_get_mprog_type(mprog), (mprog->arglist ? mprog->arglist
: "NONE"));
    send_to_char(buf, d->character);
    d->edit_number2++;
    mprog=mprog->next;
  }
  sprintf (buf, "%d) Create New Mob Prog\r\n", d->edit_number2);
  send_to_char(buf, d->character);
  sprintf (buf, "%d) Purge Mob Prog\r\n", d->edit_number2 + 1);
  send_to_char(buf, d->character);

  send_to_char("Enter number to edit [0 to exit]:  ", d->character);
  OLC_MODE(d) = MEDIT_MPROG;
}

/*-------------------------------------------------------------------*/
/*. Change Mob Progs .*/

void medit_change_mprog(struct descriptor_data *d) {

  send_to_char("", d->character);
  sprintf(buf, "1) Type: %s\r\n", medit_get_mprog_type(OLC_MPROG(d)));
  send_to_char(buf, d->character);
  sprintf(buf, "2) Args: %s\r\n", (OLC_MPROG(d)->arglist ?
OLC_MPROG(d)->arglist : "NONE"));
  send_to_char(buf, d->character);
  sprintf(buf, "3) Commands:\r\n%s\r\n\r\n", (OLC_MPROG(d)->comlist ?
OLC_MPROG(d)->comlist : "NONE"));
  send_to_char(buf, d->character);
  send_to_char("Enter number to edit [0 to exit]: ", d->character);
  OLC_MODE(d) = MEDIT_CHANGE_MPROG;
}

/*-------------------------------------------------------------------*/
/*. Change Mob Prog Type.*/
void medit_disp_mprog_types(struct descriptor_data *d)
{ int i;

  get_char_cols(d->character);
  send_to_char("", d->character);
  for (i = 0; i < NUM_PROGS-1; i++)
  {  sprintf(buf, "%s%2d%s) %s\r\n",
	grn, i, nrm, mobprog_types[i]
     );
     send_to_char(buf, d->character);
  }
  send_to_char("Enter mob prog type : ", d->character);
  OLC_MODE(d) = MEDIT_MPROG_TYPE;
}

/*-------------------------------------------------------------------*/
/*. Display main menu .*/

void medit_disp_menu(struct descriptor_data * d)
{ struct char_data *mob;

  mob = OLC_MOB(d);
  get_char_cols(d->character);

/*** Add a menu option for mob progs... */
        "%sP%s) Mob Progs   : %s%s\r\n"

  OLC_MODE(d) = MEDIT_MAIN_MENU;
}

/**************************************************************************
  The GARGANTAUN event handler
 **************************************************************************/

void medit_parse(struct descriptor_data * d, char *arg)
{ int i;

      case 'p':
      case 'P':
        OLC_MODE(d) = MEDIT_MPROG;
        medit_disp_mprog(d);
        return;

/*-------------------------------------------------------------------*/
  case MEDIT_MPROG_COMLIST:
    /*. We should never get here .*/
    cleanup_olc(d, CLEANUP_ALL);
    mudlog("SYSERR: OLC: medit_parse(): Reached MPROG_COMLIST
case!",'G',LVL_GRGOD,TRUE);
    break;
/*-------------------------------------------------------------------*/
  case MEDIT_MPROG: {
    i=atoi(arg);

    if (i == 0)
      medit_disp_menu(d);
    else if (i == d->edit_number2) {
      struct mob_prog_data *temp;
      CREATE(temp, struct mob_prog_data, 1);
      temp->next = OLC_MPROGL(d);
      temp->type = -1;
      temp->arglist = NULL;
      temp->comlist = NULL;
      OLC_MPROG(d) = temp;
      OLC_MPROGL(d) = temp;
      OLC_MODE(d) = MEDIT_CHANGE_MPROG;
      medit_change_mprog (d);
    } else if (i < d->edit_number2) {
      struct mob_prog_data *temp;
      int x=1;
      for (temp = OLC_MPROGL(d);temp && x < i;temp=temp->next)
        x++;
      OLC_MPROG(d) = temp;
      OLC_MODE(d) = MEDIT_CHANGE_MPROG;
      medit_change_mprog (d);
    } else if (i == d->edit_number2+1) {
      send_to_char ("Which mob prog do you want to purge? ", d->character);
      OLC_MODE(d) = MEDIT_PURGE_MPROG;
    } else
      medit_disp_menu(d);
  }
  return;
  case MEDIT_PURGE_MPROG: {
    struct mob_prog_data *temp;
    int x=1;

    i=atoi(arg);
    if (i <= 0 || i >= d->edit_number2) {
      medit_disp_mprog (d);
      return;
    }
    for (temp = OLC_MPROGL(d);temp && x < i;temp=temp->next)
      x++;
    OLC_MPROG(d) = temp;
    REMOVE_FROM_LIST(OLC_MPROG(d), OLC_MPROGL(d), next)
    free(OLC_MPROG(d)->arglist);
    free(OLC_MPROG(d)->comlist);
    free(OLC_MPROG(d));
    OLC_MPROG(d) = NULL;
    OLC_VAL(d) = 1;
    medit_disp_mprog (d);
  }
  return;
  case MEDIT_CHANGE_MPROG: {
    i=atoi(arg);
    if (i == 1)
      medit_disp_mprog_types(d);
    else if (i == 2) {
      send_to_char ("Enter new arg list: ", d->character);
      OLC_MODE(d) = MEDIT_MPROG_ARGS;
    } else if (i == 3) {
      send_to_char("Enter new mob prog commands:\r\n", d->character);
      /*. Pass control to modify.c .*/
      OLC_MODE(d) = MEDIT_MPROG_COMLIST;
      d->backstr = NULL;
      if (OLC_MPROG(d)->comlist) {
        SEND_TO_Q(OLC_MPROG(d)->comlist, d);
        d->backstr = str_dup(OLC_MPROG(d)->comlist);
      }
      d->str = &OLC_MPROG(d)->comlist;
      d->max_str = MAX_STRING_LENGTH;
      d->mail_to = 0;
      OLC_VAL(d) = 1;
    } else
      medit_disp_mprog(d);
  }
  return;

  case MEDIT_MPROG_TYPE:
    OLC_MPROG(d)->type = (1 << MAX(0, MIN(atoi(arg), NUM_PROGS-1)));
    OLC_VAL(d) = 1;
    medit_change_mprog(d);
    return;
  case MEDIT_MPROG_ARGS:
    OLC_MPROG(d)->arglist = str_dup(arg);
    OLC_VAL(d) = 1;
    medit_change_mprog(d);
    return;
}
/*. End of medit_parse() .*/

>>>>>>>>>>>>>Revise olc.h
----------------------------------------------------------------------------
-----------------------
>>Around line 8
::#define NUM_AFF_FLAGS           22
::#define NUM_ATTACK_TYPES        15
#define NUM_PROGS               12 
/*NOTE:This may be differnent if you put in mor progs!!*/

>>Around line 54
::struct shop_data *shop;
::struct extra_descr_data *desc;
  struct mob_prog_data *mprogl;
  struct mob_prog_data *mprog;

>>Around line 86
::#define OLC_SHOP(d)     ((d)->olc->shop)        /*. Shop structure      .*/
::#define OLC_DESC(d)     ((d)->olc->desc)        /*. Extra description   .*/
#define OLC_MPROGL(d)   ((d)->olc->mprogl)
#define OLC_MPROG(d)    ((d)->olc->mprog)

>>Around line 196
::#define MEDIT_LEVEL                     25
::#define MEDIT_ALIGNMENT                 26
#define MEDIT_MPROG                     27
#define MEDIT_CHANGE_MPROG              28
#define MEDIT_MPROG_TYPE                29
#define MEDIT_MPROG_COMLIST             30
#define MEDIT_PURGE_MPROG               31
#define MEDIT_MPROG_ARGS                32

>>>>>>>>>>>>>Revise constants.c
----------------------------------------------------------------------------
-----------------------
>>Around line 882
::};                             /* Pierce   */
::
const char *mobprog_types[] = {
//  "IN_FILE",
  "ACT",
  "SPEECH",
  "RAND",
  "FIGHT",
  "DEATH",
  "HITPRCNT",
  "ENTRY",
  "GREET",
  "ALL_GREET",
  "GIVE",
  "BRIBE",
  "\n"
};

>>>>>>>>>>>>>Revise structs.h
----------------------------------------------------------------------------
-----------------------
>>Around line 1045
::   struct olc_data *olc;             /*. OLC info - defined in olc.h   .*/
::   char *storage;
   int edit_number2;            /* Online Mobprogs*/


>>>>>>>>>>>>>>>END OF CODE!!!

Ok, this is all I could find.  I feel that I missed some stuff, so report
to me on all and any findings and fixes, if necessary.  If you can clean
this up a bit, please do.  I hope this is all you need.  Good luck and
enjoy!!!!!


+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
+-----------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/18/00 PST