code:
;-------------------------------------------------
;;; 指定された定義名のトークンが存在するか
;-------------------------------------------------
@CC_SP_TOKEN_IS_EXIST(TOKEN_NAME)
#FUNCTION
#DIMS DYNAMIC TOKEN_NAME
RETURNF XML_GET(XMLID_TOKEN, @"//defname[@parentname='%TOKEN_NAME%']") > 0

;-------------------------------------------------
;;; トークン数の取得
;-------------------------------------------------
@CC_SP_TOKEN_NUM(ACTOR_DID, TOKEN_NAME)
#FUNCTION
#DIM  DYNAMIC ACTOR_DID
#DIMS DYNAMIC TOKEN_NAME

RETURNF DT_CELL_GET("CC_SP_TOKEN_NUM", ACTOR_DID, TOKEN_NAME, 1)

;-------------------------------------------------
;;; 指定値でのトークン付与
;-------------------------------------------------
@CC_SET_SP_TOKEN(ACTOR_DID, TOKEN_NAME, VALUE)
#DIM  DYNAMIC ACTOR_DID
#DIMS DYNAMIC TOKEN_NAME
#DIM  DYNAMIC VALUE

DT_CELL_SET "CC_SP_TOKEN_NUM", ACTOR_DID, TOKEN_NAME, VALUE, 1

;-------------------------------------------------
;;; トークンの加算処理
;-------------------------------------------------
@CC_ADD_SP_TOKEN(ACTOR_DID, TOKEN_NAME, VALUE)
#DIM  DYNAMIC ACTOR_DID
#DIMS DYNAMIC TOKEN_NAME
#DIM  DYNAMIC VALUE
#DIM DYNAMIC TOKEN_COUNT

SIF VALUE < 0
    THROW 正の値を与えてください

TOKEN_COUNT = CC_SP_TOKEN_NUM(ACTOR_DID, TOKEN_NAME) + VALUE
CALL CC_SET_SP_TOKEN(ACTOR_DID, TOKEN_NAME, TOKEN_COUNT)

;-------------------------------------------------
;;; トークンの減算処理
;-------------------------------------------------
@CC_SUB_SP_TOKEN(ACTOR_DID, TOKEN_NAME, VALUE)
#DIM  ACTOR_DID
#DIMS TOKEN_NAME
#DIM  VALUE
#DIM TOKEN_COUNT
DEBUGPRINTFORML CC_SUB_SP_TOKEN({ACTOR_DID}, %TOKEN_NAME%, {VALUE})
DEBUGPRINTFORML %DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "CHARA_NAME", 1)%
SIF VALUE < 0
    THROW 正の値を与えてください

TOKEN_COUNT = CC_SP_TOKEN_NUM(ACTOR_DID, TOKEN_NAME) - VALUE
SIF !CC_SP_TOKEN_ALLOW_MINUS(TOKEN_NAME)
    TOKEN_COUNT = MAX(TOKEN_COUNT, 0)

CALL CC_SET_SP_TOKEN(ACTOR_DID, TOKEN_NAME, TOKEN_COUNT)

;-------------------------------------------------
;;; トークン個数がマイナス値を許容するか
;-------------------------------------------------
@CC_SP_TOKEN_ALLOW_MINUS(TOKEN_NAME)
#FUNCTION
#DIMS TOKEN_NAME
#DIMS DYNAMIC ALLOW_MINUS_VALUE

XML_GET XMLID_TOKEN, @"//defname[@parentname='%TOKEN_NAME%']/allowMinusValue", ALLOW_MINUS_VALUE, 1
RETURNF TOINT(ALLOW_MINUS_VALUE)

;-------------------------------------------------
;;; トークンパッシブスキル実行
;;;  - 処理順はCC_SP_TOKEN_NUMテーブルをTOKEN_PRIORITY配列の順番に作成している
;-------------------------------------------------
@CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL(EXECUTE_AT, ACTOR_DID, OPPORNENT_DID = -1, SOURCE_ACTION_DID = -1)
#DIMS DYNAMIC EXECUTE_AT
#DIM DYNAMIC ACTOR_DID
#DIM DYNAMIC OPPORNENT_DID
#DIM DYNAMIC SOURCE_ACTION_DID

#DIMS DYNAMIC PARENT_TOKEN_NAMES, SP_TOKEN_MAX_TYPE
#DIM  DYNAMIC TOKEN_TYPE_NUM
#DIM  DYNAMIC TOKEN_NUM
#DIMS DYNAMIC PARENT_TOKEN_NAME
#DIM DYNAMIC SKILL_COUNT
#DIM DYNAMIC SKILL_DID, SP_TOKEN_MAX_SKILL
#DIMS DYNAMIC FUNC_NAME
#DIM DYNAMIC TRIGGER_CHANCE
#DIMS DYNAMIC TRIGGER_CONDITION
#DIM DYNAMIC ITER_I
#DIM DYNAMIC ITER_J

TOKEN_TYPE_NUM = DT_COLUMN_NAMES("CC_SP_TOKEN_NUM")
ARRAYCOPY "RESULTS", "PARENT_TOKEN_NAMES"
;DEBUGPRINTFORML ------------------------------------------------------------
;DEBUGPRINTFORML CC_EXEC_SP_TOKEN_PASSIVE_SKILL EXECUTE_AT_%EXECUTE_AT%
;DEBUGPRINTFORML %DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "CHARA_NAME", 1)%
FOR ITER_I, 1, TOKEN_TYPE_NUM
    PARENT_TOKEN_NAME = %PARENT_TOKEN_NAMES:ITER_I%

    SIF CC_SP_TOKEN_NUM(ACTOR_DID, PARENT_TOKEN_NAME) == 0
        CONTINUE
    ;DEBUGPRINTFORML %PARENT_TOKEN_NAME% = {CC_SP_TOKEN_NUM(ACTOR_DID, PARENT_TOKEN_NAME)}個
    SKILL_COUNT = DT_SELECT("SP_TOKEN_SKILL_PARAMS", @"PARENT_TOKEN_NAME = '%PARENT_TOKEN_NAME%' AND EXECUTE_AT = '%EXECUTE_AT%'",,SKILL_DID)
    SIF SKILL_COUNT == 0
        CONTINUE
    ;DEBUGPRINTFORML %PARENT_TOKEN_NAME% SKILL_COUNT {SKILL_COUNT}
    FOR ITER_J, 0, SKILL_COUNT
        ;確率発動条件
        TRIGGER_CHANCE = CC_GET_SP_TOKEN_SKILL_PARAMS(SKILL_DID:ITER_J, "TRIGGER_CHANCE")
        ;DEBUGPRINTFORML TRIGGER_CHANCE {TRIGGER_CHANCE}
        SIF TRIGGER_CHANCE != 0 && !PERCENT(TRIGGER_CHANCE)
            CONTINUE
        ;発動条件
        TRIGGER_CONDITION = %CC_GETS_SP_TOKEN_SKILL_PARAMS(SKILL_DID:ITER_J,"TRIGGER_CONDITION")%
        ;DEBUGPRINTFORML TRIGGER_CONDITION %TRIGGER_CONDITION%
        SIF TRIGGER_CONDITION != "" && !TOINT(STRFORM(TRIGGER_CONDITION))
            CONTINUE

        FUNC_NAME = %DT_CELL_GETS("SP_TOKEN_SKILL_PARAMS", SKILL_DID:ITER_J, "FUNC_NAME", 1)%
        TRYCCALLFORM CC_SP_TOKEN_SKILL_%FUNC_NAME%(ACTOR_DID, OPPORNENT_DID, SKILL_DID:ITER_J, SOURCE_ACTION_DID)
            CALL KOJO_XML_COMBAT_BY_TRIGGER_ID(RESULT, "TRIGGER")
            CALL CC_ACTION_MANAGER_("RESOLVE")
        CATCH
            DEBUGPRINTFORML スキル<%FUNC_NAME%>が呼ばれましたが、対応するスキル処理関数が見つかりませんでした
        ENDCATCH
    NEXT
NEXT

CALL CC_ACTION_MANAGER_("RESOLVE")
IF SOURCE_ACTION_DID == -1
    CALL CLOSE_COMBAT_DRAW_WINDOW(ACTOR_DID)
ENDIF

@CC_ABNORMALITY_CHECK_COMMON_TRIGGER_CONDITION(ACTOR_DID)
#FUNCTION
#DIM ACTOR_DID

SIF DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "STATE", 1) == "戦闘不能"
    RETURNF 0
RETURNF 1

@CC_ABNORMALITY_CHECK_ESTRUS_TRIGGER_CONDITION(ACTOR_DID)
#FUNCTION
#DIM ACTOR_DID

SIF DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "STATE", 1) == "戦闘不能"
    RETURNF 0
SIF CC_SP_TOKEN_NUM(ACTOR_DID, "ESTRUS") <= 2
    RETURNF 0
SIF RAND:10 >= CC_SP_TOKEN_NUM(ACTOR_DID, "ESTRUS")
    RETURNF 0

RETURNF 1

;-------------------------------------------------
;;; トークン用ターゲティング
;-------------------------------------------------
;攻撃側、防御側決定
;RESULT:0 攻撃側リスト(MEM_LIST1)
;RESULT:1 防御側リスト(MEM_LIST2)
;ACTOR, ACTOR番のキャラが行動する
;-------------------------------------------------
; #region @CLOSE_COMBAT_SP_TOKEN_SET_TARGET
@CLOSE_COMBAT_SP_TOKEN_SET_TARGET(ACTOR_DID, SKILL_DID)
#DIM DYNAMIC ACTOR_DID
#DIM DYNAMIC ACTOR_CHARA_ID
#DIM DYNAMIC TARGET_DID
#DIM DYNAMIC TARGETING
#DIM DYNAMIC TARGETING_SIDE
#DIM DYNAMIC DECIDED_TARGETING_SIDE
#DIM DYNAMIC TARGETING_OVERRIDE_FLAG
#DIM DYNAMIC HATE_RATE
#DIM DYNAMIC HP
#DIM DYNAMIC MAX_HP
#DIM DYNAMIC ATTACK
#DIM DYNAMIC MAG
#DIM DYNAMIC SIDE
#DIM DYNAMIC CHARA_ID
#DIM DYNAMIC IS_PLAYABLE

#DIM  DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIMS DYNAMIC TAC_LIST, CC_MAX_MEMBER_NUM

#DIM  DYNAMIC MAX_TARGET
#DIM  DYNAMIC MEM_CNT
#DIM  DYNAMIC TGT_IDX
#DIMS DYNAMIC _LIST_TARGET
#DIM  DYNAMIC PREV_THREAT_POINT
#DIM  DYNAMIC THREAT_POINT
#DIM  DYNAMIC IS_ASCEND

#DIM DYNAMIC SKILL_DID
#DIMS DYNAMIC TARGET_LIST

IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ACTOR_DID, "IS_PLAYABLE", 1)
;キャラクターにセットされている脅威選定ルーチンを取得
;-------------------------------------------------
TARGETING = DT_CELL_GET("CC_ACTOR", ACTOR_DID, "TARGETING", 1)
;トークンによる脅威選定ルーチンの上書き判定
ACTOR_CHARA_ID =  DT_CELL_GET("CC_ACTOR", ACTOR_DID, "CHARA_ID", 1)

IF DT_CELL_GET("SP_TOKEN_SKILL_PARAMS", SKILL_DID, "TARGETING_REQUIRED", 1) == 1
    TARGETING = DT_CELL_GET("SP_TOKEN_SKILL_PARAMS", SKILL_DID, "OVERRIDE_TARGETING", 1)
    TARGETING_SIDE = DT_CELL_GET("SP_TOKEN_SKILL_PARAMS", SKILL_DID, "TARGETING_SIDE", 1)
    TARGETING_OVERRIDE_FLAG = 1
ENDIF

;攻撃対象側を決定
;TARGETING_SIDEの値は0 = 相手
;TARGETING_SIDEの値は1 = 味方
;TARGETING_SIDEの値は-1 = 全員(未実装)
;-------------------------------------------------
SIDE = DT_CELL_GET("CC_ACTOR", ACTOR_DID, "SIDE", 1)
IF TARGETING_SIDE == 1
    DECIDED_TARGETING_SIDE = SIDE
ELSE
    DECIDED_TARGETING_SIDE = SIDE == 0 ? 1 # 0
ENDIF

IF TARGETING == WPN_脅威選定_選択
    CALL CLOSE_COMBAT_TARGET_SELECT(ACTOR_DID, DECIDED_TARGETING_SIDE)
    TARGET_DID = RESULT
    RETURN TARGET_DID
ENDIF

;脅威度の計算とリストの作成
;-------------------------------------------------
MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = {DECIDED_TARGETING_SIDE}",, IDX)
;[挑発]持ちがいる場合は、無作為と同じ脅威選定を行う
;アクティブスキルで脅威選定が上書きされている場合はアクティブスキル側が優先される
FOR LOCAL, 0, MEM_CNT
    {
        IF !TARGETING_OVERRIDE_FLAG
            && !GROUPMATCH(TARGETING
            ,WPN_脅威選定_全体
            ,WPN_脅威選定_性攻撃男向け
            ,WPN_脅威選定_性攻撃女向け
            )
    }
        TARGETING = WPN_脅威選定_無作為
    ENDIF
NEXT
MAX_TARGET = 0
MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = {DECIDED_TARGETING_SIDE}",, IDX)
FOR LOCAL, 0, MEM_CNT
    SIF DT_CELL_GETS("CC_ACTOR", IDX:LOCAL, "STATE", 1) == "戦闘不能"
        CONTINUE
    HATE_RATE = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "HATE_RATE", 1)
    ;<挑発>のトークン持ちは脅威度を15倍
    IF CC_SP_TOKEN_NUM(IDX:LOCAL, "PROVOKE") > 0
        HATE_RATE = HATE_RATE * 15
    ENDIF
    HP     = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "HP", 1)
    MAX_HP = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "MAX_HP", 1)
    ATTACK = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "ATTACK", 1)
    MAG = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "MAG", 1)
    CHARA_ID = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "CHARA_ID", 1)

    SELECTCASE TARGETING
        CASE WPN_脅威選定_高脅威
            THREAT_POINT = ATTACK * 100 * HATE_RATE / 100
        CASE WPN_脅威選定_低脅威
            THREAT_POINT = HATE_RATE * 100 / MAX(ATTACK, 1)
        CASE WPN_脅威選定_低耐久
            THREAT_POINT = MAX_HP * 100 * MAX(HATE_RATE, 1) / 100
        CASE WPN_脅威選定_低HP
            THREAT_POINT = HP * 100 * MAX(HATE_RATE, 1) / 100
        CASE WPN_脅威選定_低割合HP, WPN_脅威選定_高割合HP
            THREAT_POINT = MAX(HP * 100 / MAX_HP, 1) * MAX(HATE_RATE, 1) / 100
        CASE WPN_脅威選定_魔術師
            THREAT_POINT = MAG * 100 * HATE_RATE / 100
        CASE WPN_脅威選定_性攻撃男向け, WPN_脅威選定_性攻撃女向け
            SIF CHARA_ID == -1
                CONTINUE
            THREAT_POINT = HATE_RATE
            THREAT_POINT = FTIMES(THREAT_POINT, 100 + (HAS_SKILL(CHARA_ID, "SEDUCTION", スキル_大分類_性技) * 50))
            SIF CC_SP_TOKEN_NUM(IDX:LOCAL, "CHEST_EXPOSE") > 0
                THREAT_POINT *= 5
            SIF CC_SP_TOKEN_NUM(IDX:LOCAL, "GENITAL_EXPOSE") > 0
                THREAT_POINT *= 5
            SIF CC_SP_TOKEN_NUM(IDX:LOCAL, "ESTRUS") > 0
                THREAT_POINT *= 5
            SIF CC_SP_TOKEN_NUM(IDX:LOCAL, "ORGASM") > 0
                THREAT_POINT *= 10
            SIF CC_SP_TOKEN_NUM(IDX:LOCAL, "STUN") > 0
                THREAT_POINT *= 2
            IF TARGETING == WPN_脅威選定_性攻撃女向け && IS_MALE(CHARA_ID)
                THREAT_POINT = -1
            ELSEIF TARGETING == WPN_脅威選定_性攻撃男向け && IS_FEMALE(CHARA_ID)
                THREAT_POINT = -1
            ENDIF
        CASEELSE
            THREAT_POINT = HATE_RATE
    ENDSELECT
    TAC_LIST:TGT_IDX = %DIC_SET(TAC_LIST:TGT_IDX, "DID", TOSTR(IDX:LOCAL))%
    TAC_LIST:TGT_IDX = %DIC_SET(TAC_LIST:TGT_IDX, "THREAT_POINT", TOSTR(THREAT_POINT))%
    TGT_IDX ++
NEXT
MAX_TARGET = TGT_IDX
TAC_LIST:(TGT_IDX) '= "-1"

; 算出した脅威度に基づくソート
;-------------------------------------------------
SELECTCASE TARGETING
        ;低いほど優先度が高い脅威選定は昇順ソート
    CASE WPN_脅威選定_低耐久,WPN_脅威選定_低HP, WPN_脅威選定_低割合HP
        CALL ARRAYSORT_DIC(TAC_LIST, "THREAT_POINT", 0)
        IS_ASCEND = 1
    CASEELSE
        IF TARGETING != WPN_脅威選定_無作為 || TARGETING != WPN_脅威選定_全体
            CALL ARRAYSORT_DIC(TAC_LIST, "THREAT_POINT", 1)
        ENDIF
