15 Mar, 2009, elanthis wrote in the 21st comment:
Votes: 0
Almost every 32-bit platform can support 64-bit numbers. How you get them varies a bit, I think. I believe long long will work on most common compilers, though.

(And was that 31 a typo? Why would it only allow 31-bits?)
15 Mar, 2009, Hades_Kane wrote in the 22nd comment:
Votes: 0
handler.c, look for this or something similar:
char *affect_bit_name( int vector )


Add your AFF_CAMO and AFF_FOCUS there.

Also, go into tables.c and look for this or something similar:
const struct flag_type affect_flags[] =


Add your camo and focus stuff there. Also, have it declared in merc.h like you did, and see if it will compile now. Anytime you are adding something like a new flag or something like that, it doesn't hurt to find an existing one in the code, do a search for it and see where all it appears so you can use that as a template on where to add everything. In this case, you could do a search for 'AFF_HIDE' and 'hide' and you'll see that its declared in merc.h and has entries in handler.c and tables.c

Good luck.
15 Mar, 2009, boblinski wrote in the 23rd comment:
Votes: 0
In handler.c I already have:
char *affect_bit_name (int vector)
{
static char buf[512];

buf[0] = '\0';
if (vector & AFF_CAMO)
strcat (buf, " camoflague");
if (vector & AFF_FOCUS)
strcat (buf, " focus");
etc
etc
return (buf[0] != '\0') ? buf + 1 : "none";
}


and in tables.c I already have:
const struct flag_type affect_flags[] = {
{"blind", A, TRUE},
etc
etc
etc
{"camoflague", ee, TRUE},
{"focus", ff, TRUE},
{NULL, 0, 0}
};


but I still get this when compiling:
Quote
$ make clean
rm -f obj/act_comm.o obj/act_enter.o obj/act_info.o obj/act_move.o obj/act_obj.o
obj/act_wiz.o obj/alias.o obj/ban.o obj/bit.o obj/board.o obj/comm.o obj/const.
o obj/db.o obj/db2.o obj/effects.o obj/fight.o obj/flags.o obj/handler.o obj/hea
ler.o obj/hedit.o obj/ignore.o obj/interp.o obj/lookup.o obj/magic.o obj/magic2.
o obj/mem.o obj/mob_cmds.o obj/mob_prog.o obj/music.o obj/nanny.o obj/olc.o obj/
olc_act.o obj/olc_mpcode.o obj/olc_save.o obj/recycle.o obj/save.o obj/scan.o ob
j/skills.o obj/special.o obj/string.o obj/tables.o obj/update.o rom *~ *.bak *.o
rig *.rej

Bob@BOB /cygdrive/c/qmud/src
$ make
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_comm.o act_comm.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_enter.o act_enter.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_info.o act_info.c
act_info.c: In function `do_focus':
act_info.c:3122: warning: this decimal constant is unsigned only in ISO C90 <—-
act_info.c:3136: warning: this decimal constant is unsigned only in ISO C90 <—-
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_move.o act_move.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_obj.o act_obj.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_wiz.o act_wiz.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/alias.o alias.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/ban.o ban.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/bit.o bit.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/board.o board.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/comm.o comm.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/const.o const.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/db.o db.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/db2.o db2.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/effects.o effects.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/fight.o fight.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/flags.o flags.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/handler.o handler.c
handler.c: In function `can_see':
handler.c:2675: warning: this decimal constant is unsigned only in ISO C90 <—-
handler.c: In function `affect_bit_name':
handler.c:2857: warning: this decimal constant is unsigned only in ISO C90 <—-
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/healer.o healer.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/hedit.o hedit.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/ignore.o ignore.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/interp.o interp.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/lookup.o lookup.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/magic.o magic.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/magic2.o magic2.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/mem.o mem.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/mob_cmds.o mob_cmds.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/mob_prog.o mob_prog.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/music.o music.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/nanny.o nanny.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/olc.o olc.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/olc_act.o olc_act.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/olc_mpcode.o olc_mpcode.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/olc_save.o olc_save.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/recycle.o recycle.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/save.o save.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/scan.o scan.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/skills.o skills.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/special.o special.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/string.o string.c
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/tables.o tables.c
tables.c:166: warning: this decimal constant is unsigned only in ISO C90 <—- :(
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/update.o update.c
rm -f rom
gcc -O -ggdb -o rom obj/act_comm.o obj/act_enter.o obj/act_info.o obj/act_move.o
obj/act_obj.o obj/act_wiz.o obj/alias.o obj/ban.o obj/bit.o obj/board.o obj/com
m.o obj/const.o obj/db.o obj/db2.o obj/effects.o obj/fight.o obj/flags.o obj/han
dler.o obj/healer.o obj/hedit.o obj/ignore.o obj/interp.o obj/lookup.o obj/magic
.o obj/magic2.o obj/mem.o obj/mob_cmds.o obj/mob_prog.o obj/music.o obj/nanny.o
obj/olc.o obj/olc_act.o obj/olc_mpcode.o obj/olc_save.o obj/recycle.o obj/save.o
obj/scan.o obj/skills.o obj/special.o obj/string.o obj/tables.o obj/update.o
15 Mar, 2009, Skol wrote in the 24th comment:
Votes: 0
http://bytes.com/groups/c/474270-big-dec...
Quote
The compiler is warning you that the rules changed
between C90 and C99, and that the type of the constant
depends on which Standard you follow – to put it another
way, the type of the constant is "unstable" in the sense
that it could change with a compiler upgrade.

For C90, the rule is as you stated: the type will be
the first of int, long int, or unsigned long int that
can accommodate the value, and on your system this comes
down to unsigned long int.

For C99, the type will be the first of int, long int,
or long long int that can accommodate the value, which
for your system would turn out to be long long int.

Recommendation: If you want an unsigned long, tack
on a "UL" suffix.

Meaning, on the wrong compiler it could too big for the type it is.
15 Mar, 2009, boblinski wrote in the 25th comment:
Votes: 0
I am really sorry about this, but I just don't understand what I have to do to fix these problems. I am hoping to add more affect_flags, and I've already got 31 defined..
15 Mar, 2009, Kayle wrote in the 26th comment:
Votes: 0
You're going to need to do a little reading and get a handle on exactly what bitwise operations, and bitwise math are. Without an understanding of these, this is not going to be a simple problem for you to fix. The easiest fix is going to be to add a second field and a second set of flags called affect2 or what have you and just have 32 of those and set them the same way but on affect2 instead of affect. This is however a cheap "hack" and not a very respectable solution, and not one that I would condone the use of, especially since there are much better options available if an individual has the patience to seek them out and learn them. Extended Bitvectors, and std::bitset being the biggest that come to mind.

boblinski said:
I'm only just learning to code in C let alone C++…

This used to be an argument I would employ a lot. It stemmed from what I know now as a fear of the unknown. I didn't know C++ and I was afraid of learning something new outside of my C comfort zone. But there is really no difference between C and C++ code except for the addition of the STL (Standard Template Library) which makes life a lot easier. Yes, they are slightly more complicated than your standard C lists and bitvectors, but they're generally easier, because unless you plan to rewrite and optimize each individual bit of code in the library, you don't really need to understand what it's doing behind the scenes, you need only know how to interact with the class itself.

For instance, you have 31 flags in your affects, by updating to C++ and using std::bitset you will effectively remove the limit and be able to have literally millions of affect flags. Not only that, but instead of having to remember to use a macro like IS_SET( ch->affect, AFF_CAMO ) or what have you, that's all compressed down to ch->affect.test( AFF_CAMO ) and the two do the exact same thing the one just does things better, like making sure things stay within the appropriate number of flags and tossing an exception or crashing if you pass an invalid AFF_*.

Boblinski, if you are seriously just learning to program, I recommend not hampering yourself by restricting yourself specifically to C. C++ is merely a superset of C with a slew of extra features designed at making the programmers life easier. If you're just learning, don't restrict yourself to the old languages, learn some of the new languages as well.

[Edit:] Reading back over this, I realized, it might not sound all that coherent.. and this just further confirms for me that I need not be posting while I'm still on pain meds. ;)
15 Mar, 2009, Skol wrote in the 27th comment:
Votes: 0
Bob, at your level of skill/experience etc? I'd add in the affects2. The snip should be pretty easy to follow. It will let you do another full set of affects without having to do the in-depth change that unlimited bits would, or delve into another programming language etc.
16 Mar, 2009, boblinski wrote in the 28th comment:
Votes: 0
Okay, I've added in affect2 snippet, however I'm getting this error:
Quote
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_wiz.o act_wiz.c
act_wiz.c: In function `do_mstat':
act_wiz.c:1715: error: `buffer' undeclared (first use in this function)
act_wiz.c:1715: error: (Each undeclared identifier is reported only once
act_wiz.c:1715: error: for each function it appears in.)
make: *** [obj/act_wiz.o] Error 1


Here's the code it's referring to:
if (victim->affected_by)
{
sprintf (buf, "Affected by %s\n\r",
affect_bit_name (victim->affected_by));
send_to_char (buf, ch);
}

if (victim->affected2_by)
{
sprintf(buf, "Also affected by %s\n\r",
affect2_bit_name(victim->affected2_by) );
/* line 1715 */ add_buf(buffer,buf);
}
16 Mar, 2009, Hades_Kane wrote in the 29th comment:
Votes: 0
Try declaring buffer higher up where 'buf' is declared?
16 Mar, 2009, boblinski wrote in the 30th comment:
Votes: 0
Hades_Kane said:
Try declaring buffer higher up where 'buf' is declared?


I added:
char buffer[MAX_STRING_LENGTH];   /*added this line*/
char buf[MAX_STRING_LENGTH];


But I still get this warning:
Quote
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/act_wiz.o act_wiz.c
act_wiz.c: In function `do_mstat':
act_wiz.c:1716: warning: passing arg 1 of `add_buf' from incompatible pointer type


Could I just edit the code to look like this:
if (victim->affected_by)
{
sprintf (buf, "Affected by %s\n\r",
affect_bit_name (victim->affected_by));
send_to_char (buf, ch);
}

if (victim->affected2_by)
{
sprintf(buf, "Also affected by %s\n\r",
affect2_bit_name (victim->affected2_by));
send_to_char (buf, ch);
}
16 Mar, 2009, Hades_Kane wrote in the 31st comment:
Votes: 0
I don't see why that would be an issue. If your affected by part is already set up that way, mirroring that shouldn't be an issue. More than likely, the author of the snippet had his stat command sending the text in a different manner than your's.
16 Mar, 2009, Sandi wrote in the 32nd comment:
Votes: 0
boblinski, that looks like a good fix to me. Sure, you could double up and use just one send_to_char (and you should learn to use add_buf() properly), but what you've done is eminently readable, and the one thing you don't want to learn from the old code is saving disk space or cpu cycles with convoluted logic at the expense of readability. That sort of thing was still needed when ROM was written, but the processors of today are hundreds of times faster and memory is really cheap (finally!).

Hades_Kane said:
Anytime you are adding something like a new flag or something like that, it doesn't hurt to find an existing one in the code, do a search for it and see where all it appears so you can use that as a template on where to add everything. In this case, you could do a search for 'AFF_HIDE' and 'hide' and you'll see that its declared in merc.h and has entries in handler.c and tables.c


I felt this was worth repeating. I did this twice this morning already, and I've been working with ROM for ten years, now. And that's worth pointing out too - you're trying to learn C, but you're also learning ROM. That might be considered akin to someone with a few years of English as a Second Language trying to work out the plots of Shakespeare.

BTW, in Windows, I use TextPad. I can't say enough good things about it - I feel it's the best program ever written for the Windows API. It has a search function that takes regexps like 'grep', can search any file or tree of folders, and prints each line found as a link on a page that then allows you to go to each example found just by clicking on it. Often, just seeing the line of surrounding code is enough. Works a treat for the kind of search HK is describing:

Searching for: AFF_HIDE
act_info.c(1208): && !IS_AFFECTED(victim, AFF_HIDE)
act_look.c(775): if ( IS_AFFECTED(victim, AFF_HIDE) ) strcat( buf, "`C(Hide)`x " );
act_move.c(1611): if ( IS_AFFECTED(ch, AFF_HIDE) )
act_move.c(1612): REMOVE_BIT(ch->affected_by, AFF_HIDE);
act_move.c(1631): SET_BIT(ch->affected_by, AFF_HIDE);
act_move.c(1650): REMOVE_BIT ( ch->affected_by, AFF_HIDE );
deep.h(1093): #define AFF_HIDE (Q)
extra.c(2387): if ( IS_AFFECTED(victim, AFF_HIDE) ) strcat( buf, "`C(Hide)`y " );
handler.c(3017): if ( IS_AFFECTED(victim, AFF_HIDE)
interp.c(475): REMOVE_BIT( ch->affected_by, AFF_HIDE );
magic2.c(200): REMOVE_BIT ( ich->affected_by, AFF_HIDE );
magic2.c(230): REMOVE_BIT ( ich->affected_by, AFF_HIDE );
tables1.c(1655): if ( vector & AFF_HIDE ) strcat( buf, " hide" );
Found 13 occurrence(s) in 9 file(s)
19 Mar, 2009, boblinski wrote in the 33rd comment:
Votes: 0
Thanks for all the help on this skill so far.

My issue now is that say my character Bob uses the skill 'focus'…

Therefore:
Quote
You are affected by the following spells:
Spell: focus : modifies none by 0 for 40 hours


Then, I log Bob off.

Then I log him back on.. it still says
Quote
You are affected by the following spells:
Spell: focus : modifies none by 0 for 40 hours


But the character doesn't actually -have- that affect on them, and when I type "focus" again…

Instead of saying:
"You are already focusing on your surroundings."

It says:
"You attempt to focus on your surroundings."

And then my affects go to:
Quote
You are affected by the following spells:
Spell: focus : modifies none by 0 for 40 hours
: modifies none by 0 for 40 hours


This is my current "do_focus":
void do_focus (CHAR_DATA * ch, char *argument)
{
AFFECT_DATA af;

if (IS_AFFECTED2 (ch, AFF_FOCUS))
{
send_to_char ("You are already focusing on your surroundings.\n\r", ch);
return;
}

send_to_char ("You attempt to focus on your surroundings.\n\r", ch);

if (number_percent () < get_skill (ch, gsn_focus))
{
check_improve (ch, gsn_focus, TRUE, 3);
af.where = TO_AFFECTS2;
af.type = gsn_focus;
af.level = ch->level;
af.duration = ch->level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FOCUS;
affect_to_char (ch, &af);
}
else
{
check_improve (ch, gsn_focus, FALSE, 3);
send_to_char ("You cannot seem to focus on your surroundings.\n\r", ch);
affect_strip (ch, gsn_focus);
REMOVE_BIT (ch->affected2_by, AFF_FOCUS);
}

return;
}


… whats wrong?
19 Mar, 2009, Sharmair wrote in the 34th comment:
Votes: 0
From your symptoms, it looks like you are either (or both) not saving the affected2_by flags,
or not loading them from the player file. Your skill code here looks for the existence of the
flag, not actually having the skill focus effect to determine if the user already has focus.

Some notes on your code here:
If the code is working right, if the user has the focus effect, they will always also have the
focus flag (though it is possible to have just the flag if they get it from something other
then this skill). So, if the user does have the effect, it should never get past the check for
already having focus. So, it really makes no sense stripping an effect they can not possibly
have. The same can be said for removing the flag that can never be set at that point in
the code, and if it could have been set (before the strip), the strip_affect call would have
already removed. Though, these things would not stop the code from working, they are
just wasted lines. Also, the proper line end is \r\n not \n\r (don't you read these forums?).
19 Mar, 2009, Igabod wrote in the 35th comment:
Votes: 0
Sharmair said:
Also, the proper line end is \r\n not \n\r (don't you read these forums?).


Can't expect him to find that one particular post in the month that he's been a member here. And since the stock ROM codebase uses the wrong format it's easy to see why he would assume that's the correct way. This is why I thought it was the correct way when you informed me of this problem with my code.
19 Mar, 2009, boblinski wrote in the 36th comment:
Votes: 0
Sharmair said:
From your symptoms, it looks like you are either (or both) not saving the affected2_by flags,
or not loading them from the player file. Your skill code here looks for the existence of the
flag, not actually having the skill focus effect to determine if the user already has focus.

Some notes on your code here:
If the code is working right, if the user has the focus effect, they will always also have the
focus flag (though it is possible to have just the flag if they get it from something other
then this skill). So, if the user does have the effect, it should never get past the check for
already having focus. So, it really makes no sense stripping an effect they can not possibly
have. The same can be said for removing the flag that can never be set at that point in
the code, and if it could have been set (before the strip), the strip_affect call would have
already removed. Though, these things would not stop the code from working, they are
just wasted lines. Also, the proper line end is \r\n not \n\r (don't you read these forums?).


Thanks for the notes, my "do_focus" now looks like:
void do_focus (CHAR_DATA * ch, char *argument)
{
AFFECT_DATA af;

if (IS_AFFECTED2 (ch, AFF_FOCUS))
{
send_to_char ("You are already focusing on your surroundings.\r\n", ch);
return;
}

send_to_char ("You attempt to focus on your surroundings.\r\n", ch);

if (number_percent () < get_skill (ch, gsn_focus))
{
send_to_char ("You begin to focus on your surroundings.\r\n", ch);
check_improve (ch, gsn_focus, TRUE, 3);
af.where = TO_AFFECTS2;
af.type = gsn_focus;
af.level = ch->level;
af.duration = ch->level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FOCUS;
affect_to_char (ch, &af);
}
else
{
check_improve (ch, gsn_focus, FALSE, 3);
send_to_char ("You try to focus but lose concentration.\r\n", ch);
}

return;
}



How do I "save the affected2_by flags" and "load the affected2_by flags from the player file" ?
20 Mar, 2009, Sharmair wrote in the 37th comment:
Votes: 0
The player file saving and loading is done in the file save.c. The main saving function is
save_char_obj(), but that basically calls functions for saving the character data itself (what
you want here), the objects the player has, the player's pet if they have one and also the
god file of immortals. The function you want for saving is the fwrite_char(). If you look
at this function, you will notice it just writes (using fprintf) data to the player file using a
'tagged' data format. It will write a word (the tag) identifying what data is being written
followed by the data itself. Though the order of things generally does not matter with a
tagged data format (there can be cases were reading one data point might rely on some
other data already being leaded, but this is not such a case) putting the new affected2_by
data close to to existing affected_by data might be good as they are really related. Look
for the existing affected_by write:
if (ch->affected_by != 0)
fprintf( fp, "AfBy %s\n", print_flags(ch->affected_by));

And just add another write for the new data:
if (ch->affected_by != 0)
fprintf( fp, "AfBy %s\n", print_flags(ch->affected_by));
if (ch->affected2_by != 0)
fprintf( fp, "AfBy2 %s\n", print_flags(ch->affected2_by));

The way these lines work is the data is only written if there is at least one flag set, also ROM
saves flags using letters for each flag, that is what print_flags() does, it converts an int to
a string of letters. You really could just write the number (using %d in the fprintf format
string), but I am using the conversion for consistency with the other flags (the use of the
letters is probably a throw back to the days when most editing was done in the files directly
in the shell and the letters were more human readable).

For reading, there is the main loading function load_char_obj() that in a like manner calls
the helper function fread_char() to load the main player data. One thing you will notice in
the fread_char() (and most tagged data read files used in ROM) is that the code pulls off
the tag (first word on a line in most cases) and then uses a switch based on the first letter
of the tag. This is done for efficiency, but it makes it VERY important that you put the code
to handle a tag in the case with the right start letter. In this case though, we are using a
tag that starts with the same letter (A) as the existing affected_by data, so we will put it
right after that. Look for the line (in the A case of the switch in fread_char() in save.c):
KEY( "AfBy",	ch->affected_by,	fread_flag( fp ) );

And make that:
KEY( "AfBy",	ch->affected_by,	fread_flag( fp ) );
KEY( "AfBy2", ch->affected2_by, fread_flag( fp ) );

Like on the save a conversion function is used, in this case to read a line with those letters
and returning a number. The macro KEY is just short hand to compare the tag with first
argument to the macro, then assign the 3rd argument to the 2nd argument, set the flag
to indicate that a valid tag was found and break out of the case. You will notice that tags
with more complex data formats requires the coder to write all these steps.
20 Mar, 2009, Sandi wrote in the 38th comment:
Votes: 0
Great post, Shamair. All I can think of to add is there are two macros - KEY for numbers, and KEYS for text. Don't get them confused. :)
15 May, 2009, boblinski wrote in the 39th comment:
Votes: 0
I'm only just getting back to this piece of my code..

It seems to be saving the affect, but now it will do this:

player A used "FOCUS"..

Quote
You are affected by the following spells:
Spell: focus : modifies none by 0 for 24 hours


Then the char logs off and back on… and has no "affects":

Quote
You are not affected by any spells.


But when he tries to use "FOCUS" again:

Quote
> focus

You are already focusing on your surroundings.


This is my DO_FOCUS()

void do_focus (CHAR_DATA * ch, char *argument)
{
AFFECT_DATA af;

if (IS_AFFECTED2 (ch, AFF_FOCUS))
{
send_to_char ("You are already focusing on your surroundings.\r\n", ch);
return;
}

send_to_char ("You attempt to focus on your surroundings.\r\n", ch);

if (number_percent () < get_skill (ch, gsn_focus))
{
check_improve (ch, gsn_focus, TRUE, 3);
af.where = TO_AFFECTS2;
af.type = gsn_focus;
af.level = ch->level;
af.duration = ch->level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FOCUS;
affect_to_char (ch, &af);
}
else
{
check_improve (ch, gsn_focus, FALSE, 3);
send_to_char ("You try to focus but get distracted.\r\n", ch);
}

return;
}
15 May, 2009, Sharmair wrote in the 40th comment:
Votes: 0
From your symptoms, it looks like you are saving the affected2_by flag, but the affected
struct (spell effect) is either not being saved or loaded correctly. Show us the code for
saving (should be at almost the end of fwrite_char() in save.c, probably a loop using paf
and writing with the tag of Affc) and loading (in fread_char() in save.c the Affc if in the A
case). Other then this, I would look in your pfile and see if you have the Affc line (should
be right before the objects). If that looks ok, then I would check if you have some code
stripping the spell effect but not clearing the affected2_by flag.
20.0/45