code:
;-------------------------------------------------
;キャラクタ表示順のリストを作成
;RESORT 所属勢力ごとの再ソートを行うかのフラグ
;-------------------------------------------------
@CREATE_SELECTOR_SORT_LIST(RESORT = 1)
#DIM RESORT
#DIM SORT_VALUE,  MAX_CHARA_NUM
#DIMS SORT_STRING, MAX_CHARA_NUM
#DIM CHARA_TABLE, MAX_CHARA_NUM
#DIM SORT_BY_STRING
VARSET SHOP_CHARA_LIST, -1

VARSET CHARA_TABLE, -1
VARSET SORT_VALUE, -1
VARSET SORT_STRING
SORT_BY_STRING = 0

FOR LOCAL, 0, CHARANUM
	SELECTCASE ソートキー
		CASE ソート_所属
			SORT_VALUE:LOCAL = CFLAG:LOCAL:所属
		CASE ソート_NO
			SORT_VALUE:LOCAL = NO:LOCAL
		CASE ソート_星
			SORT_VALUE:LOCAL = TMP_CHARA_STARS:LOCAL
		CASE ソート_名前
			SORT_STRING:LOCAL = %ANAME(LOCAL)%
			SORT_BY_STRING = 1
		CASE ソート_好感度
			SORT_VALUE:LOCAL = CFLAG:LOCAL:好感度
		CASE ソート_従属度
			SORT_VALUE:LOCAL = CFLAG:LOCAL:従属度
		CASE ソート_支配度
			SORT_VALUE:LOCAL = CFLAG:LOCAL:支配度
		CASE ソート_妊娠
			IF CFLAG:LOCAL:行動不能状態 == 行動不能_臨月
				SORT_VALUE:LOCAL = 2
			ELSEIF TALENT:LOCAL:妊娠
				SORT_VALUE:LOCAL = 1
			ELSEIF CFLAG:LOCAL:行動不能状態 == 行動不能_育児
				SORT_VALUE:LOCAL = 3
			ELSEIF CFLAG:LOCAL:行動不能状態 == 行動不能_子供
				SORT_VALUE:LOCAL = 4
			ELSE
				SORT_VALUE:LOCAL = __INT_MAX__
			ENDIF
		CASE ソート_性別
			SORT_VALUE:LOCAL = TALENT:LOCAL:性別
		CASE ソート_面識
			SORT_VALUE:LOCAL = CFLAG:LOCAL:面識
		CASE ソート_武闘
			SORT_VALUE:LOCAL = ABL:LOCAL:身体
		CASE ソート_防衛
			SORT_VALUE:LOCAL = ABL:LOCAL:器用
		CASE ソート_知識
			SORT_VALUE:LOCAL = ABL:LOCAL:知識
		CASE ソート_社交
			SORT_VALUE:LOCAL = ABL:LOCAL:社交
		CASE ソート_歌唱
			SORT_VALUE:LOCAL = ABL:LOCAL:歌唱
		CASE ソート_料理
			SORT_VALUE:LOCAL = ABL:LOCAL:料理
		CASE ソート_妖術
			SORT_VALUE:LOCAL = ABL:LOCAL:魔術
		CASE ソート_四能力
			SORT_VALUE:LOCAL = ABL:LOCAL:身体 + ABL:LOCAL:器用 + ABL:LOCAL:知識 + ABL:LOCAL:社交
		CASE ソート_七能力
			SORT_VALUE:LOCAL = ABL:LOCAL:身体 + ABL:LOCAL:器用 + ABL:LOCAL:知識 + ABL:LOCAL:社交 + ABL:LOCAL:料理 + ABL:LOCAL:歌唱 + ABL:LOCAL:魔術
		CASE ソート_夜這い助手
			SORT_VALUE:LOCAL = YOBAI_ZYOSYU_CALC_POINT(LOCAL)
		CASE ソート_手引助手
			SORT_VALUE:LOCAL = TEBIKI_ZYOSYU_CALC_POINT(LOCAL)
	ENDSELECT

	CHARA_TABLE:LOCAL = LOCAL

NEXT

FOR LOCAL,1,CHARANUM
	SIF CHARA_TABLE:LOCAL == -1
		BREAK
	FOR LOCAL:11,LOCAL,0,-1
		LOCAL:12 = CHARA_TABLE:(LOCAL:11-1)
		LOCAL:13 = CHARA_TABLE:(LOCAL:11)
		IF !SORT_BY_STRING
			IF (降順ソート && SORT_VALUE:(LOCAL:12) < SORT_VALUE:(LOCAL:13)) || (!降順ソート && SORT_VALUE:(LOCAL:12) > SORT_VALUE:(LOCAL:13))
				SWAP CHARA_TABLE:(LOCAL:11),CHARA_TABLE:(LOCAL:11 -1)
			ELSE
				BREAK
			ENDIF
		ELSE
			IF (降順ソート && SORT_STRING:(LOCAL:12) > SORT_STRING:(LOCAL:13)) || (!降順ソート && SORT_STRING:(LOCAL:12) < SORT_STRING:(LOCAL:13))
				SWAP CHARA_TABLE:(LOCAL:11),CHARA_TABLE:(LOCAL:11 -1)
			ELSE
				BREAK
			ENDIF
		ENDIF
	NEXT
NEXT

IF RESORT == 0
	FOR LOCAL:0, 0, CHARANUM
		SHOP_CHARA_LIST:LOCAL = CHARA_TABLE:LOCAL
	NEXT
ELSE

	LOCAL:5 = 0

	;SHOP_CHARA_LIST:(LOCAL:5) = MASTER
	;LOCAL:5 ++

	;主人公と同一勢力の士官が第１優先
	FOR LOCAL:0, 0, CHARANUM
		LOCAL:1 = CHARA_TABLE:LOCAL
		;主人公でない「あなた」は飛ばす
		SIF LOCAL:1 == NAME_TO_CHARA("あなた") && LOCAL:1 != MASTER
			CONTINUE
		IF CFLAG:(LOCAL:1):所属 == CFLAG:MASTER:所属
			SHOP_CHARA_LIST:(LOCAL:5) = LOCAL:1
			LOCAL:5 ++
		ENDIF
	NEXT

	;他勢力・捕虜でない士官が第２優先
	FOR LOCAL:0, 0, CHARANUM
		LOCAL:1 = CHARA_TABLE:LOCAL
		;主人公でない「あなた」は飛ばす
		SIF LOCAL:1 == NAME_TO_CHARA("あなた") && LOCAL:1 != MASTER
			CONTINUE
		IF CFLAG:(LOCAL:1):所属 != CFLAG:MASTER:所属 && !CFLAG:(LOCAL:1):捕虜先
			SIF LOCAL:1 == NAME_TO_CHARA("あなた") && LOCAL:1 != MASTER
				CONTINUE
			SHOP_CHARA_LIST:(LOCAL:5) = LOCAL:1
			LOCAL:5 ++
		ENDIF
	NEXT

	;他勢力・捕虜がラスト
	FOR LOCAL:0, 0, CHARANUM
		LOCAL:1 = CHARA_TABLE:LOCAL
		;主人公でない「あなた」は飛ばす
		SIF LOCAL:1 == NAME_TO_CHARA("あなた") && LOCAL:1 != MASTER
			CONTINUE
		IF CFLAG:(LOCAL:1):所属 != CFLAG:MASTER:所属 && CFLAG:(LOCAL:1):捕虜先
			SHOP_CHARA_LIST:(LOCAL:5) = LOCAL:1
			LOCAL:5 ++
		ENDIF
	NEXT
ENDIF

;-------------------------------------------------
;右カラムの標準的なキャラリスト
;引数）
;　LINE_NUM_BUTTON			一行にボタンを何個並べるか（初期値２）
;　BUTTON_NUM_LINE			１ボタン指定で何行とるか（初期値１）
;							捕虜の扱い等、１キャラに対して大量のボタンがある場合等に使用する想定
;他）
;　MAX_BUTTON				１ページに表示可能なボタンの最大値
;　NOW_BUTTON				現在何個目のボタンを表示したか
;　NOW_BUTTON_PAGE			現在のページで何個目のボタンを表示したか
;　MENU_CHARANUM			このメニューで選択可能なキャラの人数
;							グレー表示で選択できないが表示するキャラも含める
;　NOW_CHECK_CHARA			現在チェック中のキャラ。
;							キャラリスト順にボタンを並べたいのでループカウンタを
;							そのままキャラ番号として扱わない
;　NOW_PAGE_BUTTON_START	現在のページの最初に置くボタンが何番か
;　NOW_PAGE_BUTTON_END		現在のページの最後に置くボタンが何番か
;　PRINTOPTION				このキャラは「選択不可能非表示」か「選択可能」か
;							「選択不可能グレー表示」か判定の戻り値
;-------------------------------------------------
@COLUMN_RIGHT_CHARALIST(LINE_NUM_BUTTON = 2, BUTTON_LINE = 1)
#DIM MAX_BUTTON
#DIM NOW_BUTTON
#DIM NOW_BUTTON_PAGE
#DIM MENU_CHARANUM
#DIM NOW_CHECK_CHARA
#DIM NOW_PAGE_BUTTON_START
#DIM NOW_PAGE_BUTTON_END
#DIM LINE_NUM_BUTTON
#DIM BUTTON_LINE
#DIM PRINTOPTION
#DIM CONST MAX_ROW = 32

;ひとつのページに表示可能なボタン数の最大値を計算 ((拠点フェイズ画面最大行数 - 2 - 現在表示行数) * LINE_NUM_BUTTON) / BUTTON_LINE
MAX_BUTTON = ((MAX_ROW - 2 - (LINECOUNT - FIRST_COLUMN_RIGHT_LINE)) * LINE_NUM_BUTTON) / BUTTON_LINE

;選択可能キャラ人数
MENU_CHARANUM = 0

FOR LOCAL:0, 0, CHARANUM
	;選択可能な条件を満たしているキャラを判定
	TRYCALLFORM SHOP_LIFE_CHECKCHARA{FLAG:拠点フェイズ選択コマンド}(LOCAL:0)
	IF RESULT
		;選択可能キャラ人数加算
		MENU_CHARANUM ++
	ENDIF
NEXT

;最大ページ数の計算（キャラ数－１÷最大ボタン数で計算して＋１し、最低でも１以上にする）
SHOP_LIFE_LIST1_PAGE_MAX = MAX((MENU_CHARANUM - 1) / MAX_BUTTON + 1, 1)

;現在のページ数を範囲に収める
FLAG:拠点フェイズページ = (SHOP_LIFE_LIST1_PAGE_MAX - 1 + FLAG:拠点フェイズページ % SHOP_LIFE_LIST1_PAGE_MAX) % SHOP_LIFE_LIST1_PAGE_MAX + 1

;リセット現在ボタン数
NOW_BUTTON = 0
;リセット現在ページの表示ボタン数
NOW_BUTTON_PAGE = 0
;リセット現在ページの開始値（ボタン数）
NOW_PAGE_BUTTON_START = (FLAG:拠点フェイズページ - 1) * MAX_BUTTON
;リセット現在ページの終了値（ボタン数）
NOW_PAGE_BUTTON_END = FLAG:拠点フェイズページ * MAX_BUTTON

;キャラリスト開始
FOR LOCAL:0, 0, CHARANUM
	;今回チェックするキャラ（キャラ番号順ではなく、リスト用に並び替えられた順でチェック）
	NOW_CHECK_CHARA = SHOP_CHARA_LIST:(LOCAL:0)
	;リストから除外されているキャラなら次のキャラへ
	SIF NOW_CHECK_CHARA == -1
		CONTINUE
	;キャラが選択可能な条件を満たしているかを判定（PRINTOPTION=2 条件は満たしているが行動済みの場合グレー表示）
	RESULT = 0
	TRYCALLFORM SHOP_LIFE_CHECKCHARA{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA)
	PRINTOPTION = RESULT
	IF RESULT
		IF NOW_BUTTON >= NOW_PAGE_BUTTON_START && NOW_BUTTON < NOW_PAGE_BUTTON_END
			;ボタンを１行に並べる数
			IF NOW_BUTTON_PAGE % LINE_NUM_BUTTON != 0
				PRINTPLAIN
			ELSE
				IF NOW_BUTTON_PAGE >= 1
					CALL COLUMN_RIGHT_PRINTL
				ENDIF
			ENDIF
			;ボタンの独自指定があれば呼び、なければ通常のボタンを表示
			TRYCCALLFORM SHOP_LIFE_LIST1_BUTTON{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA, PRINTOPTION)
			CATCH
				CALL COLUMN_RIGHT_CHARALIST_BUTTON(NOW_CHECK_CHARA, 0, SHOP_LIFE_LIST1_ADD_INPUT, PRINTOPTION)
			ENDCATCH
			;現在ページの表示ボタン数を追加
			NOW_BUTTON_PAGE ++
		ENDIF
		;現在ボタン数を追加
		NOW_BUTTON ++
	ENDIF
NEXT

;ページ移動表示
IF LINECOUNT - FIRST_COLUMN_RIGHT_LINE < LINES_SHOP_DRAW
	FOR LOCAL:0, LINECOUNT - FIRST_COLUMN_RIGHT_LINE, LINES_SHOP_DRAW - 1
		CALL COLUMN_RIGHT_PRINTL
		IF LOCAL:0 == LINES_SHOP_DRAW - 3
			CALL COLUMN_RIGHT_LINE
		ELSEIF LOCAL:0 == LINES_SHOP_DRAW - 2
			IF SHOP_LIFE_LIST1_PAGE_MAX >= 2
				PRINTBUTTON @"[%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST1_PAGE_BACK
			ELSE
				SETCOLOR カラー_選択不可
				PRINTPLAINFORM [%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]
				RESETCOLOR
			ENDIF
			PRINTPLAINFORM %TOSTR_SPACE(10)%
			LOCALS:0 = page{FLAG:拠点フェイズページ}/{SHOP_LIFE_LIST1_PAGE_MAX}
			PRINTPLAINFORM %LOCALS:0, 16, LEFT%
			IF SHOP_LIFE_LIST1_PAGE_MAX >= 2
				PRINTBUTTON @"[%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST1_PAGE_NEXT
			ELSE
				SETCOLOR カラー_選択不可
				PRINTPLAINFORM [%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]
				RESETCOLOR
			ENDIF
		ENDIF
	NEXT
ENDIF

PRINTL

RETURN 0

;-------------------------------------------------
;右カラムの上下２段のキャラリスト上
;-------------------------------------------------
@COLUMN_RIGHT_CHARALIST_TOP(LINE_NUM_BUTTON = 2, BUTTON_LINE = 1)
#DIM MAX_BUTTON
#DIM NOW_BUTTON
#DIM NOW_BUTTON_PAGE
#DIM MENU_CHARANUM
#DIM NOW_CHECK_CHARA
#DIM NOW_PAGE_BUTTON_START
#DIM NOW_PAGE_BUTTON_END
#DIM LINE_NUM_BUTTON
#DIM BUTTON_LINE
#DIM PRINTOPTION

MAX_BUTTON = ((LINES_SHOP_DRAW / 2 - 2  - (LINECOUNT - FIRST_COLUMN_RIGHT_LINE)) * LINE_NUM_BUTTON) / BUTTON_LINE

MENU_CHARANUM = 0

FOR LOCAL:0, 0, CHARANUM
	RESULT = 0
	TRYCALLFORM SHOP_LIFE_CHECKCHARA{FLAG:拠点フェイズ選択コマンド}(LOCAL:0)
	IF RESULT
		MENU_CHARANUM ++
	ENDIF
NEXT

SHOP_LIFE_LIST1_PAGE_MAX = MAX((MENU_CHARANUM - 1) / MAX_BUTTON + 1, 1)

FLAG:拠点フェイズページ = (SHOP_LIFE_LIST1_PAGE_MAX - 1 + FLAG:拠点フェイズページ % SHOP_LIFE_LIST1_PAGE_MAX) % SHOP_LIFE_LIST1_PAGE_MAX + 1

NOW_BUTTON = 0
NOW_BUTTON_PAGE = 0
NOW_PAGE_BUTTON_START = (FLAG:拠点フェイズページ - 1) * MAX_BUTTON
NOW_PAGE_BUTTON_END = FLAG:拠点フェイズページ * MAX_BUTTON

FOR LOCAL:0, 0, CHARANUM
	NOW_CHECK_CHARA = SHOP_CHARA_LIST:(LOCAL:0)
	SIF NOW_CHECK_CHARA == -1
		CONTINUE
	RESULT = 0
	TRYCALLFORM SHOP_LIFE_CHECKCHARA{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA)
	PRINTOPTION = RESULT
	IF RESULT
		IF NOW_BUTTON >= NOW_PAGE_BUTTON_START && NOW_BUTTON < NOW_PAGE_BUTTON_END
			IF NOW_BUTTON_PAGE % LINE_NUM_BUTTON != 0
				PRINTPLAIN
			ELSE
				IF NOW_BUTTON_PAGE >= 1
					CALL COLUMN_RIGHT_PRINTL
				ENDIF
			ENDIF
			TRYCCALLFORM SHOP_LIFE_LIST1_BUTTON{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA, PRINTOPTION)
			CATCH
				CALL COLUMN_RIGHT_CHARALIST_BUTTON(NOW_CHECK_CHARA, 0, SHOP_LIFE_LIST1_ADD_INPUT, PRINTOPTION)
			ENDCATCH
			NOW_BUTTON_PAGE ++
		ENDIF
		NOW_BUTTON ++
	ENDIF
NEXT

FOR LOCAL:0, LINECOUNT - FIRST_COLUMN_RIGHT_LINE, LINES_SHOP_DRAW / 2 - 1
	CALL COLUMN_RIGHT_PRINTL
	IF LOCAL:0 == LINES_SHOP_DRAW / 2 - 3
		CALL COLUMN_RIGHT_LINE
	ELSEIF LOCAL:0 == LINES_SHOP_DRAW / 2 - 2
		IF SHOP_LIFE_LIST1_PAGE_MAX >= 2
			PRINTBUTTON @"[%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST1_PAGE_BACK
		ELSE
			SETCOLOR カラー_選択不可
			PRINTPLAINFORM [%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]
			RESETCOLOR
		ENDIF
		PRINTPLAINFORM %TOSTR_SPACE(10)%
		LOCALS:0 = page{FLAG:拠点フェイズページ}/{SHOP_LIFE_LIST1_PAGE_MAX}
		PRINTPLAINFORM %LOCALS:0, 16, LEFT%
		IF SHOP_LIFE_LIST1_PAGE_MAX >= 2
			PRINTBUTTON @"[%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST1_PAGE_NEXT
		ELSE
			SETCOLOR カラー_選択不可
			PRINTPLAINFORM [%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]
			RESETCOLOR
		ENDIF
	ENDIF