ENDSELECT

; 全体攻撃処理
;-------------------------------------------------
IF TARGETING == WPN_脅威選定_全体
    FOR LOCAL, 0, MAX_TARGET
        TARGET_LIST = %LIST_ADD(TARGET_LIST, DIC_GET(TAC_LIST:LOCAL, "DID"))%
    NEXT
    RESULTS = %TARGET_LIST%
    RETURN 1
ENDIF

; 最終的なターゲットの選出
;-------------------------------------------------
IF MAX_TARGET == 0
    TARGET_DID = TOINT(DIC_GET(TAC_LIST:0, "DID"))
ELSE
    FOR LOCAL, 0, MAX_TARGET
        IF LOCAL == 0
            PREV_THREAT_POINT = TOINT(DIC_GET(TAC_LIST:LOCAL,  "THREAT_POINT"))
            _LIST_TARGET = %LIST_ADD(_LIST_TARGET, DIC_GET(TAC_LIST:LOCAL, "DID"))%
        ELSE
            THREAT_POINT = TOINT(DIC_GET(TAC_LIST:LOCAL,  "THREAT_POINT"))
            ;脅威度が同値のキャラがいる場合を考慮して最終的な選出リストをつくる
            IF THREAT_POINT == PREV_THREAT_POINT
                _LIST_TARGET = %LIST_ADD(_LIST_TARGET, DIC_GET(TAC_LIST:LOCAL, "DID"))%
            ELSEIF IS_ASCEND && THREAT_POINT < PREV_THREAT_POINT
                _LIST_TARGET '= ""
                _LIST_TARGET = %LIST_ADD(_LIST_TARGET, DIC_GET(TAC_LIST:LOCAL, "DID"))%
            ELSEIF !IS_ASCEND  &&  THREAT_POINT > PREV_THREAT_POINT
                _LIST_TARGET '= ""
                _LIST_TARGET = %LIST_ADD(_LIST_TARGET, DIC_GET(TAC_LIST:LOCAL, "DID"))%
            ENDIF
        ENDIF
    NEXT
    ;アクティブスキルで脅威選定ルーチンが変更されている場合は確実にそれに従う
    IF TARGETING_OVERRIDE_FLAG
        TARGET_DID = TOINT(LIST_RAND(_LIST_TARGET))
        ;確率85%で最優先目標を狙う。同値の対象がいる場合は同値の対象からランダムに選出
    ELSEIF RAND:100 < 85 && TARGETING != WPN_脅威選定_無作為
        TARGET_DID = TOINT(LIST_RAND(_LIST_TARGET))
    ELSE
        ;上記以外は完全に無作為に選出する
        ;TARGET_DID = TOINT(DIC_GET(TAC_LIST:RAND(0,MAX_TARGET), "DID"))
        ;無作為の場合は敵視の値による重み付け抽選をおこなう
        CALL RAND_WT_INIT()
        FOR LOCAL, 0, MAX_TARGET
            ;THREAT_POINT0の場合重み付け抽選できないので1点加算
            CALL RAND_WT_SET(LOCAL, TOINT(DIC_GET(TAC_LIST:LOCAL, "THREAT_POINT")) + 1)
        NEXT
        TARGET_DID =  TOINT(DIC_GET(TAC_LIST:RAND_WT_RESULT(), "DID"))
    ENDIF
ENDIF
TARGET_LIST = %LIST_ADD(TARGET_LIST, TOSTR(TARGET_DID))%
RESULTS '=  TARGET_LIST

RETURN 1
; #endregion

;-------------------------------------------------
;;; 全員のトークンパッシブスキル実行チェック
;-------------------------------------------------
@CC_SP_TOKEN_TRIGGER_CHECK(EXECUTE_AT)
#DIMS EXECUTE_AT
#DIMS DYNAMIC ACTOR_LIST, CC_MAX_MEMBER_NUM + 1
#DIM ACTOR_DID

CALL CLOSE_COMBAT_SET_ORDER(ACTOR_LIST)

FOR LOCAL, 0, CC_MAX_MEMBER_NUM + 1
    SIF ACTOR_LIST:LOCAL == "-1"
        BREAK

    ACTOR_DID = TOINT(DIC_GET(ACTOR_LIST:LOCAL, "ACTOR_DID"))
    CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL(EXECUTE_AT, ACTOR_DID)
NEXT

CALL CLOSE_COMBAT_DRAW_WINDOW()

;-------------------------------------------------
;;; テーブルの中身をテキスト出力
;-------------------------------------------------
@DEBUG_OUTPUT_TABLE(DATA_TABLE, DESTIONATION = "CONSOLE")
#DIMS DATA_TABLE
#DIMS DYNAMIC COLUMN_NAMES
#DIM DYNAMIC IDX
#DIM DYNAMIC ROW_NUM
#DIMS DYNAMIC TEXT
#DIMS DESTIONATION
#DIMS ROWS, 1000

SIF !DT_EXIST(DATA_TABLE)
    THROW データテーブル%DATA_TABLE%が存在しません

FOR LOCAL, 0, DT_COLUMN_NAMES(DATA_TABLE)
    TEXT += @"%RESULTS:LOCAL%,"
NEXT
TEXT += "\n"
FOR LOCAL, 0, DT_ROW_LENGTH(DATA_TABLE)
    CALL DEBUG_PRINT_ROW(DATA_TABLE, LOCAL)
    TEXT += RESULTS
NEXT

SELECTCASE DESTIONATION
    CASE "CONSOLE"
        SPLIT TEXT, "\n", ROWS
        FOR LOCAL, 0, RESULT
            DEBUGPRINTFORML %ROWS:LOCAL%
        NEXT
    CASE "TEXT_FILE"
        SAVETEXT TEXT, @"sav/datatable_%DATA_TABLE%.txt"
    CASEELSE

ENDSELECT

@DEBUG_PRINT_ROW(DATA_TABLE, ROW_NUM)
#DIMS DATA_TABLE
#DIM ROW_NUM
#DIMS DYNAMIC COLUMN_NAME
#DIMS DYNAMIC TEXT

FOR LOCAL, 0, DT_COLUMN_NAMES(DATA_TABLE)
    COLUMN_NAME = %RESULTS:LOCAL%
    IF DT_COLUMN_EXIST(DATA_TABLE, COLUMN_NAME) == 5	;string
        TEXT += @"%DT_CELL_GETS(DATA_TABLE, ROW_NUM, COLUMN_NAME)%,"
    ELSE
        TEXT += @"{DT_CELL_GET(DATA_TABLE, ROW_NUM, COLUMN_NAME)},"
    ENDIF
NEXT
TEXT += "\n"

RESULTS '= TEXT


code:
;-------------------------------------------------
;;; トークン関連の処理
;-------------------------------------------------
;-------------------------------------------------
;;; 状態異常系トークンの付与判定
;-------------------------------------------------
@CC_CHECK_REGIST(ATTACKER_DID, DEFENDER_DID, TOKEN_NAME, SUCCESS_RATE)
#FUNCTION
#DIM  ATTACKER_DID
#DIM  DEFENDER_DID
#DIMS TOKEN_NAME
#DIM  SUCCESS_RATE
#DIM  DYNAMIC REGIST
#DIM  DYNAMIC TOKEN_DID

IF DT_COLUMN_EXIST("CC_ACTOR", @"REGIST_%TOKEN_NAME%")
    REGIST = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, @"REGIST_%TOKEN_NAME%", 1)
ELSE
    DEBUGPRINTFORM  @CC_CHECK_REGIST 指定されたトークン名%TOKEN_NAME%に対応する抵抗値が未定義です
    REGIST = 0
ENDIF
;;防御側トークンによる補正(補正量はトークン定義から取得すべきであり、あまり良い実装ではない。暫定)
;耐性系トークン
IF CC_SP_TOKEN_NUM(DEFENDER_DID, @"REGIST_%TOKEN_NAME%") > 0
    REGIST += 60
ENDIF

RETURNF RAND:100 < SUCCESS_RATE - REGIST

;-------------------------------------------------
;;; トークンの取得
;-------------------------------------------------
@CC_GET_TOKEN(ACTOR_DID, TOKEN_NAME)
#FUNCTION
#DIM  ACTOR_DID
#DIMS TOKEN_NAME

RETURNF DT_CELL_GET("CC_ACTOR", ACTOR_DID, TOKEN_NAME, 1)

;-------------------------------------------------
;;; 指定値でのトークン付与
;-------------------------------------------------
@CC_SET_TOKEN(ACTOR_DID, TOKEN_NAME, VALUE)
#DIM  ACTOR_DID
#DIMS TOKEN_NAME
#DIM  VALUE

DT_CELL_SET "CC_ACTOR", ACTOR_DID, TOKEN_NAME, VALUE, 1

;-------------------------------------------------
;;; トークンの加減処理
;-------------------------------------------------
@CC_CHANGE_TOKEN(ACTOR_DID, TOKEN_NAME, VALUE)
#DIM  ACTOR_DID
#DIMS TOKEN_NAME
#DIM  VALUE

VARI TOKEN_COUNT
TOKEN_COUNT = DT_CELL_GET("CC_ACTOR", ACTOR_DID, TOKEN_NAME, 1)
TOKEN_COUNT = MAX(TOKEN_COUNT + VALUE, 0)
CALL CC_SET_TOKEN(ACTOR_DID, TOKEN_NAME, TOKEN_COUNT)

repo_name: pervysquirrelz/erafl

license: unknown


code:
#DIM CONST CC_MAX_MEMBER_NUM = 12
#DIM CONST WND_ID_LEFT   = 0
#DIM CONST WND_ID_RIGHT  = 1
#DIM CONST WND_ID_BOTTOM = 2
#DIMS CC_MES_LIST, 200
#DIM  CC_DAMAGE

#DIM  CC_NUMBER_OF_NORMAL_ATTACKS
#DIM  CC_NORMAL_ATTACK_BASE_DAMAGE_RATE
#DIM  CC_NORMAL_ATTACK_BASE_CRITICAL_RATE
#DIM  CC_NORMAL_ATTACK_BASE_CRITICAL_DAMAGE_RATE
#DIM  CC_FLAG_NORMAL_ATTACK_ALL

#DIM  CC_NORMAL_ATTACK_DAMAGE_MODIFIER
#DIM  CC_NORMAL_ATTACK_CRITICAL_RATE_MODIFIER
#DIM  CC_NORMAL_ATTACK_CRITICAL_DAMAGE_MODIFIER

#DIM  CC_通常攻撃最終ダメージ補正
#DIM  CC_攻撃回数
#DIM  CC_クリティカル率
#DIM  CC_クリティカルダメージ倍率
#DIM  CC_クリティカルフラグ
#DIM  CC_全体攻撃フラグ ;攻撃可能な全ターゲットを対象に攻撃処理を実施
#DIM  CC_ダメージ処理非実施フラグ ;スキル発動のみでダメージ処理を実施しない
#DIM  CC_全対象スキル処理フラグ ;全対象に対して個別にスキルを発動する
#DIMS CC_MULTI_TARGET_LIST
#DIMS CONST CC_COLLATERAL_DAMAGE_TARGET_MAP = "CC_COLLATERAL_DAMAGE_TARGET_MAP"
#DIM  CC_ATTACKED_COUNT
#DIM  CC_MULTI_TARGET_ATTACKED_COUNT
#DIM  CC_入力受付待ち ;スキルの対象選択時など特定の入力が必須の場合、このフラグを立てる
#DIMS CC_SE ;メッセージウィンドウ描画時に効果音を鳴らす

;リストの末尾に"-1"を付加するため最大メンバー数+1を要素数として定義
#DIMS CC_ATTACKER_LIST, CC_MAX_MEMBER_NUM / 2 + 1
#DIMS CC_DEFENDER_LIST, CC_MAX_MEMBER_NUM / 2 + 1
;一時使用武器用のリスト
#DIMS _DIC_CC_TEMP_WEAPON, MAX_CHARANUM
;スキル関数を指定して直接スキル処理を呼び出すための関数
#DIMS CC_LIST_SKILL_FUNC_CALLEE
#DIM  CC_スキル再発動
#DIM  CC_再発動元スキルスロット
;戦闘画面のボタンID管理
;アクティブスキル発動ボタン(1-2桁:スロット番号,3-6桁:CHARA_ID)
#DIM CONST ACTIVE_SKILL_BTN_ID = 1000000
;戦闘画面のフロー制御
#DIMS CC_FLOW
#DIM  CC_ROUND_COUNT
#DIM  CC_FORCE_END
#DIM  CC_AUTO_MODE					;0=マニュアル、1=通常攻撃オート、2=スキルオート
#DIM SAVEDATA CC_AUTO_MODE_INPUT ;0=通常攻撃、1=スキル
#DIM SAVEDATA CC_AUTO_INPUT_WAIT = 200		;オート入力待ち時間 200=通常, 133=1.5倍速, 100=2倍速

;操作可能なフラグ関連
#DIMS CC_FLAG_DIC
;フラグ一覧
#DIMS CONST LINE_CHAN = "LINE_CHAN"
#DIMS CONST FIRST_STRIKE = "FIRST_STRIKE"
{
  #DIMS CONST CC_FLAG_DIC_KEYS = LINE_CHAN, FIRST_STRIKE
}
;アクションスタック
#DIM CONST CC_MAX_ACTION = 1000
;-------------------------------------------------
; 描画関連
;-------------------------------------------------
;キャラ選択ボタン用GID
#DIM  CC_BTN_RECT1_GID = 10000
#DIM  CC_BTN_RECT2_GID = 10001
#DIMS CC_MEM_SERECT_BTN_SRC, CC_MAX_MEMBER_NUM

#DIM  CC_TOKEN_ICONS_GID = 10010


code:
;-------------------------------------------------
;攻撃処理
;-------------------------------------------------
@CLOSE_COMBAT_ATTACK(ATTACKER_DID, DEFENDER_DID)
#DIM ACTION_DID
#DIM ATTACKER_DID
#DIM DEFENDER_DID
#DIM CHARA_ID
#DIM CONST ダメージ基準倍率 = 80
#DIM DYNAMIC ATTACK_COUNT
#DIM DYNAMIC USE_ON_ATTACK_ACTIVE_SKILL
;キャラ情報
#DIMS DYNAMIC ATK_CHARA_NAME
#DIMS DYNAMIC DEF_CHARA_NAME
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
#DIM DYNAMIC IS_PLAYABLE
#DIM DYNAMIC HP
#DIM DYNAMIC MAX_HP
#DIM DYNAMIC TOKEN_COUNT
#DIMS DYNAMIC ATK_LIST
#DIMS DYNAMIC DEF_LIST
#DIM DYNAMIC  ATK_SELECT_SLOT = -1
#DIM DYNAMIC  DEF_SELECT_SLOT = -1
#DIMS DYNAMIC SKILL_DEF_NAME
#DIMS DYNAMIC ATK_ENEMY_SELECT_SKILL
#DIMS DYNAMIC DEF_ENEMY_SELECT_SKILL
;武器情報
#DIM  DYNAMIC ATK_WEAPON_DID
#DIM  DYNAMIC DEF_WEAPON_DID
#DIMS DYNAMIC DIC_WPN_SKILL
#DIM  DYNAMIC WPN_SKILLNUM
#DIMS DYNAMIC WPN_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")

#DIM DYNAMIC LIST_LENGTH
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC ATK_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIMS DYNAMIC DEF_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")

#DIM CONST POISON_DAMAGE = 300
#DIM CONST BURN_DAMAGE = 150
#DIM CONST BEARTRAP_DAMAGE = 300

CC_DAMAGE = 0
ATK_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "CHARA_NAME", 1)%
DEF_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", DEFENDER_DID, "CHARA_NAME", 1)%
ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)

;攻撃側の処理
IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "IS_PLAYABLE", 1)
;操作可能キャラの場合
IF IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:ATK_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "ATK_SKILL_DEF_LIST"
    ATK_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", 1)
    CALL GET_WEAPON_LIST_IDX_BY_CHARA_ID(ATK_CHARA_ID)
    SIF RESULT
        ATK_WEAPON_DID = RESULT:1
ELSE
    ATK_ENEMY_SELECT_SKILL = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", 1)%
ENDIF

;防御側の処理
IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "IS_PLAYABLE", 1)
;操作可能キャラの場合
IF IS_PLAYABLE == 1
    CALL DIC_KEYS(_DIC_SKILL_LIST:DEF_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "DEF_SKILL_DEF_LIST"
    DEF_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "SELECTED_SKILL_SLOT", 1)
    CALL GET_WEAPON_LIST_IDX_BY_CHARA_ID(DEF_CHARA_ID)
    SIF RESULT
        DEF_WEAPON_DID = RESULT:1
ELSE
    DEF_ENEMY_SELECT_SKILL = %DT_CELL_GETS("CC_ACTOR", DEFENDER_DID, "ENEMY_SELECTED_SKILL", 1)%
ENDIF

;ステートの変更
;-------------------------------------------------
DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "STATE", "攻撃", 1

;攻撃処理の実行可否判定（スタンなどを処理）
;-------------------------------------------------
CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("ABNORMALITY_CHECK", ATTACKER_DID)

IF GROUPMATCH(DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "STATE", 1), "戦闘不能", "行動不能")
    DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SUBSTATE", "", 1
    RETURN 0
