The truly observant will have noticed by now that I am redoing the magic
system on my MUD. Something I came across recently is the following code in
mag_affects (magic.c) that checks whether a mob has been permanently assign an
affect before allowing a spell to assign the same affect. As explained in the
comment, this prevents players from casting a spell on a mob and then waiting
for it to wear off as a way of removing permanent affects from mobs.
This code presents a slight problem on my MUD in that I do not always have a 1
to 1 relationship between affects and spells. Some affects can be caused by
multiple spells. This code will fail a spell erroneously if a mob is affected
by the same affect from an earlier spell. I wrote the following code to
prevent this situation:
mag_affects, in magic.c:
const char *to_vict = NULL, *to_room = NULL;
int i;
+ long /*bitvector_t*/ all_affects = 0;
case SPELL_WATERWALK:
af[0].duration = 24;
af[0].bitvector = AFF_WATERWALK;
accum_duration = TRUE;
to_vict = "You feel webbing between your toes.";
break;
}
+
+ for (i = 0; i < MAX_SPELL_AFFECTS; i++)
+ all_affects |= af[i].bitvector;
- if (IS_NPC(victim) && !affected_by_spell(victim, spellnum))
+ if (IS_NPC(victim))
- for (i = 0; i < MAX_SPELL_AFFECTS; i++)
- if (AFF_FLAGGED(victim, af[i].bitvector)) {
+ if (permanent_affect(victim, all_affects)) {
send_to_char(NOEFFECT, ch);
return;
}
/*
* If the victim is already affected by this spell, and the spell does
* not have an accumulative effect, then fail the spell.
*/
- if (affected_by_spell(victim,spellnum) && !(accum_duration||accum_affect)) {
+ if (AFF_FLAGGED(victim, all_affects) && !(accum_duration || accum_affect)) {
send_to_char(NOEFFECT, ch);
return;
}
in handler.h:
+bool permanent_affect( const struct char_data *ch, long /*bitvector_t*/
bitvector);
in handler.c:
/* Returns true if any of the affects in bitvector are permanent */
+bool permanent_affect( const struct char_data *ch, long /*bitvector_t*/
bitvector) {
+ const struct affected_type *aff = ch->affected;
+ long /*bitvector_t*/ ret = bitvector & AFF_FLAGS(ch);
+
+ while (ret && aff) {
+ ret ^= ret & aff->bitvector;
+
+ aff = aff->next;
+ }
+
+ return (bool)ret;
+}
If you're using 64-bit bitvectors, replace "long" with "bitvector_t". Also
note that, with this change, you can still prevent the second spell from
working by setting accum_affect to FALSE.
Mike
--
+---------------------------------------------------------------+
| FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
| Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
+---------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/06/01 PST