NEXT
RETURN 0

;-------------------------------------------------
;右カラムの上下２段のキャラリスト下
;-------------------------------------------------
@COLUMN_RIGHT_CHARALIST_BOTTOM(LINE_NUM_BUTTON_BOTTOM = 2, BUTTON_LINE_BOTTOM = 1)
#DIM MAX_BUTTON_BOTTOM
#DIM NOW_BUTTON_BOTTOM
#DIM NOW_BUTTON_PAGE_BOTTOM
#DIM MENU_CHARANUM_BOTTOM
#DIM NOW_CHECK_CHARA_BOTTOM
#DIM NOW_PAGE_BUTTON_START_BOTTOM
#DIM NOW_PAGE_BUTTON_END_BOTTOM
#DIM LINE_NUM_BUTTON_BOTTOM
#DIM BUTTON_LINE_BOTTOM
#DIM PRINTOPTION_BOTTOM

MAX_BUTTON_BOTTOM = ((LINES_SHOP_DRAW- 2 - (LINECOUNT - FIRST_COLUMN_RIGHT_LINE)) * LINE_NUM_BUTTON_BOTTOM) / BUTTON_LINE_BOTTOM
SHOP_LIFE_LIST2_PAGE_MAX = 0
FOR LOCAL:0, 0, CHARANUM
	TRYCALLFORM SHOP_LIFE_CHECKCHARA_SUB{FLAG:拠点フェイズ選択コマンド}(LOCAL:0)
	IF RESULT
		SHOP_LIFE_LIST2_PAGE_MAX ++
	ENDIF
NEXT
SHOP_LIFE_LIST2_PAGE_MAX = MAX((SHOP_LIFE_LIST2_PAGE_MAX - 1) / MAX_BUTTON_BOTTOM + 1, 1)

FLAG:拠点フェイズページ2 = (SHOP_LIFE_LIST2_PAGE_MAX - 1 + FLAG:拠点フェイズページ2 % SHOP_LIFE_LIST2_PAGE_MAX) % SHOP_LIFE_LIST2_PAGE_MAX + 1

;キャラリストの表示
NOW_BUTTON_BOTTOM = 0
NOW_BUTTON_PAGE_BOTTOM = 0
NOW_PAGE_BUTTON_START_BOTTOM = (FLAG:拠点フェイズページ2 - 1) * MAX_BUTTON_BOTTOM
NOW_PAGE_BUTTON_END_BOTTOM = FLAG:拠点フェイズページ2 * MAX_BUTTON_BOTTOM
FOR LOCAL:0, 0, CHARANUM
	NOW_CHECK_CHARA_BOTTOM = SHOP_CHARA_LIST:(LOCAL:0)
	SIF NOW_CHECK_CHARA_BOTTOM == -1
		CONTINUE
	;選択可能な条件を満たしているかどうかを判定
	RESULT = 0
	TRYCALLFORM SHOP_LIFE_CHECKCHARA_SUB{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA_BOTTOM)
	PRINTOPTION_BOTTOM = RESULT
	IF RESULT
		IF NOW_BUTTON_BOTTOM >= NOW_PAGE_BUTTON_START_BOTTOM && NOW_BUTTON_BOTTOM < NOW_PAGE_BUTTON_END_BOTTOM
			IF NOW_BUTTON_PAGE_BOTTOM % LINE_NUM_BUTTON_BOTTOM != 0
				PRINTPLAIN
			ELSE
				IF NOW_BUTTON_PAGE_BOTTOM >= 1
					CALL COLUMN_RIGHT_PRINTL
				ENDIF
			ENDIF
			TRYCCALLFORM SHOP_LIFE_LIST2_BUTTON{FLAG:拠点フェイズ選択コマンド}(NOW_CHECK_CHARA_BOTTOM, PRINTOPTION_BOTTOM)
			CATCH
				CALL COLUMN_RIGHT_CHARALIST_BUTTON(NOW_CHECK_CHARA_BOTTOM, 0, SHOP_LIFE_LIST2_ADD_INPUT, PRINTOPTION_BOTTOM)
			ENDCATCH
			NOW_BUTTON_PAGE_BOTTOM ++
		ENDIF
		NOW_BUTTON_BOTTOM ++
	ENDIF
NEXT

FOR LOCAL:0, (LINECOUNT - FIRST_COLUMN_RIGHT_LINE), LINES_SHOP_DRAW - 1
	CALL COLUMN_RIGHT_PRINTL
	IF LOCAL:0 == LINES_SHOP_DRAW - 3
		CALL COLUMN_RIGHT_LINE
	ELSEIF LOCAL:0 == LINES_SHOP_DRAW - 2
		IF SHOP_LIFE_LIST2_PAGE_MAX >= 2
			PRINTBUTTON @"[%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST2_PAGE_BACK
		ELSE
			SETCOLOR カラー_選択不可
			PRINTPLAINFORM [%"前のページ", MAX_CHARANAME_LENGTH, LEFT%]
			RESETCOLOR
		ENDIF
		PRINTPLAINFORM %TOSTR_SPACE(10)%
		LOCALS:0 = page{FLAG:拠点フェイズページ2}/{SHOP_LIFE_LIST2_PAGE_MAX}
		PRINTPLAINFORM %LOCALS:0, 16, LEFT%
		IF SHOP_LIFE_LIST2_PAGE_MAX >= 2
			PRINTBUTTON @"[%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]", SHOP_LIFE_LIST2_PAGE_NEXT
		ELSE
			SETCOLOR カラー_選択不可
			PRINTPLAINFORM [%"次のページ", MAX_CHARANAME_LENGTH, LEFT%]
			RESETCOLOR
		ENDIF
	ENDIF
NEXT

PRINTL

RETURN 0


code:
@SELECT_CHARA_RANDOM_LOGIC_REV_TRAINER(対象)
#DIM 対象
;メイン調教者はこの前段階で含まれてるのでパス
SIF GET_ID(対象) == FLAG:逆調教メイン調教者
	RETURN 0
SIF CFLAG:(対象):所属 != CFLAG:MASTER:捕虜先 || CFLAG:(対象):捕虜先 || CFLAG:(対象):特殊状態
	RETURN 0
SIF !CFLAG:(対象):面識 && RAND:3
	RETURN 0
SIF ABL:(対象):性知識 < 2
	RETURN 0
SIF CONFIG:17 && !CFLAG:(対象):面識
	RETURN 0
RETURN 1

@SELECT_CHARA_RANDOM_BIAS_REV_TRAINER(対象)
#DIM 対象
RETURN MAX(CFLAG:対象:好感度, CFLAG:対象:依存度, CFLAG:対象:従属度, CFLAG:対象:支配度)

;-------------------------------------------------
;逆調教の参加者決定
;-------------------------------------------------
@SELECT_REV_TRAINER()
#DIM LCOUNT
#DIM メイン
VARSET メイン, -1

CALL SELECT_CHARA_RANDOM_MULTI(5, "REV_TRAINER", "REV_TRAINER")

SIF SELECTED_CHARA_NUM == 0
	RETURN -1, 0

FOR LOCAL, 0, SELECTED_CHARA_NUM
	LOCAL:1 = SELECTED_CHARA:LOCAL
	CFLAG:(LOCAL:1):調教参加フラグ = 1
	CFLAG:(LOCAL:1):強制友好化 = 1
	SIF LOCAL == 0
		メイン = LOCAL:1
NEXT

RETURN メイン, SELECTED_CHARA_NUM

repo_name: napo/erafl

license: unknown


code:
;LIFE部分に使用する変数を定義(全般的に使用する変数は VARIABLE.ERH へ)
;
;-------------------------------------------------
;カラム全般
;-------------------------------------------------
;左右カラムの表示開始時の行番号
#DIM FIRST_COLUMN_RIGHT_LINE

;FLAG:拠点フェイズ選択コマンドが選択不可のとき指定するデフォルトのメニュー番号
#DIM CONST DEFAULT_MENU_NUM = 11

;メニューに使用する番号の開始値と終了値の定数
;開始値（10以下は右カラムのボタン用）
#DIM CONST COLUMN_LEFT_MENU_START_VALUE = 11
;終了値（90以上は設定用）
#DIM CONST COLUMN_LEFT_MENU_END_VALUE = 89

;最新の右カラム（の左メニュー番号）を保存する
#DIM SAVEDATA COLUMN_RIGHT_MENU_SAVE_NUM = 11

;-------------------------------------------------
;左カラムメニュー関連
;-------------------------------------------------
;左カラムメニューのカテゴリ名称を保存する配列
#DIMS COLUMN_LEFT_CATEGORY_NAME, 10

;左カラムの表示項目と並び順を保存する（配列番号=行番号/現在の最大行数は37）
;並び順カテゴリ番号
#DIM COLUMN_LEFT_CATEGORY_NUM, 40
;並び順メニュー番号
#DIM COLUMN_LEFT_MENU_NUM, 40

;-------------------------------------------------
;右カラムコンテンツ関連
;-------------------------------------------------
;右カラムキャラリストのボタン番号への追加値定数
;　キャラリスト１ではボタン番号の追加値100
;　キャラリスト２ではボタン番号の追加値1100
;　入力値からこの追加値を引いてキャラ番号に変換する
;　という処理が多用されているため
;　この100/1100を見た目にわかりやすくするための定数
#DIM CONST SHOP_LIFE_LIST1_ADD_INPUT = 100
#DIM CONST SHOP_LIFE_LIST2_ADD_INPUT = 1100

;キャラリストページ移動ボタンに割り振る番号
#DIM CONST SHOP_LIFE_LIST1_PAGE_BACK = 98
#DIM CONST SHOP_LIFE_LIST1_PAGE_NEXT = 99
#DIM CONST SHOP_LIFE_LIST2_PAGE_BACK = 96
#DIM CONST SHOP_LIFE_LIST2_PAGE_NEXT = 97

;キャラリストの最大ページ数
;主にリスト関数で計算されるので関数内宣言で良いが
;リスト関数の使えない特殊なリストを作成する場合に共有できるようここに配置
#DIM SHOP_LIFE_LIST1_PAGE_MAX = 1
#DIM SHOP_LIFE_LIST2_PAGE_MAX = 1

;右カラムの各メニューで使用しメニューを移るとリセットされる汎用変数
#DIM MENUVAR, 100

;右カラムのタレント選択用フィルタ
#DIM TALENT_FILTER, 300

;右カラムの種族タグ選択用フィルタ
#DIM TAG_FILTER, MAX_TAGNUM

;右カラムの職業選択用
#DIM 職業候補


code: ;使用中のボタン番号を忘れないようにするためのダミーファイル


code:
;-------------------------------------------------
;戦略メニューの選択可否とメニューの選択可能キャラ存在判定を
;SHOP_AVAILに保存する
;-------------------------------------------------
@CHECK_SAVE_SLG
#DIM CHECK_SAVE_COUNTER_SLG

VARSET SHOP_AVAIL, 0

FOR CHECK_SAVE_COUNTER_SLG, 0, 99
	IF CHECK_SAVE_COUNTER_SLG <= 10 || CHECK_SAVE_COUNTER_SLG >= 90
		SHOP_AVAIL:(CHECK_SAVE_COUNTER_SLG) = 1
	ELSE
		RESULTS:0 '= ""
		TRYCALLFORM SHOP_SLG_NAME{CHECK_SAVE_COUNTER_SLG}
		;メニュー名称が存在するなら
		IF RESULTS:0 != ""
			;メニューの選択可否判定
			RESULT = 0
			TRYCCALLFORM SHOP_SLG_CHECK{CHECK_SAVE_COUNTER_SLG}
				;選択可否判定が存在し、可の場合
				IF RESULT
					SHOP_AVAIL:(CHECK_SAVE_COUNTER_SLG) = 1
				ENDIF
			CATCH
			ENDCATCH
		ENDIF
	ENDIF
NEXT


code:
;-------------------------------------------------
;左カラムカテゴリ名称設定
;-------------------------------------------------
@COLUMN_LEFT_CATEGORY_NAME_SLG
COLUMN_LEFT_CATEGORY_NAME_SLG:1 '= "自動"
COLUMN_LEFT_CATEGORY_NAME_SLG:2 '= "政策"
COLUMN_LEFT_CATEGORY_NAME_SLG:3 '= "戦略"
COLUMN_LEFT_CATEGORY_NAME_SLG:4 '= "交渉"
COLUMN_LEFT_CATEGORY_NAME_SLG:5 '= "情報"
COLUMN_LEFT_CATEGORY_NAME_SLG:6 '= "人材"
COLUMN_LEFT_CATEGORY_NAME_SLG:7 '= "特殊"
COLUMN_LEFT_CATEGORY_NAME_SLG:8 '= "進行"
COLUMN_LEFT_CATEGORY_NAME_SLG:9 '= "設定"

;-------------------------------------------------
;左カラムメニューボタン
;-------------------------------------------------
@COLUMN_LEFT_PRINTBUTTON_SLG(ARG:0, ARGS:0, ARG:1 = 0)
#DIM EXTERNAL_LINK

SIF ARG:0 < 0 || 99 < ARG:0
	THROW COLUMN_LEFT_PRINTBUTTONの項番が0～99の範囲にありません

;空指定なら同幅のスペース
IF ARGS:0 == ""
	PRINTPLAINFORM %TOSTR_SPACE(12)%
;選択不可（表示が制限されていない場合）
ELSEIF !SHOP_AVAIL:(ARG:0)
	SETCOLOR カラー_選択不可
	PRINTPLAINFORM [%ARGS:0, 10%]
	RESETCOLOR
;現在選択中
ELSEIF ARG:1
	SETCOLOR カラー_選択中
	PRINTBUTTON @"[%ARGS:0, 10%]", ARG:0
	RESETCOLOR
;通常のボタン
ELSE
	PRINTBUTTON @"[%ARGS:0, 10%]", ARG:0
ENDIF

;-------------------------------------------------
;左カラムの配列：行番号にカテゴリとメニューを保存
;-------------------------------------------------
@COLUMN_LEFT_MENULINE_SAVE_SLG
#DIM COLUMN_LEFT_CATEGORY_SAVEFLAG_SLG, 10

VARSET COLUMN_LEFT_CATEGORY_SAVEFLAG_SLG, 0
VARSET COLUMN_LEFT_CATEGORY_NUM_SLG, 0
VARSET COLUMN_LEFT_MENU_NUM_SLG, 0

CALL COLUMN_LEFT_CATEGORY_NAME_SLG

LOCAL:0 = 1
LOCAL:4 = 0
FOR LOCAL:1, 1, 8
	IF COLUMN_LEFT_CATEGORY_NAME_SLG:(LOCAL:1) != ""
		FOR LOCAL:2, 1, 10
			LOCAL:3 = LOCAL:1 * 10 + LOCAL:2
			RESULTS:0 '= ""
			TRYCALLFORM SHOP_SLG_NAME{LOCAL:3}
			IF RESULTS:0 != "" && SHOP_AVAIL:(LOCAL:3)
				IF COLUMN_LEFT_CATEGORY_SAVEFLAG_SLG:(LOCAL:1) != 1
					IF LOCAL:4 == 1
						LOCAL:0 ++
					ENDIF
					LOCAL:4 = 1
					COLUMN_LEFT_CATEGORY_NUM_SLG:(LOCAL:0) = LOCAL:1
					COLUMN_LEFT_CATEGORY_SAVEFLAG_SLG:(LOCAL:1) = 1
				ENDIF
				COLUMN_LEFT_MENU_NUM_SLG:(LOCAL:0) = LOCAL:3
				;このメニューに追加説明文があれば空行を追加する
				TRYCCALLFORM SHOP_SLG_NEXT_LINE_ADD{COLUMN_LEFT_MENU_NUM_SLG:(LOCAL:0)}
					LOCAL:0 ++
				CATCH
				ENDCATCH
				LOCAL:0 ++
			ENDIF
		NEXT
	ENDIF
NEXT

;-------------------------------------------------
;左カラムメニュー表示ボタン呼び出し ARG:0は行数
;-------------------------------------------------
@COLUMN_LEFT_MENU_SHOW_SLG(ARG:0)
#DIM SHOP_SLG_NEXT_LINE_ADD_FLAG = 0
#DIM SHOP_SLG_NAME_COLOR = 0
;固定行
SELECTCASE ARG:0
	;固定・案内
	CASE 0
		SETCOLOR カラー_注釈
		IF FLAG:観戦モード
			CALL COLOR_PRINT(" 観戦中           ", 0xB0BA90)
		ELSEIF CFLAG:MASTER:所属 == 0
			CALL COLOR_PRINT(" 放浪中           ", 0xB0BA90)
		ELSE
			CALL COLOR_PRINT(" 委任時は自動     ", 0xB0BA90)
		ENDIF
		RESETCOLOR
	;固定・開戦
	CASE 34
		CALL COLUMN_LEFT_CATEGORY_NAME_SHOW(COLUMN_LEFT_CATEGORY_NAME_SLG:8)
		TRYCALLFORM SHOP_SLG_NAME81
		CALL COLUMN_LEFT_PRINTBUTTON_SLG( 81, RESULTS:0)
	;固定・設定
	CASE 36
		CALL COLUMN_LEFT_CATEGORY_NAME_SHOW(COLUMN_LEFT_CATEGORY_NAME_SLG:9)
		CALL COLUMN_LEFT_PRINTBUTTON_SLG( 91, "設定")
	;固定・セーブ
	CASE 37
		CALL COLUMN_LEFT_CATEGORY_NAME_SHOW("")
		CALL COLUMN_LEFT_PRINTBUTTON_SLG( 92, "セーブ")
	;固定・ロード
	CASE 38
		CALL COLUMN_LEFT_CATEGORY_NAME_SHOW("")
		CALL COLUMN_LEFT_PRINTBUTTON_SLG( 93, "ロード")
	;可変・他カテゴリ名とメニューボタン
	CASEELSE
		;カテゴリ
		IF COLUMN_LEFT_CATEGORY_NUM_SLG:(ARG:0) != 0
			CALL COLUMN_LEFT_CATEGORY_NAME_SHOW(COLUMN_LEFT_CATEGORY_NAME_SLG:(COLUMN_LEFT_CATEGORY_NUM_SLG:(ARG:0)))
		ELSE
			CALL COLUMN_LEFT_CATEGORY_NAME_SHOW("")
		ENDIF
		;ひとつ前の行のメニューに追加説明文があるかチェック
		TRYCCALLFORM SHOP_SLG_NEXT_LINE_ADD{COLUMN_LEFT_MENU_NUM_SLG:(ARG:0 - 1)}
			SHOP_SLG_NEXT_LINE_ADD_FLAG = 1
		CATCH
			SHOP_SLG_NEXT_LINE_ADD_FLAG = 0
		ENDCATCH
		;右カラムに表示のあるメニューの場合
		TRYCCALLFORM SHOP_SLG_EVENTBUY_COLUMN_RIGHT_ON_CHECK{COLUMN_LEFT_MENU_NUM_SLG:(ARG:0)}
			SHOP_SLG_NAME_COLOR = 1
		CATCH
			SHOP_SLG_NAME_COLOR = 0
		ENDCATCH
		;ボタンカラー指定があれば読み込み、右カラムに表示があってもボタンをオンカラーにしない
		TRYCCALLFORM SHOP_SLG_NAME_COLOR{COLUMN_LEFT_MENU_NUM_SLG:(ARG:0)}
			SHOP_SLG_NAME_COLOR = 0
		CATCH
		ENDCATCH
		;メニューボタンがあれば表示
		IF COLUMN_LEFT_MENU_NUM_SLG:(ARG:0) != 0
			TRYCALLFORM SHOP_SLG_NAME{COLUMN_LEFT_MENU_NUM_SLG:(ARG:0)}
			CALL COLUMN_LEFT_PRINTBUTTON_SLG( COLUMN_LEFT_MENU_NUM_SLG:(ARG:0), RESULTS:0, SHOP_SLG_NAME_COLOR && FLAG:戦略フェイズ選択コマンド == COLUMN_LEFT_MENU_NUM_SLG:(ARG:0))
		;メニューボタンがなく、ひとつ前の行のメニューに追加説明文がある場合は表示
		ELSEIF SHOP_SLG_NEXT_LINE_ADD_FLAG == 1
			TRYCALLFORM SHOP_SLG_NEXT_LINE_ADD_TEXT{COLUMN_LEFT_MENU_NUM_SLG:(ARG:0 - 1)}
		;メニューボタンがなく、ひとつ前の行のメニューに追加説明文がなければ空行
		ELSE
			CALL COLUMN_LEFT_PRINTBUTTON_SLG( 0, "")
		ENDIF