ENDIF

;防御処理
VARI ARMOR
VARI BARRIER
IF DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "SUBSTATE", 1) == "防御"
    DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SUBSTATE", "", 1
    ARMOR = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "ARMOR", 1)
    BARRIER = FTIMES(ARMOR, 50)
    CALL CC_ADD_SP_TOKEN(ATTACKER_DID, "BARRIER", BARRIER)
    CALL CC_PRINT(@"%ATK_CHARA_NAME%は守りを固め、@C:{カラー_緑}@{BARRIER}@/C@点の[バリア]を得た")
    CC_SE '= "Guard_0.mp3"
    RETURN 0
ENDIF

IF ATK_SELECT_SLOT != -1
    ;操作可能キャラのON_ATTACKアクティブスキル
    CALL CC_EXEC_ACTIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID)
    IF RESULT
        DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", -1, 1
        ATK_SELECT_SLOT = -1
        RETURN 1
    ENDIF
ELSEIF ATK_ENEMY_SELECT_SKILL != ""
    ;操作不可キャラのON_ATTACKアクティブスキル
    CALL CC_EXEC_ACTIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID, ATK_ENEMY_SELECT_SKILL)
    IF RESULT
        DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", "", 1
        RETURN 1
    ENDIF
ENDIF

;通常攻撃
CALL CC_EXEC_NORMAL_ATTACK(ATTACKER_DID, DEFENDER_DID)

RETURN 1
[SKIPSTART]
CC_ATTACKED_COUNT = 0
WHILE CC_攻撃回数 > CC_ATTACKED_COUNT
    USE_ON_ATTACK_ACTIVE_SKILL = 0
    IF CC_ATTACKED_COUNT
        CALL CC_PRINT(@"@S:1@<%ATK_CHARA_NAME%の追撃>@/S@")
    ENDIF
    ;スキル処理前の基礎ダメージ値計算
    ;-------------------------------------------------
    CALL CC_CALC_DAMAGE(ATTACKER_DID, DEFENDER_DID)
    IF ATK_SELECT_SLOT != -1
        ;攻撃側アクティブスキル処理
        ;-------------------------------------------------
        CALL CC_EXEC_ACTIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID)
        IF RESULT && !CC_全対象スキル処理フラグ
            DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", -1, 1
            ATK_SELECT_SLOT = -1
            USE_ON_ATTACK_ACTIVE_SKILL = 1
        ENDIF
    ELSEIF CC_LIST_SKILL_FUNC_CALLEE != ""
        WHILE LIST_COUNT(CC_LIST_SKILL_FUNC_CALLEE) > 0
            CALL CC_EXEC_ACTIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID, LIST_GET(CC_LIST_SKILL_FUNC_CALLEE, 0))
            IF RESULT && !CC_全対象スキル処理フラグ
                USE_ON_ATTACK_ACTIVE_SKILL = 1
            ENDIF
            CC_LIST_SKILL_FUNC_CALLEE = %LIST_REMOVEAT(CC_LIST_SKILL_FUNC_CALLEE, 0)%
        WEND
        CC_スキル再発動 = 0
        CC_再発動元スキルスロット = -1
    ELSEIF ATK_ENEMY_SELECT_SKILL != ""
        CALL CC_EXEC_ACTIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID, ATK_ENEMY_SELECT_SKILL)
        IF RESULT && !CC_全対象スキル処理フラグ
            DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", "", 1
            USE_ON_ATTACK_ACTIVE_SKILL = 1
        ENDIF
    ENDIF
    ; 通常攻撃処理
    IF !CC_全体攻撃フラグ && !USE_ON_ATTACK_ACTIVE_SKILL
        ; -------------------------------------------------
        ;トークン[追撃]による攻撃回数加算、初回通常攻撃処理時に攻撃回数を1加算
        SIF CC_ATTACKED_COUNT == 0 && CC_SP_TOKEN_NUM(ATTACKER_DID, "ADD_ATTACK") > 0
            CC_攻撃回数 ++
        ;ダメージ処理前攻撃側パッシブスキル処理
        CALL CC_EXEC_PASSIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID)
        ; 武器パッシブスキル処理
        CALL CC_EXEC_WPN_PASSIVE_SKILL("ON_ATTACK", ATTACKER_DID, DEFENDER_DID)
        ;クリティカルフラグセット
        IF RAND:100 < CC_クリティカル率
            CC_クリティカルフラグ = 1
        ENDIF
        ;効果音セット
        IF CC_SE == ""
            IF CC_クリティカルフラグ
                CC_SE '= @"%S_R("Critical_0")%.mp3"
            ELSE
                CC_SE '= @"%S_R("Slash_0/Slash_1/Slash_2/Slash_3")%.mp3"
            ENDIF
        ENDIF
    ENDIF
    IF !CC_ダメージ処理非実施フラグ
        ;デコイ処理
        IF CC_DAMAGE >= 0
            CALL CC_STATUS_EFFECT_CHECK_DECOY(ATTACKER_DID, DEFENDER_DID)
            IF RESULT
                CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("AFTER_EACH_ATTACKED", DEFENDER_DID, ATTACKER_DID)
                CALL CC_EXEC_PASSIVE_SKILL("COUNTER", DEFENDER_DID, ATTACKER_DID)
                CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("COUNTER", DEFENDER_DID, ATTACKER_DID)
                RETURN 1
            ENDIF
        ENDIF
        IF !CC_全体攻撃フラグ && !USE_ON_ATTACK_ACTIVE_SKILL
            ;通常攻撃時ダメージ処理
            CALL CC_TAKE_DAMAGE(ATTACKER_DID, DEFENDER_DID, 1)
        ELSE
            ;スキル系ダメージ処理
            CALL CC_TAKE_DAMAGE(ATTACKER_DID, DEFENDER_DID, 0)
        ENDIF
        CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("AFTER_EACH_ATTACKED", DEFENDER_DID, ATTACKER_DID)
        CALL CC_EXEC_PASSIVE_SKILL("COUNTER", DEFENDER_DID, ATTACKER_DID)
        CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("COUNTER", DEFENDER_DID, ATTACKER_DID)
    ELSE
        ;CC_ダメージ処理非実施フラグ = 0
    ENDIF
    ;再発動効果を持たない攻撃時発動のアクティブスキルを使用したは攻撃回数に関わらず1度のみ攻撃行動を実行する
    SIF USE_ON_ATTACK_ACTIVE_SKILL && !CC_スキル再発動
        BREAK
    CC_ATTACKED_COUNT ++

    ;反撃等による攻撃側の死亡判定
    CALL CC_CHECK_KNOCKED_OUT(ATTACKER_DID)
    SIF RESULT
        BREAK
WEND

;戦闘不能判定
;-------------------------------------------------
;防御側HP取得
CALL CC_CHECK_KNOCKED_OUT(DEFENDER_DID)
IF RESULT == 1
    CALL CC_EXEC_WPN_PASSIVE_SKILL("DEFEAT_ENEMY", ATTACKER_DID, DEFENDER_DID)
ENDIF
;演出用のパラメータ設定
;-------------------------------------------------
DT_CELL_SET "CC_ACTOR", DEFENDER_DID, "EFFECT", "被ダメージ", 1

RETURN 1
[SKIPEND]

;-------------------------------------------------
; 攻撃開始前の処理
;-------------------------------------------------
; #region @CLOSE_COMBAT_BEFORE_ATTACK
@CLOSE_COMBAT_BEFORE_ATTACK(ATTACKER_DID, DEFENDER_DID)
#DIM ATTACKER_DID
#DIM DEFENDER_DID
#DIM CHARA_ID
;キャラ情報
#DIMS DYNAMIC ATK_CHARA_NAME
#DIMS DYNAMIC DEF_CHARA_NAME
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
#DIM  DYNAMIC ATK_IS_PLAYABLE
#DIM  DYNAMIC DEF_IS_PLAYABLE
#DIM  DYNAMIC HP
#DIM  DYNAMIC TOKEN_COUNT
#DIMS DYNAMIC ATK_LIST
#DIMS DYNAMIC DEF_LIST
#DIM  DYNAMIC ATK_SELECT_SLOT = -1
#DIM  DYNAMIC DEF_SELECT_SLOT = -1
#DIMS DYNAMIC SKILL_DEF_NAME
;武器情報
#DIM  DYNAMIC ATK_WEAPON_DID
#DIM  DYNAMIC DEF_WEAPON_DID
#DIMS DYNAMIC DIC_WPN_SKILL
#DIM  DYNAMIC WPN_SKILLNUM
#DIMS DYNAMIC WPN_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")

#DIM DYNAMIC LIST_LENGTH
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC ATK_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIMS DYNAMIC DEF_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")

;キャラ情報・スキル情報取得
;-------------------------------------------------
ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)
ATK_IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "IS_PLAYABLE", 1)
DEF_IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "IS_PLAYABLE", 1)

IF ATK_IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:ATK_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "ATK_SKILL_DEF_LIST"
    ATK_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", 1)
    CALL GET_WEAPON_LIST_IDX_BY_CHARA_ID(ATK_CHARA_ID)
    SIF RESULT
        ATK_WEAPON_DID = RESULT:1
ENDIF

IF DEF_IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:DEF_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "DEF_SKILL_DEF_LIST"
    DEF_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "SELECTED_SKILL_SLOT", 1)
    CALL GET_WEAPON_LIST_IDX_BY_CHARA_ID(DEF_CHARA_ID)
    SIF RESULT
        DEF_WEAPON_DID = RESULT:1
ENDIF

CALL CC_ACTIVESKILL_NORMAL_ATTACK_INIT(ATTACKER_DID)

;攻撃前アクティブスキル処理
;-------------------------------------------------
IF ATK_SELECT_SLOT != -1
    ;キャラアクティブスキル
    CALL CC_EXEC_ACTIVE_SKILL("BEFORE_ATTACK", ATTACKER_DID, DEFENDER_DID)
    IF RESULT
        DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", -1, 1
    ENDIF
ELSEIF !ATK_IS_PLAYABLE
    ;エネミーアクティブスキル
    SKILL_DEF_NAME = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", 1)%
    IF SKILL_DEF_NAME != ""
        CALL CC_EXEC_ACTIVE_SKILL("BEFORE_ATTACK", ATTACKER_DID, DEFENDER_DID, SKILL_DEF_NAME)
        IF RESULT
            DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", "", 1
        ENDIF
    ENDIF
ELSE
ENDIF

;パッシブスキル処理
;アクティブスキルの発動が予約されている場合パッシブスキルは発動しない
;-------------------------------------------------
IF ATK_IS_PLAYABLE
    ;キャラパッシブスキル
    CALL CC_EXEC_PASSIVE_SKILL("BEFORE_ATTACK", ATTACKER_DID, DEFENDER_DID)
    ; 武器パッシブスキル
    CALL CC_EXEC_WPN_PASSIVE_SKILL("BEFORE_ATTACK", ATTACKER_DID, DEFENDER_DID)
ELSE
    ;エネミーパッシブスキル
    IF SKILL_DEF_NAME == ""
        CALL CC_EXEC_PASSIVE_SKILL("BEFORE_ATTACK", ATTACKER_DID, DEFENDER_DID)
    ENDIF
ENDIF
;ENDIF

; FOR LOCAL, 0, FINDELEMENT(ATK_SKILL_DEF_LIST, "",,, 1)
;     XML_GET XMLID_SKILL_BATTLE, @"//defname[@parentname='%ATK_SKILL_DEF_LIST:LOCAL%']", _XML_SKILL, 3
;     SIF !RESULT
;         CONTINUE
;     XML_GET _XML_SKILL, @"//func[contains(text(), 'BEFORE_ATTACK')]", RESULTS, 1
;     IF RESULT
;         DEBUGPRINTFORML RESULTS = %RESULTS%
;         TRYCCALLFORM CC_%RESULTS%(ATTACKER_DID, DEFENDER_DID, _XML_SKILL)
;         CATCH
;             DEBUGPRINTFORML CAUTION:@CLOSE_COMBAT_ATTACK
;             DEBUGPRINTFORML スキル<%RESULTS%>が呼ばれましたが、対応するスキル処理関数が見つかりませんでした
;         ENDCATCH
;     ENDIF
; NEXT
; #endregion

;-------------------------------------------------
; 攻撃終了後の処理
;-------------------------------------------------
; #region @CLOSE_COMBAT_AFTER_ATTACK
@CLOSE_COMBAT_AFTER_ATTACK(ATTACKER_DID, DEFENDER_DID)
#DIM ATTACKER_DID
#DIM DEFENDER_DID
#DIM CHARA_ID
#DIM CONST ダメージ基準倍率 = 80
;キャラ登録番号
#DIMS DYNAMIC ATK_CHARA_NAME
#DIMS DYNAMIC DEF_CHARA_NAME
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
#DIM  DYNAMIC IS_PLAYABLE
#DIM DYNAMIC HP
#DIM DYNAMIC TOKEN_COUNT
#DIMS DYNAMIC ATK_LIST
#DIMS DYNAMIC DEF_LIST
#DIM DYNAMIC  ATK_SELECT_SLOT = -1
#DIM DYNAMIC  DEF_SELECT_SLOT = -1
#DIMS DYNAMIC SKILL_DEF_NAME

#DIM DYNAMIC LIST_LENGTH
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC ATK_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIMS DYNAMIC DEF_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")

;キャラ情報・スキル情報取得
;-------------------------------------------------
ATK_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "CHARA_NAME", 1)%
DEF_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", DEFENDER_DID, "CHARA_NAME", 1)%
ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)

IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "IS_PLAYABLE", 1)
IF IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:ATK_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "ATK_SKILL_DEF_LIST"
    ATK_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", 1)
ENDIF

IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "IS_PLAYABLE", 1)
IF IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:DEF_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "DEF_SKILL_DEF_LIST"
    DEF_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "SELECTED_SKILL_SLOT", 1)
ENDIF

;攻撃終了後アクティブスキル処理
;-------------------------------------------------
IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "IS_PLAYABLE", 1)
IF ATK_SELECT_SLOT != -1
    CALL CC_EXEC_ACTIVE_SKILL("AFTER_ATTACK", ATTACKER_DID, DEFENDER_DID)
    IF RESULT
        DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", -1, 1
    ENDIF
ELSEIF !IS_PLAYABLE
    SKILL_DEF_NAME = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", 1)%
    IF SKILL_DEF_NAME != ""
        CALL CC_EXEC_ACTIVE_SKILL("AFTER_ATTACK", ATTACKER_DID, DEFENDER_DID, SKILL_DEF_NAME)
        IF RESULT
            DT_CELL_SET "CC_ACTOR", ATTACKER_DID, "ENEMY_SELECTED_SKILL", "", 1
        ENDIF
    ENDIF
ENDIF

;攻撃終了後トークン効果誘発
;-------------------------------------------------
CALL CC_TRIGGER_SP_TOKEN_PASSIVE_SKILL("AFTER_ATTACK", ATTACKER_DID, DEFENDER_DID)

; #endregion

;-------------------------------------------------
; 特殊な状態の処理
;-------------------------------------------------
;被攻撃時のデコイ処理
;デコイが攻撃を受け止めた場合は1を返す
; @CC_STATUS_EFFECT_CHECK_DECOY(ATTACKER_DID, DEFENDER_DID)
; #DIM ATTACKER_DID
; #DIM DEFENDER_DID
; #DIM  DYNAMIC TOKEN_COUNT
; #DIM  DYNAMIC DEF_CHARA_ID
; #DIMS DYNAMIC ATK_CHARA_NAME
; #DIMS DYNAMIC DEF_CHARA_NAME
; #DIM  DYNAMIC SKILL_LV
; #DIM  DYNAMIC EFFECT_RATE
; #DIMS DYNAMIC SKILL_NAME
; #DIM DECOY_SHADOW = 0
; #DIM CHEST_EXPOSE = 0

; DECOY_SHADOW = CC_SP_TOKEN_NUM(DEFENDER_DID, "DECOY_SHADOW")

