void strafing_spell(int cmd, variant *res) { switch (cmd) { case SPELL_NAME: var_set_string(res, "Strafing"); break; case SPELL_DESC: var_set_string(res, "Blink to a new location in the line of sight of your current location."); break; case SPELL_ENERGY: if (mut_present(MUT_ASTRAL_GUIDE)) var_set_int(res, 30); else default_spell(cmd, res); break; case SPELL_CAST: teleport_player(10, TELEPORT_LINE_OF_SIGHT); var_set_bool(res, TRUE); break; default: default_spell(cmd, res); break; } }
int mut_get_powers(spell_info* spells, int max) { int i; int ct = 0; if (mut_present(MUT_ASTRAL_GUIDE)) { spell_info *spell = NULL; if (ct >= max) return ct; spell = &spells[ct++]; spell->level = 5; spell->cost = 2; spell->fail = calculate_fail_rate(5, 50, p_ptr->stat_ind[A_DEX]); spell->fn = phase_door_spell; if (ct >= max) return ct; spell = &spells[ct++]; spell->level = 15; spell->cost = 6; spell->fail = calculate_fail_rate(15, 50, p_ptr->stat_ind[A_DEX]); spell->fn = teleport_spell; } for (i = 0; i < MAX_MUTATIONS; i++) { if ( mut_present(i) && (_mutations[i].type & MUT_TYPE_ACTIVATION) ) { spell_info *base = &_mutations[i].spell; spell_info* current = NULL; int stat_idx = p_ptr->stat_ind[_mutations[i].stat]; if (ct >= max) break; current = &spells[ct]; current->fn = base->fn; current->level = base->level; current->cost = base->cost; current->fail = calculate_fail_rate(base->level, base->fail, stat_idx); ct++; } } return ct; }
int _mut_prob_lose(int i) { int result = _mutations[i].prob; if ( _mutations[i].rating > MUT_RATING_AVERAGE && mut_present(MUT_GOOD_LUCK) ) { result = 1; } if ( _mutations[i].rating < MUT_RATING_AVERAGE && mut_present(MUT_BAD_LUCK) ) { result = 1; } return result; }
bool mut_lose_random(mut_pred pred) { int prob[MAX_MUTATIONS]; int i; int tot = 0; /* build probability table */ for (i = 0; i < MAX_MUTATIONS; i++) { int cur = 0; if (mut_present(i) && !mut_locked(i)) { if (pred == NULL || (pred(i))) cur = _mut_prob_lose(i); } tot += cur; prob[i] = tot; } /* any left? */ if (tot > 0) { int j = randint0(tot); int which = -1; /* scan the probability table for the correct mutation */ for (i = 0; i < MAX_MUTATIONS; i++) { if (j < prob[i]) { which = i; break; } } if (which >= 0 && mut_present(which)) /* paranoid checks ... should always pass */ { return mut_lose(which); } } /*msg_print("You feel normal.");*/ return FALSE; }
int skills_bow_max(int sval) { if (mut_present(MUT_WEAPON_SKILLS)) return WEAPON_EXP_MASTER; if (p_ptr->prace == RACE_DEMIGOD && p_ptr->psubrace == DEMIGOD_ARTEMIS) return WEAPON_EXP_MASTER; return s_info[p_ptr->pclass].w_max[0][sval]; }
int skills_bow_max(int sval) { if (mut_present(MUT_WEAPON_SKILLS)) return WEAPON_EXP_MASTER; if (demigod_is_(DEMIGOD_ARTEMIS)) return WEAPON_EXP_MASTER; return s_info[_class_idx()].w_max[0][sval]; }
int skills_weapon_max(int tval, int sval) { /* Hack: In case somebody calls this instead of skills_bow_max() */ if (tval == TV_BOW && p_ptr->prace == RACE_DEMIGOD && p_ptr->psubrace == DEMIGOD_ARTEMIS) return WEAPON_EXP_MASTER; if (mut_present(MUT_WEAPON_SKILLS)) return WEAPON_EXP_MASTER; return s_info[p_ptr->pclass].w_max[tval-TV_WEAPON_BEGIN][sval]; }
bool mut_gain_random(mut_pred pred) { int which = mut_gain_random_aux(pred); if (which >= 0 && !mut_present(which)) { chg_virtue(V_CHANCE, 1); return mut_gain(which); } msg_print("You feel normal."); return FALSE; }
/**************************************************************** * Demigod ****************************************************************/ static void _gain_power(int which) { if (p_ptr->demigod_power[which] < 0) { int idx = mut_gain_choice(mut_demigod_pred); mut_lock(idx); p_ptr->demigod_power[which] = idx; } else if (!mut_present(p_ptr->demigod_power[which])) { mut_gain(p_ptr->demigod_power[which]); mut_lock(p_ptr->demigod_power[which]); } }
bool mut_gain(int mut_idx) { variant v; if (mut_idx < 0 || mut_idx >= MAX_MUTATIONS) return FALSE; if (mut_present(mut_idx)) return FALSE; var_init(&v); add_flag(p_ptr->muta, mut_idx); (_mutations[mut_idx].spell.fn)(SPELL_GAIN_MUT, &v); var_clear(&v); _mut_refresh(); return TRUE; }
int mut_count(mut_pred pred) { int i; int count = 0; for (i = 0; i < MAX_MUTATIONS; ++i) { if (mut_present(i)) { if (pred == NULL || (pred)(i)) ++count; } } return count; }
bool mut_lose(int mut_idx) { variant v; if (mut_idx < 0 || mut_idx >= MAX_MUTATIONS) return FALSE; if (!mut_present(mut_idx)) return FALSE; if (mut_locked(mut_idx)) return FALSE; var_init(&v); remove_flag(p_ptr->muta, mut_idx); (_mutations[mut_idx].spell.fn)(SPELL_LOSE_MUT, &v); var_clear(&v); _mut_refresh(); return TRUE; }
void mut_dump_file(FILE* file) { int i; variant desc; var_init(&desc); for (i = 0; i < MAX_MUTATIONS; ++i) { if (mut_present(i)) { (_mutations[i].spell.fn)(SPELL_MUT_DESC, &desc); fprintf(file, "%s\n", var_get_string(&desc)); } } var_clear(&desc); }
void mut_calc_bonuses(void) { int i; variant v; var_init(&v); for (i = 0; i < MAX_MUTATIONS; i++) { if ( mut_present(i) && (_mutations[i].type & MUT_TYPE_BONUS) ) { (_mutations[i].spell.fn)(SPELL_CALC_BONUS, &v); } } var_clear(&v); }
/**************************************************************** * Human ****************************************************************/ static void _human_gain_level(int new_level) { if (new_level >= 30) { if (p_ptr->demigod_power[0] < 0) { int idx = mut_gain_choice(mut_demigod_pred/*mut_human_pred*/); mut_lock(idx); p_ptr->demigod_power[0] = idx; } else if (!mut_present(p_ptr->demigod_power[0])) { mut_gain(p_ptr->demigod_power[0]); mut_lock(p_ptr->demigod_power[0]); } } }
static bool _monk_check_spell(void) { if (p_ptr->pclass == CLASS_WILD_TALENT || mut_present(MUT_DRACONIAN_METAMORPHOSIS)) return TRUE; if ((p_ptr->prace == RACE_MON_POSSESSOR || p_ptr->prace == RACE_MON_MIMIC) && !p_ptr->weapon_ct) return TRUE; if (!p_ptr->weapon_info[0].bare_hands && !p_ptr->weapon_info[1].bare_hands) { msg_print("You need to fight bare handed."); return FALSE; } if (p_ptr->riding) { msg_print("You need to get off your pet."); return FALSE; } return TRUE; }
int mut_gain_choice(mut_pred pred) { int choices[MAX_MUTATIONS]; int i; int ct = 0; menu_list_t list = { "Gain which mutation?", "Browse which mutation?", NULL, _mut_name, NULL, NULL, choices, 0}; for (i = 0; i < MAX_MUTATIONS; i++) { if (!mut_present(i)) { if (pred == NULL || (pred(i))) choices[ct++] = i; } } if (ct == 0) return -1; list.count = ct; for (;;) { i = menu_choose(&list); if (i >= 0) { char buf[1024]; char buf2[1024]; int idx = choices[i]; mut_name(idx, buf2); sprintf(buf, "You will gain %s. Are you sure?", buf2); if (get_check(buf)) { mut_gain(idx); return idx; } } msg_print("Please make a choice!"); } return -1; }
int skills_weapon_max(int tval, int sval) { assert(TV_WEAPON_BEGIN <= tval && tval <= TV_WEAPON_END); if (tval == TV_BOW) return skills_bow_max(sval); if (mut_present(MUT_WEAPON_SKILLS)) return WEAPON_EXP_MASTER; /* TODO: Add a class_t callback to override the skill tables ... */ /* Dragon Warlocks are Dragon Riders! */ if ( warlock_is_(WARLOCK_DRAGONS) && tval == TV_POLEARM && (sval == SV_LANCE || sval == SV_HEAVY_LANCE) ) { return WEAPON_EXP_MASTER; } if (warlock_is_(WARLOCK_GIANTS) && tval != TV_BOW) { int k_idx = lookup_kind(tval, sval); if (k_info[k_idx].weight >= 200) return WEAPON_EXP_MASTER; if (k_info[k_idx].weight <= 100) return WEAPON_EXP_BEGINNER; } /* Edged weapons for priests. I never understood the restriction for evil priests! */ if (p_ptr->pclass == CLASS_PRIEST && (tval == TV_SWORD || tval == TV_POLEARM)) { if (priest_is_good()) return WEAPON_EXP_BEGINNER; else if (priest_is_evil()) return WEAPON_EXP_SKILLED; } return s_info[_class_idx()].w_max[tval-TV_WEAPON_BEGIN][sval]; }
/********************************************************************** * Utilities **********************************************************************/ static bool _necro_check_touch(void) { int slot; if (p_ptr->afraid) { msg_print("You are too scared to do that!"); return FALSE; } if (!equip_find_empty_hand() && !mut_present(MUT_DRACONIAN_METAMORPHOSIS)) { msg_print("You need a free hand to touch."); return FALSE; } slot = equip_find_obj(TV_GLOVES, SV_ANY); if (slot && equip_obj(slot)->name1 != ART_HAND_OF_VECNA) { msg_print("You can't touch while wielding gloves."); return FALSE; } return TRUE; }
void mut_process(void) { int i; variant v; /* No effect on monster arena */ if (p_ptr->inside_battle) return; /* No effect on the global map */ if (p_ptr->wild_mode) return; var_init(&v); for (i = 0; i < MAX_MUTATIONS; i++) { if ( mut_present(i) && (_mutations[i].type & MUT_TYPE_EFFECT) ) { (_mutations[i].spell.fn)(SPELL_PROCESS, &v); } } var_clear(&v); }
int mut_gain_random_aux(mut_pred pred) { int prob[MAX_MUTATIONS]; int i; int tot = 0; /* build probability table */ for (i = 0; i < MAX_MUTATIONS; i++) { int cur = 0; if (!mut_present(i)) { if (pred == NULL || (pred(i))) cur = _mut_prob_gain(i); } tot += cur; prob[i] = tot; } /* any left? */ if (tot > 0) { int j = randint0(tot); /* scan the probability table for the correct mutation */ for (i = 0; i < MAX_MUTATIONS; i++) { if (j < prob[i]) { return i; } } } return -1; }
/* * do_cmd_cast calls this function if the player's class * is 'imitator'. */ static bool use_mane(int spell) { int dir; int plev = p_ptr->lev; u32b mode = (PM_ALLOW_GROUP | PM_FORCE_PET); u32b u_mode = 0L; if (randint1(50+plev) < plev/10) u_mode = PM_ALLOW_UNIQUE; /* spell code */ switch (spell) { case MS_SHRIEK: msg_print("You make a high pitched shriek."); aggravate_monsters(0); break; case MS_XXX1: break; case MS_DISPEL: { int m_idx; if (!target_set(TARGET_KILL)) return FALSE; m_idx = cave[target_row][target_col].m_idx; if (!m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; dispel_monster_status(m_idx); break; } case MS_ROCKET: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You fire a rocket."); fire_rocket(GF_ROCKET, dir, damage, 2); break; case MS_SHOOT: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You fire an arrow."); fire_bolt(GF_ARROW, dir, damage); break; case MS_XXX2: break; case MS_XXX3: break; case MS_BR_STORM: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe storm."); fire_ball(GF_STORM, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe acid."); fire_ball(GF_ACID, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe lightning."); fire_ball(GF_ELEC, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe fire."); fire_ball(GF_FIRE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe frost."); fire_ball(GF_COLD, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gas."); fire_ball(GF_POIS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nether."); fire_ball(GF_NETHER, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_LITE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe light."); fire_ball(GF_LITE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe darkness."); fire_ball(GF_DARK, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe confusion."); fire_ball(GF_CONFUSION, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_SOUND: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe sound."); fire_ball(GF_SOUND, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe chaos."); fire_ball(GF_CHAOS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_DISEN: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disenchantment."); fire_ball(GF_DISENCHANT, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_NEXUS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe nexus."); fire_ball(GF_NEXUS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_TIME: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe time."); fire_ball(GF_TIME, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_INERTIA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe inertia."); fire_ball(GF_INERT, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_GRAVITY: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe gravity."); fire_ball(GF_GRAVITY, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_SHARDS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe shards."); fire_ball(GF_SHARDS, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe plasma."); fire_ball(GF_PLASMA, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_FORCE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe force."); fire_ball(GF_FORCE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BR_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe mana."); fire_ball(GF_MANA, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ball of radiation."); fire_ball(GF_NUKE, dir, damage, 2); break; case MS_BR_NUKE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe toxic waste."); fire_ball(GF_NUKE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_CHAOS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a raw Logrus."); fire_ball(GF_CHAOS, dir, damage, 4); break; case MS_BR_DISI: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You breathe disintegration."); fire_ball(GF_DISINTEGRATE, dir, damage, (plev > 35 ? -3 : -2)); break; case MS_BALL_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid ball."); fire_ball(GF_ACID, dir, damage, 2); break; case MS_BALL_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning ball."); fire_ball(GF_ELEC, dir, damage, 2); break; case MS_BALL_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire ball."); fire_ball(GF_FIRE, dir, damage, 2); break; case MS_BALL_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost ball."); fire_ball(GF_COLD, dir, damage, 2); break; case MS_BALL_POIS: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a stinking cloud."); fire_ball(GF_POIS, dir, damage, 2); break; case MS_BALL_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether ball."); fire_ball(GF_NETHER, dir, damage, 2); break; case MS_BALL_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You gesture fluidly."); fire_ball(GF_WATER, dir, damage, 4); break; case MS_BALL_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a mana storm."); fire_ball(GF_MANA, dir, damage, 4); break; case MS_BALL_DARK: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a darkness storm."); fire_ball(GF_DARK, dir, damage, 4); break; case MS_DRAIN_MANA: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_DRAIN_MANA, dir, randint1(plev*3)+plev, 0); break; case MS_MIND_BLAST: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_MIND_BLAST, dir, damage, 0); break; case MS_BRAIN_SMASH: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_BRAIN_SMASH, dir, damage, 0); break; case MS_CAUSE_1: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_1, dir, damage, 0); break; case MS_CAUSE_2: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_2, dir, damage, 0); break; case MS_CAUSE_3: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_3, dir, damage, 0); break; case MS_CAUSE_4: if (!get_aim_dir(&dir)) return FALSE; fire_ball_hide(GF_CAUSE_4, dir, damage, 0); break; case MS_BOLT_ACID: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast an acid bolt."); fire_bolt(GF_ACID, dir, damage); break; case MS_BOLT_ELEC: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a lightning bolt."); fire_bolt(GF_ELEC, dir, damage); break; case MS_BOLT_FIRE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fire bolt."); fire_bolt(GF_FIRE, dir, damage); break; case MS_BOLT_COLD: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a frost bolt."); fire_bolt(GF_COLD, dir, damage); break; case MS_STARBURST: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke a starburst."); fire_ball(GF_LITE, dir, damage, 4); break; case MS_BOLT_NETHER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a nether bolt."); fire_bolt(GF_NETHER, dir, damage); break; case MS_BOLT_WATER: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a water bolt."); fire_bolt(GF_WATER, dir, damage); break; case MS_BOLT_MANA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mana bolt."); fire_bolt(GF_MANA, dir, damage); break; case MS_BOLT_PLASMA: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a plasma bolt."); fire_bolt(GF_PLASMA, dir, damage); break; case MS_BOLT_ICE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a ice bolt."); fire_bolt(GF_ICE, dir, damage); break; case MS_MAGIC_MISSILE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a magic missile."); fire_bolt(GF_MISSILE, dir, damage); break; case MS_SCARE: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a fearful illusion."); fear_monster(dir, plev+10); break; case MS_BLIND: if (!get_aim_dir(&dir)) return FALSE; confuse_monster(dir, plev * 2); break; case MS_CONF: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You cast a mesmerizing illusion."); confuse_monster(dir, plev * 2); break; case MS_SLOW: if (!get_aim_dir(&dir)) return FALSE; slow_monster(dir); break; case MS_SLEEP: if (!get_aim_dir(&dir)) return FALSE; sleep_monster(dir, plev*3); break; case MS_SPEED: (void)set_fast(randint1(20 + plev) + plev, FALSE); break; case MS_HAND_DOOM: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You invoke the Hand of Doom!"); fire_ball_hide(GF_HAND_DOOM, dir, 200, 0); break; case MS_HEAL: msg_print("You concentrate on your wounds!"); (void)hp_player(plev*6); (void)set_stun(0, TRUE); (void)set_cut(0, TRUE); break; case MS_INVULNER: msg_print("You cast a Globe of Invulnerability."); (void)set_invuln(randint1(7) + 7, FALSE); break; case MS_BLINK: if (mut_present(MUT_ASTRAL_GUIDE)) energy_use = 30; teleport_player(10, 0L); break; case MS_TELEPORT: if (mut_present(MUT_ASTRAL_GUIDE)) energy_use = 30; teleport_player(plev * 5, 0L); break; case MS_WORLD: world_player = TRUE; if (damage == 1 || damage == 2) msg_print("You yell 'The World! Time has stopped!'"); else if (damage == 3 || damage == 6) msg_print("You yell 'Time!'"); else msg_print("hek!"); msg_print(NULL); p_ptr->energy_need -= 1000 + (100 + randint1(200)+200)*TURNS_PER_TICK/10; p_ptr->redraw |= (PR_MAP); p_ptr->update |= (PU_MONSTERS); p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); handle_stuff(); break; case MS_SPECIAL: break; case MS_TELE_TO: { monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; if (!cave[target_row][target_col].m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[cave[target_row][target_col].m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); if (r_ptr->flagsr & RFR_RES_TELE) { if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s is unaffected!", m_name); break; } else if (r_ptr->level > randint1(100)) { if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; msg_format("%s resists!", m_name); break; } } msg_format("You command %s to return.", m_name); teleport_monster_to(cave[target_row][target_col].m_idx, py, px, 100, TELEPORT_PASSIVE); break; } case MS_TELE_AWAY: if (!get_aim_dir(&dir)) return FALSE; (void)fire_beam(GF_AWAY_ALL, dir, plev); break; case MS_TELE_LEVEL: { int target_m_idx; monster_type *m_ptr; monster_race *r_ptr; char m_name[80]; if (!target_set(TARGET_KILL)) return FALSE; target_m_idx = cave[target_row][target_col].m_idx; if (!target_m_idx) break; if (!player_has_los_bold(target_row, target_col)) break; if (!projectable(py, px, target_row, target_col)) break; m_ptr = &m_list[target_m_idx]; r_ptr = &r_info[m_ptr->r_idx]; monster_desc(m_name, m_ptr, 0); msg_format("You gesture at %^s's feet.", m_name); if ((r_ptr->flagsr & (RFR_EFF_RES_NEXU_MASK | RFR_RES_TELE)) || (r_ptr->flags1 & RF1_QUESTOR) || (r_ptr->level + randint1(50) > plev + randint1(60))) { msg_format("%^s is unaffected!", m_name); } else teleport_level(target_m_idx); break; } case MS_PSY_SPEAR: if (!get_aim_dir(&dir)) return FALSE; else msg_print("You throw a psycho-spear."); fire_beam(GF_PSY_SPEAR, dir, damage); break; case MS_DARKNESS: msg_print("You gesture in shadow."); unlite_area(10, 3); break; case MS_MAKE_TRAP: if (!target_set(TARGET_KILL)) return FALSE; msg_print("You cast a spell and cackle evilly."); trap_creation(target_row, target_col); break; case MS_FORGET: msg_print("Nothing happens."); /* TODO: forget_spell(m_idx) ... */ break; case MS_RAISE_DEAD: msg_print("You cast a animate dead."); animate_dead(0, py, px); break; case MS_S_KIN: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon minions."); for (k = 0;k < 4; k++) { (void)summon_kin_player(plev, target_row, target_col, (PM_FORCE_PET | PM_ALLOW_GROUP)); } break; } case MS_S_CYBER: { int k; int max_cyber = (dun_level / 50) + randint1(3); if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon Cyberdemons!"); if (max_cyber > 4) max_cyber = 4; for (k = 0;k < max_cyber; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_CYBER, mode); break; } case MS_S_MONSTER: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon help."); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode)); break; } case MS_S_MONSTERS: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon monsters!"); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, 0, (mode | u_mode)); break; } case MS_S_ANT: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon ants."); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_ANT, mode); break; } case MS_S_SPIDER: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon spiders."); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_SPIDER, mode); break; } case MS_S_HOUND: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon hounds."); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HOUND, mode); break; } case MS_S_HYDRA: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon hydras."); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HYDRA, mode); break; } case MS_S_ANGEL: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon angel!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_ANGEL, mode); break; } case MS_S_DEMON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon a demon from the Courts of Chaos!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_DEMON, (mode | u_mode)); break; } case MS_S_UNDEAD: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon an undead adversary!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_UNDEAD, (mode | u_mode)); break; } case MS_S_DRAGON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon dragon!"); for (k = 0;k < 1; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_DRAGON, (mode | u_mode)); break; } case MS_S_HI_UNDEAD: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon greater undead!"); for (k = 0;k < 6; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode)); break; } case MS_S_HI_DRAGON: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon ancient dragons!"); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_DRAGON, (mode | u_mode)); break; } case MS_S_AMBERITE: { int k; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon Lords of Amber!"); for (k = 0;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_AMBERITE, (mode | PM_ALLOW_UNIQUE)); break; } case MS_S_UNIQUE: { int k, count = 0; if (!target_set(TARGET_KILL)) return FALSE; msg_print("You summon special opponents!"); for (k = 0;k < 4; k++) if (summon_specific(-1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE))) count++; for (k = count;k < 4; k++) summon_specific(-1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode)); break; } default: msg_print("hoge?"); } return TRUE; }
int calculate_fail_rate(int level, int base_fail, int stat_idx) { int fail = base_fail; int min = 0; caster_info *caster_ptr = get_caster_info(); if (p_ptr->lev < level) return 100; if (caster_ptr && (caster_ptr->options & CASTER_NO_SPELL_FAIL)) return 0; if (base_fail == 0) return 0; /* Adjust Fail Rate */ fail -= 3 * (p_ptr->lev - level); fail += p_ptr->to_m_chance; fail -= 3 * (adj_mag_stat[stat_idx] - 1); if (p_ptr->heavy_spell) fail += 20; { if (p_ptr->dec_mana && p_ptr->easy_spell) fail -= 4; else if (p_ptr->easy_spell) fail -= 3; else if (p_ptr->dec_mana) fail -= 2; } /* Apply Min Fail Rate */ min = adj_mag_fail[stat_idx]; if (caster_ptr && min < caster_ptr->min_fail) min = caster_ptr->min_fail; if (mut_present(MUT_ARCANE_MASTERY)) fail -= 3; if (prace_is_(RACE_DEMIGOD) && p_ptr->psubrace == DEMIGOD_ATHENA) { fail -= 2; if (min > 0) min -= 1; } if (fail < min) fail = min; /* Stunning affects even 0% fail spells */ if (p_ptr->stun > 50) fail += 25; else if (p_ptr->stun) fail += 15; /* Max Fail Rate */ if (fail > 95) fail = 95; /* Some effects violate the Min/Max Fail Rates */ if (p_ptr->heavy_spell) fail += 5; /* Fail could go to 100% */ if (p_ptr->dec_mana) fail--; /* 5% casters could get 4% fail rates */ if (fail < 0) fail = 0; if (fail > 100) fail = 100; return fail; }
int _mut_prob_gain(int i) { int result = _mutations[i].prob; const int racial_odds = 50; if (result == 0) return 0; if (p_ptr->pclass == CLASS_BERSERKER && mut_type(i) & MUT_TYPE_ACTIVATION) return 0; switch (i) { case MUT_CHAOS_GIFT: /* TODO: Birth Chaos Warriors with this mutation */ if (p_ptr->pclass == CLASS_CHAOS_WARRIOR) return 0; break; case MUT_BAD_LUCK: if (mut_locked(MUT_GOOD_LUCK)) return 0; break; case MUT_HYPN_GAZE: if (p_ptr->prace == RACE_VAMPIRE) return racial_odds; break; case MUT_HORNS: if (p_ptr->prace == RACE_IMP) return racial_odds; break; case MUT_SHRIEK: if (p_ptr->prace == RACE_YEEK) return racial_odds; break; case MUT_POLYMORPH: if (p_ptr->prace == RACE_BEASTMAN) return racial_odds; break; case MUT_TENTACLES: if (p_ptr->prace == RACE_MIND_FLAYER) return racial_odds; break; } if ( _mutations[i].rating < MUT_RATING_AVERAGE && mut_present(MUT_GOOD_LUCK) ) { result = 1; } if ( _mutations[i].rating > MUT_RATING_AVERAGE && mut_present(MUT_BAD_LUCK) ) { result = 1; } return result; }