void gen_board_list(struct board_data *board, struct creature *ch) { PGresult *res; char time_buf[30]; int idx, count; time_t post_time; res = sql_query ("select extract(epoch from post_time), name, subject from board_messages where board='%s' order by idnum desc", tmp_sqlescape(board->name)); count = PQntuples(res); if (count == 0) { send_to_char(ch, "This board is empty.\r\n"); return; } acc_string_clear(); acc_sprintf ("This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>\r\n%sThere %s %d message%s on the board.%s\r\n", CCGRN(ch, C_NRM), (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s", CCNRM(ch, C_NRM)); for (idx = 0; idx < count; idx++) { post_time = atol(PQgetvalue(res, idx, 0)); strftime(time_buf, 30, "%b %e, %Y", localtime(&post_time)); acc_sprintf("%s%-2d %s:%s %s %-12s :: %s\r\n", CCGRN(ch, C_NRM), count - idx, CCRED(ch, C_NRM), CCNRM(ch, C_NRM), time_buf, tmp_sprintf("(%s)", PQgetvalue(res, idx, 1)), PQgetvalue(res, idx, 2)); } page_string(ch->desc, acc_get_string()); }
void check_attack(struct creature *attacker, struct creature *victim) { bool is_bountied(struct creature *hunter, struct creature *vict); struct creature *perp; // No reputation for attacking in arena if (is_arena_combat(attacker, victim)) return; perp = find_responsible_party(attacker, victim); // no reputation for attacking a bountied person if (is_bountied(perp, victim)) return; int gain = pk_reputation_gain(perp, victim); if (!gain) return; gain = MAX(1, gain / 5); gain_reputation(perp, gain); send_to_char(perp, "%sYou have gained %d reputation for viciously attacking %s.%s\r\n", CCRED(perp, C_NRM), gain, GET_NAME(victim), CCNRM(perp, C_NRM)); send_to_char(victim, "%s%s has gained %d reputation for viciously attacking you.%s\r\n", CCYEL(victim, C_NRM), GET_NAME(perp), gain, CCNRM(victim, C_NRM)); mudlog(LVL_IMMORT, CMP, true, "%s gained %d reputation for attacking %s", GET_NAME(perp), gain, GET_NAME(victim)); create_grievance(victim, perp, gain, ATTACK); }
void check_thief(struct creature *ch, struct creature *victim) { struct creature *perp; // First we need to find the perp perp = find_responsible_party(ch, victim); int gain = pk_reputation_gain(perp, victim); if (!gain) return; gain = MAX(1, gain / 10); gain_reputation(perp, gain); send_to_char(perp, "%sYou have gained %d reputation for stealing from %s.%s\r\n", CCRED(perp, C_NRM), gain, GET_NAME(victim), CCNRM(perp, C_NRM)); send_to_char(victim, "%s%s has gained %d reputation for stealing from you.%s\r\n", CCYEL(victim, C_NRM), GET_NAME(perp), gain, CCNRM(victim, C_NRM)); mudlog(LVL_IMMORT, CMP, true, "%s gained %d reputation for stealing from %s", GET_NAME(perp), gain, GET_NAME(victim)); create_grievance(victim, perp, gain, THEFT); if (is_arena_combat(ch, victim)) mudlog(LVL_POWER, CMP, true, "%s pstealing from %s in arena", GET_NAME(perp), GET_NAME(victim)); }
void count_pkill(struct creature *killer, struct creature *victim) { bool award_bounty(struct creature *, struct creature *); struct creature *perp; if (is_arena_combat(killer, victim)) return; perp = find_responsible_party(killer, victim); GET_PKILLS(perp)++; if (award_bounty(perp, victim)) return; int gain = pk_reputation_gain(perp, victim); if (!gain) return; gain_reputation(perp, gain); send_to_char(perp, "%sYou have gained %d reputation for heinously murdering %s.%s\r\n", CCRED(killer, C_NRM), gain, GET_NAME(victim), CCNRM(perp, C_NRM)); send_to_char(victim, "%s%s has gained %d reputation for heinously murdering you.%s\r\n", CCYEL(killer, C_NRM), GET_NAME(perp), gain, CCNRM(victim, C_NRM)); mudlog(LVL_IMMORT, CMP, true, "%s gained %d reputation for murdering %s", GET_NAME(perp), gain, GET_NAME(victim)); create_grievance(victim, perp, gain, MURDER); }
// юзается исключительно в act.wizards.cpp в имм командах "advance" и "set exp". void gain_exp_regardless(CHAR_DATA * ch, int gain) { int is_altered = FALSE; int num_levels = 0; ch->set_exp(ch->get_exp() + gain); if (!IS_NPC(ch)) { if (gain > 0) { while (GET_LEVEL(ch) < LVL_IMPL && GET_EXP(ch) >= level_exp(ch, GET_LEVEL(ch) + 1)) { ch->set_level(ch->get_level() + 1); num_levels++; sprintf(buf, "%sВы достигли следующего уровня!%s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM)); send_to_char(buf, ch); advance_level(ch); is_altered = TRUE; } if (is_altered) { sprintf(buf, "%s advanced %d level%s to level %d.", GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch)); mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE); } } else if (gain < 0) { // Pereplut: глупый участок кода. // gain = MAX(-max_exp_loss_pc(ch), gain); // Cap max exp lost per death // GET_EXP(ch) += gain; // if (GET_EXP(ch) < 0) // GET_EXP(ch) = 0; while (GET_LEVEL(ch) > 1 && GET_EXP(ch) < level_exp(ch, GET_LEVEL(ch))) { ch->set_level(ch->get_level() - 1); num_levels++; sprintf(buf, "%sВы потеряли уровень!%s\r\n", CCIRED(ch, C_NRM), CCNRM(ch, C_NRM)); send_to_char(buf, ch); decrease_level(ch); is_altered = TRUE; } if (is_altered) { sprintf(buf, "%s decreases %d level%s to level %d.", GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch)); mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE); } } } }
void perform_tell(CHAR_DATA * ch, CHAR_DATA * vict, char *arg) { // shapirus: не позволим телять, если жертва не видит и включила // соответствующий режим; имморталы могут телять всегда if (PRF_FLAGGED(vict, PRF_NOINVISTELL) && !CAN_SEE(vict, ch) && GET_LEVEL(ch) < LVL_IMMORT && !PRF_FLAGGED(ch, PRF_CODERINFO)) { act("$N не любит разговаривать с теми, кого не видит.", FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP); return; } // TODO: если в act() останется показ иммов, то это и эхо ниже переделать на act() if (tell_can_see(ch, vict)) { snprintf(buf, MAX_STRING_LENGTH, "%s сказал%s вам : '%s'", GET_NAME(ch), GET_CH_SUF_1(ch), arg); } else { snprintf(buf, MAX_STRING_LENGTH, "Кто-то сказал вам : '%s'", arg); } snprintf(buf1, MAX_STRING_LENGTH, "%s%s%s\r\n", CCICYN(vict, C_NRM), CAP(buf), CCNRM(vict, C_NRM)); send_to_char(buf1, vict); if (!IS_NPC(vict)) { vict->remember_add(buf1, Remember::ALL); } if (!IS_NPC(vict) && !IS_NPC(ch)) { snprintf(buf, MAX_STRING_LENGTH, "%s%s : '%s'%s\r\n", CCICYN(ch, C_NRM), tell_can_see(ch, vict) ? GET_NAME(ch) : "Кто-то", arg, CCNRM(ch, C_NRM)); vict->remember_add(buf, Remember::PERSONAL); } if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT)) { send_to_char(OK, ch); } else { snprintf(buf, MAX_STRING_LENGTH, "%sВы сказали %s : '%s'%s\r\n", CCICYN(ch, C_NRM), tell_can_see(vict, ch) ? vict->player_data.PNames[2] : "кому-то", arg, CCNRM(ch, C_NRM)); send_to_char(buf, ch); if (!IS_NPC(ch)) { ch->remember_add(buf, Remember::ALL); } } if (!IS_NPC(vict) && !IS_NPC(ch)) { vict->set_answer_id(GET_IDNUM(ch)); } }
void perform_mob_flag_list(struct char_data * ch, char *arg) { int num, mob_flag, found = 0, len; struct char_data *mob; char buf[MAX_STRING_LENGTH]; mob_flag = atoi(arg); if (mob_flag < 0 || mob_flag > NUM_MOB_FLAGS) { send_to_char(ch, "Invalid flag number!\r\n"); return; } len = snprintf(buf, sizeof(buf), "Listing mobiles with %s%s%s flag set.\r\n", QYEL, action_bits[mob_flag], QNRM); for(num=0;num<=top_of_mobt;num++) { if(IS_SET_AR((mob_proto[num].char_specials.saved.act), mob_flag)) { if ((mob = read_mobile(num, REAL)) != NULL) { char_to_room(mob, 0); len += snprintf(buf + len, sizeof(buf) - len, "%s%3d. %s[%s%5d%s]%s Level %s%-3d%s %s%s\r\n", CCNRM(ch, C_NRM),++found, CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_MOB_VNUM(mob), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM), CCYEL(ch, C_NRM), GET_LEVEL(mob), CCNRM(ch, C_NRM), GET_NAME(mob), CCNRM(ch, C_NRM)); extract_char(mob); /* Finished with the mob - remove it from the MUD */ if (len > sizeof(buf)) break; } } } if (!found) send_to_char(ch,"None Found!\r\n"); else page_string(ch->desc, buf, TRUE); return; }
void perform_mob_level_list(struct char_data * ch, char *arg) { int num, mob_level, found = 0, len; struct char_data *mob; char buf[MAX_STRING_LENGTH]; mob_level = atoi(arg); if (mob_level < 0 || mob_level > 99) { send_to_char(ch, "Invalid mob level!\r\n"); return; } len = snprintf(buf, sizeof(buf), "Listing mobiles of level %s%d%s\r\n", QYEL, mob_level, QNRM); for(num=0;num<=top_of_mobt;num++) { if((mob_proto[num].player.level) == mob_level) { if ((mob = read_mobile(num, REAL)) != NULL) { char_to_room(mob, 0); len += snprintf(buf + len, sizeof(buf) - len, "%s%3d. %s[%s%5d%s]%s %s%s\r\n", CCNRM(ch, C_NRM),++found, CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_MOB_VNUM(mob), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM), GET_NAME(mob), CCNRM(ch, C_NRM)); extract_char(mob); /* Finished with the mob - remove it from the MUD */ if (len > sizeof(buf)) break; } } } if (!found) send_to_char(ch,"None Found!\r\n"); else page_string(ch->desc, buf, TRUE); return; }
/* Set the color string pointers for that which this char will see at color * level NRM. Changing the entries here will change the colour scheme * throughout the OLC. */ void get_char_colors(struct char_data *ch) { nrm = CCNRM(ch, C_NRM); grn = CCGRN(ch, C_NRM); cyn = CCCYN(ch, C_NRM); yel = CCYEL(ch, C_NRM); }
void gods_day_now(CHAR_DATA * ch) { char mono[MAX_INPUT_LENGTH], poly[MAX_INPUT_LENGTH], real[MAX_INPUT_LENGTH]; *mono=0; *poly=0; *real=0; std::string mono_name = Celebrates::get_name_mono(Celebrates::get_mud_day()); std::string poly_name = Celebrates::get_name_poly(Celebrates::get_mud_day()); std::string real_name = Celebrates::get_name_real(Celebrates::get_real_day()); if (IS_IMMORTAL(ch)) { sprintf(poly, "Язычники : %s Нет праздника. %s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM)); sprintf(mono, "Христиане: %s Нет праздника. %s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM)); sprintf(real, "В реальном мире: %s Нет праздника. %s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM)); if (mono_name != "") { sprintf(mono, "Христиане: %s %s. %s\r\n", CCWHT(ch, C_NRM), mono_name.c_str(), CCNRM(ch, C_NRM)); } if (poly_name != "") { sprintf(poly, "Язычники : %s %s. %s\r\n", CCWHT(ch, C_NRM), poly_name.c_str(), CCNRM(ch, C_NRM)); } sprintf(mono + strlen(mono), "Пасха : %d.%02d\r\n", EasterDay + 1, EasterMonth + 1); send_to_char(poly, ch); send_to_char(mono, ch); } else if (GET_RELIGION(ch) == RELIGION_POLY) { if (poly_name != "") { sprintf(poly, "%s Сегодня %s. %s\r\n", CCWHT(ch, C_NRM), poly_name.c_str(), CCNRM(ch, C_NRM)); send_to_char(poly, ch); } } else if (GET_RELIGION(ch) == RELIGION_MONO) { if (mono_name != "") { sprintf(mono, "%s Сегодня %s. %s\r\n", CCWHT(ch, C_NRM), mono_name.c_str(), CCNRM(ch, C_NRM)); send_to_char(mono, ch); } } if (real_name != "") { sprintf(real, "В реальном мире : %s %s. %s\r\n", CCWHT(ch, C_NRM), real_name.c_str(), CCNRM(ch, C_NRM)); } send_to_char(real, ch); }
/* * Set the colour string pointers for that which this char will * see at color level NRM. Changing the entries here will change * the colour scheme throughout the OLC. */ void get_char_cols(CHAR_DATA * ch) { nrm = CCNRM(ch, C_NRM); grn = CCGRN(ch, C_NRM); cyn = CCCYN(ch, C_NRM); yel = CCYEL(ch, C_NRM); iyel = CCIYEL(ch, C_NRM); ired = CCIRED(ch, C_NRM); }
void perform_tell(struct char_data *ch, struct char_data *vict, char *arg) { struct descriptor_data *i; send_to_char(CCRED(vict, C_NRM), vict); sprintf(buf, "$n tells you, '%s'", arg); if (GET_LEVEL(ch) >= LVL_IMMORT) sprintf(buf1, "%s tells you, '%s'", CAN_SEE(vict, ch) ? GET_NAME(ch) : "An Immortal", arg); else sprintf(buf1, "%s tells you, '%s'", CAN_SEE(vict, ch) ? GET_NAME(ch) : "Someone", arg); logthistory(buf1, vict); act(buf, FALSE, ch, 0, vict, TO_VICT | TO_SLEEP); send_to_char(CCNRM(vict, C_NRM), vict); if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT)) send_to_char(OK, ch); else { send_to_char(CCRED(ch, C_CMP), ch); sprintf(buf, "You tell $N, '%s'", arg); if (GET_LEVEL(vict) < LVL_IMMORT) sprintf(buf1, "You tell %s, '%s'", CAN_SEE(ch, vict) ? GET_NAME(vict) : "Someone",arg); else sprintf(buf1, "You tell %s, '%s'", CAN_SEE(ch, vict) ? GET_NAME(vict) : "An Immortal",arg); logthistory(buf1, ch); act(buf, FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP); send_to_char(CCNRM(ch, C_CMP), ch); } for (i = descriptor_list; i; i = i->next) if (STATE(i) == CON_PLAYING && i != ch->desc && i != vict->desc && PRF_FLAGGED2(i->character, PRF2_HEARALLTELL) && GET_LEVEL(i->character) == LVL_IMPL && !IS_NPC(ch) && !IS_NPC(vict)) { send_to_char(CCRED(i->character, C_CMP), i->character); sprintf(buf, ">> %s tells %s, '%s'\r\n", GET_NAME(ch), GET_NAME(vict), arg); send_to_char(buf, i->character); send_to_char(CCNRM(i->character, C_CMP), i->character); } if (!IS_NPC(vict) && !IS_NPC(ch)) GET_LAST_TELL(vict) = GET_IDNUM(ch); }
static void perform_tell(struct char_data *ch, struct char_data *vict, char *arg) { char buf[MAX_STRING_LENGTH], *msg; snprintf(buf, sizeof(buf), "%s$n tells you, '%s'%s", CCRED(vict, C_NRM), arg, CCNRM(vict, C_NRM)); msg = act(buf, FALSE, ch, 0, vict, TO_VICT | TO_SLEEP); add_history(vict, msg, HIST_TELL); if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT)) send_to_char(ch, "%s", CONFIG_OK); else { snprintf(buf, sizeof(buf), "%sYou tell $N, '%s'%s", CCRED(ch, C_NRM), arg, CCNRM(ch, C_NRM)); msg = act(buf, FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP); add_history(ch, msg, HIST_TELL); } if (!IS_NPC(vict) && !IS_NPC(ch)) GET_LAST_TELL(vict) = GET_IDNUM(ch); }
void perform_tell(struct char_data *ch, struct char_data *vict, char *arg) { char buf[MAX_STRING_LENGTH]; send_to_char(vict, "%s", CCRED(vict, C_NRM)); snprintf(buf, sizeof(buf), "$n tells you, '%s'", arg); act(buf, FALSE, ch, 0, vict, TO_VICT | TO_SLEEP); send_to_char(vict, "%s", CCNRM(vict, C_NRM)); if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT)) send_to_char(ch, "%s", OK); else { send_to_char(ch, "%s", CCRED(ch, C_CMP)); snprintf(buf, sizeof(buf), "You tell $N, '%s'", arg); act(buf, FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP); send_to_char(ch, "%s", CCNRM(ch, C_CMP)); } if (!IS_NPC(vict) && !IS_NPC(ch)) GET_LAST_TELL(vict) = GET_IDNUM(ch); }
void enchant::print(CHAR_DATA *ch) const { send_to_char(ch, "Зачаровано %s :%s\r\n", name_.c_str(), CCCYN(ch, C_NRM)); for (std::vector<obj_affected_type>::const_iterator i = affected_.begin(), iend = affected_.end(); i != iend; ++i) { print_obj_affects(ch, *i); } if (sprintbits(affects_flags_, weapon_affects, buf2, ",")) { send_to_char(ch, "%s аффекты: %s%s\r\n", CCCYN(ch, C_NRM), buf2, CCNRM(ch, C_NRM)); } if (sprintbits(extra_flags_, extra_bits, buf2, ",")) { send_to_char(ch, "%s экстрафлаги: %s%s\r\n", CCCYN(ch, C_NRM), buf2, CCNRM(ch, C_NRM)); } if (sprintbits(no_flags_, no_bits, buf2, ",")) { send_to_char(ch, "%s неудобен: %s%s\r\n", CCCYN(ch, C_NRM), buf2, CCNRM(ch, C_NRM)); } if (weight_ != 0) { send_to_char(ch, "%s %s вес на %d%s\r\n", CCCYN(ch, C_NRM), weight_ > 0 ? "увеличивает" : "уменьшает", abs(weight_), CCNRM(ch, C_NRM)); } if (ndice_ != 0 || sdice_ != 0) { if (ndice_ >= 0 && sdice_ >= 0) { send_to_char(ch, "%s увеличивает урон на %dD%d%s\r\n", CCCYN(ch, C_NRM), abs(ndice_), abs(sdice_), CCNRM(ch, C_NRM)); } else if (ndice_ <= 0 && sdice_ <= 0) { send_to_char(ch, "%s уменьшает урон на %dD%d%s\r\n", CCCYN(ch, C_NRM), abs(ndice_), abs(sdice_), CCNRM(ch, C_NRM)); } else { send_to_char(ch, "%s изменяет урон на %+dD%+d%s\r\n", CCCYN(ch, C_NRM), ndice_, sdice_, CCNRM(ch, C_NRM)); } } }
void medit_disp_class_menu(struct descriptor_data *d) { int c; CLS(CH); for (c = 0; c < NUM_MOB_CLASSES; c++) { send_to_char(CH, "%2d) %-20s\r\n", c + 1, npc_classes[c]); } sprinttype(GET_RACE(MOB), npc_classes, buf1); send_to_char(CH, "Mob class: %s%s%s\r\n" "Enter mob class, 0 to quit: ", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); }
/* * auction_output : takes two strings and dispenses them to everyone connected * based on if they have color on or not. Note that the buf's are * commonly used *color and *black so I allocate my own buffer. */ void auction_output(char *color, char *black) { char buffer[MAX_STRING_LENGTH]; struct descriptor_data *d; if (!auction.auctioneer) auction.auctioneer = str_dup(DEFAULT_AUCTIONEER); for (d = descriptor_list; d; d = d->next) if (!d->connected && d->character && !PLR_FLAGGED(d->character, PLR_WRITING) && !PRF_FLAGGED(d->character, PRF_NOAUCT) && !ROOM_FLAGGED(d->character->in_room, ROOM_SOUNDPROOF) && !ROOM_FLAGGED(d->character->in_room, ROOM_PRISON)) { sprintf(buffer, "%s%s%s auctions, '%s%s%s'%s\r\n", CCMAG(d->character,C_NRM), auction.auctioneer, CCCYN(d->character,C_NRM), CCNRM(d->character,C_NRM), (COLOR_LEV(d->character) > C_NRM) ? color : black, CCMAG(d->character,C_NRM),CCNRM(d->character,C_NRM)); send_to_char(buffer, d->character); } }
// вывод списка неодобренных имму void NewNameShow(CHAR_DATA * ch) { if (NewNameList.empty()) return; std::ostringstream buffer; buffer << "\r\nИгроки, ждущие одобрения имени (имя <игрок> одобрить/запретить/удалить):\r\n" << CCWHT(ch, C_NRM); for (NewNameListType::const_iterator it = NewNameList.begin(); it != NewNameList.end(); ++it) buffer << "Имя: " << it->first << " " << it->second->name0 << "/" << it->second->name1 << "/" << it->second->name2 << "/" << it->second->name3 << "/" << it->second->name4 << "/" << it->second->name5 << " Email: &S" << (GET_GOD_FLAG(ch, GF_DEMIGOD) ? "неопределен" : it->second->email) << "&s Пол: " << genders[it->second->sex] << "\r\n"; buffer << CCNRM(ch, C_NRM); send_to_char(buffer.str(), ch); }
void medit_disp_skill_menu(struct descriptor_data *d) { CLS(CH); send_to_char(CH, "1) Skill: %s%s%s (%s%d%s)\r\n", CCCYN(CH, C_CMP), skills[MOB->mob_specials.mob_skills[0]].name, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->mob_specials.mob_skills[1], CCNRM(CH, C_CMP)); send_to_char(CH, "2) Skill: %s%s%s (%s%d%s)\r\n", CCCYN(CH, C_CMP), skills[MOB->mob_specials.mob_skills[2]].name, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->mob_specials.mob_skills[3], CCNRM(CH, C_CMP)); send_to_char(CH, "3) Skill: %s%s%s (%s%d%s)\r\n", CCCYN(CH, C_CMP), skills[MOB->mob_specials.mob_skills[4]].name, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->mob_specials.mob_skills[5], CCNRM(CH, C_CMP)); send_to_char(CH, "4) Skill: %s%s%s (%s%d%s)\r\n", CCCYN(CH, C_CMP), skills[MOB->mob_specials.mob_skills[6]].name, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->mob_specials.mob_skills[7], CCNRM(CH, C_CMP)); send_to_char(CH, "5) Skill: %s%s%s (%s%d%s)\r\n", CCCYN(CH, C_CMP), skills[MOB->mob_specials.mob_skills[8]].name, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->mob_specials.mob_skills[9], CCNRM(CH, C_CMP)); send_to_char("0) Quit\r\n", CH); send_to_char("Enter your choice: ", CH); }
/* * message for doing damage with a spell or skill * C3.0: Also used for weapon damage on miss and death blows */ int skill_message(int dam, struct char_data * ch, struct char_data * vict, int attacktype) { int i, j, nr; struct message_type *msg; struct obj_data *weap = GET_EQ(ch, WEAR_WIELD); for (i = 0; i < MAX_MESSAGES; i++) { if (fight_messages[i].a_type == attacktype) { nr = dice(1, fight_messages[i].number_of_attacks); for (j = 1, msg = fight_messages[i].msg; (j < nr) && msg; j++) msg = msg->next; if (!IS_NPC(vict) && (GET_LEVEL(vict) >= LVL_IMMORT)) { act(msg->god_msg.attacker_msg, FALSE, ch, weap, vict, TO_CHAR); act(msg->god_msg.victim_msg, FALSE, ch, weap, vict, TO_VICT); act(msg->god_msg.room_msg, FALSE, ch, weap, vict, TO_NOTVICT); } else if (dam != 0) { if (GET_POS(vict) == POS_DEAD) { send_to_char(CCYEL(ch, C_CMP), ch); act(msg->die_msg.attacker_msg, FALSE, ch, weap, vict, TO_CHAR); send_to_char(CCNRM(ch, C_CMP), ch); send_to_char(CCRED(vict, C_CMP), vict); act(msg->die_msg.victim_msg, FALSE, ch, weap, vict, TO_VICT | TO_SLEEP); send_to_char(CCNRM(vict, C_CMP), vict); act(msg->die_msg.room_msg, FALSE, ch, weap, vict, TO_NOTVICT); } else { send_to_char(CCYEL(ch, C_CMP), ch); act(msg->hit_msg.attacker_msg, FALSE, ch, weap, vict, TO_CHAR); send_to_char(CCNRM(ch, C_CMP), ch); send_to_char(CCRED(vict, C_CMP), vict); act(msg->hit_msg.victim_msg, FALSE, ch, weap, vict, TO_VICT | TO_SLEEP); send_to_char(CCNRM(vict, C_CMP), vict); act(msg->hit_msg.room_msg, FALSE, ch, weap, vict, TO_NOTVICT); } } else if (ch != vict) { /* Dam == 0 */ send_to_char(CCYEL(ch, C_CMP), ch); act(msg->miss_msg.attacker_msg, FALSE, ch, weap, vict, TO_CHAR); send_to_char(CCNRM(ch, C_CMP), ch); send_to_char(CCRED(vict, C_CMP), vict); act(msg->miss_msg.victim_msg, FALSE, ch, weap, vict, TO_VICT | TO_SLEEP); send_to_char(CCNRM(vict, C_CMP), vict); act(msg->miss_msg.room_msg, FALSE, ch, weap, vict, TO_NOTVICT); } return (1); } } return (0); }
void gen_board_read(struct board_data *board, struct creature *ch, char *argument) { struct creature *player; PGresult *res; time_t post_time; char time_buf[30]; int idx; if (IS_PC(ch)) player = ch; else if (ch->desc && ch->desc->original) player = ch->desc->original; else { send_to_char(ch, "You're a mob. Go awei.\r\n"); return; } if (ALLOW != react(board->read_perms, player)) { send_to_char(ch, "%s\r\n", board->deny_read); return; } idx = atoi(argument) - 1; if (idx < 0) { send_to_char(ch, "That is not a valid message.\r\n"); return; } res = sql_query ("select extract(epoch from post_time), name, subject, body from board_messages where board='%s' order by idnum limit 1 offset %d", tmp_sqlescape(board->name), idx); if (PQntuples(res) == 0) { send_to_char(ch, "That message does not exist on this board.\r\n"); return; } acc_string_clear(); post_time = atol(PQgetvalue(res, 0, 0)); strftime(time_buf, 30, "%a %b %e %Y", localtime(&post_time)); acc_sprintf("%sMessage %s : %s %-12s :: %s%s\r\n\r\n%s\r\n", CCBLD(ch, C_CMP), argument, time_buf, tmp_sprintf("(%s)", PQgetvalue(res, 0, 1)), CCNRM(ch, C_CMP), PQgetvalue(res, 0, 2), PQgetvalue(res, 0, 3)); page_string(ch->desc, acc_get_string()); }
void handle_recall_spells(CHAR_DATA* ch) { AFFECT_DATA* aff = NULL; for(AFFECT_DATA* af = ch->affected; af; af = af->next) if (af->type == SPELL_RECALL_SPELLS) { aff = af; break; } if (!aff) return; //максимальный доступный чару круг unsigned max_slot = get_max_slot(ch); //обрабатываем только каждые RECALL_SPELLS_INTERVAL секунд int secs_left = (SECS_PER_PLAYER_AFFECT*aff->duration)/SECS_PER_MUD_HOUR -SECS_PER_PLAYER_AFFECT; if (secs_left / RECALL_SPELLS_INTERVAL < max_slot -aff->modifier || secs_left <= 2) { int slot_to_restore = aff->modifier++; bool found_spells = false; struct spell_mem_queue_item *next = NULL, *prev=NULL, *i = ch->MemQueue.queue; while (i) { next = i->link; if (spell_info[i->spellnum].slot_forc[(int) GET_CLASS(ch)][(int) GET_KIN(ch)] == slot_to_restore) { if (!found_spells) { send_to_char("Ваша голова прояснилась, в памяти всплыло несколько новых заклинаний.\r\n", ch); found_spells = true; } if (prev) prev->link = next; if (i == ch->MemQueue.queue) { ch->MemQueue.queue = next; GET_MEM_COMPLETED(ch) = 0; } GET_MEM_TOTAL(ch) = MAX(0, GET_MEM_TOTAL(ch) - mag_manacost(ch, i->spellnum)); sprintf(buf, "Вы вспомнили заклинание \"%s%s%s\".\r\n", CCICYN(ch, C_NRM), spell_info[i->spellnum].name, CCNRM(ch, C_NRM)); send_to_char(buf, ch); GET_SPELL_MEM(ch, i->spellnum)++; free(i); } else prev = i; i = next; } } }
void medit_disp_att_menu(struct descriptor_data *d) { CLS(CH); send_to_char(CH, "1) Body: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_BOD(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "2) Quickness: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_QUI(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "3) Strength: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_STR(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "4) Charisma: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_CHA(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "5) Intel.: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_INT(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "6) Willpower: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_REAL_WIL(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "7) Magic: %s%d%s\r\n", CCCYN(CH, C_CMP), MOB->real_abils.mag / 100, CCNRM(CH, C_CMP)); send_to_char(CH, "q) Quit\r\n"); send_to_char("\r\nEnter your choice:\r\n", CH); d->edit_mode = MEDIT_ATTRIBUTES; }
// Returns a tmpstr allocated char* containing an appropriate ANSI // color code for the given target struct creature (tch) with the given // recipient struct creature(ch)'s color settings in mind. const char * get_char_class_color_code(struct creature *ch, struct creature *tch, int char_class) { switch (char_class) { case CLASS_MAGIC_USER: return CCMAG(ch, C_NRM); case CLASS_CLERIC: if (IS_GOOD(tch)) { return CCBLU_BLD(ch, C_NRM); } else if (IS_EVIL(tch)) { return CCRED_BLD(ch, C_NRM); } else { return CCYEL(ch, C_NRM); } case CLASS_KNIGHT: if (IS_GOOD(tch)) { return CCBLU_BLD(ch, C_NRM); } else if (IS_EVIL(tch)) { return CCRED(ch, C_NRM); } else { return CCYEL(ch, C_NRM); } case CLASS_RANGER: return CCGRN(ch, C_NRM); case CLASS_BARB: return CCCYN(ch, C_NRM); case CLASS_THIEF: return CCNRM_BLD(ch, C_NRM); case CLASS_CYBORG: return CCCYN(ch, C_NRM); case CLASS_PSIONIC: return CCMAG(ch, C_NRM); case CLASS_PHYSIC: return CCNRM_BLD(ch, C_NRM); case CLASS_BARD: return CCYEL_BLD(ch, C_NRM); case CLASS_MONK: return CCGRN(ch, C_NRM); case CLASS_MERCENARY: return CCYEL(ch, C_NRM); default: return CCNRM(ch, C_NRM); } }
void medit_disp_affected_menu(struct descriptor_data *d) { int c; CLS(CH); for (c = 0; c < AFF_MAX; c += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", c + 1, affected_bits[c], c + 2, c + 1 < AFF_MAX ? affected_bits[c + 1] : ""); } AFF_FLAGS(MOB).PrintBits(buf1, MAX_STRING_LENGTH, affected_bits, AFF_MAX); send_to_char(CH, "Affected flags: %s%s%s\r\n" "Enter affected flag, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); }
void medit_disp_mobflags_menu(struct descriptor_data *d) { int c; CLS(CH); for (c = 0; c < MOB_MAX; c += 2) { send_to_char(CH, "%2d) %-20s %2d) %-20s\r\n", c + 1, action_bits[c], c + 2, c + 1 < MOB_MAX ? action_bits[c + 1] : ""); } MOB_FLAGS(MOB).PrintBits(buf1, MAX_STRING_LENGTH, action_bits, MOB_MAX); send_to_char(CH, "Mob flags: %s%s%s\r\n" "Enter mob flag, 0 to quit:", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); }
void check_dyntext_updates(struct creature *ch) { dynamic_text_file *dyntext = NULL; for (dyntext = dyntext_list; dyntext; dyntext = dyntext->next) { if (dyntext->last_edit[0].tEdit > ch->account->entry_time) { if (!strcmp(dyntext->filename, "inews") && GET_LEVEL(ch) < LVL_AMBASSADOR) continue; if (!strcmp(dyntext->filename, "tnews") && GET_LEVEL(ch) < LVL_AMBASSADOR && !is_tester(ch)) continue; if (!strncmp(dyntext->filename, "fate", 4) || !strncmp(dyntext->filename, "arenalist", 9)) continue; send_to_char(ch, "%s [ The %s file has been updated. Use the %s command to view. ]%s\r\n", CCYEL(ch, C_NRM), dyntext->filename, dyntext->filename, CCNRM(ch, C_NRM)); } } }
void medit_disp_menu(struct descriptor_data *d) { int base = calc_karma(NULL, MOB); CLS(CH); send_to_char(CH, "Mob number: %s%d%s\r\n", CCCYN(CH, C_CMP), d->edit_number, CCNRM(CH, C_CMP)); send_to_char(CH, "1) Keywords: %s%s%s\r\n", CCCYN(CH, C_CMP), MOB->player.physical_text.keywords, CCNRM(CH, C_CMP)); send_to_char(CH, "2) Name: %s%s%s\r\n", CCCYN(CH, C_CMP), MOB->player.physical_text.name, CCNRM(CH, C_CMP)); send_to_char(CH, "3) Room description:\r\n%s%s%s\r\n", CCCYN(CH, C_CMP), MOB->player.physical_text.room_desc,CCNRM(CH, C_CMP)); send_to_char(CH, "4) Look description:\r\n%s\r\n", MOB->player.physical_text.look_desc); MOB_FLAGS(MOB).PrintBits(buf1, MAX_STRING_LENGTH, action_bits, MOB_MAX); send_to_char(CH, "5) Mob Flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); MOB->char_specials.saved.affected_by.PrintBits(buf1, MAX_STRING_LENGTH, affected_bits, AFF_MAX); send_to_char(CH, "6) Affected Flags: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); send_to_char(CH, "8) Avg. nuyen: %s%6d%s Avg. credstick value: %s%6d%s\r\n", CCCYN(CH, C_CMP), GET_NUYEN(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_BANK(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "9) Bonus karma points: %s%d%s (Total karma points: %s%d%s)\r\n", CCCYN(CH, C_CMP), GET_KARMA(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), base, CCNRM(CH, C_CMP)); send_to_char(CH, "a) Attributes: B(%s%d%s), Q(%s%d%s), S(%s%d%s), C(%s%d%s), " "I(%s%d%s), W(%s%d%s), M(%s%d%s), R(%s%d%s)\r\n", CCCYN(CH, C_CMP), GET_REAL_BOD(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_QUI(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_STR(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_CHA(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_INT(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_WIL(MOB), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), MOB->real_abils.mag / 100, CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), GET_REAL_REA(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "b) Level: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_LEVEL(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "c) Ballistic: %s%d%s, ", CCCYN(CH, C_CMP), GET_BALLISTIC(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "d) Impact: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_IMPACT(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "e) Max physical points: %s%d%s, f) Max mental points: %s%d%s\r\n", CCCYN(CH, C_CMP), (int)(GET_MAX_PHYSICAL(MOB) / 100), CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), (int)(GET_MAX_MENTAL(MOB) / 100), CCNRM(CH, C_CMP)); sprinttype(GET_POS(MOB), position_types, buf1); send_to_char(CH, "g) Position: %s%s%s, ", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); sprinttype(GET_DEFAULT_POS(MOB), position_types, buf1); send_to_char(CH, "h) Default Position: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); sprinttype(GET_SEX(MOB), genders, buf1); // strcpy(buf1, genders[GET_SEX(d->edit_mob)]); send_to_char(CH, "i) Gender: %s%s%s, ", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); send_to_char(CH, "j) Weight: %s%d%s, ", CCCYN(CH, C_CMP), GET_WEIGHT(MOB), CCNRM(CH, C_CMP)); send_to_char(CH, "k) Height: %s%d%s\r\n", CCCYN(CH, C_CMP), GET_HEIGHT(MOB), CCNRM(CH, C_CMP)); sprinttype(GET_RACE(MOB), npc_classes, buf1); send_to_char(CH, "l) Mob class: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); // gotta subtract TYPE_HIT to make it work properly sprinttype(!(MOB->mob_specials.attack_type) ? 0 : (MOB->mob_specials.attack_type - TYPE_HIT), attack_types, buf1); send_to_char(CH, "m) Attack Type: %s%s%s\r\n", CCCYN(CH, C_CMP), buf1, CCNRM(CH, C_CMP)); send_to_char("n) Skill menu.\r\n", CH); send_to_char(CH, "o) Arrive text: ^c%s^n, p) Leave text: ^c%s^n\r\n", MOB->mob_specials.arrive, MOB->mob_specials.leave); send_to_char("q) Quit and save\r\n", CH); send_to_char("x) Exit and abort\r\n", CH); send_to_char("Enter your choice:\r\n", CH); d->edit_mode = MEDIT_MAIN_MENU; }
/* * Alert: As of bpl14, this function returns the following codes: * < 0 Victim died. * = 0 No damage. * > 0 How much damage done. */ int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype) { if (GET_POS(victim) <= POS_DEAD) { /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */ if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET)) return (-1); log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.", GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch)); die(victim); return (-1); /* -je, 7/7/92 */ } /* peaceful rooms */ if (ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); return (0); } /* shopkeeper protection */ if (!ok_damage_shopkeeper(ch, victim)) return (0); /* You can't damage an immortal! */ if (!IS_NPC(victim) && (GET_LEVEL(victim) >= LVL_IMMORT)) dam = 0; if (victim != ch) { /* Start the attacker fighting the victim */ if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL)) set_fighting(ch, victim); /* Start the victim fighting the attacker */ if (GET_POS(victim) > POS_STUNNED && (FIGHTING(victim) == NULL)) { set_fighting(victim, ch); if (MOB_FLAGGED(victim, MOB_MEMORY) && !IS_NPC(ch)) remember(victim, ch); } } /* If you attack a pet, it hates your guts */ if (victim->master == ch) stop_follower(victim); /* If the attacker is invisible, he becomes visible */ if (AFF_FLAGGED(ch, AFF_INVISIBLE | AFF_HIDE)) appear(ch); /* Cut damage in half if victim has sanct, to a minimum 1 */ if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2) dam /= 2; /* Check for PK if this is not a PK MUD */ if (!pk_allowed) { check_killer(ch, victim); if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim)) dam = 0; } /* Set the maximum damage per round and subtract the hit points */ dam = MAX(MIN(dam, 100), 0); GET_HIT(victim) -= dam; /* Gain exp for the hit */ if (ch != victim) gain_exp(ch, GET_LEVEL(victim) * dam); update_pos(victim); /* * skill_message sends a message from the messages file in lib/misc. * dam_message just sends a generic "You hit $n extremely hard.". * skill_message is preferable to dam_message because it is more * descriptive. * * If we are _not_ attacking with a weapon (i.e. a spell), always use * skill_message. If we are attacking with a weapon: If this is a miss or a * death blow, send a skill_message if one exists; if not, default to a * dam_message. Otherwise, always send a dam_message. */ if (!IS_WEAPON(attacktype)) skill_message(dam, ch, victim, attacktype); else { if (GET_POS(victim) == POS_DEAD || dam == 0) { if (!skill_message(dam, ch, victim, attacktype)) dam_message(dam, ch, victim, attacktype); } else { dam_message(dam, ch, victim, attacktype); } } /* Use send_to_char -- act() doesn't send message if you are DEAD. */ switch (GET_POS(victim)) { case POS_MORTALLYW: act("$n is mortally wounded, and will die soon, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are mortally wounded, and will die soon, if not aided.\r\n"); break; case POS_INCAP: act("$n is incapacitated and will slowly die, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are incapacitated an will slowly die, if not aided.\r\n"); break; case POS_STUNNED: act("$n is stunned, but will probably regain consciousness again.", TRUE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You're stunned, but will probably regain consciousness again.\r\n"); break; case POS_DEAD: act("$n is dead! R.I.P.", FALSE, victim, 0, 0, CommTarget::TO_ROOM); send_to_char(victim, "You are dead! Sorry...\r\n"); break; default: /* >= POSITION SLEEPING */ if (dam > (GET_MAX_HIT(victim) / 4)) send_to_char(victim, "That really did HURT!\r\n"); if (GET_HIT(victim) < (GET_MAX_HIT(victim) / 4)) { send_to_char(victim, "%sYou wish that your wounds would stop BLEEDING so much!%s\r\n", CCRED(victim, C_SPR), CCNRM(victim, C_SPR)); if (ch != victim && MOB_FLAGGED(victim, MOB_WIMPY)) do_flee(victim, NULL, 0, 0); } if (!IS_NPC(victim) && GET_WIMP_LEV(victim) && (victim != ch) && GET_HIT(victim) < GET_WIMP_LEV(victim) && GET_HIT(victim) > 0) { send_to_char(victim, "You wimp out, and attempt to flee!\r\n"); do_flee(victim, NULL, 0, 0); } break; } /* Help out poor linkless people who are attacked */ if (!IS_NPC(victim) && !(victim->desc) && GET_POS(victim) > POS_STUNNED) { do_flee(victim, NULL, 0, 0); if (!FIGHTING(victim)) { act("$n is rescued by divine forces.", FALSE, victim, 0, 0, CommTarget::TO_ROOM); GET_WAS_IN(victim) = IN_ROOM(victim); char_from_room(victim); char_to_room(victim, 0); } } /* stop someone from fighting if they're stunned or worse */ if (GET_POS(victim) <= POS_STUNNED && FIGHTING(victim) != NULL) stop_fighting(victim); /* Uh oh. Victim died. */ if (GET_POS(victim) == POS_DEAD) { if (ch != victim && (IS_NPC(victim) || victim->desc)) { if (AFF_FLAGGED(ch, AFF_GROUP)) group_gain(ch, victim); else solo_gain(ch, victim); } if (!IS_NPC(victim)) { mudlog(BRF, LVL_IMMORT, TRUE, "%s killed by %s at %s", GET_NAME(victim), GET_NAME(ch), world[IN_ROOM(victim)].name); if (MOB_FLAGGED(ch, MOB_MEMORY)) forget(ch, victim); } die(victim); return (-1); } return (dam); }
int Board_show_board(int board_type, struct char_data * ch, char *arg) { int i; char tmp[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH]; if (!ch->desc) return 0; one_argument(arg, tmp); if (!*tmp || !isname(tmp, "board bulletin")) return 0; if (READ_LVL(board_type) != 0 && !COM_FLAGGED(ch, READ_LVL(board_type))) { send_to_char("You try but fail to understand the holy words.\r\n", ch); return 1; } act("$n studies the board.", TRUE, ch, 0, 0, TO_ROOM); strcpy(buf, "This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>.\r\n" "You will need to look at the board to save your message.\r\n"); if (!num_of_msgs[board_type]) strcat(buf, "The board is empty.\r\n"); else { sprintf(buf + strlen(buf), "There are %d messages on the board.\r\n", num_of_msgs[board_type]); /* uncomment below if want most recent message at bottom */ /* for (i = 0; i < num_of_msgs[board_type]; i++) { */ for (i = num_of_msgs[board_type] - 1; i >= 0; i--) { if (MSG_HEADING(board_type, i)) sprintf(buf + strlen(buf), "%s%-2d%s : %s%s\r\n", CBWHT(ch, C_NRM), i + 1, CCCYN(ch, C_NRM), MSG_HEADING(board_type, i), CCNRM(ch, C_NRM)); else { stderr_log("SYSERR: The board is fubar'd."); send_to_char("Sorry, the board isn't working.\r\n", ch); return 1; } } } page_string(ch->desc, buf, 1); return 1; }