SmaugWizard/Backup/
SmaugWizard/Backup/L/
SmaugWizard/Boards/
SmaugWizard/Building/
SmaugWizard/Corpses/
SmaugWizard/Councils/
SmaugWizard/Deity/
SmaugWizard/Gods/
SmaugWizard/MudProgs/
SmaugWizard/Player/L/
SmaugWizard/Src/
SmaugWizard/Src/res/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |				*
 * -----------------------------------------------------------|   \\._.//	*
 * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version)   |   (0...0)	*
 * -----------------------------------------------------------|    ).:.(	*
 * SMAUG (C) 1994, 1995, 1996 by Derek Snider                 |    {o o}	*
 * -----------------------------------------------------------|   / ' ' \	*
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |~'~.VxvxV.~'~*
 * Scryn, Swordbearer, Rennard, Tricops, and Gorog.           |				*
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe.    *
 * ------------------------------------------------------------------------ *
 * Comments: 'notes' attached to players to keep track of outstanding       * 
 *           and problem players.  -haus 6/25/1995                          * 
 ****************************************************************************/

/*  INSTALLATION: 1) Add following stuff to smaug.h
 *
 *  CNoteData *      comments;   (* inside CCharacter definition *)
 *  DECLARE_DO_FUN (do_comment     );
 *
 *                2) Add do_comment to interp.c, as usual
 *
 *                3) in save.c the following must be added
 *
 * save.c:107:     if (ch->comments)                                              (* saves comments *)
 * save.c:108:       fwrite_comments (ch, fp);                                           (*  in file *)
 *
 *
 * save.c:411:    ch->comments                        = NULL;                   (* nulls ch->comments *)
 *
 *
 * save.c:457:         else if (!str_cmp (word, "COMMENT")) fread_comment (ch, fp); (*snags #COMMENT*)
 *
 *                4) That looks like it to these eyes.  Lemme know if i forgot anything.
 *
 *
 * EXAMPLE:  See end of this file.
 *
 */

#include	"stdafx.h"
#include	"smaug.h"
#include	"smaugx.h"
#include	"objects.h"
#include	"rooms.h"
#include	"SmaugWizDoc.h"
#include	"descriptor.h"
#include	"character.h"

void note_attach (CCharacter *ch);


void comment_remove (CCharacter *ch, CCharacter *victim, CNoteData *pnote)
{
    if (!victim->comments)
    {
      bug ("comment remove: null board", 0);
      return;
    }

    if (!pnote)
    {
      bug ("comment remove: null pnote", 0);
      return;
    }
    
    /*
     * Remove comment from linked list.
     */
    if (!pnote->GetPrev ())
      victim->comments	= pnote->GetNext ();
    else
      pnote->GetPrev ()->SetNext (pnote->GetNext ());

    STRFREE (pnote->text   );
    STRFREE (pnote->subject);
    STRFREE (pnote->to_list);
    STRFREE (pnote->date   );
    STRFREE (pnote->sender );
    delete pnote;

    /*
     * Rewrite entire list.
     */
     save_char_obj (victim);

    return;
}

void do_comment (CCharacter *ch, char *argument)
{
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    CNoteData  *pnote;
    CCharacter  *victim;
    int vnum;
    int anum;

    if (ch->IsNpc ())
    {
	ch->SendText ("Mobs can't use the comment command.\n\r");
	return;
    }

    if (!ch->GetDesc ())
    {
	bug ("do_comment: no descriptor", 0);
	return;
    }

    /* Put in to prevent crashing when someone issues a comment command
       from within the editor. -Narn */
    if (ch->GetDesc ()->m_Connected == CON_EDITING)
    {
	ch->SendText ("You can't use the comment command from within the editor.\n\r");
	return;
    }

    switch (ch->GetSubstate ())
    {
	default:
	  break;
	case SUB_WRITING_NOTE:
	  if (!ch->GetNotes ())
	  {
	     bug ("do_comment: note got lost?", 0);
	     ch->SendText ("Your note got lost!\n\r");
	     ch->StopEditing ();
	     return;
	  }
	  if (ch->dest_buf != ch->GetNotes ())
	     bug ("do_comment: sub_writing_note: ch->dest_buf != ch->GetNotes ()", 0);
	  STRFREE (ch->GetNotes ()->text);
	  ch->GetNotes ()->text = ch->GetEditBuffer ();
	  ch->StopEditing ();	   
	  return;
    }

    set_char_color (AT_NOTE, ch);
    argument = one_argument (argument, arg);
    smash_tilde (argument);

    if (!str_cmp (arg, "about"))
    {

        victim = get_char_world (ch, argument);
	if (!victim)
	{
	   ch->SendText ("They're not logged on!\n\r");   /* maybe fix this? */
	   return;
	}

    if (victim->IsNpc ())
    {
	ch->SendText ("No comments about mobs\n\r");
	return;
    }


    }


    if (!str_cmp (arg, "list"))
    {
        victim = get_char_world (ch, argument);
	if (!victim)
	{
	   ch->SendText ("They're not logged on!\n\r");   /* maybe fix this? */
	   return;
	}

        if (victim->IsNpc ())
        {
	    ch->SendText ("No comments about mobs\n\r");
	    return;
        }

	if (victim->GetTrustLevel () >= ch->GetTrustLevel ())
	{
	  ch->SendText ("You're not of the right caliber to do this...\n\r");
	  return;
	}

	if (!victim->comments)
	{
	  ch->SendText ("There are no relevant comments.\n\r");
	  return;
	}

	vnum = 0;
	for (pnote = victim->comments; pnote; pnote = pnote->GetNext ())
	{
	  vnum++;
	  sprintf (buf, "%2d) %-10s [%s] %s\n\r",
	     vnum,
	     pnote->sender,
             pnote->date, 
	     pnote->subject);
/* Brittany added date to comment list and whois with above change */
	  ch->SendText (buf);
	}

	/* act (AT_ACTION, "$n glances over the notes.");, NULL, NULL, TO_ROOM); */
	return;
    }

    if (!str_cmp (arg, "read"))
    {
	BOOL fAll;

        argument = one_argument (argument, arg1);
        victim = get_char_world (ch, arg1);
	if (!victim)
	{
	   ch->SendText ("They're not logged on!\n\r");   /* maybe fix this? */
	   return;
	}

        if (victim->IsNpc ())
        {
	    ch->SendText ("No comments about mobs\n\r");
	    return;
        }

	if (victim->GetTrustLevel () >= ch->GetTrustLevel ())
	{
	  ch->SendText ("You're not of the right caliber to do this...\n\r");
	  return;
	}

	if (!victim->comments)
	{
	  ch->SendText ("There are no relevant comments.\n\r");
	  return;
	}



	if (!str_cmp (argument, "all"))
	{
	    fAll = TRUE;
	    anum = 0;
	}
	else
	if (is_number (argument))
	{
	    fAll = FALSE;
	    anum = atoi (argument);
	}
	else
	{
	    ch->SendText ("Note read which number?\n\r");
	    return;
	}

	vnum = 0;
	for (pnote = victim->comments; pnote; pnote = pnote->GetNext ())
	{
	    vnum++;
	    if (vnum == anum || fAll)
	    {
		sprintf (buf, "[%3d] %s: %s\n\r%s\n\rTo: %s\n\r",
		    vnum,
		    pnote->sender,
		    pnote->subject,
		    pnote->date,
		    pnote->to_list
		   );
		ch->SendText (buf);
		ch->SendText (pnote->text);
		/* act (AT_ACTION, "$n reads a note.");, NULL, NULL, TO_ROOM); */
		return;
	    }
	}

	ch->SendText ("No such comment.\n\r");
	return;
    }

    if (!str_cmp (arg, "write"))
    {
	note_attach (ch);
	ch->SetSubstate (SUB_WRITING_NOTE);
	ch->dest_buf = ch->GetNotes ();
	start_editing (ch, ch->GetNotes ()->text);
	return;
    }

    if (!str_cmp (arg, "subject"))
    {
	note_attach (ch);
	STRFREE (ch->GetNotes ()->subject);
	ch->GetNotes ()->subject = STRALLOC (argument);
	ch->SendText ("Ok.\n\r");
	return;
    }

    if (!str_cmp (arg, "to"))
    {
	note_attach (ch);
	STRFREE (ch->GetNotes ()->to_list);
	ch->GetNotes ()->to_list = STRALLOC (argument);
	ch->SendText ("Ok.\n\r");
	return;
    }

    if (!str_cmp (arg, "clear"))
    {
	if (ch->GetNotes ())
	{
	    STRFREE (ch->GetNotes ()->text);
	    STRFREE (ch->GetNotes ()->subject);
	    STRFREE (ch->GetNotes ()->to_list);
	    STRFREE (ch->GetNotes ()->date);
	    STRFREE (ch->GetNotes ()->sender);
	    delete ch->GetNotes ();
	}
	ch->SetNotes (NULL);

	ch->SendText ("Ok.\n\r");
	return;
    }

    if (!str_cmp (arg, "show"))
    {
	if (!ch->GetNotes ())
	{
	    ch->SendText ("You have no comment in progress.\n\r");
	    return;
	}

	sprintf (buf, "%s: %s\n\rTo: %s\n\r",
	    ch->GetNotes ()->sender,
	    ch->GetNotes ()->subject,
	    ch->GetNotes ()->to_list
	   );
	ch->SendText (buf);
	ch->SendText (ch->GetNotes ()->text);
	return;
    }

    if (!str_cmp (arg, "post"))
    {
	char *strtime;

	if (!ch->GetNotes ())
	{
	    ch->SendText ("You have no comment in progress.\n\r");
	    return;
	}

        argument = one_argument (argument, arg1);
        victim = get_char_world (ch, arg1);
	if (!victim)
	{
	   ch->SendText ("They're not logged on!\n\r");   /* maybe fix this? */
	   return;
	}

        if (victim->IsNpc ())
        {
	    ch->SendText ("No comments about mobs\n\r");
	    return;
        }

	if (victim->GetTrustLevel () > ch->GetTrustLevel ())
	{
	  ch->SendText ("You're not of the right caliber to do this...\n\r");
	  return;
	}

	/* act (AT_ACTION, "$n posts a note.");, NULL, NULL, TO_ROOM); */

	strtime = NCCP CurrentTime.GetString ();
	ch->GetNotes ()->date = STRALLOC (strtime);

	pnote = ch->GetNotes ();
	ch->SetNotes (NULL);


	/* LIFO to make life easier */
	pnote->SetNext (victim->comments);
        if (victim->comments)
	   victim->comments->SetPrev (pnote);
        pnote->SetPrev (NULL);
        victim->comments = pnote;

        save_char_obj (victim);


#ifdef NOTDEFD
	fclose (fpReserve);
	sprintf (notefile, "%s/%s", BOARD_DIR, board->note_file);
	if ((fp = fopen (notefile, "a")) == NULL)
	{
	    perror (notefile);
	}
	else
	{
	    fprintf (fp, "Sender  %s~\nDate    %s~\nTo      %s~\nSubject %s~\nText\n%s~\n\n",
		pnote->sender,
		pnote->date,
		pnote->to_list,
		pnote->subject,
		pnote->text
		);
	    fclose (fp);
	}
	fpReserve = fopen (NULL_FILE, "r");
#endif

	ch->SendText ("Ok.\n\r");
	return;
    }

    if (!str_cmp (arg, "remove"))
    {
        argument = one_argument (argument, arg1);
        victim = get_char_world (ch, arg1);
	if (!victim)
	{
	   ch->SendText ("They're not logged on!\n\r");   /* maybe fix this? */
	   return;
	}

        if (victim->IsNpc ())
        {
	    ch->SendText ("No comments about mobs\n\r");
	    return;
        }

	if ( (victim->GetTrustLevel () >= ch->GetTrustLevel ())
           || (ch->GetTrustLevel () < 58))   /* switch to some LEVEL_ thingie */
	{
	  ch->SendText ("You're not of the right caliber to do this...\n\r");
	  return;
	}

	/*argument = one_argument (argument, arg); */
	if (!is_number (argument))
	{
	    ch->SendText ("Comment remove which number?\n\r");
	    return;
	}

	anum = atoi (argument);
	vnum = 0;
	for (pnote = victim->comments; pnote; pnote = pnote->GetNext ())
	{
	    vnum++;
	    if ((58 <= ch->GetTrustLevel ())    /* switch to some LEVEL_ thingie */
	    &&   (vnum == anum))
	    {
		comment_remove (ch, victim, pnote);
		ch->SendText ("Ok.\n\r");
		/* act (AT_ACTION, "$n removes a note.");, NULL, NULL, TO_ROOM); */
		return;
	    }
	}

	ch->SendText ("No such comment.\n\r");
	return;
    }

    ch->SendText ("Huh?  Type 'help comment' for usage (i hope!).\n\r");
    return;
}


void fwrite_comments (CCharacter *ch, FILE *fp)
{
	CNoteData	*pnote;

	if (! ch->comments)
		return;

	for (pnote=ch->comments; pnote; pnote = pnote->GetNext ()) {
		fprintf (fp, "#COMMENT\n");
		fprintf (fp, "sender	%s~\n", pnote->sender);
		fprintf (fp, "date  	%s~\n", pnote->date);
		fprintf (fp, "to     	%s~\n", pnote->to_list);
		fprintf (fp, "subject	%s~\n", pnote->subject);
		fprintf (fp, "text\n%s~\n", pnote->text);
	}
}


void fread_comment (CCharacter *ch, FILE *fp)
{
	char	*word, *pLine;

	CNoteData	*pNote = new CNoteData;

	for (;;) {
		if (feof (fp)) {
			fclose (fp);
			delete pNote;
			bug ("fread_comment: EOF while read for %s", ch->GetName ());
			return;
		}
		pLine = fread_line (fp);
		word = ParseWord (pLine);

		if (! str_cmp (word, "sender"))
			pNote->sender = ParseString (pLine, fp);

		else if (! str_cmp (word, "date"))
			pNote->date	= ParseString (pLine, fp);

		else if (! str_cmp (word, "to"))
			pNote->to_list = ParseString (pLine, fp);

		else if (! str_cmp (word, "subject"))
			pNote->subject = ParseString (pLine, fp);

		else if (! str_cmp (word, "text")) {
			pNote->text	= ParseString (pLine, fp);
			break;
		}

		else {
			bug ("fread_comment: Bad keyword (%s)", word);
			ThrowSmaugException (SE_NOTES);
		}
	}

	pNote->SetNext (ch->comments);
	pNote->SetPrev (NULL);
	ch->comments = pNote;
}




/*
<758hp 100m 690mv> <#10316> loadup boo
Log: Haus: loadup boo
Log: Reading in player data for: Boo
Done.
<758hp 100m 690mv> <#10316> poke boo
You poke him in the ribs.
<758hp 100m 690mv> <#10316> comment subject boo's a nutcase!
Ok.
<758hp 100m 690mv> <#10316> comment to all
Ok.
<758hp 100m 690mv> <#10316> comment write
Begin entering your text now (/? = help /s = save /c = clear /l = list)
-----------------------------------------------------------------------
> He transed shimmy to temple square!
> /s
Done.
<758hp 100m 690mv> <#10316> comment post boo
Ok.
<758hp 100m 690mv> <#10316> comment list boo
 1) Haus: boo's a nutcase!
<758hp 100m 690mv> <#10316> comment read boo 1
[  1] Haus: boo's a nutcase!
Sun Jun 25 18:26:54 1995
To: all
He transed shimmy to temple square!
<758hp 100m 690mv> <#10316> comment remove boo 1
Ok.
<758hp 100m 690mv> <#10316> comment list boo
There are no relevent comments.
*/