; ;分身を持つ場合は分身を優先
; IF DECOY_SHADOW
;     TOKEN_COUNT = DECOY_SHADOW
; ELSE
;     TOKEN_COUNT = CC_SP_TOKEN_NUM(DEFENDER_DID, "DECOY")
; ENDIF
; DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)
; ATK_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "CHARA_NAME", 1)%
; DEF_CHARA_NAME = %DT_CELL_GETS("CC_ACTOR", DEFENDER_DID, "CHARA_NAME", 1)%
; IF TOKEN_COUNT > 0
;     ;幻影投影を持っている場合デコイ持続判定を行う
;     SKILL_LV = HAS_SKILL(DEF_CHARA_ID, "WPN_DECOY_AMPLIFIER", スキル_大分類_武器)
;     IF SKILL_LV > 0
;         CALL SKILL_GET_NAME(武器スキル_パッシブ, "WPN_DECOY_AMPLIFIER", 1)
;         SKILL_NAME = %RESULTS%
;         CALL SKILL_GET_EFFECT_RATE(武器スキル_パッシブ, "WPN_DECOY_AMPLIFIER", SKILL_LV, 1)
;         EFFECT_RATE = RESULT
;         IF RAND:100 < EFFECT_RATE
;             IF DECOY_SHADOW
;                 CALL CC_PRINT(@"%ATK_CHARA_NAME%の攻撃を%DEF_CHARA_NAME%の分身が代わりに引き受けた！")
;                 CALL CC_PRINT(@"@C:{カラー_黄緑}@<%SKILL_NAME%> %DEF_CHARA_NAME%の分身はなお形を保っている！@/C@")
;             ELSE
;                 CALL CC_PRINT(@"%ATK_CHARA_NAME%の攻撃を%DEF_CHARA_NAME%のデコイが代わりに引き受けた！")
;                 CALL CC_PRINT(@"@C:{カラー_黄緑}@<%SKILL_NAME%> %DEF_CHARA_NAME%のデコイはなお形を保っている！@/C@")
;             ENDIF
;             ;攻撃自体は成功しているので1を返す
;             RETURN 1
;         ENDIF
;     ENDIF
;     IF DECOY_SHADOW
;         CALL CC_SUB_SP_TOKEN(DEFENDER_DID, "DECOY_SHADOW", 1)
;         CALL CC_PRINT(@"%ATK_CHARA_NAME%の攻撃を%DEF_CHARA_NAME%の分身が代わりに引き受けた！")
;         CALL CC_PRINT(@"分身の一体が霧散した……！")
;     ELSE
;         CALL CC_SET_SP_TOKEN(DEFENDER_DID, "DECOY", 0)
;         CALL CC_PRINT(@"%ATK_CHARA_NAME%の攻撃を%DEF_CHARA_NAME%のデコイが代わりに引き受けた！")
;         CALL CC_PRINT(@"デコイは霧散した……！")
;     ENDIF
;     ;攻撃自体は成功しているので1を返す
;     RETURN 1
; ENDIF
; CHEST_EXPOSE = CC_SP_TOKEN_NUM(DEFENDER_DID, "CHEST_EXPOSE")
; IF CHEST_EXPOSE > 0
; ENDIF
; RETURN 0


code:
;=================================================
;戦闘用のユーザー関数
;各種イベントやクエストから呼ばれる想定
;=================================================

;-------------------------------------------------
;@CC_INIT()
;CC関連の初期化を行う
;-------------------------------------------------
@CC_INIT()
IF DT_EXIST("CC_ACTOR")
    DT_CLEAR "CC_ACTOR"
ENDIF
IF DT_EXIST("CC_SKILL_SLOT")
    DT_CLEAR "CC_SKILL_SLOT"
ENDIF

CALL CREATE_CC_ACTOR_TABLE()
CALL CREATE_CC_SKILL_SLOT_TABLE()
CALL CREATE_CC_SP_TOKEN_NUM_TABLE()

CALL CC_ACTION_MANAGER_("INIT")
VARSET _DIC_CC_TEMP_WEAPON
;武器スキルのクールタイムは開始時に常にリセット
FOR LOCAL, 0, VARSIZE("ACTIVE_SKILL_COOLTIME")
    CVARSET WPN_ACTIVE_SKILL_COOLTIME, LOCAL, 0
NEXT
CC_ROUND_COUNT = 1
CC_FORCE_END = 0

;戦闘で使用するスプライトの初期化
CALL CLOSE_COMBAT_DISPOSE_SPRITE(1)

;戦闘用BGMの再生を停止
;戦闘開始前からBGMが鳴っていた場合はそれを再生する
@CC_STOPBGM()
IF FL_PREVBGM != ""
    CALL  FL_PLAYBGM(FL_PREVBGM)
ELSE
    CALL FL_STOPBGM()
ENDIF

;-------------------------------------------------
; @CC_SET_TEMP_WEAPON()
; 特定のキャラクターに戦闘時のみ一時的に特定の武器を武器を使用させたい場合に使う
; ここにセットされた装備は本来の装備に優先される
; 基本的にはモブキャラ向けを想定しているが、自キャラに一時的に素手を強要したい場合などにも使える
;-------------------------------------------------
@CC_SET_TEMP_WEAPON(CHARA_ID, WEAPON_ID, WEAPON_NAME = "", MATERIAL)
#DIM CHARA_ID
#DIMS WEAPON_NAME
#DIM WEAPON_ID
#DIM MATERIAL

IF WEAPON_NAME == ""
    CALL GET_WEAPON_NAME(WEAPON_ID)
    WEAPON_NAME = %RESULTS%
    WEAPON_NAME '= @"%WPN_材質別接頭文字:MATERIAL%の%WEAPON_NAME%"
ENDIF
_DIC_CC_TEMP_WEAPON:CHARA_ID '= @"[WEAPON_NAME:%WEAPON_NAME%][WEAPON_ID:{WEAPON_ID}][MATERIAL:{MATERIAL}]"

;-------------------------------------------------
;@CC_ADDCHARA
;キャラクターデータを持つキャラクターをキャラ番号指定でメンバーに追加する
;引数:1 "ATTACKER","DEFENDER"のいずれかを指定
;引数:2 キャラ番号
;-------------------------------------------------
@CC_ADDCHARA(SIDE, CHARA_ID)
#DIMS SIDE
#DIM CHARA_ID
#DIM DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIM DYNAMIC MEM_CNT

IF SIDE == "ATTACKER"
    MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = 1",,IDX)
    IF MEM_CNT >= CC_MAX_MEMBER_NUM / 2
        DEBUGPRINTFORML CLOSE_COMBAT:エラー 攻撃側メンバーが上限({CC_MAX_MEMBER_NUM / 2})を超えています
        THROW CLOSE_COMBAT:エラー 攻撃側メンバーが上限を超えています
    ELSE
        CALL CC_SET_CHARADATA(CHARA_ID, 1)
    ENDIF
ELSE
    MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = 0",,IDX)
    IF MEM_CNT >= CC_MAX_MEMBER_NUM / 2
        DEBUGPRINTFORML CLOSE_COMBAT:エラー 防御側メンバーが上限({CC_MAX_MEMBER_NUM / 2})を超えています
        THROW CLOSE_COMBAT:エラー 防御側メンバーが上限を超えています
    ELSE
        CALL CC_SET_CHARADATA(CHARA_ID, 0)
    ENDIF
ENDIF

;-------------------------------------------------
;@CC_ADDPARTY()
;クエストのパーティメンバーを戦闘メンバーに追加する
;引数:1 デフォルトは"ATTACKER"(左：攻撃側)。"ATTACKER","DEFENDER"のいずれかを指定
;-------------------------------------------------
;region @CC_ADDPARTY
@CC_ADDPARTY(SIDE = "ATTACKER")
#DIMS SIDE
FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY)
    CALL CC_ADDCHARA(SIDE, TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL)))
NEXT
;#endregion

;-------------------------------------------------
;@CC_ADDMOB
;キャラクターデータを持たないモブをパラメータを直接指定して戦闘メンバーに追加する
;引数:1 "ATTACKER","DEFENDER"のいずれかを指定
;引数:2 表示する名前を指定
;引数:3 現HPを指定
;引数:4 最大HPを指定
;引数:5 戦闘値を指定
;-------------------------------------------------
@CC_ADDMOB(SIDE, CC_NAME, HP, MAXHP, 戦闘, 魔術 = 0, エリート = 0, 脅威選定 = 0)
#DIMS SIDE
#DIMS CC_NAME
#DIM HP
#DIM MAXHP
#DIM 戦闘
#DIM 魔術
#DIM エリート
#DIM 脅威選定
#DIM DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIM DYNAMIC MEM_CNT

IF SIDE == "ATTACKER"
    MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = 1",,IDX)
    IF MEM_CNT >= CC_MAX_MEMBER_NUM / 2
        DEBUGPRINTFORML CLOSE_COMBAT:エラー 攻撃側メンバーが上限({CC_MAX_MEMBER_NUM / 2})を超えています
        THROW CLOSE_COMBAT:エラー 攻撃側メンバーが上限を超えています
    ELSE
        CALL CC_SET_MOBDATA(1, CC_NAME, HP, MAXHP, 戦闘, 魔術, エリート, 脅威選定)
    ENDIF
ELSE
    MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = 0",,IDX)
    IF MEM_CNT >= CC_MAX_MEMBER_NUM / 2
        DEBUGPRINTFORML CLOSE_COMBAT:エラー 攻撃側メンバーが上限({CC_MAX_MEMBER_NUM / 2})を超えています
        THROW CLOSE_COMBAT:エラー 攻撃側メンバーが上限を超えています
    ELSE
        CALL CC_SET_MOBDATA(0, CC_NAME, HP, MAXHP, 戦闘, 魔術, エリート, 脅威選定)
    ENDIF
ENDIF

;-------------------------------------------------
;;; @CC_ENEMY_DATA または"ENEMY_DATA"テーブルに定義済みのモブを戦闘メンバーに追加する
;;; - ARG
;;; 引数:0 (必須) "ATTACKER","DEFENDER"のいずれかを指定
;;; 引数:1 (必須) @CC_ENEMY_DATA の ENEMY_DEF_NAME
;;; 引数:2 (任意) 戦闘画面の表示上のモブ名。デフォルトはENEMY_NAME
;;; 引数:3 (任意)能力値を補正する場合指定。テーブル定義の能力値に対してn%加算し補正をかける。百分率指定
;;; 引数:4 (任意)オプション辞書  [KEY:VALUE]の辞書形式で指定。各オプションは以下参照
;;; "CHARA_ID" 指定したキャラとテーブルにないパラメータの同期をとる（ポートレイト、衣装状態など） 。戦闘用パラメータはテーブルの値より参照
;;; "HP"など"CC_ACTOR" に含まれるパラメータを指定することで、パラメータを上書き可能
;;;   -  ENEMY_PASSIVE_SKILL と ENEMY_ACTIVE_SKILL は入れ子対策のため`[ENEMY_PASSIVE_SKILL:<SMITE;1><MANA_SMITE;1>]`形式で与えてください
;;; - RETURN
;;; RESULT:0 データテーブル上のID
;;;-------------------------------------------------
@CC_ADDMOB_FROM_TABLE(SIDES, ENEMY_DEF_NAME, CC_NAME = "", 能力値補正率 = 0, DIC_OPTIONS)
#DIMS ENEMY_DEF_NAME
#DIMS CC_NAME
#DIM  能力値補正率
#DIMS SIDES
#DIM  SIDE
#DIM  PLACEMENT
#DIM  ステータス補正
#DIMS DIC_OPTIONS
#DIM  DYNAMIC ID
#DIM  ACTOR_DID
#DIM  COLUMN_NUM
#DIMS COLUMNS, 1000
#DIMS DIC_SKILL

;戦闘開始時の補正ステータス
#DIM  DYNAMIC 最大HP
#DIM  DYNAMIC 攻撃力
#DIM  DYNAMIC 魔力
#DIM  DYNAMIC 防御力
#DIM  DYNAMIC 軽減値
#DIM  DYNAMIC 行動力
#DIM  DYNAMIC 最大HP補正率
#DIM  DYNAMIC 攻撃力補正率
#DIM  DYNAMIC 魔力補正率
#DIM  DYNAMIC 防御力補正率
#DIM  DYNAMIC 軽減値補正率
#DIM  DYNAMIC 行動力補正率
#DIM  DYNAMIC CHARA_ID
#DIM  DYNAMIC SHOW_PORTRAIT

DT_SELECT "ENEMY_DATA", @"ENEMY_DEF_NAME = '%ENEMY_DEF_NAME%'"
IF RESULT < 1
    DEBUGPRINTFORML @CC_ADDMOB_FROM_TABLE エラー：指定されたエネミー定義"%ENEMY_DEF_NAME%"は存在しません
    RETURN 0
ELSE
    ID = RESULT:1
ENDIF

IF SIDES == "ATTACKER" || SIDES == "DEFENDER"
    SIDE = SIDES == "ATTACKER" ? 1 # 0
ELSE
    SIDE = TOINT(SIDES)
ENDIF
;位置情報　仮仕様で登録順
PLACEMENT = DT_SELECT("CC_ACTOR", @"SIDE = {SIDE}")

IF CC_NAME == ""
    CC_NAME = %DT_CELL_GETS("ENEMY_DATA", ID, "ENEMY_NAME", 1)%
ENDIF

最大HP補正率 = FTIMES(能力値補正率, 75) + 100
攻撃力補正率 = FTIMES(能力値補正率, 100) + 100
魔力補正率 =   FTIMES(能力値補正率, 100) + 100
防御力補正率 = FTIMES(能力値補正率, 50) + 100
軽減値補正率 = FTIMES(能力値補正率, 75) + 100
行動力補正率 = FTIMES(能力値補正率, 50) + 100

最大HP = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "MAX_HP", 1), 最大HP補正率)
攻撃力 = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "ATTACK", 1), 攻撃力補正率)
魔力   = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "MAG", 1), 魔力補正率)
防御力 = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "DEFENCE", 1), 防御力補正率)
軽減値 = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "ARMOR", 1), 軽減値補正率)
行動力 = FTIMES(DT_CELL_GET("ENEMY_DATA", ID, "AGILITY", 1), 行動力補正率)

IF DIC_CONTAINSKEY(DIC_OPTIONS, "CHARA_ID")
    CHARA_ID = DIC_GETINT(DIC_OPTIONS, "CHARA_ID")
    SHOW_PORTRAIT = 1
ELSE
    CHARA_ID = -1
ENDIF

{
    DT_ROW_ADD "CC_ACTOR"
        ,"CHARA_ID", CHARA_ID
        ,"CHARA_NAME", CC_NAME
        ,"ENEMY_TYPE", DT_CELL_GET("ENEMY_DATA", ID, "ENEMY_TYPE", 1)
        ,"SIDE", SIDE
        ,"PLACEMENT", PLACEMENT
        ,"MAX_HP", 最大HP
        ,"HP", 最大HP
        ,"STR", 攻撃力
        ,"MAG", 魔力
        ,"FACTION", -1
        ,"ATTACK", 攻撃力
        ,"DEFENCE", 防御力
        ,"ARMOR", 軽減値
        ,"AGILITY", 行動力
        ,"CRITICAL_RATE", DT_CELL_GET("ENEMY_DATA", ID, "CRITICAL_RATE", 1)
        ,"CRITICAL_DAMAGE_RATE", DT_CELL_GET("ENEMY_DATA", ID, "CRITICAL_DAMAGE_RATE", 1)
        ,"HATE_RATE", DT_CELL_GET("ENEMY_DATA", ID, "HATE_RATE", 1)
        ,"TARGETING", DT_CELL_GET("ENEMY_DATA", ID, "TARGETING", 1)
        ,"REGIST_POISON", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_POISON", 1)
        ,"REGIST_STUN", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_STUN", 1)
        ,"REGIST_BURN", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_BURN", 1)
        ,"REGIST_CHARM", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_CHARM", 1)
        ,"REGIST_PANIC", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_PANIC", 1)
        ,"REGIST_BLIND", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_BLIND", 1)
        ,"REGIST_DEATH", DT_CELL_GET("ENEMY_DATA", ID, "REGIST_DEATH", 1)
        ,"SELECTED_SKILL_SLOT", -1
        ,"ENEMY_AI", DT_CELL_GETS("ENEMY_DATA", ID, "ENEMY_AI", 1)
        ,"ENEMY_DEF_NAME", ENEMY_DEF_NAME
        ,"ENEMY_AI_ROUTINE_MODE", DT_CELL_GETS("ENEMY_DATA", ID, "ENEMY_AI_ROUTINE_MODE", 1)
        ,"ENEMY_AI_ROUTINE_SEQUENCE", DT_CELL_GET("ENEMY_DATA", ID, "ENEMY_AI_ROUTINE_SEQUENCE", 1)
        ,"ENEMY_ACTIVE_SKILL", DT_CELL_GETS("ENEMY_DATA", ID, "ENEMY_ACTIVE_SKILL", 1)
        ,"ENEMY_PASSIVE_SKILL", DT_CELL_GETS("ENEMY_DATA", ID, "ENEMY_PASSIVE_SKILL", 1)
        ,"DROP_ITEM_LIST", DT_CELL_GETS("ENEMY_DATA", ID, "DROP_ITEM_LIST", 1)
        ,"EXP", DT_CELL_GET("ENEMY_DATA", ID, "EXP", 1)
        ,"SHOW_PORTRAIT", SHOW_PORTRAIT
        ,"IS_PLAYABLE", 0
}
ACTOR_DID = RESULT
;CALL DEBUG_TIMER_END

;CALL DEBUG_OUTPUT_TABLE("CC_ACTOR")

