/******************************************************************************* Save this file to your ./src directory, and if necessary, add zoom.o to your Makefile. Now, follow the rest of these instructions... -------------------------------------------------------------------------merc.h- Add this with your other maxes: #define MAX_ZOOM 21 Now, add this to struct pc_data: bool can_zoom[MAX_ZOOM]; Add this with your other GSNs: extern sh_int gsn_zoom; ------------------------------------------------------------------------magic.h- Add this to the bottom of the file. DECLARE_SPELL_FUN( spell_zoom ); ------------------------------------------------------------------------const.c- Add this to your skill table. { "zoom", {25, 30, 40, 50}, {2, 3, 4, 4}, spell_zoom, TAR_IGNORE, POS_STANDING, &gsn_zoom, SLOT (0), 10, 12, "", "!Zoom!", ""}, ---------------------------------------------------------------------act_move.c- At the top, add this: extern int zoom_vnum[MAX_ZOOM]; extern char * const zoom_name[MAX_ZOOM]; In the function move_char(), after the char_to_room() call: if (!IS_NPC(ch)) { char buf[MSL]; int i; for (i = 0; i < MAX_ZOOM; i++) { if (zoom_vnum[i] == ch->in_room->vnum && !ch->pcdata->can_zoom[i] && get_skill (ch, gsn_zoom) > 0) { ch->pcdata->can_zoom[i] = TRUE; sprintf (buf, "You have discovered a new Zoom" " location to: %s!\n\r", zoom_name[i]); send_to_char (buf, ch); break; } } } -------------------------------------------------------------------------save.c- Tind this bit of code in fwrite_char(): if (IS_NPC (ch)) { fprintf (fp, "Vnum %d\n", ch->pIndexData->vnum); } else { Anywhere within that else statement, add this block of code: fprintf (fp, "Zoom"); for (i = 0; i < MAX_ZOOM; i++) fprintf (fp, " %d", ch->pcdata->can_zoom[i]); fprintf (fp, "\n"); Now, in fread_char(), create a 'Z' case: case 'Z': if (!str_cmp (word, "Zoom")) { int zoom; for (zoom = 0; zoom < MAX_ZOOM; zoom++) ch->pcdata->can_zoom[zoom] = fread_number (fp); fMatch = TRUE; break; } break; ---------------------------------------------------------------------------db.c- Add this to your other GSNs: sh_int gsn_zoom; -------------------------------------------------------------------------------- If you followed those instructions, everything should be working. Go ahead and cut off these instructions, you're done. Here is a default helpfile, if you don't wish to write your own: -1 'ZOOM'~ Syntax: cast 'zoom' <place> The Zoom spell will instantly take you to a number of predefined places, if you've visited them in the past. When you find a new Zoom target, you will be notified. But be warned; no matter how hard your head, you can't fly through the ceiling. ~ *******************************************************************************/ /*************************************************************************** * You may use this code as you see fit within any non-commercial MUD. * * My only conditions are that my comments remain in tact, that you do not * * hesitate to give me feedback on the code, and that you don't claim my * * work as your own. Enjoy. . -- Midboss * * *********************************************************************** * * "Zoom" spell for instant transportation to predefined locations. * ***************************************************************************/ #include <stdio.h> #include <string.h> #include "merc.h" #include "interp.h" /* * Comment this out if you want the spell to only transport the user. */ #define GROUP /* * From magic.c. */ extern char *target_name; /* * The zoom location stuff. It's set up for the stock ROM areas, so adjust * the values to fit your MUD's world. */ char * const zoom_name[MAX_ZOOM] = { "Midgaard", "New Thalos", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }; int zoom_vnum[MAX_ZOOM] = { 3001, 9506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int zoom_cost[MAX_ZOOM] = { 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* * The 'zoom' spell. It will take a player (or his group) to an area of his * or her choosing, but only to a predefined vnum within that area, and only * to specific areas. Additionally, the player must have been to the area at * least once before to zoom to it. */ void spell_zoom (int sn, int level, CHAR_DATA * ch, void *vo, int target) { #ifdef GROUP CHAR_DATA * gch, * gch_next; #endif int i, where = -1; int members = 1; ROOM_INDEX_DATA * to_room, * was_in; if (IS_NPC (ch)) { send_to_char ("Your spell fizzled.\n\r", ch); return; } /* * Let's see if we can find a location. */ for (i = 0; i < MAX_ZOOM; i++) { if ((ch->pcdata->can_zoom[i] || IS_IMMORTAL (ch)) && !str_prefix (target_name, zoom_name[i])) { where = i; break; } } to_room = get_room_index (zoom_vnum[where]); was_in = ch->in_room; /* * Make sure there was a proper argument, a location was found, the * destination room isn't NULL, and we aren't zooming in a circle. */ if (target_name[0] == '\0' || where == -1 || to_room == NULL || to_room == was_in) { /* * Hit Z or R twice! */ act ("You fly into the air and do a barrel roll.", ch, NULL, NULL, TO_CHAR); act ("$n flies into the air and does a barrel roll.", ch, NULL, NULL, TO_ROOM); return; } /* * Make sure the character has enough MP. Checks for other members, * if needed. */ #ifdef GROUP for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) if (is_same_group (gch, ch) && gch != ch) ++members; #endif if (ch->mana < members * zoom_cost[where]) { ch->mana = 0; act ("You fly about aimlessly for a moment," " and forget where you were going.", ch, NULL, NULL, TO_CHAR); act ("You flies about aimlessly for a moment.", ch, NULL, NULL, TO_CHAR); return; } /* * Deduct the mana cost. */ ch->mana = UMAX (0, ch->mana - members * zoom_cost[where]); /* * We can't fly through the ceiling, can we? */ if (!IS_SET(ch->in_room->room_flags, ROOM_INDOORS)) { act ("You zoom head-first into the ceiling!", ch, NULL, NULL, TO_CHAR); act ("$n zooms head-first into the ceiling!", ch, NULL, NULL, TO_ROOM); ch->hit = UMAX (1, ch->hit - (ch->max_hit * 5 / 100)); return; } /* * Now transport the character, and if necessary, his or her party. */ act ("You hover in the air for a second, then zoom into the sky.", ch, NULL, NULL, TO_CHAR); act ("$n hovers in the air for a second, then zooms into the sky.", ch, NULL, NULL, TO_ROOM); char_from_room (ch); char_to_room (ch, to_room); act ("$n suddenly descends from the sky and lands.", ch, NULL, NULL, TO_ROOM); do_function (ch, &do_look, "auto"); #ifdef GROUP for (gch = was_in->people; gch != NULL; gch = gch_next) { gch_next = gch->next_in_room; if (is_same_group (gch, ch) && gch != ch) { act ("You zoom into the sky after $N.", gch, NULL, ch, TO_CHAR); act ("$n zooms into the sky after $N.", gch, NULL, ch, TO_ROOM); char_from_room (gch); char_to_room (gch, to_room); act ("$n suddenly descends from the sky and lands.", gch, NULL, NULL, TO_ROOM); do_function (gch, &do_look, "auto"); } } #endif return; } /* * Simple command to list all known zoom locations. If you want your * MUD's users to have access to it, remember to add the command entry * and declaration to interp.c and interp.h respectively. */ void do_zoomlist (CHAR_DATA * ch, char * argument) { char buf[MSL]; int i, show = 0; if (IS_NPC (ch)) return; if (get_skill (ch, gsn_zoom) < 1) { send_to_char ("Huh?\n\r", ch); return; } buf[0] = '\0'; for (i = 0; i < MAX_ZOOM; i++) { if ((IS_IMMORTAL (ch) || ch->pcdata->can_zoom[i]) && zoom_name[i][0] != '\0') { ++show; sprintf (buf + strlen (buf), "%-25s %3dmp%s", zoom_name[i], zoom_cost[i], show % 2 == 0 ? "\n\r" : " "); } } if (show < 1) { send_to_char ("You know of no Zoom locations.\n\r", ch); return; } send_to_char ("You know of the following Zoom locations:\n\r", ch); send_to_char (buf, ch); }