From: Mark Gerritsen 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)