Wrote this up for a special procedure I was writing one day. I think it's pretty useful for a number of things, and may ought to be considered as a util function for future releases of circlemud. I know it sure does make mobile aggression more interesting when players can't predict who will be attacked ;) This is a utility function that allows you to choose a random target from a room. The function allows for restrictions to be sent as arguments to add to the versatility of the function. The arguments are sent in an integer and the default call of random_target(ch, 0); will be to find a random mortal/NPC in the room. To expand on targets, you can use bitwise operators in the function call, ie random_target(ch, TARG_MORT | TARG_MOB); would return a random target from mobs and mortals in the room. If the TARG_ALL flag is sent, everything in the room will be a target, including the character himself. If anyone sees any problems with this or has an idea of how it can be improved, please give me a holler to let me know at this email address. Anyhow, here are the instructions on installing it. It should work with all versions of circlemud. 1) The following should be added somewhere in structs.h: // Definitions for random_target() by Chuck Reed #define TARG_MORT (1 << 0) #define TARG_IMM (1 << 1) #define TARG_MOB (1 << 2) #define TARG_SELF (1 << 3) #define TARG_ALL (1 << 4) struct target_data { struct char_data *c; struct target_data *prev; struct target_data *next; }; 2) Now add the following function to utils.c and protoype it in utils.h: struct char_data *random_target(struct char_data *ch, int type) { struct target_data *t, *ctp, *ptp; int node, add, count = 0, i; struct char_data *cp, *rc; if (ch->in_room == NOWHERE) { log("SYSERROR: random_target() being called on ch->in_room == NOWHERE"); return NULL; } if (!world[ch->in_room].people) // Hmm, not even counting the player himself! YAY! return NULL; t = malloc(sizeof(struct target_data)); t->c = NULL; t->prev = NULL; t->next = NULL; ptp = t; for (cp = world[ch->in_room].people; cp; cp = cp->next_in_room) { add = FALSE; count++; if ((type & TARG_ALL)) // Any target is allowed add = TRUE; else if (cp == ch) { // Self targeting check if ((type & TARG_SELF)) add = TRUE; }else if (IS_MOB(cp)) { // Mob targeting check if ((type & TARG_MOB)) add = TRUE; }else if (GET_LEVEL(cp) >= LVL_IMMORT) { // Immortal targeting check if ((type & TARG_IMM)) add = TRUE; }else if ((type & TARG_MORT)) // Mortal targeting check add = TRUE; if (add == TRUE) { ctp = malloc(sizeof(struct target_data)); ctp->prev = ptp; ctp->next = NULL; ctp->c = cp; ptp->next = ctp; ptp = ctp; } } if (count == 0) // No valid targets return NULL; // At this point we should have a list of valid targets pointed to by t // Note: The first node of the list (0) is invalid, so number(1,count) is always used node = number(1, count); for (i = 0, ctp = t;ctp;i++, ctp = ctp->next) if (i == node) { rc = ctp->c; // Save pointer to be returned for (ctp = t; ctp;) // Free the list of targets if (ctp->next != NULL) { ctp = ctp->next; free(ctp->prev); } else { free(ctp); ctp = NULL; } return rc; } return NULL; } +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST