Portal spell help

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago #6859 by JTP
Portal spell help was created by JTP
Hi, anyone able to get this old circlemud snippet working with tba ?
Make appropriate spell define.


spell_parser.c
--------------
case SPELL_PORTAL:              MANUAL_SPELL(spell_portal); break;

spello(SPELL_PORTAL, 150, 100, 5, POS_STANDING,
       TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL);



spells.c
--------
ASPELL(spell_portal)
{
  /* create a magic portal */
  struct obj_data *tmp_obj, *tmp_obj2;
  struct extra_descr_data *ed;
  struct room_data *rp, *nrp;
  struct char_data *tmp_ch = (struct char_data *) victim;
  char buf[512];

  assert(ch);
  assert((level >= 0) && (level <= LVL_IMPL));


  /*
    check target room for legality.
   */
  rp = &world[ch->in_room];
  tmp_obj = read_object(PORTAL, VIRTUAL);
  if (!rp || !tmp_obj) {
    send_to_char("The magic fails\n\r", ch);
    extract_obj(tmp_obj);
    return;
  }
  if (IS_SET(rp->room_flags, ROOM_TUNNEL)) {
    send_to_char("There is no room in here to summon!\n\r", ch);
    extract_obj(tmp_obj);
    return;
  }

  if (!(nrp = &world[tmp_ch->in_room])) {
    char str[180];
    sprintf(str, "%s not in any room", GET_NAME(tmp_ch));
    log(str);
    send_to_char("The magic cannot locate the target\n", ch);
    extract_obj(tmp_obj);
    return;
  }

  if (ROOM_FLAGGED(tmp_ch->in_room, ROOM_NOMAGIC)) {
    send_to_char("Your target is protected against your magic.\n\r", ch);
    extract_obj(tmp_obj);
    return;
  }

  sprintf(buf, "Through the mists of the portal, you can faintly see %s",nrp->n
ame);

  CREATE(ed , struct extra_descr_data, 1);
  ed->next = tmp_obj->ex_description;
  tmp_obj->ex_description = ed;
  CREATE(ed->keyword, char, strlen(tmp_obj->name) + 1);
  strcpy(ed->keyword, tmp_obj->name);
  ed->description = str_dup(buf);

  tmp_obj->obj_flags.value[0] = 1;
  tmp_obj->obj_flags.value[1] = tmp_ch->in_room;
  obj_to_room(tmp_obj,ch->in_room);

  act("$p suddenly appears.",TRUE,ch,tmp_obj,0,TO_ROOM);
  act("$p suddenly appears.",TRUE,ch,tmp_obj,0,TO_CHAR);

/* Portal at other side */
   rp = &world[ch->in_room];
   tmp_obj2 = read_object(PORTAL, VIRTUAL);
   if (!rp || !tmp_obj2) {
     send_to_char("The magic fails\n\r", ch);
     extract_obj(tmp_obj2);
     return;
   }
  sprintf(buf,"Through the mists of the portal, you can faintly see %s", rp->na
me);

  CREATE(ed , struct extra_descr_data, 1);
  ed->next = tmp_obj2->ex_description;
  tmp_obj2->ex_description = ed;
  CREATE(ed->keyword, char, strlen(tmp_obj2->name) + 1);
  strcpy(ed->keyword, tmp_obj2->name);
  ed->description = str_dup(buf);
  tmp_obj2->obj_flags.value[0] = 1;
  tmp_obj2->obj_flags.value[1] = ch->in_room;
  obj_to_room(tmp_obj2,tmp_ch->in_room);
  act("$p suddenly appears.", TRUE, tmp_ch, tmp_obj2, 0, TO_ROOM);
  act("$p suddenly appears.", TRUE, tmp_ch, tmp_obj2, 0, TO_CHAR);
}

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

More
10 months 1 week ago #6860 by thomas
Replied by thomas on topic Portal spell help
I assume you're talking about this spell: drive.google.com/open?id=0B40XbRH2Qbx5SWJCZzIzUlloeFU ? The code certainly looks similar.

It's been a while since I last actually tested my code - this seems to be working against the latest build:
diff --git a/src/act.movement.c b/src/act.movement.c
index a5a8e1d..1c242cf 100644
--- a/src/act.movement.c
+++ b/src/act.movement.c
@@ -676,12 +676,26 @@ ACMD(do_gen_door)
 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) {
+				  room_rnum target_room_rnum = real_room(GET_OBJ_VAL(obj, 1));
+				  if (target_room_rnum != NOWHERE) {
+					  char_from_room(ch);
+					  char_to_room(ch, target_room_rnum);
+					  look_at_room(ch, 1);
+					  return;
+				  }
+	  }
     for (door = 0; door < DIR_COUNT; door++)
       if (EXIT(ch, door))
         if (EXIT(ch, door)->keyword)
diff --git a/src/limits.c b/src/limits.c
index a79f8cb..bc3fe43 100644
--- a/src/limits.c
+++ b/src/limits.c
@@ -448,6 +448,17 @@ void point_update(void)
 	extract_obj(j);
       }
     }
