bool quest_spider_death_hook(char *fmt) { int i, mcnt = 0; if (p_ptr->inside_quest != QUEST_SPIDER) return FALSE; for (i = m_max - 1; i >= 1; i--) { /* Access the monster */ monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ if (!m_ptr->r_idx) continue; if (m_ptr->status <= MSTATUS_ENEMY) mcnt++; } if (mcnt <= 1) { cmsg_print(TERM_YELLOW, "The forest is now safer, thanks to you."); /* Yavanna LOVES saving forests */ GOD(GOD_YAVANNA) { cmsg_print(TERM_L_GREEN, "You feel the gentle touch of Yavanna, as she smiles at you."); inc_piety(GOD_YAVANNA, 6000); } cquest.status = QUEST_STATUS_COMPLETED; del_hook(HOOK_MONSTER_DEATH, quest_spider_death_hook); process_hooks_restart = TRUE; return (FALSE); }
bool cmsg_input_num(byte color, cptr prompt, int *num, int min, int max) { bool result = FALSE; char buf[10]; msg_boundary(); auto_more_state = AUTO_MORE_PROMPT; cmsg_print(color, prompt); result = askfor_aux(buf, 10, FALSE); if (result) { if (isalpha(buf[0])) *num = max; else *num = atoi(buf); if (*num > max) *num = max; if (*num < min) *num = min; msg_format("%d", *num); } else cmsg_print(TERM_L_RED, "Cancelled"); msg_line_clear(); return result; }
static void _skills_riding_gain(int inc) { int current = p_ptr->skill_exp[SKILL_RIDING]; int max = skills_riding_max(); int update = MIN(max, current + inc); if (update > current) { p_ptr->skill_exp[SKILL_RIDING] = update; p_ptr->update |= PU_BONUS; /* Give some feedback every 100 points */ if (update/100 > current/100) { if (update <= 500) cmsg_print(TERM_L_BLUE, "You are starting to get the hang of riding. Keep at it!"); else if (update <= 1000) cmsg_print(TERM_L_BLUE, "You feel more comfortable while riding."); else if (update <= 2000) cmsg_print(TERM_L_BLUE, "You feel your riding improve."); else if (update <= 5000) cmsg_print(TERM_L_BLUE, "You are getting quite good at riding."); else cmsg_print(TERM_L_BLUE, "Soon you will be a riding master!"); } } }
bool quest_invasion_turn_hook(char *fmt) { bool old_quick_messages = quick_messages; if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE); if (p_ptr->lev < 45) return (FALSE); /* Wait until the end of the current quest */ if (p_ptr->inside_quest) return ( FALSE); /* Wait until the end of the astral mode */ if (p_ptr->astral) return ( FALSE); /* Ok give the quest */ quick_messages = FALSE; cmsg_print(TERM_YELLOW, "A Thunderlord appears in front of you and says:"); cmsg_print(TERM_YELLOW, "'Hello, noble hero. I am Liron, rider of Tolan. Turgon, King of Gondolin sent me.'"); cmsg_print(TERM_YELLOW, "'Gondolin is being invaded; he needs your help now or everything will be lost.'"); cmsg_print(TERM_YELLOW, "'I can bring you to Gondolin, but we must go now.'"); /* This is SO important a question that flush pending inputs */ flush(); if (!get_check("Will you come?")) { cmsg_print(TERM_YELLOW, "'Turgon overestimated you... Now Gondolin will fall.'"); cmsg_print(TERM_YELLOW, "'I will return alone and die there. May you be doomed!'"); cquest.status = QUEST_STATUS_FAILED; town_info[2].destroyed = TRUE; quick_messages = old_quick_messages; del_hook(HOOK_END_TURN, quest_invasion_turn_hook); process_hooks_restart = TRUE; return (FALSE); } cmsg_print(TERM_YELLOW, "'You made the right decision! Quickly, jump on Tolan!'"); cmsg_print(TERM_YELLOW, "'Here we are: Gondolin. You must speak with Turgon now.'"); p_ptr->wild_mode = FALSE; p_ptr->wilderness_x = 49; p_ptr->wilderness_y = 11; p_ptr->town_num = 2; p_ptr->oldpx = p_ptr->px = 117; p_ptr->oldpy = p_ptr->py = 24; dun_level = 0; p_ptr->leaving = TRUE; cmsg_print(TERM_YELLOW, "'Turgon hails you.'"); quest_describe(QUEST_INVASION); cquest.status = QUEST_STATUS_TAKEN; quick_messages = old_quick_messages; quest_invasion_init_hook(QUEST_INVASION); del_hook(HOOK_END_TURN, quest_invasion_turn_hook); process_hooks_restart = TRUE; return (FALSE); }
bool cmsg_input(byte color, cptr prompt, char *buf, int len) { bool result = FALSE; msg_boundary(); auto_more_state = AUTO_MORE_PROMPT; cmsg_print(color, prompt); result = askfor(buf, len); if (result) msg_print(buf); else cmsg_print(TERM_L_RED, "Cancelled"); msg_line_clear(); return result; }
bool quest_wolves_death_hook(char *fmt) { int i, mcnt = 0; if (p_ptr->inside_quest != QUEST_WOLVES) return FALSE; /* Process the monsters (backwards) */ for (i = m_max - 1; i >= 1; i--) { /* Access the monster */ monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ if (!m_ptr->r_idx) continue; if (m_ptr->status <= MSTATUS_ENEMY) mcnt++; } /* Nobody left ? */ if (mcnt <= 1) { quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED; del_hook(HOOK_MONSTER_DEATH, quest_wolves_death_hook); del_hook(HOOK_GEN_QUEST, quest_wolves_gen_hook); process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "Lothlorien is safer now."); return (FALSE); } return FALSE; }
/* Prompt the user for a choice: [1] keys[0] is the default choice if quick_messages and PROMPT_FORCE_CHOICE is not set. [2] keys[0] is returned on ESC if PROMPT_ESCAPE_DEFAULT is set. [3] You get back the char in the keys prompt, not the actual character pressed. This makes a difference if PROMPT_CASE_SENSITIVE is not set (and simplifies your coding). Sample Usage: char ch = cmsg_prompt(TERM_VIOLET, "Really commit suicide? [Y,n]", "nY", PROMPT_NEW_LINE | PROMPT_CASE_SENSITIVE); if (ch == 'Y') {...} */ static char cmsg_prompt_imp(byte color, cptr prompt, char keys[], int options) { if (options & PROMPT_NEW_LINE) msg_boundary(); auto_more_state = AUTO_MORE_PROMPT; cmsg_print(color, prompt); for (;;) { char ch = inkey(); int i; if (ch == ESCAPE && (options & PROMPT_ESCAPE_DEFAULT)) return keys[0]; if (ch == '\r' && (options & PROMPT_RETURN_1)) return keys[1]; for (i = 0; ; i++) { char choice = keys[i]; if (!choice) break; if (ch == choice) return choice; if (!(options & PROMPT_CASE_SENSITIVE)) { if (tolower(ch) == tolower(choice)) return choice; } } if (!(options & PROMPT_FORCE_CHOICE) && quick_messages) return keys[0]; } }
bool quest_invasion_stair_hook(char *fmt) { cptr down; down = get_next_arg_str(fmt); if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return TRUE; if (!strcmp(down, "up")) { if (cquest.status == QUEST_STATUS_FAILED) { cmsg_print(TERM_YELLOW, "The armies of Morgoth totally devastated Gondolin, leaving nothing but ruins..."); } else if (cquest.status == QUEST_STATUS_COMPLETED) { cmsg_print(TERM_YELLOW, "Turgon appears before you and speaks:"); cmsg_print(TERM_YELLOW, "'I will never be able to thank you enough.'"); cmsg_print(TERM_YELLOW, "'My most powerful mages will cast a powerful spell for you, giving you extra life.'"); p_ptr->hp_mod += 150; p_ptr->update |= (PU_HP); cquest.status = QUEST_STATUS_FINISHED; } else { /* Flush input */ flush(); if (!get_check("Really abandon the quest?")) return TRUE; cmsg_print(TERM_YELLOW, "You flee away from Maeglin and his army..."); cquest.status = QUEST_STATUS_FAILED; town_info[2].destroyed = TRUE; } del_hook(HOOK_STAIR, quest_invasion_stair_hook); process_hooks_restart = TRUE; return (FALSE); } return TRUE; }
void cmsg_format(byte color, cptr fmt, ...) { va_list vp; char buf[1024]; va_start(vp, fmt); (void)vstrnfmt(buf, 1024, fmt, vp); va_end(vp); cmsg_print(color, buf); }
/* Note: Angband uses proprietary format strings, like %^s that string_vprintf() won't handle. So, let's hope 1024 is enough for every message! (It should be ...) */ void msg_format(cptr fmt, ...) { va_list vp; char buf[1024]; va_start(vp, fmt); (void)vstrnfmt(buf, 1024, fmt, vp); va_end(vp); cmsg_print(TERM_WHITE, buf); }
bool quest_poison_drop_hook(char *fmt) { s32b mcnt = 0, i, x, y, o_idx; object_type *o_ptr; o_idx = get_next_arg(fmt); o_ptr = &p_ptr->inventory[o_idx]; if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE; if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) return FALSE; if (p_ptr->wild_mode) return FALSE; if (o_ptr->tval != TV_POTION2) return FALSE; if (o_ptr->sval != SV_POTION2_CURE_WATER) return FALSE; for (i = m_max - 1; i >= 1; i--) { /* Access the monster */ monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ if (!m_ptr->r_idx) continue; if (m_ptr->status <= MSTATUS_NEUTRAL) mcnt++; } if (mcnt < 10) { for (x = 1; x < cur_wid - 1; x++) for (y = 1; y < cur_hgt - 1; y++) { if (!in_bounds(y, x)) continue; if (cave[y][x].feat == FEAT_TAINTED_WATER) cave_set_feat(y, x, FEAT_SHAL_WATER); } cmsg_print(TERM_YELLOW, "Well done! The water seems to be clean now."); cquest.status = QUEST_STATUS_COMPLETED; del_hook(HOOK_DROP, quest_poison_drop_hook); process_hooks_restart = TRUE; return FALSE; } else { msg_print("There are too many monsters left to cure the water."); return TRUE; } return FALSE; }
void monster_type_copy(monster_type *dest, monster_type*src) { *dest = *src; flag_init(&dest->blow, 2); flag_copy(&dest->blow, &src->blow); flag_init(&dest->inventory, 2); flag_copy(&dest->inventory, &src->inventory); flag_init(&dest->flags, 2); flag_copy(&dest->flags, &src->flags); flag_init(&dest->spells, 2); flag_copy(&dest->spells, &src->spells); flag_init(&dest->ai_states, 2); flag_copy(&dest->ai_states, &src->ai_states); if (dest->sr_ptr != NULL) cmsg_print(TERM_VIOLET, "*ERROR*: monster_type_dup called with a sr_ptr! Contact the maintainer."); if (dest->mind != NULL) cmsg_print(TERM_VIOLET, "*ERROR*: monster_type_dup called with a mind! Contact the maintainer."); }
bool quest_invasion_death_hook(char *fmt) { s32b r_idx, m_idx; m_idx = get_next_arg(fmt); r_idx = m_list[m_idx].r_idx; if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; if (r_idx == test_monster_name("Maeglin, the Traitor of Gondolin")) { cmsg_print(TERM_YELLOW, "You did it! Gondolin will remain hidden."); cquest.status = QUEST_STATUS_COMPLETED; del_hook(HOOK_MONSTER_DEATH, quest_invasion_death_hook); process_hooks_restart = TRUE; return (FALSE); } return FALSE; }
static void _cyber_move_player(void) { /* Cyberdemons move erratically (cf get_rep_dir()) and make a lot of noise */ if (one_in_(66)) { int i; cmsg_print(TERM_RED, "The dungeon trembles!"); if (disturb_minor) disturb(0, 0); for (i = 1; i < m_max; i++) { monster_type *m_ptr = &m_list[i]; if (!m_ptr->r_idx) continue; if (m_ptr->cdis < MAX_SIGHT * 2 && MON_CSLEEP(m_ptr)) (void)set_monster_csleep(i, 0); } } }
bool quest_invasion_ai_hook(char *fmt) { monster_type *m_ptr; s32b m_idx; m_idx = get_next_arg(fmt); m_ptr = &m_list[m_idx]; if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; /* Ugly but thats better than a call to test_monster_name which is SLOW */ if (m_ptr->r_idx == 825) { /* Oups he fleed */ if ((m_ptr->fy == cquest.data[0]) && (m_ptr->fx == cquest.data[1])) { delete_monster_idx(m_idx); cmsg_print(TERM_YELLOW, "Maeglin found the way to Gondolin! All hope is lost now!"); cquest.status = QUEST_STATUS_FAILED; town_info[2].destroyed = TRUE; return (FALSE); } /* Attack or flee ?*/ if (distance(m_ptr->fy, m_ptr->fx, p_ptr->py, p_ptr->px) <= 2) { return (FALSE); } else { process_hooks_return[0].num = cquest.data[0]; process_hooks_return[1].num = cquest.data[1]; return (TRUE); } } return (FALSE); }
void msg_print(cptr msg) { cmsg_print(TERM_WHITE, msg); }