Code:
diff --git a/src/act.movement.c b/src/act.movement.c
index a5a8e1d..b84a4ad 100644
--- a/src/act.movement.c
+++ b/src/act.movement.c
@@ -109,52 +109,35 @@ int has_scuba(struct char_data *ch)
return (0);
}
-
-/** 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
+/**
+ * performs all needed checks for seeing if a character may move from one room to another.
*
- * @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)
+ * move into. If this is negative, use the passed command number for specials check.
+ * @param was_in room number we're leaving.
+ * @param going_to room number we want to enter.
+ * @param need_specials_check If TRUE will cause check of special function.
+ * @param special_command command number for specials check.
+ * @retval int 1 if allowed to move, 0 otherwise.
+ *
+ */
+static int can_leave(struct char_data *ch, int dir, room_rnum was_in, room_rnum going_to,
+ int need_specials_check, int special_command)
{
/* 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. */
+ /* 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').
+ * also might prevent the movement.
* Note -- only check if following; this avoids 'double spec-proc' bug */
- if (need_specials_check && special(ch, dir + 1, spec_proc_args))
+ if (need_specials_check && special(ch, special_command, spec_proc_args))
return 0;
/* Leave Trigger Checks: Does a leave trigger block exit from the room? */
@@ -245,6 +228,103 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check)
send_to_char(ch, "You aren't godly enough to use that room!\r\n");
return (0);
}
+ return 1;
+}
+
+static int allow_move_post_checks(struct char_data *ch, int dir, room_rnum was_in, room_rnum going_to)
+{
+ /* 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_LEVEL(ch) < LVL_IMMORT)
+ {
+ mudlog(BRF, LVL_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);
+
+}
+
+/** 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)
+{
+ /* 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 */
+
+ /*
+ * 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').
+ */
+
+ if (!can_leave(ch, dir, was_in, going_to, need_specials_check, dir+1)) {
+ return 0;
+ }
+
/* All checks passed, nothing will prevent movement now other than lack of
* move points. */
@@ -285,56 +365,7 @@ int do_simple_move(struct char_data *ch, int dir, int need_specials_check)
/*---------------------------------------------------------------------*/
/* 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_LEVEL(ch) < LVL_IMMORT)
- {
- mudlog(BRF, LVL_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);
+ return allow_move_post_checks(ch, dir, was_in, going_to);
}
int perform_move(struct char_data *ch, int dir, int need_specials_check)
@@ -673,15 +704,67 @@ ACMD(do_gen_door)
return;
}
+static void perform_enter_portal(struct char_data *ch, struct obj_data *obj)
+{
+ room_rnum going_to = real_room(GET_OBJ_VAL(obj, 1));
+ room_rnum was_in = IN_ROOM(ch);
+
+ int need_movement = 10;
+ if (going_to == NOWHERE) {
+ send_to_char(ch, "You jump straight through the portal, going nowhere.\r\n");
+ return;
+ }
+ if (!can_leave(ch, -1, was_in, going_to, TRUE, find_command("enter"))) {
+ return;
+ }
+
+ /* Move Point Requirement Check */
+ if (GET_MOVE(ch) < need_movement && !IS_NPC(ch))
+ {
+ send_to_char(ch, "You are too exhausted.\r\n");
+ return;
+ }
+
+
+ /* Begin: the leave operation. */
+ /*---------------------------------------------------------------------*/
+ /* If applicable, subtract movement cost. */
+ if (GET_LEVEL(ch) < LVL_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))
+ {
+ act("$n enters a shimmering portal and disappears.", TRUE, ch, 0, 0, TO_ROOM);
+ }
+ send_to_char(ch, "You enter the portal.\r\n");
+
+ char_from_room(ch);
+ char_to_room(ch, going_to);
+ /*---------------------------------------------------------------------*/
+ /* End: the leave operation. The character is now in the new room. */
+
+ allow_move_post_checks(ch, -1, was_in, going_to);
+}
+
ACMD(do_enter)
{
char buf[MAX_INPUT_LENGTH];
+ char *tmp = buf;
int door;
+ struct obj_data *obj;
one_argument(argument, buf);
- if (*buf) { /* an argument was supplied, search for door
- * keyword */
+ if (*buf) {
+ int number = get_number(&tmp);
+ /* an argument was supplied, search for door keyword */
+ if ((obj = get_obj_in_list_vis(ch, buf, &number, world[IN_ROOM(ch)].contents))
+ && CAN_SEE_OBJ(ch, obj)
+ && GET_OBJ_VNUM(obj) == PORTAL_VNUM) {
+ perform_enter_portal(ch, obj);
+ return;
+ }
for (door = 0; door < DIR_COUNT; door++)
if (EXIT(ch, door))
if (EXIT(ch, door)->keyword)
Something worth trying might be to add a chance for the target to "sense the spell" so it would be comparatively harder to portal to a high level mob. Anyway, it's not covered this time around