[long code] Gossiping socials

From: Sammy (samedi@dhc.net)
Date: 02/18/97


As promised (a day late), here's a mod to allow players to gossip socials.
For example, you type:

> gossip @snicker

[GOSSIP] Samedi snickers.

> gossip @pat janitor

[GOSSIP] Samedi pats the janitor on his head.

You can also substitue the gemote command in place of "gossip @", or take
that bit out.

In file interpreter.h

#define SCMD_GRATZ	4  /* find this line */
#define SCMD_GMOTE	5  /* add this line */

In file comm.h

#define TO_CHAR		4  /* find this line */
#define TO_GMOTE	5  /* add this line */

In file act.comm.c

/* replace your do_gen_comm with this, or add the parts I commented */
ACMD(do_gen_comm)
{
  extern int level_can_shout;
  extern int holler_move_cost;
  struct descriptor_data *i;
  char color_on[24];
  byte gmote = FALSE; /* add this line */

  /* Array of flags which must _not_ be set in order for comm to be heard */
  static int channels[] = {
    0,
    PRF_DEAF,
    PRF_NOGOSS,
    PRF_NOAUCT,
    PRF_NOGRATZ,
    0
  };

  /*
   * com_msgs: [0] Message if you can't perform the action because of noshout
   *           [1] name of the action
   *           [2] message if you're not on the channel
   *           [3] a color string.
   */
  static char *com_msgs[][4] = {
    {"You cannot holler!!\r\n",
      "holler",
      "",
    KYEL},

    {"You cannot shout!!\r\n",
      "shout",
      "Turn off your noshout flag first!\r\n",
    KYEL},

    {"You cannot gossip!!\r\n",
      "gossip",
      "You aren't even on the channel!\r\n",
    KYEL},

    {"You cannot auction!!\r\n",
      "auction",
      "You aren't even on the channel!\r\n",
    KMAG},

    {"You cannot congratulate!\r\n",
      "congrat",
      "You aren't even on the channel!\r\n",
    KGRN}
  };

  ACMD(do_gmote);  /* add this line */

  /* to keep pets, etc from being ordered to shout */
  if (!ch->desc)
    return;

  if (PLR_FLAGGED(ch, PLR_NOSHOUT)) {
    send_to_char(com_msgs[subcmd][0], ch);
    return;
  }
  if (ROOM_FLAGGED(ch->in_room, ROOM_SOUNDPROOF)) {
    send_to_char("The walls seem to absorb your words.\r\n", ch);
    return;
  }
  /* level_can_shout defined in config.c */
  if (GET_LEVEL(ch) < level_can_shout) {
    sprintf(buf1, "You must be at least level %d before you can %s.\r\n",
	    level_can_shout, com_msgs[subcmd][1]);
    send_to_char(buf1, ch);
    return;
  }
  /* make sure the char is on the channel */
  if (PRF_FLAGGED(ch, channels[subcmd])) {
    send_to_char(com_msgs[subcmd][2], ch);
    return;
  }
  /* skip leading spaces */
  skip_spaces(&argument);

  /* add these four lines */
  if(subcmd == SCMD_GMOTE || (subcmd == SCMD_GOSSIP && *argument == '@')) {
    subcmd = SCMD_GOSSIP;
    gmote = TRUE;
  }

  /* make sure that there is something there to say! */
  if (!*argument) {
    sprintf(buf1, "Yes, %s, fine, %s we must, but WHAT???\r\n",
	    com_msgs[subcmd][1], com_msgs[subcmd][1]);
    send_to_char(buf1, ch);
    return;
  }

  /* add these seven lines */
  if (gmote) {
    if (*argument == '@')
      do_gmote(ch, argument + 1, 0, 1);
    else
      do_gmote(ch, argument, 0, 1);
    return;
  }

  if (subcmd == SCMD_HOLLER) {
    if (GET_MOVE(ch) < holler_move_cost) {
      send_to_char("You're too exhausted to holler.\r\n", ch);
      return;
    } else
      GET_MOVE(ch) -= holler_move_cost;
  }
  /* set up the color on code */
  strcpy(color_on, com_msgs[subcmd][3]);

  /* first, set up strings to be given to the communicator */
  if (PRF_FLAGGED(ch, PRF_NOREPEAT))
    send_to_char(OK, ch);
  else {
    if (COLOR_LEV(ch) >= C_CMP)
      sprintf(buf1, "%sYou %s, '%s'%s", color_on, com_msgs[subcmd][1],
	      argument, KNRM);
    else
      sprintf(buf1, "You %s, '%s'", com_msgs[subcmd][1], argument);
    act(buf1, FALSE, ch, 0, 0, TO_CHAR | TO_SLEEP);
  }

  sprintf(buf, "$n %ss, '%s'", com_msgs[subcmd][1], argument);

  /* now send all the strings out */
  for (i = descriptor_list; i; i = i->next) {
    if (!i->connected && i != ch->desc && i->character &&
	!PRF_FLAGGED(i->character, channels[subcmd]) &&
	!PLR_FLAGGED(i->character, PLR_WRITING) &&
	!ROOM_FLAGGED(i->character->in_room, ROOM_SOUNDPROOF)) {

      if (subcmd == SCMD_SHOUT &&
	  ((world[ch->in_room].zone != world[i->character->in_room].zone) ||
	   GET_POS(i->character) < POS_RESTING))
	continue;

      if (COLOR_LEV(i->character) >= C_NRM)
	send_to_char(color_on, i->character);
      act(buf, FALSE, ch, 0, i->character, TO_VICT | TO_SLEEP);
      if (COLOR_LEV(i->character) >= C_NRM)
	send_to_char(KNRM, i->character);
    }
  }
}

