Index: func_spec
===================================================================
--- func_spec	(Revision 2457)
+++ func_spec	(Arbeitskopie)
@@ -516,7 +516,7 @@
 mixed  *object_info(object, int, void|int);
 string  object_name(null|object default: F_THIS_OBJECT);
 int     object_time(object default: F_THIS_OBJECT);
-object  present_clone(object|string, object default: F_THIS_OBJECT); /* PRELIMINARY */
+object  present_clone(object|string, object|int|void, int|void);
 string  program_name(null|object default: F_THIS_OBJECT);
 int     program_time(object default: F_THIS_OBJECT);
 void    replace_program(void|string);
Index: efuns.h
===================================================================
--- efuns.h	(Revision 2457)
+++ efuns.h	(Arbeitskopie)
@@ -76,7 +76,7 @@
 extern svalue_t *f_blueprint (svalue_t *sp);
 extern svalue_t *v_clones (svalue_t *sp, int num_args);
 extern svalue_t *v_object_info (svalue_t *sp, int num_args);
-extern svalue_t *f_present_clone (svalue_t *sp);
+extern svalue_t *v_present_clone (svalue_t *sp, int num_arg);
 extern svalue_t *f_to_object(svalue_t *sp);
 extern svalue_t *f_set_is_wizard(svalue_t *sp);  /* optional */
 extern svalue_t *tell_room(svalue_t *sp);
Index: efuns.c
===================================================================
--- efuns.c	(Revision 2457)
+++ efuns.c	(Arbeitskopie)
@@ -4473,15 +4473,15 @@
 
 /*-------------------------------------------------------------------------*/
 svalue_t *
-f_present_clone (svalue_t *sp)
+v_present_clone (svalue_t *sp, int num_arg)
 
 /* EFUN present_clone()
  *
- *    object present_clone(string str, object env)
- *    object present_clone(object obj, object env)
+ *    object present_clone(string str [, object env] [, [int n])
+ *    object present_clone(object obj [, object env] [, [int n])
  *
- * Search in the inventory of <env> for the first object with the
- * same blueprint as object <obj>, resp. for the first object with
+ * Search in the inventory of <env> for the <n>th object with the
+ * same blueprint as object <obj>, resp. for the <n>th object with
  * the loadname <str>, and return that object.
  *
  * If not found, 0 is returned.
@@ -4490,10 +4490,48 @@
 {
     string_t * name; /* the shared loadname to look for */
     object_t *obj;   /* the object under scrutiny */
+    object_t *env;   /* the environment to search in */
+    int       count; /* the <count> object is searched */
 
-    /* Test and get the arguments from the stack */
-    if (sp[-1].type == T_STRING)
+    /* Get the arguments */
+    svalue_t *arg = sp - num_arg + 1;   // first argument
+    env = current_object;  // default
+    count = -1;
+    if (num_arg == 3)
     {
+        // if we got 3 args, the third must be a number.
+        count = arg[2].u.number;
+        free_svalue(sp--);
+        num_arg--;
+    }
+    if (num_arg == 2)
+    {
+        // the second arg may be an object or a number
+        if (arg[1].type == T_NUMBER)
+        {
+            // But it must not be 0 (which is probably a destructed object)
+            // and we don't accept two numbers (as second and third arg)
+            if (arg[1].u.number == 0 || count != -1)
+            {
+                vefun_arg_error(2, T_OBJECT, T_NUMBER, sp);
+                return sp; /* NOTREACHED */
+            }
+            count = arg[1].u.number;
+        }
+        else if (arg[1].type == T_OBJECT)
+        {
+            env = arg[1].u.ob;
+        }
+        free_svalue(sp--);
+        num_arg--;
+    }
+    /* no number given? search for the first object */
+    if (count == -1)
+        count = 1;
+
+    /* Get the name/object to search for */
+    if (arg->type == T_STRING)
+    {
         size_t len;
         long i;
         char * end;
@@ -4501,7 +4539,7 @@
         char * name0;  /* Intermediate name */
         char * tmpbuf; /* intermediate buffer for stripping any #xxxx */
         
-        name0 = get_txt(sp[-1].u.str);
+        name0 = get_txt(arg->u.str);
         tmpbuf = NULL;
         
         /* Normalize the given string and check if it is
@@ -4511,7 +4549,7 @@
 
         /* First, slash of a trailing '#<num>' */
 
-        len = mstrsize((sp-1)->u.str);
+        len = mstrsize(arg->u.str);
         i = (long)len;
         end = name0 + len;
 
@@ -4531,7 +4569,7 @@
                         errorf("Out of memory (%ld bytes) for temporary "
                                "buffer in present_clone().\n", i+1);
                     }
-                    strncpy(tmpbuf, get_txt(sp[-1].u.str), (size_t)i);
+                    strncpy(tmpbuf, get_txt(arg->u.str), (size_t)i);
                     name0[i] = '\0';
                 }
 
@@ -4559,26 +4597,27 @@
             tmpbuf = name0 = NULL;
         }
     }
-    else if (sp[-1].type == T_OBJECT)
+    else if (arg->type == T_OBJECT)
     {
-        name = sp[-1].u.ob->load_name;
+        name = arg->u.ob->load_name;
     }
     else
-        efun_gen_arg_error(1, sp[-1].type, sp);
+        vefun_exp_arg_error(1, TF_STRING|TF_OBJECT, arg->type, sp);
 
     obj = NULL;
     if (name)
     {
         /* We have a name, now look for the object */
-        for (obj = sp->u.ob->contains; obj != NULL; obj = obj->next_inv)
+        for (obj = env->contains; obj != NULL; obj = obj->next_inv)
         {
-            if (!(obj->flags & O_DESTRUCTED) && name == obj->load_name)
+            if (!(obj->flags & O_DESTRUCTED) && name == obj->load_name
+                && --count <= 0)
                 break;
         }
     }
 
-    /* Assign the result */
-    sp = pop_n_elems(2, sp) + 1;
+    /* Free first argument and assign the result */
+    free_svalue(sp);
     if (obj != NULL)
         put_ref_object(sp, obj, "present_clone");
     else