IF DIC_OPTIONS != ""
    COLUMN_NUM = DIC_KEYSF(DIC_OPTIONS)
    ARRAYCOPY "RESULTS", "COLUMNS"
    FOR LOCAL, 0, COLUMN_NUM
        SIF COLUMNS:LOCAL == "CHARA_ID"
            CONTINUE

        IF GROUPMATCH(COLUMNS:LOCAL, "ENEMY_ACTIVE_SKILL", "ENEMY_PASSIVE_SKILL")
            DIC_SKILL = %DIC_GET(DIC_OPTIONS, COLUMNS:LOCAL)%
            ;DEBUGPRINTFORML DIC_SKILL: %DIC_SKILL%
            DIC_SKILL = %REPLACE(DIC_SKILL, "<", "[")%
            DIC_SKILL = %REPLACE(DIC_SKILL, ";", ":")%
            DIC_SKILL = %REPLACE(DIC_SKILL, ">", "]")%
            ;DEBUGPRINTFORML DIC_SKILL: %DIC_SKILL%
            CALL CC_SETS_ENEMYDATA(ACTOR_DID, COLUMNS:LOCAL, DIC_SKILL)
            CONTINUE
        ENDIF

        SELECTCASE DT_COLUMN_EXIST("CC_ACTOR", COLUMNS:LOCAL)
            CASE 1, 2, 3, 4
                ;DEBUGPRINTFORML BEFORE {DT_CELL_GET("CC_ACTOR", TARGET_DID, COLUMNS:LOCAL, 1)}
                CALL CC_SET_ENEMYDATA(ACTOR_DID, COLUMNS:LOCAL, DIC_GETINT(DIC_OPTIONS, COLUMNS:LOCAL))
                ;DEBUGPRINTFORML AFTER {DT_CELL_GET("CC_ACTOR", TARGET_DID, COLUMNS:LOCAL, 1)}
            CASE 5
                ;DEBUGPRINTFORML BEFORE %DT_CELL_GETS("CC_ACTOR", TARGET_DID, COLUMNS:LOCAL, 1)%
                CALL CC_SETS_ENEMYDATA(ACTOR_DID, COLUMNS:LOCAL, DIC_GET(DIC_OPTIONS, COLUMNS:LOCAL))
                ;DEBUGPRINTFORML AFTER %DT_CELL_GETS("CC_ACTOR", TARGET_DID, COLUMNS:LOCAL, 1)%
            CASEELSE
                DEBUGPRINTFORML 指定された行名%COLUMNS:LOCAL%が存在しません
        ENDSELECT
    NEXT
ENDIF

;トークン管理テーブルにキャラクターを追加
DT_ROW_ADD "CC_SP_TOKEN_NUM", "ID", ACTOR_DID
CALL CC_CREATE_ACTOR_FLAG(ACTOR_DID)

RETURN ACTOR_DID

;-------------------------------------------------
;;; エネミーデータの指定キーに値を設定する
;;; 引数:1 データテーブル上のID(@CC_ENEMY_DATAの返り値を指定するとよい)
;;; 引数:2 キー名
;;; 引数:3 設定値
;;; 文字列用
;;;-------------------------------------------------
@CC_SETS_ENEMYDATA(ENEMY_DID, KEY, VALUES)
#DIM  ENEMY_DID
#DIMS KEY
#DIMS VALUES

DT_CELL_SET "CC_ACTOR", ENEMY_DID, KEY, VALUES, 1
;;; 数値用
@CC_SET_ENEMYDATA(ENEMY_DID, KEY, VALUE)
#DIM  ENEMY_DID
#DIMS KEY
#DIM VALUE

DT_CELL_SET "CC_ACTOR", ENEMY_DID, KEY, VALUE, 1

;-------------------------------------------------
;@CC_ADD_COMBAT_EXP
;MASTERと同じ所属勢力の戦闘参加メンバー全員に引数:1 で指定した戦闘経験値を追加する
;引数:1 獲得経験値
;引数:2 経験値獲得メッセージ表示の有無(表示しない場合0を指定)
;引数:3 自動レベルアップの有無(実施しない場合0を指定)
;-------------------------------------------------
@CC_ADD_COMBAT_EXP(COMBAT_EXP, メッセージ表示 = 1, 自動レベルアップ = 1)
#DIM COMBAT_EXP
#DIM メッセージ表示
#DIM 自動レベルアップ
#DIM DYNAMIC MEMBER_LIST, CC_MAX_MEMBER_NUM + 1

CALL CC_GET_MEMBER_LIST(MEMBER_LIST, CFLAG:MASTER:所属)
FOR LOCAL, 0, FINDELEMENT(MEMBER_LIST, -1)
    CALL PRINT_ADD_EXP(MEMBER_LIST:LOCAL, "戦闘経験値", COMBAT_EXP, メッセージ表示)
    SIF TALENT:(MEMBER_LIST:LOCAL):魔術師 || TALENT:(MEMBER_LIST:LOCAL):成長型 == 12
        CALL PRINT_ADD_EXP(MEMBER_LIST:LOCAL, "魔術経験値", COMBAT_EXP, メッセージ表示)
    IF 自動レベルアップ == 1
        CALL TRAIN_AUTO_ABLUP(MEMBER_LIST:LOCAL, メッセージ表示 ? 0 # 1)
    ENDIF
NEXT
SIF メッセージ表示
    PRINTL

;-------------------------------------------------
;@CC_GET_DROP_ITEM
;指定のサイドに属するエネミーにドロップアイテムが設定されている場合、取得判定を行う
;引数:1
;-------------------------------------------------
; #region @CC_GET_LOOT_FROM
@CC_GET_LOOT_FROM(SIDES)
#DIMS SIDES
#DIM  DYNAMIC SIDE
#DIM  DYNAMIC MEM_CNT
#DIM  DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIM  DYNAMIC LIST_IDX
#DIMS DYNAMIC DROP_ITEM_LIST
#DIMS DYNAMIC ITEM_IDS
#DIMS DYNAMIC DROP_NUMS
#DIMS DYNAMIC DROP_NUMS_RANGE, 2
#DIM  DYNAMIC DROP_NUM
#DIM  DYNAMIC DROP_RATE
#DIM  DYNAMIC SUM_ITEM, ITEM_LENGTH
#DIM  DYNAMIC SUM_MONEY
#DIM  DYNAMIC SUM_EXP
#DIMS DYNAMIC LIST_DROP_EQUIP
#DIM  ITER_I
#DIM  ITER_J

;集計処理
SIDE = SIDES == "ATTACKER" ? 1 # 0
MEM_CNT = DT_SELECT("CC_ACTOR", @"SIDE = {SIDE}",,IDX)
FOR ITER_I, 0, MEM_CNT
    DROP_ITEM_LIST = %DT_CELL_GETS("CC_ACTOR", IDX:ITER_I, "DROP_ITEM_LIST", 1)%
    SIF RESULT < 0
        RETURN 0
    FOR ITER_J, 0, LIST_COUNT(DROP_ITEM_LIST)
        LIST_IDX = ITER_J * 3
        DROP_RATE = TOINT(LIST_GET(DROP_ITEM_LIST, LIST_IDX + 2))
        SIF DROP_RATE < RAND:1000
            CONTINUE
        ITEM_IDS = %LIST_GET(DROP_ITEM_LIST, LIST_IDX)%
        DROP_NUMS = %LIST_GET(DROP_ITEM_LIST, LIST_IDX + 1)%
        SPLIT DROP_NUMS, "-", DROP_NUMS_RANGE
        IF RESULT > 1
            DROP_NUM = RAND(TOINT(DROP_NUMS_RANGE:0), TOINT(DROP_NUMS_RANGE:1) + 1)
        ELSE
            DROP_NUM = TOINT(DROP_NUMS)
        ENDIF
        SELECTCASE ITEM_IDS
            CASE "MONEY"
                SUM_MONEY += DROP_NUM
            CASEELSE
                ;数値の場合ITEM_IDが指定されているとみなす
                IF ISNUMERIC(ITEM_IDS)
                    SUM_ITEM:(TOINT(ITEM_IDS)) += DROP_NUM
                ELSEIF EXISTVAR(ITEM_IDS)
                    SUM_ITEM:(GETVAR(ITEM_IDS)) += DROP_NUM
                ELSE
                    ;文字列の場合EQUIP_DATAテーブルの装備品定義名が指定されているとみなす
                    LIST_DROP_EQUIP = %LIST_ADD(LIST_DROP_EQUIP, @"%ITEM_IDS%,{DROP_NUM}")%
                ENDIF
        ENDSELECT

    NEXT
    SUM_EXP += DT_CELL_GET("CC_ACTOR", IDX:ITER_I, "EXP", 1)
NEXT

;ラベル
PRINTL
CALL PRINT_TITLE("COMBAT REWARD","戦利品")

;資金・アイテム獲得処理
SIF SUM_MONEY != 0
    CALL QST_CHANGE_ITEM(@"MONEY,{SUM_MONEY},", 0)
FOR ITER_I, 0, ITEM_LENGTH
    IF SUM_ITEM:ITER_I != 0
        CALL QST_CHANGE_ITEM(@"{ITER_I},{SUM_ITEM:ITER_I},", 0)
    ENDIF
NEXT
FOR LOCAL, 0, LIST_COUNT(LIST_DROP_EQUIP)
    IF LOCAL != 0 && LOCAL % 2 != 0
        CALL QST_CHANGE_ITEM(@"%LIST_GET(LIST_DROP_EQUIP, LOCAL - 1)%,%LIST_GET(LIST_DROP_EQUIP, LOCAL)%,", 0)
    ENDIF
NEXT
PRINTL
;経験値獲得処理
CALL CC_ADD_COMBAT_EXP(SUM_EXP)

WAIT
; #endregion

;-------------------------------------------------
;@CC_APPLY_CHARA_HP
;MASTERと同じ所属勢力の戦闘参加メンバー全員の体力を戦闘後の値に変更する
;-------------------------------------------------
@CC_APPLY_CHARA_HP()
#DIM DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIM DYNAMIC CHARA_ID
#DIM DYNAMIC HP
#DIM DYNAMIC MEM_CNT

MEM_CNT = DT_SELECT("CC_ACTOR",,, IDX)
FOR LOCAL, 0, MEM_CNT
    IF DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "FACTION", 1) == CFLAG:MASTER:所属
        CHARA_ID = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "CHARA_ID", 1)
        HP = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "HP", 1)
        BASE:CHARA_ID:体力 = MAX(1, HP)
    ENDIF
NEXT

;-------------------------------------------------
;@CC_GET_MEMBER_LIST
;第二引数に指定した所属のメンバーを参加メンバーから取得する
;引数:1 参加メンバーIDを格納するための一次元配列
;引数:2 CFLAG:ID:所属
;-------------------------------------------------
@CC_GET_MEMBER_LIST(MEMBER_LIST, 所属)
#DIM REF MEMBER_LIST
#DIM 所属
#DIM DYNAMIC MEMBER_LIST_IDX
#DIM DYNAMIC IDX, CC_MAX_MEMBER_NUM
#DIM DYNAMIC MEM_CNT
VARSET MEMBER_LIST, -1

MEM_CNT = DT_SELECT("CC_ACTOR",,, IDX)
FOR LOCAL, 0, MEM_CNT
    IF DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "FACTION", 1) == 所属
        MEMBER_LIST:MEMBER_LIST_IDX = DT_CELL_GET("CC_ACTOR", IDX:LOCAL, "CHARA_ID", 1)
        MEMBER_LIST_IDX ++
    ENDIF
NEXT

RETURN

;=================================================
;内部処理用
;=================================================
;-------------------------------------------------
; キャラを戦闘メンバーとして登録する
;-------------------------------------------------
; #region @CC_SET_CHARADATA
@CC_SET_CHARADATA(CHARA_ID, SIDE)
#DIM CHARA_ID
#DIM SIDE
#DIM DYNAMIC IDX
#DIM  DYNAMIC ACTOR_DID
#DIM  DYNAMIC EQUIP_DID
#DIM  DYNAMIC SLOT_IDX
#DIM  DYNAMIC SKILL_LV
#DIM  DYNAMIC EFFECT_RATE
#DIMS DYNAMIC SKILL_DEF_NAME
#DIMS DYNAMIC DIC_WPN_SKILL
#DIMS DYNAMIC MEM_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIM  DYNAMIC FACTION
#DIM  DYNAMIC IS_PLAYABLE
#DIM  DYNAMIC PLACEMENT
#DIMS DYNAMIC INTEGRATED_WPN_PASSIVE_SKILLS
;戦闘開始時の補正ステータス
#DIM  DYNAMIC 攻撃力
#DIM  DYNAMIC 魔力
#DIM  DYNAMIC 防御力
#DIM  DYNAMIC 軽減値
#DIM  DYNAMIC 行動力
#DIM  DYNAMIC 攻撃力補正率 = 100
#DIM  DYNAMIC 魔力補正率 = 100
#DIM  DYNAMIC 防御力補正率 = 100
#DIM  DYNAMIC 軽減値補正率 = 100
#DIM  DYNAMIC 行動力補正率 = 100

#DIM  ITER_I
#DIM  ITER_J

CALL C_COND_SET_INFO_TO_MAP(CHARA_ID, "BEFORE_COMBAT")

CALL CC_CALC_CHARA_STATUS(CHARA_ID)
DT_SELECT "CHARA_STATUS",@"CHARA_ID = {CHARA_ID}",, IDX
攻撃力 = DT_CELL_GET("CHARA_STATUS", IDX, "ATTACK", 1)
魔力   = DT_CELL_GET("CHARA_STATUS", IDX, "MAG", 1)
防御力 = DT_CELL_GET("CHARA_STATUS", IDX, "DEFENCE", 1)
軽減値 = DT_CELL_GET("CHARA_STATUS", IDX, "ARMOR", 1)
行動力 = DT_CELL_GET("CHARA_STATUS", IDX, "AGILITY", 1)

;;戦闘開始時のスキルによるパラメータ補正
;少数精鋭による補正
SKILL_LV = HAS_SKILL(CHARA_ID, "FEW_ELITE", スキル_大分類_冒険)
IF SKILL_LV
    攻撃力補正率 += 5 * (QST_MAX_PARTYNUM - MAX(QST_PARTYNUM, 1))
    軽減値補正率 += 5 * (QST_MAX_PARTYNUM - MAX(QST_PARTYNUM, 1))
ENDIF

;食事による補正（１戦闘永続）
IF CFLAG:CHARA_ID:QST食事
    TRYCALLFORMF GET_INFO_INSTANT_BUFF_{CFLAG:CHARA_ID:QST食事}("AGI")
    行動力補正率 += RESULT
ENDIF

;補正率に基づく補正
攻撃力 = FTIMES(攻撃力, 攻撃力補正率)
魔力   = FTIMES(魔力,   魔力補正率)
防御力 = FTIMES(防御力, 防御力補正率)
軽減値 = FTIMES(軽減値, 軽減値補正率)
行動力 = FTIMES(行動力, 行動力補正率)

;DEBUGPRINTFORML %ANAME(CHARA_ID)%の攻撃力{攻撃力},攻撃力補正率{攻撃力補正率}

;位置情報　仮仕様で登録順
PLACEMENT = DT_SELECT("CC_ACTOR", @"SIDE = {SIDE}")

;自陣営の場合は操作可能キャラとして登録
IF CFLAG:CHARA_ID:所属 == 所属_プレイヤー
    IS_PLAYABLE = 1
ELSE
    IS_PLAYABLE = 0
ENDIF

;軽量化のため武器パッシブを事前集約
VARI WPN_NUM
VARI  WPN_IDX, 10
WPN_NUM = DT_SELECT("WEAPON_STOCK", @"EQUIP_CHARA_ID = {CHARA_ID}", "EQUIP_SLOT_ID ASC", WPN_IDX)
FOR LOCAL, 0, WPN_NUM
    INTEGRATED_WPN_PASSIVE_SKILLS += DT_CELL_GETS("WEAPON_STOCK", WPN_IDX:LOCAL, "PASSIVE_WEAPON_SKILL", 1)
NEXT

{
    DT_ROW_ADD "CC_ACTOR"
        ,"CHARA_ID", CHARA_ID
        ,"CHARA_NAME", ANAME(CHARA_ID)
        ,"SIDE", SIDE
        ,"PLACEMENT", PLACEMENT
        ,"FACTION", CFLAG:CHARA_ID:所属
        ,"MAX_HP", DT_CELL_GET("CHARA_STATUS", IDX, "MAX_HP", 1)
        ,"HP", MAX(1 ,DT_CELL_GET("CHARA_STATUS", IDX, "HP", 1))
        ,"STR", DT_CELL_GET("CHARA_STATUS", IDX, "STR", 1)
        ,"MAG", 魔力
        ,"ATTACK", 攻撃力
        ,"DEFENCE", 防御力
        ,"ARMOR", 軽減値
        ,"AGILITY", 行動力
        ,"CRITICAL_RATE", DT_CELL_GET("CHARA_STATUS", IDX, "CRITICAL_RATE", 1)
        ,"CRITICAL_DAMAGE_RATE", DT_CELL_GET("CHARA_STATUS", IDX, "CRITICAL_DAMAGE_RATE", 1)
        ,"HATE_RATE", DT_CELL_GET("CHARA_STATUS", IDX, "HATE_RATE", 1)
        ,"TARGETING", DT_CELL_GET("CHARA_STATUS", IDX, "TARGETING", 1)
        ,"SELECTED_SKILL_SLOT", -1
        ,"SHOW_PORTRAIT", 1
        ,"IS_PLAYABLE", IS_PLAYABLE
        ,"INTEGRATED_WPN_PASSIVE_SKILLS", INTEGRATED_WPN_PASSIVE_SKILLS
        ,"REGIST_POISON", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_POISON", 1)
        ,"REGIST_STUN", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_STUN", 1)
        ,"REGIST_BURN", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_BURN", 1)
        ,"REGIST_CHARM", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_CHARM", 1)
        ,"REGIST_PANIC", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_PANIC", 1)
        ,"REGIST_BLIND", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_BLIND", 1)
        ,"REGIST_DEATH", DT_CELL_GET("CHARA_STATUS", IDX, "REGIST_DEATH", 1)
}
ACTOR_DID = RESULT

;トークン管理テーブルにキャラクターを追加
DT_ROW_ADD "CC_SP_TOKEN_NUM", "ID", ACTOR_DID
;アクターフラグ用の連想配列を作成
CALL CC_CREATE_ACTOR_FLAG(ACTOR_DID)

;発情トークン追加
CALL CC_ADD_SP_TOKEN(ACTOR_DID, "ESTRUS", TCVAR:CHARA_ID:媚薬)
CALL CC_SET_SP_TOKEN(ACTOR_DID, "CHEST_EXPOSE", C_COND("露出_胸:露出",,CHARA_ID))
CALL CC_SET_SP_TOKEN(ACTOR_DID, "GENITAL_EXPOSE", C_COND("露出_秘部:露出",,CHARA_ID))

;アクティブスキルスロットにセットされているスキルをスロット用テーブルにセット
FOR LOCAL, 0, LIST_COUNT(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0)
    SKILL_DEF_NAME = %LIST_GET(_LIST_ACTIVE_SKILL_SLOT:CHARA_ID:0, LOCAL)%
    SKILL_LV = HAS_SKILL(CHARA_ID, SKILL_DEF_NAME, スキル_大分類_冒険)
    {
        DT_ROW_ADD "CC_SKILL_SLOT"
            ,"CHARA_ID", CHARA_ID
            ,"SKILL_DEF_NAME", SKILL_DEF_NAME
            ,"SKILL_LV", SKILL_LV
            ,"EQUIP_DID", 0
            ,"SKILL_SLOT_IDX", LOCAL
            ,"COOLTIME", ACTIVE_SKILL_COOLTIME:CHARA_ID:LOCAL
    }
NEXT
;装備のアクティブスキルをスロット用テーブルにセット
CALL GET_ALL_WEAPON_LIST_IDX_BY_CHARA_ID(CHARA_ID)
FOR ITER_I, 0, RESULT
    EQUIP_DID = RESULT:(1 + ITER_I)
    DIC_WPN_SKILL '= @"%DT_CELL_GETS("WEAPON_STOCK", EQUIP_DID, "ACTIVE_WEAPON_SKILL", 1)%"
    IF DIC_WPN_SKILL != ""
        CALL DIC_KEYS(DIC_WPN_SKILL)
        ARRAYCOPY "RESULTS", "MEM_SKILL_DEF_LIST"
        FOR ITER_J, 0, RESULT
            {
                DT_ROW_ADD "CC_SKILL_SLOT"
                    ,"CHARA_ID", CHARA_ID
                    ,"SKILL_DEF_NAME", MEM_SKILL_DEF_LIST:ITER_J
                    ,"SKILL_LV", TOINT(DIC_GET(DIC_WPN_SKILL, MEM_SKILL_DEF_LIST:ITER_J))
                    ,"EQUIP_DID", EQUIP_DID
                    ,"SKILL_SLOT_IDX", SLOT_IDX + 3
            }
            SLOT_IDX ++
        NEXT
    ENDIF
NEXT

;スキル処理：ルーンプリローダーの初期詠唱点
SKILL_LV = HAS_SKILL(CHARA_ID, "WPN_ADD_CAST_AT_START", スキル_大分類_武器)
IF SKILL_LV
    CALL SKILL_GET_EFFECT_RATE(武器スキル_パッシブ, "WPN_ADD_CAST_AT_START", SKILL_LV, 1)
    EFFECT_RATE = RESULT
    CALL CC_ADD_SP_TOKEN(ACTOR_DID, "CAST", EFFECT_RATE)
ENDIF

;スキル処理：残響の初期歌唱点
SKILL_LV = HAS_SKILL(CHARA_ID, "WPN_ADD_SONG_AT_START", スキル_大分類_武器)
IF SKILL_LV
    CALL SKILL_GET_EFFECT_RATE(武器スキル_パッシブ, "WPN_ADD_SONG_AT_START", SKILL_LV, 1)
    EFFECT_RATE = RESULT
    CALL CC_ADD_SP_TOKEN(ACTOR_DID, "SONG", EFFECT_RATE)
ENDIF

;食事トークン追加処理
IF CFLAG:CHARA_ID:QST食事
    IF EXISTFUNCTION(@"GET_INFO_INSTANT_BUFF_{CFLAG:CHARA_ID:QST食事}") > 0
        TRYCALLFORMF GET_INFO_INSTANT_BUFF_{CFLAG:CHARA_ID:QST食事}("TURN")
        EFFECT_RATE = RESULT
        DT_CELL_SET "CC_ACTOR", ACTOR_DID, "MEAL_EFFECT_ID", CFLAG:CHARA_ID:QST食事, 1
        CALL CC_ADD_SP_TOKEN(ACTOR_DID, "MEAL_EFFECT", EFFECT_RATE)
        ;食事効果フラグをリセット
        CFLAG:CHARA_ID:QST食事 = 0
    ENDIF
ENDIF
; #endregion

@CC_SET_MOBDATA(SIDE, CC_NAME, HP, MAX_HP, 戦闘, 魔術 , MOB_ELITE , 作戦)
#DIM SIDE
#DIMS CC_NAME
#DIM HP
#DIM MAX_HP
#DIM 戦闘
#DIM 魔術

;追加分
#DIM MOB_ELITE
#DIM 防御力
#DIM 軽減値
#DIM 行動力
#DIM 敵視
#DIM 作戦
#DIM 敵視_高脅威
#DIM 敵視_低脅威
#DIM 敵視_魔術師
#DIM 敵視_低耐久

#DIM ACTOR_DID
#DIM PLACEMENT
IF !MOB_ELITE
    防御力 = 戦闘 / 10
    軽減値 = LIMIT(MAX_HP / 15, 0, 300)
    行動力 = 戦闘 * 125 / 100
    敵視   = 100
ELSE
    防御力 = 戦闘 / 8
    軽減値 = LIMIT(MAX_HP / 15, 0, 500)
    行動力 = 戦闘 * 175 / 100
    敵視   = 150
ENDIF
;位置情報　仮仕様で登録順
PLACEMENT = DT_SELECT("CC_ACTOR", @"SIDE = {SIDE}")

{
    DT_ROW_ADD "CC_ACTOR"
        ,"CHARA_ID", -1
        ,"CHARA_NAME", CC_NAME
        ,"SIDE", SIDE
        ,"PLACEMENT", PLACEMENT
        ,"MAX_HP", MAX_HP
        ,"HP", HP
        ,"STR", 戦闘
        ,"MAG", 魔術
        ,"FACTION", -1
        ,"ATTACK", 戦闘
        ,"DEFENCE", 防御力
        ,"ARMOR", 軽減値
        ,"AGILITY", 行動力
        ,"HATE_RATE", 敵視
        ,"TARGETING", 作戦
        ,"SELECTED_SKILL_SLOT", -1
        ,"ENEMY_ACTIVE_SKILL", ""
}
ACTOR_DID = RESULT

;トークン管理テーブルにキャラクターを追加
DT_ROW_ADD "CC_SP_TOKEN_NUM", "ID", ACTOR_DID
;アクターフラグ用の連想配列を作成
CALL CC_CREATE_ACTOR_FLAG(ACTOR_DID)

; DEBUGPRINTFORML *-----------------------*
; DEBUGPRINTFORML %CC_NAME%
; DEBUGPRINTFORML 敵視_高脅威:{敵視_高脅威}
; DEBUGPRINTFORML 敵視_低脅威:{敵視_低脅威}
; DEBUGPRINTFORML 敵視_魔術師:{敵視_魔術師}
; DEBUGPRINTFORML 敵視_低耐久:{敵視_低耐久}

RETURN
; #endregion

;-------------------------------------------------
; 戦闘前に実行されるスキルによる能力補正
; このファイルで扱うのはいまいち。暫定
;-------------------------------------------------
@CC_CALC_ATK_BUFF(CHARA_ID, _XML_SKILL, 補正前攻撃力)
#DIM CHARA_ID
#DIMS _XML_SKILL
#DIM 補正前攻撃力
#DIM DYNAMIC 加算攻撃力
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM DYNAMIC SKILL_LV

XML_GET _XML_SKILL, "//defname[.//func[text()='ATK_BUFF_BY_MULTIPLIER']]/@parentname", RESULTS, 1
IF RESULT
    SKILL_DEF_NAME = %RESULTS%
    CALL SKILL_GET_LEVEL(CHARA_ID, 1, SKILL_DEF_NAME)
    SKILL_LV = RESULT
    XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
    IF RESULT
        加算攻撃力 = (補正前攻撃力 * TOINT(RESULTS)) / 100
    ENDIF
ENDIF

RETURN 加算攻撃力

@CC_CALC_DEF_BUFF(CHARA_ID, _XML_SKILL, 補正前軽減値)
#DIM CHARA_ID
#DIMS _XML_SKILL
#DIM 補正前軽減値
#DIM DYNAMIC 加算軽減値
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM DYNAMIC SKILL_LV

XML_GET _XML_SKILL, "//defname[.//func[text()='DEF_BUFF_BY_MULTIPLIER']]/@parentname", RESULTS, 1
IF RESULT
    SKILL_DEF_NAME = %RESULTS%
    CALL SKILL_GET_LEVEL(CHARA_ID, 1, SKILL_DEF_NAME)
    SKILL_LV = RESULT
    XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
    IF RESULT
        加算軽減値 = (補正前軽減値 * TOINT(RESULTS)) / 100
    ENDIF
ENDIF

RETURN 加算軽減値

;-------------------------------------------------
;;;各アクターのフラグ
;-------------------------------------------------
@CC_CREATE_ACTOR_FLAG(ACTOR_DID)
#DIM  ACTOR_DID
MAP_RELEASE @"ACTOR_FLAG_{ACTOR_DID}"
MAP_CREATE @"ACTOR_FLAG_{ACTOR_DID}"

@CC_SETS_ACTOR_FLAG(ACTOR_DID, KEYS, VALUES)
#DIM  ACTOR_DID
#DIMS KEYS
#DIMS VALUES
MAP_SET @"ACTOR_FLAG_{ACTOR_DID}", KEYS, VALUES

;;; 数値をフラグ変数にセット
@CC_SET_ACTOR_FLAG(ACTOR_DID, KEYS, VALUE)
#DIM  ACTOR_DID
#DIMS KEYS
#DIM  VALUE
CALL CC_SETS_ACTOR_FLAG(ACTOR_DID, KEYS, TOSTR(VALUE))

;;; 数値をフラグ変数に加算
@CC_ADD_ACTOR_FLAG(ACTOR_DID, KEYS, ADD_VALUE)
#DIM  ACTOR_DID
#DIMS KEYS
#DIM  ADD_VALUE
#DIM  CURRENT_VALUE

CURRENT_VALUE = CC_GET_ACTOR_FLAG(ACTOR_DID, KEYS)
CALL CC_SET_ACTOR_FLAG(ACTOR_DID, KEYS, CURRENT_VALUE + ADD_VALUE)

;;; @CC_SET_ACTOR_FLAGでセットしたフラグ変数を取得する
@CC_GETS_ACTOR_FLAG(ACTOR_DID, KEYS)
#FUNCTIONS
#DIM  ACTOR_DID
#DIMS KEYS
RETURNF MAP_GET(@"ACTOR_FLAG_{ACTOR_DID}", KEYS)

;;; @CC_SET_ACTOR_FLAGでセットしたフラグ変数を数値変換して取得する
@CC_GET_ACTOR_FLAG(ACTOR_DID, KEYS)
#FUNCTION
#DIM  ACTOR_DID
#DIMS KEYS
RETURNF TOINT(CC_GETS_ACTOR_FLAG(ACTOR_DID, KEYS))

;;; @CC_SET_ACTOR_FLAGでセットしたフラグ変数を削除する
@CC_REMOVE_ACTOR_FLAG(ACTOR_DID, KEYS)
#DIM  ACTOR_DID
#DIMS KEYS
MAP_REMOVE @"ACTOR_FLAG_{ACTOR_DID}", KEYS

@CC_RELEASE_ALL_ACTOR_FLAG
#DIM MEM_CNT
#DIM IDX, CC_MAX_MEMBER_NUM

MEM_CNT = DT_SELECT("CC_ACTOR",,, IDX)
FOR LOCAL, 0, MEM_CNT
    MAP_RELEASE @"ACTOR_FLAG_{IDX:LOCAL}"
NEXT
;-------------------------------------------------
;戦闘処理時のスキル実行関数
;-------------------------------------------------
;キャラクターアクティブスキル
; #region @CC_EXEC_ACTIVE_SKILL
@CC_EXEC_ACTIVE_SKILL(EXECUTE_AT, ATTACKER_DID, DEFENDER_DID = 0, SKILL_DEF_NAME = "")
#DIMS EXECUTE_AT
#DIMS SUBCATEGORY
#DIM ATTACKER_DID
#DIM DEFENDER_DID
#DIMS SKILL_DEF_NAME

;キャラ情報
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
;武器情報
#DIM  DYNAMIC ATK_WPN_DID
#DIM  DYNAMIC DEF_WPN_DID
#DIMS DYNAMIC ATK_WPN_SKILL
#DIMS DYNAMIC DEF_WPN_SKILL
;スキル情報
#DIM DYNAMIC  ATK_SELECT_SLOT = -1
#DIM DYNAMIC  DEF_SELECT_SLOT = -1
#DIMS DYNAMIC _XML_SKILL
#DIM DYNAMIC  ERR_FLG
#DIM DYNAMIC  ATK_SKILL_SLOT_ID
#DIM DYNAMIC  COLLATERAL_TARGET_TYPE
#DIM DYNAMIC  COLLATERAL_TARGET_RANGE
#DIM DYNAMIC  SKILL_LEVEL
VARSET RESULT

ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
IF ATK_CHARA_ID != -1
    ATK_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "SELECTED_SKILL_SLOT", 1)
    DT_SELECT "CC_SKILL_SLOT", @"CHARA_ID = {ATK_CHARA_ID} AND SKILL_SLOT_IDX = {ATK_SELECT_SLOT}",,ATK_SKILL_SLOT_ID
    SIF RESULT
        ATK_WPN_SKILL '= @"%DT_CELL_GETS("CC_SKILL_SLOT", ATK_SKILL_SLOT_ID, "SKILL_DEF_NAME", 1)%"
ENDIF
IF DEFENDER_DID
    DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)
    IF DEF_CHARA_ID != -1
        DEF_SELECT_SLOT = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "SELECTED_SKILL_SLOT", 1)
        DT_SELECT "CC_SKILL_SLOT", @"CHARA_ID = {DEF_CHARA_ID} AND SKILL_SLOT_IDX = {DEF_SELECT_SLOT}"
        SIF RESULT
            DEF_WPN_SKILL '= @"%DT_CELL_GETS("CC_SKILL_SLOT", RESULT:1, "SKILL_DEF_NAME", 1)%"
    ENDIF
ENDIF

;XML取得
IF SKILL_DEF_NAME == "" && ATK_CHARA_ID != -1
    SKILL_DEF_NAME = %ATK_WPN_SKILL%
ENDIF
IF STRFIND(SKILL_DEF_NAME, "WPN_") != 0
    XML_GET XMLID_SKILL_BATTLE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ELSE
    XML_GET XMLID_WPN_SKILL_ACTIVE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
ENDIF
;スキル処理
SELECTCASE EXECUTE_AT
    CASE "ON_ATTACK", "BEFORE_ATTACK", "AFTER_ATTACK"
        XML_GET _XML_SKILL, @"//func[//executeAt[(text()='%EXECUTE_AT%')]]", RESULTS, 1
        IF RESULT
            TRYCCALLFORM CC_%RESULTS%(ATTACKER_DID, DEFENDER_DID, _XML_SKILL)
                CALL KOJO_XML_COMBAT_BY_TRIGGER_ID(RESULT, "TRIGGER")
                CALL CC_ACTION_MANAGER_("RESOLVE")
                RETURN 1
            CATCH
                DEBUGPRINTFORML CAUTION:@CLOSE_COMBAT_ATTACK
                DEBUGPRINTFORML スキル<%SKILL_DEF_NAME%>が呼ばれましたが、対応するスキル処理関数が見つかりませんでした
                RETURN 0
            ENDCATCH
        ENDIF
    CASE "TARGETING"
        VARI TARGETING
        VARI TARGETING_SIDE
        VARS TARGETING_TOKEN_NAME
        ERR_FLG = 1

        IF XML_GET(_XML_SKILL, "defname/collateralTargetType", RESULTS, 1)
            IF ISNUMERIC(RESULTS)
                COLLATERAL_TARGET_TYPE = TOINT(RESULTS)
            ELSEIF EXISTVAR(@"WPN_COLLATERAL_TARGET_%RESULTS%")
                COLLATERAL_TARGET_TYPE = GETVAR(@"WPN_COLLATERAL_TARGET_%RESULTS%")
            ENDIF

            IF ATK_CHARA_ID == -1
                SKILL_LEVEL = CC_HAS_SKILL(ATTACKER_DID, SKILL_DEF_NAME)
            ELSE
                SKILL_LEVEL = DT_CELL_GET("CC_SKILL_SLOT", ATK_SKILL_SLOT_ID, "SKILL_LV", 1)
            ENDIF
            ;DEBUGPRINTFORML SKILL_LEVEL {SKILL_LEVEL}
            XML_GET _XML_SKILL, @"defname/value[@label='collateralTargetRange']/li[{SKILL_LEVEL}]", RESULTS, 1
            COLLATERAL_TARGET_RANGE = TOINT(RESULTS)
            DEBUGPRINTFORML %SKILL_DEF_NAME% COLLATERAL_TARGET_TYPE = {COLLATERAL_TARGET_TYPE} COLLATERAL_TARGET_RANGE = {COLLATERAL_TARGET_RANGE}
        ENDIF

        XML_GET _XML_SKILL, "//overrideTargeting", RESULTS, 1
        IF RESULT > 0
            IF ISNUMERIC(RESULTS)
                TARGETING = TOINT(RESULTS)
                ERR_FLG = 0
            ELSEIF EXISTVAR(@"WPN_脅威選定_%RESULTS%")
                TARGETING = GETVAR(@"WPN_脅威選定_%RESULTS%")
                ERR_FLG = 0
            ENDIF

            IF TARGETING == WPN_脅威選定_トークン
                XML_GET _XML_SKILL, "//targetingToken", RESULTS, 1
                TARGETING_TOKEN_NAME '= RESULT > 0 ? @"%RESULTS%" # ""
                IF (TARGETING_TOKEN_NAME != "" && !CC_SP_TOKEN_IS_EXIST(TARGETING_TOKEN_NAME)) || TARGETING_TOKEN_NAME == ""
                    ERR_FLG = 1
                ELSE
                    ERR_FLG = 0
                ENDIF
            ENDIF
        ELSE
            RETURN 0,0,0, COLLATERAL_TARGET_TYPE, COLLATERAL_TARGET_RANGE
        ENDIF
        XML_GET _XML_SKILL, "//targetingSide", RESULTS, 1
        IF RESULT
            TARGETING_SIDE = TOINT(RESULTS)
        ENDIF
        RESULTS = %TARGETING_TOKEN_NAME%
        RETURN !ERR_FLG, TARGETING, TARGETING_SIDE, COLLATERAL_TARGET_TYPE, COLLATERAL_TARGET_RANGE
