void friend_addmessage(FRIEND *f, void *data) { MESSAGE *msg = data; message_add(&messages_friend, data, &f->msg); /* if msg_type is text/action ? create tray popup */ switch(msg->msg_type) { case MSG_TYPE_TEXT: case MSG_TYPE_ACTION_TEXT: { char_t m[msg->length + 1]; memcpy(m, msg->msg, msg->length); m[msg->length] = 0; notify(f->name, f->name_length, m, msg->length, f); break; } } if(sitem->data != f) { f->notify = 1; } }
/* * Flush the screen, make a noise */ void bell(cptr reason) { /* Mega-Hack -- Flush the output */ Term_fresh(); /* Hack -- memorize the reason if possible */ if (character_generated && reason) { message_add(reason, MSG_BELL); /* Window stuff */ p_ptr->window |= (PW_MESSAGE); /* Force window redraw */ window_stuff(); } /* Make a bell noise (if allowed) */ if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0); /* Flush the input (later!) */ flush(); }
bool quest_poison_init_hook(int q_idx) { /* Get a place to place the poison */ if (!cquest.data[1]) { cquest.data[1] = TRUE; cquest.data[0] = rand_int(4); if (wizard) message_add(MESSAGE_MSG, format("Wilderness poison %d, %d", wild_locs[cquest.data[0]][0], wild_locs[cquest.data[0]][1]), TERM_BLUE); } if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { add_hook(HOOK_DROP, quest_poison_drop_hook, "poison_drop"); add_hook(HOOK_WILD_GEN, quest_poison_gen_hook, "poison_gen"); add_hook(HOOK_QUEST_FINISH, quest_poison_finish_hook, "poison_finish"); } if (cquest.status < QUEST_STATUS_COMPLETED) { add_hook(HOOK_INIT_QUEST, quest_poison_quest_hook, "poison_iquest"); } add_hook(HOOK_CHAR_DUMP, quest_poison_dump_hook, "poison_dump"); return (FALSE); }
/* * Read the saved messages */ static void rd_messages(void) { int i; char buf[128]; u16b tmp16u; s16b num; /* Total */ rd_s16b(&num); /* Read the messages */ for (i = 0; i < num; i++) { /* Read the message */ rd_string(buf, sizeof(buf)); /* Read the message type */ rd_u16b(&tmp16u); /* Save the message */ message_add(buf, tmp16u); } }
/* * Output a message to the top line of the screen. * * Break long messages into multiple pieces (40-72 chars). * * Allow multiple short messages to "share" the top line. * * Prompt the user to make sure he has a chance to read them. * * These messages are memorized for later reference (see above). * * We could do a "Term_fresh()" to provide "flicker" if needed. * * The global "msg_flag" variable can be cleared to tell us to "erase" any * "pending" messages still on the screen, instead of using "msg_flush()". * This should only be done when the user is known to have read the message. * * We must be very careful about using the "msg("%s", )" functions without * explicitly calling the special "msg("%s", NULL)" function, since this may * result in the loss of information if the screen is cleared, or if anything * is displayed on the top line. * * Hack -- Note that "msg("%s", NULL)" will clear the top line even if no * messages are pending. */ static void msg_print_aux(u16b type, const char *msg) { int n; char *t; char buf[1024]; byte color; int w, h; if (!Term) return; /* Obtain the size */ (void)Term_get_size(&w, &h); /* Hack -- Reset */ if (!msg_flag) message_column = 0; /* Message Length */ n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ if (message_column && (!msg || ((message_column + n) > (w - 8)))) { /* Flush */ msg_flush(message_column); /* Forget it */ msg_flag = FALSE; /* Reset */ message_column = 0; } /* No message */ if (!msg) return; /* Paranoia */ if (n > 1000) return; /* Memorize the message (if legal) */ if (character_generated && !(p_ptr->is_dead)) message_add(msg, type); /* Window stuff */ p_ptr->redraw |= (PR_MESSAGE); /* Copy it */ my_strcpy(buf, msg, sizeof(buf)); /* Analyze the buffer */ t = buf; /* Get the color of the message */ color = message_type_color(type); /* Split message */ while (n > w - 1) { char oops; int check, split; /* Default split */ split = w - 8; /* Find the rightmost split point */ for (check = (w / 2); check < w - 8; check++) if (t[check] == ' ') split = check; /* Save the split character */ oops = t[split]; /* Split the message */ t[split] = '\0'; /* Display part of the message */ Term_putstr(0, 0, split, color, t); /* Flush it */ msg_flush(split + 1); /* Restore the split character */ t[split] = oops; /* Insert a space */ t[--split] = ' '; /* Prepare to recurse on the rest of "buf" */ t += split; n -= split; } /* Display the tail of the message */ Term_putstr(message_column, 0, n, color, t); /* Remember the message */ msg_flag = TRUE; /* Remember the position */ message_column += n + 1; /* Send refresh event */ event_signal(EVENT_MESSAGE); }
/* * Memorize a message, Log it, Search it, and Display it in pieces */ static void borg_note_aux(cptr what) { int j, n, i, k; int w, h, x, y; term *old = Term; /* Memorize it */ message_add(what, MSG_GENERIC); /* Log the message */ if (borg_fff) froff(borg_fff, "%s\n", what); /* Mega-Hack -- Check against the search string */ if (borg_match[0] && strstr(what, borg_match)) { /* Tell the user why you quit */ borg_oops("Search string was matched"); } /* Scan windows */ for (j = 0; j < 8; j++) { if (!angband_term[j]) continue; /* Check flag */ if (!(window_flag[j] & PW_BORG_1)) continue; /* Activate */ Term_activate(angband_term[j]); /* Access size */ Term_get_size(&w, &h); /* Access cursor */ Term_locate(&x, &y); /* Erase current line */ clear_row(y); /* Total length */ n = strlen(what); /* Too long */ if (n > w - 2) { char buf[1024]; /* Split */ while (n > w - 2) { /* Default */ k = w - 2; /* Find a split point */ for (i = w / 2; i < w - 2; i++) { /* Pre-emptive split point */ if (isspace(what[i])) k = i; } /* Copy over the split message */ for (i = 0; i < k; i++) { /* Copy */ buf[i] = what[i]; } /* Indicate split */ buf[i++] = '\\'; /* Terminate */ buf[i] = '\0'; /* Show message */ roff(buf); /* Advance (wrap) */ if (++y >= h) y = 0; /* Erase next line */ clear_row(y); /* Advance */ what += k; /* Reduce */ n -= k; } /* Show message tail */ roff(what); /* Advance (wrap) */ if (++y >= h) y = 0; /* Erase next line */ clear_row(y); } /* Normal */ else { /* Show message */ roff(what); /* Advance (wrap) */ if (++y >= h) y = 0; /* Erase next line */ clear_row(y); } /* Flush output */ Term_fresh(); /* Use correct window */ Term_activate(old); } }
/* * Destroy an item */ void do_cmd_destroy(void) { int item, amt = 1; int old_number; bool force = FALSE; object_type *o_ptr; object_type forge; object_type *q_ptr = &forge; bool is_equipped = FALSE; char o_name[MAX_NLEN]; char out_val[MAX_NLEN+40]; cptr q, s; int mode = USE_INVEN | USE_FLOOR; if (p_ptr->pclass == CLASS_RUNE_KNIGHT) mode |= USE_EQUIP; if (p_ptr->special_defense & KATA_MUSOU) { set_action(ACTION_NONE); } /* Hack -- force destruction */ if (command_arg > 0) force = TRUE; /* Get an item */ q = "Destroy which item? "; s = "You have nothing to destroy."; if (!get_item(&item, q, s, mode)) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; is_equipped = equip_is_valid_slot(item); } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Hack for Rune Knight: They can destroy worn equipment, but only if it has the Sacrifice rune. get_item() is not smart enough to handle this restriction ... */ if (is_equipped && o_ptr->rune != RUNE_SACRIFICE) { msg_print("You must first remove that item before destroying it."); return; } /* Verify unless quantity given beforehand */ if (!force && (confirm_destroy || (object_value(o_ptr) > 0))) { object_desc(o_name, o_ptr, OD_OMIT_PREFIX); /* Make a verification */ sprintf(out_val, "Really destroy %s? [y/n/Auto]", o_name); msg_print(NULL); /* HACK : Add the line to message buffer */ message_add(out_val); p_ptr->window |= (PW_MESSAGE); window_stuff(); /* Get an acceptable answer */ while (TRUE) { char i; /* Prompt */ prt(out_val, 0, 0); i = inkey(); /* Erase the prompt */ prt("", 0, 0); if (i == 'y' || i == 'Y') { break; } if (i == ESCAPE || i == 'n' || i == 'N') { /* Cancel */ return; } if (i == 'A') { /* Add an auto-destroy preference line */ if (autopick_autoregister(o_ptr)) { /* Auto-destroy it */ autopick_alter_item(item, TRUE); } /* The object is already destroyed. */ return; } } /* while (TRUE) */ } /* See how many items */ if (o_ptr->number > 1) { /* Get a quantity */ amt = get_quantity(NULL, o_ptr->number); /* Allow user abort */ if (amt <= 0) return; } /* Describe the object */ old_number = o_ptr->number; o_ptr->number = amt; object_desc(o_name, o_ptr, 0); o_ptr->number = old_number; /* Take a turn */ energy_use = 100; /* Artifacts cannot be destroyed */ if (!can_player_destroy_object(o_ptr)) { energy_use = 0; /* Message */ msg_format("You cannot destroy %s.", o_name); /* Done */ return; } object_copy(q_ptr, o_ptr); stats_on_p_destroy(o_ptr, amt); if (prace_is_(RACE_MON_JELLY)) jelly_eat_object(o_ptr); else if (prace_is_(RACE_MON_SWORD) && object_is_melee_weapon(o_ptr)) sword_absorb_object(o_ptr); else if (prace_is_(RACE_MON_RING) && object_is_jewelry(o_ptr)) ring_absorb_object(o_ptr); else msg_format("You destroy %s.", o_name); if (o_ptr->rune == RUNE_SACRIFICE) { int add_hp = is_equipped ? p_ptr->mhp : p_ptr->mhp/3; int add_sp = is_equipped ? p_ptr->msp : p_ptr->msp/3; msg_print("You feel a surge of wondrous power enter your body."); p_ptr->chp = MIN(p_ptr->mhp, p_ptr->chp + add_hp); p_ptr->chp_frac = 0; p_ptr->csp = MIN(p_ptr->msp, p_ptr->csp + add_sp); p_ptr->csp_frac = 0; p_ptr->redraw |= (PR_MANA); p_ptr->window |= (PW_PLAYER); p_ptr->window |= (PW_SPELL); p_ptr->redraw |= (PR_HP); if (is_equipped) { blast_object(o_ptr); o_ptr->curse_flags = TRC_HEAVY_CURSE; } } else if (is_equipped) blast_object(o_ptr); sound(SOUND_DESTITEM); /* Reduce the charges of rods/wands */ reduce_charges(o_ptr, amt); /* Eliminate the item (from the pack) */ if (item >= 0) { if (!is_equipped) { inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); } } /* Eliminate the item (from the floor) */ else { floor_item_increase(0 - item, -amt); floor_item_describe(0 - item); floor_item_optimize(0 - item); } if ( p_ptr->pclass == CLASS_NECROMANCER && (q_ptr->tval == TV_LIFE_BOOK || q_ptr->tval == TV_CRUSADE_BOOK) ) { int sp = 0; int osp = p_ptr->csp; switch (q_ptr->sval) { case 0: sp = 10; break; case 1: sp = 25; break; case 2: sp = 100; break; case 3: sp = 666; break; } p_ptr->csp += sp; if (p_ptr->csp >= p_ptr->msp) { p_ptr->csp = p_ptr->msp; p_ptr->csp_frac = 0; } if (p_ptr->csp > osp) msg_print("You feel your head clear."); p_ptr->redraw |= (PR_MANA); } if (high_level_book(q_ptr)) { bool gain_expr = FALSE; if (p_ptr->prace == RACE_ANDROID) { } else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER)) { gain_expr = TRUE; } else if (p_ptr->pclass == CLASS_PALADIN) { if (is_good_realm(p_ptr->realm1)) { if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE; } else { if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE; } } if (gain_expr && (p_ptr->exp < PY_MAX_EXP)) { s32b tester_exp = p_ptr->max_exp / 20; if (tester_exp > 10000) tester_exp = 10000; if (q_ptr->sval < 3) tester_exp /= 4; if (tester_exp<1) tester_exp = 1; msg_print("You feel more experienced."); gain_exp(tester_exp * amt); } } if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK) { virtue_add(VIRTUE_UNLIFE, 1); virtue_add(VIRTUE_VITALITY, -1); } else if ( high_level_book(q_ptr) && (q_ptr->tval == TV_DEATH_BOOK || q_ptr->tval == TV_NECROMANCY_BOOK) ) { virtue_add(VIRTUE_UNLIFE, -1); virtue_add(VIRTUE_VITALITY, 1); } if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d) virtue_add(VIRTUE_ENCHANTMENT, -1); if (object_value_real(q_ptr) > 30000) virtue_add(VIRTUE_SACRIFICE, 2); else if (object_value_real(q_ptr) > 10000) virtue_add(VIRTUE_SACRIFICE, 1); if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0) virtue_add(VIRTUE_HARMONY, 1); if (equip_is_valid_slot(item)) calc_android_exp(); }
/* * Initialize a game. */ void init_game(game *g) { player *p_ptr; design *d_ptr; card *c_ptr; int goal[MAX_GOAL]; int i, j, k, n; /* Save current random seed */ g->start_seed = g->random_seed; #if 0 sprintf(msg, "start seed: %u\n", g->start_seed); message_add(msg); #endif /* Game is not simulated */ g->simulation = 0; /* Set size of VP pool */ g->vp_pool = g->num_players * 12; /* Increase size of pool in third expansion */ if (g->expanded >= 3) g->vp_pool += 5; /* First game round */ g->round = 1; /* No phase or turn */ g->cur_action = -1; g->turn = 0; /* Clear selected actions */ for (i = 0; i < MAX_ACTION; i++) g->action_selected[i] = 0; /* Game is not over */ g->game_over = 0; /* No cards in deck yet */ g->deck_size = 0; /* Clear goals */ for (i = 0; i < MAX_GOAL; i++) { /* Goal is not active */ g->goal_active[i] = 0; /* Goal is not available */ g->goal_avail[i] = 0; } /* Clear number of pending takeovers */ g->num_takeover = 0; /* Set Oort Cloud kind to "any" */ g->oort_kind = GOOD_ANY; /* Loop over card designs */ for (i = 0; i < MAX_DESIGN; i++) { /* Get design pointer */ d_ptr = &library[i]; /* Get number of cards in use */ n = d_ptr->expand[g->expanded]; /* Add cards */ for (j = 0; j < n; j++) { /* Get card pointer */ c_ptr = &g->deck[g->deck_size++]; /* No owner */ c_ptr->start_owner = c_ptr->owner = -1; /* Put location in draw deck */ c_ptr->start_where = c_ptr->where = WHERE_DECK; /* Card is not unpaid */ c_ptr->unpaid = 0; /* Card's location is not known */ c_ptr->known = 0; /* Clear used power list */ for (k = 0; k < MAX_POWER; k++) c_ptr->used[k] = 0; /* Card has not produced */ c_ptr->produced = 0; /* Set card's design */ c_ptr->d_ptr = d_ptr; /* Card is not covered by a good */ c_ptr->covered = -1; /* Card is not followed by any other */ c_ptr->next = -1; } } /* Add goals when expanded */ if (g->expanded && !g->goal_disabled) { /* No goals available yet */ n = 0; /* Use correct "first" goals */ if (g->expanded == 1) { /* First expansion only */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_SIX_DEVEL; } else if (g->expanded == 2) { /* First and second expansion */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_8_ACTIVE; } else { /* All expansions */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_4_MILITARY; } /* Add "first" goals to list */ for (i = j; i <= k; i++) { /* Add goal to list */ goal[n++] = i; } /* Select four "first" goals at random */ for (i = 0; i < 4; i++) { /* Choose goal at random */ j = game_rand(g) % n; /* Goal is active */ g->goal_active[goal[j]] = 1; /* Goal is available */ g->goal_avail[goal[j]] = 1; /* Remove chosen goal from list */ goal[j] = goal[--n]; } /* No goals available yet */ n = 0; /* Use correct "most" goals */ if (g->expanded == 1) { /* First expansion only */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_PRODUCTION; } else if (g->expanded == 2) { /* First and second expansion */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_REBEL; } else { /* All expansions */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_CONSUME; } /* Add "most" goals to list */ for (i = j; i <= k; i++) { /* Add goal to list */ goal[n++] = i; } /* Select two "most" goals at random */ for (i = 0; i < 2; i++) { /* Choose goal at random */ j = game_rand(g) % n; /* Goal is active */ g->goal_active[goal[j]] = 1; /* Goal is available */ g->goal_avail[goal[j]] = 1; /* Remove chosen goal from list */ goal[j] = goal[--n]; } } /* Loop over players */ for (i = 0; i < g->num_players; i++) { /* Get player pointer */ p_ptr = &g->p[i]; /* Clear all claimed goals */ for (j = 0; j < MAX_GOAL; j++) { /* Goal is unclaimed */ p_ptr->goal_claimed[j] = 0; /* No progress toward goal */ p_ptr->goal_progress[j] = 0; } /* Player has no actions chosen */ p_ptr->action[0] = p_ptr->prev_action[0] = -1; p_ptr->action[1] = p_ptr->prev_action[1] = -1; /* Player has not used prestige/search action */ p_ptr->prestige_action_used = 0; /* Player has not used phase bonus */ p_ptr->phase_bonus_used = 0; /* Player has no start world */ p_ptr->start = -1; /* Player has no card to be placed */ p_ptr->placing = -1; /* Player has no cards in any area */ for (j = 0; j < MAX_WHERE; j++) { /* Clear list head */ p_ptr->head[j] = -1; p_ptr->start_head[j] = -1; } /* Player has no bonus military accrued */ p_ptr->bonus_military = 0; /* Player has no bonus settle discount */ p_ptr->bonus_reduce = 0; /* Player has not discarded any end of turn cards */ p_ptr->end_discard = 0; /* No cards played yet */ p_ptr->table_order = 0; /* Player has no prestige */ p_ptr->prestige = p_ptr->prestige_turn = 0; /* Player has no points */ p_ptr->vp = p_ptr->goal_vp = p_ptr->end_vp = 0; /* Player is not the winner */ p_ptr->winner = 0; /* Player has earned no rewards this phase */ p_ptr->phase_cards = p_ptr->phase_vp = 0; p_ptr->phase_prestige = 0; /* Player has no fake cards */ p_ptr->fake_hand = p_ptr->total_fake = 0; p_ptr->fake_discards = 0; } }
/* * Initialize a game. */ void init_game(game *g) { player *p_ptr; design *d_ptr; card *c_ptr; int goal[MAX_GOAL]; int i, j, k, n; int num_goal = 0; /* Save current random seed */ g->start_seed = g->random_seed; #if 0 sprintf(msg, "start seed: %u\n", g->start_seed); message_add(msg); #endif /* Apply campaign options */ apply_campaign(g); /* Game is not simulated */ g->simulation = 0; /* Set size of VP pool */ g->vp_pool = g->num_players * 12; /* Increase size of pool in third expansion */ if (g->expanded == 3) g->vp_pool += 5; /* No game round yet */ g->round = 0; /* No phase or turn */ g->cur_action = ACT_ROUND_START; g->turn = 0; /* Clear selected actions */ for (i = 0; i < MAX_ACTION; i++) g->action_selected[i] = 0; /* Game is not over */ g->game_over = 0; /* No cards in deck yet */ g->deck_size = 0; /* Clear goals */ for (i = 0; i < MAX_GOAL; i++) { /* Goal is not active */ g->goal_active[i] = 0; /* Goal is not available */ g->goal_avail[i] = 0; } /* Clear number of pending takeovers */ g->num_takeover = 0; /* Set Oort Cloud kind to "any" */ g->oort_kind = GOOD_ANY; /* Loop over card designs */ for (i = 0; i < num_design; i++) { /* Get design pointer */ d_ptr = &library[i]; /* Get number of cards in use */ n = d_ptr->expand[g->expanded]; /* Skip promo cards if not included */ if (!g->promo && (d_ptr->flags & FLAG_PROMO)) n = 0; /* Add cards */ for (j = 0; j < n; j++) { /* Check for too large deck */ if (g->deck_size >= MAX_DECK) { /* Error */ display_error("Deck is too large!"); exit(1); } /* Get card pointer */ c_ptr = &g->deck[g->deck_size++]; /* No owner */ c_ptr->start_owner = c_ptr->owner = -1; /* Put location in draw deck */ c_ptr->start_where = c_ptr->where = WHERE_DECK; /* Clear card misc flags */ c_ptr->misc = 0; /* Set card's design */ c_ptr->d_ptr = d_ptr; /* Card is not covering another */ c_ptr->covering = -1; /* No goods on card */ c_ptr->num_goods = 0; /* Card is not followed by any other */ c_ptr->next = c_ptr->start_next = -1; } } /* Loop over players */ for (i = 0; i < g->num_players; i++) { /* Get player pointer */ p_ptr = &g->p[i]; /* Clear all claimed goals */ for (j = 0; j < MAX_GOAL; j++) { /* Goal is unclaimed */ p_ptr->goal_claimed[j] = 0; /* No progress toward goal */ p_ptr->goal_progress[j] = 0; } /* Player has no actions chosen */ p_ptr->action[0] = p_ptr->prev_action[0] = -1; p_ptr->action[1] = p_ptr->prev_action[1] = -1; /* Player has not used prestige/search action */ p_ptr->prestige_action_used = 0; /* Player has not used phase bonus */ p_ptr->phase_bonus_used = 0; /* Player has no card to be placed */ p_ptr->placing = -1; /* Player has no cards in any area */ for (j = 0; j < MAX_WHERE; j++) { /* Clear list head */ p_ptr->head[j] = -1; p_ptr->start_head[j] = -1; } /* Player has no bonus military accrued */ p_ptr->bonus_military = 0; /* Player has no bonus settle discount */ p_ptr->bonus_reduce = 0; /* Player has not used any partial hand military powers */ p_ptr->hand_military_spent = 0; /* Player has not spent any military */ p_ptr->military_spent = 0; /* Player has not discarded any end of turn cards */ p_ptr->end_discard = 0; /* No cards played yet */ p_ptr->table_order = 0; /* Player has no prestige */ p_ptr->prestige = p_ptr->prestige_turn = 0; /* Player has no points */ p_ptr->vp = p_ptr->goal_vp = p_ptr->end_vp = 0; /* Player is not the winner */ p_ptr->winner = 0; /* Player has earned no rewards this phase */ p_ptr->phase_cards = p_ptr->phase_vp = 0; p_ptr->phase_prestige = 0; /* Player has no fake cards */ p_ptr->fake_hand = 0; p_ptr->fake_discards = 0; p_ptr->drawn_round = 0; /* Player has not skipped build phases */ p_ptr->skip_develop = p_ptr->skip_settle = 0; /* Clear lowest hand size */ p_ptr->low_hand = 0; } /* Check for campaign */ if (g->camp) { /* Set aside campaign cards */ init_campaign(g); } /* Add goals when expanded */ if (g->expanded > 0 && g->expanded < 4 && !g->goal_disabled) { /* No goals available yet */ n = 0; /* Use correct "first" goals */ if (g->expanded == 1) { /* First expansion only */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_SIX_DEVEL; } else if (g->expanded == 2) { /* First and second expansion */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_8_ACTIVE; } else { /* All expansions */ j = GOAL_FIRST_5_VP; k = GOAL_FIRST_4_MILITARY; } /* Add "first" goals to list */ for (i = j; i <= k; i++) { /* Add goal to list */ goal[n++] = i; } /* Assume no campaign goals */ k = 0; /* Check for campaign goals */ if (g->camp) num_goal = g->camp->num_goal; /* Loop over campaign goals */ for (i = 0; i < num_goal; i++) { /* Skip "most" goals */ if (g->camp->goal[i] > GOAL_FIRST_4_MILITARY) continue; /* Goal is active */ g->goal_active[g->camp->goal[i]] = 1; /* Goal is available */ g->goal_avail[g->camp->goal[i]] = 1; /* Remove campaign goal from list */ for (j = 0; j < n; j++) { /* Check for match */ if (goal[j] == g->camp->goal[i]) { /* Remove from list */ goal[j] = goal[--n]; } } /* Count campaign "first" goals */ k++; } /* Select four "first" goals at random */ for (i = k; i < 4; i++) { /* Choose goal at random */ j = game_rand(g) % n; /* Goal is active */ g->goal_active[goal[j]] = 1; /* Goal is available */ g->goal_avail[goal[j]] = 1; /* Remove chosen goal from list */ goal[j] = goal[--n]; } /* No goals available yet */ n = 0; /* Use correct "most" goals */ if (g->expanded == 1) { /* First expansion only */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_PRODUCTION; } else if (g->expanded == 2) { /* First and second expansion */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_REBEL; } else { /* All expansions */ j = GOAL_MOST_MILITARY; k = GOAL_MOST_CONSUME; } /* Add "most" goals to list */ for (i = j; i <= k; i++) { /* Add goal to list */ goal[n++] = i; } /* Assume no campaign goals */ k = 0; /* Loop over campaign goals */ for (i = 0; i < num_goal; i++) { /* Skip "first" goals */ if (g->camp->goal[i] < GOAL_MOST_MILITARY) continue; /* Goal is active */ g->goal_active[g->camp->goal[i]] = 1; /* Goal is available */ g->goal_avail[g->camp->goal[i]] = 1; /* Remove campaign goal from list */ for (j = 0; j < n; j++) { /* Check for match */ if (goal[j] == g->camp->goal[i]) { /* Remove from list */ goal[j] = goal[--n]; } } /* Count campaign goals */ k++; } /* Select two "most" goals at random */ for (i = k; i < 2; i++) { /* Choose goal at random */ j = game_rand(g) % n; /* Goal is active */ g->goal_active[goal[j]] = 1; /* Goal is available */ g->goal_avail[goal[j]] = 1; /* Remove chosen goal from list */ goal[j] = goal[--n]; } } }
void tox_message(uint8_t tox_message_id, uint16_t param1, uint16_t param2, void *data) { switch(tox_message_id) { case DHT_CONNECTED: { /* param1: connection status (1 = connected, 0 = disconnected) */ tox_connected = param1; redraw(); break; } case DNS_RESULT: { /* param1: result (0 = failure, 1 = success) * data: resolved tox id (if successful) */ if(param1) { friend_addid(data, edit_addmsg.data, edit_addmsg.length); } else { addfriend_status = ADDF_BADNAME; } free(data); redraw(); break; } case OPEN_FILES: { tox_postmessage(TOX_SENDFILES, param1, param2, data); break; } case SAVE_FILE: { tox_postmessage(TOX_ACCEPTFILE, param1, param2, data); break; } case NEW_AUDIO_IN_DEVICE: { if(UI_STRING_ID_INVALID == param1) { list_dropdown_add_hardcoded(&dropdown_audio_in, data, data); } else { list_dropdown_add_localized(&dropdown_audio_in, param1, data); } if (loaded_audio_in_device != 0 && (dropdown_audio_in.dropcount - 1) == loaded_audio_in_device) { toxaudio_postmessage(AUDIO_SET_INPUT, 0, 0, data); dropdown_audio_in.selected = loaded_audio_in_device; loaded_audio_in_device = 0; } break; } case NEW_AUDIO_OUT_DEVICE: { list_dropdown_add_hardcoded(&dropdown_audio_out, data, data); if (loaded_audio_out_device != 0 && (dropdown_audio_out.dropcount - 1) == loaded_audio_out_device) { toxaudio_postmessage(AUDIO_SET_OUTPUT, 0, 0, data); dropdown_audio_out.selected = loaded_audio_out_device; loaded_audio_out_device = 0; } break; } case NEW_VIDEO_DEVICE: { if(UI_STRING_ID_INVALID == param1) { // Device name is a hardcoded string. // data is a pointer to a buffer, that contains device handle pointer, // followed by device name string. list_dropdown_add_hardcoded(&dropdown_video, data + sizeof(void*), *(void**)data); } else { // Device name is localized with param1 containing UI_STRING_ID. // data is device handle pointer. list_dropdown_add_localized(&dropdown_video, param1, data); } //param2 == true, if this device will be chosen by video detecting code. if(param2) { dropdown_video.selected = dropdown_video.over = (dropdown_video.dropcount - 1); } break; } case FRIEND_REQUEST: { /* data: pointer to FRIENDREQ structure */ list_addfriendreq(data); break; } case FRIEND_ADD: { /* confirmation that friend has been added to friend list (add) */ if(param1) { /* friend was not added */ addfriend_status = param2; } else { /* friend was added */ edit_addid.length = 0; edit_addmsg.length = 0; FRIEND *f = &friend[param2]; friends++; f->msg.scroll = 1.0; memcpy(f->cid, data, sizeof(f->cid)); friend_setname(f, NULL, 0); list_addfriend(f); addfriend_status = ADDF_SENT; } free(data); redraw(); break; } case FRIEND_ACCEPT: { /* confirmation that friend has been added to friend list (accept) */ if(!param1) { FRIEND *f = &friend[param2]; FRIENDREQ *req = data; friends++; memcpy(f->cid, req->id, sizeof(f->cid)); friend_setname(f, NULL, 0); list_addfriend2(f, req); redraw(); } free(data); break; } case FRIEND_DEL: { friend_free(data); friends--; break; } case FRIEND_MESSAGE: { friend_addmessage(&friend[param1], data); redraw(); break; } #define updatefriend(fp) redraw();//list_draw(); if(sitem && fp == sitem->data) {ui_drawmain();} #define updategroup(gp) redraw();//list_draw(); if(sitem && gp == sitem->data) {ui_drawmain();} case FRIEND_NAME: { FRIEND *f = &friend[param1]; friend_setname(f, data, param2); updatefriend(f); break; } case FRIEND_STATUS_MESSAGE: { FRIEND *f = &friend[param1]; free(f->status_message); f->status_length = param2; f->status_message = data; updatefriend(f); break; } case FRIEND_STATUS: { FRIEND *f = &friend[param1]; f->status = param2; updatefriend(f); break; } case FRIEND_TYPING: { FRIEND *f = &friend[param1]; friend_set_typing(f, param2); updatefriend(f); break; } case FRIEND_ONLINE: { FRIEND *f = &friend[param1]; f->online = param2; if(!f->online) { friend_set_typing(f, 0); } updatefriend(f); break; } case FRIEND_CALL_STATUS: { /* param1: friend id param2: call id data: integer call status */ FRIEND *f = &friend[param1]; uint8_t status = (size_t)data; if(status == CALL_NONE && (f->calling == CALL_OK || f->calling == CALL_OK_VIDEO)) { toxaudio_postmessage(AUDIO_CALL_END, param2, 0, NULL); if(f->calling == CALL_OK_VIDEO) { toxvideo_postmessage(VIDEO_CALL_END, param2, 0, NULL); } video_end(param1 + 1); } f->calling = status; f->callid = param2; if(status == CALL_OK) { toxaudio_postmessage(AUDIO_CALL_START, param2, 0, NULL); } call_notify(f, status); updatefriend(f); break; } case FRIEND_CALL_VIDEO: { /* param1: friend id param2: call id */ FRIEND *f = &friend[param1]; f->calling = CALL_OK_VIDEO; f->callid = param2; updatefriend(f); toxvideo_postmessage(VIDEO_CALL_START, param2, 0, NULL); toxaudio_postmessage(AUDIO_CALL_START, param2, 0, NULL); f->call_width = 640; f->call_height = 480; video_begin(param1 + 1, f->name, f->name_length, 640, 480); call_notify(f, CALL_OK_VIDEO); break; } case FRIEND_CALL_MEDIACHANGE: { /* param1: friend id param2: call id data: zero = audio, nonzero = audio/video */ FRIEND *f = &friend[param1]; if(!data) { video_end(param1 + 1); } else { f->call_width = 640; f->call_height = 480; video_begin(param1 + 1, f->name, f->name_length, 640, 480); } break; } case FRIEND_CALL_START_VIDEO: { /* param1: friend id param2: call id */ FRIEND *f = &friend[param1]; if(f->calling == CALL_OK) { f->calling = CALL_OK_VIDEO; toxvideo_postmessage(VIDEO_CALL_START, param2, 0, NULL); updatefriend(f); } break; } case FRIEND_CALL_STOP_VIDEO: { /* param1: friend id param2: call id */ FRIEND *f = &friend[param1]; if(f->calling == CALL_OK_VIDEO) { f->calling = CALL_OK; toxvideo_postmessage(VIDEO_CALL_END, param2, 0, NULL); updatefriend(f); } break; } case FRIEND_VIDEO_FRAME: { /* param1: friend id param2: call id data: frame data */ uint16_t *image = data; FRIEND *f = &friend[param1]; _Bool b = (image[0] != f->call_width || image[1] != f->call_height); if(b) { f->call_width = image[0]; f->call_height = image[1]; } video_frame(param1 + 1, (void*)&image[2], image[0], image[1], b); free(image); break; } case PREVIEW_FRAME_NEW: case PREVIEW_FRAME: { if(video_preview) { video_frame(0, data, param1, param2, tox_message_id == PREVIEW_FRAME_NEW); } free(data); break; } case FRIEND_FILE_IN_NEW: case FRIEND_FILE_IN_NEW_INLINE: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->incoming[param2]; _Bool inline_png = (tox_message_id == FRIEND_FILE_IN_NEW_INLINE); MSG_FILE *msg = malloc(sizeof(MSG_FILE)); msg->author = 0; msg->msg_type = MSG_TYPE_FILE; msg->filenumber = param2; msg->status = (inline_png ? FILE_OK : FILE_PENDING); msg->name_length = (ft->name_length > sizeof(msg->name)) ? sizeof(msg->name) : ft->name_length; msg->size = ft->total; msg->progress = 0; msg->speed = 0; msg->inline_png = inline_png; msg->path = NULL; memcpy(msg->name, ft->name, msg->name_length); friend_addmessage(f, msg); ft->chatdata = msg; file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_OUT_NEW: case FRIEND_FILE_OUT_NEW_INLINE: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->outgoing[param2]; _Bool inline_png = (tox_message_id == FRIEND_FILE_OUT_NEW_INLINE); MSG_FILE *msg = malloc(sizeof(MSG_FILE)); msg->author = 1; msg->msg_type = MSG_TYPE_FILE; msg->filenumber = param2; msg->status = FILE_PENDING; msg->name_length = (ft->name_length >= sizeof(msg->name)) ? sizeof(msg->name) - 1 : ft->name_length; msg->size = ft->total; msg->progress = 0; msg->speed = 0; msg->inline_png = inline_png; msg->path = NULL; memcpy(msg->name, ft->name, msg->name_length); msg->name[msg->name_length] = 0; friend_addmessage(f, msg); ft->chatdata = msg; updatefriend(f); break; } case FRIEND_FILE_IN_STATUS: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->incoming[param2]; MSG_FILE *msg = ft->chatdata; msg->status = (size_t)data; file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_OUT_STATUS: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->outgoing[param2]; MSG_FILE *msg = ft->chatdata; msg->status = (size_t)data; file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_IN_DONE: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->incoming[param2]; MSG_FILE *msg = ft->chatdata; msg->status = FILE_DONE; msg->path = data; file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_IN_DONE_INLINE: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->incoming[param2]; MSG_FILE *msg = ft->chatdata; msg->status = FILE_DONE; msg->path = data; friend_recvimage(f, data, msg->size); file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_OUT_DONE: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->outgoing[param2]; MSG_FILE *msg = ft->chatdata; msg->status = FILE_DONE; msg->path = data; file_notify(f, msg); updatefriend(f); break; } case FRIEND_FILE_IN_PROGRESS: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->incoming[param2]; FILE_PROGRESS *p = data; MSG_FILE *msg = ft->chatdata; msg->progress = p->bytes; msg->speed = p->speed; free(p); updatefriend(f); break; } case FRIEND_FILE_OUT_PROGRESS: { FRIEND *f = &friend[param1]; FILE_T *ft = &f->outgoing[param2]; FILE_PROGRESS *p = data; MSG_FILE *msg = ft->chatdata; msg->progress = p->bytes; msg->speed = p->speed; free(p); updatefriend(f); break; } case GROUP_ADD: { GROUPCHAT *g = &group[param1]; g->name_length = snprintf((char*)g->name, sizeof(g->name), "Groupchat #%u", param1); g->topic_length = sizeof("Drag friends to invite them") - 1; memcpy(g->topic, "Drag friends to invite them", sizeof("Drag friends to invite them") - 1); g->msg.scroll = 1.0; g->type = tox_group_get_type(data, param1); list_addgroup(g); redraw(); break; } case GROUP_MESSAGE: { GROUPCHAT *g = &group[param1]; message_add(&messages_group, data, &g->msg); if(sitem && g == sitem->data) { redraw();//ui_drawmain(); } break; } case GROUP_PEER_DEL: { GROUPCHAT *g = &group[param1]; if (param2 > MAX_GROUP_PEERS) //TODO: dynamic arrays. break; if(g->peername[param2]) { free(g->peername[param2]); g->peername[param2] = NULL; } g->peers--; g->peername[param2] = g->peername[g->peers]; g->peername[g->peers] = NULL; if (g->type == TOX_GROUPCHAT_TYPE_AV) { g->last_recv_audio[param2] = g->last_recv_audio[g->peers]; g->last_recv_audio[g->peers] = 0; group_av_peer_remove(g, param2); g->source[param2] = g->source[g->peers]; } if (g->peers == g->our_peer_number) { g->our_peer_number = param2; } g->topic_length = snprintf((char*)g->topic, sizeof(g->topic), "%u users in chat", g->peers); updategroup(g); break; } case GROUP_PEER_ADD: case GROUP_PEER_NAME: { GROUPCHAT *g = &group[param1]; if (param2 > MAX_GROUP_PEERS) //TODO: dynamic arrays. break; if(g->peername[param2]) { free(g->peername[param2]); } if(tox_message_id == GROUP_PEER_ADD) { if (g->type == TOX_GROUPCHAT_TYPE_AV) { group_av_peer_add(g, param2); } if (tox_group_peernumber_is_ours(data, param1, param2)) { g->our_peer_number = param2; } uint8_t *n = malloc(10); n[0] = 9; memcpy(n + 1, "<unknown>", 9); data = n; g->peers++; } g->peername[param2] = data; g->topic_length = snprintf((char*)g->topic, sizeof(g->topic), "%u users in chat", g->peers); updategroup(g); break; } case GROUP_TITLE: { GROUPCHAT *g = &group[param1]; if (param2 > sizeof(g->name)) { memcpy(g->name, data, sizeof(g->name)); g->name_length = sizeof(g->name); } else { memcpy(g->name, data, param2); g->name_length = param2; } free(data); updategroup(g); break; } case GROUP_AUDIO_START: { GROUPCHAT *g = &group[param1]; if (g->type == TOX_GROUPCHAT_TYPE_AV) { g->audio_calling = 1; toxaudio_postmessage(GROUP_AUDIO_CALL_START, param1, 0, NULL); updategroup(g); } break; } case GROUP_AUDIO_END: { GROUPCHAT *g = &group[param1]; if (g->type == TOX_GROUPCHAT_TYPE_AV) { g->audio_calling = 0; toxaudio_postmessage(GROUP_AUDIO_CALL_END, param1, 0, NULL); updategroup(g); } break; } case GROUP_UPDATE: { GROUPCHAT *g = &group[param1]; updategroup(g); break; } }
void message_add_va(PlayerNumber plyr_idx, const char *fmt_str, va_list arg) { static char full_msg_text[2048]; vsprintf(full_msg_text, fmt_str, arg); message_add(plyr_idx, full_msg_text); }
/* * Print messages to standard output. */ void message_add_formatted(game *g, char *msg, char *tag) { /* Print without formatting */ message_add(g, msg); }
/* * Destroy an item */ void do_cmd_destroy(void) { int item, amt = 1; int old_number; bool force = FALSE; object_type *o_ptr; char o_name[MAX_NLEN]; char out_val[160]; cptr q, s; /* Hack -- force destruction */ if (command_arg > 0) force = TRUE; /* Get an item */ #ifdef JP q = "どのアイテムを壊しますか? "; s = "壊せるアイテムを持っていない。"; #else q = "Destroy which item? "; s = "You have nothing to destroy."; #endif if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Verify unless quantity given */ if (!force && (!(auto_destroy && (object_value(o_ptr) < 1)))) { object_desc(o_name, o_ptr, OD_OMIT_PREFIX); /* Make a verification */ sprintf(out_val, #ifdef JP "本当に%sを壊しますか? [y/n/Auto]", #else "Really destroy %s? [y/n/Auto]", #endif o_name); msg_print(NULL); /* HACK : Add the line to message buffer */ message_add(out_val); p_ptr->window |= (PW_MESSAGE); window_stuff(); /* Get an acceptable answer */ while (TRUE) { char i; /* Prompt */ prt(out_val, 0, 0); i = inkey(); /* Erase the prompt */ prt("", 0, 0); if (i == 'y' || i == 'Y') { break; } if (i == ESCAPE || i == 'n' || i == 'N') { /* Cancel */ return; } if (i == 'A') { /* Add an auto-destroy preference line */ if (autopick_autoregister(o_ptr)) { /* Auto-destroy it */ autopick_alter_item(item, TRUE); } /* The object is already destroyed. */ return; } } /* while (TRUE) */ } /* See how many items */ if (o_ptr->number > 1) { /* Get a quantity */ amt = get_quantity(NULL, o_ptr->number); /* Allow user abort */ if (amt <= 0) return; } /* Describe the object */ old_number = o_ptr->number; o_ptr->number = amt; object_desc(o_name, o_ptr, 0); o_ptr->number = old_number; /* Take a turn */ energy_use = 100; /* Can the player destroy the object? */ if (!can_player_destroy_object(o_ptr)) { /* Don't take a turn */ energy_use = 0; /* Message */ #ifdef JP msg_format("%sは破壊不可能だ。", o_name); #else msg_format("You cannot destroy %s.", o_name); #endif /* Done */ return; } /* Message */ #ifdef JP msg_format("%sを壊した。", o_name); #else msg_format("You destroy %s.", o_name); #endif sound(SOUND_DESTROY); if (high_level_book(o_ptr)) { bool gain_expr = FALSE; if (p_ptr->pclass == CLASS_WARRIOR) { gain_expr = TRUE; } else if (p_ptr->pclass == CLASS_PALADIN) { if (p_ptr->realm1 == REALM_LIFE) { if (o_ptr->tval != TV_LIFE_BOOK) gain_expr = TRUE; } else { if (o_ptr->tval == TV_LIFE_BOOK) gain_expr = TRUE; } } if (gain_expr && (p_ptr->exp < PY_MAX_EXP)) { s32b tester_exp = p_ptr->max_exp / 20; if (tester_exp > 10000) tester_exp = 10000; if (o_ptr->sval < 3) tester_exp /= 4; if (tester_exp < 1) tester_exp = 1; #ifdef JP msg_print("更に経験を積んだような気がする。"); #else msg_print("You feel more experienced."); #endif gain_exp(tester_exp * amt); } } /* Reduce the charges of rods/wands */ reduce_charges(o_ptr, amt); /* Eliminate the item (from the pack) */ if (item >= 0) { inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); } /* Eliminate the item (from the floor) */ else { floor_item_increase(0 - item, -amt); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
void global_message_args(long targets, const char *language_entry, ...) { struct globalMessage *message = NULL; va_list arg_list; dict_iterator_t it; char response[MAXLEN]; const char *fmt; if(!targets || !global) return; fmt = strdup(language_entry); /* Notice users/opers/helpers */ for (it = dict_first(clients); it; it = iter_next(it)) { struct userNode *luser = iter_data(it); language_entry = user_find_message(luser, fmt); va_start(arg_list, language_entry); vsnprintf(response, MAXLEN-2, language_entry, arg_list); response[MAXLEN-1] = 0; if (message) message_del(message); message = message_add(targets | MESSAGE_OPTION_SOURCELESS, now, 0, "", response); if (!message) continue; /* opers */ if(message->flags & MESSAGE_RECIPIENT_OPERS && IsOper(luser)) { if(luser->uplink != self) notice_target(luser->nick, message); if ((message->flags & MESSAGE_RECIPIENT_LUSERS) || (message->flags & MESSAGE_RECIPIENT_HELPERS) || (message->flags & MESSAGE_RECIPIENT_AUTHED)) continue; } /* helpers */ if (message->flags & MESSAGE_RECIPIENT_HELPERS && IsHelper(luser)) { notice_target(luser->nick, message); if ((message->flags & MESSAGE_RECIPIENT_LUSERS) || (message->flags & MESSAGE_RECIPIENT_AUTHED)) continue; } /* authed */ if ((message->flags & MESSAGE_RECIPIENT_AUTHED) && luser->handle_info) { notice_target(luser->nick, message); if (message->flags & MESSAGE_RECIPIENT_LUSERS) continue; } /* users */ if (message->flags & MESSAGE_RECIPIENT_LUSERS) { notice_target(luser->nick, message); } } message_del(message); }
static struct globalMessage* message_create(struct userNode *user, unsigned int argc, char *argv[]) { unsigned long duration = 0; char *text = NULL; char *sender; long flags = 0; unsigned int i; sender = user->handle_info->handle; for(i = 0; i < argc; i++) { if((i + 1) > argc) { global_notice(user, "MSG_MISSING_PARAMS", argv[argc]); return NULL; } if(!irccasecmp(argv[i], "text")) { i++; text = unsplit_string(argv + i, argc - i, NULL); break; } else if (!irccasecmp(argv[i], "sourceless")) { i++; flags |= MESSAGE_OPTION_SOURCELESS; } else if (!irccasecmp(argv[i], "target")) { i++; if(!irccasecmp(argv[i], "all")) { flags |= MESSAGE_RECIPIENT_ALL; } else if(!irccasecmp(argv[i], "authed")) { flags |= MESSAGE_RECIPIENT_AUTHED; } else if(!irccasecmp(argv[i], "users")) { flags |= MESSAGE_RECIPIENT_LUSERS; } else if(!irccasecmp(argv[i], "helpers")) { flags |= MESSAGE_RECIPIENT_HELPERS; } else if(!irccasecmp(argv[i], "opers")) { flags |= MESSAGE_RECIPIENT_OPERS; } else if(!irccasecmp(argv[i], "staff") || !irccasecmp(argv[i], "privileged")) { flags |= MESSAGE_RECIPIENT_STAFF; } else if(!irccasecmp(argv[i], "channels")) { flags |= MESSAGE_RECIPIENT_CHANNELS; } else if(!irccasecmp(argv[i], "rchannels")) { flags |= MESSAGE_RECIPIENT_RCHANNELS; } else if(!irccasecmp(argv[i], "announcement") || !irccasecmp(argv[i], "announce")) { flags |= MESSAGE_RECIPIENT_ANNOUNCE; } else { global_notice(user, "GMSG_INVALID_TARGET", argv[i]); return NULL; } } else if (irccasecmp(argv[i], "duration") == 0) { duration = ParseInterval(argv[++i]); } else if (irccasecmp(argv[i], "from") == 0) { sender = argv[++i]; } else { global_notice(user, "MSG_INVALID_CRITERIA", argv[i]); return NULL; } } if(!flags) { flags = MESSAGE_RECIPIENT_LUSERS; } if(!text) { global_notice(user, "GMSG_MESSAGE_REQUIRED"); return NULL; } return message_add(flags, now, duration, sender, text); }