+
+    else if (GET_OBJ_VNUM(j) == PORTAL_VNUM) {
+    	if (GET_OBJ_TIMER(j) > 0)
+				GET_OBJ_TIMER(j)--;
+			if (!GET_OBJ_TIMER(j)) {
+				act("A glowing portal fades from existance.",TRUE, world[j->in_room].people, j, 0, TO_ROOM);
+				act("A glowing portal fades from existance.", TRUE, world[j->in_room].people, j, 0, TO_CHAR);
+				extract_obj(j);
+			}
+    }
+
     /* If the timer is set, count it down and at 0, try the trigger
      * note to .rej hand-patchers: make this last in your point-update() */
     else if (GET_OBJ_TIMER(j)>0) {
diff --git a/src/spell_parser.c b/src/spell_parser.c
index 30510d4..0aa4e0b 100644
--- a/src/spell_parser.c
+++ b/src/spell_parser.c
@@ -277,6 +277,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
     case SPELL_SUMMON:		MANUAL_SPELL(spell_summon); break;
     case SPELL_WORD_OF_RECALL:  MANUAL_SPELL(spell_recall); break;
     case SPELL_TELEPORT:	MANUAL_SPELL(spell_teleport); break;
+    case SPELL_PORTAL:		MANUAL_SPELL(spell_portal); break;
     }
 
   return (1);
@@ -881,6 +882,9 @@ void mag_assign_spells(void)
 	MAG_AFFECTS | MAG_ALTER_OBJS,
 	"You feel less sick.");
 
+  spello(SPELL_PORTAL, "portal", 150, 100, 5, POS_STANDING,
+         TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, NULL);
+
   spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING,
 	TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
 	"You feel less protected.");
diff --git a/src/spells.c b/src/spells.c
index 1861408..c09b46a 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -448,3 +448,78 @@ ASPELL(spell_detect_poison)
     }
   }
 }
+
+ASPELL(spell_portal) {
+	/* create a magic portal */
+	struct obj_data *portal_obj;
+	struct extra_descr_data *extra_desc;
+	char buf[512];
+
+	assert(ch);
+	assert((level >= 0) && (level <= LVL_IMPL));
+
+	/*
+	 check target room for legality.
+	 */
+
+	portal_obj = read_object(PORTAL_VNUM, VIRTUAL);
+	if (IN_ROOM(ch) == NOWHERE || !portal_obj) {
+		send_to_char(ch, "The magic fails\r\n");
+		extract_obj(portal_obj);
+		return;
+	}
+	if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_TUNNEL)) {
+		send_to_char(ch, "There is no room in here to summon!\r\n");
+		extract_obj(portal_obj);
+		return;
+	}
+
+	if (IN_ROOM(victim) == NOWHERE) {
+		log("%s not in any room", GET_NAME(victim));
+		send_to_char(ch, "The magic cannot locate the target\n");
+		extract_obj(portal_obj);
+		return;
+	}
+
+	if (ROOM_FLAGGED(IN_ROOM(victim), ROOM_NOMAGIC)) {
+		send_to_char(ch, "Your target is protected against your magic.\r\n");
+		extract_obj(portal_obj);
+		return;
+	}
+
+	sprintf(buf, "Through the mists of the portal, you can faintly see %s",
+			world[IN_ROOM(victim)].name);
+
+	CREATE(extra_desc, struct extra_descr_data, 1);
+	extra_desc->next = portal_obj->ex_description;
+	portal_obj->ex_description = extra_desc;
+	CREATE(extra_desc->keyword, char, strlen(portal_obj->name) + 1);
+	strcpy(extra_desc->keyword, portal_obj->name);
+	extra_desc->description = strdup(buf);
+
+	portal_obj->obj_flags.timer = 2;
+	portal_obj->obj_flags.value[1] = world[IN_ROOM(victim)].number;
+	obj_to_room(portal_obj, IN_ROOM(ch));
+
+	act("$p suddenly appears.", TRUE, ch, portal_obj, 0, TO_ROOM);
+	act("$p suddenly appears.", TRUE, ch, portal_obj, 0, TO_CHAR);
+
+	/* Portal at other side */
+	portal_obj = read_object(PORTAL_VNUM, VIRTUAL);
+	sprintf(buf, "Through the mists of the portal, you can faintly see %s",
+			world[IN_ROOM(ch)].name);
+
+	CREATE(extra_desc, struct extra_descr_data, 1);
+	extra_desc->next = portal_obj->ex_description;
+	portal_obj->ex_description = extra_desc;
+	CREATE(extra_desc->keyword, char, strlen(portal_obj->name) + 1);
+	strcpy(extra_desc->keyword, portal_obj->name);
+	extra_desc->description = strdup(buf);
+
+	portal_obj->obj_flags.timer = 2;
+	portal_obj->obj_flags.value[1] = world[IN_ROOM(ch)].number;
+	obj_to_room(portal_obj, IN_ROOM(victim));
+
+	act("$p suddenly appears.", TRUE, victim, portal_obj, 0, TO_ROOM);
+	act("$p suddenly appears.", TRUE, victim, portal_obj, 0, TO_CHAR);
+}
diff --git a/src/spells.h b/src/spells.h
index c88c554..c5c63b4 100644
--- a/src/spells.h
+++ b/src/spells.h
@@ -15,6 +15,8 @@
 #define DEFAULT_STAFF_LVL	12
 #define DEFAULT_WAND_LVL	12
 
