Welcome to the Builder Academy

Question Portal spell help

More
08 Sep 2017 19:51 #6867 by JTP
Replied by JTP on topic Portal spell help
What about the check to restrict atriums and closed zones ? How Can We get that to work ?

Please Log in or Create an account to join the conversation.

More
08 Sep 2017 22:30 #6868 by thomas
Replied by thomas on topic Portal spell help
Actually, this is something we want to check when people use the portal, isn't it?
I've rewritten a bit of act.movement.c so we don't duplicate too much code.
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 :)

Please Log in or Create an account to join the conversation.

More
08 Sep 2017 23:39 #6872 by JTP
Replied by JTP on topic Portal spell help
Also just tested that if you cast portal on a mob/player in the same room your already in.

Spawns both portals to and from in the room.

How can that be prevented, so it will say your already there or something ?

Please Log in or Create an account to join the conversation.

More
08 Sep 2017 23:44 #6873 by thomas
Replied by thomas on topic Portal spell help
add a check for current room in the spell function
Code:
+ if (IN_ROOM(victim) == IN_ROOM(ch)) { + send_to_char(ch, "The portal fails to form! You're here already...\r\n"); + extract_obj(portal_obj); + return; + }

And yes, the patch above will preserve the checks for entering closed zones. I realize that there might be missing a check for house access, since you could portal past an atrium room and the code currently just checks for this situation - this would solve that:
Code:
if (!can_leave(ch, -1, was_in, going_to, TRUE, find_command("enter"))) { return; } + if (ROOM_FLAGGED(going_to, ROOM_HOUSE) && !House_can_enter(ch, GET_ROOM_VNUM(going_to))) { + send_to_char(ch, "private property!\r\n"); + 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; }

Please Log in or Create an account to join the conversation.

Time to create page: 0.215 seconds