ENDSELECT
RETURN 0

;キャラクターパッシブスキル
; #region @CC_EXEC_PASSIVE_SKILL
@CC_EXEC_PASSIVE_SKILL(EXECUTE_AT, ATTACKER_DID, DEFENDER_DID, SKILL_DEF_NAME = "")
#DIMS EXECUTE_AT
#DIM ATTACKER_DID
#DIM DEFENDER_DID
#DIMS SKILL_DEF_NAME

;キャラ情報
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
#DIM  DYNAMIC ATK_IS_PLAYABLE
#DIM  DYNAMIC DEF_IS_PLAYABLE
;スキル情報
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC ATK_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIMS DYNAMIC DEF_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
#DIMS DYNAMIC _DIC_ATK_SKILL

ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)
ATK_IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "IS_PLAYABLE", 1)
DEF_IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "IS_PLAYABLE", 1)

IF ATK_IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:ATK_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "ATK_SKILL_DEF_LIST"
    _DIC_ATK_SKILL '= _DIC_SKILL_LIST:ATK_CHARA_ID:1
ELSE
    CALL DIC_KEYS(DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "ENEMY_PASSIVE_SKILL", 1))
    ARRAYCOPY "RESULTS", "ATK_SKILL_DEF_LIST"
    _DIC_ATK_SKILL '= DT_CELL_GETS("CC_ACTOR", ATTACKER_DID, "ENEMY_PASSIVE_SKILL", 1)
ENDIF
IF DEF_IS_PLAYABLE
    CALL DIC_KEYS(_DIC_SKILL_LIST:DEF_CHARA_ID:1)
    ARRAYCOPY "RESULTS", "DEF_SKILL_DEF_LIST"
ELSE
    CALL DIC_KEYS(DT_CELL_GETS("CC_ACTOR", DEFENDER_DID, "ENEMY_PASSIVE_SKILL", 1))
    ARRAYCOPY "RESULTS", "DEF_SKILL_DEF_LIST"
ENDIF

VARI XML_RESULT
VARS XML_RESULTS
FOR LOCAL, 0, FINDELEMENT(ATK_SKILL_DEF_LIST, "",,, 1)
    XML_GET XMLID_SKILL_BATTLE, @"//defname[@parentname='%ATK_SKILL_DEF_LIST:LOCAL%']", _XML_SKILL, 3
    SIF !RESULT
        CONTINUE
    ;XML_GET _XML_SKILL, @"//func[contains(text(), 'ATKSKILL')]", RESULTS, 1
    ;アクティブスキルは除く
    XML_GET _XML_SKILL, @"//func[//subcategory[(text()='ACTIVE')]]", XML_RESULTS, 1
    SIF RESULT
        CONTINUE
    XML_GET _XML_SKILL, @"//triggerChance/li[{DIC_GETINT(_DIC_ATK_SKILL, ATK_SKILL_DEF_LIST:LOCAL)}]", XML_RESULTS, 1
    SIF RESULT && !PERCENT(TOINT(XML_RESULTS))
        CONTINUE
    XML_GET _XML_SKILL, "//triggerCondition", XML_RESULTS, 1
    XML_RESULT = RESULT
    SIF XML_RESULT
        DEBUGPRINTFORML triggerCondition %XML_RESULTS% = {TOINT(STRFORM(XML_RESULTS))}
    SIF XML_RESULT && !TOINT(STRFORM(XML_RESULTS))
        CONTINUE
    XML_GET _XML_SKILL, @"//func[//executeAt[(text()='%EXECUTE_AT%')]]", XML_RESULTS, 1
    SIF !RESULT
        CONTINUE
    DEBUGPRINTFORML EXEC CC_%XML_RESULTS%
    TRYCCALLFORM CC_%XML_RESULTS%(ATTACKER_DID, DEFENDER_DID, _XML_SKILL)
        ;パッシブは行数が増えがちなので使用せずEXECとまとめて表示
        ;CALL KOJO_XML_COMBAT_BY_TRIGGER_ID(RESULT, "TRIGGER")
    CATCH
        DEBUGPRINTFORML CAUTION:@CLOSE_COMBAT_ATTACK
        DEBUGPRINTFORML スキル<%ATK_SKILL_DEF_LIST:LOCAL%>が呼ばれましたが、対応するスキル処理関数が見つかりませんでした
    ENDCATCH
NEXT
CALL CC_ACTION_MANAGER_("RESOLVE")
; #endregion

;-------------------------------------------------
;;; HAS_SKILLのキャラ・エネミー対応版
;;; CC_ACTOR生成後(つまりCLOSE_COMBAT中のみ)使用可能
;-------------------------------------------------
@CC_HAS_SKILL(ACTOR_DID, SKILL_DEF_NAME, MAJORGENRE = スキル_大分類_冒険)
#FUNCTION
#DIM  ACTOR_DID
#DIMS SKILL_DEF_NAME
#DIM  MAJORGENRE
#DIM  DYNAMIC CHARA_ID
#DIMS DYNAMIC DIC_ENEMY_SKILLS

CHARA_ID = DT_CELL_GET("CC_ACTOR", ACTOR_DID, "CHARA_ID", 1)
IF CHARA_ID != -1
    RETURNF HAS_SKILL(CHARA_ID, SKILL_DEF_NAME, MAJORGENRE)
ELSE
    DIC_ENEMY_SKILLS = %DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "ENEMY_ACTIVE_SKILL", 1)%
    IF DIC_CONTAINSKEY(DIC_ENEMY_SKILLS, SKILL_DEF_NAME)
        RETURNF TOINT(DIC_GET(DIC_ENEMY_SKILLS, SKILL_DEF_NAME))
    ENDIF
    DIC_ENEMY_SKILLS = %DT_CELL_GETS("CC_ACTOR", ACTOR_DID, "ENEMY_PASSIVE_SKILL", 1)%
    IF DIC_CONTAINSKEY(DIC_ENEMY_SKILLS, SKILL_DEF_NAME)
        RETURNF TOINT(DIC_GET(DIC_ENEMY_SKILLS, SKILL_DEF_NAME))
    ENDIF
ENDIF
RETURNF 0

;-------------------------------------------------
;指定した定義名のスキルを習得済みの場合スキルレベルを返す
;装備スキル(武器、レリック)の場合はその武器のDIDをRESULT:1として返す
;装備スキルに重複したスキルがセットされている場合は、最も高いLVを優先して返す
;-------------------------------------------------
@HAS_SKILL(CHARA_ID, SKILL_DEF_NAME, MAJORGENRE = スキル_大分類_冒険)
; #region
#FUNCTION
#DIM  CHARA_ID
#DIMS SKILL_DEF_NAME
#DIM  MAJORGENRE
#DIM  DYNAMIC DID, 1000
#DIMS DYNAMIC SKILL_DIC
#DIM  DYNAMIC TEMP_SKILL_LV
#DIM  DYNAMIC TEMP_DID
#DIM  DYNAMIC CONFIRMED_SKILL_LV
#DIM  DYNAMIC CONFIRMED_DID

SIF CHARA_ID == -1
    RETURNF 0

IF MAJORGENRE != スキル_大分類_武器
    CALLF DIC_KEYSF(_DIC_SKILL_LIST:CHARA_ID:MAJORGENRE)
    IF FINDELEMENT(RESULTS, SKILL_DEF_NAME) != -1
        RETURNF TOINT(DIC_GET(_DIC_SKILL_LIST:CHARA_ID:MAJORGENRE, SKILL_DEF_NAME))
    ELSE
        RETURNF 0
    ENDIF
ELSE
    DT_SELECT "WEAPON_STOCK", @"EQUIP_CHARA_ID = {CHARA_ID}", "EQUIP_SLOT_ID ASC", DID
    FOR LOCAL, 0, RESULT
        SKILL_DIC = %DT_CELL_GETS("WEAPON_STOCK", DID:LOCAL, "ACTIVE_WEAPON_SKILL", 1)%
        IF DIC_CONTAINSKEY(SKILL_DIC, SKILL_DEF_NAME)
            TEMP_SKILL_LV = TOINT(DIC_GET(SKILL_DIC, SKILL_DEF_NAME))
            TEMP_DID = DID:LOCAL
            IF TEMP_SKILL_LV > CONFIRMED_SKILL_LV
                CONFIRMED_SKILL_LV = TEMP_SKILL_LV
                CONFIRMED_DID = TEMP_DID
            ENDIF
        ENDIF
        SKILL_DIC = %DT_CELL_GETS("WEAPON_STOCK", DID:LOCAL, "PASSIVE_WEAPON_SKILL", 1)%
        IF DIC_CONTAINSKEY(SKILL_DIC, SKILL_DEF_NAME)
            TEMP_SKILL_LV = TOINT(DIC_GET(SKILL_DIC, SKILL_DEF_NAME))
            TEMP_DID = DID:LOCAL
            IF TEMP_SKILL_LV > CONFIRMED_SKILL_LV
                CONFIRMED_SKILL_LV = TEMP_SKILL_LV
                CONFIRMED_DID = TEMP_DID
            ENDIF
        ENDIF
    NEXT
    RESULT:1 = CONFIRMED_DID
    RETURNF CONFIRMED_SKILL_LV
ENDIF
; #endregion

;-------------------------------------------------
;;; 特定の装備が指定したスキルを持つかどうかを判定する
;;; 持つ場合はスキルレベルを返す
;-------------------------------------------------
@WPN_HAS_SKILL(EQUIP_DID, SKILL_DEF_NAME)
; #region
#FUNCTION
#DIM  EQUIP_DID
#DIMS SKILL_DEF_NAME
#DIM  DYNAMIC SKILL_LV
#DIMS DYNAMIC SKILL_DIC

SKILL_DIC = %DT_CELL_GETS("WEAPON_STOCK", EQUIP_DID, "ACTIVE_WEAPON_SKILL", 1)%
IF DIC_CONTAINSKEY(SKILL_DIC, SKILL_DEF_NAME)
    SKILL_LV = TOINT(DIC_GET(SKILL_DIC, SKILL_DEF_NAME))
ENDIF
SKILL_DIC = %DT_CELL_GETS("WEAPON_STOCK", EQUIP_DID, "PASSIVE_WEAPON_SKILL", 1)%
IF DIC_CONTAINSKEY(SKILL_DIC, SKILL_DEF_NAME)
    SKILL_LV = TOINT(DIC_GET(SKILL_DIC, SKILL_DEF_NAME))
ENDIF

RETURNF SKILL_LV
; #endregion

;-------------------------------------------------
;;; 戦闘系スキルのジャンルを取得
;;; - ARGS
;;;     - SKILL_DEF_NAME {string}: スキル定義名
;;; - RETURN
;;;     - RESULT:0 {int}: 0=該当なし 1=キャラクターの戦闘スキル 2=装備スキル
;;;     - RESULT:1 {int}: スキルのジャンル(キャラクターの戦闘スキルはアクティブ、パッシブ混在なので実質装備のみ有効な返り値
;;;       武器スキル_アクティブor武器スキル_パッシブ)
;-------------------------------------------------
@CC_GET_SKILL_GENRE(SKILL_DEF_NAME)
; #region CC_GET_SKILL_GENRE
#FUNCTION
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM  DYNAMIC GENRE
#DIM  DYNAMIC WPN_SKILL_GENRE
#DIMS DYNAMIC _XML_SKILL

;キャラクターの戦闘スキルかを判定
XML_GET XMLID_SKILL_BATTLE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
IF RESULT
    RESULT:1 = 1
    RETURNF 1
ENDIF
;装備スキルかを判定
WPN_SKILL_GENRE = WPN_SKILL_GET_GENRE(SKILL_DEF_NAME)
IF WPN_SKILL_GENRE != -1
    RESULT:1 = 2
    RETURNF 2
ENDIF

RETURNF 0

;-------------------------------------------------
;;; 武器スキルのジャンルを取得
;;;-------------------------------------------------
@WPN_SKILL_GET_GENRE(SKILL_DEF_NAME)
; #region
#FUNCTION
#DIMS DYNAMIC SKILL_DEF_NAME
#DIMS DYNAMIC _XML_SKILL
#DIM  DYNAMIC GENRE

GENRE = 武器スキル_アクティブ
XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
IF RESULT
    RETURNF GENRE
ENDIF

GENRE = 武器スキル_パッシブ
XML_GET XMLID_WPN_SKILL:GENRE, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
IF RESULT
    RETURNF GENRE
ENDIF

RETURNF -1
;#endregion

;-------------------------------------------------
;;; 武器スキルのXMLを取得
;;;-------------------------------------------------
@WPN_SKILL_GET_XML(SKILL_DEF_NAME)
; #region
#DIMS SKILL_DEF_NAME

VARS _XML_SKILL
XML_GET XMLID_WPN_SKILL:武器スキル_アクティブ, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
IF !RESULT
    XML_GET XMLID_WPN_SKILL:武器スキル_パッシブ, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3
    IF !RESULT
        PRINTFORMW エラー:@WPN_SKILL_GET_EFFECT_RATE スキル<%SKILL_DEF_NAME%>のデータが取得できませんでした
        THROW
    ENDIF
ENDIF

RESULTS = %_XML_SKILL%
RETURN 1

;-------------------------------------------------
;;; 武器スキルのXMLを取得(式中関数版)
;;;-------------------------------------------------
@WPN_SKILL_GET_XMLF(SKILL_DEF_NAME)
; #region
#FUNCTIONS
#DIMS SKILL_DEF_NAME
#DIMS _XML_SKILL

IF XML_GET(XMLID_WPN_SKILL:武器スキル_アクティブ, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3)
    RETURNF _XML_SKILL
ELSEIF XML_GET(XMLID_WPN_SKILL:武器スキル_パッシブ, @"//defname[@parentname='%SKILL_DEF_NAME%']", _XML_SKILL, 3)
    RETURNF _XML_SKILL
ELSE
    THROW エラー:@WPN_SKILL_GET_EFFECT_RATE スキル<%SKILL_DEF_NAME%>のデータが取得できませんでした
ENDIF
;-------------------------------------------------
;;; 武器スキルの効果量を取得
;;;-------------------------------------------------
@WPN_SKILL_GET_EFFECT_RATE(SKILL_DEF_NAME, SKILL_LV)
; #region
#DIMS SKILL_DEF_NAME
#DIM  SKILL_LV

VARS _XML_SKILL
CALL WPN_SKILL_GET_XML(SKILL_DEF_NAME)
_XML_SKILL = %RESULTS%

VARI RATE, 3
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

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

;-------------------------------------------------
;;; 武器スキルの効果量を取得(式中関数版)
;;;-------------------------------------------------
@WPN_SKILL_GET_EFFECT_RATEF(SKILL_DEF_NAME, SKILL_LV, RATE_ID = 1)
; #region
#FUNCTION
#DIMS SKILL_DEF_NAME
#DIM  SKILL_LV
#DIM  RATE_ID
#DIMS _XML_SKILL

_XML_SKILL = %WPN_SKILL_GET_XMLF(SKILL_DEF_NAME)%

SELECTCASE RATE_ID
    CASE 1
        SIF XML_GET(_XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1)
            RETURNF TOINT(RESULTS)
    CASE 2
        SIF XML_GET(_XML_SKILL, @"//rate2/li[{SKILL_LV}]", RESULTS, 1)
            RETURNF TOINT(RESULTS)
    CASE 3
        SIF XML_GET(_XML_SKILL, @"//rate3/li[{SKILL_LV}]", RESULTS, 1)
            RETURNF TOINT(RESULTS)
ENDSELECT

THROW エラー:@WPN_SKILL_GET_EFFECT_RATEF スキル<%SKILL_DEF_NAME%> LV={SKILL_LV} RATE={RATE_ID}のデータが取得できませんでした

