diff -uNr src_org/birth.c src/birth.c --- src_org/birth.c Mon May 9 18:05:18 2011 +++ src/birth.c Tue May 10 21:09:32 2011 @@ -1970,6 +1970,8 @@ "武芸の書は、様々な戦闘の技について書かれています。この本は技を覚えるときに読む必要がありますが、一度覚えた技は使うのに本を持つ必要はありません。技を使うときには必ず武器を装備していなければいけません。", "呪術は忌むべき領域です。複数の呪いの言葉を歌のように紡ぎながら詠唱します。多くの呪文は詠唱し続けることによって効果が持続されます。呪文には相手の行動を束縛するもの、ダメージを与えるもの、攻撃に対して反撃するものが多くあります。" +, +"無作為は数々の領域から出鱈目に選ばれた力を使える魔法です。運や出鱈目の神が味方すれば有用な魔法も沢山含まれることになります。" #else "Life magic is very good for healing; it relies mostly on healing, protection and detection spells. Also life magic have a few attack spells as well. It said that some high level spell of life magic can disintegrate Undead monsters into ash.", @@ -1997,6 +1999,9 @@ "The books of Kendo describe about various combat techniques. When learning new techniques, you are required to carry the books, but once you memorizes them, you don't have to carry them. When using a technique, wielding a weapon is required.", "Hex is a very terrible realm. Spells gives continual effects when they are spelled continually like songs. Spells may obstract monsters' actions, may deal damages in sight, may revenge against enemies." +, + +"Thaumat is a very ramdom realm." #endif }; @@ -2015,7 +2020,8 @@ "邪悪な怪物に対する攻撃に優れています", "様々な魔法効果を持った歌を歌います", "打撃攻撃に特殊能力を付加します", -"敵を邪魔しつつ復讐を狙います" +"敵を邪魔しつつ復讐を狙います", +"ランダムな魔法を得ます" #else "Good at detection and healing.", "Utility and protective spells.", @@ -2029,7 +2035,8 @@ "Destroys evil creatures.", "Song with magical effects.", "Special attacks on melee.", -"Good at obstacle and revenge." +"Good at obstacle and revenge.", +"Random spells chosen of most books." #endif }; @@ -2160,6 +2167,11 @@ (*count)++; auto_select = REALM_HEX; } + if (choices & CH_THAUMAT) + { + (*count)++; + auto_select = REALM_THAUMAT; + } clear_from(10); @@ -4290,6 +4302,100 @@ return TRUE; } +static int thaumat_get_rand_spell(int rlm, int lev, int *pn_lev) +{ + int j, i, cnt, ridx, rlev; + for(j=0;j<20;j++) + { + cnt = 0; + for(i=0;i<32;i++) + { + magic_type *s_ptr; + s_ptr = &mp_ptr->info[rlm - 1][i]; + if (s_ptr->slevel >= lev -(j/3) && s_ptr->slevel <= lev + j) + { + if (randint0(cnt+1) == 0) + { + ridx = i; + rlev = s_ptr->slevel; + } + cnt++; + } + } + if (cnt > 0) + { + break; + } + } + if (cnt == 0) + { + return -1; + } + *pn_lev = rlev; + return ridx; +} + +static void init_birth_thaumat_magic(void) +{ + int i, j; + struct mgctmp_type { + int slevel; + int rlm, spl; + } mgc[THAUMAT_MAGICNUM]; + + for(i = 0; i < THAUMAT_MAGICNUM; i++) + { + int rlm = REALM_CHAOS, spl = 1, lev = 1; + for(;;) + { + rlm = randint1(MAX_MAGIC);/* 1 ~ 10 */ + spl = thaumat_get_rand_spell(rlm, ((i)*50)/(THAUMAT_MAGICNUM-1)+randint0(2), &lev); + if (spl != -1) + { + bool kaburi_flg = FALSE; + for(j=0;j i; j--) + { + if (mgc[j-1].slevel > mgc[j].slevel) + { + struct mgctmp_type tmp; + tmp = mgc[j]; + mgc[j] = mgc[j-1]; + mgc[j-1] = tmp; + } + } + } + for(i = 0; i < THAUMAT_MAGICNUM; i++) + { + p_ptr->magic_num1[i] = mgc[i].rlm; + p_ptr->magic_num1[i + THAUMAT_MAGICNUM] = mgc[i].spl; + } +} /* * Player class @@ -4498,7 +4604,6 @@ cp_ptr = &class_info[p_ptr->pclass]; mp_ptr = &m_info[p_ptr->pclass]; - /* Display */ c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15); @@ -5918,6 +6023,13 @@ /* Choose the magic realms */ if (!get_player_realms()) return FALSE; + /*hack THAUMAT*/ + if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + mp_ptr = &m_info[CLASS_WARRIOR_MAGE]; + init_birth_thaumat_magic(); + } + /* Choose the players seikaku */ p_ptr->pseikaku = 0; while(1) @@ -6439,6 +6551,13 @@ mp_ptr = &m_info[p_ptr->pclass]; ap_ptr = &seikaku_info[p_ptr->pseikaku]; + /*hack THAUMAT*/ + if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + mp_ptr = &m_info[CLASS_WARRIOR_MAGE]; + init_birth_thaumat_magic(); + } + /* Calc hitdie, but don't roll */ get_extra(FALSE); diff -uNr src_org/cmd6.c src/cmd6.c --- src_org/cmd6.c Mon May 9 18:05:18 2011 +++ src/cmd6.c Tue May 10 21:03:34 2011 @@ -1980,6 +1980,11 @@ case SV_SCROLL_SPELL: { + if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + break; + } + if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_IMITATOR) || (p_ptr->pclass == CLASS_MINDCRAFTER) || (p_ptr->pclass == CLASS_SORCERER) || (p_ptr->pclass == CLASS_ARCHER) || (p_ptr->pclass == CLASS_MAGIC_EATER) || (p_ptr->pclass == CLASS_RED_MAGE) || (p_ptr->pclass == CLASS_SAMURAI) || (p_ptr->pclass == CLASS_BLUE_MAGE) || (p_ptr->pclass == CLASS_CAVALRY) || (p_ptr->pclass == CLASS_BERSERKER) || (p_ptr->pclass == CLASS_SMITH) || (p_ptr->pclass == CLASS_MIRROR_MASTER) || (p_ptr->pclass == CLASS_NINJA)) break; p_ptr->add_spells++; p_ptr->update |= (PU_SPELLS); @@ -6826,6 +6831,444 @@ } } +static magic_type * thaumat_magic_to_spl_ptr(int i) +{ + int rlm, spl; + magic_type *s_ptr; + rlm = p_ptr->magic_num1[i]; + spl = p_ptr->magic_num1[i + THAUMAT_MAGICNUM]; + s_ptr = &mp_ptr->info[rlm - 1][spl]; + return s_ptr; +} + +static bool thaumat_magic_ok_to_cast(int pow_idx) +{ + magic_type *s_ptr = thaumat_magic_to_spl_ptr(pow_idx); + if (p_ptr->lev >= s_ptr->slevel) + { + return TRUE; + } + return FALSE; +} + +static int select_thaumat_magic_aux(bool only_browse) +{ + int use_realm = -1, spell = -1, need_mana; + char info[80]; + int c_lev_start; + char choice; + int i, num, keyselected; + bool ask = FALSE, request_list = FALSE; + int flag = 0; + bool casting = FALSE; + int sn; + char asking_buf[160], out_val[160]; + +#ifdef ALLOW_REPEAT /* TNB */ + + /* Get the spell, if available */ + if (repeat_pull(&sn)) + { + if (thaumat_magic_ok_to_cast(sn)) + { + /* Success */ + return (sn); + } + } + +#endif /* ALLOW_REPEAT -- TNB */ + + /*TODO:menu & repeat*/ + while (TRUE) + { +#ifdef JP + if (!get_com("[A] 低, [B] 中, [C] 高:", &choice, TRUE)) +#else + if (!get_com("[A] Low, [B] Middle, [C] High:", &choice, TRUE)) +#endif + { + return -1; + } + if (choice == 'A' || choice == 'a') + { + c_lev_start = 0; + break; + } + if (choice == 'B' || choice == 'b') + { + c_lev_start = 12; + break; + } + if (choice == 'C' || choice == 'c') + { + c_lev_start = 12+12; + break; + } + } + num = 12; + + /*Check abalable*/ + { + int cnt = 0; + for (i = c_lev_start; i < c_lev_start+12; i++) + { + if (thaumat_magic_ok_to_cast(i)) + { + cnt++; + } + } + if (cnt == 0) + { +#ifdef JP +msg_print("そのランクにはまだ唱えられる魔法がない。"); +#else + msg_print("You do not have enough experience to use that rank."); +#endif + return -1; + } + } + + /* Build a prompt */ + if (only_browse) + { +#ifdef JP +(void) strnfmt(asking_buf, 78, "('*'で一覧, ESCで中断) どの魔法を調べますか?"); +#else + (void)strnfmt(asking_buf, 78, "(*=List, ESC=exit) Browse which spell? "); +#endif + } + else + { +#ifdef JP +(void) strnfmt(asking_buf, 78, "('*'で一覧, ESCで中断) どの魔法を使いますか?"); +#else + (void)strnfmt(asking_buf, 78, "(*=List, ESC=exit) Use which spell? "); +#endif + } + + /* Save the screen */ + screen_save(); + + choice= (always_show_list) ? ESCAPE:1 ; + while (!flag) + { + if(choice==ESCAPE) choice = ' '; + else if( !get_com(asking_buf, &choice, TRUE) )break; + + /* ??? */ + if (choice == ESCAPE || choice == 'z') + { + casting = FALSE; + break; + } + /* Request redraw */ + if ((choice == ' ') || (choice == '*') || (choice == '?')) + { + int y = 1, x = 0; + + /* Hide the list */ + if (request_list) + { + /* Hide list */ + request_list = FALSE; + + /* Restore the screen */ + screen_load(); + screen_save(); + } + else + { + request_list = TRUE; + } + + /* Show the list */ + if (request_list) + { + int nline; + /* Display a list of spells */ + prt("", y, x); +#ifdef JP +put_str("名前", y, x + 3); +#else + put_str("Name", y, x + 3); +#endif + +#ifdef JP +put_str(format("Lv MP 失率 効果"), y, x + 29); +#else +put_str(format("Lv MP Fail Info"), y, x + 29); +#endif + + /* Dump the spells */ + num = 0; + for (i = c_lev_start; i < c_lev_start + 12; i++) + { + const char kakko = ')'; + magic_type *s_ptr; + /* TEST THAUMAT XXX */ + if (!thaumat_magic_ok_to_cast(i)) + { + break; + } + num++; + use_realm = p_ptr->magic_num1[i]; + spell = p_ptr->magic_num1[i+THAUMAT_MAGICNUM]; + s_ptr = &mp_ptr->info[use_realm - 1][spell]; + need_mana = s_ptr->smana; + + /* Get extra info */ + strcpy(info, do_spell(use_realm, spell, SPELL_INFO)); + sprintf(out_val, "%c%c ", 'a'+i-c_lev_start, kakko); + strcat(out_val, format("%-25s %2d %4d %3d%% %s", + do_spell(use_realm, spell, SPELL_NAME), /* realm, spell */ + s_ptr->slevel, need_mana, spell_chance(spell, use_realm), info)); + nline = i - c_lev_start + 1; + prt(out_val, y + nline, x); + } + + /* Clear the bottom line */ + prt("", y + nline + 1, x); + } + + /* Redo asking */ + continue; + } + + { + /* Note verify */ + ask = isupper(choice); + + /* Lowercase */ + if (ask) choice = tolower(choice); + + /* Extract request */ + keyselected = (islower(choice) ? A2I(choice) : -1); + } + + /* Totally Illegal */ + if ((keyselected < 0) || (keyselected >= num)) + { + bell(); + continue; + } + + /*selected*/ + use_realm = p_ptr->magic_num1[c_lev_start+keyselected]; + spell = p_ptr->magic_num1[c_lev_start+keyselected+THAUMAT_MAGICNUM]; + + /* Verify it */ + if (ask) + { + char tmp_val[160]; + + /* Prompt */ +#ifdef JP +(void) strnfmt(tmp_val, 78, "%sを使いますか?", do_spell(use_realm, spell, SPELL_NAME)); +#else + (void)strnfmt(tmp_val, 78, "Use %s? ", do_spell(use_realm, spell, SPELL_NAME)); +#endif + + /* Belay that order */ + if (!get_check(tmp_val)) continue; + } + + if (only_browse) + { + int j, line; + char temp[62*4]; + /* Clear lines, position cursor (really should use strlen here) */ + Term_erase(0, 16, 255); + Term_erase(0, 15, 255); + Term_erase(0, 14, 255); + + roff_to_buf(do_spell(use_realm, spell, SPELL_DESC), 62, temp, sizeof(temp)); + for(j=0, line = 15;temp[j];j+=(1+strlen(&temp[j]))) + { + prt(&temp[j], line, 2); + line++; + } + +#ifdef JP + prt("何かキーを押して下さい。",0,0); +#else + prt("Hit any key.",0,0); +#endif + (void)inkey(); + continue; + } + + /* Stop the loop */ + flag = TRUE; + casting = TRUE; + } + + screen_load(); + + if (!casting) + { + return -1; + } + +#ifdef ALLOW_REPEAT + repeat_push(c_lev_start+keyselected); +#endif /* ALLOW_REPEAT */ + + return (c_lev_start+keyselected); +} + +static int select_thaumat_magic(bool only_browse) +{ + int power_idx; + int use_realm, spell, need_mana; + magic_type *s_sele_ptr; + int chance; + + power_idx = select_thaumat_magic_aux(only_browse); + + if (only_browse) + { + return -1; + } + if (power_idx == -1) + { + return -1; + } + + /*TEST*/ + s_sele_ptr = thaumat_magic_to_spl_ptr(power_idx); + use_realm = p_ptr->magic_num1[power_idx]; + spell = p_ptr->magic_num1[power_idx + THAUMAT_MAGICNUM]; + need_mana = s_sele_ptr->smana; + + /* Verify "dangerous" spells */ + if (need_mana > p_ptr->csp) + { + if (flush_failure) flush(); + + /* Warning */ +#ifdef JP +msg_print("その呪文を詠唱するのに十分なマジックポイントがない。"); +#else + msg_print("You do not have enough mana to cast this spell."); +#endif + + + if (!over_exert) return -1; + + /* Verify */ +#ifdef JP + if (!get_check_strict("それでも挑戦しますか? ", CHECK_OKAY_CANCEL)) return -1; +#else + if (!get_check_strict("Attempt it anyway? ", CHECK_OKAY_CANCEL)) return -1; +#endif + + } + + /* Spell failure chance */ + chance = spell_chance(spell, use_realm); + /* Failed spell */ + if (randint0(100) < chance) + { + if (flush_failure) flush(); + +#ifdef JP +msg_format("呪文をうまく唱えられなかった!"); +#else + msg_format("You failed to get the spell off!"); +#endif + + sound(SOUND_FAIL); + /* Failure casting may activate some side effect */ + do_spell(use_realm, spell, SPELL_FAIL); + + if ((randint1(100) < spell)) + { +#ifdef JP +msg_print("カオス的な効果を発生した!"); +#else + msg_print("You produce a chaotic effect!"); +#endif + + wild_magic(spell); + } + } + /* Process spell */ + else + { + /* Canceled spells cost neither a turn nor mana */ + if (!do_spell(use_realm, spell, SPELL_CAST)) return -1; + } + + /* Take a turn */ + energy_use = 100; + + /* Sufficient mana */ + if (need_mana <= p_ptr->csp) + { + /* Use some mana */ + p_ptr->csp -= need_mana; + } + else + { + /* Damage CON (possibly permanently) */ + if (randint0(100) < 85) + { + bool perm = (randint0(100) < 25); + + /* Message */ +#ifdef JP +msg_print("体を悪くしてしまった!"); +#else + msg_print("You have damaged your health!"); +#endif + + + /* Reduce stat */ + if (randint0(2)) + { + (void)dec_stat(A_STR, 15 + randint1(10), perm); + } + else + { + (void)dec_stat(A_CON, 15 + randint1(10), perm); + } + } + } + + /* Redraw mana */ + p_ptr->redraw |= (PR_MANA); + + /* Window stuff */ + p_ptr->window |= (PW_PLAYER); + p_ptr->window |= (PW_SPELL); + + return 0; +} + +void do_cmd_thaumat_magic(bool only_browse) +{ + int item; + + /* Not when confused */ + if (!only_browse && p_ptr->confused) + { +#ifdef JP +msg_print("混乱していて唱えられない!"); +#else + msg_print("You are too confused!"); +#endif + + return; + } + + item = select_thaumat_magic(only_browse); + if (item == -1) + { + energy_use = 0; + return; + } +} + static int select_magic_eater(bool only_browse) { int ext=0; diff -uNr src_org/defines.h src/defines.h --- src_org/defines.h Tue Sep 15 22:21:06 2009 +++ src/defines.h Tue May 10 20:23:40 2011 @@ -720,6 +720,7 @@ #define CH_MUSIC 0x08000 /* This is 16th bit */ #define CH_HISSATSU 0x10000 #define CH_HEX 0x20000 +#define CH_THAUMAT 0x40000 /* @@ -741,7 +742,8 @@ #define REALM_MUSIC 16 #define REALM_HISSATSU 17 #define REALM_HEX 18 -#define MAX_REALM 18 +#define REALM_THAUMAT 19 +#define MAX_REALM 19 #define VALID_REALM (MAX_REALM + MAX_MAGIC - MIN_TECHNIC + 1) #define NUM_TECHNIC (MAX_REALM - MIN_TECHNIC + 1) @@ -751,6 +753,8 @@ #define technic2magic(A) (is_magic(A) ? (A) : (A) - MIN_TECHNIC + 1 + MAX_MAGIC) #define is_good_realm(REALM) ((REALM) == REALM_LIFE || (REALM) == REALM_CRUSADE) +#define THAUMAT_MAGICNUM 36 + /* * Magic-books for the realms */ diff -uNr src_org/do-spell.c src/do-spell.c --- src_org/do-spell.c Mon May 9 18:05:18 2011 +++ src/do-spell.c Mon May 9 21:18:00 2011 @@ -494,7 +494,7 @@ } -static void wild_magic(int spell) +void wild_magic(int spell) { int counter = 0; int type = SUMMON_BIZARRE1 + randint0(6); diff -uNr src_org/dungeon.c src/dungeon.c --- src_org/dungeon.c Mon May 9 18:05:18 2011 +++ src/dungeon.c Mon May 9 18:57:40 2011 @@ -4774,6 +4774,8 @@ do_cmd_magic_eater(TRUE); else if (p_ptr->pclass == CLASS_SNIPER) do_cmd_snipe_browse(); + else if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + do_cmd_thaumat_magic(TRUE); else do_cmd_browse(); break; } @@ -4882,6 +4884,8 @@ do_cmd_kaji(FALSE); else if (p_ptr->pclass == CLASS_SNIPER) do_cmd_snipe(); + else if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + do_cmd_thaumat_magic(FALSE); else do_cmd_cast(); } diff -uNr src_org/externs.h src/externs.h --- src_org/externs.h Mon May 9 18:05:20 2011 +++ src/externs.h Mon May 9 21:18:32 2011 @@ -812,10 +812,12 @@ extern void ring_of_power(int dir); extern void do_cmd_use(void); extern void do_cmd_magic_eater(bool only_browse); +extern void do_cmd_thaumat_magic(bool only_browse); /* do-spell.c */ extern void stop_singing(void); extern cptr do_spell(int realm, int spell, int mode); +extern void wild_magic(int spell); /* dungeon.c */ extern void leave_quest_check(void); diff -uNr src_org/load.c src/load.c --- src_org/load.c Mon May 9 18:05:18 2011 +++ src/load.c Mon May 9 20:05:26 2011 @@ -3653,6 +3653,11 @@ /* Important -- Initialize the magic */ mp_ptr = &m_info[p_ptr->pclass]; + /*hack THAUMAT*/ + if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + mp_ptr = &m_info[CLASS_WARRIOR_MAGE]; + } /* Read spell info */ rd_u32b(&p_ptr->spell_learned1); diff -uNr src_org/store.c src/store.c --- src_org/store.c Mon May 9 18:05:20 2011 +++ src/store.c Mon May 9 18:57:54 2011 @@ -4559,6 +4559,8 @@ do_cmd_magic_eater(TRUE); else if (p_ptr->pclass == CLASS_SNIPER) do_cmd_snipe_browse(); + else if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + do_cmd_thaumat_magic(TRUE); else do_cmd_browse(); break; } diff -uNr src_org/tables.c src/tables.c --- src_org/tables.c Mon May 9 18:05:20 2011 +++ src/tables.c Mon May 9 18:17:38 2011 @@ -4067,7 +4067,7 @@ (CH_NATURE), /* Ranger */ (CH_CRUSADE | CH_DEATH), /* Paladin */ (CH_ARCANE), /* Warrior-Mage */ - (CH_CHAOS | CH_DAEMON), /* Chaos-Warrior */ + (CH_CHAOS | CH_DAEMON | CH_THAUMAT), /* Chaos-Warrior */ (CH_LIFE | CH_NATURE | CH_DEATH | CH_ENCHANT), /* Monk */ (CH_NONE), /* Mindcrafter */ @@ -4161,7 +4161,7 @@ "歌", "武芸", "呪術", - "不明" + "無作為" }; #endif @@ -4190,7 +4190,7 @@ "Music", "Kendo", "Hex", - "unknown" + "Thaumat" }; diff -uNr src_org/xtra1.c src/xtra1.c --- src_org/xtra1.c Mon May 9 18:05:20 2011 +++ src/xtra1.c Tue May 10 18:13:02 2011 @@ -2122,6 +2122,12 @@ return; } + if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + p_ptr->new_spells = 0; + return; + } + p = spell_category_name(mp_ptr->spell_book); /* Determine the number of spells allowed */ @@ -2462,6 +2468,10 @@ { levels = p_ptr->lev; } + else if (p_ptr->pclass == CLASS_CHAOS_WARRIOR && p_ptr->realm1 == REALM_THAUMAT) + { + levels = p_ptr->lev; + } else { if(mp_ptr->spell_first > p_ptr->lev) diff -uNr src_org/z-config.h src/z-config.h --- src_org/z-config.h Wed Jul 21 22:51:26 2004 +++ src/z-config.h Mon May 9 21:19:10 2011 @@ -600,7 +600,9 @@ /* * Use world score server */ +/* #define WORLD_SCORE + */ #endif #endif /* HAVE_CONFIG_H */