ENDSELECT

RESETCOLOR
PRINT


code:
@FIND_GENERAL_SKILL(発動者, スキル名)
#DIM 発動者
#DIMS スキル名
#DIM ジャンル
#DIM スキルID
FOR LOCAL, 0, VARSIZE("SKILL_GENRE")
	FOR LOCAL:1, 0, MAX_SKILLS
		TRYCCALLFORM SKILL_0_%SKILL_GENRE_ENG:LOCAL%_{LOCAL:1}_NAME()
			IF RESULTS == スキル名
				ジャンル = LOCAL
				スキルID = LOCAL:1
				GOTO FOUND
			ENDIF
		CATCH
			CONTINUE
		ENDCATCH
	NEXT
NEXT

RETURN 0

$FOUND

FOR LOCAL, 0, MAX_SKILL_SLOT
	IF SKILL_NO_SLOT:発動者:ジャンル:LOCAL == 0 && SKILL_ID_SLOT:発動者:ジャンル:LOCAL == スキルID
		RETURN 1
	ENDIF
NEXT

RETURN 0

;---------------------------------
;SP, BASE, CAPTURE, ESCAPEスキル発動用
;---------------------------------
@SKILL_COMBAT_INVOKE(発動者, 発動番号, ジャンル, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
#DIM 発動者
#DIM 発動番号
#DIM ジャンル
#DIM 発動側
#DIM 発動勢力
#DIM 発動部隊
#DIM 対象勢力
#DIM 対象部隊

SIF BATTLE_SKILL_SEALED:発動側:発動番号 || BATTLE_SUMMONED_CHARA:発動側:発動番号
	RETURN 0

FOR LOCAL, 0, MAX_SKILL_SLOT
	SIF SKILL_NO_SLOT:発動者:ジャンル:LOCAL < 0
		CONTINUE
	SIF SKILL_ID_SLOT:発動者:ジャンル:LOCAL < 0
		CONTINUE
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, ジャンル, SKILL_NO_SLOT:発動者:ジャンル:LOCAL, SKILL_ID_SLOT:発動者:ジャンル:LOCAL, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
NEXT

;---------------------------------
;SP, BASE, CAPTURE, ESCAPEスキル発動用 CAPTUREでは発動側が捕縛側、ESCAPEでは発動側が逃走側
;---------------------------------
@SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, ジャンル, スキルNO, スキルID, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
#DIM 発動者
#DIM 発動番号
#DIM ジャンル
#DIM スキルNO
#DIM スキルID
#DIM 発動側
#DIM 発動勢力
#DIM 発動部隊
#DIM 対象勢力
#DIM 対象部隊

SIF BATTLE_SKILL_SEALED:発動側:発動番号
	RETURN -1

;存在判定
TRYCCALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_EXIST
CATCH
	RETURN -1
ENDCATCH
;対象選択
TRYCCALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_SETTARGET(発動者, 発動番号, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
	IF !RESULT
		RESETCOLOR
		RETURN 0
	ENDIF
CATCH
ENDCATCH
;発動率判定
CALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_RATE(発動者, 発動番号, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)

;技術研究の成果
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 1
	RESULT += 50
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 7
	RESULT += 100

IF RAND:1000 >= RESULT * BATTLE_SKILL_RATE:発動側:発動番号 / 100
	RESETCOLOR
	RETURN 0
ENDIF
;発動判定
CALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_CAN_INVOKE(発動者, 発動番号, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
IF !RESULT
	RESETCOLOR
	RETURN 0
ENDIF
;TRYCCALLFORM SKILL_{発動者}_%ジャンル%_{スキル}_INVOKE_TEXT(発動者)
;	CATCH
CALLFORM SKILL_PRINT_INVOKE(発動者, ジャンル, スキルNO, スキルID)
;ENDCATCH
CALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_INVOKE(発動者, 発動番号, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
RETURN RESULT

;---------------------------------
;国家方針・研究スキル
;---------------------------------
@TECHNOLOGY_PERSONAL_SKILL_COMBAT_INVOKE(発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
#DIM 発動者
#DIM 発動番号
#DIM ジャンル
#DIM 発動側
#DIM 発動勢力
#DIM 発動部隊
#DIM 対象勢力
#DIM 対象部隊
#DIM 都市

SIF BATTLE_COMMANDER_NUM:発動側 == 0
	RETURN 0

SIF BATTLE_SKILL_SEALED:発動側:発動番号 || BATTLE_SUMMONED_CHARA:発動側:発動番号
	RETURN 0

発動者 = BATTLE_COMMANDER:(発動側):0
発動番号 = 0
;国人衆参戦
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 2
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, スキル_ジャンル_PERSONAL, 0, 40, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)

@TECHNOLOGY_TROOP_SKILL_COMBAT_INVOKE(発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
#DIM 発動者
#DIM 発動番号
#DIM ジャンル
#DIM 発動側
#DIM 発動勢力
#DIM 発動部隊
#DIM 対象勢力
#DIM 対象部隊
#DIM 都市

SIF BATTLE_COMMANDER_NUM:発動側 == 0
	RETURN 0

SIF BATTLE_SKILL_SEALED:発動側:発動番号 || BATTLE_SUMMONED_CHARA:発動側:発動番号
	RETURN 0

発動者 = BATTLE_COMMANDER:(発動側):0
発動番号 = 0
;弾幕強化
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 3
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, スキル_ジャンル_TROOP, 0, 34, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 4
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, スキル_ジャンル_TROOP, 0, 35, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 5
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, スキル_ジャンル_TROOP, 0, 36, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)
SIF TECHNOLOGY_STATUS:(CFLAG:発動者:所属):TECHNOLOGY_BATTLE_SKILL >= 6
	CALL SKILL_COMBAT_TRY_INVOKE(発動者, 発動番号, スキル_ジャンル_TROOP, 0, 37, 発動側, 発動勢力, 発動部隊, 対象勢力, 対象部隊)

;---------------------------------
;スキル発動時のデフォルト地の文
;---------------------------------
@SKILL_PRINT_INVOKE(発動者, ジャンル, スキルNO, スキルID)
#DIM 発動者
#DIM スキルNO
#DIM スキルID
#DIM ジャンル
CALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_NAME
PRINTFORML %ANAME(発動者)%のスキル「%RESULTS%」発動！

;---------------------------------
;暗殺の効果用
;---------------------------------
@COMBAT_ASSASINATE(対象側, 対象番号)
#DIM 対象側
#DIM 対象番号
BATTLE_身体:対象側:対象番号 = 0
BATTLE_器用:対象側:対象番号 = 0
BATTLE_知識:対象側:対象番号 = 0
BATTLE_社交:対象側:対象番号 = 0
BATTLE_魔術:対象側:対象番号 = 0
BATTLE_料理:対象側:対象番号 = 0
BATTLE_歌唱:対象側:対象番号 = 0
BATTLE_身体パワー:対象側:対象番号 = 0
BATTLE_器用パワー:対象側:対象番号 = 0
BATTLE_知識パワー:対象側:対象番号 = 0
BATTLE_魔術パワー:対象側:対象番号 = 0
BATTLE_歌唱パワー:対象側:対象番号 = 0
BATTLE_料理パワー:対象側:対象番号 = 0
BATTLE_SKILL_RATE:対象側:対象番号 = 0
BATTLE_SKILL_SEALED:対象側:対象番号 = 1

;---------------------------------
;召喚系スキル
;---------------------------------
@BATTLE_SUMMON(発動側, 対象, 部隊フラグ)
#DIM 発動側
#DIM 対象
#DIM 部隊フラグ

FOR LOCAL:0, 0, VARSIZE("BATTLE_COMMANDER", 1)
	SIF BATTLE_COMMANDER:発動側:LOCAL >= 0
		CONTINUE
	SIF 部隊フラグ == 0 && BATTLE_COMMANDER_NUM:発動側 >= MAX_CITY_COMMANDER
		BREAK
	BATTLE_COMMANDER:発動側:LOCAL = 対象
	BATTLE_身体:発動側:LOCAL = ABL:対象:身体
	BATTLE_器用:発動側:LOCAL = ABL:対象:器用
	BATTLE_知識:発動側:LOCAL = ABL:対象:知識
	BATTLE_社交:発動側:LOCAL = ABL:対象:社交
	BATTLE_歌唱:発動側:LOCAL = ABL:対象:歌唱
	BATTLE_料理:発動側:LOCAL = ABL:対象:料理
	BATTLE_魔術:発動側:LOCAL = ABL:対象:魔術
	BATTLE_身体パワー:発動側:LOCAL = ABL_POWER(BATTLE_身体:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_器用パワー:発動側:LOCAL = ABL_POWER(BATTLE_器用:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_知識パワー:発動側:LOCAL = ABL_POWER(BATTLE_知識:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_魔術パワー:発動側:LOCAL = ABL_POWER(BATTLE_魔術:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_歌唱パワー:発動側:LOCAL = ABL_POWER(BATTLE_歌唱:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_料理パワー:発動側:LOCAL = ABL_POWER(BATTLE_料理:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_魔術パワー:発動側:LOCAL = ABL_POWER(BATTLE_魔術:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_SKILL_RATE:発動側:LOCAL = 0
	BATTLE_SUMMONED_CHARA:発動側:LOCAL = 1
	BATTLE_COMMANDER_NUM:発動側 ++
	RETURN 1
NEXT
RETURN 0

;---------------------------------
;モブ召喚系スキル
;---------------------------------
@BATTLE_ADD_MOB(発動側, 部隊フラグ, 名前, 身体値, 器用値, 知識値,  社交値, 魔術値, 料理値, 歌唱値)
#DIM 発動側
#DIM 部隊フラグ
#DIM 対象
#DIMS 名前
#DIM 身体値
#DIM 器用値
#DIM 知識値
#DIM 社交値
#DIM 魔術値
#DIM 料理値
#DIM 歌唱値

CALL ADD_VOID_CHARA()
対象 = RESULT
NAME:対象 = %名前%
CALLNAME:対象 = %名前%
TALENT:対象:戦闘モブ = 1
ABL:対象:身体 = 身体値
ABL:対象:器用 = 器用値
ABL:対象:知識 = 知識値
ABL:対象:社交 = 社交値
ABL:対象:魔術 = 魔術値
ABL:対象:料理 = 料理値
ABL:対象:歌唱 = 歌唱値
FOR LOCAL, 0, VARSIZE("BATTLE_COMMANDER", 1)
	SIF BATTLE_COMMANDER:発動側:LOCAL >= 0
		CONTINUE
	SIF 部隊フラグ == 0 && BATTLE_COMMANDER_NUM:発動側 >= MAX_CITY_COMMANDER
		BREAK
	BATTLE_COMMANDER:発動側:LOCAL = 対象
	BATTLE_身体:発動側:LOCAL = ABL:対象:身体
	BATTLE_器用:発動側:LOCAL = ABL:対象:器用
	BATTLE_知識:発動側:LOCAL = ABL:対象:知識
	BATTLE_社交:発動側:LOCAL = ABL:対象:社交
	BATTLE_歌唱:発動側:LOCAL = ABL:対象:歌唱
	BATTLE_料理:発動側:LOCAL = ABL:対象:料理
	BATTLE_魔術:発動側:LOCAL = ABL:対象:魔術
	BATTLE_身体パワー:発動側:LOCAL = ABL_POWER(BATTLE_身体:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_器用パワー:発動側:LOCAL = ABL_POWER(BATTLE_器用:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_知識パワー:発動側:LOCAL = ABL_POWER(BATTLE_知識:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_魔術パワー:発動側:LOCAL = ABL_POWER(BATTLE_魔術:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_歌唱パワー:発動側:LOCAL = ABL_POWER(BATTLE_歌唱:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_料理パワー:発動側:LOCAL = ABL_POWER(BATTLE_料理:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_魔術パワー:発動側:LOCAL = ABL_POWER(BATTLE_魔術:発動側:LOCAL, BATTLE_COMMANDER:発動側:LOCAL)
	BATTLE_SKILL_RATE:発動側:LOCAL = 0
	BATTLE_SUMMONED_CHARA:発動側:LOCAL = 1
	BATTLE_COMMANDER_NUM:発動側 ++
	RETURN 対象
NEXT
RETURN -1

;---------------------------------
;スキル発動時のデフォルト地の文
;---------------------------------
@SKILL_INIT(対象)
#DIM 対象
#DIM ジャンル
#DIM 対象NO
#DIM スキルID

FOR LOCAL , 0, SKILL_MAJOR_GENRE_NUM
	BASE_SKILL_POINT:対象:LOCAL = 初期SP
	_DIC_SKILL_LIST:対象:LOCAL '= ""
NEXT

FOR ジャンル, 0, SKILL_GENRE_NUM
	FOR スキルID, 0, MAX_SKILL_SLOT
		SKILL_NO_SLOT:対象:ジャンル:スキルID = -1
		SKILL_ID_SLOT:対象:ジャンル:スキルID = -1
	NEXT
NEXT

対象NO = NO:対象
TRYCALLFORM SKILL_INIT_{対象NO}_GENERAL(対象)

;ジャンルごとで習得させていく
FOR ジャンル, 0, SKILL_GENRE_NUM
	FOR スキルID, 0, MAX_SKILL_SLOT
		;0番は汎用にするので、「あなた」には何も学ばせない
		SIF 対象NO == 0
			GOTO CANCEL
		TRYCCALLFORM SKILL_{対象NO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_EXIST
			;初期状態で習得不可のスキルは弾く
			TRYCCALLFORM SKILL_{対象NO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_NO_LEARN_INIT
				GOTO CANCEL
			CATCH
				CALL SKILL_LEARN(対象, ジャンル, 対象NO, スキルID)
			ENDCATCH
		CATCH
			$CANCEL
		ENDCATCH
	NEXT
NEXT

;---------------------------------
;スキルの説明
;---------------------------------
@SKILL_EXPLANATION(ジャンル, スキルNO, スキルID, スペース)
#DIM ジャンル
#DIM スキルNO
#DIM スキルID
#DIMS アクセサ
#DIMS キャラ名
#DIMS スキル名
#DIMS レベル
#DIMS 説明
#DIMS 伝達不可
#DIMS 発動率
#DIM スペース
;描画内容を用意
アクセサ = SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_
CALLFORM %アクセサ%NAME
スキル名 = %(STRLENS(RESULTS:0) > 20 ? TOHALF(RESULTS:0) # RESULTS:0)%
IF スキルNO == 0
	キャラ名 = 汎用
ELSEIF スキルNO > 10000
	キャラ名 = 特殊
ELSE
	キャラ名 = %SNAME(NO_TO_CHARA(スキルNO))%
ENDIF
CALLFORM %アクセサ%LEVEL
レベル '= TOSTR(RESULT)

CALLFORM %アクセサ%EXPLANATION
説明 = %RESULTS%

TRYCCALLFORM %アクセサ%RATE_VARABLE
	発動率 '= "可変"
CATCH
	CALLFORM %アクセサ%RATE
	発動率 = %DECIMAL_STRING(RESULT, 1)%
ENDCATCH

TRYCCALLFORM %アクセサ%CANT_TELL
	伝達不可 '= "伝達不可"
CATCH
	伝達不可 '= ""
ENDCATCH

PRINTFORML %スキル名, 35, LEFT%LV%レベル, 3, LEFT% 発動率%発動率, 6, LEFT%%SKILL_GENRE_JP:ジャンル, 6, LEFT%%伝達不可, 10, LEFT%%キャラ名, MAX_CHARANAME_LENGTH/2, LEFT%
PRINTFORML %TOSTR_SPACE(スペース)%%説明%

;---------------------------------
;空きスロットにスキルのセット
;習得できれば1が戻る　空きがなければ0
;---------------------------------
@SKILL_LEARN_BY_NAME(対象, ジャンル, スキルNO, スキル名)
#DIM 対象
#DIM ジャンル
#DIM スキルNO
#DIMS スキル名
#DIM スキルID
#DIM 空きスロット

;いっぱいならだめ
空きスロット = GET_EMPTY_SKILL_SLOT(対象, ジャンル)
SIF 空きスロット == -1
	RETURN 0

FOR スキルID, 0, MAX_SKILLS
	TRYCCALLFORM SKILL_{スキルNO}_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_NAME
		IF RESULTS == スキル名
			CALL SKILL_LEARN(対象, ジャンル, スキルNO, スキルID)
			RETURN RESULT
		ENDIF
	CATCH
	ENDCATCH
NEXT

RETURN 0

;---------------------------------
;空きスロットにスキルのセット
;習得できれば1が戻る　空きがなければ0
;---------------------------------
@SKILL_LEARN(対象, ジャンル, スキルNO, スキルID)
#DIM 対象
#DIM ジャンル
#DIM スキルNO
#DIM スキルID
#DIM 空きスロット

;いっぱいならだめ
空きスロット = GET_EMPTY_SKILL_SLOT(対象, ジャンル)
SIF 空きスロット == -1
	RETURN 0

;重複してたらダメでしょ
SIF CHECK_SKILL_DUPLICATE(対象, ジャンル, スキルNO, スキルID)
	RETURN 0

SKILL_NO_SLOT:対象:ジャンル:空きスロット = スキルNO
SKILL_ID_SLOT:対象:ジャンル:空きスロット = スキルID

RETURN 1

;-------------------------------------------------
;;; FL用スキル習得処理
;;; 引数の内容でセットされるため、習得可能判定はこの関数を呼び出す前に行う
;-------------------------------------------------
@SKILL_LEARN2(CHARA_ID, MAJOR_GENRE, SKILL_DEF_NAME, SKILL_LEVEL)
#DIM CHARA_ID
#DIM MAJOR_GENRE
#DIM SKILL_LEVEL
#DIMS SKILL_DEF_NAME

_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE = %DIC_SET(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE, SKILL_DEF_NAME, TOSTR(SKILL_LEVEL))%

;-------------------------------------------------
;;; スキル忘却処理
;-------------------------------------------------
@SKILL_FORGET(CHARA_ID, MAJOR_GENRE, SKILL_DEF_NAME)
#DIM  CHARA_ID
#DIM  MAJOR_GENRE
#DIMS SKILL_DEF_NAME

;アクティブスキルスロットにセットされている場合は、アクティブスキルスロットから消去
CALL SKILL_EDIT_ACTIVE_SKILL_SLOT(CHARA_ID, SKILL_DEF_NAME, 1)
;キャラクターのスキル習得状況を解除
_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE = %DIC_REMOVE(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE, SKILL_DEF_NAME)%

RETURN 1

;-------------------------------------------------
;;; アクティブスキルスロットの編集処理
;-------------------------------------------------
@SKILL_EDIT_ACTIVE_SKILL_SLOT(CHARA_ID, SKILL_DEF_NAME, FORCE_DELETE = 0)
#DIM  CHARA_ID
#DIMS SKILL_DEF_NAME
#DIM  FORCE_DELETE

IF LIST_INDEXOF(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0, SKILL_DEF_NAME) != -1 || FORCE_DELETE
	_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0 = %LIST_REMOVEALL(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0, SKILL_DEF_NAME)%
ELSE
	IF LIST_COUNT(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0) == 3
		CALLF TAG_PRINT(@"@C:{カラー_注意}@%ANAME(CHARA_ID)%のスキルスロットに空きがありません@/C@", 1)
		RETURN 0
	ENDIF
	_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0 = %LIST_ADD(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0, SKILL_DEF_NAME)%
ENDIF
RETURN 1

;-------------------------------------------------
;@SKILL_GET_LEVEL
;キャラクターのスキルレベルを取得
;-------------------------------------------------
;region @SKILL_GET_LEVEL
@SKILL_GET_LEVEL(CHARA_ID, MAJOR_GENRE, SKILL_DEF_NAME)
#DIM CHARA_ID
#DIM MAJOR_GENRE
#DIMS SKILL_DEF_NAME

RETURN TOINT(DIC_GET(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE, SKILL_DEF_NAME))

;@SKILL_GET_LEVELの式中関数版
@SKILL_GET_LEVELF(CHARA_ID, MAJOR_GENRE, SKILL_DEF_NAME)
#FUNCTION
#DIM CHARA_ID
#DIM MAJOR_GENRE
#DIMS SKILL_DEF_NAME

RETURNF TOINT(DIC_GET(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE, SKILL_DEF_NAME))
;#endregion

;-------------------------------------------------
;;; スキルレベルからレベルに対応する効果量を取得
;;; GENRE は大分類ではなく小分類である点に注意(スキル_ジャンル_戦闘,武器スキル_パッシブ など)
;;;  -> v0.341以降は武器スキルの効果量取得は @WPN_SKILL_GET_EFFECT_RATE 関数を使用する
;-------------------------------------------------
;region @FUNCTION_NAME
@SKILL_GET_EFFECT_RATE(GENRE, SKILL_DEF_NAME, SKILL_LV, IS_WPN_SKILL = 0)
#DIM  GENRE
#DIMS SKILL_DEF_NAME
#DIM  SKILL_LV
#DIM  IS_WPN_SKILL
#DIMS DYNAMIC _XML_SKILL
#DIM  DYNAMIC RATE, 3
VARSET RESULT
VARSET RESULTS
;スキル定義のXML取得
IF !IS_WPN_SKILL
	XML_GET XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ELSE
	XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ENDIF
IF RESULT
	XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
	IF RESULT
		RATE:0 = TOINT(RESULTS)
	ENDIF
	XML_GET _XML_SKILL, @"//rate2/li[{SKILL_LV}]", RESULTS, 1
	IF RESULT
		RATE:1 = TOINT(RESULTS)
	ENDIF
	XML_GET _XML_SKILL, @"//rate3/li[{SKILL_LV}]", RESULTS, 1
	IF RESULT
		RATE:2 = TOINT(RESULTS)
	ENDIF
ENDIF

IF RATE:0 != 0
	RESULT:1 = RATE:1
	RESULT:2 = RATE:2
	RETURN RATE:0
ELSE
	RETURN 0
ENDIF
;#endregion

;-------------------------------------------------
;;; スキル名称を取得
;-------------------------------------------------
@SKILL_GET_NAME(GENRE, SKILL_DEF_NAME, IS_WPN_SKILL = 0)
;region
#DIM  GENRE
#DIMS SKILL_DEF_NAME
#DIM  SKILL_LV
#DIM  IS_WPN_SKILL
#DIMS DYNAMIC _XML_SKILL
VARSET RESULT
VARSET RESULTS
;スキル定義のXML取得
IF !IS_WPN_SKILL
	XML_GET XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ELSE
	XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ENDIF
IF RESULT
	XML_GET _XML_SKILL, @"//skillname", RESULTS, 1
	RETURN 1
ENDIF

;-------------------------------------------------
;;; スキル名称を取得(式中関数版)
;-------------------------------------------------
@SKILL_GET_NAMEF(GENRE, SKILL_DEF_NAME, IS_WPN_SKILL = 0)
#FUNCTIONS
;region
#DIM  GENRE
#DIMS SKILL_DEF_NAME
#DIM  SKILL_LV
#DIM  IS_WPN_SKILL
#DIMS DYNAMIC _XML_SKILL
VARSET RESULTS
;スキル定義のXML取得
IF !IS_WPN_SKILL
	SIF XML_GET(XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3)
		RESULT = XML_GET(_XML_SKILL, @"//skillname", RESULTS, 1)
ELSE
	SIF XML_GET(XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3)
		RESULT = XML_GET(_XML_SKILL, @"//skillname", RESULTS, 1)
ENDIF

RETURNF RESULTS
;#endregion

@SKILL_CHECK_USED_SKILL_POINT(CHARA_ID, MAJOR_GENRE)
#DIM CHARA_ID
#DIM MAJOR_GENRE
#DIM DYNAMIC SKILL_POINT

CALL DIC_KEYS(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE)

FOR LOCAL, 0, RESULT
	SKILL_POINT += TOINT(DIC_GET(_DIC_SKILL_LIST:CHARA_ID:MAJOR_GENRE, RESULTS:LOCAL))
NEXT

RETURN SKILL_POINT

;---------------------------------
;空きスロットの取得　空きがなければ-1
;---------------------------------
@GET_EMPTY_SKILL_SLOT(対象, ジャンル)
#FUNCTION
#DIM 対象
#DIM ジャンル
#DIM 空きスロット
;空きスロットを探す
FOR 空きスロット, 0, MAX_SKILL_SLOT
	IF SKILL_NO_SLOT:対象:ジャンル:空きスロット < 0 && SKILL_ID_SLOT:対象:ジャンル:空きスロット < 0
		空きスロット --
		BREAK
	ENDIF
NEXT

;いっぱいならだめ
SIF 空きスロット == MAX_SKILL_SLOT
	RETURNF -1

RETURNF 空きスロット

;---------------------------------------
;汎用スキル初期化処理用、名前からスキル拾ってきて覚えさせるやつ
;普通にやるぶんにはSKILL_LEARN_BY_NAMEつかえ
;---------------------------------------
@LEARN_SKILL_GENERAL_BY_NAME(対象, 汎用スキル名)
#DIM 対象
#DIMS 汎用スキル名
#DIM ジャンル
#DIM スキルID
#DIM 空きスロット
FOR ジャンル, 0, SKILL_GENRE_NUM
	FOR スキルID, 0, MAX_SKILLS
		TRYCCALLFORM SKILL_0_%SKILL_GENRE_ENG:ジャンル%_{スキルID}_NAME
			SIF RESULTS == 汎用スキル名
				GOTO FOUND
		CATCH
		ENDCATCH
	NEXT
NEXT

SIF ジャンル == SKILL_GENRE_NUM
	THROW %ANAME(対象)%に指定された%汎用スキル名%は存在しない

$FOUND

SIF CHECK_SKILL_DUPLICATE(対象, ジャンル, 0, スキルID)
	RETURN 0

空きスロット = GET_EMPTY_SKILL_SLOT(対象, ジャンル)

SIF 空きスロット == -1
	RETURN 0

CALL SKILL_LEARN(対象, ジャンル, 0, スキルID)

RETURN 1

;---------------------------------------
;指定したスキルをもう覚えているかを調べる
;---------------------------------------
@CHECK_SKILL_DUPLICATE(対象, ジャンル, スキルNO, スキルID)
#FUNCTION
#DIM 対象
#DIM ジャンル
#DIM スキルID
#DIM スキルNO
#DIM スキル

FOR スキル, 0, MAX_SKILL_SLOT
	SIF SKILL_NO_SLOT:対象:ジャンル:スキル == スキルNO && SKILL_ID_SLOT:対象:ジャンル:スキル == スキルID
		RETURNF 1
NEXT

RETURNF 0

;-------------------------------------------------
; スキル定義名からスキル表示名を取得する
;-------------------------------------------------
@GET_SKILL_NAME(SKILL_DEF_NAME, GENRE)
#FUNCTIONS
#DIMS SKILL_DEF_NAME
#DIM GENRE

VARSET RESULTS
XML_GET XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/skillname", RESULTS, 1
RETURNF RESULTS

;-------------------------------------------------
; スキル定義名から武器スキル表示名を取得する
;-------------------------------------------------
@GET_WPN_SKILL_NAME(SKILL_DEF_NAME, GENRE)
#FUNCTIONS
#DIMS SKILL_DEF_NAME
#DIM GENRE

VARSET RESULTS
XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/skillname", RESULTS, 1
RETURNF RESULTS

;-------------------------------------------------
;@GET_SKILL_DESC
;スキル説明文を取得
;-------------------------------------------------
;region @GET_SKILL_DESC
@GET_SKILL_DESC(SKILL_DEF_NAME, GENRE, SKILL_LV, IS_WPN_SKILL = 0, WITH_TOKEN_TOOLTIP = 0, CR_CHAR = "<br>")
#DIMS SKILL_DEF_NAME
#DIM  GENRE
#DIM  SKILL_LV
#DIM  IS_WPN_SKILL
#DIM  WITH_TOKEN_TOOLTIP
#DIMS CR_CHAR

#DIMS DYNAMIC TEXT
#DIM  DYNAMIC RATE, 3
#DIM  GROUP_COUNT
#DIM  XML_ID
#DIMS _XML

VARSET RESULT

;レベルに対応した効果量を取得
CALL SKILL_GET_EFFECT_RATE(GENRE, SKILL_DEF_NAME, SKILL_LV, IS_WPN_SKILL)
RATE:0 = RESULT
RATE:1 = RESULT:1
RATE:2 = RESULT:2
IF !IS_WPN_SKILL
	XML_GET XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/description", RESULTS, 1
ELSE
	XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/description", RESULTS, 1
ENDIF
TEXT = %RESULTS%

;説明本文の改行を指定の文字列にに変換
TEXT = %REPLACE(TEXT, "\\\\n", CR_CHAR)%

;代用表記を置換
TEXT = %REPLACE(TEXT, "\\[\\$RATE\\]", @"{RATE:0}")%
TEXT = %REPLACE(TEXT, "\\[\\$RATE2\\]", @"{RATE:1}")%
TEXT = %REPLACE(TEXT, "\\[\\$RATE3\\]", @"{RATE:2}")%

TEXT = %GET_SKILL_DESC_TOKEN_TOOLTIP(TEXT, WITH_TOKEN_TOOLTIP)%

IF !IS_WPN_SKILL
	XML_ID = XMLID_SKILL:GENRE
ELSE
	XML_ID = XMLID_WPN_SKILL:GENRE
ENDIF

XML_GET XML_ID, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML, 3
TEXT = %REPLACE_TAGGED_VALUE(TEXT, _XML, SKILL_LV)%
RESULTS = %TEXT%

;[VALUE:dispIdName]の置換
@REPLACE_TAGGED_VALUE(TEXT, _XML, SKILL_LV = 1)
#FUNCTIONS
#DIMS TEXT
#DIMS _XML
#DIM  SKILL_LV
#DIM  TAG_COUNT
#DIMS DISP_ID_NAME, MAX_MODIFIER_PER_SKILL

TAG_COUNT = XML_GET(_XML, @"//value/@dispIdName", DISP_ID_NAME, 1)
;DEBUGPRINTFORML %SKILL_DEF_NAME% VALUE_COUNT = {TAG_COUNT}
FOR LOCAL, 0, TAG_COUNT
	XML_GET _XML, @"//value[@dispIdName = '%DISP_ID_NAME:LOCAL%']/li[{SKILL_LV}]", RESULTS, 1
	TEXT = %REPLACE(TEXT, @"\\[\\$VALUE:%DISP_ID_NAME:LOCAL%\\]", @"%RESULTS%")%
NEXT
;DEBUGPRINTFORML TEXT %TEXT%

RETURNF TEXT
;#endregion
;-------------------------------------------------
;@GET_SKILL_DESC_TOKEN_TOOLTIP
;トークン情報ツールチップを置換。[$TOKEN:TOKEN_DEF_NAME]形式で指定
;-------------------------------------------------
@GET_SKILL_DESC_TOKEN_TOOLTIP(TEXT, WITH_TOKEN_TOOLTIP)
#FUNCTIONS
#DIMS TEXT
#DIM  WITH_TOKEN_TOOLTIP

#DIM  M_COUNT
#DIM  GROUP_COUNT
#DIM  IDX
#DIMS REPLACED
#DIMS TOOLTIP
REPLACED '= ""
RESULTS '= ""
M_COUNT = REGEXPMATCH(TEXT, "(?<=\\[\\$TOKEN:).*?(?=\\])", GROUP_COUNT, RESULTS)
FOR LOCAL, 0, M_COUNT
	;DEBUGPRINTFORML RESULTS:LOCAL = %RESULTS:LOCAL%
	DT_SELECT "SP_TOKEN_PARAMS", @"TOKEN_DEF_NAME = '%RESULTS:LOCAL%'",,IDX
	IF WITH_TOKEN_TOOLTIP
		TOOLTIP = %DT_CELL_GETS("SP_TOKEN_PARAMS", IDX, "TOOLTIP", 1)%
		;行頭のタブまたはスペースを削除する
		TOOLTIP = %REPLACE(TOOLTIP, "[ |\t]+", "")%
		REPLACED '= @"@C:{カラー_パステルブルー}@@T:%TOOLTIP%@%DT_CELL_GETS("SP_TOKEN_PARAMS", IDX, "TOKEN_NAME", 1)%@/T@@/C@"
	ELSE
		REPLACED = %DT_CELL_GETS("SP_TOKEN_PARAMS", IDX, "TOKEN_NAME", 1)%
	ENDIF
	TEXT = %REPLACE(TEXT, @"\\[\\$TOKEN:%RESULTS:LOCAL%\\]", @"【%REPLACED%】")%
NEXT
;DEBUGPRINTFORML TEXT %TEXT%
RETURNF TEXT
;-------------------------------------------------
; スキル定義から指定のデータを取得する
;-------------------------------------------------
@GET_SKILL_DATA(SKILL_DEF_NAME, DATANAME, IS_WPN_SKILL = 0, GENRE)
#FUNCTIONS
#DIMS SKILL_DEF_NAME
#DIMS DATANAME
#DIM  IS_WPN_SKILL
#DIM  GENRE
VARSET RESULTS
IF !IS_WPN_SKILL
	XML_GET XMLID_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/%DATANAME%", RESULTS, 1
ELSE
	XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']/%DATANAME%", RESULTS, 1
ENDIF
RETURNF RESULTS

;-------------------------------------------------
;@SKILL_GET_BASE_SP_EXTEND_LIMIT()
;スキルポイントの拡張上限値
;-------------------------------------------------
;region @SKILL_GET_BASE_SP_EXTEND_LIMIT()
@SKILL_GET_BASE_SP_EXTEND_LIMIT(CHARA_ID, MAJOR_GENRE)
#FUNCTION
#DIM CHARA_ID
#DIM MAJOR_GENRE
#DIM DYNAMIC RELATION_POINT
#DIM DYNAMIC LIMIT_SKILL_POINT
;主人公は陥落済みとして扱う
IF CHARA_ID == MASTER
	RELATION_POINT = 2
ELSE
	RELATION_POINT = 陥落度(CHARA_ID)
ENDIF
IF MAJOR_GENRE == スキル_大分類_冒険
	LIMIT_SKILL_POINT = QST_スキルポイント初期上限値 + CFLAG:CHARA_ID:冒険スキル拡張上限
	SELECTCASE RELATION_POINT
		CASE 1
			LIMIT_SKILL_POINT += 5
		CASE 2
			LIMIT_SKILL_POINT += 10
	ENDSELECT
ELSEIF MAJOR_GENRE == スキル_大分類_性技
	LIMIT_SKILL_POINT = QST_スキルポイント初期上限値 + CFLAG:CHARA_ID:性技スキル拡張上限
	SELECTCASE RELATION_POINT
		CASE 1
			LIMIT_SKILL_POINT += 5
		CASE 2
			LIMIT_SKILL_POINT += 10
	ENDSELECT
ELSEIF MAJOR_GENRE == スキル_大分類_生活
	LIMIT_SKILL_POINT = 10
ENDIF

RETURNF LIMIT_SKILL_POINT

;#endregion

;-------------------------------------------------
;;; 武器スキル定義XMLからパラメータ参照用テーブルを作成
;-------------------------------------------------
@WPN_SKILL_GET_PARAMS_TO_TABLE(WEAPON_DID, GENRE, SKILL_DEF_NAME = "", _XML_SKILL = "")
#DIM  WEAPON_DID
#DIM  GENRE
#DIMS SKILL_DEF_NAME
#DIMS _XML_SKILL

#DIM  DYNAMIC CHARA_ID
#DIMS DYNAMIC SKILL_NAME
#DIM  DYNAMIC SKILL_LV
#DIM  DYNAMIC EFFECT_RATE
#DIMS DYNAMIC DIC_WPN_SKILL

IF SKILL_DEF_NAME == "" && _XML_SKILL == ""
	THROW @WPN_SKILL_GET_PARAMS_TO_TABLE:SKILL_DEF_NAMEか_XML_SKILLのいずれかの指定が必要
ENDIF

IF DT_EXIST("WPN_SKILL_PARAMS")
	DT_CLEAR "WPN_SKILL_PARAMS"
ENDIF
CALL CREATE_WPN_SKILL_PARAMS_TABLE

IF SKILL_DEF_NAME != ""
	XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
	SIF !RESULT
		RETURN 0
ELSE
	XML_GET _XML_SKILL, "//defname/@parentname", RESULTS,1
	SKILL_DEF_NAME = %RESULTS%
ENDIF

XML_GET _XML_SKILL, "//skillname", RESULTS,1
SKILL_NAME = %RESULTS%
DIC_WPN_SKILL = %DT_CELL_GETS("WEAPON_STOCK", WEAPON_DID, "PASSIVE_WEAPON_SKILL", 1)%
SKILL_LV = TOINT(DIC_GET(DIC_WPN_SKILL, SKILL_DEF_NAME))
XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
EFFECT_RATE = TOINT(RESULTS)

{
	DT_ROW_ADD "WPN_SKILL_PARAMS"
		,"SKILL_DEF_NAME", SKILL_DEF_NAME
		,"SKILL_NAME", SKILL_NAME
		,"SKILL_LV", SKILL_LV
		,"EFFECT_RATE", EFFECT_RATE
}

RETURN 1


code:
{
    #DIMS CONST SKILL_MAJOR_GENRE_ENG =
        "LIFE", "ADV", "LEWD"
}

{
    #DIMS CONST SKILL_MAJOR_GENRE =
        "生活", "冒険", "性技"
}

{
    #DIMS CONST SKILL_GENRE_ENG =
        "LIFE", "BATTLE", "QUEST", "LEWD"
}

{
    #DIMS CONST SKILL_GENRE_JP =
        "生活", "戦闘", "クエスト", "性技"
}

#DIM CONST SKILL_MAJOR_GENRE_NUM = VARSIZE("SKILL_MAJOR_GENRE_ENG")
#DIM CONST SKILL_GENRE_NUM = VARSIZE("SKILL_GENRE_ENG")
#DIMS SKILL_SELECT_TAB

#DIM CONST QST_スキルポイント初期上限値 = 10
#DIM CONST QST_スキルポイント拡張上限値 = 38
#DIM CONST スキル_大分類_生活 = 0
#DIM CONST スキル_大分類_冒険 = 1
#DIM CONST スキル_大分類_性技 = 2
#DIM CONST スキル_大分類_武器 = 9

#DIM CONST スキル_ジャンル_生活 = 0
#DIM CONST スキル_ジャンル_戦闘 = 1
#DIM CONST スキル_ジャンル_クエスト = 2
#DIM CONST スキル_ジャンル_性技 = 3
#DIM XMLID_SKILL = XMLID_SKILL_LIFE, XMLID_SKILL_BATTLE, XMLID_SKILL_QUEST, XMLID_SKILL_LEWD
#DIM CONST 武器スキル_パッシブ = 0
#DIM CONST 武器スキル_アクティブ = 1
#DIM XMLID_WPN_SKILL = XMLID_WPN_SKILL_PASSIVE, XMLID_WPN_SKILL_ACTIVE

#DIM CONST スキル_ジャンル_PERSONAL = 0
#DIM CONST スキル_ジャンル_TROOP = 1
#DIM CONST スキル_ジャンル_UNIQUE = 2
#DIM CONST MAX_SKILL_SLOT = 12
#DIM CONST MAX_SKILLS = 500
#DIM CONST 初期SP = 3
#DIMS SKILL_DEF_LIST, MAX_SKILLS
#DIM SKILL_NUM
#DIM CHARADATA USED_SKILL_POINT, SKILL_MAJOR_GENRE_NUM
#DIM SAVEDATA CHARADATA BASE_SKILL_POINT, SKILL_MAJOR_GENRE_NUM
;[(str SKILL_DEF_NAME):(int SKILL_LEVEL)]の形式で連想配列で保持する
#DIMS SAVEDATA CHARADATA _DIC_SKILL_LIST, SKILL_MAJOR_GENRE_NUM
#DIMS SAVEDATA CHARADATA _LIST_ACTIVE_SKILL_SLOT
#DIM  CHARADATA ACTIVE_SKILL_COOLTIME, 3
#DIM  CHARADATA WPN_ACTIVE_SKILL_COOLTIME, 3

#DIM SAVEDATA CHARADATA SKILL_NO_SLOT, SKILL_GENRE_NUM, MAX_SKILL_SLOT
#DIM SAVEDATA CHARADATA SKILL_ID_SLOT, SKILL_GENRE_NUM, MAX_SKILL_SLOT

#DIM COMBAT_SKILL_TARGET

#DIM  SHOP_SKILL_NO_LIST, SKILL_GENRE_NUM, 3000
#DIM  SHOP_SKILL_ID_LIST, SKILL_GENRE_NUM, 3000
#DIM  SHOP_SKILL_LEVEL_LIST, SKILL_GENRE_NUM, 3000
#DIM  SHOP_SKILL_NO_SLOT, SKILL_GENRE_NUM, MAX_SKILL_SLOT * SKILL_GENRE_NUM
#DIM  SHOP_SKILL_ID_SLOT, SKILL_GENRE_NUM, MAX_SKILL_SLOT * SKILL_GENRE_NUM
#DIM  SHOP_SKILL_NUM, SKILL_GENRE_NUM
#DIM  SHOP_SKILL_PAGE, SKILL_GENRE_NUM + 1
#DIM  SHOP_SKILL_PAGE_NUM
#DIM  SHOP_SKILL_CURRENT_PAGE
#DIMS SHOP_SKILL_MODE
#DIMS SHOP_SKILL_LEARN_MODE
#DIMS SHOP_SKILL_FILTER
#DIM  SHOP_SKILL_LEARN_OMIT_CONFIRM_FLAG
#DIM  CONST SKILL_LEARN_PRICE = 0, 2000, 5000, 8000, 50000, 100000
#DIM  CONST SKILL_FORGET_PRICE = 5000

#DIM  CONST MAX_MODIFIER_PER_SKILL = 20
#DIM  CONST MAX_VALUE_PER_SKILL = 20


code:
;-------------------------------------------------
; アイテム加工画面
;-------------------------------------------------
@SKILL_LEARNING_MENU()
#DIM CONST WINDOW_ID = 0
#DIM DYNAMIC LINE_NUM
#DIM USE_MODULE_ID

LINE_NUM = LINECOUNT

CALL WndMgr_DestroyWindow(-1)
WHILE 1
    LINE_NUM = LINECOUNT
    CALL DRAW_SKILL_LEARNING_WINDOW()
    CALL HO_CRAFT_WINDOW_INPUT
    IF RESULT == -1
        RETURN -1
    ELSEIF RESULT == 1
        RETURN 1
    ENDIF
    CLEARLINE LINECOUNT - LINE_NUM
WEND

@DRAW_SKILL_LEARNING_WINDOW
#DIM CONST WINDOW_ID = 0
#DIM CONST WND_WIDTH  = 120
#DIM CONST WND_HEIGHT = 30
#DIM DYNAMIC L_CNT
#DIM DYNAMIC BTN_ID

#DIMS DYNAMIC _LIST_MEMBER
#DIM DYNAMIC MEMBER_NUM
#DIM DYNAMIC CHARA_ID
#DIM DYNAMIC F_COL0
#DIM DYNAMIC F_COL1

#DIM DYNAMIC MODULE_ID
#DIMS DYNAMIC ITEM_NAME
#DIM DYNAMIC ITEM_NUM
#DIM DYNAMIC MATERIAL_NEEDS, ITEM_LENGTH
#DIM DYNAMIC WPN_MATERIAL_NEEDS, WPN_材質種類数, ITEM_LENGTH
#DIMS DYNAMIC WEAPON_NAME
#DIM DYNAMIC 材質種類
#DIM DYNAMIC アイテム種類
#DIM DYNAMIC IS_CRAFTABLE

BTN_ID = HO_アイテムクラフトボタンID

CALL WndMgr_CheckExistWindow()
FINDELEMENT RESULT, WINDOW_ID, 1
IF RESULT == -1
    CALL WndMgr_CreateWindow(WINDOW_ID, 0, 1, WND_WIDTH, WND_HEIGHT, 2)
ELSE
    CALL WndMgr_ResetWindow(WINDOW_ID)
ENDIF

;CATEGORYタブの文字色
IF !HO_CRAFT_CATEGORY
    F_COL0 = カラー_選択中
    F_COL1 = カラー_白
ELSE
    F_COL0 = カラー_白
    F_COL1 = カラー_選択中
ENDIF

CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_注釈}@◇スキル習得◇@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_注釈}@習得するスキルを選択してください@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{F_COL0}@@B:0@[生活]@/B@@/C@　@C:{F_COL1}@@B:1@[冒険]@/B@@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
ENDIF

;フッター出力
;-------------------------------------------------
L_CNT = WND_HEIGHT - 4
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@B:9999999@@C:{カラー_白}@[キャンセル]@/C@@/B@")

CALL WndMgr_DisplayAll()

RETURN

@SKILL_LEARNING_WINDOW_INPUT
;入力受付
ONEINPUT
CLEARLINE 1
PRINTL

;キャンセルボタン
IF RESULT == 9999999
    RETURN -1
ELSEIF RESULT == 0 || RESULT == 1
    INVERTBIT HO_CRAFT_CATEGORY, 0
ELSEIF HO_CRAFT_CATEGORY == 0 ;アイテム作成モード
    CALL SKILL_LEARNING_WINDOW_INPUT(RESULT)
    SIF RESULT
        RETURN 1
ENDIF

; #DIM INPUT_VALUE
; #DIMS DYNAMIC ITEM_NAME
; #DIMS DYNAMIC MATERIAL_NAME
; #DIM DYNAMIC ITEM_ID
; #DIM DYNAMIC ITEM_NUM
; #DIM DYNAMIC MATERIAL_NEEDS, ITEM_LENGTH
; #DIM DYNAMIC F_COL
; #DIM DYNAMIC ERR_FLG
; #DIM FIRST_LINE

; ITEM_ID = INPUT_VALUE - HO_アイテムクラフトボタンID
; IF ITEM_ID <= 100000 ;クラフト可能なアイテムのボタンが押された
;     CALL GET_ITEM_NAME(ITEM_ID)
;     ITEM_NAME = %RESULTS%
;     CALLF TAG_PRINT(@"%ITEM_NAME%のクラフトには以下の資源を消費します　@C:{カラー_選択不可}@(所持数:{HO_ITEM_STOCK:ITEM_ID})@/C@", 1)
;     PRINTL
;     FIRST_LINE = LINECOUNT
;     WHILE 1
;         CALL GET_ITEM_MATERIAL_NEEDS(ITEM_ID, MATERIAL_NEEDS)
;         FOR LOCAL:0, 0, ITEM_LENGTH
;             IF MATERIAL_NEEDS:(LOCAL:0) > 0
;                 CALL GET_ITEM_NAME(LOCAL:0)
;                 MATERIAL_NAME = %RESULTS%
;                 CALLF TAG_PRINT(@"　@C:{カラー_白}@%MATERIAL_NAME% × {(MATERIAL_NEEDS:(LOCAL:0)* 生産回数)}@/C@ @C:{カラー_選択不可}@(所持数:{HO_ITEM_STOCK:(LOCAL:0)})@/C@", 1)
;             ENDIF
;         NEXT
;         ;生産に関する情報を取得
;         CALL GET_ITEM_INFO(ITEM_ID, ITEM_基準生産量)
;         基準生産量 = RESULT
;         CALL GET_ITEM_NAME(ITEM_ID)
;         生産物名 = %RESULTS%
;         現在時刻 '= @"{HO_TIME / 60}:%TOSTR(HO_TIME % 60, "00")%"

;         ;生産に関する情報を印字
;         生産時間 = 基準生産時間 * 生産回数
;         完了予定時刻 '= @"{(HO_TIME + 生産時間) / 60}:%TOSTR((HO_TIME + 生産時間) % 60, "00")%"
;         PRINTL
;         CALLF TAG_PRINT(@"　　@C:{カラー_注意}@→ %生産物名% × {基準生産量 * 生産回数}@/C@　", 0)

;         ;生産量増減時のエラーチェック
;         ERR_FLG = 0
;         FOR LOCAL:0, 0, ITEM_LENGTH
;             IF (MATERIAL_NEEDS:(LOCAL:0) * (生産回数 + 1)) > HO_ITEM_STOCK:(LOCAL:0)
;                 ERR_FLG = 1
;             ENDIF
;         NEXT
;         ;;完了予定時刻が27時を超過する場合増分を認めない
;         SIF HO_TIME + (基準生産時間 * (生産回数 + 1)) > HO_CLOCK(2700)
;             ERR_FLG = 1

;         ;ボタン印字
;         IF 生産回数 > 1
;             CALLF TAG_PRINT(@"@B:3@[-]@/B@ ", 4)
;         ELSE
;             CALLF TAG_PRINT(@"@C:{カラー_選択不可}@[-]@/C@ ", 4)
;         ENDIF
;         IF !ERR_FLG && 生産回数 < 10
;             CALLF TAG_PRINT(@"@B:2@[+]@/B@ ", 4)
;         ELSE
;             CALLF TAG_PRINT(@"@C:{カラー_選択不可}@[+]@/C@ ", 4)
;         ENDIF
;         CALLF TAG_PRINT(@"　　　 @C:{カラー_注釈}@所要時間:{生産時間}分 (%現在時刻% → %完了予定時刻%)@/C@", 1)
;         PRINTL
;         CALLF TAG_PRINT(@"　@B:1@[決定]@/B@　　　　@B:0@[キャンセル]@/B@", 5)

;         ;入力受付
;         ONEINPUT
;         SELECTCASE RESULT
;             CASE 1
;                 CALL CHANGE_ITEM_STOCK(ITEM_ID, 基準生産量 * 生産回数)
;                 CALL USE_MATERIAL(MATERIAL_NEEDS, 生産回数)
;             ;口上表示用
;                 TFLAG:クラフト_アイテムID = ITEM_ID
;                 TFLAG:クラフト_作成量 = 基準生産量 * 生産回数
;                 RETURN 1
;             CASE 0
;                 RETURN 0
;             CASE 2
;                 生産回数 ++
;             CASE 3
;                 生産回数 --
;         ENDSELECT
;         CLEARLINE LINECOUNT - FIRST_LINE
;     WEND
; ELSE ;クラフト不可能なアイテムのボタンが押された
;     ITEM_ID -= 100000
;     CALL GET_ITEM_NAME(ITEM_ID)
;     ITEM_NAME = %RESULTS%
;     PRINTFORML 材料が不足しています。%ITEM_NAME%のクラフトには以下の資源が必要です
;     PRINTL
;     CALL GET_ITEM_MATERIAL_NEEDS(ITEM_ID, MATERIAL_NEEDS)
;     FOR LOCAL:0, 0, ITEM_LENGTH
;         IF MATERIAL_NEEDS:(LOCAL:0) > 0
;             CALL GET_ITEM_NAME(LOCAL:0)
;             MATERIAL_NAME = %RESULTS%
;             IF MATERIAL_NEEDS:(LOCAL:0) > HO_ITEM_STOCK:(LOCAL:0)
;                 F_COL = カラー_注意
;             ELSE
;                 F_COL = カラー_白
;             ENDIF
;             CALLF TAG_PRINT(@"　@C:{F_COL}@%MATERIAL_NAME%　×　{MATERIAL_NEEDS:(LOCAL:0)}@/C@ @C:{カラー_選択不可}@(所持数:{HO_ITEM_STOCK:(LOCAL:0)})@/C@", 1)
;         ENDIF
;     NEXT
;     WAIT
; ENDIF


code:
@LEWDSKILL_CUM_INFLATION(CHARA_ID, BASE_AMOUNT)
#DIM CHARA_ID
#DIM BASE_AMOUNT
#DIM DYNAMIC 増加量
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM DYNAMIC SKILL_LV
VARSET RESULTS

;スキル定義のXML取得
XML_GET XMLID_SKILL_LEWD, @"//defname[@parentname='CUM_INFLATION']", _XML_SKILL, 3
IF RESULT
    XML_GET _XML_SKILL, @"defname/@parentname", RESULTS
    SKILL_DEF_NAME = %RESULTS%
    CALL SKILL_GET_LEVEL(CHARA_ID, スキル_大分類_性技, SKILL_DEF_NAME)
    SKILL_LV = RESULT
    XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
    IF RESULT
        増加量 = (BASE_AMOUNT * TOINT(RESULTS)) / 100
    ENDIF
ENDIF
RETURN 増加量

@LEWDSKILL_MILK_INFLATION(CHARA_ID, BASE_AMOUNT)
#DIM CHARA_ID
#DIM BASE_AMOUNT
#DIM DYNAMIC 増加量
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM DYNAMIC SKILL_LV
VARSET RESULTS

;スキル定義のXML取得
XML_GET XMLID_SKILL_LEWD, @"//defname[@parentname='MILK_INFLATION']", _XML_SKILL, 3
IF RESULT
    XML_GET _XML_SKILL, @"defname/@parentname", RESULTS
    SKILL_DEF_NAME = %RESULTS%
    CALL SKILL_GET_LEVEL(CHARA_ID, スキル_大分類_性技, SKILL_DEF_NAME)
    SKILL_LV = RESULT
    XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
    IF RESULT
        増加量 = (BASE_AMOUNT * TOINT(RESULTS)) / 100
    ENDIF
ENDIF
RETURN 増加量


code:
@SHOP_LIFE_SWAP_SKILL(対象)
#DIM 対象
#DIM 一つ目ジャンル
#DIM 一つ目位置
#DIM 入力値ジャンル
#DIM 入力値位置
#DIM FIRST_LINE

FIRST_LINE = LINECOUNT
VARSET 一つ目ジャンル, -1
VARSET 一つ目位置, -1

$SHOW_LOOP

CALL SINGLE_DRAWLINE
PRINTFORML ◆%ANAME(対象)%のスキル◆
PRINTFORML ※同一ジャンル間でのみ入れ替えられます
LOCAL:2 = 0
FOR LOCAL, 0, SKILL_GENRE_NUM
	FOR LOCAL:1, 0, MAX_SKILL_SLOT
		TRYCCALLFORM SKILL_{SKILL_NO_SLOT:対象:LOCAL:(LOCAL:1)}_%SKILL_GENRE_ENG:LOCAL%_{SKILL_ID_SLOT:対象:LOCAL:(LOCAL:1)}_EXIST
		CATCH
			CONTINUE
		ENDCATCH
		CALL COLOR_LINE
		IF 一つ目ジャンル == LOCAL && 一つ目位置 == LOCAL:1
			SETCOLOR カラー_注意
			PRINTPLAINFORM [入れ替え]
		ELSEIF 一つ目ジャンル != -1 && 一つ目ジャンル != LOCAL
			SETCOLOR カラー_選択不可
			PRINTPLAINFORM [入れ替え]
		ELSE
			RESETCOLOR
			PRINTBUTTON "[入れ替え]", LOCAL * 1000 + LOCAL:1
		ENDIF
		RESETCOLOR
		CALL SKILL_EXPLANATION(LOCAL, SKILL_NO_SLOT:対象:LOCAL:(LOCAL:1), SKILL_ID_SLOT:対象:LOCAL:(LOCAL:1), 5)
		LOCAL:2 = 1
	NEXT
NEXT
SIF !LOCAL:2
	PRINTFORML

DRAWLINE
PRINTBUTTON "[戻る]", 1000000

INPUT

;戻す
IF RESULT == 1000000
	CLEARLINE LINECOUNT - FIRST_LINE
	RETURN
ENDIF

入力値ジャンル = RESULT / 1000
入力値位置 = RESULT % 1000

;最低限の入力値バリデーション
IF !INRANGE(入力値ジャンル, 0, SKILL_GENRE_NUM - 1) || !INRANGE(入力値位置, 0, MAX_SKILL_SLOT - 1)
	CLEARLINE LINECOUNT - FIRST_LINE
	GOTO SHOW_LOOP
ENDIF

;一つ目が指定されている場合は選択不可なやつを弾く
IF (一つ目ジャンル != -1 && 入力値ジャンル != 一つ目ジャンル) || (一つ目ジャンル == 入力値ジャンル && 一つ目位置 == 入力値位置)
	CLEARLINE LINECOUNT - FIRST_LINE
	GOTO SHOW_LOOP
ENDIF

;習得していなければ弾く
TRYCCALLFORM SKILL_{SKILL_NO_SLOT:対象:入力値ジャンル:入力値位置}_%SKILL_GENRE_ENG:入力値ジャンル%_{SKILL_ID_SLOT:対象:入力値ジャンル:入力値位置}_EXIST
CATCH
	CLEARLINE LINECOUNT - FIRST_LINE
	GOTO SHOW_LOOP
ENDCATCH

;一つ目の指定
IF 一つ目ジャンル == -1
	一つ目ジャンル = 入力値ジャンル
	一つ目位置 = 入力値位置
	CLEARLINE LINECOUNT - FIRST_LINE
	GOTO SHOW_LOOP
ELSE
	SWAP SKILL_NO_SLOT:対象:入力値ジャンル:入力値位置, SKILL_NO_SLOT:対象:一つ目ジャンル:一つ目位置
	SWAP SKILL_ID_SLOT:対象:入力値ジャンル:入力値位置, SKILL_ID_SLOT:対象:一つ目ジャンル:一つ目位置
	RESTART
ENDIF

;-------------------


code:
;能力アップ画面の処理

;-------------------------------------------------
;コマンド実行時の自動能力上昇 ARG:0……キャラ番号
;ARG:1 = 1:メッセージを非表示
;ARG:1 = 2:メッセージをログ表示(ハウジングモードのみ)
;-------------------------------------------------
@TRAIN_AUTO_ABLUP(ARG:0, ARG:1 = 0)
#DIM 初期値
#DIM 能力
#DIM 必要経験値
#DIM 対応経験値
;能力固定フラグが立っているなら処理しない
IF CFLAG:(ARG:0):能力固定フラグ
	RETURN
ENDIF

FOR 能力, 0, 85
	初期値 = ABL:(ARG:0):能力
	IF ABLNAME:能力 == "性知識"
		;性知識は別枠
		CALL TRAIN_AUTO_ABLUP_KNOWLEDGE(ARG:0, ARG:1)
		CONTINUE
	ENDIF

	;能力に対応する経験値の名称を取得
	RESULTS =
	TRYCALLFORM ABLUP_EXPNAME{能力}
	SIF RESULTS == ""
		CONTINUE

	対応経験値 = GETNUM(EXP, RESULTS)

	WHILE ABL:(ARG:0):能力 < 9999
		;必要な経験値の計算
		RESULT = 0
		TRYCALLFORM CALC_ABLUP_EXP{能力}(ARG:0)
		必要経験値 = RESULT

		SIF 必要経験値 < 0 || EXP:(ARG:0):対応経験値 < 必要経験値
			BREAK
		ABL:(ARG:0):能力 ++
		EXP:(ARG:0):対応経験値 -= 必要経験値
	WEND

	SIF 初期値 == ABL:(ARG:0):能力
		CONTINUE

	IF ARG:1 == 0
		SETCOLOR カラー_オレンジ
		PRINTFORML %ANAME(ARG:0)%の%ABLNAME:(能力)%が上昇した(Lv{初期値}→{ABL:(ARG:0):能力})
		RESETCOLOR
	ELSEIF ARG:1 == 2 && FLAG:ハウジングモード
		CALL HO_PRINT_LOG(@"%ANAME(ARG:0)%の%ABLNAME:(能力)%が上昇した(Lv{初期値}→@C:{カラー_緑}@{ABL:(ARG:0):能力}@/C@)")
	ENDIF
NEXT

;-------------------------------------------------
;性知識の特殊なLv上昇処理 ARG:0……キャラ番号 ARG:1……1ならメッセージを非表示
;-------------------------------------------------
@TRAIN_AUTO_ABLUP_KNOWLEDGE(ARG:0, ARG:1)
;能力固定フラグが立っているなら処理しない
IF CFLAG:(ARG:0):能力固定フラグ
	RETURN
ENDIF

WHILE ABL:(ARG:0):性知識 < 5
	;常に経験値100でLv上昇
	IF EXP:(ARG:0):性知識経験値 >= 100
		ABL:(ARG:0):性知識 ++
		EXP:(ARG:0):性知識経験値 = 0
		IF ARG:1 == 0
			SETCOLOR カラー_オレンジ
			PRINTFORML %ANAME(ARG:0)%の性知識が上昇しました(Lv{ABL:(ARG:0):性知識})
			RESETCOLOR
		ENDIF
	ELSE
		BREAK
	ENDIF
WEND


code:
;能力上昇 Ｃ感

;-------------------------------------------------
;能力上昇に必要な経験を設定
;-------------------------------------------------
@ABLUP_EXPNAME0
RESULTS = Ｃ感経験値

;-------------------------------------------------
;能力上昇に必要な経験量を返す関数
;-------------------------------------------------
@CALC_ABLUP_EXP0(ARG:0)
SELECTCASE ABL:(ARG:0):Ｃ感
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 15
	CASE 2
		LOCAL:0 = 30
	CASE 3
		LOCAL:0 = 100
	CASE 4
		LOCAL:0 = 200
	CASEELSE
		LOCAL:0 = 500 + 300 * (ABL:(ARG:0):Ｃ感 - 5)
ENDSELECT

IF ARG:0 == MASTER
	TIMES LOCAL:0, 2.00
ENDIF

;素質による補正
IF TALENT:(ARG:0):Ｃ鈍感
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):Ｃ敏感
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乱)
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫核)
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)


code:
;能力上昇 Ｖ感

;-------------------------------------------------
;能力上昇に必要な経験を設定
;-------------------------------------------------
@ABLUP_EXPNAME1
RESULTS = Ｖ感経験値

;-------------------------------------------------
;能力上昇に必要な経験量を返す関数
;-------------------------------------------------
@CALC_ABLUP_EXP1(ARG:0)
SELECTCASE ABL:(ARG:0):Ｖ感
	CASE 0
		LOCAL:0 = 8
	CASE 1
		LOCAL:0 = 25
	CASE 2
		LOCAL:0 = 50
	CASE 3
		LOCAL:0 = 150
	CASE 4
		LOCAL:0 = 300
	CASEELSE
		LOCAL:0 = 500 + 400 * (ABL:(ARG:0):Ｖ感 - 5)
ENDSELECT

IF ARG:0 == MASTER
	TIMES LOCAL:0, 2.00
ENDIF

;素質による補正
IF TALENT:(ARG:0):Ｖ鈍感
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):Ｖ敏感
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乱)
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫壷)
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)


code:
;能力上昇 Ａ感

;-------------------------------------------------
;能力上昇に必要な経験を設定
;-------------------------------------------------
@ABLUP_EXPNAME2
RESULTS = Ａ感経験値

;-------------------------------------------------
;能力上昇に必要な経験量を返す関数
;-------------------------------------------------
@CALC_ABLUP_EXP2(ARG:0)
SELECTCASE ABL:(ARG:0):Ａ感
	CASE 0
		LOCAL:0 = 8
	CASE 1
		LOCAL:0 = 25
	CASE 2
		LOCAL:0 = 50
	CASE 3
		LOCAL:0 = 150
	CASE 4
		LOCAL:0 = 300
	CASEELSE
		LOCAL:0 = 500 + 400 * (ABL:(ARG:0):Ａ感 - 5)
ENDSELECT

IF ARG:0 == MASTER
	TIMES LOCAL:0, 2.00
ENDIF

;素質による補正
IF TALENT:(ARG:0):Ａ鈍感
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):Ａ敏感
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乱)
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_尻穴狂い)
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)


code:
;経験値のみによる能力上昇

;-------------------------------------------------
;奉仕
;-------------------------------------------------
@ABLUP_EXPNAME20
RESULTS = 奉仕経験値

@CALC_ABLUP_EXP20(ARG:0)
SELECTCASE ABL:(ARG:0):奉仕
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 30
	CASE 2
		LOCAL:0 = 60
	CASE 3
		LOCAL:0 = 150
	CASE 4
		LOCAL:0 = 300
	CASEELSE
		LOCAL:0 = 500 + 250 * (ABL:(ARG:0):奉仕 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):献身的
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):無関心
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):感情乏しい
	TIMES LOCAL:0, 1.20
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;性交
;-------------------------------------------------
@ABLUP_EXPNAME21
RESULTS = 性交経験値

@CALC_ABLUP_EXP21(ARG:0)
SELECTCASE ABL:(ARG:0):性交
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 15
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 160
	CASEELSE
		LOCAL:0 = 240 + 120 * (ABL:(ARG:0):性交 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;レズ
;-------------------------------------------------
@ABLUP_EXPNAME22
RESULTS = レズ経験値

@CALC_ABLUP_EXP22(ARG:0)
SELECTCASE ABL:(ARG:0):レズ
	CASE 0
		LOCAL:0 = 50
	CASE 1
		LOCAL:0 = 100
	CASE 2
		LOCAL:0 = 200
	CASE 3
		LOCAL:0 = 350
	CASE 4
		LOCAL:0 = 550
	CASEELSE
		LOCAL:0 = 800 + 400 * (ABL:(ARG:0):レズ - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):女嫌い
	TIMES LOCAL:0, 2.00
ENDIF
IF TALENT:(ARG:0):両刀
	TIMES LOCAL:0, 0.50
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;ＢＬ
;-------------------------------------------------
@ABLUP_EXPNAME23
RESULTS = ＢＬ経験値

@CALC_ABLUP_EXP23(ARG:0)
SELECTCASE ABL:(ARG:0):ＢＬ
	CASE 0
		LOCAL:0 = 50
	CASE 1
		LOCAL:0 = 100
	CASE 2
		LOCAL:0 = 200
	CASE 3
		LOCAL:0 = 350
	CASE 4
		LOCAL:0 = 550
	CASEELSE
		LOCAL:0 = 800 + 400 * (ABL:(ARG:0):ＢＬ - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):男嫌い
	TIMES LOCAL:0, 2.00
ENDIF
IF TALENT:(ARG:0):両刀
	TIMES LOCAL:0, 0.50
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;露出
;-------------------------------------------------
@ABLUP_EXPNAME24
RESULTS = 露出経験値

@CALC_ABLUP_EXP24(ARG:0)
SELECTCASE ABL:(ARG:0):露出
	CASE 0
		LOCAL:0 = 15
	CASE 1
		LOCAL:0 = 60
	CASE 2
		LOCAL:0 = 120
	CASE 3
		LOCAL:0 = 250
	CASE 4
		LOCAL:0 = 400
	CASEELSE
		LOCAL:0 = 600 + 300 * (ABL:(ARG:0):露出 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):目立ちたがり
	TIMES LOCAL:0, 0.60
ENDIF
IF TALENT:(ARG:0):恥じらい
	TIMES LOCAL:0, 1.50
ENDIF
IF TALENT:(ARG:0):恥薄い
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;自慰
;-------------------------------------------------
@ABLUP_EXPNAME25
RESULTS = 自慰経験値

@CALC_ABLUP_EXP25(ARG:0)
SELECTCASE ABL:(ARG:0):自慰
	CASE 0
		LOCAL:0 = 10
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 150
	CASEELSE
		LOCAL:0 = 200 + 100 * (ABL:(ARG:0):自慰 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):自慰しやすい
	TIMES LOCAL:0, 0.60
ENDIF
IF TALENT:(ARG:0):自制心
	TIMES LOCAL:0, 1.50
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;精愛
;-------------------------------------------------
@ABLUP_EXPNAME26
RESULTS = 精愛経験値

@CALC_ABLUP_EXP26(ARG:0)
SELECTCASE ABL:(ARG:0):精愛
	CASE 0
		LOCAL:0 = 10
	CASE 1
		LOCAL:0 = 30
	CASE 2
		LOCAL:0 = 60
	CASE 3
		LOCAL:0 = 120
	CASE 4
		LOCAL:0 = 250
	CASEELSE
		LOCAL:0 = 400 + 200 * (ABL:(ARG:0):精愛 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):汚臭敏感
	TIMES LOCAL:0, 1.50
ENDIF
IF TALENT:(ARG:0):汚臭鈍感 || TALENT:(ARG:0):汚れ無視
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;射精
;-------------------------------------------------
@ABLUP_EXPNAME27
RESULTS = 射精経験値

@CALC_ABLUP_EXP27(ARG:0)
SELECTCASE ABL:(ARG:0):射精
	CASE 0
		LOCAL:0 = 15
	CASE 1
		LOCAL:0 = 30
	CASE 2
		LOCAL:0 = 60
	CASE 3
		LOCAL:0 = 120
	CASE 4
		LOCAL:0 = 250
	CASEELSE
		LOCAL:0 = 400 + 200 * (ABL:(ARG:0):射精 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;噴乳
;-------------------------------------------------
@ABLUP_EXPNAME28
RESULTS = 噴乳経験値

@CALC_ABLUP_EXP28(ARG:0)
SELECTCASE ABL:(ARG:0):噴乳
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 160
	CASEELSE
		LOCAL:0 = 320 + 160 * (ABL:(ARG:0):噴乳 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;排泄
;-------------------------------------------------
@ABLUP_EXPNAME29
RESULTS = 排泄経験値

@CALC_ABLUP_EXP29(ARG:0)
SELECTCASE ABL:(ARG:0):排泄
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 20
	CASE 3
		LOCAL:0 = 40
	CASE 4
		LOCAL:0 = 60
	CASEELSE
		LOCAL:0 = 80 + 40 * (ABL:(ARG:0):排泄 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF
IF TALENT:(ARG:0):恥じらい
	TIMES LOCAL:0, 1.50
ENDIF
IF TALENT:(ARG:0):恥薄い
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;触手
;-------------------------------------------------
@ABLUP_EXPNAME30
RESULTS = 触手経験値

@CALC_ABLUP_EXP30(ARG:0)
SELECTCASE ABL:(ARG:0):触手
	CASE 0
		LOCAL:0 = 10
	CASE 1
		LOCAL:0 = 30
	CASE 2
		LOCAL:0 = 60
	CASE 3
		LOCAL:0 = 120
	CASE 4
		LOCAL:0 = 250
	CASEELSE
		LOCAL:0 = 400 + 200 * (ABL:(ARG:0):触手 - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;出産
;-------------------------------------------------
@ABLUP_EXPNAME31
RESULTS = 出産経験値

@CALC_ABLUP_EXP31(ARG:0)
SELECTCASE ABL:(ARG:0):出産
	CASE 0
		LOCAL:0 = 1
	CASE 1
		LOCAL:0 = 1
	CASE 2
		LOCAL:0 = 1
	CASE 3
		LOCAL:0 = 2
	CASE 4
		LOCAL:0 = 2
	CASEELSE
		LOCAL:0 = 3
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;肝臓
;-------------------------------------------------
@ABLUP_EXPNAME32
RESULTS = 肝臓経験値

@CALC_ABLUP_EXP32(ARG:0)
LOCAL = POWER(ABL:(ARG:0):肝臓 + 1, 2) * 100
RETURN MAX(LOCAL, 1)

;-------------------------------------------------
;マゾ
;-------------------------------------------------
@ABLUP_EXPNAME33
RESULTS = 被虐経験値

@CALC_ABLUP_EXP33(ARG:0)
SELECTCASE ABL:(ARG:0):マゾ
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 160
	CASEELSE
		LOCAL:0 = 200 + 80 * (ABL:(ARG:0):マゾ - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):Ｍ気質
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;サド
;-------------------------------------------------
@ABLUP_EXPNAME34
RESULTS = 嗜虐経験値

@CALC_ABLUP_EXP34(ARG:0)
SELECTCASE ABL:(ARG:0):サド
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 160
	CASEELSE
		LOCAL:0 = 200 + 80 * (ABL:(ARG:0):サド - 5)
ENDSELECT

;素質による補正
IF TALENT:(ARG:0):Ｓ気質
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;催眠
;-------------------------------------------------
@ABLUP_EXPNAME35
RESULTS = 催眠経験値

@CALC_ABLUP_EXP35(ARG:0)
SELECTCASE ABL:(ARG:0):催眠
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 20
	CASE 2
		LOCAL:0 = 40
	CASE 3
		LOCAL:0 = 80
	CASE 4
		LOCAL:0 = 140
	CASEELSE
		LOCAL:0 = 200 + 80 * (ABL:(ARG:0):催眠 - 5)
ENDSELECT

;素質による補正
SIF TALENT:(ARG:0):素直
	TIMES LOCAL:0, 0.80

SIF TALENT:(ARG:0):中毒しやすい
	TIMES LOCAL:0, 0.80

RETURN MAX(LOCAL:0, 1)


code:
;能力上昇 Ｂ感

;-------------------------------------------------
;能力上昇に必要な経験を設定
;-------------------------------------------------
@ABLUP_EXPNAME3
RESULTS = Ｂ感経験値

;-------------------------------------------------
;能力上昇に必要な経験量を返す関数
;-------------------------------------------------
@CALC_ABLUP_EXP3(ARG:0)
SELECTCASE ABL:(ARG:0):Ｂ感
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 15
	CASE 2
		LOCAL:0 = 30
	CASE 3
		LOCAL:0 = 100
	CASE 4
		LOCAL:0 = 200
	CASEELSE
		LOCAL:0 = 500 + 300 * (ABL:(ARG:0):Ｂ感 - 5)
ENDSELECT

IF ARG:0 == MASTER
	TIMES LOCAL:0, 2.00
ENDIF

;素質による補正
IF TALENT:(ARG:0):Ｂ鈍感
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):Ｂ敏感
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乱)
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乳)
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)


code:
;能力上昇 Ｍ感

;-------------------------------------------------
;能力上昇に必要な経験を設定
;-------------------------------------------------
@ABLUP_EXPNAME4
RESULTS = Ｍ感経験値

;-------------------------------------------------
;能力上昇に必要な経験量を返す関数
;-------------------------------------------------
@CALC_ABLUP_EXP4(ARG:0)
SELECTCASE ABL:(ARG:0):Ｍ感
	CASE 0
		LOCAL:0 = 5
	CASE 1
		LOCAL:0 = 15
	CASE 2
		LOCAL:0 = 30
	CASE 3
		LOCAL:0 = 100
	CASE 4
		LOCAL:0 = 200
	CASEELSE
		LOCAL:0 = 500 + 300 * (ABL:(ARG:0):Ｍ感 - 5)
ENDSELECT

IF ARG:0 == MASTER
	TIMES LOCAL:0, 2.00
ENDIF

;素質による補正
IF TALENT:(ARG:0):Ｍ鈍感
	TIMES LOCAL:0, 1.20
ENDIF
IF TALENT:(ARG:0):Ｍ敏感
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_淫乱)
	TIMES LOCAL:0, 0.80
ENDIF
IF GETBIT(TALENT:(ARG:0):淫乱系, 素質_淫乱_蕩唇)
	TIMES LOCAL:0, 0.80
ENDIF

RETURN MAX(LOCAL:0, 1)


code:
;経験値のみによる能力上昇(SLG能力)

;-------------------------------------------------
;身体
;-------------------------------------------------
@ABLUP_EXPNAME50
RESULTS = 身体経験値

@CALC_ABLUP_EXP50(ARG:0)
;最大値は300
IF ABL:(ARG:0):身体 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):身体) / GROWTYPE_RATE(ARG:0, "身体")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):身体
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;器用
;-------------------------------------------------
@ABLUP_EXPNAME51
RESULTS = 器用経験値

@CALC_ABLUP_EXP51(ARG:0)
;最大値は300
IF ABL:(ARG:0):器用 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):器用) / GROWTYPE_RATE(ARG:0, "器用")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):器用
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;知識
;-------------------------------------------------
@ABLUP_EXPNAME52
RESULTS = 知識経験値

