/*! * @brief 反増殖結界の判定 * @param m_idx 判定の対象となるモンスターID * @return 反増殖の効果が適用されるならTRUEを返す */ bool multiply_barrier(int m_idx) { monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; if (!hex_spelling(HEX_ANTI_MULTI)) return FALSE; if ((p_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE; return TRUE; }
bool stop_hex_spell_all(void) { int i; for (i = 0; i < 32; i++) { if (hex_spelling(i)) do_spell(REALM_HEX, i, SPELL_STOP); } p_ptr->magic_num1[0] = 0; p_ptr->magic_num2[0] = 0; /* Print message */ if (p_ptr->action == ACTION_SPELL) set_action(ACTION_NONE); /* Redraw status */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA); return TRUE; }
/*! * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する * @return なし */ bool stop_hex_spell(void) { int spell; char choice; char out_val[160]; bool flag = FALSE; int y = 1; int x = 20; int sp[MAX_KEEP]; if (!hex_spelling_any()) { #ifdef JP msg_print("呪文を詠唱していません。"); #else msg_print("You are casting no spell."); #endif return FALSE; } /* Stop all spells */ else if ((p_ptr->magic_num2[0] == 1) || (p_ptr->lev < 35)) { return stop_hex_spell_all(); } else { #ifdef JP strnfmt(out_val, 78, "どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)", I2A(0), I2A(p_ptr->magic_num2[0] - 1)); #else strnfmt(out_val, 78, "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)", I2A(0), I2A(p_ptr->magic_num2[0] - 1)); #endif screen_save(); while (!flag) { int n = 0; Term_erase(x, y, 255); prt(" 名前", y, x + 5); for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { Term_erase(x, y + n + 1, 255); put_str(format("%c) %s", I2A(n), do_spell(REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2); sp[n++] = spell; } } if (!get_com(out_val, &choice, TRUE)) break; if (isupper(choice)) choice = tolower(choice); if (choice == 'l') /* All */ { screen_load(); return stop_hex_spell_all(); } if ((choice < I2A(0)) || (choice > I2A(p_ptr->magic_num2[0] - 1))) continue; flag = TRUE; } } screen_load(); if (flag) { int n = sp[A2I(choice)]; do_spell(REALM_HEX, n, SPELL_STOP); p_ptr->magic_num1[0] &= ~(1L << n); p_ptr->magic_num2[0]--; } /* Redraw status */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA); return flag; }
/*! * @brief 一定時間毎に呪術で消費するMPを処理する / * Upkeeping hex spells Called from dungeon.c * @return なし */ void check_hex(void) { int spell; s32b need_mana; u32b need_mana_frac; bool res = FALSE; /* Spells spelled by player */ if (p_ptr->realm1 != REALM_HEX) return; if (!p_ptr->magic_num1[0] && !p_ptr->magic_num1[1]) return; if (p_ptr->magic_num1[1]) { p_ptr->magic_num1[0] = p_ptr->magic_num1[1]; p_ptr->magic_num1[1] = 0; res = TRUE; } /* Stop all spells when anti-magic ability is given */ if (p_ptr->anti_magic) { stop_hex_spell_all(); return; } need_mana = 0; for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { const magic_type *s_ptr; s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell]; need_mana += mod_need_mana(s_ptr->smana, spell, REALM_HEX); } } /* Culcurates final mana cost */ need_mana_frac = 0; s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */ need_mana += (p_ptr->magic_num2[0] - 1); /* Not enough mana */ if (s64b_cmp(p_ptr->csp, p_ptr->csp_frac, need_mana, need_mana_frac) < 0) { stop_hex_spell_all(); return; } /* Enough mana */ else { s64b_sub(&(p_ptr->csp), &(p_ptr->csp_frac), need_mana, need_mana_frac); p_ptr->redraw |= PR_MANA; if (res) { #ifdef JP msg_print("詠唱を再開した。"); #else msg_print("You restart spelling."); #endif p_ptr->action = ACTION_SPELL; /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS | PU_HP); /* Redraw map and status bar */ p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE); /* Update monsters */ p_ptr->update |= (PU_MONSTERS); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); } } /* Gain experiences of spelling spells */ for (spell = 0; spell < 32; spell++) { const magic_type *s_ptr; if (!hex_spelling(spell)) continue; s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell]; if (p_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER) p_ptr->spell_exp[spell] += 5; else if(p_ptr->spell_exp[spell] < SPELL_EXP_SKILLED) { if (one_in_(2) && (dun_level > 4) && ((dun_level + 10) > p_ptr->lev)) p_ptr->spell_exp[spell] += 1; } else if(p_ptr->spell_exp[spell] < SPELL_EXP_EXPERT) { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; } else if(p_ptr->spell_exp[spell] < SPELL_EXP_MASTER) { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; } } /* Do any effects of continual spells */ for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { do_spell(REALM_HEX, spell, SPELL_CONT); } } }
static _blow_info_t _get_blow_info(int hand) { _blow_info_t result = {0}; int arm = hand / 2; object_type *o_ptr = equip_obj(p_ptr->weapon_info[hand].slot); if (!o_ptr) return result; /* TODO: Use race_ptr and class_ptr instead of this giant switch ... */ switch (p_ptr->pclass) { case CLASS_WARRIOR: result.num = 600; result.wgt = 70; result.mul = 50 + p_ptr->lev/2; break; case CLASS_MAULER: result.num = 175; result.wgt = 280; result.mul = 75; break; case CLASS_BERSERKER: result.num = 600; result.wgt = 70; result.mul = 75; break; case CLASS_RAGE_MAGE: result.num = 300; result.wgt = 70; result.mul = 30; break; case CLASS_MAGE: case CLASS_NECROMANCER: case CLASS_BLOOD_MAGE: case CLASS_HIGH_MAGE: case CLASS_BLUE_MAGE: result.num = 400; result.wgt = 100; result.mul = 20; break; case CLASS_WARLOCK: result.num = 400; result.wgt = 100; result.mul = 35; switch (p_ptr->psubclass) { case WARLOCK_DRAGONS: if ( p_ptr->riding && (object_is_(o_ptr, TV_POLEARM, SV_LANCE) || object_is_(o_ptr, TV_POLEARM, SV_HEAVY_LANCE)) ) { result.mul = 65; } break; case WARLOCK_ANGELS: case WARLOCK_DEMONS: result.num = 450; break; case WARLOCK_HOUNDS: result.num = 475; break; case WARLOCK_GIANTS: result.wgt = 200; result.mul = 50 + p_ptr->lev/5; result.num = 500; break; } break; case CLASS_PSION: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_PRIEST: case CLASS_MAGIC_EATER: case CLASS_MINDCRAFTER: result.num = 500; result.wgt = 100; result.mul = 35; break; case CLASS_DEVICEMASTER: result.num = 400; result.wgt = 100; result.mul = 35; if (p_ptr->psubclass == DEVICEMASTER_POTIONS || p_ptr->psubclass == DEVICEMASTER_SCROLLS) result.num = 500; break; case CLASS_ROGUE: result.num = 525; result.wgt = 40; result.mul = 30; if (o_ptr->weight < 50) result.num = 600; break; case CLASS_SCOUT: result.num = 400; result.wgt = 70; result.mul = 25; break; case CLASS_RANGER: result.num = 500; result.wgt = 70; result.mul = 40; break; case CLASS_PALADIN: case CLASS_SAMURAI: result.num = 550; result.wgt = 70; result.mul = 45; break; case CLASS_MYSTIC: result.num = 100; result.wgt = 100; result.mul = 10; break; case CLASS_WEAPONSMITH: case CLASS_RUNE_KNIGHT: result.num = 525; result.wgt = 150; result.mul = 55; break; case CLASS_WEAPONMASTER: result.num = weaponmaster_get_max_blows(o_ptr, hand); result.wgt = 70; result.mul = 50; break; case CLASS_WARRIOR_MAGE: case CLASS_RED_MAGE: result.num = 525; result.wgt = 70; result.mul = 30; break; case CLASS_CHAOS_WARRIOR: result.num = 550; result.wgt = 70; result.mul = 45; break; case CLASS_MONK: result.num = 500; result.wgt = 60; result.mul = 30; break; case CLASS_TOURIST: case CLASS_TIME_LORD: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_ARCHAEOLOGIST: result.num = 400; result.wgt = 70; result.mul = 30; if (archaeologist_is_favored_weapon(o_ptr)) { result.num = 500; result.mul = 40; } break; case CLASS_BLOOD_KNIGHT: result.num = 300; result.wgt = 150; result.mul = 30; break; case CLASS_DUELIST: result.num = 100; result.wgt = 70; result.mul = 40; break; case CLASS_IMITATOR: result.num = 550; result.wgt = 70; result.mul = 40; break; case CLASS_WILD_TALENT: result.num = 450; result.wgt = 70; result.mul = 40; break; case CLASS_BEASTMASTER: result.num = 500; result.wgt = 70; result.mul = 35; break; case CLASS_CAVALRY: { u32b flgs[TR_FLAG_SIZE]; object_flags(o_ptr, flgs); if (p_ptr->riding && have_flag(flgs, TR_RIDING)) {result.num = 550; result.wgt = 70; result.mul = 65;} else {result.num = 500; result.wgt = 100; result.mul = 35;} break; } case CLASS_SORCERER: result.num = 100; result.wgt = 1; result.mul = 10; break; case CLASS_ARCHER: case CLASS_BARD: result.num = 450; result.wgt = 70; result.mul = 20; break; case CLASS_FORCETRAINER: result.num = 400; result.wgt = 60; result.mul = 20; break; case CLASS_MIRROR_MASTER: case CLASS_SNIPER: result.num = 400; result.wgt = 100; result.mul = 30; break; case CLASS_NINJA: result.num = 425; result.wgt = 20; result.mul = 10; break; case CLASS_MONSTER: result.num = 500; result.wgt = 70; result.mul = 50; if (prace_is_(RACE_MON_LICH)) { result.num = 400; result.mul = 30; } else if (prace_is_(RACE_MON_POSSESSOR)) { result.num = 400; } else if (prace_is_(RACE_MON_MIMIC)) { result.num = 400; } else if (prace_is_(RACE_MON_TROLL)) { result.num = 550; } else if (prace_is_(RACE_MON_GIANT)) { result.num = 550; result.mul = 50 + p_ptr->lev/5; result.wgt = 200; if (giant_is_(GIANT_HRU) && p_ptr->lev >= 40) result.mul = 80; } else if ( prace_is_(RACE_MON_JELLY) || demon_is_(DEMON_KHORNE) ) { result.num = 600; result.mul = 50 + p_ptr->lev/5; } else if (prace_is_(RACE_MON_LEPRECHAUN)) { result.num = 300; result.mul = 20; } else if (prace_is_(RACE_MON_SWORD)) { result.num = 525; if (p_ptr->lev >= 45) /* Death Scythes retaliate! */ result.num = 300; } else if (prace_is_(RACE_MON_GOLEM)) { result.num = 100; } break; } if (hex_spelling(HEX_XTRA_MIGHT) || hex_spelling(HEX_BUILDING) || p_ptr->tim_building_up) { result.wgt /= 2; result.mul += 20; } /* Xorns and Mariliths have multiple sets of arms */ if (arm > 0) result.num -= 100; if (result.num < 100) result.num = 100; if (o_ptr->tval == TV_SWORD && o_ptr->sval == SV_POISON_NEEDLE) result.num = 100; return result; }