void leave_group(struct char_data *ch) { struct group_data *group; struct char_data *tch; struct iterator_data Iterator; bool found_pc = FALSE; if ((group = ch->group) == NULL) return; send_to_group(NULL, group, "%s has left the group.\r\n", GET_NAME(ch)); remove_from_list(ch, group->members); ch->group = NULL; if (group->members->iSize) { for (tch = (struct char_data *) merge_iterator(&Iterator, group->members); tch; tch = next_in_list(&Iterator)) if (!IS_NPC(tch)) found_pc = TRUE; remove_iterator(&Iterator); } if (!found_pc) SET_BIT(GROUP_FLAGS(group), GROUP_NPC); if (GROUP_LEADER(group) == ch && group->members->iSize) { group->leader = (struct char_data *) random_from_list(group->members); send_to_group(NULL, group, "%s has assumed leadership of the group.\r\n", GET_NAME(GROUP_LEADER(group))); } else if (group->members->iSize == 0) free_group(group); }
void free_group(struct group_data * group) { struct char_data *tch; struct iterator_data Iterator; if (group->members->iSize) { for (tch = (struct char_data *) merge_iterator(&Iterator, group->members); tch; tch = next_in_list(&Iterator)) leave_group(tch); remove_iterator(&Iterator); } free_list(group->members); remove_from_list(group, group_list); free(group); }
/** The oemit(/list) command. * \verbatim * This implements @oemit and @oemit/list. * \endverbatim * \param executor The object \@oemit'ing * \param speaker The object making the sound (executor, unless /spoof'ing) * \param list the list of dbrefs to oemit from the emit. * \param message the message to emit. * \param flags PEMIT_* flags. * \param format a format_msg structure to pass to notify_anything() from \@message * \param pe_info the pe_info to use for evaluating speech locks */ void do_oemit_list(dbref executor, dbref speaker, char *list, const char *message, int flags, struct format_msg *format, NEW_PE_INFO *pe_info) { char *temp, *p; const char *s; dbref who; dbref room; int matched = 0; dbref pass[11]; dbref locs[10]; int i, oneloc = 0; int na_flags = NA_INTER_HEAR | NA_PROPAGATE; /* If no message, further processing is pointless. * If no list, they should have used @remit. */ if (!message || !*message || !list || !*list) return; if (flags & PEMIT_SPOOF) na_flags |= NA_SPOOF; for (i = 0; i < 11; i++) pass[i] = NOTHING; /* Find out what room to do this in. If they supplied a db# before * the '/', then oemit to anyone in the room who's not on list. * Otherwise, oemit to every location which has at least one of the * people in the list. This is intended for actions which involve * players who are in different rooms, e.g.: * * X (in #0) fires an arrow at Y (in #2). * * X sees: You fire an arrow at Y. (pemit to X) * Y sees: X fires an arrow at you! (pemit to Y) * #0 sees: X fires an arrow at Y. (oemit/list to X Y) * #2 sees: X fires an arrow at Y. (from the same oemit) */ /* Find out what room to do this in. They should have supplied a db# * before the '/'. */ if ((temp = strchr(list, '/'))) { *temp++ = '\0'; room = noisy_match_result(executor, list, NOTYPE, MAT_EVERYTHING); if (!GoodObject(room)) { notify(executor, T("I can't find that room.")); return; } if (!Loud(speaker) && !eval_lock_with(speaker, room, Speech_Lock, pe_info)) { fail_lock(executor, room, Speech_Lock, T("You may not speak there!"), NOTHING); return; } oneloc = 1; /* we are only oemitting to one location */ } else { temp = list; } s = temp; while (s && *s) { p = next_in_list(&s); /* If a room was given, we match relative to the room */ if (oneloc) who = match_result_relative(executor, room, p, NOTYPE, MAT_OBJ_CONTENTS); else who = noisy_match_result(executor, p, NOTYPE, MAT_OBJECTS); /* matched tracks the number of valid players we've found. * room is the given room (possibly nothing right now) * pass[0..10] are dbrefs of players * locs[0..10] are corresponding dbrefs of locations * pass[11] is always NOTHING */ if (GoodObject(who) && GoodObject(Location(who)) && (Loud(speaker) || (oneloc && Location(who) == room) || eval_lock_with(speaker, Location(who), Speech_Lock, pe_info)) ) { if (matched < 10) { locs[matched] = Location(who); pass[matched] = who; matched++; } else { notify(executor, T("Too many people to oemit to.")); break; } } } if (!matched) { if (oneloc) { /* A specific location was given, but there were no matching objects to * omit, so just remit */ notify_anything(executor, speaker, na_loc, &room, NULL, na_flags, message, NULL, room, format); } else { notify(executor, T("No matching objects.")); } return; } /* Sort the list of rooms to oemit to so we don't oemit to the same * room twice */ qsort((void *) locs, matched, sizeof(locs[0]), dbref_comp); for (i = 0; i < matched; i++) { if (i != 0 && locs[i] == locs[i - 1]) continue; notify_anything(executor, speaker, na_loc, &locs[i], pass, na_flags, message, NULL, locs[i], format); } }
/** The whisper command. * \param player the enactor. * \param arg1 name of the object to whisper to. * \param arg2 message to whisper. * \param noisy if 1, others overhear that a whisper has occurred. * \param pe_info the pe_info for evaluating interact locks */ void do_whisper(dbref player, const char *arg1, const char *arg2, int noisy, NEW_PE_INFO *pe_info) { dbref who; int key; const char *gap; char *tbuf, *tp; char *p; dbref good[100]; int gcount = 0; const char *head; int overheard; char *current; const char **start; char sname[BUFFER_LEN]; if (!arg1 || !*arg1) { notify(player, T("Whisper to whom?")); return; } if (!arg2 || !*arg2) { notify(player, T("Whisper what?")); return; } tp = tbuf = (char *) mush_malloc(BUFFER_LEN, "string"); if (!tbuf) mush_panic("Unable to allocate memory in do_whisper"); overheard = 0; head = arg1; start = &head; /* Figure out what kind of message */ gap = " "; switch (*arg2) { case SEMI_POSE_TOKEN: gap = ""; case POSE_TOKEN: key = 1; arg2++; break; default: key = 2; break; } *tp = '\0'; /* Make up a list of good and bad names */ while (head && *head) { current = next_in_list(start); who = match_result(player, current, TYPE_PLAYER, MAT_NEAR_THINGS | MAT_CONTAINER); if (!GoodObject(who) || !can_interact(player, who, INTERACT_HEAR, pe_info)) { safe_chr(' ', tbuf, &tp); safe_str_space(current, tbuf, &tp); if (GoodObject(who)) notify_format(player, T("%s can't hear you."), AName(who, AN_SYS, NULL)); } else { /* A good whisper */ good[gcount++] = who; if (gcount >= 100) { notify(player, T("Too many people to whisper to.")); break; } } } *tp = '\0'; if (*tbuf) notify_format(player, T("Unable to whisper to:%s"), tbuf); if (!gcount) { mush_free(tbuf, "string"); return; } /* Drunk wizards... */ if (Dark(player)) noisy = 0; /* Set up list of good names */ tp = tbuf; safe_str(T(" to "), tbuf, &tp); for (who = 0; who < gcount; who++) { if (noisy && (get_random32(0, 100) < (uint32_t) WHISPER_LOUDNESS)) overheard = 1; safe_itemizer(who + 1, (who == gcount - 1), ",", T("and"), " ", tbuf, &tp); safe_str(AName(good[who], AN_SAY, NULL), tbuf, &tp); } *tp = '\0'; if (key == 1) { notify_format(player, (gcount > 1) ? T("%s sense: %s%s%s") : T("%s senses: %s%s%s"), tbuf + 4, AName(player, AN_SAY, NULL), gap, arg2); p = tprintf("You sense: %s%s%s", AName(player, AN_SAY, NULL), gap, arg2); } else { notify_format(player, T("You whisper, \"%s\"%s."), arg2, tbuf); p = tprintf(T("%s whispers%s: %s"), AName(player, AN_SAY, NULL), gcount > 1 ? tbuf : "", arg2); } strcpy(sname, AName(player, AN_SAY, NULL)); for (who = 0; who < gcount; who++) { notify_must_puppet(good[who], p); if (Location(good[who]) != Location(player)) overheard = 0; } if (overheard) { dbref first = Contents(Location(player)); if (!GoodObject(first)) return; p = tprintf(T("%s whispers%s."), sname, tbuf); DOLIST(first, first) { overheard = 1; for (who = 0; who < gcount; who++) { if ((first == player) || (first == good[who])) { overheard = 0; break; } } if (overheard) notify_noecho(first, p); } }
static void * listGetNext(UtilList * ul) { Generic_list l = *(Generic_list *) & ul->hdl; return next_in_list(l); }