16 Mar, 2009, boblinski wrote in the 1st comment:
Votes: 0
Hi there, I'm trying to add a skill called Creep.

Creep is basically an exact copy of Sneak, except it works in different areas.. I can't seem to figure out why it's not working right because I copied it from sneak part by part..

I'm not having any trouble compiling.. it's just that when I -move- (n, s, e, w, u, d) creep should fail depending on the sector type of the new room..

Here's the code:
/*** making CREEP fail out of forest-areas ***/
if (IS_AFFECTED2(ch, AFF_CREEP)
&& (to_room->sector_type == SECT_AIR
|| to_room->sector_type == SECT_CITY
|| to_room->sector_type == SECT_INSIDE
|| to_room->sector_type == SECT_WATER_SWIM
|| to_room->sector_type == SECT_WATER_NOSWIM
|| to_room->sector_type == SECT_UNUSED
|| to_room->sector_type == SECT_DESERT))
{
affect_strip (ch, gsn_creep);
REMOVE_BIT (ch->affected2_by, AFF_CAMOFLAGUE);
REMOVE_BIT (ch->affected2_by, AFF_CREEP);
send_to_char ("Your movement becomes more noticeable.\n\r", ch);
}
/***END making CREEP fail out of forest-areas END***/


But, if I 'creep' and move from a SECT_FOREST room to a SECT_CITY room.. it tells me I'm still creeping.
16 Mar, 2009, Ssolvarain wrote in the 2nd comment:
Votes: 0
Your if check looks strange.
17 Mar, 2009, Hades_Kane wrote in the 3rd comment:
Votes: 0
boblinski said:
But, if I 'creep' and move from a SECT_FOREST room to a SECT_CITY room.. it tells me I'm still creeping.


You could try putting this if check after the character has already moved, and instead of checking for to_room you could check for ch->in_room.

I can't exactly tell what your problem is, but my guess would be that it would be in the to_room bit, so maybe moving it further down and doing that might do the trick.
17 Mar, 2009, David Haley wrote in the 4th comment:
Votes: 0
It would also be helpful to show what IS_AFFECTED2 expands to.

Also, instead of testing if the target sector is a bad type, you can test if it's not the right type. Shouldn't fix your problem, but can be simpler. I.e., instead of:
if (affected_by_creep AND (target is city OR target is desert OR target is inside OR ……) )
do:
if (affected_by_creep AND (target is not forest AND target is not jungle) )
17 Mar, 2009, boblinski wrote in the 5th comment:
Votes: 0
Hmmm, it turns out I haven't added what IS_AFFECTED2 does… I only just added the aff2 snippet and it didn't mention doing that one.

Would this suffice?–>
bool is_affected2 (CHAR_DATA * ch, int sn)
{
AFFECT_DATA *paf;

for (paf = ch->affected2; paf != NULL; paf = paf->next)
{
if (paf->type == sn)
return TRUE;
}

return FALSE;
}
17 Mar, 2009, David Haley wrote in the 6th comment:
Votes: 0
IS_AFFECTED2 had to be defined as something or it wouldn't have compiled; note that IS_AFFECTED2 and is_affected2 are not the same thing (C is case sensitive). Could you also show what IS_AFFECTED2 is defined as? It's important that we see everything so that we know where you're at.
17 Mar, 2009, boblinski wrote in the 7th comment:
Votes: 0
/*
* Character macros.
*/
#define IS_NPC(ch) (IS_SET((ch)->act, ACT_IS_NPC))
#define IS_IMMORTAL(ch) (get_trust(ch) >= LEVEL_IMMORTAL)
#define IS_HERO(ch) (get_trust(ch) >= LEVEL_HERO)
#define IS_TRUSTED(ch,level) (get_trust((ch)) >= (level))
#define IS_AFFECTED(ch, sn) (IS_SET((ch)->affected_by, (sn)))
#define IS_AFFECTED2(ch, sn) (IS_SET((ch)->affected2_by, (sn))) /*affect2*/


