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