+#define PORTAL_VNUM 20
+
 #define CAST_UNDEFINED	(-1)
 #define CAST_SPELL	0
 #define CAST_POTION	1
@@ -93,8 +95,9 @@
 #define SPELL_IDENTIFY               52 /* Reserved Skill[] DO NOT CHANGE */
 #define SPELL_FLY                    53 /* Reserved Skill[] DO NOT CHANGE */
 #define SPELL_DARKNESS               54
+#define SPELL_PORTAL				 55
 /** Total Number of defined spells */
-#define NUM_SPELLS                   54
+#define NUM_SPELLS                   55
 
 /* Insert new spells here, up to MAX_SPELLS */
 #define MAX_SPELLS		    130
@@ -226,6 +229,7 @@ ASPELL(spell_information);
 ASPELL(spell_identify);
 ASPELL(spell_enchant_weapon);
 ASPELL(spell_detect_poison);
+ASPELL(spell_portal);
 
 /* basic magic calling functions */

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

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago - 10 months 1 week ago #6863 by JTP
Replied by JTP on topic Portal spell help
Wanted to restrict portal a bit:
  /* 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 ;
    }
  }

  /* 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;
  }
  /* Room Level Requirements: Is ch privileged enough to enter the room? */
  if (ROOM_FLAGGED(going_to, ROOM_GODROOM) && GET_LEVEL(ch) < LVL_GOD)
  {
    send_to_char(ch, "You aren't godly enough to use that room!\r\n");
    return;
  }
added to spell_portal:
ASPELL(spell_portal) {
        /* create a magic portal */
        struct obj_data *portal_obj;
        struct extra_descr_data *extra_desc;
        char buf[512];
+        int dir;

+        room_rnum was_in = IN_ROOM(ch);
+        room_rnum going_to = EXIT(ch, dir)->to_room;

But compiles gives me the following errors:
gcc -g -O2 -Wall    -c -o spells.o spells.c
spells.c: In function ‘spell_portal’:
spells.c:749: warning: ‘dir’ is used uninitialized in this function
gcc -o ../bin/circle  act.comm.o act.informative.o act.item.o act.movement.o act.offensive.o act.other.o act.social.o act.wizard.o aedit.o asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o clan.o class.o comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o genobj.o genolc.o genqst.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o house.o ibt.o improved-edit.o interpreter.o limits.o lists.o magic.o mail.o medit.o mobact.o modify.o msgedit.o mud_event.o oasis.o oasis_copy.o oasis_delete.o oasis_list.o objsave.o oedit.o players.o prefedit.o protocol.o qedit.o quest.o races.o random.o redit.o sedit.o shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o utils.o weather.o zedit.o zmalloc.o   -lcrypt
Last edit: 10 months 1 week ago by JTP.

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

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago #6864 by JTP
Replied by JTP on topic Portal spell help
This was in the patch and works.
        if (ROOM_FLAGGED(IN_ROOM(victim), ROOM_NOMAGIC)) {
                send_to_char(ch, "Your target is protected against your magic.\r\n");
                extract_obj(portal_obj);
                return;
        }

But this one still allows portal:
  /* Room Level Requirements: Is ch privileged enough to enter the room? */
  if (ROOM_FLAGGED(IN_ROOM(victim), ROOM_GODROOM) && GET_LEVEL(ch) < LVL_GOD) {
    send_to_char(ch, "You aren't godly enough to use that room!\r\n");
        extract_obj(portal_obj);
        return;
  }


I dont get it.

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

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago #6865 by JTP
Replied by JTP on topic Portal spell help
But need to restrict people from Going into People's houses and gloses zones to.

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

More
10 months 1 week ago #6866 by thomas
Replied by thomas on topic Portal spell help

Jan wrote:

This was in the patch and works.
        if (ROOM_FLAGGED(IN_ROOM(victim), ROOM_NOMAGIC)) {
                send_to_char(ch, "Your target is protected against your magic.\r\n");
                extract_obj(portal_obj);
                return;
        }

But this one still allows portal:
  /* Room Level Requirements: Is ch privileged enough to enter the room? */
  if (ROOM_FLAGGED(IN_ROOM(victim), ROOM_GODROOM) && GET_LEVEL(ch) < LVL_GOD) {
    send_to_char(ch, "You aren't godly enough to use that room!\r\n");
        extract_obj(portal_obj);
        return;
  }


I dont get it.

Have you tested it with a mortal?

I just tested your code with a level 1 magic user (had to alter the mana requirements a bit and add it to the learned spells list for mages) and I am forbidden from entering a godroom, just as you intended.

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

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago #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
10 months 1 week ago #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.
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.

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
10 months 1 week ago #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
10 months 1 week ago #6873 by thomas
Replied by thomas on topic Portal spell help
add a check for current room in the spell function
+	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:
  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: 2.148 seconds