@CALC_ABLUP_EXP52(ARG:0)
;最大値は300
IF ABL:(ARG:0):知識 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):知識) / GROWTYPE_RATE(ARG:0, "知識")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):知識
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;社交
;-------------------------------------------------
@ABLUP_EXPNAME53
RESULTS = 社交経験値

@CALC_ABLUP_EXP53(ARG:0)
;最大値は300
IF ABL:(ARG:0):社交 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):社交) / GROWTYPE_RATE(ARG:0, "社交")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):社交
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;魔術
;-------------------------------------------------
@ABLUP_EXPNAME54
RESULTS = 魔術経験値

@CALC_ABLUP_EXP54(ARG:0)
;最大値は300
IF ABL:(ARG:0):魔術 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):魔術) * 5 / GROWTYPE_RATE(ARG:0, "魔術")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):魔術
		CASE IS >= 50
			TIMES LOCAL:0, 1.50
		CASE IS >= 30
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;観察
;-------------------------------------------------
@ABLUP_EXPNAME55
RESULTS = 観察経験値

@CALC_ABLUP_EXP55(ARG:0)
;最大値は300
IF ABL:(ARG:0):観察 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):観察) / GROWTYPE_RATE(ARG:0, "観察")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):観察
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;歌唱
;-------------------------------------------------
@ABLUP_EXPNAME60
RESULTS = 歌唱経験値