That what you mean at the bottom of that code? That's in merc.h..
17 Mar, 2009, Zeno wrote in the 8th comment:
Votes: 0
You say moving to a SECT_CITY. Is it only this sector, or does it not work at all?
17 Mar, 2009, boblinski wrote in the 9th comment:
Votes: 0
Not at all, the 'creep' affect just stays on the whole time instead of failing in set sectors.
17 Mar, 2009, David Haley wrote in the 10th comment:
Votes: 0
There's two ways for an effect to be "on" a player. One is for the bitvector to be set; the other is for the linked list of effects to contain an effect with the right skill number. (I hate that they misspelled it "affect"… sigh)
So you need to look into how you are setting the effect, and where you are checking it. You need to be setting and checking it in the same places.
17 Mar, 2009, boblinski wrote in the 11th comment:
Votes: 0
I think this is everything that needs mentioned:

interp.h:
DECLARE_DO_FUN(	do_creep		);


merc.h:
/*
* Bits for 'affected2_by'.
* Used in #MOBILES.
*/
#define AFF_CAMOFLAGUE (A)
#define AFF_FOCUS (B)
#define AFF_CREEP (C)

//and further down

extern sh_int gsn_creep;


act_move.c:
// in 'void move_char'

if (IS_AFFECTED2(ch, AFF_CREEP)
&& (to_room->sector_type == SECT_AIR
|| to_room->sector_type == SECT_CITY
|| to_room->sector_type == SECT_INSIDE
|| to_room->sector_type == SECT_WATER_SWIM
|| to_room->sector_type == SECT_WATER_NOSWIM
|| to_room->sector_type == SECT_UNUSED
|| to_room->sector_type == SECT_DESERT))
{
affect_strip (ch, gsn_creep);
REMOVE_BIT (ch->affected2_by, AFF_CAMOFLAGUE);
REMOVE_BIT (ch->affected2_by, AFF_CREEP);
send_to_char ("Your movement becomes more noticeable.\n\r", ch);
}

//and further down

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

send_to_char ("You try to make your movements go unnoticed.\n\r", ch);
affect_strip (ch, gsn_creep);

if (IS_AFFECTED2 (ch, AFF_CREEP))
return;

if (number_percent () < get_skill (ch, gsn_creep))
{
check_improve (ch, gsn_creep, TRUE, 3);
af.where = TO_AFFECTS;
af.type = gsn_creep;
af.level = ch->level;
af.duration = ch->level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CREEP;
affect_to_char (ch, &af);
}
else
check_improve (ch, gsn_creep, FALSE, 3);

return;
}


const.c:
{
"creep", {53, 53, 4, 10}, {0, 0, 4, 6},
spell_null, TAR_IGNORE, POS_STANDING,
&gsn_creep, SLOT (0), 0, 12,
"", "Your movement becomes more noticeable.", ""},


db.c:
sh_int gsn_creep;


handler.c:
//in 'int get_skill'

else if (sn == gsn_creep || sn == gsn_camoflague)
skill = ch->level * 2 + 20;

//and further down
//in 'char *affect2_bit_name'

if (vector & AFF_CREEP)
strcat (buf, " creep");


interp.c:
{"creep",	do_creep, POS_STANDING, 0, LOG_NORMAL, 1},


tables.c:
//in 'const struct flag_type affect2_flags'

{"creep", C, TRUE},


Sorry, I'm just completely stuck with this.
17 Mar, 2009, David Haley wrote in the 12th comment:
Votes: 0
Quote
affect_to_char (ch, &af);

That's your problem, you're adding it using the function that only knows about the first set of effect lists, not your affected2 stuff.
17 Mar, 2009, boblinski wrote in the 13th comment:
Votes: 0
Alright, so what do I have to change? do I need to add something for:

Quote
affect_to_char (ch, &af2);


I don't remember adding anything about af2 when I added affect2…
17 Mar, 2009, Sharmair wrote in the 14th comment:
Votes: 0
David Haley said:
Quote
affect_to_char (ch, &af);

That's your problem, you're adding it using the function that only knows about the first set of effect lists, not your affected2 stuff.

Actually, I am not really sure he has a 2nd list. None if the code he has shown, other then his is_affected2()
(which would not have compiled with other info he had given) indicate there is a 2nd list. And I really
don't see a need to have a 2nd list anyway.

