* SQL support is now reported via @config compile. [RLB]
* Player aliases may now be supplied to @pemit/list. [RLB]
* Width() and height() take optional second argument for defaults. [RLB]
+ * Unique() removes contiguous duplicates in lists. [RLB]
+ * NextDbref() now returns the next object to be created. [RLB]
apply to exits, as well.
See also: lcon(), lexits(), con(), exit()
+
+& NEXTDBREF()
+ nextdbref()
+
+ This function returns the next dbref on the free list; when the next
+ object is @created (or @dug, or @opened, or @pcreated, etc.), it
+ will have this dbref.
+
& NOR()
nor(<boolean>, <boolean>,...)
value of %q0 to its original "are delicious!"
See also: u(), setq(), r()
-
+
+ & UNIQUE()
+ unique(<list>[, <sort type>[,<sep>[, <osep>]]])
+
+ unique() returns a copy of <list> with consecutive duplicate items
+ removed. It does not sort the list. The optional <sort type> describes
+ what type of data is in the list; see 'help sorting' for details. If
+ no type is given, the elements are compared as strings. The optional
+ third and fourth arguments are the list delimiter and output seperator.
+
+ Examples:
+ > think unique(a b b c b)
+ a b c b
+ > think unique(1 2 2.0 3, f)
+ 1 2 3
+ > think unique(1|2|3|3, n, |, _)
+ 1_2_3
+
+
& V()
& V-FUNCTION
V(<name of attribute>)
{"NEARBY", fun_nearby, 2, 2, FN_REG},
{"NEQ", fun_neq, 2, 2, FN_REG},
{"NEXT", fun_next, 1, 1, FN_REG},
+ {"NEXTDBREF", fun_nextdbref, 0, 0, FN_REG},
{"NLSEARCH", fun_lsearch, 1, INT_MAX, FN_REG},
{"NOR", fun_nor, 1, INT_MAX, FN_REG},
{"NOT", fun_not, 1, 1, FN_REG},
{"UFUN", fun_ufun, 1, 11, FN_REG},
{"ULDEFAULT", fun_uldefault, 1, 12, FN_NOPARSE},
{"ULOCAL", fun_ulocal, 1, 11, FN_REG},
+ {"UNIQUE", fun_unique, 1, 4, FN_REG},
{"IDLE_TIMES", fun_idle_times, 1, 1, FN_REG},
{"UTCTIME", fun_time, 0, 0, FN_REG},
{"U", fun_ufun, 1, 11, FN_REG},
#pragma warning( default : 4761) /* Re-enable conversion warning */
#endif
+/* ARGSUSED */
+FUNCTION(fun_nextdbref)
+{
+ if (first_free != NOTHING) {
+ safe_dbref(first_free, buff, bp);
+ } else {
+ safe_dbref(db_top, buff, bp);
+ }
+}
+
/* ARGSUSED */
FUNCTION(fun_num)
{
#define CACHE_SIZE 8 /**< Maximum size of the lnum cache */
+FUNCTION(fun_unique)
+{
+ char sep;
+ char **a1, **a2;
+ int n1, x1, x2;
+ char *sort_type = ALPHANUM_LIST;
+ int osepl = 0;
+ char *osep = NULL, osepd[2] = { '\0', '\0' };
+
+ /* if no lists, then no work */
+ if (!*args[0])
+ return;
+
+ if (!delim_check(buff, bp, nargs, args, 3, &sep))
+ return;
+
+ a1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray");
+
+ if (!a1)
+ mush_panic("Unable to allocate memory in fun_unique");
+
+ /* make array out of the list */
+ n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep);
+
+ a2 = mush_malloc(n1 * sizeof(char *), "ptrarray");
+ if (!a2)
+ mush_panic("Unable to allocate memory in fun_unique");
+
+ if (nargs >= 2)
+ sort_type = get_list_type_noauto(args, nargs, 2);
+
+ if (sort_type == UNKNOWN_LIST)
+ sort_type = ALPHANUM_LIST;
+
+ if (nargs < 4) {
+ osepd[0] = sep;
+ osep = osepd;
+ if (sep)
+ osepl = 1;
+ } else if (nargs == 4) {
+ osep = args[3];
+ osepl = arglens[3];
+ }
+
+
+ a2[0] = a1[0];
+ for (x1 = x2 = 1; x1 < n1; x1++) {
+ if (gencomp(executor, a1[x1], a2[x2 - 1], sort_type) == 0)
+ continue;
+ a2[x2] = a1[x1];
+ x2++;
+ }
+
+ for (x1 = 0; x1 < x2; x1++) {
+ if (x1 > 0)
+ safe_strl(osep, osepl, buff, bp);
+ safe_str(a2[x1], buff, bp);
+ }
+
+ mush_free(a1, "ptrarray");
+ mush_free(a2, "ptrarray");
+
+}
+
+
/* ARGSUSED */
FUNCTION(fun_lnum)
{
FUNCTION_PROTO(fun_nearby);
FUNCTION_PROTO(fun_neq);
FUNCTION_PROTO(fun_next);
+FUNCTION_PROTO(fun_nextdbref);
FUNCTION_PROTO(fun_nor);
FUNCTION_PROTO(fun_not);
FUNCTION_PROTO(fun_null);
FUNCTION_PROTO(fun_ufun);
FUNCTION_PROTO(fun_uldefault);
FUNCTION_PROTO(fun_ulocal);
+FUNCTION_PROTO(fun_unique);
FUNCTION_PROTO(fun_updiv);
FUNCTION_PROTO(fun_v);
FUNCTION_PROTO(fun_vadd);