@CALC_ABLUP_EXP60(ARG:0)
;最大値は300
IF ABL:(ARG:0):歌唱 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):歌唱) / GROWTYPE_RATE(ARG:0, "歌唱")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):歌唱
		CASE IS >= 50
			TIMES LOCAL:0, 1.50
		CASE IS >= 30
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;料理
;-------------------------------------------------
@ABLUP_EXPNAME61
RESULTS = 料理経験値

@CALC_ABLUP_EXP61(ARG:0)
;最大値は300
IF ABL:(ARG:0):料理 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):料理) / GROWTYPE_RATE(ARG:0, "料理")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):料理
		CASE IS >= 50
			TIMES LOCAL:0, 1.50
		CASE IS >= 30
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;話術
;-------------------------------------------------
@ABLUP_EXPNAME62
RESULTS = 話術経験値

@CALC_ABLUP_EXP62(ARG:0)
;最大値は300
IF ABL:(ARG:0):話術 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):話術) / GROWTYPE_RATE(ARG:0, "話術")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):話術
		CASE IS >= 50
			TIMES LOCAL:0, 1.50
		CASE IS >= 30
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;戦闘
;-------------------------------------------------
@ABLUP_EXPNAME63
RESULTS = 戦闘経験値

@CALC_ABLUP_EXP63(ARG:0)
;最大値は300
IF ABL:(ARG:0):戦闘 >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):戦闘) / GROWTYPE_RATE(ARG:0, "戦闘")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):戦闘
		CASE IS >= 50
			TIMES LOCAL:0, 1.50
		CASE IS >= 30
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF

RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;能力レベルARG:0に対する必要経験値(×100)を返す関数(SLG系)
;-------------------------------------------------
@ABLUP_NEED_EXP_SLG(ARG:0)
#FUNCTION
SELECTCASE ARG:0
	CASE IS >= 120
		RETURNF 7000 + (ARG:0 - 120) * 600
	CASE IS >= ランク閾値:ランク_ＳＬＧ:ランク_S
		RETURNF 4000 + (ARG:0 - 100) * 150
	CASE IS >= ランク閾値:ランク_ＳＬＧ:ランク_A
		RETURNF 2500 + (ARG:0 - 80) * 100
	CASE IS >= ランク閾値:ランク_ＳＬＧ:ランク_C
		RETURNF 1500 + (ARG:0 - 60) * 70
	CASE IS >= ランク閾値:ランク_ＳＬＧ:ランク_F
		RETURNF 700 + (ARG:0 - 30) * 10
	CASEELSE
		RETURNF 350
ENDSELECT


code:
;経験値のみによる能力上昇(ライブ活動関連能力)
;-------------------------------------------------
;演技力ＣＯ
;-------------------------------------------------
@ABLUP_EXPNAME81
RESULTS = 演技ＣＯ経験

@CALC_ABLUP_EXP81(ARG:0)
;最大値は300
IF ABL:(ARG:0):演技力ＣＯ >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):演技力ＣＯ) / GROWTYPE_RATE(ARG:0, "演技力ＣＯ")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):演技力ＣＯ
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;演技力ＣＵ
;-------------------------------------------------
@ABLUP_EXPNAME82
RESULTS = 演技ＣＵ経験