It does seem he added a 2nd set of affected_by flags though. In the code he gave for do_creep, I don't
see where the affected2_by flags are even set. The affect struct he adds seems to actually set the
affected_by flag AFF_DETECT_EVIL (the flag in the same position as AFF_CREEP). This might explain
why his code uses direct REMOVE_BITs after stripping the effect. There probably should be a new
affect_data::where type for having the affect_data::bitvector work on the new affected2_by flag set.
I am not sure this is his only problem though.
17 Mar, 2009, boblinski wrote in the 15th comment:
Votes: 0
Sharmair said:
David Haley said:
Quote
affect_to_char (ch, &af);

That's your problem, you're adding it using the function that only knows about the first set of effect lists, not your affected2 stuff.

Actually, I am not really sure he has a 2nd list. None if the code he has shown, other then his is_affected2()
(which would not have compiled with other info he had given) indicate there is a 2nd list. And I really
don't see a need to have a 2nd list anyway.

It does seem he added a 2nd set of affected_by flags though. In the code he gave for do_creep, I don't
see where the affected2_by flags are even set. The affect struct he adds seems to actually set the
affected_by flag AFF_DETECT_EVIL (the flag in the same position as AFF_CREEP). This might explain
why his code uses direct REMOVE_BITs after stripping the effect. There probably should be a new
affect_data::where type for having the affect_data::bitvector work on the new affected2_by flag set.
I am not sure this is his only problem though.


*sighs*

Yup, it appears as though when I use the "creep" skill, even though it says "creep" in my affects, the character is actually affected by AFF_DETECT_EVIL.

Do you think I should start a thread about affect2, and post everything I've added, and see what more I need to implement?
18 Mar, 2009, Sharmair wrote in the 16th comment:
Votes: 0
It might help to know what all the snippet put in, but in this case I will just explain how the
effects in the affect_type list are handled and tell you what code SHOULD (and maybe was)
be added to handle the new flag set.

The affect_type struct is used on characters in the game to track changes (if any) a skill or
spell does for the duration of the skill/spell. A skill/spell may have more then one affect_type
struct if it changes a number of things. A single struct has two modes of tracking though,
it can track a flag set (bits to set on effect add, and removed on effect strip) and also an
apply. Almost all of the applies are just to change things like str, hp, damroll, saves etc
(though the APPLY_SPELL_AFFECT might be like the APPLY_WEARSPELL in SMAUG), but
in your case you are just using the APPLY_NONE, which means you are not using that mode,
if you were though, the data for the apply (in most cases the number of points to change)
would be in the affect_type::modifier member. The flag mode (what you are using in this
case) uses the affect_type::where and affect_type::bitvector members. The where part
tells the affect_modify() what flag set to modify with the bits in the bitvector part. When
you added the new flag set, you should have added a new #define in merc.h after the
struct affect_type definition,maybe something like:
#define TO_AFFECTS2  6

And basically any time you use the affect_type::bitvector member, some code to do
whatever (set/reset bits, list flag names etc) with the proper set of flags.
As an example, in the affect_modify() in handler.c, in the first switch statement you might
have something like:
case TO_AFFECTS2:
SET_BIT(ch->affected2_by, paf->bitvector);
break;

You might already have this code (maybe using different names) and only have to change
the setup in your code to something like:
af.where = TO_AFFECTS2;


As a note here, I am not so sure putting something like SMAUGs extended bitvectors in
would be any more difficult (I have a trick that makes a change over take less coding with
respect to the code for existing flags) then what you are doing, and in this case would be
a conceptually better solution.
18 Mar, 2009, David Haley wrote in the 17th comment:
Votes: 0
Sharmair said:
None if the code he has shown, other then his is_affected2()
(which would not have compiled with other info he had given) indicate there is a 2nd list. And I really
don't see a need to have a 2nd list anyway.

Well, I was going off of the is_affected2 code. And no, I definitely don't see the need for a second list.

FWIW though that isn't the problem I was talking about in what you replied to. He was using a function that is only aware of one kind of effects, not the other using his new bitvector.
0.0/17