(Fwd) soc-olc

From: Cyber Reaper (Pcyber@greatbasin.com)
Date: 10/23/96


------- Forwarded Message Follows -------
Date:          Thu, 24 Oct 1996 03:05:55 -0700 (PDT)
From:          Terry Valladon <cyber@greatbasin.com>
To:            Reaper@cyber.reno.nv.us
Subject:       soc-olc

ok... I looked through my files and found a on-line social editor... 
if someone wants to make one and use this for ideas... but I am look 
ing for one that dont require a total overhaul of the code.... and 
has a good menu.... =:) PEACE


>X-Nvlenv-01Date-Posted:  3-Jul-1996 14:12:36 -0400; at
> cougar.colstate.cc.oh.us
>From: DCARVER@cougar.colstate.cc.oh.us (David A. Carver)
>To: circle@pvv.ntnu.no
>Subject: CODE: social editor
>Date: 03 Jul 96 14:12:29 EDT
>Sender: owner-circle@pvv.ntnu.no
>
>Luckily, I became a pack rat lately.  Haven't had a chance to add this 
>code to my mud yet, but here is the social editor code somebody asked for.
>
>Dave
>
>
>
>----- Forwarded Message follows -------
>Date sent:      11-May-1996 23:59:10 -0700
>Send reply to:  scottm@dns.workcomm.net (Michael Scott)
>To:             circle@pvv.unit.no (Circle Mailinglist)
>Subject:        WARNING! NO NEWBIE CODERS: Adding AEDIT (social editor)
>From:           owner-circle@pvv.unit.no
>
>    My last project was adding an online social editor to SaberMUD 
>(mine) .. and it was a little more difficult than i imagined .. so for 
>all those who are contemplating adding a social editor to their mud, I 
>am going to sort of outline what it took .. that way you know what yer 
>getting into :>
>
>    First of all the command_info structure which is used in a 
>variable named cmd_info in interpreter.c is a HARD CODED variable.. to 
>have an editor which can dynamically add socials on line, you need to 
>create another pointer to a command_info structure which you allocate 
>enough space for at boot time (after figuring out how many socials you 
>have in the social file and how many ACTUAL commands you have in cmd_info)..
>I used 'used_cmd_info' for this variable which was put in the place of 
>cmd_info throughout the mud where a command like decision was based.: 
>struct command_info *used_cmd_info;
>
>    Then I had to add to the social file some more info ... (the 
>command stuff which was going to get taken out of interpreter.c) like 
>min position the char had to be in .. the minimum level for the 
>command/social.. etc.. i decided on a firstline social format of this:
>~accuse accuse 0 6 5 0
>^ the actual command name
>         ^ the name I want to be used to decide WHERE to sort this 
>command into the command listing.. (explained more later)
>               ^ this number is the 'hide' flag (already in old file)
>                 ^ this is the minimum position the character has to be 
>in to do the social.
>                   ^ this is the minimum position the victim has to be 
>in to do the social. (already in old file)
>                     ^ this is the min. level that the character has to 
>be to do the social.
>
>
>    Then after working my way through the socials file.. i had to go 
>into act.social.c and add all these extra fields to what the 
>social_messg can handle.. and i also MOVED it from act.social.c to 
>structs.h because more than just the socials handler file would need 
>it (aedit.c in particular) here's what my structure ended up looking 
>like (at the end of structs.h):
>
>/* used in the socials */
>struct social_messg {
>   int act_nr;
>   char *command;               /* holds copy of activating command */
>   char *sort_as;       /* holds a copy of a similar command or
>                 * abbreviation to sort by for the parser */
>   int hide;            /* ? */
>   int min_victim_position; /* Position of victim */
>   int min_char_position;   /* Position of char */
>   int min_level_char;          /* Minimum level of socialing char */
>
>   /* No argument was supplied */
>   char *char_no_arg;
>   char *others_no_arg;
>
>   /* An argument was there, and a victim was found */
>   char *char_found;
>   char *others_found;
>   char *vict_found;
>
>   /* An argument was there, but no victim was found */
>   char *not_found;
>
>   /* The victim turned out to be the character */
>   char *char_auto;
>   char *others_auto;
>};
>
>    Of course you need to go into act.social.c and adjust how the 
>boot_social_messages() routine loads the data from the file.. (include 
>the new info).
>    Then I took the sort out of that routine and placed it into a 
>new routine after it .. which i named 'create_command_list()' and they 
>ended up looking like this:
>
>void boot_social_messages(void) {
>   FILE *fl;
>   int nr = 0, hide, min_char_pos, min_pos, min_lvl, curr_soc = -1;
>   char next_soc[MAX_STRING_LENGTH], sorted[MAX_INPUT_LENGTH];
>
>   /* open social file */
>   if (!(fl = fopen(SOCMESS_FILE, "r"))) {
>      sprintf(buf, "Can't open socials file '%s'", SOCMESS_FILE);
>      perror(buf);
>      exit(1);
>   }
>
>   /* count socials & allocate space */
>   *next_soc = NULL;
>   while (!feof(fl)) {
>      fgets(next_soc, MAX_STRING_LENGTH, fl);
>      if (*next_soc == '~') top_of_socialt++;
>   }
>   sprintf(buf, "Social table contains %d socials.", top_of_socialt);
>   log(buf);
>   rewind(fl);
>   
>   CREATE(soc_mess_list, struct social_messg, top_of_socialt + 1);
>
>   /* now read 'em */
>   for (;;) {
>      fscanf(fl, " %s ", next_soc);
>      if (*next_soc == '$') break;
>      if (fscanf(fl, " %s %d %d %d %d \n",
>         sorted, &hide, &min_char_pos, &min_pos, &min_lvl) != 5) {
>     fprintf(stderr, "Format error in social file near social '%s'\n",
>         next_soc);
>     exit(1);
>      }
>      /* read the stuff */
>      curr_soc++;
>      soc_mess_list[curr_soc].command = str_dup(next_soc+1);
>      soc_mess_list[curr_soc].sort_as = str_dup(sorted);
>      soc_mess_list[curr_soc].hide = hide;
>      soc_mess_list[curr_soc].min_char_position = min_char_pos;
>      soc_mess_list[curr_soc].min_victim_position = min_pos;
>      soc_mess_list[curr_soc].min_level_char = min_lvl;
>
>      soc_mess_list[curr_soc].char_no_arg = fread_action(fl, nr);
>      soc_mess_list[curr_soc].others_no_arg = fread_action(fl, nr);
>      soc_mess_list[curr_soc].char_found = fread_action(fl, nr);
>      soc_mess_list[curr_soc].others_found = fread_action(fl, nr);
>      soc_mess_list[curr_soc].vict_found = fread_action(fl, nr);
>      soc_mess_list[curr_soc].not_found = fread_action(fl, nr);
>      soc_mess_list[curr_soc].char_auto = fread_action(fl, nr);
>      soc_mess_list[curr_soc].others_auto = fread_action(fl, nr);
>   }
>
>   /* close file & set top */
>   fclose(fl);
>   top_of_socialt = curr_soc;
>}
>
>
>/* this function adds in the loaded socials and assigns them a command # */
>void create_command_list(void)  {
>   int i, j, k;
>   struct social_messg temp;
>   extern struct command_info *used_cmd_info;
>   extern struct command_info cmd_info[];
>
>   /* free up old command list */
>   if (used_cmd_info) free(used_cmd_info);
>   used_cmd_info = NULL;
>
>   /* re check the sort on the socials */
>   for (j = 0; j < top_of_socialt; j++) {
>      k = j;
>      for (i = j + 1; i <= top_of_socialt; i++)
>        if (str_cmp(soc_mess_list[i].sort_as, soc_mess_list[k].sort_as) < 0)
>        k = i;
>      if (j != k) {
>     temp = soc_mess_list[j];
>     soc_mess_list[j] = soc_mess_list[k];
>     soc_mess_list[k] = temp;
>      }
>   }
>
>   /* count the commands in the command list */
>   i = 0;
>   while(*cmd_info[i].command != '\n') i++;
>   i++;
>
>   CREATE(used_cmd_info, struct command_info, top_of_socialt + i + 2);
>
>   /* this loop sorts the socials and commands together into one big list */
>   i = 0;
>   j = 0;
>   k = 0;
>   while ((*cmd_info[i].command != '\n') || (j <= top_of_socialt))  {
>      if ((i < NUM_RESERVED_CMDS) ||
>      (j > top_of_socialt) ||
>      (str_cmp(cmd_info[i].sort_as, soc_mess_list[j].sort_as) < 1))
>        used_cmd_info[k++] = cmd_info[i++];
>      else  {
>     soc_mess_list[j].act_nr        = k;
>     used_cmd_info[k].command       = soc_mess_list[j].command;
>     used_cmd_info[k].sort_as       = soc_mess_list[j].sort_as;
>     used_cmd_info[k].minimum_position  = soc_mess_list[j].min_char_position;
>     used_cmd_info[k].command_pointer   = do_action;
>     used_cmd_info[k].minimum_level     = soc_mess_list[j++].min_level_char;
>     used_cmd_info[k].subcmd        = 0;
>     used_cmd_info[k++].show            = 1;
>      }
>   }
>   used_cmd_info[k].command     = str_dup("\n");
>   used_cmd_info[k].sort_as     = str_dup("zzzzzzz");
>   used_cmd_info[k].minimum_position    = 0;
>   used_cmd_info[k].command_pointer = 0;
>   used_cmd_info[k].minimum_level   = 0;
>   used_cmd_info[k].subcmd      = 0;
>   used_cmd_info[k].show            = 0;
>   sprintf(buf, "Command info rebuilt, %d total commands.", k);
>   log(buf);
>}
>
>
>    Then.. in db.c i added a prototype at the top:
>void create_command_list(void);
>
>    Then where it boots all the info up i added a line:
>   log("Loading social messages.");
>   boot_social_messages();
>   create_command_list();    /* newline */
>
>
>    This effectively read all the info from the socials file, then 
>sorted it with what was already in the cmd_info variable (in 
>interpreter.c) and ended up in used_cmd_info..
>    So this means you have to go back through interpreter.c and 
>REMOVE any line with the do_action statement in it.. (its a social) and 
>put the appropriate info into the socials file .. (ie. min level able to 
>do the command, min position .. etc)..
>    BUT there is ONE more slot which i added to retain the basic 
>functionality of the cmd_info list.. and thats a "sort_as" variable.. 
>which tells the create_command_info WHERE to place the command.. (for 
>example many muds, want the tell command to trigger when you type 't 
>person blah' .. henceforth they place the tell command at the beginning 
>of the 't' commands.  so .. here's an example of what i did to my 
>command_info structure (in interpreter.h):
>
>struct command_info {
>   char *command;
>   char *sort_as;
>   byte minimum_position;
>   void (*command_pointer) (struct char_data *ch, char * argument, int cmd,
int subcmd);
>   sh_int minimum_level;
>   int  subcmd;
>   int  show;
>};
>
>then here's an example of the 't' section of my interpreter.c's 
>definition of cmd_info:
>
>  { "tell"  , "t"       , POS_DEAD    , do_tell     , 0, 0, 1 },
>  { "take"  , "take"    , POS_RESTING , do_get      , 0, 0, 1 },
>  { "taste" , "taste"   , POS_RESTING , do_eat      , 0, SCMD_TASTE, 1 },
>  { "teleport"  , "teleport"    , POS_DEAD    , do_teleport , LVL_GOD, 0, 1 },
>  { "thaw"  , "thaw"    , POS_DEAD    , do_wizutil  , LVL_FREEZE,
SCMD_THAW, 1 },
>  { "title" , "ti"      , POS_DEAD    , do_title    , 0, 0, 1 },
>  { "time"  , "time"    , POS_DEAD    , do_time     , 0, 0, 1 },
>  { "toggle"    , "toggle"  , POS_DEAD    , do_toggle   , 0, 0, 1 },
>  { "transfer"  , "transfer"    , POS_SLEEPING, do_trans    , LVL_GOD, 0, 1 },
>  { "typo"  , "typo"    , POS_DEAD    , do_gen_write, 0, SCMD_TYPO, 1 },
>
>
>    notice that the first field (the actual command name) is NOT 
>sorted into alphabetical order.. but the second field (the newly added 
>sort_as field) IS sorted into alphabetical order.. this means that when the
>create_command_list() routine goes to add in the socials it will know 
>where to place each social.. (note: the second field now back in the 
>example of the 'socials' file .. is the same as the second field here in 
>the command_info structure of cmd_info, it tells the social where to go 
>in relation to the next ACTUAL command..)  DO NOT make the sort_as field 
>a value equivalent to 'LATER' than the original command .. this field is 
>ONLY meant to tell the create_command_list() routine if a command was 
>meant to be shifted before other commands.. (or else all the commands 
>behind the command which you put a 'later than' sort_as field will be 
>shifted too.)
>
>    Hmm... then I'd guess you have your own dynamic command list.. 
>which enables you to build a aedit..(pretty much copy redit.c then 
>replace with the appropriate menu and defines in OLC.H .)..
>heres an example of my aedit.c (most important routines):
>------------------------------------------------------------------
>
>/*
>**  File: aedit.c
>**  Comment: OLC for MUDs -- this one edits socials
>*/
>
>#include "conf.h"
>#include "sysdep.h"
>
>#include "structs.h"
>#include "interpreter.h"
>#include "handler.h"
>#include "comm.h"
>#include "utils.h"
>#include "db.h"
>#include "olc.h"
>#include "screen.h"
>
>extern int               top_of_socialt;
>extern struct social_messg  *soc_mess_list;
>extern char         *edit_errors[];
>extern char         *position_types[];
>
>#define RESERVE_CMDS        15  /* reserve these commands to come straight
>                     * from the cmd list then start sorting */
>
>/* external functs */
>void create_command_list(void);
>void free_action(struct social_messg *action);
>
>
>/* function protos */
>void aedit_disp_menu(struct descriptor_data * d);
>void aedit_parse(struct descriptor_data * d, char *arg);
>void aedit_setup_new(struct descriptor_data *d);
>void aedit_setup_existing(struct descriptor_data *d, int real_num);
>void aedit_save_to_disk(struct descriptor_data *d);
>void aedit_save_internally(struct descriptor_data *d);
>
>
>
>/*
>** Utils and exported functions.
>*/
>
>void aedit_setup_new(struct descriptor_data *d) {
>   CREATE(OLC_ACTION(d), struct social_messg, 1);
>   OLC_ACTION(d)->command = str_dup("newcmd");
>   OLC_ACTION(d)->sort_as = str_dup("newcmd");
>   OLC_ACTION(d)->hide    = 0;
>   OLC_ACTION(d)->min_victim_position = POS_STANDING;
>   OLC_ACTION(d)->min_char_position   = POS_STANDING;
>   OLC_ACTION(d)->min_level_char      = 0;
>   OLC_ACTION(d)->char_no_arg = str_dup("This action is unfinished.");
>   OLC_ACTION(d)->others_no_arg = str_dup("This action is unfinished.");
>   OLC_ACTION(d)->char_found = NULL;
>   OLC_ACTION(d)->others_found = NULL;
>   OLC_ACTION(d)->vict_found = NULL;
>   OLC_ACTION(d)->not_found = NULL;
>   OLC_ACTION(d)->char_auto = NULL;
>   OLC_ACTION(d)->others_auto = NULL;
>   aedit_disp_menu(d);
>   OLC_VAL(d) = 0;
>}
>
>/*------------------------------------------------------------------------*/
>
>void aedit_setup_existing(struct descriptor_data *d, int real_num) {
>   CREATE(OLC_ACTION(d), struct social_messg, 1);
>   OLC_ACTION(d)->command = str_dup(soc_mess_list[real_num].command);
>   OLC_ACTION(d)->sort_as = str_dup(soc_mess_list[real_num].sort_as);
>   OLC_ACTION(d)->hide    = soc_mess_list[real_num].hide;
>   OLC_ACTION(d)->min_victim_position =
soc_mess_list[real_num].min_victim_position;
>   OLC_ACTION(d)->min_char_position   =
soc_mess_list[real_num].min_char_position;
>   OLC_ACTION(d)->min_level_char      = soc_mess_list[real_num].min_level_char;
>   OLC_ACTION(d)->char_no_arg   =
>   ((soc_mess_list[real_num].char_no_arg !=
NULL)?str_dup(soc_mess_list[real_num].char_no_arg):NULL);
>   OLC_ACTION(d)->others_no_arg =
>   ((soc_mess_list[real_num].others_no_arg !=
NULL)?str_dup(soc_mess_list[real_num].others_no_arg):NULL);
>   OLC_ACTION(d)->char_found    =
>   ((soc_mess_list[real_num].char_found !=
NULL)?str_dup(soc_mess_list[real_num].char_found):NULL);
>   OLC_ACTION(d)->others_found  =
>   ((soc_mess_list[real_num].others_found !=
NULL)?str_dup(soc_mess_list[real_num].others_found):NULL);
>   OLC_ACTION(d)->vict_found    =
>   ((soc_mess_list[real_num].vict_found !=
NULL)?str_dup(soc_mess_list[real_num].vict_found):NULL);
>   OLC_ACTION(d)->not_found     =
>   ((soc_mess_list[real_num].not_found !=
NULL)?str_dup(soc_mess_list[real_num].not_found):NULL);
>   OLC_ACTION(d)->char_auto     =
>   ((soc_mess_list[real_num].char_auto !=
NULL)?str_dup(soc_mess_list[real_num].char_auto):NULL);
>   OLC_ACTION(d)->others_auto   =
>   ((soc_mess_list[real_num].others_auto !=
NULL)?str_dup(soc_mess_list[real_num].others_auto):NULL);
>   OLC_VAL(d) = 0;
>   aedit_disp_menu(d);
>}
>
>/*------------------------------------------------------------------------*/
>      
>void aedit_save_internally(struct descriptor_data *d) {
>   struct social_messg *new_soc_mess_list = NULL;
>   int i;
>   
>   /* add a new social into the list */
>   if (OLC_ZNUM(d) > top_of_socialt)  {
>      CREATE(new_soc_mess_list, struct social_messg, top_of_socialt + 2);
>      for (i = 0; i <= top_of_socialt; i++)
>        new_soc_mess_list[i] = soc_mess_list[i];
>      new_soc_mess_list[++top_of_socialt] = *OLC_ACTION(d);
>      free(soc_mess_list);
>      soc_mess_list = new_soc_mess_list;
>      create_command_list();
>   }
>   /* pass the editted action back to the list - no need to add */
>   else {
>      free_action(&soc_mess_list[OLC_ZNUM(d)]);
>      soc_mess_list[OLC_ZNUM(d)] = *OLC_ACTION(d);
>   }
>   olc_add_to_save_list(-1, OLC_SAVE_ACTION);
>}
>
>
>/*------------------------------------------------------------------------*/
>
>void aedit_save_to_disk(struct descriptor_data *d) {
>   FILE *fp;
>   int i;
>
>   if (!(fp = fopen(SOCMESS_FILE, "w+")))  {
>      sprintf(buf, "Can't open socials file '%s'", SOCMESS_FILE);
>      perror(buf);
>      exit(1);
>   }
>
>   for (i = 0; i <= top_of_socialt; i++)  {
>      sprintf(buf, "~%s %s %d %d %d %d\n",
>          soc_mess_list[i].command,
>          soc_mess_list[i].sort_as,
>          soc_mess_list[i].hide,
>          soc_mess_list[i].min_char_position,
>          soc_mess_list[i].min_victim_position,
>          soc_mess_list[i].min_level_char);
>      fputs(buf, fp);
>      sprintf(buf, "%s\n%s\n%s\n%s\n",
>          ((soc_mess_list[i].char_no_arg)?soc_mess_list[i].char_no_arg:"#"),
>
((soc_mess_list[i].others_no_arg)?soc_mess_list[i].others_no_arg:"#"),
>          ((soc_mess_list[i].char_found)?soc_mess_list[i].char_found:"#"),
>          ((soc_mess_list[i].others_found)?soc_mess_list[i].others_found:"#"));
>      fputs(buf, fp);
>      sprintf(buf, "%s\n%s\n%s\n%s\n\n",
>          ((soc_mess_list[i].vict_found)?soc_mess_list[i].vict_found:"#"),
>          ((soc_mess_list[i].not_found)?soc_mess_list[i].not_found:"#"),
>          ((soc_mess_list[i].char_auto)?soc_mess_list[i].char_auto:"#"),
>          ((soc_mess_list[i].others_auto)?soc_mess_list[i].others_auto:"#"));
>      fputs(buf, fp);
>   }
>   
>   fprintf(fp, "$\n");
>   fclose(fp);
>   olc_remove_from_save_list(-1, OLC_SAVE_ACTION);
>}
>
>/*------------------------------------------------------------------------*/
>
>/* Menu functions */
>...
>
>    Anyways .. i am SURE that this is FAR from complete, but as for 
>a quicky explanation of what it took to impl an aedit function.. i hope 
>it covers all the basis.
>
>        I for some reason i forgot a major portion of 
>something, and you're still stumped, let me know.
>
>                                  Michael Scott aka Manx!
>                   FLAMES == scottm@workcomm.net
>
>Ps. Sorry for the long post.. but the code examples I felt sortof added 
>to the easability of understanding.
>A Tickism minute:
>On justice and on friendship, there is no price,
>but there are established credit limits.
>         -- The Tick
>+==================================================================+
>| David Carver, Programmer Analyst        "Spooooooooonnnnnn!!!"   |      
>| Columbus State Community College               -- The Tick       |
>| Email: dcarver@cougar.colstate.cc.oh.us                          | 
>+==================================================================+
>       
>                
>



Realms of Reality....
http://greatbasin.net/~cyber/index.html
telnet://login.greatbasin.net PORT: 4000
Mailto: Reaper@cyber.reno.nv.us
***HD crashed... lost old SIG... will have to deal with it till L8R =:)
\\//
 ||
+-----------------------------------------------------------+
| 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