@CALC_ABLUP_EXP82(ARG:0)
;最大値は300
IF ABL:(ARG:0):演技力ＣＵ >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):演技力ＣＵ) / GROWTYPE_RATE(ARG:0, "演技力ＣＵ")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):演技力ＣＵ
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;演技力ＰＡ
;-------------------------------------------------
@ABLUP_EXPNAME83
RESULTS = 演技ＰＡ経験

@CALC_ABLUP_EXP83(ARG:0)
;最大値は300
IF ABL:(ARG:0):演技力ＰＡ >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):演技力ＰＡ) / GROWTYPE_RATE(ARG:0, "演技力ＰＡ")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):演技力ＰＡ
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)

;-------------------------------------------------
;演技力ＬＥ
;-------------------------------------------------
@ABLUP_EXPNAME84
RESULTS = 演技ＬＥ経験

@CALC_ABLUP_EXP84(ARG:0)
;最大値は300
IF ABL:(ARG:0):演技力ＬＥ >= 300
	RETURN -1
ENDIF

LOCAL:0 = ABLUP_NEED_EXP_SLG(ABL:(ARG:0):演技力ＬＥ) / GROWTYPE_RATE(ARG:0, "演技力ＬＥ")

SIF ID_TO_CHARA(FLAG:お気に入り指定キャラ) == ARG:0
	TIMES LOCAL:0, 0.80

IF TALENT:(ARG:0):サボり魔
	SELECTCASE ABL:(ARG:0):演技力ＬＥ
		CASE IS >= 90
			TIMES LOCAL:0, 1.50
		CASE IS >= 80
			TIMES LOCAL:0, 1.25
		CASEELSE
			TIMES LOCAL:0, 1.1
	ENDSELECT
ENDIF
RETURN MAX(LOCAL:0, 1)


code:
#DIM CONST カラー_選択不可 = 0x606060
#DIM CONST カラー_選択中 = 0xee7800
#DIM CONST カラー_注意= 0xFFFF00
#DIM CONST カラー_警告 = 0xFF0000

#DIM CONST カラー_男 = 0x8000FF
#DIM CONST カラー_女 = 0xFF0080
#DIM CONST カラー_男双 = 0xB000FF
#DIM CONST カラー_女双 = 0xFF00BF
#DIM CONST カラー_男の娘 = 0x40C0FF
#DIM CONST カラー_男の娘双 = 0xFF80FF
#DIM CONST カラー_性別不明 = 0x808080
#DIM CONST カラー_赤 = 0xFF0000
#DIM CONST カラー_黄 = 0xFFFF00
#DIM CONST カラー_パ赤 = 0xC07070
#DIM CONST カラー_パ青 = 0x7070C0
#DIM CONST カラー_パ緑 = 0x70C070
#DIM CONST カラー_青 = 0x0000FF
#DIM CONST カラー_シアン = 0x00FFFF
#DIM CONST カラー_黄緑 = 0x00FF80
#DIM CONST カラー_暗緑 = 0x206020
#DIM CONST カラー_パ紫 = 0xC070C0
#DIM CONST カラー_パ黄 = 0x505020
#DIM CONST カラー_パ青緑 = 0x205050
#DIM CONST カラー_白 = 0xC0C0C0
#DIM CONST カラー_黒 = 0x000000
#DIM CONST カラー_ダークグレー = 0x202020
#DIM CONST カラー_灰色 = 0x404040
#DIM CONST カラー_明灰色 = 0x777777
#DIM CONST カラー_ピンク = 0xFA58F4
#DIM CONST カラー_黒桃 = 0x990099
#DIM CONST カラー_オレンジ = 0xFFA500
#DIM CONST カラー_クリーム = 0xFFFFCC
#DIM CONST カラー_緑 = 0x00FF00
#DIM CONST カラー_シルバー = 0x808992
#DIM CONST カラー_永久同盟 = 0x00FFFF
#DIM CONST カラー_連合 = 0xFFA500
#DIM CONST カラー_討伐 = 0xFF0000
#DIM CONST カラー_同盟 = 0x00FF00
#DIM CONST カラー_停戦 = 0xFF00FF
#DIM CONST カラー_敵 = 0xA0A0A0

#DIM CONST カラー_上昇 = 0x40C0FF
#DIM CONST カラー_下降 = 0xD04040
#DIM CONST カラー_素質発動 = 0xff6666
#DIM CONST カラー_スキル発動 = 0xADFF2F

#DIM CONST カラー_妊娠 = 0xFFC0C0
#DIM CONST カラー_催眠 = 0xFF80FF

#DIM CONST カラー_注釈 = 0x8090A0

;　強調色が足りない時用
#DIM CONST カラー_オリーブ = 0x8B9E53
;補佐色
#DIM CONST カラー_ダークオレンジ = 0xC66630
#DIM CONST カラー_ダークイエロー = 0x999939
#DIM CONST カラー_ダークレッド = 0x942C2C
;深陥落カラー
#DIM CONST カラー_レッド = 0xD04040
#DIM CONST カラー_グリーン = 0x609040
#DIM CONST カラー_パープル = 0x8970DF
;浅陥落カラー
#DIM CONST カラー_イエローグリーン = 0x809940
#DIM CONST カラー_ブルー = 0x6070DC
#DIM CONST カラー_ライトグリーン = 0x90A060
#DIM CONST カラー_ライトブルー = 0x7090D0
#DIM CONST カラー_パステルピンク = 0xE5ABBE
#DIM CONST カラー_パステルグリーン = 0xA0A966
#DIM CONST カラー_パステルブルー = 0x87A8DB
;暴君に服従（服従ルートはブルー～パープル、少しずらしてシアン系）
#DIM CONST カラー_暴君カラー = 0x50A0A0
;好敵手に恋慕（恋慕ルートはピンク～レッド、少しずらしてオレンジ系）
#DIM CONST カラー_好敵手カラー = 0xCC9930
;小町を愛玩（愛玩ルートはグリーン～イエローグリーン、少しずらしてミントグリーン系）
#DIM CONST カラー_小町カラー = 0x70BB90
;シルバーのバリエーション
#DIM CONST カラー_シルバーブルー = 0x90A9BF
;季節
#DIM CONST カラー_春 = 0xE597B2
#DIM CONST カラー_夏 = 0x72AE66
#DIM CONST カラー_秋 = 0xCC9930
#DIM CONST カラー_冬 = 0x99B3DB
;天候
#DIM CONST カラー_雪天 = 0x98AAAB
#DIM CONST カラー_曇天 = 0x708E94
#DIM CONST カラー_雨天 = 0x5383C3
#DIM CONST カラー_晴天 = 0xD9D09F
;酔い
#DIM CONST カラー_ほろ酔い = 0xD0A0A0
#DIM CONST カラー_酔い = 0xFFC0C0
#DIM CONST カラー_酩酊 = 0xD08000
#DIM CONST カラー_泥酔 = 0x804000
;マップ用
#DIM CONST カラー_土 = 0x302010
#DIM CONST カラー_樹 = 0x555555
#DIM CONST カラー_畳床 = 0x363910
#DIM CONST カラー_板壁 = 0x736950
#DIM CONST カラー_板床 = 0x332C16
#DIM CONST カラー_石壁 = 0x606066
#DIM CONST カラー_石床 = 0x202029
#DIM CONST カラー_水場 = 0x105060
#DIM CONST カラー_春の樹 = 0xB38699
#DIM CONST カラー_夏の樹 = 0x0e6953
#DIM CONST カラー_秋の樹 = 0x652D30
#DIM CONST カラー_冬の樹 = 0x39435B
#DIM CONST カラー_春の土 = 0x283020
#DIM CONST カラー_夏の土 = 0x0e3129
#DIM CONST カラー_秋の土 = 0x403029
#DIM CONST カラー_冬の土 = 0x262C39
#DIM CONST カラー_春の夜の樹 = 0x3f212d
#DIM CONST カラー_夏の夜の樹 = 0x031611
#DIM CONST カラー_秋の夜の樹 = 0x2b0508
#DIM CONST カラー_冬の夜の樹 = 0x1e2330
#DIM CONST カラー_春の夜の土 = 0x101c0a
#DIM CONST カラー_夏の夜の土 = 0x051c1a
#DIM CONST カラー_秋の夜の土 = 0x0f0b09
#DIM CONST カラー_冬の夜の土 = 0x0d0f14

#DIM CONST カラー_素質_通常 = 0xC0C0C0
#DIM CONST カラー_素質_注意 = 0x87A8DB


code:
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
; カラーバー表示用関数群
;
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

;================================================================
; ゲージ(割合カラーバー)の表示処理。
;  左端色から右端色へとグラデーションする。
;--------------------------------
;	nBarVol		: バー現在値
;	nBarVolMax	: バー最大値（0以下指定だとnBarVolと同値として扱う）
;	nScaleNum	: 目盛数（10000(0.01%*10000=100%)を割り切れる数で指定することを推奨）
;	nScaleWidht	: 一目盛の幅（PRINT_RECTの幅の値）
;					※ nScaleWidht*nScaleNumがバーの長さになる
;	colorLeft	: バーの色(左端のメモリの色)
;	colorRigth	: バーの色(右端(100%)のメモリの色)
;	colorEmpty	: バーの色(Empty部分)
;	flgExtra	: 特殊表示フラグ（ビット演算。）
;					0x0001:最大値を超えて表示する, 0x0002:太いバー, 0x0004:細いバー, 0x0008:極太バー
;					0x0010:BOTTOM表示, 0x0020:TOP表示
;					0x0100:,
;					0x1000:メモリ区切りあり,
;--------------------------------
; 注意点
;	メモリ区切りありの場合、メモリ幅が小さいときれいに表示されない模様。
;================================================================
@PRINT_RATE_BAR( nBarVol, nBarVolMax, nScaleNum, nScaleWidht, colorLeft, colorRigth, colorEmpty, flgExtra )
#DIM nBarVol
#DIM nBarVolMax
#DIM nScaleNum
#DIM nScaleWidht
#DIM colorLeft
#DIM colorRigth
#DIM colorEmpty
#DIM flgExtra

