/* this function takes a real number for a room and returns: FALSE - mortals shouldn't be able to teleport to this destination TRUE - mortals CAN teleport to this destination * accepts NULL ch data */ int valid_mortal_tele_dest(struct char_data *ch, room_rnum dest, bool dim_lock) { if (dest == NOWHERE) return FALSE; if (IS_AFFECTED(ch, AFF_DIM_LOCK) && dim_lock) return FALSE; /* this function needs a vnum, not rnum */ if (ch && !House_can_enter(ch, GET_ROOM_VNUM(dest))) return FALSE; if (ZONE_FLAGGED(GET_ROOM_ZONE(dest), ZONE_NOASTRAL)) return FALSE; if (ROOM_FLAGGED(dest, ROOM_PRIVATE)) return FALSE; if (ROOM_FLAGGED(dest, ROOM_DEATH)) return FALSE; if (ROOM_FLAGGED(dest, ROOM_GODROOM)) return FALSE; if (ZONE_FLAGGED(GET_ROOM_ZONE(dest), ZONE_CLOSED)) return FALSE; if (ZONE_FLAGGED(GET_ROOM_ZONE(dest), ZONE_NOASTRAL)) return FALSE; //passed all tests! return TRUE; }
bool show_worldmap(struct char_data *ch) { room_rnum rm = IN_ROOM(ch); zone_rnum zn = GET_ROOM_ZONE(rm); if (ROOM_FLAGGED(rm, ROOM_WORLDMAP)) return TRUE; if (ZONE_FLAGGED(zn, ZONE_WORLDMAP)) return TRUE; return FALSE; }
/** Move a PC/NPC character from their current location to a new location. This * is the standard movement locomotion function that all normal walking * movement by characters should be sent through. This function also defines * the move cost of normal locomotion as: * ( (move cost for source room) + (move cost for destination) ) / 2 * * @pre Function assumes that ch has no master controlling character, that * ch has no followers (in other words followers won't be moved by this * function) and that the direction traveled in is one of the valid, enumerated * direction. * @param ch The character structure to attempt to move. * @param dir The defined direction (NORTH, SOUTH, etc...) to attempt to * move into. * @param need_specials_check If TRUE will cause * @retval int 1 for a successful move (ch is now in a new location) * or 0 for a failed move (ch is still in the original location). */ int do_simple_move(struct char_data *ch, int dir, int need_specials_check) { /* Begin Local variable definitions */ /*---------------------------------------------------------------------*/ /* Used in our special proc check. By default, we pass a NULL argument * when checking for specials */ char spec_proc_args[MAX_INPUT_LENGTH] = ""; /* The room the character is currently in and will move from... */ room_rnum was_in = IN_ROOM(ch); /* ... and the room the character will move into. */ room_rnum going_to = EXIT(ch, dir)->to_room; /* How many movement points are required to travel from was_in to going_to. * We redefine this later when we need it. */ int need_movement = 0; /* Contains the "leave" message to display to the was_in room. */ char leave_message[SMALL_BUFSIZE]; /*---------------------------------------------------------------------*/ /* End Local variable definitions */ /* Begin checks that can prevent a character from leaving the was_in room. */ /* Future checks should be implemented within this section and return 0. */ /*---------------------------------------------------------------------*/ /* Check for special routines that might activate because of the move and * also might prevent the movement. Special requires commands, so we pass * in the "command" equivalent of the direction (ie. North is '1' in the * command list, but NORTH is defined as '0'). * Note -- only check if following; this avoids 'double spec-proc' bug */ if (need_specials_check && special(ch, dir + 1, spec_proc_args)) return 0; /* Leave Trigger Checks: Does a leave trigger block exit from the room? */ if (!leave_mtrigger(ch, dir) || IN_ROOM(ch) != was_in) /* prevent teleport crashes */ return 0; if (!leave_wtrigger(&world[IN_ROOM(ch)], ch, dir) || IN_ROOM(ch) != was_in) /* prevent teleport crashes */ return 0; if (!leave_otrigger(&world[IN_ROOM(ch)], ch, dir) || IN_ROOM(ch) != was_in) /* prevent teleport crashes */ return 0; /* Charm effect: Does it override the movement? */ if (AFF_FLAGGED(ch, AFF_CHARM) && ch->master && was_in == IN_ROOM(ch->master)) { send_to_char(ch, "The thought of leaving your master makes you weep.\r\n"); act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM); return (0); } /* Water, No Swimming Rooms: Does the deep water prevent movement? */ if ((SECT(was_in) == SECT_WATER_NOSWIM) || (SECT(going_to) == SECT_WATER_NOSWIM)) { if (!has_boat(ch)) { send_to_char(ch, "You need a boat to go there.\r\n"); return (0); } } /* Flying Required: Does lack of flying prevent movement? */ if ((SECT(was_in) == SECT_FLYING) || (SECT(going_to) == SECT_FLYING)) { if (!has_flight(ch)) { send_to_char(ch, "You need to be flying to go there!\r\n"); return (0); } } /* Underwater Room: Does lack of underwater breathing prevent movement? */ if ((SECT(was_in) == SECT_UNDERWATER) || (SECT(going_to) == SECT_UNDERWATER)) { if (!has_scuba(ch) && !IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_NOHASSLE)) { send_to_char(ch, "You need to be able to breathe water to go there!\r\n"); return (0); } } /* Houses: Can the player walk into the house? */ if (ROOM_FLAGGED(was_in, ROOM_ATRIUM)) { if (!House_can_enter(ch, GET_ROOM_VNUM(going_to))) { send_to_char(ch, "That's private property -- no trespassing!\r\n"); return (0); } } /* Check zone level recommendations */ if ((ZONE_MINLVL(GET_ROOM_ZONE(going_to)) != -1) && ZONE_MINLVL(GET_ROOM_ZONE(going_to)) > GET_LEVEL(ch)) { send_to_char(ch, "This zone is above your recommended level.\r\n"); } /* Check zone flag restrictions */ if (ZONE_FLAGGED(GET_ROOM_ZONE(going_to), ZONE_CLOSED)) { send_to_char(ch, "A mysterious barrier forces you back! That area is off-limits.\r\n"); return (0); } if (ZONE_FLAGGED(GET_ROOM_ZONE(going_to), ZONE_NOIMMORT) && (GET_ADMLEVEL(ch) >= ADMLVL_IMMORT) && (GET_ADMLEVEL(ch) < ADMLVL_GRGOD)) { send_to_char(ch, "A mysterious barrier forces you back! That area is off-limits.\r\n"); return (0); } /* Room Size Capacity: Is the room full of people already? */ if (ROOM_FLAGGED(going_to, ROOM_TUNNEL) && num_pc_in_room(&(world[going_to])) >= CONFIG_TUNNEL_SIZE) { if (CONFIG_TUNNEL_SIZE > 1) send_to_char(ch, "There isn't enough room for you to go there!\r\n"); else send_to_char(ch, "There isn't enough room there for more than one person!\r\n"); return (0); } /* Room Level Requirements: Is ch privileged enough to enter the room? */ if (ROOM_FLAGGED(going_to, ROOM_GODROOM) && GET_ADMLEVEL(ch) < ADMLVL_GOD) { send_to_char(ch, "You aren't godly enough to use that room!\r\n"); return (0); } /* All checks passed, nothing will prevent movement now other than lack of * move points. */ /* move points needed is avg. move loss for src and destination sect type */ need_movement = (movement_loss[SECT(was_in)] + movement_loss[SECT(going_to)]) / 2; /* Move Point Requirement Check */ if (GET_MOVE(ch) < need_movement && !IS_NPC(ch)) { if (need_specials_check && ch->master) send_to_char(ch, "You are too exhausted to follow.\r\n"); else send_to_char(ch, "You are too exhausted.\r\n"); return (0); } /*---------------------------------------------------------------------*/ /* End checks that can prevent a character from leaving the was_in room. */ /* Begin: the leave operation. */ /*---------------------------------------------------------------------*/ /* If applicable, subtract movement cost. */ if (GET_ADMLEVEL(ch) < ADMLVL_IMMORT && !IS_NPC(ch)) GET_MOVE(ch) -= need_movement; /* Generate the leave message and display to others in the was_in room. */ if (!AFF_FLAGGED(ch, AFF_SNEAK)) { snprintf(leave_message, sizeof(leave_message), "$n leaves %s.", dirs[dir]); act(leave_message, TRUE, ch, 0, 0, TO_ROOM); } char_from_room(ch); char_to_room(ch, going_to); /*---------------------------------------------------------------------*/ /* End: the leave operation. The character is now in the new room. */ /* Begin: Post-move operations. */ /*---------------------------------------------------------------------*/ /* Post Move Trigger Checks: Check the new room for triggers. * Assumptions: The character has already truly left the was_in room. If * the entry trigger "prevents" movement into the room, it is the triggers * job to provide a message to the original was_in room. */ if (!entry_mtrigger(ch) || !enter_wtrigger(&world[going_to], ch, dir)) { char_from_room(ch); char_to_room(ch, was_in); return 0; } /* Display arrival information to anyone in the destination room... */ if (!AFF_FLAGGED(ch, AFF_SNEAK)) act("$n has arrived.", TRUE, ch, 0, 0, TO_ROOM); /* ... and the room description to the character. */ if (ch->desc != NULL) look_at_room(ch, 0); /* ... and Kill the player if the room is a death trap. */ if (ROOM_FLAGGED(going_to, ROOM_DEATH) && GET_ADMLEVEL(ch) < ADMLVL_IMMORT) { mudlog(BRF, ADMLVL_IMMORT, TRUE, "%s hit death trap #%d (%s)", GET_NAME(ch), GET_ROOM_VNUM(going_to), world[going_to].name); death_cry(ch); extract_char(ch); return (0); } /* At this point, the character is safe and in the room. */ /* Fire memory and greet triggers, check and see if the greet trigger * prevents movement, and if so, move the player back to the previous room. */ entry_memory_mtrigger(ch); if (!greet_mtrigger(ch, dir)) { char_from_room(ch); char_to_room(ch, was_in); look_at_room(ch, 0); /* Failed move, return a failure */ return (0); } else greet_memory_mtrigger(ch); /*---------------------------------------------------------------------*/ /* End: Post-move operations. */ /* Only here is the move successful *and* complete. Return success for * calling functions to handle post move operations. */ return (1); }