self._init_notebook_skill1()
self._init_notebook_skill2()
self._init_notebook_setting()
+ self._init_notebook_simulator()
self._init_notebook_amulet()
self.frame_view.EnableNoteBook()
self.notebook_skill1_view.bind_button_search(self.OnClickSkill1Search)
self.notebook_skill1_view.bind_button_clear(self.OnClickSkill1Clear)
+ def _init_notebook_simulator(self):
+ u""" Seed1,Seed2による錬金シミュレータータブのviewの初期化 """
+ self.notebook_simulator_view = self.frame_view.notebook_simulator_view
+ self.notebook_simulator_view.bind_button_search(self.OnClickSimulatorSearch)
+ self.notebook_simulator_view.bind_button_clear(self.OnClickSimulatorClear)
+
+
def _update_notebook_amulet(self, amulet_id=None):
u""" お守り検索タブのviewの更新
amulet_id が Noneでない場合、お守りの種類に応じてComboboxを再設定する
self.notebook_skill2_view.clear_result_text()
self.notebook_skill2_view.clear_inishie()
+ u""" Alchemy Simulator's event """
+ def OnClickSimulatorSearch(self, evt):
+ u""" alchemy simulation from seed1, seed2"""
+ seeds = self.notebook_simulator_view.get_seed_values()
+ alchemy_type = self.notebook_simulator_view.get_tenun_radio_key()
+ if seeds is not None:
+ seed1, seed2 = seeds
+ #try:
+ result = self.db_accessor.simulate_nazo(seed1, seed2)
+ self.notebook_simulator_view.set_values(view.KEY_NAZO, *result)
+ result = self.db_accessor.simulate_komyou(seed1, seed2)
+ self.notebook_simulator_view.set_values(view.KEY_KOMYOU, *result)
+ result = self.db_accessor.simulate_inishie(seed1, seed2)
+ self.notebook_simulator_view.set_values(view.KEY_INISHIE, *result)
+ result = self.db_accessor.simulate_tenun(seed1, seed2, alchemy_type)
+ self.notebook_simulator_view.set_tenun_values(result)
+ #except KeyError, e:
+ # self._show_message_dialog(message=u"指定されたSeed値は存在しません")
+ #finally:
+ self.notebook_simulator_view.update_highlight(self._highlight_skills)
+ else:
+ self._show_message_dialog(message=u"Seed値には数字を入力してください")
+
+ def OnClickSimulatorClear(self, evt):
+ u""" clear simulator form """
+ self.notebook_simulator_view.clear_seed_values()
+ self.notebook_simulator_view.clear_grid()
+ self.notebook_simulator_view.clear_highlight()
+
u""" amulet search event """
def OnClickAmuletRadioAmulet(self, evt):
u""" switch skill lists by amulet id """
--- /dev/null
+# -*- coding: utf-8 -*-
+
+u"""
+錬金のシミュレータ
+2013/12/19 written by kei9
+"""
+
+# import modules
+import sqlite3
+
+import mh4constnumbers
+from randomgenerator import RandomGenerator
+from skillminmaxtable import SkillMinMaxTableAccessor
+from skilltable import SkillTableAccessor
+from amulettable import AmuletTableAccessor
+from sufficienttable import SufficientTableAccessor
+
+class AlchemySimulator(object):
+ u""" 特定Seed1,2から生じる錬金結果を模擬するクラス """
+ def __init__(self, db_cursor):
+ u""" 錬金結果の模擬クラス """
+ self._cursor = db_cursor
+ acc_minmax = SkillMinMaxTableAccessor(db_cursor)
+ acc_skill = SkillTableAccessor(db_cursor)
+ acc_amulet = AmuletTableAccessor(db_cursor)
+ self._acc_suff = SufficientTableAccessor(db_cursor)
+ self._skill_id2name, self._skill_name2id = acc_skill.get_dict()
+ self._amu_id2name, self._amu_name2id = acc_amulet.get_dict()
+ self._minmax_dict = acc_minmax.get_minmax_by_id()
+
+ def _get_skill_value(self, rand1, rand2, skill_max, skill_min):
+ u""" 与えられた2つの乱数値とスキルの最大、最小値からスキル値を計算する """
+ value = (rand1 ^ rand2) % (skill_max - skill_min + 1) + skill_min # XOR
+ return value
+
+ def alchemy_nazo_id(self, seed1, seed2):
+ u""" なぞの錬金
+ return (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+ """
+ gen_c = RandomGenerator(seed1) # generator C
+ gen_d = RandomGenerator(seed2) # generator D
+ return self._judge(gen_c, gen_d, mh4constnumbers.NAME_AMULET0) # nazo
+
+ def alchemy_nazo_name(self, seed1, seed2):
+ u""" なぞの錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ val = self.alchemy_nazo_id(seed1, seed2)
+ skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name = val
+ if skill2_id in self._skill_id2name:
+ return (self._skill_id2name[skill1_id], skill1_val,
+ self._skill_id2name[skill2_id], skill2_val, slot_num, type_name)
+ else:
+ return (self._skill_id2name[skill1_id], skill1_val, u"", 0, slot_num, type_name)
+
+ def alchemy_komyou_id(self, seed1, seed2):
+ u""" 光明の錬金
+ return (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+ """
+ gen_c = RandomGenerator(seed1) # generator C
+ gen_d = RandomGenerator(seed2) # generator D
+ return self._judge(gen_c, gen_d, mh4constnumbers.NAME_AMULET1) # komyou
+
+ def alchemy_komyou_name(self, seed1, seed2):
+ u""" 光明の錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ val = self.alchemy_komyou_id(seed1, seed2)
+ skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name = val
+ if skill2_id in self._skill_id2name:
+ return (self._skill_id2name[skill1_id], skill1_val,
+ self._skill_id2name[skill2_id], skill2_val, slot_num, type_name)
+ else:
+ return (self._skill_id2name[skill1_id], skill1_val, u"", 0, slot_num, type_name)
+
+ def alchemy_inishie_id(self, seed1, seed2):
+ u""" いにしえの錬金
+ return (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+ """
+ gen_c = RandomGenerator(seed1) # generator C
+ gen_d = RandomGenerator(seed2) # generator D
+ return self._judge(gen_c, gen_d, mh4constnumbers.NAME_AMULET2) # inishie
+
+ def alchemy_inishie_name(self, seed1, seed2):
+ u""" いにしえの錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ val = self.alchemy_inishie_id(seed1, seed2)
+ skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name = val
+ if skill2_id in self._skill_id2name:
+ return (self._skill_id2name[skill1_id], skill1_val,
+ self._skill_id2name[skill2_id], skill2_val, slot_num, type_name)
+ else:
+ return (self._skill_id2name[skill1_id], skill1_val, u"", 0, slot_num, type_name)
+
+ def alchemy_tenun_id(self, seed1, seed2, alchemy_type):
+ u""" 天運の錬金 (古*3または歪*3限定。)
+ return list of (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+ """
+ if alchemy_type == mh4constnumbers.KEY_TENUN555:
+ result_num_max = mh4constnumbers.TENUN555_MAX
+ result_num_min = mh4constnumbers.TENUN555_MIN
+ yuga_divisor = mh4constnumbers.TENUN555_DIVISOR
+ elif alchemy_type == mh4constnumbers.KEY_TENUN888:
+ result_num_max = mh4constnumbers.TENUN888_MAX
+ result_num_min = mh4constnumbers.TENUN888_MIN
+ yuga_divisor = mh4constnumbers.TENUN888_DIVISOR
+ else:
+ raise NotImplementedError(u"Irregular Alchemy Type!")
+
+ gen_a = RandomGenerator(seed1) # generator A
+ gen_b = RandomGenerator(seed2) # generator B
+
+ result_num = gen_a.get_next() % (result_num_max - result_num_min + 1) + result_num_min
+ result_list = []
+
+ for i in range(result_num):
+ s1 = gen_a.get_next()
+ s2 = gen_b.get_next()
+ amulet_type = s1 % yuga_divisor
+ if 0 <= amulet_type < 10:
+ u""" 謎のお守り """
+ amulet_name = mh4constnumbers.NAME_AMULET0
+ elif 10 <= amulet_type < 55:
+ u""" 光るお守り """
+ amulet_name = mh4constnumbers.NAME_AMULET1
+ elif 55 <= amulet_type < 85:
+ u""" 古びたお守り """
+ amulet_name = mh4constnumbers.NAME_AMULET2
+ elif 85 <= amulet_type < 100:
+ u""" 歪んだお守り """
+ amulet_name = mh4constnumbers.NAME_AMULET3
+ else:
+ raise NotImplementedError(u"Divisor must be incorrect")
+
+ gen_c = RandomGenerator(s1) # generator C
+ gen_d = RandomGenerator(s2) # generator D
+
+ result_list.append(self._judge(gen_c, gen_d, amulet_name))
+ return result_list
+
+ def alchemy_tenun_name(self, seed1, seed2, alchemy_type):
+ u""" 天運の錬金(古*3または歪*3限定。)
+ return list of (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ result_list = []
+ result = self.alchemy_tenun_id(seed1, seed2, alchemy_type)
+ for skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name in result:
+ if skill2_id in self._skill_id2name:
+ result_list.append(
+ (self._skill_id2name[skill1_id], skill1_val,
+ self._skill_id2name[skill2_id], skill2_val, slot_num, type_name))
+ else:
+ result_list.append((self._skill_id2name[skill1_id], skill1_val, u"", 0, slot_num, type_name))
+
+ return result_list
+
+ def _judge(self, gen_c, gen_d, amulet_name):
+ u""" 乱数生成器C,Dおよびお守りの種類から鑑定を行う
+ return (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+ """
+ amulet_id = self._amu_name2id[amulet_name]
+ skill1_minmax, skill2_minmax = self._minmax_dict[amulet_id]
+ s1 = gen_c.get_next() # for skill1 dicision
+ s1 %= len(skill1_minmax) # skill1_pos
+ skill1_id = [x for i,x in enumerate(sorted(skill1_minmax.keys())) if i == s1][0]
+ min1, max1 = skill1_minmax[skill1_id]
+
+ x1 = gen_c.get_next()
+ x2 = gen_d.get_next()
+ skill1_val = (x1 ^ x2) % (max1 - min1 + 1) + min1 # XOR
+
+ y1 = gen_c.get_next()
+ y2 = gen_d.get_next()
+ border = mh4constnumbers.SKILL2_BORDER_DICT[amulet_name]
+
+ if (y1 ^ y2) % 100 >= border: # decide skill2 to exist
+ s2 = gen_d.get_next() # for skill2 dicision
+ s2 %= len(skill2_minmax) # skill2_pos
+ skill2_id = [x for i,x in enumerate(sorted(skill2_minmax.keys())) if i == s2][0]
+ min2, max2 = skill2_minmax[skill2_id]
+
+ if min2 < 0:
+ z0 = gen_c.get_next()
+ else:
+ z0 = None
+
+ z1 = gen_c.get_next()
+ z2 = gen_d.get_next()
+ if min2 < 0 and z0 % 2 == 0: # skill2 val is minus
+ skill2_val = (z1 ^ z2) % (1 - min2) + min2
+ else: # skill2 val is plus
+ skill2_val = (z1 ^ z2) % max2 + 1
+
+ if skill2_id == skill1_id or skill2_val == 0:
+ skill2_id = None
+ skill2_val = 0
+ else:
+ skill2_id = None
+ skill2_val = 0
+
+ # slot number
+ if skill2_val <= 0:
+ suff_val = (skill1_val * 10) // max1
+ else:
+ suff_val = (skill1_val * 10) // max1 + (skill2_val * 10) // max2
+
+ w = gen_c.get_next()
+ if (w & mh4constnumbers.SEED_DECIDE_FLAG) != 0: # falg = 128, 50%
+ w2 = gen_c.get_next()
+ else:
+ w2 = gen_d.get_next()
+ _slot = w2 % 100
+
+ th1_slot, th2_slot, th3_slot = self._acc_suff.select_thresholds_by_id(amulet_id, suff_val)
+ if _slot < th1_slot:
+ slot_num = 0
+ slot_point = mh4constnumbers.SLOT_POINT0
+ elif th1_slot <= _slot < th2_slot:
+ slot_num = 1
+ slot_point = mh4constnumbers.SLOT_POINT1
+ elif th2_slot <= _slot < th3_slot:
+ slot_num = 2
+ slot_point = mh4constnumbers.SLOT_POINT2
+ elif th3_slot <= _slot:
+ slot_num = 3
+ slot_point = mh4constnumbers.SLOT_POINT3
+
+ type_name = self._decide_amulet_type(suff_val, slot_point, amulet_name)
+
+ return (skill1_id, skill1_val, skill2_id, skill2_val, slot_num, type_name)
+
+
+ def _decide_amulet_type(self, suff_val, slot_point, amulet_name):
+ u""" 鑑定結果の護石名を充足値、スロットポイント、お守り名から決定する """
+ type_val = suff_val + slot_point
+
+ border1, border2, border3 = mh4constnumbers.TYPE_BORDER_DICT[amulet_name]
+ if type_val >= border3[0]:
+ return border3[1]
+ elif type_val >= border2[0]:
+ return border2[1]
+ elif type_val >= border1[0]: # 0
+ return border1[1]
+ else:
+ return None
from seed2inishietable import Seed2InishieTableAccessor
from sufficienttable import SufficientTableAccessor
from seed1tenuntable import Seed1TenunTableAccessor
+from alchemysimulator import AlchemySimulator
class DataBaseAccessor(object):
u""" this is access class to database """
self._acc_seed2inishie = Seed2InishieTableAccessor(self._cursor)
self._acc_sufficient = SufficientTableAccessor(self._cursor)
self._acc_seed1tenun = Seed1TenunTableAccessor(self._cursor)
+ self._simulator = AlchemySimulator(self._cursor)
self._minmax_dict_by_name = self._acc_minmax.get_minmax_by_name()
else:
return None
+ def simulate_nazo(self, seed1, seed2):
+ u""" なぞの錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ return self._simulator.alchemy_nazo_name(seed1, seed2)
+
+ def simulate_komyou(self, seed1, seed2):
+ u""" 光明の錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ return self._simulator.alchemy_komyou_name(seed1, seed2)
+
+ def simulate_inishie(self, seed1, seed2):
+ u""" いにしえの錬金
+ return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ return self._simulator.alchemy_inishie_name(seed1, seed2)
+
+ def simulate_tenun(self, seed1, seed2, alchemy_key):
+ u""" 天運の錬金
+ return list of (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
+ """
+ return self._simulator.alchemy_tenun_name(seed1, seed2, alchemy_key)
+
def close(self):
u""" close database accessor """
self._cursor.close()
SKILL2_BORDER_DICT[NAME_AMULET0] = 100 # nazo
SKILL2_BORDER_DICT[NAME_AMULET1] = 35 # hika
SKILL2_BORDER_DICT[NAME_AMULET2] = 25 # huru
-SKILL2_BORDER_DICT[NAME_AMULET2] = 20 # yuga
+SKILL2_BORDER_DICT[NAME_AMULET3] = 20 # yuga
# amulet
--- /dev/null
+# -*- coding: utf-8 -*-
+
+# random generator for MH4
+# データベース関連の定数値など
+# 2013/12/18 written by kei9
+
+# import modules
+import mh4constnumbers
+
+class RandomGenerator():
+ u""" MH4での乱数生成器 """
+ COEFFICIENT = 176
+ DIVISOR = 65363
+
+ def __init__(self, seed):
+ self._first_seed = seed
+ self._next_seed = seed
+
+ def get_next(self):
+ u""" 前回の乱数値より次の乱数値を計算する """
+ self._next_seed = self._get_next_rand(self._next_seed)
+ return self._next_seed
+
+ def _get_next_rand(self, seed):
+ u""" 指定されたseedから乱数を生成する """
+ return seed * self.COEFFICIENT % self.DIVISOR
+
+
KEY_AMULET3 = u"amulet3"
KEY_THRESHOLD1 = u"threshold1"
KEY_THRESHOLD2 = u"threshold2"
+KEY_NAZO = u"nazo"
+KEY_KOMYOU = u"komyou"
+KEY_INISHIE = u"inishie"
+KEY_TENUN = u"tenun"
KEY_TENUN555 = u"tenun555"
KEY_TENUN888 = u"tenun888"
AMULET_NAME_TO_SHORT_NAME_DICT = {NAME_AMULET0:SHORT_NAME_AMULET0,
NUM_SKILL1_GRID_COL = 9
NUM_SKILL1_GRID_ROW = 50
+# simulator grid
+LABEL_FORMAT_SIMULATOR_GRID_ROW1 = u"なぞの錬金"
+LABEL_FORMAT_SIMULATOR_GRID_ROW2 = u"光明の錬金"
+LABEL_FORMAT_SIMULATOR_GRID_ROW3 = u"いにしえの錬金"
+LABEL_FORMAT_SIMULATOR_GRID_ROW4 = u"天運の錬金: 1枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW5 = u"天運の錬金: 2枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW6 = u"天運の錬金: 3枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW7 = u"天運の錬金: 4枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW8 = u"天運の錬金: 5枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW9 = u"天運の錬金: 6枠目"
+LABEL_FORMAT_SIMULATOR_GRID_ROW10 = u"天運の錬金: 7枠目"
+LABEL_FORMAT_SIMULATOR_GRID_COL1 = u"護石名"
+LABEL_FORMAT_SIMULATOR_GRID_COL2 = u"スキル1"
+LABEL_FORMAT_SIMULATOR_GRID_COL3 = u"値"
+LABEL_FORMAT_SIMULATOR_GRID_COL4 = u"スキル2"
+LABEL_FORMAT_SIMULATOR_GRID_COL5 = u"値"
+LABEL_FORMAT_SIMULATOR_GRID_COL6 = u"スロット数"
+NUM_SIMULATOR_GRID_COL = 6
+NUM_SIMULATOR_GRID_ROW = 10
+SIMULATOR_GRID_SKILL_NAME_COLS = [1,3]
+SIMULATOR_GRID_ROW_DICT = {KEY_NAZO:0, KEY_KOMYOU:1, KEY_INISHIE:2, KEY_TENUN:(3,4,5,6,7,8,9)}
+
# amulet seed2s grid
LABEL_FORMAT_AMULET_SEED2S_GRID_COL1 = u"錬金の種類"
NUM_AMULET_SEED2S_GRID_COL = 1
<object class="notebookpage" expanded="1">
<property name="bitmap"></property>
<property name="label">Seed1対応スキル</property>
- <property name="select">1</property>
+ <property name="select">0</property>
<object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<object class="notebookpage" expanded="1">
<property name="bitmap"></property>
<property name="label">錬金シミュレータ</property>
- <property name="select">0</property>
+ <property name="select">1</property>
<object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="permission">none</property>
<property name="rows">2</property>
<property name="vgap">0</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER|wxALL</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
+ <object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER|wxALL</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
+ <object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
</object>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxRadioBox" expanded="1">
+ <object class="wxRadioBox" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="name">bSizer29</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
- <object class="spacer" expanded="1">
+ <object class="spacer" expanded="0">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_BOTTOM|wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
- <object class="wxButton" expanded="1">
+ <object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_BOTTOM|wxALL</property>
<property name="proportion">0</property>
- <object class="wxButton" expanded="1">
+ <object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
</object>
</object>
</object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">錬金結果</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer231</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panel18</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer30</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">5</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">GridSimulator</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">80</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">5</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
</object>
</object>
</object>
</object>
<object class="notebookpage">
<label>Seed1対応スキル</label>
- <selected>1</selected>
+ <selected>0</selected>
<object class="wxPanel" name="NoteBookPanelSkill1">
<style>wxTAB_TRAVERSAL</style>
<object class="wxBoxSizer">
</object>
<object class="notebookpage">
<label>錬金シミュレータ</label>
- <selected>0</selected>
+ <selected>1</selected>
<object class="wxPanel" name="NotebookAlchemySimulator">
<style>wxTAB_TRAVERSAL</style>
<object class="wxBoxSizer">
</object>
</object>
</object>
+ <object class="sizeritem">
+ <option>1</option>
+ <flag>wxEXPAND</flag>
+ <border>5</border>
+ <object class="wxStaticBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <label>錬金結果</label>
+ <object class="sizeritem">
+ <option>1</option>
+ <flag>wxEXPAND | wxALL</flag>
+ <border>5</border>
+ <object class="wxPanel" name="m_panel18">
+ <style>wxTAB_TRAVERSAL</style>
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <option>1</option>
+ <flag>wxALL|wxEXPAND</flag>
+ <border>0</border>
+ <object class="wxGrid" name="GridSimulator" />
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
</object>
</object>
</object>
from notebookskill2view import NoteBookSkill2View
from notebookskill1view import NoteBookSkill1View
from notebookamuletview import NoteBookAmuletView
+from notebookalchemysimulatorview import NoteBookAlchemySimulatorView
class MainFrameView():
u""" メインのフレームクラス """
# skill2 search from seed2 view
self.notebook_skill1_view = NoteBookSkill1View(self.frame)
+ # simulator view
+ self.notebook_simulator_view = NoteBookAlchemySimulatorView(self.frame)
+
+ # amulet view
+ self.notebook_amulet_view = NoteBookAmuletView(self.frame)
+
+ # flow view
+ self.notebook_flow_view = NoteBookFlowView(self.frame)
+
+ # setting view
+ self.notebook_setting_view = NoteBookSettingView(self.frame)
+
+ def Show(self):
+ self.frame.Show()
+
+ def Close(self):
+ self.frame.Close(True)
+
+ def DisableNoteBook(self):
+ self.note_book.Disable()
+
+ def EnableNoteBook(self):
+ self.note_book.Enable()
+
+ def OnAboutBox(self, evt):
+ u""" Show About Box """
+ info = wx.AboutDialogInfo()
+ info.Name = constnumbers.NAME
+ info.Version = constnumbers.VERSION
+ info.Copyright = constnumbers.COPYRIGHT
+ info.Description = constnumbers.DESCRIPTION
+ info.WebSite = (constnumbers.WEBSITE_LINK, constnumbers.WEBSITE_TEXT)
+ info.Developers = constnumbers.DEVELOPERS
+ info.License = constnumbers.LICENSE_TEXT
+ wx.AboutBox(info)
+
+ # amulet view
+ self.notebook_amulet_view = NoteBookAmuletView(self.frame)
+
+ # flow view
+ self.notebook_flow_view = NoteBookFlowView(self.frame)
+
+ # setting view
+ self.notebook_setting_view = NoteBookSettingView(self.frame)
+
+ def Show(self):
+ self.frame.Show()
+
+ def Close(self):
+ self.frame.Close(True)
+
+ def DisableNoteBook(self):
+ self.note_book.Disable()
+
+ def EnableNoteBook(self):
+ self.note_book.Enable()
+
+ def OnAboutBox(self, evt):
+ u""" Show About Box """
+ info = wx.AboutDialogInfo()
+ info.Name = constnumbers.NAME
+ info.Version = constnumbers.VERSION
+ info.Copyright = constnumbers.COPYRIGHT
+ info.Description = constnumbers.DESCRIPTION
+ info.WebSite = (constnumbers.WEBSITE_LINK, constnumbers.WEBSITE_TEXT)
+ info.Developers = constnumbers.DEVELOPERS
+ info.License = constnumbers.LICENSE_TEXT
+ wx.AboutBox(info)
+
# amulet view
self.notebook_amulet_view = NoteBookAmuletView(self.frame)
--- /dev/null
+
+# -*- coding: utf-8 -*-
+
+# GUIのメインフレームにおける錬金シミュレーターNotebookのview
+# 2013/12/15 written by kei9
+import wx
+from wx import xrc
+import wx.grid
+
+import constnumbers
+
+class NoteBookAlchemySimulatorView():
+ u""" メインのフレームの錬金シミュレータータブ """
+ def __init__(self, frame):
+ self.frame = frame
+ self._init_view()
+
+ def _init_view(self):
+ # initialize view
+ self.grid_sim = xrc.XRCCTRL(self.frame, "GridSimulator")
+ self.grid_sim.Bind(wx.EVT_SIZE, self.OnGridSizeChanged)
+
+ self.button_search = xrc.XRCCTRL(self.frame, "ButtonSimulatorSearch")
+ self.button_clear = xrc.XRCCTRL(self.frame, "ButtonSimulatorClear")
+
+ self.radiobox_tenun = xrc.XRCCTRL(self.frame, "RadioBoxSimulatorTenun")
+
+ # load simulator grid value
+ self.grid_sim.CreateGrid(constnumbers.NUM_SIMULATOR_GRID_ROW, constnumbers.NUM_SIMULATOR_GRID_COL)
+ self.grid_sim.SetColLabelValue(0, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL1)
+ self.grid_sim.SetColLabelValue(1, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL2)
+ self.grid_sim.SetColLabelValue(2, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL3)
+ self.grid_sim.SetColLabelValue(3, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL4)
+ self.grid_sim.SetColLabelValue(4, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL5)
+ self.grid_sim.SetColLabelValue(5, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_COL6)
+
+ self.grid_sim.SetRowLabelValue(0, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW1)
+ self.grid_sim.SetRowLabelValue(1, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW2)
+ self.grid_sim.SetRowLabelValue(2, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW3)
+ self.grid_sim.SetRowLabelValue(3, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW4)
+ self.grid_sim.SetRowLabelValue(4, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW5)
+ self.grid_sim.SetRowLabelValue(5, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW6)
+ self.grid_sim.SetRowLabelValue(6, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW7)
+ self.grid_sim.SetRowLabelValue(7, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW8)
+ self.grid_sim.SetRowLabelValue(8, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW9)
+ self.grid_sim.SetRowLabelValue(9, constnumbers.LABEL_FORMAT_SIMULATOR_GRID_ROW10)
+ self.grid_sim.DisableDragGridSize()
+ self.grid_sim.EnableEditing(False)
+
+ # text ctrl
+ self.text_ctrl_seed1 = xrc.XRCCTRL(self.frame, "TextCtrlSimulatorSeed1")
+ self.text_ctrl_seed2 = xrc.XRCCTRL(self.frame, "TextCtrlSimulatorSeed2")
+
+
+ def OnGridSizeChanged(self, event):
+ u""" Gridリサイズ時に親パネルのwidthに応じて自動で横に伸長する """
+ width, height = self.grid_sim.GetParent().GetSize()
+ each_width = (width - 130) / (constnumbers.NUM_SIMULATOR_GRID_COL) # consider margin size
+ self.grid_sim.SetRowLabelSize(120)
+ for col in range(constnumbers.NUM_SIMULATOR_GRID_COL):
+ self.grid_sim.SetColSize(col, each_width)
+
+ def bind_button_search(self, event_func, evt=wx.EVT_BUTTON):
+ u""" 検索ボタンへのイベント登録 """
+ self.button_search.Bind(evt, event_func)
+
+ def bind_button_clear(self, event_func, evt=wx.EVT_BUTTON):
+ u""" クリアボタンへのイベント登録 """
+ self.button_clear.Bind(evt, event_func)
+
+ def update_highlight(self, skill_names, color="Yellow"):
+ u""" スキル名が一致するセルをハイライトする """
+ for row in range(self.grid_sim.GetNumberRows()):
+ for col in constnumbers.SIMULATOR_GRID_SKILL_NAME_COLS:
+ skill_name = self.grid_sim.GetCellValue(row, col)
+ if skill_name in skill_names:
+ self.grid_sim.SetCellBackgroundColour(row, col, color)
+ else:
+ self.grid_sim.SetCellBackgroundColour(row, col, wx.NullColor)
+
+ def clear_highlight(self):
+ u""" セルの強調表示をクリアする """
+ for row in range(self.grid_sim.GetNumberRows()):
+ for col in range(self.grid_sim.GetNumberCols()):
+ self.grid_sim.SetCellBackgroundColour(row, col, wx.NullColor)
+
+ def clear_grid(self):
+ u""" セルの内容をクリアする """
+ for row in range(self.grid_sim.GetNumberRows()):
+ for col in range(self.grid_sim.GetNumberCols()):
+ self.grid_sim.SetCellValue(row, col, u"")
+
+ def set_seed_values(self, seed1, seed2):
+ u""" TextCtrlに与えられた値をセットする"""
+ self.text_ctrl_seed1.SetValue(u"{0}".format(seed1))
+ self.text_ctrl_seed2.SetValue(u"{0}".format(seed2))
+
+ def clear_seed_values(self):
+ u""" TextCtrlに与えられた値をセットする"""
+ self.text_ctrl_seed1.SetValue(u"")
+ self.text_ctrl_seed2.SetValue(u"")
+
+ def get_seed_values(self):
+ u""" TextCtrlから入力されたSeed1, Seed2の値を得る。数値に変換できない時はNoneを返す"""
+ seed1 = self.text_ctrl_seed1.GetValue()
+ seed2 = self.text_ctrl_seed2.GetValue()
+ if seed1.isdigit() and seed2.isdigit():
+ return int(seed1), int(seed2)
+ else:
+ return None
+
+ def get_tenun_radio_key(self):
+ u""" 天運の錬金で使用したお守りの種類を示すkeyを返す """
+ idx = self.radiobox_tenun.GetSelection()
+ if idx == 0:
+ return constnumbers.KEY_TENUN555
+ elif idx == 1:
+ return constnumbers.KEY_TENUN888
+ else:
+ return None
+
+ def set_tenun_radio_key(self, alchemy_key):
+ u""" 天運の錬金で使用したお守りの種類を示すkeyにより、ラジオボックスの選択状態を変更 """
+ if alchemy_key == constnumbers.KEY_TENUN555:
+ self.radiobox_tenun.SetSelection(0)
+ elif alchemy_key == constnumbers.KEY_TENUN888:
+ self.radiobox_tenun.SetSelection(1)
+ else:
+ pass
+
+ def set_tenun_values(self, values):
+ u""" values: list of (skill_name1, skill_val1, skill_name2, skill_val2, slot_num, amulet_name)
+ 天運の錬金の対応する値のセット """
+ rows = constnumbers.SIMULATOR_GRID_ROW_DICT[constnumbers.KEY_TENUN]
+
+ for row in rows:
+ for col in range(self.grid_sim.GetNumberCols()):
+ self.grid_sim.SetCellValue(row, col, u"")
+
+ for row, (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, amulet_name) in zip(rows, values):
+ self.grid_sim.SetCellValue(row, 0, amulet_name)
+ self.grid_sim.SetCellValue(row, 1, skill1_name)
+ self.grid_sim.SetCellValue(row, 2, u"{0}".format(skill1_val))
+ if skill2_name != u"":
+ self.grid_sim.SetCellValue(row, 3, skill2_name)
+ self.grid_sim.SetCellValue(row, 4, u"{0}".format(skill2_val))
+ else:
+ self.grid_sim.SetCellValue(row, 3, u"")
+ self.grid_sim.SetCellValue(row, 4, u"")
+ self.grid_sim.SetCellValue(row, 5, u"{0}".format(slot_num))
+
+ def set_values(self, alchemy_type,
+ skill1_name, skill1_val, skill2_name, skill2_val, slot_num, amulet_name):
+ u""" なぞ・光明・いにしえの錬金の対応する値のセット """
+ row = constnumbers.SIMULATOR_GRID_ROW_DICT[alchemy_type]
+ self.grid_sim.SetCellValue(row, 0, amulet_name)
+ self.grid_sim.SetCellValue(row, 1, skill1_name)
+ self.grid_sim.SetCellValue(row, 2, u"{0}".format(skill1_val))
+ if skill2_name != u"":
+ self.grid_sim.SetCellValue(row, 3, skill2_name)
+ self.grid_sim.SetCellValue(row, 4, u"{0}".format(skill2_val))
+ else:
+ self.grid_sim.SetCellValue(row, 3, u"")
+ self.grid_sim.SetCellValue(row, 4, u"")
+ self.grid_sim.SetCellValue(row, 5, u"{0}".format(slot_num))
self.text_ctrl_inishie_threshold1 = xrc.XRCCTRL(self.frame, "TextCtrlInishieThreshold1")
self.text_ctrl_inishie_threshold2 = xrc.XRCCTRL(self.frame, "TextCtrlInishieThreshold2")
- self.list_box_amulet_prospect = xrc.XRCCTRL(self.frame, "ListBoxSeedSkillAmuletProspect")
- self.ID_LIST_BOX_AMULET_PROSPECT = xrc.XRCID("ListBoxSeedSkillAmuletProspect")
-
def OnSkill2GridSize(self, event):
u""" Gridリサイズ時に親パネルのwidthに応じて自動で横に伸長する """
width, height = self.skill2_grid.GetParent().GetSize()