; #endregion

;-------------------------------------------------
;;; スキルのクールタイムを取得
;;;-------------------------------------------------
@WPN_SKILL_GET_COOLTIME(SKILL_DEF_NAME, SKILL_LV)
; #region
#DIMS DYNAMIC SKILL_DEF_NAME
#DIM  DYNAMIC SKILL_LV

VARS _XML_SKILL
CALL WPN_SKILL_GET_XML(SKILL_DEF_NAME)
_XML_SKILL = %RESULTS%

XML_GET _XML_SKILL, @"//cooltime/li[{SKILL_LV}]", RESULTS, 1
RETURN TOINT(RESULTS)
; #endregion

;武器パッシブスキル
; #region @CC_EXEC_WPN_PASSIVE_SKILL
@CC_EXEC_WPN_PASSIVE_SKILL(EXECUTE_AT, ATTACKER_DID, DEFENDER_DID)
#DIMS EXECUTE_AT
#DIM ATTACKER_DID
#DIM DEFENDER_DID

;キャラ情報
#DIM  DYNAMIC ATK_CHARA_ID
#DIM  DYNAMIC DEF_CHARA_ID
;武器情報
#DIM  DYNAMIC ATK_EQUIP_DID, 3
#DIM  DYNAMIC ATK_EQUIPNUM
#DIM  DYNAMIC DEF_EQUIP_DID, 3
#DIMS DYNAMIC DIC_WPN_SKILL
#DIM  DYNAMIC WPN_SKILLNUM
#DIMS DYNAMIC WPN_SKILL_DEF_LIST, VARSIZE("SKILL_DEF_LIST")
;スキル情報
#DIMS DYNAMIC _XML_SKILL
#DIMS DYNAMIC SKILL_DEF_NAME

#DIM  DYNAMIC ITER_I
#DIM  DYNAMIC ITER_J

ATK_CHARA_ID = DT_CELL_GET("CC_ACTOR", ATTACKER_DID, "CHARA_ID", 1)
DEF_CHARA_ID = DT_CELL_GET("CC_ACTOR", DEFENDER_DID, "CHARA_ID", 1)
IF ATK_CHARA_ID != -1
    CALL GET_ALL_WEAPON_LIST_IDX_BY_CHARA_ID(ATK_CHARA_ID)
    ATK_EQUIPNUM = RESULT
    FOR LOCAL, 0, ATK_EQUIPNUM
        ATK_EQUIP_DID:LOCAL = RESULT:(1 + LOCAL)
    NEXT
ENDIF

FOR ITER_I, 0, ATK_EQUIPNUM
    SIF !ATK_EQUIP_DID:ITER_I
        CONTINUE
    DIC_WPN_SKILL = %DT_CELL_GETS("WEAPON_STOCK", ATK_EQUIP_DID:ITER_I, "PASSIVE_WEAPON_SKILL", 1)%
    CALL DIC_KEYS(DIC_WPN_SKILL)
    SIF !RESULT
        CONTINUE
    WPN_SKILLNUM = RESULT
    ARRAYCOPY "RESULTS", "WPN_SKILL_DEF_LIST"
    FOR ITER_J, 0, WPN_SKILLNUM
        XML_GET XMLID_WPN_SKILL_PASSIVE, @"//defname[@parentname='%WPN_SKILL_DEF_LIST:ITER_J%']", _XML_SKILL, 3
        SIF !RESULT
            CONTINUE
        XML_GET _XML_SKILL, @"//triggerChance/li[{DIC_GETINT(DIC_WPN_SKILL, WPN_SKILL_DEF_LIST:ITER_J)}]", RESULTS, 1
        SIF RESULT && !PERCENT(TOINT(RESULTS))
            CONTINUE
        XML_GET _XML_SKILL, "//triggerCondition", RESULTS, 1
        ;DEBUGPRINTFORML CONDITION: %RESULTS% = {TOINT(STRFORM(RESULTS))}
        SIF RESULT && !TOINT(STRFORM(RESULTS))
            CONTINUE
        XML_GET _XML_SKILL, @"//func[//executeAt[(text()='%EXECUTE_AT%')]]", RESULTS, 1
        SIF !RESULT
            CONTINUE
        TRYCCALLFORM CC_%RESULTS%(ATTACKER_DID, DEFENDER_DID, _XML_SKILL, ATK_EQUIP_DID:ITER_I)
            ;パッシブは行数が増えがちなので、使用しない。
            ;CALL KOJO_XML_COMBAT_BY_TRIGGER_ID(RESULT, "TRIGGER")
            CALL CC_ACTION_MANAGER_("RESOLVE")
        CATCH
            DEBUGPRINTFORML スキル<%WPN_SKILL_DEF_LIST:ITER_J%>が呼ばれましたが、対応するスキル処理関数が見つかりませんでした
        ENDCATCH
    NEXT
NEXT
; #endregion

;-------------------------------------------------
; コスト付きスキルのコスト支払い処理
;-------------------------------------------------
; #region @CC_COST_ITEM_TOCAST
@CC_COST_ITEM_TOCAST(CHARA_DID, SKILL_DEF_NAME)
#DIM CHARA_DID
#DIMS SKILL_DEF_NAME
#DIMS DYNAMIC DIC_REQITEM_TOCAST
#DIMS DYNAMIC REQ_ITEM_NAME
#DIM  DYNAMIC REQ_ITEM_NUM
#DIM  DYNAMIC COST_ITEM, ITEM_LENGTH

;アイテムの場合プレイヤー所属以外のキャラは要求コストを無視
SIF DT_CELL_GET("CC_ACTOR", CHARA_DID, "FACTION", 1) != CFLAG:MASTER:所属
    RETURN 1

;武器スキルかどうか確認
DIC_REQITEM_TOCAST = %GET_SKILL_DATA(SKILL_DEF_NAME, "reqItemToCast", 1, 武器スキル_アクティブ)%

;習得スキルかどうか確認
SIF DIC_REQITEM_TOCAST == ""
    DIC_REQITEM_TOCAST = %GET_SKILL_DATA(SKILL_DEF_NAME, "reqItemToCast", 0, スキル_ジャンル_戦闘)%

IF DIC_REQITEM_TOCAST != ""
    CALL DIC_KEYS(DIC_REQITEM_TOCAST)
    FOR LOCAL, 0, RESULT
        REQ_ITEM_NAME = %RESULTS:LOCAL%
        REQ_ITEM_NUM = TOINT(DIC_GET(DIC_REQITEM_TOCAST, RESULTS:LOCAL))
        IF HO_ITEM_STOCK:GETVAR(REQ_ITEM_NAME) < REQ_ITEM_NUM
            RETURN 0
        ELSE
            COST_ITEM:GETVAR(REQ_ITEM_NAME) -= REQ_ITEM_NUM
        ENDIF
    NEXT
    CALL CHANGE_ITEM_STOCK_M(COST_ITEM)
ENDIF
RETURN 1
; #endregion

; #region @CC_COST_ITEM_TOCAST
@CC_COST_TOKEN_TOCAST(CHARA_DID, DIC_REQTOKEN_TOCAST)
#DIM  CHARA_DID
#DIMS SKILL_DEF_NAME
#DIM  GENRE
#DIMS DYNAMIC DIC_REQTOKEN_TOCAST
#DIMS DYNAMIC REQ_ITEM_NAME
#DIM  DYNAMIC REQ_ITEM_NUM
#DIM  DYNAMIC NOW_OWN_ITEM
#DIM  ITER_I

IF DIC_REQTOKEN_TOCAST != ""
    CALL DIC_KEYS(DIC_REQTOKEN_TOCAST)
    FOR ITER_I, 0, RESULT
        REQ_ITEM_NAME = %RESULTS:ITER_I%
        REQ_ITEM_NUM = TOINT(DIC_GET(DIC_REQTOKEN_TOCAST, RESULTS:ITER_I))
        NOW_OWN_ITEM = DT_CELL_GET("CC_ACTOR", CHARA_DID, REQ_ITEM_NAME, 1)
        DT_CELL_SET "CC_ACTOR", CHARA_DID, REQ_ITEM_NAME, MAX(NOW_OWN_ITEM - REQ_ITEM_NUM, 0), 1
    NEXT
ENDIF
RETURN 1
; #endregion

; #region @CC_COST_SP_TOKEN_TOCAST
@CC_COST_SP_TOKEN_TOCAST(CHARA_DID, DIC_REQTOKEN_TOCAST)
#DIM  CHARA_DID
#DIMS DIC_REQTOKEN_TOCAST

#DIMS DYNAMIC REQ_TOKEN_NAME
#DIM  DYNAMIC REQ_TOKEN_NUM
#DIM  KEY_NUM
#DIM  ITER_I

IF DIC_REQTOKEN_TOCAST != ""
    CALL DIC_KEYS(DIC_REQTOKEN_TOCAST)
    KEY_NUM = RESULT
    FOR ITER_I, 0, KEY_NUM
        REQ_TOKEN_NAME = %RESULTS:ITER_I%
        REQ_TOKEN_NUM = TOINT(DIC_GET(DIC_REQTOKEN_TOCAST, RESULTS:ITER_I))
        CALL CC_SUB_SP_TOKEN(CHARA_DID, REQ_TOKEN_NAME, REQ_TOKEN_NUM)
    NEXT
ENDIF
RETURN 1
; #endregion

;-------------------------------------------------
;スキル定義XMLからパラメータ参照用テーブルを作成
;-------------------------------------------------
; #region @SKILL_GET_PARAMS_TO_TABLE
@SKILL_GET_PARAMS_TO_TABLE(_XML_SKILL, CHARA_DID, EQUIP_DID = 0)
#DIMS _XML_SKILL
#DIM  CHARA_DID
#DIM  EQUIP_DID
#DIM  DYNAMIC CHARA_ID
#DIM  DYNAMIC IS_PLAYABLE
#DIMS DYNAMIC SKILL_DEF_NAME
#DIMS DYNAMIC CATEGORY
#DIMS DYNAMIC SUBCATEGORY
#DIMS DYNAMIC SKILL_NAME
#DIM  DYNAMIC SKILL_LV
#DIM  DYNAMIC SKILL_COOLTIME
#DIM  DYNAMIC EFFECT_RATE
#DIM  DYNAMIC EFFECT_RATE2
#DIM  DYNAMIC EFFECT_RATE3
#DIM  DYNAMIC WEAPON_DID
#DIMS DYNAMIC DIC_WPN_SKILL
#DIMS DYNAMIC REQITEM_TOCAST
#DIMS DYNAMIC REQTOKEN_TOCAST
#DIMS DYNAMIC ENEMY_SKILL
#DIM  DYNAMIC VALUE_LABEL_COUNT
#DIMS DYNAMIC LABELS, MAX_VALUE_PER_SKILL

CHARA_ID = DT_CELL_GET("CC_ACTOR", CHARA_DID, "CHARA_ID", 1)
IS_PLAYABLE = DT_CELL_GET("CC_ACTOR", CHARA_DID, "IS_PLAYABLE", 1)
IF DT_EXIST("SKILL_PARAMS")
    DT_CLEAR "SKILL_PARAMS"
ENDIF
CALL CREATE_SKILL_PARAMS_TABLE

XML_GET _XML_SKILL, "//defname/@parentname", RESULTS, 1
SIF !RESULT
    RETURN 0
SKILL_DEF_NAME = %RESULTS%
XML_GET _XML_SKILL, "//skillname", RESULTS,1
SKILL_NAME = %RESULTS%
XML_GET _XML_SKILL, "//subcategory", RESULTS,1
SUBCATEGORY = %RESULTS%
;通常アクティブスキル
IF !EQUIP_DID
    IF IS_PLAYABLE
        CALL SKILL_GET_LEVEL(CHARA_ID, 1, SKILL_DEF_NAME)
        SKILL_LV = RESULT
    ELSE
        IF SUBCATEGORY == "ACTIVE"
            ENEMY_SKILL = %DT_CELL_GETS("CC_ACTOR", CHARA_DID, "ENEMY_ACTIVE_SKILL", 1)%
            SKILL_LV = TOINT(DIC_GET(ENEMY_SKILL, SKILL_DEF_NAME))
            ; ENDIF
        ELSE
            ENEMY_SKILL = %DT_CELL_GETS("CC_ACTOR", CHARA_DID, "ENEMY_PASSIVE_SKILL", 1)%
            SKILL_LV = TOINT(DIC_GET(ENEMY_SKILL, SKILL_DEF_NAME))
        ENDIF
    ENDIF
    ;武器アクティブスキル
ELSE
    IF IS_PLAYABLE
        IF SUBCATEGORY == "ACTIVE"
            DIC_WPN_SKILL = %DT_CELL_GETS("WEAPON_STOCK", EQUIP_DID, "ACTIVE_WEAPON_SKILL", 1)%
        ELSE
            DIC_WPN_SKILL = %DT_CELL_GETS("WEAPON_STOCK", EQUIP_DID, "PASSIVE_WEAPON_SKILL", 1)%
        ENDIF
        SKILL_LV = TOINT(DIC_GET(DIC_WPN_SKILL, SKILL_DEF_NAME))
    ELSE
        RETURN 0
    ENDIF
ENDIF
;効果量とクールタイム
XML_GET _XML_SKILL, @"//rate/li[{SKILL_LV}]", RESULTS, 1
EFFECT_RATE  = TOINT(RESULTS)
XML_GET _XML_SKILL, @"//rate2/li[{SKILL_LV}]", RESULTS, 1
EFFECT_RATE2 = TOINT(RESULTS)
XML_GET _XML_SKILL, @"//rate3/li[{SKILL_LV}]", RESULTS, 1
EFFECT_RATE3 = TOINT(RESULTS)
XML_GET _XML_SKILL, @"//cooltime/li[{SKILL_LV}]", RESULTS, 1
SKILL_COOLTIME = TOINT(RESULTS)

;ラベル付き効果量
;modifierと分けるため、defname直下のみ取得
VALUE_LABEL_COUNT = XML_GET(_XML_SKILL, @"defname/value/@label", LABELS, 1)
;DEBUGPRINTFORML VALUE_LABEL_COUNT = {VALUE_LABEL_COUNT}
FOR LOCAL, 0, VALUE_LABEL_COUNT
    XML_GET _XML_SKILL, @"defname/value[@label = '%LABELS:LOCAL%']/li[{SKILL_LV}]", RESULTS, 1
    MAP_SET CCS_MAP_SKILL_VALUES, LABELS:LOCAL, RESULTS
NEXT
;DEBUGPRINTFORML CCS_MAP_SKILL_VALUES %SKILL_DEF_NAME%
;DEBUGPRINTFORML %MAP_TOXML(CCS_MAP_SKILL_VALUES)%

;消費コスト_アイテム
RESULTS '= ""
XML_GET _XML_SKILL, @"//reqItemToCast", RESULTS, 1
REQITEM_TOCAST = %RESULTS%
IF REQITEM_TOCAST != ""
    REQITEM_TOCAST = %REPLACE(REQITEM_TOCAST, "\\$RATE", @"{EFFECT_RATE}")%
ENDIF
;消費コスト_トークン
RESULTS '= ""
XML_GET _XML_SKILL, @"//reqTokenToCast", RESULTS, 1
REQTOKEN_TOCAST = %RESULTS%
IF REQTOKEN_TOCAST != ""
    REQTOKEN_TOCAST = %REPLACE(REQTOKEN_TOCAST, "\\$RATE", @"{EFFECT_RATE}")%
ENDIF

{
    DT_ROW_ADD "SKILL_PARAMS"
        ,"SKILL_DEF_NAME", SKILL_DEF_NAME
        ,"SKILL_NAME", SKILL_NAME
        ,"SKILL_LV", SKILL_LV
        ,"EFFECT_RATE", EFFECT_RATE
        ,"EFFECT_RATE2", EFFECT_RATE2
        ,"EFFECT_RATE3", EFFECT_RATE3
        ,"COOLTIME", SKILL_COOLTIME
        ,"REQITEM_TOCAST", REQITEM_TOCAST
        ,"REQTOKEN_TOCAST", REQTOKEN_TOCAST
}
RETURN 1
; #endregion

;-------------------------------------------------
;全員分のパッシブ発動チェック
;-------------------------------------------------
@CC_PASSIVE_CHECK_ALL(EXECUTE_AT)
#DIMS EXECUTE_AT
#DIMS ACTOR_LIST, CC_MAX_MEMBER_NUM + 1
#DIM  DYNAMIC ACTOR_DID
#DIM  DYNAMIC TARGET_DID

CALL CLOSE_COMBAT_SET_ORDER(ACTOR_LIST)
FOR LOCAL, 0, CC_MAX_MEMBER_NUM + 1
    SIF ACTOR_LIST:LOCAL == "-1"
        BREAK

    ACTOR_DID = TOINT(DIC_GET(ACTOR_LIST:LOCAL, "ACTOR_DID"))
    CALL CLOSE_COMBAT_SET_TARGET(ACTOR_DID)
    TARGET_DID = RESULT
    CALL CC_EXEC_PASSIVE_SKILL(EXECUTE_AT, ACTOR_DID, TARGET_DID)
    CALL CC_EXEC_WPN_PASSIVE_SKILL(EXECUTE_AT, ACTOR_DID, TARGET_DID)

    CALL CLOSE_COMBAT_DRAW_WINDOW(ACTOR_DID)

NEXT