In file interpreter.c

ACMD(do_gecho);  /* find this line */
ACMD(do_gmote);  /* add this line */

  { "gecho"    , POS_DEAD    , do_gecho    , LVL_GOD, 0},/* find this line */
  { "gemote"   , POS_SLEEPING, do_gen_comm , 0, SCMD_GMOTE },/*add this */

In file comm.c

#include "house.h"   /* find this line */
#include "screen.h"  /* add this line */

/* replace stock act with this one, or add the parts I commented */
void act(char *str, int hide_invisible, struct char_data *ch,
	 struct obj_data *obj, void *vict_obj, int type)
{
  struct char_data *to;
  static int sleep;
  struct descriptor_data *i; /* add this line */

  if (!str || !*str)
    return;

  /*
   * Warning: the following TO_SLEEP code is a hack.
   * 
   * I wanted to be able to tell act to deliver a message regardless of sleep
   * without adding an additional argument.  TO_SLEEP is 128 (a single bit
   * high up).  It's ONLY legal to combine TO_SLEEP with one other TO_x
   * command.  It's not legal to combine TO_x's with each other otherwise.
   */

  /* check if TO_SLEEP is there, and remove it if it is. */
  if ((sleep = (type & TO_SLEEP)))
    type &= ~TO_SLEEP;


  if (type == TO_CHAR) {
    if (ch && SENDOK(ch))
      perform_act(str, ch, obj, vict_obj, ch);
    return;
  }
  if (type == TO_VICT) {
    if ((to = (struct char_data *) vict_obj) && SENDOK(to))
      perform_act(str, ch, obj, vict_obj, to);
    return;
  }
  /* ASSUMPTION: at this point we know type must be TO_NOTVICT or TO_ROOM */
  /* or TO_GMOTE */

  /* add from here to GMOTE_END */
  if (type == TO_GMOTE) {
    for (i = descriptor_list; i; i = i->next) {
      if (!i->connected && i->character &&
	!PRF_FLAGGED(i->character, PRF_NOGOSS) &&
	!PLR_FLAGGED(i->character, PLR_WRITING) &&
	!ROOM_FLAGGED(i->character->in_room, ROOM_SOUNDPROOF)) {

        send_to_char(CCYEL(i->character, C_NRM), i->character);
        perform_act(str, ch, obj, vict_obj, i->character);
        send_to_char(CCNRM(i->character, C_NRM), i->character);
      }
    }
    return;
  }
  /* GMOTE_END */

  if (ch && ch->in_room != NOWHERE)
    to = world[ch->in_room].people;
  else if (obj && obj->in_room != NOWHERE)
    to = world[obj->in_room].people;
  else {
    log("SYSERR: no valid target to act()!");
    return;
  }

  for (; to; to = to->next_in_room)
    if (SENDOK(to) && !(hide_invisible && ch && !CAN_SEE(to, ch)) &&
	(to != ch) && (type == TO_ROOM || (to != vict_obj)))
      perform_act(str, ch, obj, vict_obj, to);
}

In file act.social.c

/* add this new function (at the end of the file is fine */
ACMD(do_gmote)
{
  int act_nr, length;
  char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
  struct social_messg *action;
  struct char_data *vict = NULL;

  half_chop(argument, buf, arg);

  if(subcmd)
    for (length = strlen(buf), cmd = 0; *cmd_info[cmd].command != '\n'; cmd++)
      if (!strncmp(cmd_info[cmd].command, buf, length))
 	break;

  if ((act_nr = find_action(cmd)) < 0) {
    send_to_char("That's not a social!\r\n", ch);
    return;
  }
  action = &soc_mess_list[act_nr];

  if (!action->char_found)
    *arg = '\0';

  if (!*arg) {
    if(!action->others_no_arg || !*action->others_no_arg) {
      send_to_char("Who are you going to do that to?\r\n", ch);
      return;
    }
    sprintf(buf, "[GOSSIP] %s", action->others_no_arg);
  } else if (!(vict = get_char_vis(ch, arg))) {
    send_to_char(action->not_found, ch);
    send_to_char("\r\n", ch);
    return;
  } else if (vict == ch) {
    if(!action->others_auto || !*action->others_auto) {
      send_to_char(action->char_auto, ch);
      send_to_char("\r\n", ch);
      return;
    }
    sprintf(buf, "[GOSSIP] %s", action->others_auto);
  } else {
    if (GET_POS(vict) < action->min_victim_position)
      act("$N is not in a proper position for that.",
	  FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP);
    else {
      sprintf(buf, "[GOSSIP] %s", action->others_found);
    }
  }
  act(buf, FALSE, ch, 0, vict, TO_GMOTE);
}


Note that socials are sent in third person to everyone.  That's my
preference.  Feel free to change it.  That part is yours to try.

Sam

+-----------------------------------------------------------+
| Ensure that you have read the CircleMUD Mailing List FAQ: |
|   http://cspo.queensu.ca/~fletcher/Circle/list_faq.html   |
|    Or send 'info circle' to majordomo@cspo.queensu.ca     |
+-----------------------------------------------------------+



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