Summon Spell (w/answer) [by Mark Gerritsen]
Snippet Posted Wednesday, August 12th @ 11:37:49 PM, by George Greer in the Skills dept.
Added Jul 6, 1998. Click the link below to read it or download it.

From: Mark Gerritsen <m.p.h.gerritsen@student.utwente.nl>
Subject: Summon/Answer snippet

This is an alternative to the summon spell. If you summon someone, they
get informed of who summoned them and from where, and they can choose
whether or not to answer the summon. The way I did it here, when imm+
summon someone of lower level, they can't refuse, but that's easy to
change. The casting of the spell still works the same, but the victim gets
a message like:  "Havoc is summoning you from Hav's Playground."  They
then have about 2 minutes to answer the summon before it runs out.  This
is controlled by the duration value, and can be longer or shorter too, if
wanted. Summons also wear off if the victim or caster die or leave the
game. If the victim answers, (s)he's transported to the room the caster
was in when the spell was cast.  A victim can be summoned by more players
at a time, but only once per player (at a time). If the same spellcaster
summons you again, the previous spell is overruled. Answering goes by name
of the caster: "answer Havoc".


--- In structs.h, under:
/* Structure used for chars following other chars */
struct follow_type {
   struct char_data *follower;
   struct follow_type *next;
};

--- Add:
/* Structure used for summoning */
struct summon_type {
   struct char_data *summoner;
   room_rnum dest_room;
   int duration;
   struct summon_type *next;
};

--- And under:
   struct char_data *master;             /* Who is char following?        */

--- Add:
   struct summon_type *summoners;       /* List of chars summoning      */


---In spells.c, replace the existing ASPELL(spell_summon) with this one:
ASPELL(spell_summon)
{
  struct summon_type *i, *temp = NULL;

  if (ch == NULL || victim == NULL)
    return;

  if ((GET_LEVEL(ch) >= LVL_IMMORT) && (GET_LEVEL(ch) > GET_LEVEL(victim))) {
    act("$n disappears suddenly.", TRUE, victim, 0, 0, TO_ROOM);
    char_from_room(victim);
    char_to_room(victim, ch->in_room);
    act("$n arrives suddenly.", TRUE, victim, 0, 0, TO_ROOM);
    act("$n has summoned you!", FALSE, ch, 0, victim, TO_VICT);
    look_at_room(victim, 0);
    return;
  }
  for (i = victim->summoners; i; i = i->next) {
    if (i->summoner == ch) {
      REMOVE_FROM_LIST(i, victim->summoners, next);
    }
  }
  CREATE(temp, struct summon_type, 1);
  temp->summoner = ch;
  temp->dest_room = ch->in_room;
  temp->duration = 2;
  temp->next = victim->summoners;
  victim->summoners = temp;
  sprintf(buf, "$n is summoning you from %s.", world[ch->in_room].name);
  act(buf, FALSE, ch, 0, victim, TO_VICT);
}


--- In magic.c, for example under affect_update, add:
void summon_update(void)
{
  struct char_data *i;
  struct summon_type *j, *temp, *next_in_list;

  for (i = character_list; i; i = i->next) {
    for (j = i->summoners; j; j = j->next) {
      next_in_list = j->next;
      j->duration -= 1;
      if (j->duration == 0) {
        REMOVE_FROM_LIST(j, i->summoners, next);
        free(j);
      }
    }
  }
}

void remove_summon(struct char_data *ch)
{
  struct char_data *i;
  struct summon_type *j, *temp, *next_in_list;

  for (i = character_list; i; i = i->next) {
    for (j = i->summoners; j; j = j->next) {
      next_in_list = j->next;
      if (ch == j->summoner) {
        REMOVE_FROM_LIST(j, i->summoners, next);
        free(j);
      }
    }
  }
  for (j = ch->summoners; j; j = next_in_list) {
    next_in_list = j->next;
    REMOVE_FROM_LIST(j, ch->summoners, next);
    free(j);
  }
}


--- In comm.c, with the external functions, add:
void summon_update(void);       /* In spells.c */

--- then in heartbeat, under:
    affect_update();

--- add:
    summon_update();


--- In handler.c, with the external functions, add:
void remove_summon(struct char_data *ch);

--- then in extract_char, under:
  char_from_room(ch);

--- add:
  remove_summon(ch);


--- At the bottom of act.other.c, add:
ACMD(do_answer)
{
  struct summon_type *i, *temp;
  struct char_data *vict;
  int found = 0, exact = 0, matches = 0;

  one_argument(argument, arg);

  if (!*arg) {
    act("Answer who?", TRUE, ch, 0, 0, TO_CHAR);
    return;
  }
  vict = get_char_vis(ch, arg);
  if (!vict) {
    act(NOPERSON, TRUE, ch, 0, 0, TO_CHAR);
    return;
  }
  if (vict == ch) {
    act("You can't summon yourself!", TRUE, ch, 0, 0, TO_CHAR);
    return;
  }
  for (i = ch->summoners; i; i = i->next) {
    if ((i->summoner) == vict) {
      found = 1;
      act("$n disappears suddenly.", TRUE, ch, 0, 0, TO_ROOM);
      char_from_room(ch);
      char_to_room(ch, i->dest_room);
      act("$n arrives suddenly.", TRUE, ch, 0, 0, TO_ROOM);
      sprintf(buf, "Summon by %s answered!", GET_NAME(vict));
      act(buf, TRUE, ch, 0, 0, TO_CHAR);
      look_at_room(ch, 0);
      REMOVE_FROM_LIST(i, ch->summoners, next);
      free(i);
      break;
    }
  }
  if (found == 0) {
    sprintf(buf, "%s doesn't have a summon pending for you.", GET_NAME(vict));
    act(buf, TRUE, ch, 0, 0, TO_CHAR);
  }
}


--- And finally, in interpreter.c, with all the other ACMDs, add:
ACMD(do_answer);

--- and in the command list:
  { "answer"   , POS_STUNNED , do_answer   , 0, 0 },


After all this PRF_NOSUMMON only has use for preventing yourself from being
charmed. Note I didn't put in any checks for summoning (possibly agressive)
mobs either. They could probably be charmed and ordered to answer summons,
so if you need it, add a check in ASPELL(spell_summon).

Enjoy & happy coding,

Havoc of Dagmarck (Mark Gerritsen)



<< Summon Mob Spell [by Fili] | Reply | View as text | Flattened | Teleport Spell [by Franco] >>

 


Related Links
  download
Related Articles
More by greerga
 
 

CircleMUD Snippets
 
Note: Not all of these snippets will work perfectly with your version of code, so be prepared to fix one or two bugs that may arise, and please let me know what you needed to do to fix it. Sending a corrected version is always welcome.
Finally, if you wish to use any of the snippets from this page, you are more than welcome, just mention the authors in your credits. If you wish to release any of these snippets to the public on another site, contact me FIRST.