/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// *
* -----------------------------------------------------------| (0...0) *
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( *
* -----------------------------------------------------------| {o o} *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~*
* Tricops and Fireblade | *
* ------------------------------------------------------------------------ *
* 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 St{rfeldt, 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 mud.h
*
* NOTE_DATA * comments; (* inside char_data 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 <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"
void note_attach(CHAR_DATA * ch);
void comment_remove(CHAR_DATA * ch, CHAR_DATA * victim, NOTE_DATA * 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->prev)
victim->comments = pnote->next;
else
pnote->prev->next = pnote->next;
STRFREE(pnote->text);
STRFREE(pnote->subject);
STRFREE(pnote->to_list);
STRFREE(pnote->date);
STRFREE(pnote->sender);
DISPOSE(pnote);
/*
* Rewrite entire list.
*/
save_char_obj(victim);
return;
}
void do_comment(CHAR_DATA * ch, char *argument)
{
char buf[MSL];
char arg[MIL];
char arg1[MIL];
NOTE_DATA *pnote;
CHAR_DATA *victim;
int vnum;
int anum;
if (IS_NPC(ch))
{
send_to_char("Mobs can't use the comment command.\n\r", ch);
return;
}
if (!ch->desc)
{
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->desc->connected == CON_EDITING)
{
send_to_char("You can't use the comment command from within the editor.\n\r", ch);
return;
}
switch (ch->substate)
{
default:
break;
case SUB_WRITING_NOTE:
if (!ch->pnote)
{
bug("do_comment: note got lost?", 0);
send_to_char("Your note got lost!\n\r", ch);
stop_editing(ch);
return;
}
if (ch->dest_buf != ch->pnote)
bug("do_comment: sub_writing_note: ch->dest_buf != ch->pnote", 0);
STRFREE(ch->pnote->text);
ch->pnote->text = copy_buffer(ch);
stop_editing(ch);
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)
{
send_to_char("They're not logged on!\n\r", ch); /* maybe fix this? */
return;
}
if (IS_NPC(victim))
{
send_to_char("No comments about mobs\n\r", ch);
return;
}
}
if (!str_cmp(arg, "list"))
{
victim = get_char_world(ch, argument);
if (!victim)
{
send_to_char("They're not logged on!\n\r", ch); /* maybe fix this? */
return;
}
if (IS_NPC(victim))
{
send_to_char("No comments about mobs\n\r", ch);
return;
}
if (get_trust(victim) >= get_trust(ch))
{
send_to_char("You're not of the right caliber to do this...\n\r", ch);
return;
}
if (!victim->comments)
{
send_to_char("There are no relevant comments.\n\r", ch);
return;
}
vnum = 0;
for (pnote = victim->comments; pnote; pnote = pnote->next)
{
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 */
send_to_char(buf, ch);
}
/* act( AT_ACTION, "$n glances over the notes.", ch, 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)
{
send_to_char("They're not logged on!\n\r", ch); /* maybe fix this? */
return;
}
if (IS_NPC(victim))
{
send_to_char("No comments about mobs\n\r", ch);
return;
}
if (get_trust(victim) >= get_trust(ch))
{
send_to_char("You're not of the right caliber to do this...\n\r", ch);
return;
}
if (!victim->comments)
{
send_to_char("There are no relevant comments.\n\r", ch);
return;
}
if (!str_cmp(argument, "all"))
{
fAll = TRUE;
anum = 0;
}
else if (is_number(argument))
{
fAll = FALSE;
anum = atoi(argument);
}
else
{
send_to_char("Note read which number?\n\r", ch);
return;
}
vnum = 0;
for (pnote = victim->comments; pnote; pnote = pnote->next)
{
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);
send_to_char(buf, ch);
send_to_char(pnote->text, ch);
/* act( AT_ACTION, "$n reads a note.", ch, NULL, NULL, TO_ROOM ); */
return;
}
}
send_to_char("No such comment.\n\r", ch);
return;
}
if (!str_cmp(arg, "write"))
{
note_attach(ch);
ch->substate = SUB_WRITING_NOTE;
ch->dest_buf = ch->pnote;
start_editing(ch, ch->pnote->text);
set_editor_desc(ch, "A player comment.");
return;
}
if (!str_cmp(arg, "subject"))
{
note_attach(ch);
STRFREE(ch->pnote->subject);
ch->pnote->subject = STRALLOC(argument);
send_to_char("Ok.\n\r", ch);
return;
}
if (!str_cmp(arg, "to"))
{
note_attach(ch);
STRFREE(ch->pnote->to_list);
ch->pnote->to_list = STRALLOC(argument);
send_to_char("Ok.\n\r", ch);
return;
}
if (!str_cmp(arg, "clear"))
{
if (ch->pnote)
{
STRFREE(ch->pnote->text);
STRFREE(ch->pnote->subject);
STRFREE(ch->pnote->to_list);
STRFREE(ch->pnote->date);
STRFREE(ch->pnote->sender);
DISPOSE(ch->pnote);
}
ch->pnote = NULL;
send_to_char("Ok.\n\r", ch);
return;
}
if (!str_cmp(arg, "show"))
{
if (!ch->pnote)
{
send_to_char("You have no comment in progress.\n\r", ch);
return;
}
sprintf(buf, "%s: %s\n\rTo: %s\n\r", ch->pnote->sender, ch->pnote->subject, ch->pnote->to_list);
send_to_char(buf, ch);
send_to_char(ch->pnote->text, ch);
return;
}
if (!str_cmp(arg, "post"))
{
char *strtime;
if (!ch->pnote)
{
send_to_char("You have no comment in progress.\n\r", ch);
return;
}
argument = one_argument(argument, arg1);
victim = get_char_world(ch, arg1);
if (!victim)
{
send_to_char("They're not logged on!\n\r", ch); /* maybe fix this? */
return;
}
if (IS_NPC(victim))
{
send_to_char("No comments about mobs\n\r", ch);
return;
}
if (get_trust(victim) > get_trust(ch))
{
send_to_char("You're not of the right caliber to do this...\n\r", ch);
return;
}
/* act( AT_ACTION, "$n posts a note.", ch, NULL, NULL, TO_ROOM ); */
strtime = ctime(¤t_time);
strtime[strlen(strtime) - 1] = '\0';
ch->pnote->date = STRALLOC(strtime);
pnote = ch->pnote;
ch->pnote = NULL;
/* LIFO to make life easier */
pnote->next = victim->comments;
if (victim->comments)
victim->comments->prev = pnote;
pnote->prev = 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
send_to_char("Ok.\n\r", ch);
return;
}
if (!str_cmp(arg, "remove"))
{
argument = one_argument(argument, arg1);
victim = get_char_world(ch, arg1);
if (!victim)
{
send_to_char("They're not logged on!\n\r", ch); /* maybe fix this? */
return;
}
if (IS_NPC(victim))
{
send_to_char("No comments about mobs\n\r", ch);
return;
}
if ((get_trust(victim) >= get_trust(ch)) || (get_trust(ch) < 58)) /* switch to some LEVEL_ thingie */
{
send_to_char("You're not of the right caliber to do this...\n\r", ch);
return;
}
/*argument = one_argument(argument, arg); */
if (!is_number(argument))
{
send_to_char("Comment remove which number?\n\r", ch);
return;
}
anum = atoi(argument);
vnum = 0;
for (pnote = victim->comments; pnote; pnote = pnote->next)
{
vnum++;
if ((58 <= get_trust(ch)) /* switch to some LEVEL_ thingie */
&& (vnum == anum))
{
comment_remove(ch, victim, pnote);
send_to_char("Ok.\n\r", ch);
/* act( AT_ACTION, "$n removes a note.", ch, NULL, NULL, TO_ROOM ); */
return;
}
}
send_to_char("No such comment.\n\r", ch);
return;
}
send_to_char("Huh? Type 'help comment' for usage (i hope!).\n\r", ch);
return;
}
void fwrite_comments(CHAR_DATA * ch, FILE * fp)
{
NOTE_DATA *pnote;
if (!ch->comments)
return;
for (pnote = ch->comments; pnote; pnote = pnote->next)
{
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);
}
return;
}
void fread_comment(CHAR_DATA * ch, FILE * fp)
{
NOTE_DATA *pnote;
for (;;)
{
char letter;
do
{
letter = getc(fp);
if (feof(fp))
{
fclose(fp);
return;
}
}
while (isspace(letter));
ungetc(letter, fp);
CREATE(pnote, NOTE_DATA, 1);
if (str_cmp(fread_word(fp), "sender"))
break;
pnote->sender = fread_string(fp);
if (str_cmp(fread_word(fp), "date"))
break;
pnote->date = fread_string(fp);
if (str_cmp(fread_word(fp), "to"))
break;
pnote->to_list = fread_string(fp);
if (str_cmp(fread_word(fp), "subject"))
break;
pnote->subject = fread_string(fp);
if (str_cmp(fread_word(fp), "text"))
break;
pnote->text = fread_string(fp);
pnote->next = ch->comments;
pnote->prev = NULL;
ch->comments = pnote;
return;
}
bug("fread_comment: bad key word. strap in!", 0);
/* exit( 1 ); */
}
/*
<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.
*/