From: "Mathew Earle Reuther" <graymere@zipcon.net>
> Changes made thusfar:
>
> Added to struct player_special_data in structs.h:
> int *memory; /* PC's memory for intro system */
Change this to a long:
long *memory; /* PC's memory for intro system */
>
>
> Added to db.c:
> (in load_char):
> } else if(!strcmp(tag, "Mem ")) {
> ch->player_specials->memory = fbgetstring(fl);
What you get here is a char *, pointing to a string. What you want
to do is copy the way tongues/affs/saving throws are saved, and do this:
else if(!strcmp(tag, "Mem ")) {
/* here you could free the old list, if you wish */
/* allocate room for the memories */
CREATE(ch->player_specials->memory, long, num+1);
/* first line is number of remembered people */
ch->player_specials->memory[0] = (long)num;
for(i = 1; i <= num; i++) {
fbgetline(fl, line);
sscanf(line, "%ld", &lnum);
/* here could be a check to see if that player even exist anymore */
ch->player_specials->memory[i] = lnum;
}
}
> (in save_char):
> if(ch->player_specials->memory && *ch->player_specials->memory) {
> strcpy(buf, ch->player_specials->memory);
> fbprintf(fl, "Mem : %s\n", buf);
> }
>
Again, this saves a string, if you're lucky. Since memory is a pointer
to a place in memory, there is no saying what the string would be,
or if it would be NULL terminated.
I'd suggest saving as above:
if(ch->player_specials->memory) {
fbprintf(fl, "Mem : %ld\n", ch->player_specials->memory[0]);
for (i = 1; i <= ch->player_specials->memory[0]; i++)
fbprintf(fl, "%ld\n", ch->player_specials->memory[i];
}
>
> Created a memory.c file containing the following code:
>
> /* Does ch know victim? */
> bool knows_char(struct char_data *ch, struct char_data *victim)
> {
int i, bot, mid, top;
>
> /* Characters always know NPCs and IMMORTALS and vice versa */
> if (IS_NPC(ch) || IS_NPC(victim) || (GET_LEVEL(ch) >= LVL_IMMORT)
> || (GET_LEVEL(victim) >= LVL_IMMORT))
> return TRUE;
>
if (!ch->player_specials->memory)
return FALSE;
>
> /* Simple sequential search. If the data was sorted, a binary search
> could be attempted */
/* indeed - so the list is sorted */
bot = 1;
top = ch->player_specials->memory[0];
/* perform binary search */
for (;;) {
mid = (bot + top) / 2;
if (bot>=top)
return FALSE;
if (ch->player_specials->memory[mid] = GET_IDNUM(victim);
return TRUE;
if (ch->player_specials->memory[mid] > GET_IDNUM(victim))
top = mid - 1;
else
bot = mid + 1;
}
> return FALSE;
> }
>
> /* Add victim to ch's know list */
> void add_know(struct char_data *ch, struct char_data *victim)
> {
int i, found = 0;
>
> if (knows_char(ch,victim))
> return;
/* simple case first */
if (!ch->player_specials->memory) {
CREATE(ch->player_specials->memory, int, 2);
ch->player_specials->memory[0] = 1;
ch->player_specials->memory[1] = GET_IDNUM(victim);
return;
}
ch->player_specials->memory[0]++;
/* number of remembered + index -> +1*/
RECREATE(ch->player_specials->memory, int,
ch->player_specials->memory[0]+1);
for (i = ch->player_specials->memory[0]+1;i > 1; i--) {
if (ch->player_specials->memory[i-1] < GET_IDNUM(victim)) {
ch->player_specials->memory[i] = GET_IDNUM(victim);
found = i;
} else
ch->player_specials->memory[i] =
ch->player_specials->memory[i-1]
}
if (!found)
ch->player_specials->memory[1] = GET_IDNUM(victim);
> }
>
> Questions:
>
> Is malloc() the correct method of memory allocation to use in add_know?
> (And of course, free() afterwards?)
>
You should use the circle CREATE and RECREATE macros, as above.
This does some simple error checking for you.
> Why do I get a warning for comparing a pointer to an integer in this line
> of knows_char():
> for (i = 1; i < ch->player_specials->memory; i++)
Because ch->player_specials->memory is a pointer to an int. You really
wanted
for (i = 1; i <= ch->player_specials->memory[0]; i++)
>
> Did I add the int *memory to the right structure? (And is int* memory;
> correct in the first place?)
>
As I noted above, a list of idnums should be the same type as idnum, long.
> Am I saving and loading the data to the pfile (ASCII, of course) in a
> manner which will allow it to function in the intended manner?
No. The things that could go wrong are too numerous to mention. You need
to save things to a known format, and then read them from the same known
format.
The changes above are mailercode only. Use with caution, and be prepared
for fire, crashes, automobile accidents etc.
Welcor
--
+---------------------------------------------------------------+
| FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
| Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
| Newbie List: http://groups.yahoo.com/group/circle-newbies/ |
+---------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 06/25/03 PDT