CALL PRINT_RATE_BAR_EX( nBarVol, nBarVolMax, nScaleNum, nScaleWidht, colorLeft, colorRigth, colorEmpty, flgExtra, 0, 0x000000 )

RETURN

;================================================================
; ゲージ(割合カラーバー)の表示処理。
;  左端色から右端色へとグラデーションする。
;--------------------------------
;	nBarVol		: バー現在値
;	nBarVolMax	: バー最大値（0以下指定だとnBarVolと同値として扱う）
;	nScaleNum	: 目盛数（10000(0.01%*10000=100%)を割り切れる数で指定することを推奨）
;	nScaleWidht	: 一目盛の幅（PRINT_RECTの幅の値）
;					※ nScaleWidht*nScaleNumがバーの長さになる
;	colorLeft	: バーの色(左端のメモリの色)
;	colorRigth	: バーの色(右端(100%)のメモリの色)
;	colorEmpty	: バーの色(Empty部分)
;	flgExtra	: 特殊表示フラグ（ビット演算。）
;					0x0001:最大値を超えて表示する, 0x0002:太いバー, 0x0004:細いバー, 0x0008:極太バー
;					0x0010:BOTTOM表示, 0x0020:TOP表示
;					0x0100:,
;					0x1000:メモリ区切りあり,
;	nBarVol2	: nBarVol ～ nBarVol2までの値をcolorEmptyとは別の色で処理するために使用する
;	colorVol2	:
;--------------------------------
; 注意点
;	メモリ区切りありの場合、メモリ幅が小さいときれいに表示されない模様。
;================================================================
@PRINT_RATE_BAR_EX( nBarVol, nBarVolMax, nScaleNum, nScaleWidht, colorLeft, colorRigth, colorEmpty, flgExtra, nBarVol2, colorVol2 )
#LOCALSIZE 4
#DIM nBarVol
#DIM nBarVolMax
#DIM nScaleNum
#DIM nScaleWidht
#DIM colorLeft
#DIM colorRigth
#DIM colorEmpty
#DIM flgExtra
#DIM nBarVol2
#DIM colorVol2

#DIM colorLeft_RGB, 3
#DIM colorRigth_RGB, 3
#DIM nPointX
#DIM nPointY
#DIM nHeight
#DIM nRate
#DIM nLimitOver
#DIM nScaleRate
#DIM colorMem
#DIM nRate2

colorMem = GETCOLOR()

; nRate,nScaleRateは0.1%単位
IF flgExtra & 0x0008
	nHeight = 90
ELSEIF flgExtra & 0x0002
	nHeight = 40
ELSEIF flgExtra & 0x0004
	nHeight = 12
ELSE
	nHeight = 24
ENDIF
IF flgExtra & 0x1000
	nPointX = LIMIT( 12, nScaleWidht / 10, nScaleWidht / 3 )
ELSE
	nPointX = 0
ENDIF
IF flgExtra & 0x0010
	nPointY = (100 - nHeight) * 4 / 5
ELSEIF flgExtra & 0x0020
	nPointY = (100 - nHeight) * 1 / 5
ELSE
	nPointY = (100 - nHeight) / 2
ENDIF

colorLeft_RGB:0 = colorLeft / 256 / 256
colorLeft_RGB:1 = colorLeft / 256 % 256
colorLeft_RGB:2 = colorLeft % 256
colorRigth_RGB:0 = colorRigth / 256 / 256
colorRigth_RGB:1 = colorRigth / 256 % 256
colorRigth_RGB:2 = colorRigth % 256

nLimitOver = ((flgExtra & 0x01) ? 1 # 0)

IF nBarVolMax > 0
	nRate = MAX(10000 * nBarVol / nBarVolMax, 0)
	nRate2 = MAX(10000 * nBarVol2 / nBarVolMax, 0)
ELSE
	nRate = 10000
	nRate2 = 10000
ENDIF
IF nLimitOver == 0
	nRate = LIMIT(nRate, 0, 10000)
	nRate2 = LIMIT(nRate2, 0, 10000)
ENDIF

; 1目盛で進むパーセンテージを算出
nScaleRate = MAX(10000 / nScaleNum, 1)

; ゲージの描画ループ（1目盛ずつ色をグラデーションさせながら描画する）
FOR LOCAL, 0, nScaleNum
	IF nRate > 0
		LOCAL:1 = LIMIT( colorLeft_RGB:0 + (colorRigth_RGB:0 - colorLeft_RGB:0) * LOCAL / nScaleNum, 0, 0xFF )
		LOCAL:2 = LIMIT( colorLeft_RGB:1 + (colorRigth_RGB:1 - colorLeft_RGB:1) * LOCAL / nScaleNum, 0, 0xFF )
		LOCAL:3 = LIMIT( colorLeft_RGB:2 + (colorRigth_RGB:2 - colorLeft_RGB:2) * LOCAL / nScaleNum, 0, 0xFF )
		SETCOLOR ((LOCAL:1 * 256 * 256) + (LOCAL:2 * 256) + (LOCAL:3))
	ELSE
		IF nRate2 > 0
			SETCOLOR colorVol2
		ELSE
			; 現在値を超えたので空のゲージ表示になる
			SETCOLOR colorEmpty
		ENDIF
	ENDIF
	PRINT_RECT nPointX, nPointY, nScaleWidht - nPointX, nHeight
	nRate -= nScaleRate
	nRate2 -= nScaleRate
NEXT

IF nLimitOver
	; 最大値を超えて表示する場合の表示処理。もう色は変えない
	WHILE nRate > 0 || nRate2 > 0
		PRINT_RECT nPointX, nPointY, nScaleWidht - nPointX, nHeight
		nRate -= nScaleRate
		nRate2 -= nScaleRate
	WEND
ENDIF

; フォント色を元に戻す
SETCOLOR colorMem

RETURN

;================================================================
; RGBスライダーの生成。（バーっぽく見えるけど実際はボタンの集合体）
;--------------------------------
;	nBaseColor	: 基準となるカラー値
;================================================================
@PRINT_RGB_SLIDER( nBaseColor )
#LOCALSIZE 4
#DIM nBaseColor

#DIM nColorBuf
#DIM color_RGB, 3
#DIM nSelectMark
#DIM loopColor
#DIM loopRGB
#DIM colorMem
#DIMS strFontMem

colorMem = GETCOLOR()
strFontMem = %GETFONT()%
nColorBuf = nBaseColor

SIF LINEISEMPTY() == 0
	PRINTFORML

color_RGB:0 = nColorBuf / 256 / 256
color_RGB:1 = nColorBuf / 256 % 256
color_RGB:2 = nColorBuf % 256

SETFONT "ＭＳ ゴシック"
FOR loopRGB, 0, 3
	SELECTCASE loopRGB
		CASE 0
			; R値を変更
			PRINTFORM %" Ｒ値: "%
		CASE 1
			; G値を変更
			PRINTFORM %" Ｇ値: "%
		CASE 2
			; B値を変更
			PRINTFORM %" Ｂ値: "%
	ENDSELECT
	FOR loopColor, 0, 65
		; 0x00～0xFF（0x04刻み）
		nSelectMark = 0
		LOCAL:1 = color_RGB:0
		LOCAL:2 = color_RGB:1
		LOCAL:3 = color_RGB:2
		SELECTCASE loopRGB
			CASE 0
				; R値を変更
				LOCAL:1 = LIMIT(loopColor * 0x04, 0x00, 0xFF)
				SIF loopColor == ((color_RGB:0 + 3) / 0x04)
					nSelectMark = 1
			CASE 1
				; G値を変更
				LOCAL:2 = LIMIT(loopColor * 0x04, 0x00, 0xFF)
				SIF loopColor == ((color_RGB:1 + 3) / 0x04)
					nSelectMark = 1
			CASE 2
				; B値を変更
				LOCAL:3 = LIMIT(loopColor * 0x04, 0x00, 0xFF)
				SIF loopColor == ((color_RGB:2 + 3) / 0x04)
					nSelectMark = 1
		ENDSELECT
		LOCAL = (LOCAL:1 * 256 * 256) + (LOCAL:2 * 256) + (LOCAL:3)
		SETCOLOR LOCAL
		; 半角サイズの■ボタン。番号はそのカラー値を使用する
		IF nSelectMark == 0
			PRINTBUTTON @"%UNICODE(0x2588)%", LOCAL
		ELSE
			PRINTBUTTON @"%UNICODE(0x2593)%", LOCAL
		ENDIF
	NEXT
	PRINTL
	RESETCOLOR
NEXT

; フォント,色を元に戻す
SETCOLOR colorMem
SETFONT strFontMem

RETURN

;================================================================
; HSBスライダーの生成。（バーっぽく見えるけど実際はボタンの集合体）
;
; ※ MEMO 同じ位置を連続で押下した時に、押下する度に色が変化してしまうことがある。
;		ボタンの集合体で表現しているため、中間の値を表示できないことが原因？
;		（ボタン65個に対して、彩度,明度は0～255、色相は0～360）
;--------------------------------
;	nBaseColor	: 基準となるカラー値
;================================================================
@PRINT_HSB_SLIDER( nBaseColor )
#LOCALSIZE 4
#DIM nBaseColor

#DIM nColorBuf
#DIM color_RGB, 3
#DIM color_RGB_Max
#DIM color_RGB_Min
#DIM color_HSB, 3
#DIM arrBuf_HSB, 3
#DIM nSelectMark
#DIM loopColor
#DIM loopHSB
#DIM colorMem
#DIMS strFontMem
; color_HSB		: 渡された色のHSB値を保持する。[0]:色相, [1]:彩度, [2]:明度
; color_RGB_Max	: 渡された色のRGB成分の内、最大の値を保持する。
; color_RGB_Min	: 渡された色のRGB成分の内、最小の値を保持する。

colorMem = GETCOLOR()
strFontMem = %GETFONT()%
nColorBuf = nBaseColor

SIF LINEISEMPTY() == 0
	PRINTFORML

color_RGB:0 = nColorBuf / 256 / 256
color_RGB:1 = nColorBuf / 256 % 256
color_RGB:2 = nColorBuf % 256
; RGB成分の内、最大,最小の成分を確認
color_RGB_Max = MAX( color_RGB:0, color_RGB:1, color_RGB:2 )
color_RGB_Min = MIN( color_RGB:0, color_RGB:1, color_RGB:2 )

; 色相の算出
IF color_RGB_Max == color_RGB_Min
	color_HSB:0 = 0
ELSE
	IF (color_RGB_Max == color_RGB:1)
		color_HSB:0 = 60 * (color_RGB:2 - color_RGB:0) / (color_RGB_Max - color_RGB_Min) + 120
	ELSEIF (color_RGB_Max == color_RGB:2)
		color_HSB:0 = 60 * (color_RGB:0 - color_RGB:1) / (color_RGB_Max - color_RGB_Min) + 240
	ELSEIF (color_RGB_Max == color_RGB:0)
		color_HSB:0 = 60 * (color_RGB:1 - color_RGB:2) / (color_RGB_Max - color_RGB_Min)
		SIF color_HSB:0 < 0
			color_HSB:0 = color_HSB:0 + 360
	ELSE
	ENDIF
ENDIF
color_HSB:0 = LIMIT(color_HSB:0, 0, 359)

; 彩度の算出
IF color_RGB_Max == color_RGB_Min
	color_HSB:1 = 0
ELSE
	color_HSB:1 = 0xFF * (color_RGB_Max - color_RGB_Min) / color_RGB_Max
ENDIF

; 明度の算出
color_HSB:2 = color_RGB_Max

SETFONT "ＭＳ ゴシック"
FOR loopHSB, 0, 3
	SELECTCASE loopHSB
		CASE 0
			; 色相を変更
			PRINTFORM %" 色相: "%
		CASE 1
			; 彩度を変更
			PRINTFORM %" 彩度: "%
		CASE 2
			; 明度を変更
			PRINTFORM %" 明度: "%
	ENDSELECT
	FOR loopColor, 0, 65
		; 0～255（4刻み）
		nSelectMark = 0
		arrBuf_HSB:0 = color_HSB:0
		arrBuf_HSB:1 = color_HSB:1
		arrBuf_HSB:2 = color_HSB:2
		SELECTCASE loopHSB
			CASE 0
				; 色相を変更
				arrBuf_HSB:0 = LIMIT( loopColor * 4 * 360 / 256, 0, 360 )
				IF loopColor == ((10 * color_HSB:0 * 256 / 360 + 15) / 10 / 4)
					nSelectMark = 1
					arrBuf_HSB:0 = color_HSB:0
				ENDIF
			CASE 1
				; 彩度を変更
				arrBuf_HSB:1 = LIMIT( loopColor * 4, 0x00, 0xFF )
				IF loopColor == ((color_HSB:1 + 3) / 4)
					nSelectMark = 1
					arrBuf_HSB:1 = color_HSB:1
				ENDIF
			CASE 2
				; 明度を変更
				arrBuf_HSB:2 = LIMIT( loopColor * 4, 0x00, 0xFF )
				IF loopColor == ((color_HSB:2 + 3) / 4)
					nSelectMark = 1
					arrBuf_HSB:2 = color_HSB:2
				ENDIF
		ENDSELECT
		; 色の算出式は色相によって変わる
		color_RGB_Max = LIMIT( arrBuf_HSB:2, 0, 255 )
		color_RGB_Min = LIMIT( color_RGB_Max - (arrBuf_HSB:1 * color_RGB_Max / 0xFF), 0, 255 )
		SELECTCASE arrBuf_HSB:0
			CASE 0 TO 59
				LOCAL:1 = color_RGB_Max
				LOCAL:2 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (arrBuf_HSB:0) / 60)
				LOCAL:3 = color_RGB_Min
			CASE 60 TO 119
				LOCAL:1 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (120 - arrBuf_HSB:0) / 60)
				LOCAL:2 = color_RGB_Max
				LOCAL:3 = color_RGB_Min
			CASE 120 TO 179
				LOCAL:1 = color_RGB_Min
				LOCAL:2 = color_RGB_Max
				LOCAL:3 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (arrBuf_HSB:0 - 120) / 60)
			CASE 180 TO 239
				LOCAL:1 = color_RGB_Min
				LOCAL:2 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (240 - arrBuf_HSB:0) / 60)
				LOCAL:3 = color_RGB_Max
			CASE 240 TO 299
				LOCAL:1 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (arrBuf_HSB:0 - 240) / 60)
				LOCAL:2 = color_RGB_Min
				LOCAL:3 = color_RGB_Max
			CASE 300 TO 360
				LOCAL:1 = color_RGB_Max
				LOCAL:2 = color_RGB_Min
				LOCAL:3 = color_RGB_Min + ((color_RGB_Max - color_RGB_Min) * (360 - arrBuf_HSB:0) / 60)
		ENDSELECT
		; 同じ位置を押下しても色が変わっていってしまう。緩和策として0x04区切りに直す
		LOCAL:1 = LIMIT( (LOCAL:1 + 3) / 0x04 * 0x04, 0, 255 )
		LOCAL:2 = LIMIT( (LOCAL:2 + 3) / 0x04 * 0x04, 0, 255 )
		LOCAL:3 = LIMIT( (LOCAL:3 + 3) / 0x04 * 0x04, 0, 255 )
		LOCAL = (LOCAL:1 * 256 * 256) + (LOCAL:2 * 256) + (LOCAL:3)
		SETCOLOR LOCAL
		; 半角サイズの■ボタン。番号はそのカラー値を使用する
		IF nSelectMark == 0
			PRINTBUTTON @"%UNICODE(0x2588)%", LOCAL
		ELSE
			PRINTBUTTON @"%UNICODE(0x2593)%", LOCAL
		ENDIF
	NEXT
	PRINTL
	RESETCOLOR
NEXT

; フォント,色を元に戻す
SETCOLOR colorMem
SETFONT strFontMem

RETURN

;================================================================
; カラースライダー二つを表示してピックできるなにか
; サンプルは色のサンプルリスト 0x形式でコンマ区切り
;================================================================
@COLOR_PICKER(初期色 = -1, サンプル文字列 = "")
#DIM 初期色
#DIM 色
#DIMS サンプル文字列
#DIM サンプル, 15
#DIM サンプル数
#DIM FIRST_LINE

CALL SINGLE_DRAWLINE()

FIRST_LINE = LINECOUNT

VARSET サンプル数, 0

IF サンプル文字列 != ""
	SPLIT サンプル文字列, ",", RESULTS
	サンプル数 = RESULT
	FOR LOCAL, 0, サンプル数
		サンプル:LOCAL = TOINT(RESULTS:LOCAL)
	NEXT
ENDIF

色 = 初期色 == -1 ? 0 # 初期色

; スライダー操作ループ
WHILE 1
	REDRAW 0
	SIF LINECOUNT > FIRST_LINE
		CLEARLINE LINECOUNT - FIRST_LINE

	色 = LIMIT( 色, 0x000000, 0xFFFFFF )

	PRINTFORM 現在のカラー：0x%TOSTR(色, "X6")%
	SETCOLOR 色
	PRINTFORML ■
	RESETCOLOR

	; RGBスライダー（実際はボタンの集合体）を表示する
	PRINTFORML RGBスライダー
	CALL PRINT_RGB_SLIDER( 色 )
	PRINTL

	; HSBスライダー（実際はボタンの集合体）を表示する
	PRINTFORML HSBスライダー
	CALL PRINT_HSB_SLIDER( 色 )
	PRINTL

	IF サンプル数 > 0
		PRINTFORM その他の色 :
		FOR LOCAL, 0, サンプル数
			LOCAL:1 = サンプル:(LOCAL)
			SETCOLOR LOCAL:1
			PRINTBUTTON @"■", LOCAL:1
			PRINTFORM
			RESETCOLOR
		NEXT
		PRINTL
	ENDIF

	IF 初期色 != -1
		PRINTFORML   最初の色 :
		SETCOLOR 初期色
		PRINTBUTTON @"■", 初期色
		RESETCOLOR
		PRINTL
	ENDIF

	PRINTBUTTON "[戻る]", -1

	; 入力待機（RGBスライダー,HSBスライダーのボタンの値が色を示す値になっている）
	REDRAW 1
	INPUT

	SIF RESULT == -1
		BREAK

	色 = RESULT
WEND

RETURN 色