code:
;;; V0.360リリース以降にソース削除
;;; 以下のソースにて代替
;;; QST_RANDOM_EQUIP_LOOT_WEAPON()
;;; QST_RANDOM_EQUIP_LOOT_RELIC()
; ;-------------------------------------------------
; ; 汎用武器ガチャ
; ;-------------------------------------------------
; ;武器の抽選
; ; #region @QST_WEAPON_GACHA
; @QST_WEAPON_GACHA(TABLE_RANK = 0)
; #DIM TABLE_RANK
; #DIMS DYNAMIC DIC_WPN_PASSIVE
; #DIMS DYNAMIC DIC_WPN_ACTIVE
; #DIM  DYNAMIC WEAPON_ID
; #DIMS DYNAMIC WEAPON_NAME
; #DIMS DYNAMIC CATEGORY
; #DIM  DYNAMIC MATERIAL
; #DIM  DYNAMIC RANK

; CATEGORY = %S_R("SHORT_SWORD/LONG_SWORD/AXE/GUN")%
; ;武器種ID
; SELECTCASE CATEGORY
;     CASE "SHORT_SWORD"
;         WEAPON_ID = TOINT(S_R("1/5"))
;     CASE "LONG_SWORD"
;         WEAPON_ID = 2
;     CASE "AXE"
;         WEAPON_ID = 3
;     CASE "GUN"
;         WEAPON_ID = 6
; ENDSELECT

; ;武器の材質
; CALL RAND_WT_INIT()
; CALL RAND_WT_SET(WPN_材質_鉄, 50)
; CALL RAND_WT_SET(WPN_材質_鋼, 30)
; CALL RAND_WT_SET(WPN_材質_銀, 20)
; MATERIAL = RAND_WT_RESULT()

; ;武器ランク
; CALL RAND_WT_INIT()
; CALL RAND_WT_SET(0, 70)
; CALL RAND_WT_SET(1, 20)
; CALL RAND_WT_SET(2, 10)
; SELECTCASE RAND_WT_RESULT()
;     CASE 0
;         RANK = RAND:2
;     CASE 1
;         RANK = RAND(2, 4)
;     CASE 2
;         RANK = RAND(3, 6)
; ENDSELECT

; ;スキル抽選
; CALL QST_WEAPON_GACHA_SKILL_PASSIVE(CATEGORY, TABLE_RANK)
; DIC_WPN_PASSIVE = %RESULTS%
; CALL QST_WEAPON_GACHA_SKILL_ACTIVE(CATEGORY, TABLE_RANK)
; DIC_WPN_ACTIVE = %RESULTS%

; ;武器名
; CALL GET_WEAPON_NAME(WEAPON_ID)
; WEAPON_NAME '= @"%WPN_材質別接頭文字:MATERIAL%の%RESULTS%"

; CALL QST_GET_WEAPON(WEAPON_ID, WEAPON_NAME, MATERIAL, RANK, DIC_WPN_PASSIVE, DIC_WPN_ACTIVE)

; @QST_WEAPON_GACHA_SKILL_PASSIVE(CATEGORY, TABLE_RANK = 0)
; #DIMS CATEGORY
; #DIM  TABLE_RANK
; #DIMS DYNAMIC LIST_SKILL_LOTO_TARGET
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_PASSIVE
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_ACTIVE
; #DIMS DYNAMIC DIC_WPN_PASSIVE
; #DIMS DYNAMIC SKILL_DEF_NAME
; #DIM  DYNAMIC MAX_SKILL_LV
; #DIM  DYNAMIC SKILL_LV
; {
;     #DIMS CONST LIST_PASSIVE_SHORT_SWORD =
;         "WPN_UPWARD_ARMOR_DECAY"
;         ,"WPN_ADDITIONAL_ATTACK"
;         ,"WPN_ADD_POISON"
; }
; {
;     #DIMS CONST LIST_PASSIVE_LONG_SWORD =
;         "WPN_TRAMPLE"
;         ,"WPN_ADD_POISON"
; }
; {
;     #DIMS CONST LIST_PASSIVE_AXE =
;         "WPN_TRAMPLE"
;         ,"WPN_ADD_POISON"
; }

; VARSET RESULTS
; SIF !EXISTVAR(@"LIST_PASSIVE_%CATEGORY%")
;     RETURN 0

; ;武器スキル_パッシブ
; FOR LOCAL, 0, VARSIZE(@"LIST_PASSIVE_%CATEGORY%")
;     LIST_SKILL_LOTO_TARGET = %LIST_ADD(LIST_SKILL_LOTO_TARGET, GETVARS(@"LIST_PASSIVE_%CATEGORY%:{LOCAL}"))%
; NEXT
; CALL LIST_SHUFFLE(LIST_SKILL_LOTO_TARGET)
; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_TARGET)
;     SIF RAND(0, 100) < 75 - LOCAL * 45
;         BREAK
;     LIST_SKILL_LOTO_RESULT_PASSIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_PASSIVE, LIST_GET(LIST_SKILL_LOTO_TARGET, LOCAL))%
; NEXT

; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_RESULT_PASSIVE)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_RESULT_PASSIVE, LOCAL)%
;     CALLF GET_SKILL_DATA(SKILL_DEF_NAME, "maxlv", 1, 武器スキル_パッシブ)
;     SIF RESULTS == ""
;         CONTINUE
;     MAX_SKILL_LV = TOINT(RESULTS)
;     CALL RAND_WT_INIT()
;     CALL RAND_WT_SET(1, 75)
;     CALL RAND_WT_SET(2, 20)
;     CALL RAND_WT_SET(3, 5)
;     SKILL_LV = MIN(RAND_WT_RESULT(), MAX_SKILL_LV)
;     DIC_WPN_PASSIVE = %DIC_SET(DIC_WPN_PASSIVE, SKILL_DEF_NAME, TOSTR(SKILL_LV))%
; NEXT

; RESULTS = %DIC_WPN_PASSIVE%
; RETURN

; @QST_WEAPON_GACHA_SKILL_ACTIVE(CATEGORY, TABLE_RANK = 0)
; #DIMS CATEGORY
; #DIM  TABLE_RANK
; #DIMS DYNAMIC LIST_SKILL_LOTO_TARGET
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_ACTIVE
; #DIMS DYNAMIC DIC_WPN_ACTIVE
; #DIMS DYNAMIC SKILL_DEF_NAME
; #DIM  DYNAMIC MAX_SKILL_LV
; #DIM  DYNAMIC SKILL_LV
; {
;     #DIMS CONST LIST_ACTIVE_LONG_SWORD =
;         "WPN_SMITE"
; }
; {
;     #DIMS CONST LIST_ACTIVE_AXE =
;         "WPN_SMITE"
; }
; {
;     #DIMS CONST LIST_ACTIVE_GUN =
;         "WPN_HARDSHOT"
; }

; VARSET RESULTS
; SIF !EXISTVAR(@"LIST_ACTIVE_%CATEGORY%")
;     RETURN 0

; ;武器スキル_アクティブ
; FOR LOCAL, 0, VARSIZE(@"LIST_ACTIVE_%CATEGORY%")
;     LIST_SKILL_LOTO_TARGET = %LIST_ADD(LIST_SKILL_LOTO_TARGET, GETVARS(@"LIST_ACTIVE_%CATEGORY%:{LOCAL}"))%
; NEXT
; CALL LIST_SHUFFLE(LIST_SKILL_LOTO_TARGET)
; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_TARGET)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_TARGET, LOCAL)%
;     ;武器種毎の確定枠
;     SELECTCASE CATEGORY
;         CASE "GUN"
;             IF SKILL_DEF_NAME == "WPN_HARDSHOT"
;                 LIST_SKILL_LOTO_RESULT_ACTIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_ACTIVE, SKILL_DEF_NAME)%
;                 CONTINUE
;             ENDIF
;     ENDSELECT
;     ;抽選枠
;     SIF RAND(0, 100) < 75 - LOCAL * 45
;         BREAK
;     LIST_SKILL_LOTO_RESULT_ACTIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_ACTIVE, SKILL_DEF_NAME)%
; NEXT

; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_RESULT_ACTIVE)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_RESULT_ACTIVE, LOCAL)%
;     CALLF GET_SKILL_DATA(SKILL_DEF_NAME, "maxlv", 1, 武器スキル_アクティブ)
;     DEBUGPRINTFORML %SKILL_DEF_NAME%MAX_LV = %RESULTS%
;     SIF RESULTS == ""
;         CONTINUE
;     MAX_SKILL_LV = TOINT(RESULTS)
;     CALL RAND_WT_INIT()
;     CALL RAND_WT_SET(1, 75)
;     CALL RAND_WT_SET(2, 20)
;     CALL RAND_WT_SET(3, 5)
;     SKILL_LV = MIN(RAND_WT_RESULT(), MAX_SKILL_LV)
;     DIC_WPN_ACTIVE = %DIC_SET(DIC_WPN_ACTIVE, SKILL_DEF_NAME, TOSTR(SKILL_LV))%
; NEXT

; RESULTS = %DIC_WPN_ACTIVE%
; RETURN
; ; #endregion

; ;-------------------------------------------------
; ; 汎用レリックガチャ
; ;-------------------------------------------------
; ;武器の抽選
; ; #region @QST_WEAPON_GACHA
; @QST_RELIC_GACHA(TABLE_RANK = 0)
; #DIM TABLE_RANK
; #DIMS DYNAMIC DIC_WPN_PASSIVE
; #DIMS DYNAMIC DIC_WPN_ACTIVE
; #DIM  DYNAMIC WEAPON_ID
; #DIMS DYNAMIC WEAPON_NAME
; #DIMS DYNAMIC CATEGORY
; #DIM  DYNAMIC MATERIAL
; #DIM  DYNAMIC RANK

; CATEGORY = %S_R("BRACELET/AMULET/NECKLACE/BOOTS/SHIELD/RING")%
; ;武器種ID
; SELECTCASE CATEGORY
;     CASE "BRACELET"
;         WEAPON_ID = 1
;     CASE "AMULET"
;         WEAPON_ID = 2
;     CASE "NECKLACE"
;         WEAPON_ID = 3
;     CASE "BOOTS"
;         WEAPON_ID = 4
;     CASE "SHIELD"
;         WEAPON_ID = 5
;     CASE "RING"
;         WEAPON_ID = 6
; ENDSELECT

; ;武器の材質
; CALL RAND_WT_INIT()
; IF TABLE_RANK < 1
;     CALL RAND_WT_SET(WPN_材質_銅, 60)
; ENDIF
; CALL RAND_WT_SET(WPN_材質_鉄, 40)
; CALL RAND_WT_SET(WPN_材質_鋼, 20)
; CALL RAND_WT_SET(WPN_材質_銀, 10)
; CALL RAND_WT_SET(WPN_材質_金, 2)
; MATERIAL = RAND_WT_RESULT()

; ;武器ランク
; CALL RAND_WT_INIT()
; IF TABLE_RANK < 1
;     CALL RAND_WT_SET(0, 60)
; ENDIF
; CALL RAND_WT_SET(1, 20)
; CALL RAND_WT_SET(2, 15)
; CALL RAND_WT_SET(3, 10 + TABLE_RANK * 5)
; CALL RAND_WT_SET(4, 5  + TABLE_RANK * 5)

; SELECTCASE RAND_WT_RESULT()
;     CASE 0
;         RANK = RAND:2
;     CASE 1
;         RANK = RAND(2, 4)
;     CASE 2
;         RANK = RAND(3, 6)
; ENDSELECT

; ;スキル抽選
; CALL QST_RELIC_GACHA_SKILL_PASSIVE(CATEGORY, TABLE_RANK)
; DIC_WPN_PASSIVE = %RESULTS%
; CALL QST_RELIC_GACHA_SKILL_ACTIVE(CATEGORY, TABLE_RANK)
; DIC_WPN_ACTIVE = %RESULTS%

; ;武器名
; CALL GET_WEAPON_NAME(WEAPON_ID, 1)
; WEAPON_NAME '= @"%WPN_材質別接頭文字:MATERIAL%の%RESULTS%"

; CALL QST_GET_WEAPON(WEAPON_ID, WEAPON_NAME, MATERIAL, RANK, DIC_WPN_PASSIVE, DIC_WPN_ACTIVE, 1)

; @QST_RELIC_GACHA_SKILL_PASSIVE(CATEGORY, TABLE_RANK = 0)
; #DIMS CATEGORY
; #DIM  TABLE_RANK
; #DIMS DYNAMIC LIST_SKILL_LOTO_TARGET
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_PASSIVE
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_ACTIVE
; #DIMS DYNAMIC DIC_WPN_PASSIVE
; #DIMS DYNAMIC SKILL_DEF_NAME
; #DIM  DYNAMIC MAX_SKILL_LV
; #DIM  DYNAMIC SKILL_LV
; {
;     #DIMS CONST LIST_PASSIVE_BRACELET =
;         "WPN_UPWARD_ARMOR_DECAY"
;         ,"WPN_ADD_POISON"
; }
; {
;     #DIMS CONST LIST_PASSIVE_AMULET =
;         "WPN_ADD_SONG_AT_START"
;         ,"WPN_MAG_DEFENCE_UP"
; }
; {
;     #DIMS CONST LIST_PASSIVE_NECKLACE =
;         "WPN_DECOY_AMPLIFIER"
;         ,"WPN_MAG_DEFENCE_UP"
; }
; {
;     #DIMS CONST LIST_PASSIVE_BOOTS =
;         "WPN_TRAMPLE"
;         ,"WPN_ADDITIONAL_ATTACK"
; }
; {
;     #DIMS CONST LIST_PASSIVE_SHIELD =
;         "WPN_MAG_DEFENCE_UP"
; }
; {
;     #DIMS CONST LIST_PASSIVE_RING =
;         "WPN_ADD_CAST_AT_START"
; }
; {
;     #DIMS COST_LIST_PASSIVE_STATUS_BOOST_ATK =
;         "WPN_DEF_PENETRATE"
;         ,"WPN_MAG_PENETRATE"
;         ,"WPN_ATK_BONUS"
;         ,"WPN_MAG_BONUS"
; }
; {
;     #DIMS COST_LIST_PASSIVE_STATUS_BOOST_DEF =
;         "WPN_ARMOR_BONUS"
;         ,"WPN_BOOST_REGIST_STUN"
;         ,"WPN_BOOST_REGIST_POISON"
;         ,"WPN_BOOST_REGIST_BURN"
; }

; VARSET RESULTS
; SIF !EXISTVAR(@"LIST_PASSIVE_%CATEGORY%")
;     RETURN 0

; ;武器スキル_パッシブ
; FOR LOCAL, 0, VARSIZE(@"LIST_PASSIVE_%CATEGORY%")
;     LIST_SKILL_LOTO_TARGET = %LIST_ADD(LIST_SKILL_LOTO_TARGET, GETVARS(@"LIST_PASSIVE_%CATEGORY%:{LOCAL}"))%
; NEXT
; CALL LIST_SHUFFLE(LIST_SKILL_LOTO_TARGET)
; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_TARGET)
;     SIF RAND(0, 100) < 75 - LOCAL * 45
;         BREAK
;     LIST_SKILL_LOTO_RESULT_PASSIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_PASSIVE, LIST_GET(LIST_SKILL_LOTO_TARGET, LOCAL))%
; NEXT

; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_RESULT_PASSIVE)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_RESULT_PASSIVE, LOCAL)%
;     CALLF GET_SKILL_DATA(SKILL_DEF_NAME, "maxlv", 1, 武器スキル_パッシブ)
;     SIF RESULTS == ""
;         CONTINUE
;     MAX_SKILL_LV = TOINT(RESULTS)
;     CALL RAND_WT_INIT()
;     CALL RAND_WT_SET(1, 95)
;     CALL RAND_WT_SET(2, 5)
;     SKILL_LV = MIN(RAND_WT_RESULT(), MAX_SKILL_LV)
;     DIC_WPN_PASSIVE = %DIC_SET(DIC_WPN_PASSIVE, SKILL_DEF_NAME, TOSTR(SKILL_LV))%
; NEXT

; RESULTS = %DIC_WPN_PASSIVE%
; RETURN

; @QST_RELIC_GACHA_SKILL_ACTIVE(CATEGORY, TABLE_RANK = 0)
; #DIMS CATEGORY
; #DIM  TABLE_RANK
; #DIMS DYNAMIC LIST_SKILL_LOTO_TARGET
; #DIMS DYNAMIC LIST_SKILL_LOTO_RESULT_ACTIVE
; #DIMS DYNAMIC DIC_WPN_ACTIVE
; #DIMS DYNAMIC SKILL_DEF_NAME
; #DIM  DYNAMIC MAX_SKILL_LV
; #DIM  DYNAMIC SKILL_LV
; {
;     #DIMS CONST LIST_ACTIVE_BRACELET =
;         "WPN_RECOVER_STUN_ALL"
;         ,"WPN_ADD_FRAGILE"
; }
; {
;     #DIMS CONST LIST_ACTIVE_AMULET =
;         "WPN_ADD_CAST_SELF"
;         ,"WPN_MAG_DEFENCE_UP"
; }
; {
;     #DIMS CONST LIST_ACTIVE_NECKLACE =
;         "WPN_RECOVER_STUN_ALL"
;         ,"WPN_ADD_MAG_GUARD"
; }
; ; {
; ;     #DIMS CONST LIST_ACTIVE_BOOTS =
; ;         ""
; ; }
; {
;     #DIMS CONST LIST_ACTIVE_SHIELD =
;         "WPN_ADD_MAG_GUARD"
;         ,"WPN_FRONT_DEFENCE"
; }
; {
;     #DIMS CONST LIST_ACTIVE_RING =
;         "WPN_ADD_CAST_SELF"
; }

; VARSET RESULTS
; SIF !EXISTVAR(@"LIST_ACTIVE_%CATEGORY%")
;     RETURN 0

; ;武器スキル_アクティブ
; FOR LOCAL, 0, VARSIZE(@"LIST_ACTIVE_%CATEGORY%")
;     LIST_SKILL_LOTO_TARGET = %LIST_ADD(LIST_SKILL_LOTO_TARGET, GETVARS(@"LIST_ACTIVE_%CATEGORY%:{LOCAL}"))%
; NEXT
; CALL LIST_SHUFFLE(LIST_SKILL_LOTO_TARGET)
; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_TARGET)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_TARGET, LOCAL)%
;     ; ;武器種毎の確定枠
;     ; SELECTCASE CATEGORY
;     ;     CASE "GUN"
;     ;         IF SKILL_DEF_NAME == "WPN_HARDSHOT"
;     ;             LIST_SKILL_LOTO_RESULT_ACTIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_ACTIVE, SKILL_DEF_NAME)%
;     ;             CONTINUE
;     ;         ENDIF
;     ; ENDSELECT
;     ;抽選枠
;     SIF RAND(0, 100) < 75 - LOCAL * 45
;         BREAK
;     LIST_SKILL_LOTO_RESULT_ACTIVE = %LIST_ADD(LIST_SKILL_LOTO_RESULT_ACTIVE, SKILL_DEF_NAME)%
; NEXT

; FOR LOCAL, 0, LIST_COUNT(LIST_SKILL_LOTO_RESULT_ACTIVE)
;     SKILL_DEF_NAME = %LIST_GET(LIST_SKILL_LOTO_RESULT_ACTIVE, LOCAL)%
;     CALLF GET_SKILL_DATA(SKILL_DEF_NAME, "maxlv", 1, 武器スキル_アクティブ)
;     DEBUGPRINTFORML %SKILL_DEF_NAME%MAX_LV = %RESULTS%
;     SIF RESULTS == ""
;         CONTINUE
;     MAX_SKILL_LV = TOINT(RESULTS)
;     CALL RAND_WT_INIT()
;     CALL RAND_WT_SET(1, 95)
;     CALL RAND_WT_SET(2, 5)
;     ;CALL RAND_WT_SET(3, 5)
;     SKILL_LV = MIN(RAND_WT_RESULT(), MAX_SKILL_LV)
;     DIC_WPN_ACTIVE = %DIC_SET(DIC_WPN_ACTIVE, SKILL_DEF_NAME, TOSTR(SKILL_LV))%
; NEXT

; RESULTS = %DIC_WPN_ACTIVE%
; RETURN
; ; #endregion


code:
;-------------------------------------------------
;クエストモードでは未探索のルーム情報を伏せる
;-------------------------------------------------
@QST_SET_FOG_OF_WAR(ROOM_IDX = -1)
#DIM ROOM_IDX
IF ROOM_IDX == -1
    FOR LOCAL, 0, HO_MAX_ROOMNUM
        CALL HO_SET_MAPDATA(LOCAL, "FOG_OF_WAR", "1")
    NEXT
ELSE
    CALL HO_SET_MAPDATA(ROOM_IDX, "FOG_OF_WAR", "1")
ENDIF

;対象ROOM_IDXの戦場の霧を晴らす
;ARG:1が0以外の場合、隣接するルームも晴らす
;マップデータ定義で[IS_HIDDEN_ROOM:1]が指定されている場合は隣接ルーム晴らしから除外
@QST_CLEAR_FOG_OF_WAR(ROOM_IDX, 対象のみ = 0)
#DIM ROOM_IDX
#DIM 対象のみ
#DIMS DYNAMIC _LIST_ROOM_PATH
CALL HO_GET_PATH(ROOM_IDX)
_LIST_ROOM_PATH = %RESULTS%
CALL HO_SET_MAPDATA(ROOM_IDX, "FOG_OF_WAR", "0")
IF !対象のみ
    FOR LOCAL, 0, LIST_COUNT(_LIST_ROOM_PATH)
        CALL HO_GET_MAPDATA(HO_有効マップID, TOINT(LIST_GET(_LIST_ROOM_PATH, LOCAL)), "IS_HIDDEN_ROOM")
        SIF RESULT == 1
            CONTINUE
        CALL HO_SET_MAPDATA(TOINT(LIST_GET(_LIST_ROOM_PATH, LOCAL)), "FOG_OF_WAR", "0")
    NEXT
ENDIF

;-------------------------------------------------
;クエストの探索状態を保持する
;-------------------------------------------------
;探索済ルームの情報を開示
@QST_EXPLORED_ROOMS_DISCLOSURE()
#DIM  DYNAMIC QUEST_ID

QUEST_ID = QST_有効クエストID

;探索状態を保持しないクエスト中は追加しない
IF !QST_SAVE_EXPLORED
    RETURN
ENDIF

;デバッグ用表示:ルームIDXを表示
DEBUGPRINTL 探索済ルームIDX

;探索済ルームリストに設定されているルームの霧を晴らす
CALL LIST_FOREACH(QST_LIST_EXPLORED_ROOM:QUEST_ID, "QST_LIST_EXPLORED_ROOM_FOREACH_CLEAR_FOG_ROOM")

;-------------------------------------------------
;探索済ルームリストに設定されているルームの霧を晴らす(LIST_FOREACH用関数)
@QST_LIST_EXPLORED_ROOM_FOREACH_CLEAR_FOG_ROOM(STR_ROOM_IDX)
#DIMS STR_ROOM_IDX
;デバッグ用表示:ルームIDXを表示
DEBUGPRINTFORM %STR_ROOM_IDX%,
;霧を晴らす
CALL QST_CLEAR_FOG_OF_WAR(TOINT(STR_ROOM_IDX))

;-------------------------------------------------
;クエストの探索状態保持設定の取得
@QST_GET_QST_SAVE_EXPLORED()
#DIM DYNAMIC QUEST_ID

QUEST_ID = QST_有効クエストID

;クエストごとの探索状態保持設定の関数をチェック
TRYCCALLFORM QST_QUEST_{QUEST_ID}_SAVE_EXPLORED()
    QST_SAVE_EXPLORED = RESULT
    DEBUGPRINTFORML FUNCTION "QST_QUEST_{QUEST_ID}_SAVE_EXPLORED" EXIST
    DEBUGPRINTFORML QST_SAVE_EXPLORED: {QST_SAVE_EXPLORED}
CATCH
    ;関数がない場合は探索状態を保持しない
    QST_SAVE_EXPLORED = 0
    DEBUGPRINTFORML FUNCTION "QST_QUEST_{QUEST_ID}_SAVE_EXPLORED" NOT EXIST
ENDCATCH

;-------------------------------------------------
;探索済ルームをリストに追加
@QST_ADD_LIST_EXPLORED_ROOM(ROOM_IDX, FORCED = 0)
#DIM  ROOM_IDX
#DIM  FORCED
#DIMS DYNAMIC STR_ROOM_IDX
#DIM  DYNAMIC QUEST_ID
#DIM  DYNAMIC NOT_SAVE_EXPLORED
#DIM  DYNAMIC MAP_ID

QUEST_ID = QST_有効クエストID
MAP_ID   = HO_有効マップID
STR_ROOM_IDX '= TOSTR(ROOM_IDX)

;探索状態を保持しないクエスト中は追加しない
IF !QST_SAVE_EXPLORED
    RETURN
ENDIF

;「探索状態を保持しない」設定がされているルームは追加しない
;・設定がされていない(0:設定なし, -1:未定義)ルームは追加する
;・強制設定フラグがONの場合はルーム設定を無視して追加する
IF !FORCED
    CALL HO_GET_MAPDATA(MAP_ID, ROOM_IDX, "NOT_SAVE_EXPLORED")
    NOT_SAVE_EXPLORED = RESULT
    IF !GROUPMATCH(NOT_SAVE_EXPLORED , 0, -1)
        RETURN
    ENDIF
ENDIF

;既に探索済ルームリストに追加済の場合は追加しない(重複追加防止)
IF LIST_INDEXOF(QST_LIST_EXPLORED_ROOM:QUEST_ID, STR_ROOM_IDX) != -1
    RETURN
ENDIF

;探索済ルームリストにルームIDXを追加
QST_LIST_EXPLORED_ROOM:QUEST_ID '= LIST_ADD(QST_LIST_EXPLORED_ROOM:QUEST_ID, STR_ROOM_IDX)

;-------------------------------------------------
;探索済ルームをリストから削除
@QST_REMOVE_LIST_EXPLORED_ROOM(ROOM_IDX)
#DIM  ROOM_IDX
#DIMS DYNAMIC STR_ROOM_IDX
#DIM  DYNAMIC QUEST_ID

QUEST_ID = QST_有効クエストID
STR_ROOM_IDX '= TOSTR(ROOM_IDX)

QST_LIST_EXPLORED_ROOM:QUEST_ID '= LIST_REMOVEALL(QST_LIST_EXPLORED_ROOM:QUEST_ID, STR_ROOM_IDX)

;-------------------------------------------------
;探索済ルームリストの件数を取得
@QST_GET_LIST_EXPLORED_ROOM_COUNT()
#FUNCTION
#DIM  DYNAMIC QUEST_ID

QUEST_ID = QST_有効クエストID

RETURNF LIST_COUNT(QST_LIST_EXPLORED_ROOM:QUEST_ID)

;-------------------------------------------------
;ルーム設定「探索状態を保持しない」
;-------------------------------------------------
@QST_SET_ROOM_NOT_SAVE_EXPLORED(ROOM_IDX = -1)
#DIM ROOM_IDX
CALL HO_SET_MAPDATA(ROOM_IDX, "NOT_SAVE_EXPLORED", "1")

@QST_CLEAR_ROOM_NOT_SAVE_EXPLORED(ROOM_IDX = -1)
#DIM ROOM_IDX
CALL HO_SET_MAPDATA(ROOM_IDX, "NOT_SAVE_EXPLORED", "0")

;-------------------------------------------------
;クエスト用コンパニオン追加関数
;-------------------------------------------------
@QST_ADD_COMPANION(CHARA_ID)
#DIM CHARA_ID
#DIMS DYNAMIC _LIST_COMPANION

VARSET RESULTS

SIF CHARA_ID == MASTER
    RETURN 0

CFLAG:CHARA_ID:調教参加フラグ = 1
TFLAG:参加者数 ++
CALL HO_SET_CHARAACT(CHARA_ID, "同行中")

;リストの管理
CALL HO_GET_MASTER_DATA("COMPANION_LIST")
_LIST_COMPANION = %RESULTS%
IF LIST_INDEXOF(_LIST_COMPANION, TOSTR(CHARA_ID)) == -1
    _LIST_COMPANION = %LIST_ADD(_LIST_COMPANION, TOSTR(CHARA_ID))%
    CALL HO_SET_MASTER_DATA("COMPANION_LIST", _LIST_COMPANION)
ELSE
    THROW 同一キャラを多重に登録しようとしました CHARA_ID{CHARA_ID}
ENDIF
;広域変数のパーティリストに対象を追加
;_LIST_QST_PARTY = %LIST_ADD(_LIST_QST_PARTY, TOSTR(CHARA_ID))%
RETURN 1

;-------------------------------------------------
;入室時に自動実行されるタイプのイベントを呼び出す
@QST_EXEC_ENTER_EVENT(ROOM_IDX)
#DIM ROOM_IDX
#DIM  DYNAMIC EVENT_ROOM_IDX
#DIM  DYNAMIC EVENT_LIST_IDX
#DIMS DYNAMIC _LIST_EVENT_LIST
#DIMS DYNAMIC EVENT_TRIGGER
#DIMS DYNAMIC EVENT_TYPE
#DIM DYNAMIC  IS_EVENT_EXECUTED
#DIMS DYNAMIC EVENT_STATE

FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "ROOM_IDX")
    EVENT_ROOM_IDX = RESULT
    IF ROOM_IDX == EVENT_ROOM_IDX
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TRIGGER")
        EVENT_TRIGGER = %RESULTS%

        IF EVENT_TRIGGER == "ENTER_ROOM" || EVENT_TRIGGER == "COLIDE_PLAYER"
            ;EVENT_TYPEが"ONCE"かつ実行済みのイベントは実行しない
            CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TYPE")
            EVENT_TYPE = %RESULTS%
            CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "IS_EVENT_EXECUTED")
            IS_EVENT_EXECUTED = RESULT
            CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE")
            EVENT_STATE = %RESULTS%
            SIF (EVENT_TYPE == "ONCE" && IS_EVENT_EXECUTED == 1) || EVENT_STATE == "DEACTIVE"
                RETURN
            CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
            PRINTL
            QST_NOWEV_LIST_IDX = EVENT_LIST_IDX
            QST_NOWEV = RESULT
            TRYCCALLFORM  QST_QUEST_{QST_有効クエストID}_EVENT_{QST_NOWEV}
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "IS_EVENT_EXECUTED", "1")
            CATCH
                QST_NOWEV_LIST_IDX = -1
            ENDCATCH
        ENDIF
    ENDIF
NEXT

CALL QST_EVENTEND()

@QST_EXEC_EVENT_PAWN_COLIDE(ROOM_IDX, EVENT_LIST_IDX)
#DIM  ROOM_IDX
#DIM  EVENT_LIST_IDX
#DIM  DYNAMIC EVENT_ROOM_IDX
#DIMS DYNAMIC _LIST_EVENT_LIST
#DIMS DYNAMIC EVENT_TRIGGER
#DIMS DYNAMIC EVENT_TYPE
#DIM DYNAMIC  IS_EVENT_EXECUTED
#DIMS DYNAMIC EVENT_STATE

CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "ROOM_IDX")
EVENT_ROOM_IDX = RESULT
IF ROOM_IDX == EVENT_ROOM_IDX
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TRIGGER")
    EVENT_TRIGGER = %RESULTS%

    IF EVENT_TRIGGER == "COLIDE_PLAYER"
        ;EVENT_TYPEが"ONCE"かつ実行済みのイベントは実行しない
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TYPE")
        EVENT_TYPE = %RESULTS%
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "IS_EVENT_EXECUTED")
        IS_EVENT_EXECUTED = RESULT
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE")
        EVENT_STATE = %RESULTS%
        SIF (EVENT_TYPE == "ONCE" && IS_EVENT_EXECUTED == 1) || EVENT_STATE == "DEACTIVE"
            RETURN
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
        PRINTL
        QST_NOWEV_LIST_IDX = EVENT_LIST_IDX
        QST_NOWEV = RESULT
        TRYCCALLFORM  QST_QUEST_{QST_有効クエストID}_EVENT_{QST_NOWEV}
            CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "IS_EVENT_EXECUTED", "1")
        CATCH
            QST_NOWEV_LIST_IDX = -1
        ENDCATCH
    ENDIF
ENDIF

CALL QST_EVENTEND()

;-------------------------------------------------
;イベントスロットのボタンクリック時に呼び出されるイベントを呼び出す
@QST_EXEC_EVENT_SLOT_EVENT(EVENT_LIST_IDX)
#DIM  DYNAMIC EVENT_LIST_IDX
#DIMS DYNAMIC _LIST_EVENT_LIST

QST_NOWEV_LIST_IDX = EVENT_LIST_IDX
CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
QST_NOWEV = RESULT
PRINTL
TRYCALLFORM QST_QUEST_{QST_有効クエストID}_EVENT_{QST_NOWEV}

CALL QST_EVENTEND()
;全滅したか、スロットイベントが調教イベントを起動した場合、コモンイベントの呼び出しは実施しない
IF RESULT || FLAG:ウフフフラグ
    RETURN
ENDIF
CALL QST_EVENT_汎用イベント

;-------------------------------------------------
;イベントリスト管理関数
;-------------------------------------------------
@QST_SET_EVENT_LIST(EVENT_LIST_IDX, DATANAME, VALUES, MAP_ID = -1)
#DIM  EVENT_LIST_IDX
#DIMS DATANAME
#DIMS VALUES
#DIM  MAP_ID

SIF MAP_ID == -1
    MAP_ID = HO_有効マップID
SIF _DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX == "-1"
    _DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX '= ""

_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX = %DIC_SET(_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX, DATANAME, VALUES)%
RETURN

@QST_GET_EVENT_LIST(EVENT_LIST_IDX, DATANAME, MAP_ID = -1)
#DIM MAP_ID
#DIM EVENT_LIST_IDX
#DIM ROOM_IDX
#DIMS DATANAME

SIF MAP_ID == -1
    MAP_ID = HO_有効マップID

VARSET RESULTS
SIF DIC_GET(_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX, DATANAME) == ""
    RETURN -1

ISNUMERIC DIC_GET(_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX, DATANAME)
IF RESULT
    RETURN TOINT(DIC_GET(_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX, DATANAME))
ELSE
    RESULTS = %DIC_GET(_DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX, DATANAME)%
    RETURN
ENDIF

;-------------------------------------------------
;イベントリストに登録されたイベントのフラグ管理
;-------------------------------------------------
@QST_SET_EVENT_FLAG(EVENT_ID, VALUE)
#DIM EVENT_ID
#DIM VALUE
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
    TARGET_EVENT_ID = RESULT
    IF EVENT_ID == TARGET_EVENT_ID
        CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_FLAG", TOSTR(VALUE))
        RETURN 1
    ENDIF
NEXT
RETURN 0

@QST_GET_EVENT_FLAG(EVENT_ID)
#DIM EVENT_ID
#DIM VALUE
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
    TARGET_EVENT_ID = RESULT
    IF EVENT_ID == TARGET_EVENT_ID
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_FLAG")
        SIF RESULT == -1
            RESULT = 0
        RETURN RESULT
    ENDIF
NEXT
RETURN 0

;EVENT_IDではイベントを一意に識別できない場合、こちらを使用する
;QST_NOWEV_LIST_IDXはイベント実行直前にセットされる
@QST_SET_EVENT_FLAG_BY_IDX(VALUE)
#DIM VALUE
SIF VALUE == -1
    RETURN 0
CALL QST_SET_EVENT_LIST(QST_NOWEV_LIST_IDX, "EVENT_FLAG", TOSTR(VALUE))
RETURN 1

@QST_GET_EVENT_FLAG_BY_IDX()
CALL QST_GET_EVENT_LIST(QST_NOWEV_LIST_IDX, "EVENT_FLAG")
SIF RESULT == -1
    RETURN 0
RETURN RESULT

;セーブデータに保持されるフラグ管理変数
@QST_SET_SV_EVENT_FLAG(EVENT_ID, VALUE)
#DIM EVENT_ID
#DIM VALUE
QST_SV_EVENT_FLAG:QST_有効クエストID:EVENT_ID = VALUE
RETURN

@QST_GET_SV_EVENT_FLAG(EVENT_ID)
#DIM EVENT_ID
RETURN QST_SV_EVENT_FLAG:QST_有効クエストID:EVENT_ID

;式中関数版
@QST_GET_SV_EVENT_FLAGF(EVENT_ID)
#FUNCTION
#DIM EVENT_ID
RETURNF QST_SV_EVENT_FLAG:QST_有効クエストID:EVENT_ID

;-------------------------------------------------
;;; フラグ連想配列管理用
;;; 実行中のクエスト専用のフラグ連想配列に任意のキー：値のペアを格納できる
;;; 呼び出しは @QST_GET_FLAGMAPを使用する
;;; クエスト終了時に初期化される点に注意
;;;
;;; 【特殊なフラグ】
;;; 以下の固定キーに値をセットすると、特定のタイミングで所定の処理が実行される
;;;
;;; - EVENTCOMEND_CALLEE
;;; 値をセットすると、コマンド実行時に毎回値に指定した関数が呼び出される
;;; ※呼び出し不要となった場合は明示的に値をクリアすること
;;;
;;; - EVENTCOMEND_CALLEE_ONCE
;;; 値をセットすると、コマンド実行時に一度だけ指定した関数が呼び出される
;;; ※呼び出し後に自動的にクリアされるため、明示的なクリアは不要
;;;
;;; - TRAIN_EXIT_CALLEE
;;; 値をセットすると、調教終了時にその値に対応した関数が呼び出される
;;; ※呼び出し後に自動的にクリアされるため、明示的なクリアは不要
;;;
;-------------------------------------------------
@QST_SET_FLAGMAP(KEYS, VALUES)
#DIMS KEYS
#DIMS VALUES
MAP_SET @"QUEST_{QST_有効クエストID}_MAP", KEYS, VALUES

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

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

CURRENT_VALUE = QST_GETINT_FLAGMAP(KEYS)
CALL QST_SETINT_FLAGMAP(KEYS, CURRENT_VALUE + ADD_VALUE)

;;; @QST_SET_FLAGMAPでセットしたフラグ変数を取得する
@QST_GET_FLAGMAP(KEYS)
#FUNCTIONS
#DIMS KEYS
RETURNF MAP_GET(@"QUEST_{QST_有効クエストID}_MAP", KEYS)

;;; @QST_SET_FLAGMAPでセットしたフラグ変数を数値変換して取得する
@QST_GETINT_FLAGMAP(KEYS)
#FUNCTION
#DIMS KEYS
RETURNF TOINT(QST_GET_FLAGMAP(KEYS))

;;; @QST_SET_FLAGMAPでセットしたフラグ変数を削除する
@QST_REMOVE_FLAGMAP(KEYS)
#DIMS KEYS
MAP_REMOVE @"QUEST_{QST_有効クエストID}_MAP", KEYS

;-------------------------------------------------
;イベントの活性、非活性
;-------------------------------------------------
@QST_ACTIVATE_EVENT(EVENT_ID)
#DIM EVENT_ID
#DIM VALUE
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
    TARGET_EVENT_ID = RESULT
    IF EVENT_ID == TARGET_EVENT_ID
        CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE", "ACTIVE")
        RETURN 1
    ENDIF
NEXT
RETURN 0

;-------------------------------------------------
;;; イベント非活性化
;;; ※QST_ADD_EVENT_QUEST_XX_EVENT_XXから呼び出した場合は
;;; 呼び出し元イベントIDのみ非活性化可能(指定先EVENT_IDの登録状況を保証出来ないため)
;-------------------------------------------------
@QST_DEACTIVATE_EVENT(EVENT_ID)
#DIM EVENT_ID
#DIM VALUE
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
    CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
    TARGET_EVENT_ID = RESULT
    IF EVENT_ID == TARGET_EVENT_ID
        CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE", "DEACTIVE")
        RETURN 1
    ENDIF
NEXT
RETURN 0

@QST_DEACTIVATE_THIS_EVENT()
CALL QST_SET_EVENT_LIST(QST_NOWEV_LIST_IDX, "EVENT_STATE", "DEACTIVE")

;-------------------------------------------------
;イベントスロット上に表示するイベント名を変更する
;EVENT_IDが未指定の場合、現在実行しているイベントの名称を変更する
;-------------------------------------------------
@QST_SET_EVENT_SLOT_NAME(EVENT_ID = -1, EVENT_SLOT_NAME)
#DIM EVENT_ID
#DIMS EVENT_SLOT_NAME
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
IF EVENT_ID != -1
    FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
        TARGET_EVENT_ID = RESULT
        IF EVENT_ID == TARGET_EVENT_ID
            CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_SLOT_NAME", EVENT_SLOT_NAME)
            RETURN 1
        ENDIF
    NEXT
ELSE
    CALL QST_SET_EVENT_LIST(QST_NOWEV_LIST_IDX, "EVENT_SLOT_NAME", EVENT_SLOT_NAME)
ENDIF
RETURN 0

;現在設定されているイベント名を取得
@QST_GET_EVENT_SLOT_NAME(EVENT_ID = -1)
#DIM EVENT_ID
#DIM  DYNAMIC EVENT_LIST_IDX
#DIM  DYNAMIC TARGET_EVENT_ID
#DIMS DYNAMIC _LIST_EVENT_LIST
IF EVENT_ID != -1
    FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
        TARGET_EVENT_ID = RESULT
        IF EVENT_ID == TARGET_EVENT_ID
            CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_SLOT_NAME")
            RETURN 1
        ENDIF
    NEXT
ELSE
    CALL QST_GET_EVENT_LIST(QST_NOWEV_LIST_IDX, "EVENT_SLOT_NAME")
ENDIF
RETURN 0

;-------------------------------------------------
;調教終了後イベント呼出用リスト管理
;-------------------------------------------------
@QST_ENQUEUE_TRAIN_EXIT_EVENT(EVENT_ID)
#DIM EVENT_ID
_LIST_QST_TRAIN_EXIT_EVENT = %LIST_ADD(_LIST_QST_TRAIN_EXIT_EVENT, TOSTR(EVENT_ID))%

@QST_ENQUEUE_TRAIN_EXIT_FUNC(FUNCTION_NAME)
#DIMS FUNCTION_NAME
_LIST_QST_TRAIN_EXIT_EVENT = %LIST_ADD(_LIST_QST_TRAIN_EXIT_EVENT, FUNCTION_NAME)%

@QST_DEQUEUE_TRAIN_EXIT_EVENT()
#DIM DYNAMIC EVENT_ID

VARSET RESULTS
SIF LIST_COUNT(_LIST_QST_TRAIN_EXIT_EVENT) == 0
    RETURN -1
;数値がセットされていた場合はEVENT_IDとして返す
IF TOINT(LIST_GET(_LIST_QST_TRAIN_EXIT_EVENT, 0))
    EVENT_ID = TOINT(LIST_GET(_LIST_QST_TRAIN_EXIT_EVENT, 0))
    _LIST_QST_TRAIN_EXIT_EVENT = %LIST_REMOVEAT(_LIST_QST_TRAIN_EXIT_EVENT, 0)%

    RETURN EVENT_ID
ELSE
    ;文字列がセットされていた場合はRESULTSにセットして1を返す
    RESULTS = %LIST_GET(_LIST_QST_TRAIN_EXIT_EVENT, 0)%
    _LIST_QST_TRAIN_EXIT_EVENT = %LIST_REMOVEAT(_LIST_QST_TRAIN_EXIT_EVENT, 0)%
    RETURN 1
ENDIF

;-------------------------------------------------
;;; 指定したマップ画像に変更する
;;; GMAPタイプのクエストのみ有効。指定する画像は RESOURCES/MAPIMAGE/ に予め配置すること
;-------------------------------------------------
@QST_CHANGE_MAP_IMAGE(SPRITE_NAME)
#DIMS SPRITE_NAME
CALL スプライト生成(@"mapimage/%SPRITE_NAME%", SPRITE_NAME)
ME_mapImage = %SPRITE_NAME%
RETURN

;-------------------------------------------------
;;; 指定したエリア間にパスを追加する
;-------------------------------------------------
@QST_ADD_PATH(ROOM_FROM, ROOM_TO)
#DIM  ROOM_FROM
#DIM  ROOM_TO
#DIM  ROOM_IDX_TEMP
#DIMS LIST_PATH

;若い番号のエリアから順に処理
IF ROOM_FROM > ROOM_TO
    ROOM_IDX_TEMP = ROOM_FROM
    ROOM_FROM = ROOM_TO
    ROOM_TO = ROOM_IDX_TEMP
ENDIF

CALL HO_GET_MAPDATA(HO_有効マップID, ROOM_FROM, "ROOM_PATH")
LIST_PATH = %RESULTS%
IF LIST_INDEXOF(LIST_PATH, TOSTR(ROOM_TO)) == -1
    LIST_PATH = %LIST_ADD(LIST_PATH, TOSTR(ROOM_TO))%
ENDIF
CALL HO_SET_MAPDATA(ROOM_FROM, "ROOM_PATH", LIST_PATH)

CALL HO_GET_MAPDATA(HO_有効マップID, ROOM_TO, "ROOM_PATH")
LIST_PATH = %RESULTS%
IF LIST_INDEXOF(LIST_PATH, TOSTR(ROOM_FROM)) == -1
    LIST_PATH = %LIST_ADD(LIST_PATH, TOSTR(ROOM_FROM))%
ENDIF
CALL HO_SET_MAPDATA(ROOM_TO, "ROOM_PATH", LIST_PATH)

;-------------------------------------------------
;;; 指定したエリア間のパスを削除する
;-------------------------------------------------
@QST_REMOVE_PATH(ROOM_FROM, ROOM_TO)
#DIM  ROOM_FROM
#DIM  ROOM_TO
#DIM  ROOM_IDX_TEMP
#DIMS LIST_PATH

;若い番号のエリアから順に処理
IF ROOM_FROM > ROOM_TO
    ROOM_IDX_TEMP = ROOM_FROM
    ROOM_FROM = ROOM_TO
    ROOM_TO = ROOM_IDX_TEMP
ENDIF

CALL HO_GET_MAPDATA(HO_有効マップID, ROOM_FROM, "ROOM_PATH")
LIST_PATH = %RESULTS%
IF LIST_INDEXOF(LIST_PATH, TOSTR(ROOM_TO)) != -1
    LIST_PATH = %LIST_REMOVEALL(LIST_PATH, TOSTR(ROOM_TO))%
ENDIF
CALL HO_SET_MAPDATA(ROOM_FROM, "ROOM_PATH", LIST_PATH)

CALL HO_GET_MAPDATA(HO_有効マップID, ROOM_TO, "ROOM_PATH")
LIST_PATH = %RESULTS%
IF LIST_INDEXOF(LIST_PATH, TOSTR(ROOM_FROM)) != -1
    LIST_PATH = %LIST_REMOVEALL(LIST_PATH, TOSTR(ROOM_FROM))%
ENDIF
CALL HO_SET_MAPDATA(ROOM_TO, "ROOM_PATH", LIST_PATH)

repo_name: pervysquirrelz/erafl

license: unknown


code:
;-------------------------------------------------
;居住区交流開始時に一度呼び出される各種データの初期化処理
;-------------------------------------------------
@QST_INIT_QUEST_DATA(QUEST_ID, QST_QUEST_TYPE)
#DIM  QUEST_ID
#DIM DYNAMIC IDX
#DIM DYNAMIC CHARA_ID
#DIM DYNAMIC 初期位置
#DIMS DYNAMIC _LIST_MEMBER

;各種データを初期化
VARSET _DIC_HO_MASTER_DATA
VARSET _DIC_HO_MAPDATA
VARSET _DIC_HO_CHARALIST
VARSET _LIST_QST_TRAIN_EXIT_EVENT
VARSET HO_LOG_MESSAGE

VARSET _DIC_QST_EVENT_LIST
VARSET _DIC_HO_CHARALIST, "-1"
VARSET QST_FLAG

;小さいフォントが参照可能なら使用可能な状態にする
GETFONT
CHKFONT "Microsoft Himalaya"
IF RESULT
    HO_SFONT '= "Microsoft Himalaya"
ELSE
    HO_SFONT '= "ＭＳ ゴシック"
ENDIF

;TFLAG,各調教用キャラクターシステム変数を手動で初期化する
VARSET TFLAG
FOR LOCAL, 0,CHARANUM
    VARSET EX:LOCAL:0, 0
    VARSET SOURCE:LOCAL:0, 0
    VARSET TCVAR:LOCAL:0, 0
    VARSET CUP:LOCAL:0, 0
    VARSET CDOWN:LOCAL:0, 0
    VARSET DOWNBASE:LOCAL:0, 0
NEXT

;調教イベントのターン数初期化
QST_調教ターン数 = 20
;イベント選択制限の初期化
QST_イベント選択制限 = -1
;ステータス画面の描写対象をMASTERに
HO_ステータス描画対象 = MASTER

;クエスト用データの初期化
QST_応急治療点 = 3
FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY)
    CALL SKILL_GET_LEVEL(TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL)), スキル_大分類_冒険, "MEDIC")
    IF RESULT
        QST_応急治療点 += 1
    ENDIF
NEXT

;;マップ型クエスト
;今はマップが一つしか無いので0固定
IF QST_QUEST_TYPE == "MAP" || QST_QUEST_TYPE == "GMAP"
    HO_有効マップID = 0
    CALL QST_LOAD_MAPDATA(HO_有効マップID, QUEST_ID)
    ;交流に参加するキャラの初期ステータスを設定
    CALL HO_FIND_ROOM_BY_TAG("クエスト開始地点")
    初期位置 = RESULT

    ;キャラクターリスト生成
    ;-------------------------------------------------
    FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY)
        CHARA_ID = TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))
        SIF CHARA_ID == MASTER
            CONTINUE
        _DIC_HO_CHARALIST:IDX '= @"[CHARA_ID:{CHARA_ID}][ROOM_IDX:{初期位置}][ACTION:待機]"
        IDX ++
        ;クエストモードで同行するキャラは同行扱いでスタート
        CALL QST_ADD_COMPANION(CHARA_ID)
        CFLAG:CHARA_ID:交流参加 = 1
        CFLAG:CHARA_ID:調教中帰らない = 1
    NEXT
    ;キャラリスト末尾を示す"-1"をセット
    _DIC_HO_CHARALIST:IDX '= "-1"

    ;イベント生成
    ;-------------------------------------------------
    CALL QST_INIT_EVENT_LIST(QUEST_ID, HO_有効マップID)

    ;すべてのルームに戦場の霧をかける
    CALL QST_SET_FOG_OF_WAR

    ;探索済ルームの情報を開示
    CALL QST_GET_QST_SAVE_EXPLORED()
    IF QST_SAVE_EXPLORED
        CALL QST_EXPLORED_ROOMS_DISCLOSURE()
    ENDIF

    ;プレイヤーの初期位置を設定
    CALL HO_FIND_ROOM_BY_TAG("クエスト開始地点")
    初期位置 = RESULT
    HO_MASTER現在地 = 初期位置
    HO_MASTER_USE_MODULE_LIST_IDX = -1

    ;プレイヤー初期位置と隣接ルームの戦場の霧を晴らす
    CALL QST_CLEAR_FOG_OF_WAR(HO_MASTER現在地)
ENDIF

;クエストモードで調教終了時にイベントを呼ぶ際に使用する変数を初期化
QST_TRAIN_EXIT_EVENT_ID = -1

;-------------------------------------------------
;;クエスト用マップ読み込み処理
@QST_LOAD_MAPDATA(MAP_ID, QUEST_ID)
#DIM MAP_ID
#DIM QUEST_ID
#DIM DYNAMIC NODE_ID
#DIM DYNAMIC IDX, HO_MAX_ROOMNUM
TRYCCALLFORM QST_SET_MAPDATA_QUEST_{QUEST_ID}(MAP_ID)
CATCH
    THROW @HO_LOAD_MAPDATA:無効なQUEST_IDが指定されました。
ENDCATCH

IF QST_QUEST_TYPE == "GMAP"
    CALL GMAPEDIT_IMPORT_MAPDATA(QST_GMAPDATA_PATH, QST_GMAPDATA_FILENAME, 1)
    DT_SELECT "GMAPDATA",, "NODE_ID ASC", IDX
    FOR LOCAL, 0, RESULT
        NODE_ID = DT_CELL_GET("GMAPDATA", IDX:LOCAL, "NODE_ID", 1)
        _DIC_HO_MAPDATA:MAP_ID:NODE_ID = %DIC_SET(_DIC_HO_MAPDATA:MAP_ID:NODE_ID, "ROOM_NAME", DT_CELL_GETS("GMAPDATA", IDX:LOCAL, "NODE_NAME", 1))%
        _DIC_HO_MAPDATA:MAP_ID:NODE_ID = %DIC_SET(_DIC_HO_MAPDATA:MAP_ID:NODE_ID, "ROOM_PATH", DT_CELL_GETS("GMAPDATA", IDX:LOCAL, "PATH_LIST", 1))%
        ;NODE_ID 0番にクエスト開始地点をセット
        IF NODE_ID == 0
            _DIC_HO_MAPDATA:MAP_ID:NODE_ID = %DIC_SET(_DIC_HO_MAPDATA:MAP_ID:NODE_ID, "ROOM_ID", "200")%
        ELSE
            _DIC_HO_MAPDATA:MAP_ID:NODE_ID = %DIC_SET(_DIC_HO_MAPDATA:MAP_ID:NODE_ID, "ROOM_ID", "201")%
        ENDIF
    NEXT
ENDIF

FOR LOCAL, 0, HO_MAX_ROOMNUM
    _DIC_HO_MAPDATA:HO_有効マップID:LOCAL = %DIC_REMOVE(_DIC_HO_MAPDATA:HO_有効マップID:LOCAL, "EVENT_ID_LIST")%
NEXT

;定義ファイルからイベントリストを生成する
@QST_INIT_EVENT_LIST(QUEST_ID, MAP_ID = -1)
#DIM QUEST_ID
#DIM MAP_ID
#DIM EVENT_NUM

#DIMS DYNAMIC _LIST_EVENT
#DIM DYNAMIC EVENT_LIST_IDX
#DIM DYNAMIC EVENT_ID
#DIM DYNAMIC HAS_EVENT_REGISTED
#DIM DYNAMIC ROOM_IDX
#DIM DYNAMIC EVENT_SLOT_IDX
#DIMS DYNAMIC EVENT_TRIGGER
#DIMS DYNAMIC _LIST_EVENT_SLOT
#DIMS DYNAMIC EVENT_SLOT_NAME
#DIMS DYNAMIC EVENT_TYPE
#DIMS DYNAMIC DIC_EVENT_OPTION

DEBUGPRINTFORML @QST_INIT_EVENT_LIST QUEST_ID {QUEST_ID}

IF MAP_ID == -1
    MAP_ID = HO_有効マップID
ENDIF
VARSET _DIC_QST_EVENT_LIST:MAP_ID:0, "-1"
;ルームに依存するイベントをイベントリストに登録
FOR ROOM_IDX, 0, HO_MAX_ROOMNUM
    CALL HO_GET_MAPDATA(MAP_ID, ROOM_IDX, "EVENT_LIST")
    _LIST_EVENT = %RESULTS%
    EVENT_NUM = LIST_COUNT(_LIST_EVENT)
    FOR EVENT_SLOT_IDX, 0, EVENT_NUM
        FOR LOCAL, 0, QST_MAX_EVENTNUM
            IF _DIC_QST_EVENT_LIST:MAP_ID:LOCAL == "-1"
                EVENT_LIST_IDX = LOCAL
                BREAK
            ENDIF
        NEXT
        EVENT_ID = TOINT(LIST_GET(_LIST_EVENT, EVENT_SLOT_IDX))
        CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID", TOSTR(EVENT_ID), MAP_ID)
        CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "ROOM_IDX", TOSTR(ROOM_IDX), MAP_ID)
        VARSET RESULTS
        QST_NOWEV = EVENT_ID
        TRYCCALLFORM QST_ADD_EVENT_QUEST_{QUEST_ID}_EVENT_{EVENT_ID}
            EVENT_TRIGGER = %RESULTS:0%
            EVENT_SLOT_NAME = %RESULTS:1%
            EVENT_TYPE = %RESULTS:2%
            DIC_EVENT_OPTION = %RESULTS:3%
            ; DEBUGPRINTFORML EVENT_ID:{EVENT_ID},EVENT_SLOT_NAME%EVENT_SLOT_NAME%
            CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TRIGGER", EVENT_TRIGGER, MAP_ID)
            CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TYPE", EVENT_TYPE, MAP_ID)
            IF EVENT_TRIGGER == "EVENT_SLOT"
                VARSET _LIST_EVENT_SLOT
                CALL HO_GET_MAPDATA(MAP_ID, ROOM_IDX, "EVENT_SLOT")
                _LIST_EVENT_SLOT = %RESULTS%
                _LIST_EVENT_SLOT = %LIST_ADD(_LIST_EVENT_SLOT, TOSTR(EVENT_LIST_IDX))%
                CALL HO_SET_MAPDATA(ROOM_IDX, "EVENT_SLOT", _LIST_EVENT_SLOT)
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_SLOT_NAME", EVENT_SLOT_NAME, MAP_ID)
            ENDIF
            IF EVENT_TYPE == "PAWN"
                CALL QST_CREATE_EVENT_PAWN(ROOM_IDX, EVENT_LIST_IDX)
            ENDIF
            ;オプション値の反映
            IF DIC_CONTAINSKEY(DIC_EVENT_OPTION ,"EVENT_STATE")
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE", DIC_GET(DIC_EVENT_OPTION, "EVENT_STATE"), MAP_ID)
            ENDIF
            IF DIC_CONTAINSKEY(DIC_EVENT_OPTION ,"EVENT_COLOR")
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_COLOR", DIC_GET(DIC_EVENT_OPTION, "EVENT_COLOR"), MAP_ID)
            ENDIF
            IF DIC_CONTAINSKEY(DIC_EVENT_OPTION ,"EVENT_ICON")
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ICON", DIC_GET(DIC_EVENT_OPTION, "EVENT_ICON"), MAP_ID)
            ENDIF
            IF DIC_CONTAINSKEY(DIC_EVENT_OPTION ,"EVENT_COLOR")
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_COLOR", DIC_GET(DIC_EVENT_OPTION, "EVENT_COLOR"), MAP_ID)
            ENDIF
        CATCH
            THROW @QST_INIT_EVENT_LIST エラー:QUEST_ID{QUEST_ID} マップデータで指定されたEVENT_ID:{EVENT_ID}に対応する関数が存在しません
        ENDCATCH

    NEXT
NEXT

;ルームに依存しない未登録イベントをイベントリストに登録
FOR EVENT_ID, 0 ,QST_MAX_EVENTNUM
    HAS_EVENT_REGISTED = 0
    FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
        CALL QST_GET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID")
        IF RESULT == EVENT_ID
            HAS_EVENT_REGISTED = 1
        ENDIF
    NEXT
    SIF HAS_EVENT_REGISTED
        CONTINUE
    FOR EVENT_LIST_IDX, 0, QST_MAX_EVENTNUM
        IF _DIC_QST_EVENT_LIST:MAP_ID:EVENT_LIST_IDX == "-1"
            VARSET RESULTS
            QST_NOWEV = EVENT_ID
            TRYCCALLFORM QST_ADD_EVENT_QUEST_{QUEST_ID}_EVENT_{EVENT_ID}
                EVENT_TRIGGER = %RESULTS:0%
                EVENT_SLOT_NAME = %RESULTS:1%
                EVENT_TYPE = %RESULTS:2%
                DIC_EVENT_OPTION = %RESULTS:3%
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TRIGGER", EVENT_TRIGGER, MAP_ID)
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_ID", TOSTR(EVENT_ID), MAP_ID)
                CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_TYPE", EVENT_TYPE, MAP_ID)
                ;オプション値の反映
                IF DIC_CONTAINSKEY(DIC_EVENT_OPTION ,"EVENT_STATE")
                    CALL QST_SET_EVENT_LIST(EVENT_LIST_IDX, "EVENT_STATE", DIC_GET(DIC_EVENT_OPTION, "EVENT_STATE"), MAP_ID)
                ENDIF
                BREAK
            CATCH
            ENDCATCH
        ENDIF
    NEXT
NEXT

CALL QST_INIT_汎用イベント(QUEST_ID, MAP_ID)


code:
;-------------------------------------------------
;クエストの処理のコントロール
;-------------------------------------------------

;-------------------------------------------------
;SHOP画面から呼び出されるクエスト選択画面
;-------------------------------------------------
@QST_SELECT_QUEST

IF !FLTUTOR:クエストに挑む前に
    CALL TUTORIAL_クエストに挑む前に
ENDIF

CALL QST_DRAW_MENU_WINDOW

;-------------------------------------------------
;「クエストモード」
;-------------------------------------------------
@QUEST_MODE_START(QUEST_ID = 0)
#DIM CHARA_ID
#DIMS _LIST_MEMBER
#DIM QUEST_ID

;一度BGMを停止
CALL FL_STOPBGM()

DEBUGPRINTFORML QUEST_ID_{QUEST_ID}が呼び出されました

;広域変数に実行するクエストのIDをセット
QST_有効クエストID = QUEST_ID

;クエスト初期処理
FLAG:調教モード = 調教_クエスト
FLAG:ウフフフラグ = 0
FLAG:クエストモード = 1
FLAG:クエスト_中断を許可 = 0
FLAG:クエスト_交流コマンド許可 = 0
FLAG:クエスト_ウフフ許可 = 0
FLAG:移動制限フラグ = 0

;クエスト時のデータの反映とフラグ初期化
FOR LOCAL, 0, CHARANUM
    ;衣装データを反映
    CFLAG:LOCAL:衣装プリセット = 衣装プリセット_クエスト
    CALL SET_CHARA_CLOTH_DATA(LOCAL)

    ;クエストでの好感度上昇値初期化
    CFLAG:LOCAL:QST好感度ボーナス = 0
NEXT

IF LIST_INDEXOF(_LIST_QST_PARTY, TOSTR(MASTER)) == -1
    FLAG:クエスト_あなた不参加 = 1
ENDIF

;パーティ人数を広域変数にセット
QST_PARTYNUM = LIST_COUNT(_LIST_QST_PARTY)
;一度でもパーティに参加したキャラを記録するリストを初期化
_LIST_PARTY_PARTICIPANT_RECORD = %_LIST_QST_PARTY%

CALL CLEAR_MPLY()
CALL CLEAR_MTAR()

TRYCALLFORM QST_TYPE_QUEST_{QST_有効クエストID}
QST_QUEST_TYPE = %RESULTS%

;クエスト用連想配列を作成。クエストの内部フラグなどを自由に格納できる領域
;広域変数なので関数をまたいでも参照可能。クエスト終了時に解放
MAP_RELEASE @"QUEST_{QST_有効クエストID}_MAP"
MAP_CREATE @"QUEST_{QST_有効クエストID}_MAP"
;エリア効果格納用の連想配列を作成
CALL HO_ROOM_EFFECT_CREATE_MAP

FLAG:ハウジングモード = 1
;全行動回数を消費。START_TRAIN_COMMON内部でもSHOP_TIMEが+1されるため-1で相殺
SHOP_TIME += CALC_SHOP_TIME() - SHOP_TIME - 1
IF QST_QUEST_TYPE == "MAP" || QST_QUEST_TYPE == "GMAP"
    ;クエストの導入イベントを実行
    CALL QST_INIT_QUEST_DATA(QST_有効クエストID, QST_QUEST_TYPE)
    CALL QST_INIT_QUEST()
    CALL QST_INTRO_EVENT()
    CALL START_TRAIN_COMMON

ELSE ;"DIALOGUE"型クエスト(マップ探索を伴わないクエスト)の処理
    ;クエストの導入イベントを実行
    CALL QST_INIT_QUEST_DATA(QST_有効クエストID, QST_QUEST_TYPE)
    CALL QST_INIT_QUEST()
    CALL QST_INTRO_EVENT()
ENDIF

;-------------------------------------------------
;クエスト固有の初期化処理
;-------------------------------------------------
@QST_INIT_QUEST()
TRYCALLFORM QST_INIT_QUEST_{QST_有効クエストID}

;-------------------------------------------------
;導入イベント呼出
;-------------------------------------------------
@QST_INTRO_EVENT()
TRYCCALLFORM QST_INTRO_QUEST_{QST_有効クエストID}
CATCH
    DEBUGPRINTFORML @QST_INTRO_EVENT QUEST_ID:{QST_有効クエストID}IDのQST_INTRO_EVENTは未定義です
ENDCATCH

;-------------------------------------------------
;クエストモード中の各イベント実行後に呼ばれる処理
;-------------------------------------------------
@QST_EVENTEND()
#DIM DYNAMIC CHARA_ID
;衣装損壊判定
FOR LOCAL, 0, QST_PARTYNUM
    CHARA_ID = TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))
    CALL QST_CHECK_ARMOR_BREAK(CHARA_ID)
NEXT

IF FLAG:調教モード == 調教_クエスト
    ;DO_TRAINを実行した場合は全滅判定しない(DO_TRAIN処理後に全滅判定する)
    IF FLAG:DO_DUMMYCOM > 0
        ;調教の結果全員行動不能になった場合全滅フラグを立てる
        CALL QST_IS_PARTY_KNOCKED_OUT()
        IF RESULT
            FLAG:QST_全滅フラグ = 1
            RETURN 1
        ENDIF
    ELSE
        ;DUMMYCOMが立っていない場合は全滅処理を呼び出す
        ;全滅フラグはイベント側が必要に応じて立てるのでここではセットしない
        CALL QST_IS_PARTY_KNOCKED_OUT()
        IF RESULT
            CALL QST_PARTY_KNOCKED_OUT
            IF RESULT
                RETURN 1
            ENDIF
        ENDIF
    ENDIF
ENDIF

;-------------------------------------------------
; パーティ全滅イベントが定義されている場合実行
;-------------------------------------------------
@QST_PARTY_KNOCKED_OUT()
TRYCCALLFORM QST_QUEST_{QST_有効クエストID}_PARTY_KNOCKED_OUT
    PRINTL
    RETURN 1
CATCH
ENDCATCH

;-------------------------------------------------
;コマンド実行後処理
;クエストモードが有効な場合に @EVENTCOMEND から呼ばれる
;-------------------------------------------------
@QST_EVENTCOMEND()
#DIM DYNAMIC CHARA_ID
#DIMS FUNCTION_NAME

FOR LOCAL, 0, CHARANUM
    TCVAR:LOCAL:HO体力増減値 = 0
    TCVAR:LOCAL:HO気力増減値 = 0
NEXT

;クエスト用連想配列にEVENTCOMEND_CALLEE_ONCEがセットされている場合、対象関数を呼び出す
IF MAP_HAS(@"QUEST_{QST_有効クエストID}_MAP", "EVENTCOMEND_CALLEE_ONCE") == 1
    FUNCTION_NAME = %MAP_GET(@"QUEST_{QST_有効クエストID}_MAP", "EVENTCOMEND_CALLEE_ONCE")%
    MAP_REMOVE @"QUEST_{QST_有効クエストID}_MAP", "EVENTCOMEND_CALLEE_ONCE"
    TRYCCALLFORM %FUNCTION_NAME%
        DEBUGPRINTFORML EVENTCOMEND_CALLEE_ONCE = %FUNCTION_NAME%を呼び出し
    CATCH
        DEBUGPRINTFORML QUEST_{QST_有効クエストID}_MAPのEVENTCOMEND_CALLEE_ONCEに指定された関数%FUNCTION_NAME%は存在しません
    ENDCATCH
ELSEIF MAP_HAS(@"QUEST_{QST_有効クエストID}_MAP", "EVENTCOMEND_CALLEE") == 1
    FUNCTION_NAME = %MAP_GET(@"QUEST_{QST_有効クエストID}_MAP", "EVENTCOMEND_CALLEE")%
    TRYCCALLFORM %FUNCTION_NAME%
        DEBUGPRINTFORML EVENTCOMEND_CALLEE = %FUNCTION_NAME%を呼び出し
    CATCH
        DEBUGPRINTFORML QUEST_{QST_有効クエストID}_MAPのEVENTCOMEND_CALLEEに指定された関数%FUNCTION_NAME%は存在しません
    ENDCATCH
ENDIF

IF FLAG:QST_全滅フラグ == 1
    CALL QST_PARTY_KNOCKED_OUT
    FLAG:QST_全滅フラグ = 0
ENDIF

;クエスト終了
IF TFLAG:クエスト_完了フラグ
    CALL TRAIN_EXIT(0)
    LINES_TRAIN = LINECOUNT
    RETURN
ENDIF

CALL QST_EVENTEND()

;-------------------------------------------------
;クエスト中の調教終了時処理
;クエストモードが有効な場合に @TRAIN_EXIT から呼ばれる
;調教モードが切り替わるタイミングでも呼ばれる点に注意
;-------------------------------------------------
@QST_TRAIN_EXIT(終了理由)
#DIM 終了理由
#DIM DYNAMIC CHARA_ID
#DIM DYNAMIC EVENT_ID

;EVENTCOMEND_CALLEEの削除
CALL QST_REMOVE_FLAGMAP("EVENTCOMEND_CALLEE")
CALL QST_REMOVE_FLAGMAP("EVENTCOMEND_CALLEE_ONCE")

;次回の調教イベントに持ち越さない調教フラグを削除
CVARSET CFLAG, GETNUM(CFLAG, "主導除外") , 0
CVARSET CFLAG, GETNUM(CFLAG, "凌辱被害者フラグ") , 0

;調教参加者をパーティメンバーのみに
CVARSET CFLAG, GETNUM(CFLAG, "調教参加フラグ") , 0
FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY)
    CHARA_ID = TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))
    CFLAG:CHARA_ID:調教参加フラグ = 1
    CALL HO_TRAIN_EXIT_CALC_SATISFACTION(CHARA_ID)
    FLAG:ウフフイベント獲得淫堕点 += LIMIT(RESULT, 0, 30) / 2
NEXT

TFLAG:参加者数 = QST_PARTYNUM - 1
FLAG:ウフフフラグ = 0
FLAG:調教モード = 調教_クエスト
TFLAG:奉仕モード = 0
TFLAG:売春フラグ = 0
TFLAG:奉仕カテゴリ = 0
TFLAG:交流中断不可 = 0
TFLAG:調教開始時刻 = 0
TFLAG:調教経過時間 = 0
FLAG:クエスト_刻限による終了無効 = 0

;自動調教の制御系フラグを全てクリア
CALL TRAIN_EXIT_CREAR_AUTO_TRAIN_CONTROL_FLAG()

;調教関連の変数を初期化
FLAG:主導権所有者 = 0
TFLAG:調教経過時間 = 0
CALL CLEAR_MPLY()
CALL CLEAR_MTAR()
FOR LOCAL,0 , CHARANUM
    IF IS_PARTICIPATE_TRAIN(LOCAL)
        CALL ADD_MPLY(LOCAL)
        BREAK
    ENDIF
NEXT

;調教終了後イベントを呼出
CALL QST_DEQUEUE_TRAIN_EXIT_EVENT()
IF RESULTS == ""
    EVENT_ID = RESULT
    IF EVENT_ID != -1
        TRYCCALLFORM QST_QUEST_{QST_有効クエストID}_EVENT_{EVENT_ID}
            PRINTL
        CATCH
            DEBUGPRINTFORML QUEST_{QST_有効クエストID},EVENT_ID{EVENT_ID}に対応するイベント定義関数が存在しません
        ENDCATCH
    ENDIF
ELSE
    TRYCCALLFORM %RESULTS%
        PRINTL
    CATCH
        DEBUGPRINTFORML QUEST_{QST_有効クエストID},関数名:%RESULTS%に対応する関数が定義されていません
    ENDCATCH
ENDIF
VARS FUNCTION_NAME
FUNCTION_NAME = %QST_GET_FLAGMAP("TRAIN_EXIT_CALLEE")%
IF FUNCTION_NAME != ""
    CALL QST_REMOVE_FLAGMAP("TRAIN_EXIT_CALLEE")
    TRYCCALLFORM %FUNCTION_NAME%
        PRINTL
    CATCH
        DEBUGPRINTFORML QUEST_{QST_有効クエストID},関数名:%FUNCTION_NAME%に対応する関数が定義されていません
    ENDCATCH
ENDIF

;調教の結果全員行動不能になった場合全滅イベントを呼び出す
CALL QST_IS_PARTY_KNOCKED_OUT()
IF RESULT
    CALL QST_PARTY_KNOCKED_OUT()
ENDIF

;-------------------------------------------------
;クエストモードの有効時クエストの終了時に呼ばれる処理
;AFTERTRAIN後、@EVENTEND から呼ばれる
;-------------------------------------------------
@QUEST_EVENTEND
#DIM CHARA_ID

;成長処理のため、クエスト内PT編成機能でパーティから離脱している仲間の調教参加フラグを立てる
FOR LOCAL, 0, LIST_COUNT(_LIST_PARTY_PARTICIPANT_RECORD)
    CHARA_ID = LIST_GETINT(_LIST_PARTY_PARTICIPANT_RECORD, LOCAL)
    IF !IS_SAME_FACTION(CHARA_ID)
        CFLAG:CHARA_ID:調教参加フラグ = 0
    ELSE
        CFLAG:CHARA_ID:調教参加フラグ = 1
    ENDIF
NEXT

;クエスト終了時の好感度上昇処理
CALL QST_UPDATE_RELATION()

;クエスト用一時連想配列を解放
MAP_RELEASE @"QUEST_{QST_有効クエストID}_MAP"

;各種フラグクリア
FLAG:QST_終了時刻 = 0
QST_イベント選択制限 = -1
FLAG:移動制限フラグ = 0
FLAG:クエスト_ウフフ許可 = 0
TFLAG:クエスト_ダミー設備ID = 0
QST_QUEST_TYPE '= ""

;-------------------------------------------------
;クエストモードの有効時クエストの終了時に呼ばれる処理
;AFTERTRAIN後、@EVENTEND から呼ばれる
;-------------------------------------------------
@QST_UPDATE_RELATION
#DIM CHARA_ID
#DIM PARTY_NUM
#DIMS LIST_PARTY

LIST_PARTY = %_LIST_PARTY_PARTICIPANT_RECORD%
PARTY_NUM = LIST_COUNT(LIST_PARTY)
SIF PARTY_NUM <= 1
    RETURN

PRINTL
VARI IS_LIKE_CHANGED
VARI I
VARI J
VARI 好感度上昇値
VARI TARGET_ID
FOR I, 0, PARTY_NUM
    CHARA_ID = TOINT(LIST_GET(LIST_PARTY, I))
    IF CHARA_ID == MASTER || TCVAR:CHARA_ID:行動不能フラグ == 1 || CFLAG:CHARA_ID:QST好感度ボーナス <= 0 || !IS_SAME_FACTION(CHARA_ID)
        CONTINUE
    ENDIF
    FOR J, 0, PARTY_NUM
        TARGET_ID = LIST_GETINT(LIST_PARTY, J)
        IF !IS_SAME_FACTION(TARGET_ID)
            CONTINUE
        ENDIF
        IF TARGET_ID == CHARA_ID
            CONTINUE
        ENDIF
        好感度上昇値 = MIN(QST_MAX_RELATION_UP, CFLAG:CHARA_ID:QST好感度ボーナス)
        IF TARGET_ID == MASTER
            CFLAG:CHARA_ID:好感度 += 好感度上昇値
            IS_LIKE_CHANGED = 1
        ELSE
            CALL REL_ADD(CHARA_ID, TARGET_ID, 好感度上昇値)
            IS_LIKE_CHANGED = 1
        ENDIF
    NEXT
    IF IS_LIKE_CHANGED
        PRINTFORML Passing through an adventure, the favorability between %ANAME(CHARA_ID)% and friends has increased {好感度上昇値}.
    ENDIF
NEXT


code:
;-------------------------------------------------
; クエスト選択画面
;-------------------------------------------------
@QST_DRAW_MENU_WINDOW
#DIM LINE_NUM
#DIMS DYNAMIC _LIST_QST_PREV_PARTY
#DIM ITER_I

CALL PRINTLINE_RESERVE()

;初期処理
QST_SELECT_QUEST_ID = -1
SIF QST_DIC_QUEST_FILTER == ""
    QST_DIC_QUEST_FILTER '= "[ALL:1]"

;パーティ編成が空の場合、あなたを固定で追加
FOR ITER_I, 0, VARSIZE("_LIST_QST_PARTY_PRESET")
    IF _LIST_QST_PARTY_PRESET:ITER_I == ""
        _LIST_QST_PARTY_PRESET:ITER_I = %LIST_ADD(_LIST_QST_PARTY_PRESET:ITER_I, TOSTR(MASTER))%
        ;パーティ編成済みの場合、現在キャラクターが編成条件を満たしているか確認し、満たしていない場合パーティから除外する
    ELSE
        _LIST_QST_PREV_PARTY = %_LIST_QST_PARTY_PRESET:ITER_I%
        _LIST_QST_PARTY_PRESET:ITER_I '= ""
        FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PREV_PARTY)
            CALL HOUSING_MODE_CHECK_CHARA_JOINABLE(TOINT(LIST_GET(_LIST_QST_PREV_PARTY, LOCAL)))
            IF !RESULT
                CONTINUE
            ELSE
                _LIST_QST_PARTY_PRESET:ITER_I = %LIST_ADD(_LIST_QST_PARTY_PRESET:ITER_I, LIST_GET(_LIST_QST_PREV_PARTY, LOCAL))%
            ENDIF
        NEXT
    ENDIF
NEXT

WHILE 1
    LINE_NUM = LINECOUNT
    REDRAW 0
    CALL WndMgr_DestroyWindow(-1)
    CALL QST_DRAW_MENU_WINDOW_PARENT
    CALL QST_DRAW_MENU_WINDOW_LEFT
    CALL QST_DRAW_MENU_WINDOW_RIGHT
    CALL QST_DRAW_MENU_WINDOW_BOTTOM
    CALL WndMgr_DisplayAll()
    REDRAW 1
    CALL QST_WINDOW_INPUT()
    IF RESULT == -1
        RETURN
    ELSEIF RESULT == 0
        CLEARLINE LINECOUNT - LINE_NUM
        SELECTCASE QST_GUILD_MENU_CATEGORY
            CASE 8
                CALL HO_SHOP_MENU("ギルドショップ", "得点引換", "QUEST_MENU_DIC_SHOP_STOCK_0")
            CASE 9
                CALL HO_ITEM_MENU()
        ENDSELECT
        QST_GUILD_MENU_CATEGORY = 0
    ELSEIF RESULT == 1
        BREAK
    ENDIF
    CLEARLINE LINECOUNT - LINE_NUM
WEND
CALL QUEST_MODE_START(QST_SELECT_QUEST_ID)

@QST_DRAW_MENU_WINDOW_PARENT
#DIM CONST WINDOW_ID = 0
#DIM CONST WND_WIDTH  = 170
#DIM CONST WND_HEIGHT = 45
#DIM DYNAMIC L_CNT
#DIM DYNAMIC F_COL, 11
#DIM CONST BTN_ID = 100

;CATEGORYタブの文字色
VARSET F_COL, カラー_白
F_COL:QST_GUILD_MENU_CATEGORY = カラー_選択中

CALL WndMgr_CreateWindow(WINDOW_ID, 0, 1, WND_WIDTH, WND_HEIGHT, 2)
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@S:1@@C:{カラー_注釈}@◇　ギルド　◇@/C@@/S@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
LOCALS '= @"@C:{F_COL:0}@@B:{BTN_ID}@[クエストボード]@/B@@/C@"
LOCALS += @"@C:{F_COL:8}@@B:{BTN_ID + 8}@　[得点の利用]@/B@@/C@"
LOCALS += @"@C:{F_COL:9}@@B:{BTN_ID + 9}@　[アイテム確認]@/B@@/C@"
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, LOCALS)
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))

LOCALS '= @"@B:9999999@[キャンセル]@/B@"
CALL WndMgr_TextSet(WINDOW_ID, WND_HEIGHT - 3, @"%LOCALS%")

@QST_DRAW_MENU_WINDOW_LEFT
#DIM CONST WINDOW_ID = 1
#DIM CONST WND_WIDTH  = 64
#DIM CONST WND_HEIGHT = 38
#DIM CONST ヘッダー行数 = 4
#DIM CONST クエストリスト行数 = 28
#DIM CONST BTN_ID = 1000
#DIMS DYNAMIC DETAIL_LIST, ITEM_LENGTH
#DIM DYNAMIC ITEM_NUM
#DIM DYNAMIC L_CNT
#DIM DYNAMIC PAGE_NUM
#DIMS DYNAMIC STR_FOOTER
#DIM DYNAMIC DETAIL_LINECOUNT
#DIM DYNAMIC QUEST_ID
#DIMS DYNAMIC LIST_QUEST_TAG
#DIMS DYNAMIC TAGS
#DIM DYNAMIC TAG_UNMATCHED
#DIM DYNAMIC ITER_I
#DIM DYNAMIC ITER_J

CALL HO_TRADE_COUNT_PAGE_NUM(HO_ITEM_STOCK, クエストリスト行数)
PAGE_NUM = RESULT

;ウィンドウ作成
CALL WndMgr_CreateWindow(WINDOW_ID, 2, 6, WND_WIDTH, WND_HEIGHT, 2)
CALL WndMgr_Attribute(WINDOW_ID, "BorderColor", カラー_選択不可)

;ヘッダー
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_注釈}@◇受注可能なクエスト◇@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
;フィルター
LOCALS '= @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "ALL") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:ALL]@[ALL]@/B@@/C@"
LOCALS += " /"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "周期") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:周期]@ [周期・恒常]@/B@@/C@"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "単発") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:単発]@ [単発]@/B@@/C@"
LOCALS += " /"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "探索") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:探索]@ [探索]@/B@@/C@"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "街") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:街]@ [街]@/B@@/C@"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "連戦") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:連戦]@ [連戦]@/B@@/C@"
LOCALS += @"@C:{DIC_GET(QST_DIC_QUEST_FILTER, "イベント") == "1" ? カラー_選択中 # カラー_選択不可}@@B:[FILTER:イベント]@ [イベント]@/B@@/C@"
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, LOCALS)
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))

;明細リスト作成
DETAIL_LINECOUNT = 0
L_CNT = 0
FOR QUEST_ID, 0, QST_MAX_QUESTNUM
    TRYCALLFORM QST_AVAILABLE_QUEST_{QUEST_ID}(QUEST_ID)
    SIF !RESULT
        CONTINUE
    ;フィルターの反映
    ;フィルタ[ALL]がOFF
    IF DIC_GET(QST_DIC_QUEST_FILTER, "ALL") != "1"
        VARSET RESULTS
        TAG_UNMATCHED = 1
        ;クエストのタグを取得
        TRYCALLFORM QST_QUEST_TAG_{QUEST_ID}
        LIST_QUEST_TAG = %RESULTS%
        ;フィルタと一致するタグがあるかチェック
        FOR ITER_I, 0, LIST_COUNT(LIST_QUEST_TAG)
            TAG_UNMATCHED = 0
            TAGS = %LIST_GET(LIST_QUEST_TAG, ITER_I)%
            IF DIC_GET(QST_DIC_QUEST_FILTER, TAGS) != "1"
                TAG_UNMATCHED = 1
                BREAK
            ENDIF
        NEXT
        SIF TAG_UNMATCHED
            CONTINUE
    ENDIF
    TRYCCALLFORM QST_TITLE_QUEST_{QUEST_ID}
        IF QUEST_ID == QST_SELECT_QUEST_ID
            LOCALS '= @"@C:{カラー_選択中}@%RESULTS%@/C@"
        ELSE
            LOCALS '= @"@C:{カラー_白}@%RESULTS%@/C@"
        ENDIF
        DETAIL_LIST:DETAIL_LINECOUNT '= @"@B:{BTN_ID + QUEST_ID}@%LOCALS%@/B@"
        DETAIL_LINECOUNT ++
    CATCH
    ENDCATCH
NEXT
PAGE_NUM = DETAIL_LINECOUNT / クエストリスト行数

;明細リスト出力
L_CNT = 0
FOR LOCAL, クエストリスト行数 * QST_MENU_PAGE_LEFT, クエストリスト行数 * (QST_MENU_PAGE_LEFT + 1)
    IF  L_CNT / クエストリスト行数 <= 0
        CALL WndMgr_TextSet(WINDOW_ID, L_CNT + ヘッダー行数, TAG_PRINT_SHAPE(DETAIL_LIST:LOCAL, 24, 1, 0) )
        L_CNT++
    ELSE
        CALL WndMgr_TextAdd(WINDOW_ID, (L_CNT % クエストリスト行数) + ヘッダー行数, TAG_PRINT_SHAPE(DETAIL_LIST:LOCAL, 24, 1, 0))
        L_CNT ++
    ENDIF
    L_CNT ++
NEXT

;フッター
IF PAGE_NUM > 0
    STR_FOOTER += QST_MENU_PAGE_LEFT > 0 ? @"@B:{9000}@<<@/B@ " # "   "
    STR_FOOTER += @"%TOSTR(QST_MENU_PAGE_LEFT + 1, "..")% "
    STR_FOOTER += QST_MENU_PAGE_LEFT < PAGE_NUM ? @"@B:{9001}@>>@/B@" # "  "
    CALLF TAG_PRINT_SHAPE(STR_FOOTER, WND_WIDTH - 8, 1, 2)
    CALL WndMgr_TextSet(WINDOW_ID, WND_HEIGHT - 3, @"@C:{カラー_注釈}@%RESULTS%@/C@")
ENDIF

@QST_DRAW_MENU_WINDOW_RIGHT
#DIM CONST WINDOW_ID = 2
#DIM CONST WND_WIDTH  = 102
#DIM CONST WND_HEIGHT = 25
#DIM CONST ヘッダー行数 = 2
#DIM CONST BTN_ID = 2000
#DIM DYNAMIC L_CNT

;ウィンドウ作成
CALL WndMgr_CreateWindow(WINDOW_ID, 66, 6, WND_WIDTH, WND_HEIGHT, 2)
CALL WndMgr_Attribute(WINDOW_ID, "BorderColor", カラー_選択不可)
SIF QST_SELECT_QUEST_ID == -1
    RETURN
;ヘッダー
TRYCALLFORM QST_TITLE_QUEST_{QST_SELECT_QUEST_ID}
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_注釈}@◇%RESULTS%◇@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))

;クエスト概要欄
VARSET RESULTS
FOR LOCAL, 0, 10
    TRYCALLFORM QST_SUMALLY1_QUEST_{QST_SELECT_QUEST_ID}
    CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"%RESULTS:LOCAL%")
NEXT
;クエスト備考欄
L_CNT++
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_注釈}@◇備考◇@/C@")
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
VARSET RESULTS
FOR LOCAL, 0, 7
    TRYCALLFORM QST_SUMALLY2_QUEST_{QST_SELECT_QUEST_ID}
    CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"%RESULTS:LOCAL%")
NEXT

@QST_DRAW_MENU_WINDOW_BOTTOM
#DIM CONST WINDOW_ID = 3
#DIM CONST WND_WIDTH  = 102
#DIM CONST WND_HEIGHT = 13
#DIM CONST ヘッダー行数 = 2
#DIM CONST パーティリスト行数 = 7
#DIM CONST BTN_ID = 3000
#DIM DYNAMIC L_CNT
#DIM DYNAMIC CHARA_ID
#DIMS DYNAMIC P_SPRITE
#DIM DYNAMIC TOTAL_POWER
#DIM DYNAMIC AVG_POWER

CALL WndMgr_CreateWindow(WINDOW_ID, 66, 31, WND_WIDTH, WND_HEIGHT, 2)
CALL WndMgr_Attribute(WINDOW_ID, "BorderColor", カラー_選択不可)

;ヘッダー
CALL WndMgr_TextSet(WINDOW_ID, L_CNT, @"@C:{カラー_注釈}@◇パーティ編成◇@/C@")
FOR LOCAL, 0, QST_MAX_PARTY_PRESET
    CALL WndMgr_TextAdd(WINDOW_ID, L_CNT, @"@C:{QST_SELECT_PARTY_PRESET == LOCAL ? カラー_選択中 # カラー_選択不可}@　@B:{4000 + LOCAL}@[編成{LOCAL + 1}]@/B@@/C@")
NEXT
L_CNT ++
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))

;ポートレイト表示部
FOR LOCAL, 0, パーティリスト行数
    CALL WndMgr_TextSet(WINDOW_ID, ヘッダー行数 + LOCAL, "")
NEXT
FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET)
    CHARA_ID = TOINT(LIST_GET(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET, LOCAL))
    CALL RESET_FACE_SPRITE(CHARA_ID)
    CALL HO_SET_PORTRAIT_SPRITE(CHARA_ID, "ステータス画面")
    P_SPRITE = %CSTR:CHARA_ID:キャラ顔グラ%
    LOCALS = %TAG_PRINT_SHAPE(@"@B:{BTN_ID + CHARA_ID}@[%SNAME(CHARA_ID)%]@/B@", 13, 1, 2)%
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 0, @"%LOCALS%")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 1, "")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 2, "")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 3, "")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 4, "")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 5, "")
    CALL WndMgr_TextAdd(WINDOW_ID, ヘッダー行数 + 6, @"@B:{BTN_ID + CHARA_ID}@@I:%P_SPRITE%,height='{GETCONFIG("フォントサイズ") * 40}',ypos='-500'@@/I@@/B@")
NEXT

;フッター
L_CNT = ヘッダー行数 + パーティリスト行数
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"@C:{カラー_選択不可}@―@/C@" * ((WND_WIDTH / 2) - 2))
VARSET LOCALS
;クエスト開始ボタン
;・「クエストが選択されている」「パーティメンバーが1人以上」で選択可能
IF QST_SELECT_QUEST_ID != -1 && LIST_COUNT(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET)
    LOCALS += @"@B:{BTN_ID + 900}@[クエストを開始する]@/B@　"
ELSE
    LOCALS += @"@C:{カラー_選択不可}@[クエストを開始する]@/C@　"
ENDIF
;パーティ編成ボタン
LOCALS += @"@B:{BTN_ID + 901}@[パーティ編成]@/B@　"
;平均戦闘値
TOTAL_POWER = 0
FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET)
    CHARA_ID = TOINT(LIST_GET(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET, LOCAL))
    TOTAL_POWER += ABL:CHARA_ID:戦闘
NEXT
IF LOCAL
    AVG_POWER = TOTAL_POWER / LOCAL
ELSE
    ;0除算対策
    AVG_POWER = 0
ENDIF
LOCALS += @"@C:{カラー_注釈}@《平均戦闘値:{AVG_POWER}》@/C@　"
CALL WndMgr_TextSet(WINDOW_ID, L_CNT++, @"%LOCALS%")

@QST_WINDOW_INPUT()
#DIMS INPUT_VALUES
#DIM  INPUT_VALUE
#DIM DYNAMIC VALUE
#DIM DYNAMIC INPUT_WINDOW_ID
#DIM PREV_FILTER_IS_ALL
#DIMS KEYS

ONEINPUTS
CLEARLINE 1
PRINTL
INPUT_VALUES = %RESULTS%
IF ISNUMERIC(INPUT_VALUES)
    INPUT_VALUE = TOINT(INPUT_VALUES)
    ;キャンセル
    IF INPUT_VALUE == 9999999
        RETURN -1
    ELSEIF INRANGE(INPUT_VALUE, 100, 110)
        QST_GUILD_MENU_CATEGORY = INPUT_VALUE - 100
        IF INRANGE(QST_GUILD_MENU_CATEGORY, 8, 10)
            RETURN 0
        ENDIF
    ELSEIF INRANGE(INPUT_VALUE, 1000, 1000 + QST_MAX_QUESTNUM)
        IF QST_SELECT_QUEST_ID != INPUT_VALUE - 1000
            QST_SELECT_QUEST_ID = INPUT_VALUE - 1000
            CALL FL_PLAYSE("Page_0.mp3")
        ENDIF
    ELSEIF INRANGE(INPUT_VALUE, 3000, 3000 + CHARANUM)
        VARSET SHOP_CHARA_LIST, -1
        FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET)
            SHOP_CHARA_LIST:LOCAL = TOINT(LIST_GET(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET, LOCAL))
        NEXT
        CALL SHOW_INFO_WITH_UI(INPUT_VALUE - 3000, 1)
        ;パーティプリセット切り替え
    ELSEIF INRANGE(INPUT_VALUE, 4000, 4000 + QST_MAX_PARTY_PRESET - 1)
        QST_SELECT_PARTY_PRESET = INPUT_VALUE - 4000
    ELSEIF INRANGE(INPUT_VALUE, 3900, 3901)
        IF INPUT_VALUE == 3900
            _LIST_QST_PARTY = %_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET%
            QST_PARTYNUM = LIST_COUNT(_LIST_QST_PARTY)
            CALL QST_WINDOW_ERROR_CHECK()
            IF RESULT
                ;クエスト開始
                CALL FL_PLAYSE("Step_1.mp3")
                RETURN 1
            ENDIF
        ELSE
            CALL PRINTLINE_CLEAR()
            CALL DRAW_LINE()
            PRINTL ◇ パーティ選択
            CALL DRAW_LINE()
            ;キャラ選択
            VARSET SELECTED_CHARA
            FOR LOCAL, 0, LIST_COUNT(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET)
                SELECTED_CHARA:(TOINT(LIST_GET(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET, LOCAL))) = 1
            NEXT
            CALL SELECT_CHARA_LIST_MULTI_ONLY_LOGIC_SLG(6, "QUEST", "QUEST")
            _LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET '= ""
            FOR LOCAL, 0, SELECTED_CHARA_NUM
                _LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET = %LIST_ADD(_LIST_QST_PARTY_PRESET:QST_SELECT_PARTY_PRESET, TOSTR(SELECTED_CHARA:LOCAL))%
            NEXT
        ENDIF
    ELSEIF INRANGE(INPUT_VALUE, 9000, 9001)
        IF INPUT_VALUE == 9001
            QST_MENU_PAGE_LEFT ++
        ELSE
            QST_MENU_PAGE_LEFT --
        ENDIF
    ENDIF
ELSE
    IF DIC_CONTAINSKEY(INPUT_VALUES, "FILTER")
        ;変更前のフィルタがALLだったかを記憶
        PREV_FILTER_IS_ALL = ((DIC_GET(QST_DIC_QUEST_FILTER, "ALL") == "1") ? 1 # 0)
        ;今回変更するフィルタ名を取得
        KEYS = %DIC_GET(INPUT_VALUES, "FILTER")%
        ;QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, KEYS, DIC_GET(QST_DIC_QUEST_FILTER, KEYS) == "1" ? "0" # "1")%

        SELECTCASE KEYS
                ;ALL
            CASE "ALL"
                ;フィルタ情報を「ALLのみON」に上書きする
                QST_DIC_QUEST_FILTER '= "[ALL:1]"
                ;クエスト周期フィルタ変更時
            CASE "周期", "単発"
                ;クエスト周期フィルタを一旦全部OFFにして変更対象のフィルタだけONにする
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "周期", "0")%
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "単発", "0")%

                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, KEYS  , "1")%
                ;クエスト種類フィルタ変更時
            CASE "探索", "街", "連戦", "イベント"
                ;クエスト種類フィルタを一旦全部OFFにして変更対象のフィルタだけONにする
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "探索"    , "0")%
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "街"      , "0")%
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "連戦"    , "0")%
                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "イベント", "0")%

                QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, KEYS      , "1")%
        ENDSELECT

        ;ALL以外に切り替えた場合はALLをOFFにする
        SIF KEYS != "ALL"
            QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "ALL","0")%

        ;ALLからALL以外に切り替えた場合、変更してないほうのフィルタグループをすべてONする
        IF PREV_FILTER_IS_ALL && KEYS != "ALL"
            SELECTCASE KEYS
                    ;クエスト周期フィルタ変更時
                CASE "周期", "単発"
                    ;クエスト種類フィルタをすべてON
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "探索"    , "1")%
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "街"      , "1")%
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "連戦"    , "1")%
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "イベント", "1")%
                    ;クエスト種類フィルタ変更時
                CASE "探索", "街", "連戦", "イベント"
                    ;クエスト周期フィルタをすべてON
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "周期", "1")%
                    QST_DIC_QUEST_FILTER = %DIC_SET(QST_DIC_QUEST_FILTER, "単発", "1")%
            ENDSELECT
        ENDIF
        ;ページ指定をリセット
        QST_MENU_PAGE_LEFT = 0
    ENDIF
ENDIF

@QST_WINDOW_ERROR_CHECK()
IF LIST_COUNT(_LIST_QST_PARTY) == 0
    CALLF TAG_PRINT(@"@C:{カラー_注意}@パーティが編成されていません@/C@", 1)
    WAIT
    RETURN 0
ENDIF
;クエスト固有の開始条件が設定されていればそちらに従う
TRYCCALLFORM QST_CAN_START_QUEST_{QST_SELECT_QUEST_ID}(QST_SELECT_QUEST_ID)
    RETURN RESULT
CATCH
    RETURN 1
ENDCATCH

@SELECT_CHARA_LIST_SHOW_LOGIC_QUEST(CHARA_ID)
#DIM CHARA_ID
RETURN CFLAG:CHARA_ID:所属 == CFLAG:MASTER:所属

@SELECT_CHARA_LIST_SELECT_LOGIC_QUEST(CHARA_ID)
#DIM CHARA_ID
;RETURN CHARA_ID != MASTER
RETURN 1


code:
;-------------------------------------------------
;クエスト定義ファイル
;QUEST_0:サンプルクエスト
;-------------------------------------------------
;クエスト選択画面で表示されるクエスト名
@QST_TITLE_QUEST_0
RESULTS '= "Goblin cave"

;ギルドメニューでクエストをフィルターする際のタグリスト。末尾の','を忘れないように
@QST_QUEST_TAG_0
RESULTS '= "周期,探索,"

;クエスト選択画面で呼び出される概要説明
;タグで装飾が可能(@FuncTagSetText_CreateColorBarText 参照)
;クエストメニュー右上段の概要欄。10行まで
@QST_SUMALLY1_QUEST_0
RESULTS:0 '= "It seems the goblins are attacking the villagers"
RESULTS:1 '= "If you go to the den of the goblins and defeat them, the guild will pay you a reward."
RESULTS:2 '= "Also, if you help the captured villagers, you can get additional reward(s)."

;クエストメニュー右下段の備考欄。難易度や条件、報酬等を記述。7行まで
@QST_SUMALLY2_QUEST_0
RESULTS:0 '= @"Difficulty：@C:{カラー_注意}@★@/C@"
RESULTS:1 '= "Reward：3,500ディナリ～"
RESULTS:2 '= "Recommended party size: 3+　　　Recommended party strength：20+"
RESULTS:3 '= ""
RESULTS:4 '= ""
RESULTS:5 '= @"@C:{カラー_選択不可}@「You shouldn't go alone, we saw so many younglings and wannabe heroes get destroyed」@/C@"
RESULTS:6 '= @"@C:{カラー_選択不可}@「...especially that young girl, Miji, what a horrible sight.」@/C@"

;-------------------------------------------------
;クエストの実行可能条件を定義
;-------------------------------------------------
@QST_AVAILABLE_QUEST_0(QUEST_ID)
#DIM QUEST_ID
RETURN 1

;-------------------------------------------------
;マップデータ定義
;[ROOM_ID:]　…　配置するエリアの種類
;[ROOM_PATH:]　…　エリア間の接続情報(※)
;[EVENT_LIST:]　…　エリアに配置するイベントのID(※)
;(※)要素の末尾の','を忘れないように注意
;<マップを編集するには>
;EmueraをDEBUGMODEで起動した場合、[領地の手入れ]画面から編集したエリア情報をテキストファイルにエクスポートできます
;sav/txt00.txtに出力されたマップ情報をコピペして編集すると少し楽になります
;<DEBUG MODE起動方法>
;https://ja.osdn.net/projects/emuera/wiki/debug
;-------------------------------------------------
@QST_SET_MAPDATA_QUEST_0(MAP_ID)
#DIM MAP_ID
QST_MAPNAME '= "ゴブリンの洞窟"
_DIC_HO_MAPDATA:MAP_ID:0  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:1  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:2  '= "[ROOM_ID:201][ROOM_PATH:7,][EVENT_LIST:0,]"
_DIC_HO_MAPDATA:MAP_ID:3  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:4  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:5  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:6  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:7  '= "[ROOM_ID:201][ROOM_PATH:2,8,12,][EVENT_LIST:6,]"
_DIC_HO_MAPDATA:MAP_ID:8  '= "[ROOM_ID:201][ROOM_PATH:7,][EVENT_LIST:1,]"
_DIC_HO_MAPDATA:MAP_ID:9  '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:10 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:11 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:12 '= "[ROOM_ID:201][ROOM_PATH:7,17,][EVENT_LIST:4,]"
_DIC_HO_MAPDATA:MAP_ID:13 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:14 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:15 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:16 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:17 '= "[ROOM_ID:201][ROOM_PATH:12,22,][EVENT_LIST:3,7,]"
_DIC_HO_MAPDATA:MAP_ID:18 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:19 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:20 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:21 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:22 '= "[ROOM_ID:200][ROOM_PATH:17,]"
_DIC_HO_MAPDATA:MAP_ID:23 '= "[ROOM_ID:0]"
_DIC_HO_MAPDATA:MAP_ID:24 '= "[ROOM_ID:0]"

;-------------------------------------------------
;クエストのタイプ
;マップ探索を伴う場合 "MAP"
;会話・文章のみで完結する場合 "DIALOGUE"
;-------------------------------------------------
@QST_TYPE_QUEST_0
RESULTS '= "MAP"

;-------------------------------------------------
;QST_INTRO_QUEST_n はQUEST開始前に呼ばれる
;クエストの導入文などを記述
;"DIALOGUE"型のクエストの場合当この関数のみを実行します
;-------------------------------------------------
@QST_INTRO_QUEST_0
PRINTFORMW %QST_LEADER_NAME()% headed to the cave pointed by the map provided by the guild
PRINTFORMW According to the request form, goblins based in a cave in the mountains have looted nearby farmers and peddlers.
PRINTFORMW %QST_LEADER_NAME()%'s mission imposed is the eradication of the goblins
PRINTL
PRINTFORMW Also, in the request form, if you find a survivor taken by a goblin, you want to rescue as much as possible.
PRINTFORMW If possible, you may do your best to release survivors from miserable fate.
PRINTL
PRINTFORMW …… They have the ugly properties of eating as desires to take away the herself.
PRINTFORMW You shouldn't despise the wise but wise goblins
PRINTFORMW %QST_LEADER_NAME()%'s party became prisoners, it would not be safe ...
PRINTW
CALL FL_PLAYBGM("Ambient_dark_0.ogg")

;-------------------------------------------------
;イベントリストに登録するイベント情報を記述する
;<記述方法>
;EVENT_TRIGGER
; "ENTER_ROOM" イベントが配置されたルームの入室時に強制的に実行される
; "EVENT_SLOT" イベントリストのクリック時に実行される
; "TRAIN_EXIT" 調教イベント終了後 ※予め変数:QST_TRAIN_EXIT_EVENT_ID に調教終了後に実行したいイベントIDを指定する必要がある
;EVENT_SLOT_NAME
; イベントリスト上の表示名
;EVENT_TYPE
; "ONCE" クエスト中一度のみ呼出されるイベント(※トリガーが"ENTER_ROOM"のイベントのみ機能)
;           実行済みかをフラグ管理するまでもないイベント(会話など)で使用する想定
;
;戻り値
; RESULT:0 = EVENT_TRIGGER
; RESULT:1 = EVENT_SLOT_NAME
; RESULT:2 = EVENT_TYPE
;-------------------------------------------------
;-------------------------------------------------
;EV0
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_0
#DIMS EVENT_TRIGGER = "ENTER_ROOM"
RESULTS = %EVENT_TRIGGER%

;-------------------------------------------------
;実行するイベントの実行内容を記述
;イベント用の関数はTRYCALLFORMで呼ばれるため
;@QST_QUEST_{QUEST_ID}_EVENT_{EVENT_ID}の書式で記述する
;-------------------------------------------------
@QST_QUEST_0_EVENT_0
#DIM CONST 関連イベントID = 2
#DIM DYNAMIC EV2救出実行済み
CALL QST_GET_EVENT_FLAG(関連イベントID)
SIF RESULT == 1
    EV2救出実行済み = 1

IF !EV2救出実行済み
    PRINTFORMW %QST_LEADER_NAME ()% set a surprise to the goblins!
    PRINTFORMW The goblins are confused by being surprised！
ELSE
    PRINTFORMW After hearing the fuss I had earlier, the goblins were solidifying the protection
    PRINTFORMW %QST_LEADER_NAME()% appears ready to shoot！
ENDIF
;;戦闘イベント処理
;白兵戦参加メンバーの初期化
CALL CC_INIT()
;クエストのパーティメンバーを攻撃側として追加
CALL CC_ADDPARTY("ATTACKER")

;防御側キャラクターの設定(最大6名)
CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン１")
CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン２")
IF EV2救出実行済み
    CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン３")
    CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン４")
ENDIF
;戦闘処理呼出
CALL CLOSE_COMBAT()
IF RESULT == 1
    ;戦闘終了後のHPをパーティに適用
    CALL CC_APPLY_CHARA_HP()
    ;防御側エネミーから戦利品を獲得
    CALL CC_GET_LOOT_FROM("DEFENDER")
    CALL FL_PLAYSE("Fanfare_0.ogg")
    PRINTFORMW %QST_LEADER_NAME()% succeeded in defeating goblins nesting in the cave!
    CALL COLOR_PRINTW("I got 3,500 dinari as a reward", カラー_注意)
    MONEY += 3500
    ;QST_SV_QUEST_FLAGはセーブされるクエストの状態を示すフラグ。QST_有効クエストIDには現在のクエストID(ゴブ洞は0)が入る
    ;クエストが攻略済みかを判定する場合に使うとよい
    QST_SV_QUEST_FLAG:QST_有効クエストID = 1
    ;クエスト終了時の決まり文句
    TFLAG:クエスト_完了フラグ = 1
    CALL TRAIN_EXIT()
ELSE
    ;敗北イベント
    PRINTFORMW The goblins were victorious against the defeated %QST_LEADER_NAME()%, and began to play with it ...
    CALL QST_QUEST_0_DEFEAT_EVENT
ENDIF

;-------------------------------------------------
;EV1
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_1
#DIMS EVENT_TRIGGER = "ENTER_ROOM"
RESULTS = %EVENT_TRIGGER%

@QST_QUEST_0_EVENT_1
#DIM CONST EVENT_ID = 1
#DIM CONST 派生イベントID = 2
#DIM EVENT_FLAG
CALL QST_GET_EVENT_FLAG(派生イベントID)
EVENT_FLAG = RESULT
;このイベントは後続の派生イベント(EV2)の選択結果で2回目以降の処理が変わるのでセットされたフラグを見て内容を分岐
DEBUGPRINTFORML {EVENT_FLAG}
SELECTCASE EVENT_FLAG
        ;初回
    CASE 0
        PRINTFORMW There are countless goblins in the darkness of the Kojikoji.
        PRINTFORMW They seem to be playing with the captured woman ...
        ;調教モードをクエスト -> 慰安に切替
        FLAG:ウフフフラグ = 1
        FLAG:調教モード = 調教_慰安
        TFLAG:調教ターン数 = 8
        FLAG:調教スキップ可 = 1

        CVARSET CFLAG, GETNUM(CFLAG, "調教参加フラグ") , 0
        ;慰安モブを追加
        CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")
        CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")
        CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")
        ;適当に被害者を追加
        FOR LOCAL, 0, 4
            CALL QST_QUEST_0_CREATE_TRAIN_VICTIMS
        NEXT
        ;調教後に呼び出される後続イベント
        CALL QST_ENQUEUE_TRAIN_EXIT_EVENT(派生イベントID)
        ;ゴブリンを討伐
    CASE 1
        PRINTFORMW A goblin carcass is scattered on a pilgrimage
        ;被害者を見捨てる
    CASE 2
        PRINTFORMW The goblins are continuing to insult ...
        PRINTFORMW I don't seem to notice the hidden %QST_LEADER_NAME()%
ENDSELECT

;-------------------------------------------------
;EV2
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_2
#DIMS EVENT_TRIGGER = "TRAIN_EXIT"
RESULTS = %EVENT_TRIGGER%

@QST_QUEST_0_EVENT_2
#DIM CONST EVENT_ID = 2
#DIM EVENT_FLAG
PRINTFORMW The insult by goblin continues ...
PRINTFORMW Should they rescue them ...?
CALL COLOR_PRINTW("If you make a fuss here, you will get the attention of other goblins.", カラー_注意)
CALL ASK_YN("救出を試みる", "見捨てる")
IF RESULT == 0
    PRINTFORMW %QST_LEADER_NAME()% picked up weapons and attacked the goblin!
    ;戦闘イベント
    CALL CC_INIT()
    ;クエストのパーティメンバーを攻撃側として追加
    CALL CC_ADDPARTY("ATTACKER")
    ;防御側エネミー設定
    CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン１")
    CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン２")
    CALL CC_ADDMOB_FROM_TABLE("DEFENDER", "ゴブリン", "ゴブリン３")
    ;戦闘処理呼出
    CALL CLOSE_COMBAT()
    ;CLOSE_COMBATの戻り値は攻撃側勝利 = 1,防衛側勝利 = 2
    IF RESULT == 1
        ;戦闘終了後のHPをパーティに適用
        CALL CC_APPLY_CHARA_HP()
        ;防御側エネミーから戦利品を獲得
        CALL CC_GET_LOOT_FROM("DEFENDER")
        PRINTFORMW %QST_LEADER_NAME()% who won the battle succeeded in releasing women
        PRINTFORMW When they thanked them with tears, they headed to the exit with a gait that did not witness
        PRINTFORMW I got some money as a reward
        CALL COLOR_PRINTW("2,000ディナリを得た", カラー_注意)
        MONEY += 2000
        CALL QST_SET_EVENT_FLAG(EVENT_ID, 1)
    ELSE
        CALL CC_APPLY_CHARA_HP()
        CALL COLOR_PRINTW(@"%QST_LEADER_NAME()%はゴブリンたちに打ち負かされてしまった……", カラー_注意)
        PRINTFORMW When the goblins were defeated by the defeated %QST_LEADER_NAME()%, they began to play with a sloppy smile ...
        CALL QST_QUEST_0_DEFEAT_EVENT
    ENDIF
ELSE
    PRINTFORMW %QST_LEADER_NAME()% quietly left the place ...
    CALL QST_SET_EVENT_FLAG(EVENT_ID, 2)
ENDIF

;-------------------------------------------------
;EV3
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_3
#DIMS EVENT_TRIGGER = "EVENT_SLOT"
#DIMS EVENT_SLOT_NAME = "Wooden box"
RESULTS:0 = %EVENT_TRIGGER%
RESULTS:1 = %EVENT_SLOT_NAME%

@QST_QUEST_0_EVENT_3
#DIM CONST EVENT_ID = 3
#DIM EVENT_FLAG

CALL QST_GET_EVENT_FLAG(EVENT_ID)
IF !RESULT
    PRINTFORMW %QST_LEADER_NAME()% opened the box ...
    CALL CHANGE_ITEM_STOCK(ITEM_薬草, 3)
    CALL GET_ITEM_NAME(ITEM_薬草)
    CALL COLOR_PRINTW(@"I got 3x %results%", カラー_注意)
    CALL QST_SET_EVENT_FLAG(EVENT_ID, 1)
    CALL QST_SET_EVENT_SLOT_NAME(EVENT_ID, "Wooden box (empty)")
ELSE
    PRINTFORMW This wooden box is a kara
ENDIF

;-------------------------------------------------
;EV4
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_4
#DIMS EVENT_TRIGGER = "EVENT_SLOT"
#DIMS EVENT_SLOT_NAME = "Treasure chest"
RESULTS:0 = %EVENT_TRIGGER%
RESULTS:1 = %EVENT_SLOT_NAME%

@QST_QUEST_0_EVENT_4
#DIM CONST EVENT_ID = 4
#DIM EVENT_FLAG
#DIM TARGET_ID

CALL QST_GET_EVENT_FLAG(EVENT_ID)
IF !RESULT
    PRINTFORMW %QST_LEADER_NAME()% opened the treasure chest ...
    PRINTFORMW
    TARGET_ID = TOINT(LIST_GET(_LIST_QST_PARTY, RAND(0, QST_PARTYNUM)))
    CALL COLOR_PRINTW(@"―――― It's a trap of corrosion solution! The bleeding rotten liquid attacks %ANAME(TARGET_ID)%!", カラー_注意)
    CALL QST_ARMOR_BREAK(TARGET_ID, 被覆部位_乳首, 100)
    IF !RESULT
        PRINTFORMW %ANAME(TARGET_ID)%, but fortunately nothing happened ...
    ENDIF
    PRINTFORMW
    PRINTFORMW %ANAME(TARGET_ID)% frowned and wiped the liquid again, revealed the inside of the box ...
    CALL CHANGE_ITEM_STOCK(ITEM_鉄インゴット, 3)
    CALL GET_ITEM_NAME(ITEM_鉄インゴット)
    CALL COLOR_PRINTW(@"I got 3 %RESULTS% from the box", カラー_注意)
    CALL QST_SET_EVENT_FLAG(EVENT_ID, 1)
    CALL QST_SET_EVENT_SLOT_NAME(EVENT_ID, "Treasure box (empty)")
ELSE
    PRINTFORMW This treasure chest is Karako
ENDIF

;-------------------------------------------------
;EV5
;敗北イベント後の共通エンディング（クエスト失敗）
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_5
#DIMS EVENT_TRIGGER = "TRAIN_EXIT"
RESULTS = %EVENT_TRIGGER%

@QST_QUEST_0_EVENT_5
#DIM CONST EVENT_ID = 5
#DIM EVENT_FLAG
#DIM TARGET_ID

PRINTFORMW %QST_LEADER_NAME()% has been humiliated by a group of goblins ...
PRINTFORMW Look at the gaps of the goblins and somehow aim for the exit of the cave ...
PRINTL
PRINTFORMW Fortunately, the goblins have found a new target, or they don't seem to notice %QST_LEADER_NAME()%.
PRINTW
PRINTFORMW %QST_LEADER_NAME()% escaped the cave with a crawling body ...
TFLAG:クエスト_完了フラグ = 1
CALL TRAIN_EXIT()

;-------------------------------------------------
;EV6
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_6
#DIMS EVENT_TRIGGER = "ENTER_ROOM"
#DIMS EVENT_TYPE = "ONCE"
RESULTS:0 = %EVENT_TRIGGER%
RESULTS:2 = %EVENT_TYPE%

@QST_QUEST_0_EVENT_6
#DIM EVENT_ID = 6
PRINTFORMW The aisle is divided into two hands here
PRINTFORMW If you go straight, you will reach the deepest part of this cave.Probably the goblins are lurking
PRINTFORMW …… On the other hand, the cry of the goblins can be heard from the right side of the foot.
PRINTFORMW %ANAME(QST_RANDCHARA())% noticed that the remnants of the torn human clothing are scattered in front of the right hand.
PRINTW
PRINTFORMW If you go to the right, you may be able to find the people taken away ...

;QST_SET(GET)_SV_EVENT_FLAGは各クエストのイベント毎のフラグをセーブデータに保持するので
;複数回実行可能なタイプのクエストで、貴重品入手イベント等を１回のみ実行したい場合などは
;このフラグで制御するとよい
CALL QST_GET_SV_EVENT_FLAG(EVENT_ID)
SIF RESULT == 1
    RETURN
PRINTW
PRINTFORMW %QST_LEADER_NAME()% collected equipment that could be used from scattered clothing
CALL QST_GET_WEAPON(1, "Adventurer's iron dagger", WPN_材質_鉄)
CALL COLOR_PRINTW(@"―― Weapons can be changed from [ITEM] -> [Weapon]", カラー_注意)
PRINTL
{
    CALL QST_GET_WEAPON(
        20
        ,"濁り剣盾の呪印"
        ,WPN_材質_その他
        ,0
        ,"[WPN_VAGINA_GUARD:1][WPN_PENIS_GUARD:1]"
        ,""
        ,WPN_装備種別_レリック
        ,1
        )
}
CALL COLOR_PRINTW(@"――Relic can be changed from [ITEM] -> [Relic]", カラー_注意)
CALL QST_SET_SV_EVENT_FLAG(EVENT_ID, 1)

;-------------------------------------------------
;EV7
;-------------------------------------------------
@QST_ADD_EVENT_QUEST_0_EVENT_7
#DIMS EVENT_TRIGGER = "ENTER_ROOM"
#DIMS EVENT_TYPE = "ONCE"
RESULTS:0 = %EVENT_TRIGGER%
RESULTS:2 = %EVENT_TYPE%

@QST_QUEST_0_EVENT_7
#DIM EVENT_ID = 7

PRINTFORMW There is a product that seems to be a looted goblin beside the aisle
PRINTFORMW Maybe there is something that can be used ...
PRINTL
CALL COLOR_PRINTW(@"―― You can check the contents by clicking the [wooden box] button on the right of the map screen", カラー_注意)

;-------------------------------------------------
;以下イベントリストで管理する必要のない処理,イベント固有の関数など
;-------------------------------------------------
@QST_QUEST_0_DEFEAT_EVENT
#DIM CONST 派生イベントID = 5
FLAG:ウフフフラグ = 1
FLAG:調教モード = 調教_慰安
TFLAG:調教ターン数 = 20

;主導除外フラグが立ったキャラクターは慰安調教で常にターゲットに回る。
;拘束中など自主的に行動させたくないシチュエーションでこのフラグを立てる。
CVARSET CFLAG, GETNUM(CFLAG, "調教参加フラグ") , 0
FOR LOCAL, 0, QST_PARTYNUM
    ;調教コマンドのプレイヤーにならなくなる。一方的に嬲られるシチュ用
    CFLAG:(TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))):主導除外 = 1
    ;良感情を極めて得にくくなるフラグ
    CFLAG:(TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))):凌辱被害者フラグ = 1
    CFLAG:(TOINT(LIST_GET(_LIST_QST_PARTY, LOCAL))):調教参加フラグ = 1
NEXT
;慰安モブを追加
CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")
CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")
CALL QST_TRAIN_MOB_PRESET("ゴブリン", @"%SPLIT_RAND("醜悪な/小太りの/痩せた/子",1)%ゴブリン")

CALL QST_ENQUEUE_TRAIN_EXIT_EVENT(派生イベントID)
RETURN

;-------------------------------------------------
;慰安モブの定義
;-------------------------------------------------
@QST_QUEST_0_CREATE_TRAIN_VICTIMS(主導除外フラグ = 1)
#DIM 対象
#DIMS 名前
#DIM 主導除外フラグ

名前 = %SPLIT_RAND("冒険者/村娘/魔術師/行商人/孕み袋",1)%

CALL CREATE_RANDOM_CHARA(0, -1, 1)
FLAG:汎用武将カウント --
対象 = RESULT
IF LOCAL == -1
    RETURN -1
ENDIF

NO:対象 = GET_EMPTY_NO()
NAME:対象 = %名前%
CALLNAME:対象 = %名前%
TALENT:対象:処女 = 0
TALENT:対象:キス未経験 = 0
TALENT:対象:童貞 = 0
TALENT:対象:アナル処女 = 0
CSTR:対象:0 =
CSTR:対象:1 =
TALENT:対象:性別 = 1
ABL:対象:性知識 =  3
ABL:対象:Ｃ感 = 28
ABL:対象:奉仕 = 1
ABL:対象:性技 = RAND(10, 14)
ABL:対象:欲望 = RAND(3, 7)
ABL:対象:性交 = RAND(13, 15)
ABL:対象:サド = RAND(0, 3)
ABL:対象:主導度Ｕ = RAND(0, 500)
ABL:対象:倒錯度 = RAND(0, 300)
TALENT:対象:貞操無頓着 = 1
TALENT:対象:貞操観念 = 0
TALENT:対象:崩壊 = RAND(0, 1)
TALENT:対象:母乳体質 = 1
SEXUAL_EXPERIENCE:(対象):初体験_処女 = ゴブリン
SEXUAL_LAST_EXPERIENCE:(対象):初体験_処女 = ゴブリン
SEXUAL_EXPERIENCE:(対象):初体験_キス = ゴブリン
SEXUAL_LAST_EXPERIENCE:(対象):初体験_キス = ゴブリン
SEXUAL_EXPERIENCE:(対象):初体験_童貞 = ゴブリン
SEXUAL_LAST_EXPERIENCE:(対象):初体験_童貞 = ゴブリン
SEXUAL_EXPERIENCE:(対象):初体験_アナル処女 = ゴブリン
SEXUAL_LAST_EXPERIENCE:(対象):初体験_アナル処女 = ゴブリン
;CFLAG:対象:慰安モブ = 1
CFLAG:対象:調教参加フラグ  = 主導除外フラグ
CFLAG:対象:主導除外  = 1
CFLAG:対象:慰安モブ = 1


code:
;-------------------------------------------------
;クエスト定義ファイル
;QUEST_10
;-------------------------------------------------
@QST_TITLE_QUEST_10
RESULTS '= "魔導工学者エル"

;ギルドメニューでクエストをフィルターする際のタグリスト。末尾の','を忘れないように
@QST_QUEST_TAG_10
RESULTS '= "単発,イベント,"

;-------------------------------------------------
;クエストの実行可能条件を定義
;-------------------------------------------------
@QST_AVAILABLE_QUEST_10(QUEST_ID)
#DIM QUEST_ID
SIF CFLAG:NAME_TO_CHARA("エル"):所属 == 所属_プレイヤー
    RETURN 0

RETURN 1

;-------------------------------------------------
;クエストのタイプ
;マップ探索を伴う場合 "MAP"
;文章のみで完結する場合 "DIALOGUE"
;-------------------------------------------------
@QST_TYPE_QUEST_10
RESULTS '= "DIALOGUE"

;クエストメニュー右上段の概要欄。10行まで
@QST_SUMALLY1_QUEST_10
RESULTS:0 '= "エルと名乗る少女があなたを訪ねてくる"
RESULTS:1 '= "曰く、あなたの領地は非常に珍しい特質を帯びており、彼女の研究にはうってつけらしい"
RESULTS:2 '= "彼女は錬金術や素材加工について専門的な知識を提供できると言っているが……"

;クエストメニュー右下段の備考欄。難易度や条件、報酬等を記述。7行まで
@QST_SUMALLY2_QUEST_10
RESULTS:0 '= @"難易度：-"
RESULTS:1 '= "支度金：7,000ディナリ(工房を仕立てるのに使わせてもらうよ)"
RESULTS:4 '= @"@C:{カラー_選択不可}@「この嬢ちゃんはコモンウェルスの都ノルディアのアカデミーの出だそうだ」@/C@"
RESULTS:5 '= @"@C:{カラー_選択不可}@「あそこは控えめに言っても奇人・変人の巣窟だが、頭がキレるのは間違いないだろう」@/C@"

;-------------------------------------------------
;QST_INTRO_QUEST_n はQUEST開始前に呼ばれる
;クエストの導入文などを記述
;"DIALOGUE"型のクエストは当該関数のCALLのみ行う
;-------------------------------------------------
@QST_INTRO_QUEST_10
#DIM WEAPON_LIST_IDX

SETCOLOR エル_口上カラー
PRINTFORMDW %ANAME(MASTER)%はテーブルを挟んでエルと名乗る少女と対峙している
PRINTFORMDW 彼女は魔導工学者という肩書を名乗っており、研究のために%ANAME(MASTER)%を間借りしたいとのことだ
PRINTFORMDW 対価として彼女の知識や精製物を提供できると言っている
PRINTL
PRINTFORMW 「普通、マナが極度に集中した土地はとても厳しい環境になるんだ。樹海であったり火山であったりね」
PRINTFORML 「ところがキミの土地はギュッとマナが詰まっているのにとても安定している」
PRINTFORMW 「……少なくとも私はこれまでそんな場所を見たことがないし、聞いたこともない」
PRINTL
PRINTFORMDW 彼女は大きなマリンブルーの瞳をキラキラさせ、好奇心を抑えきれぬ様子で熱弁する
PRINTFORMW 「私達魔導工学者は動力機関を動かすにせよ、明かりを灯すにせよ、安定的なエネルギーをどこから引っ張ってくるのか常々頭を悩ませていてね」
PRINTFORMW 「その点キミの土地は落ち着いてエネルギーを調達できる、研究にはうってつけの場所に見える」
PRINTL
PRINTFORMW 「どうだろう、私を雇ってみる気はないかな？少し時間を貰えれば成果をキミに対価として提供できるはずだ」
PRINTL
PRINTFORMDW あの広く、ひなびた土地に彼女が言うほどの価値があるのか%ANAME(MASTER)%は疑問を拭えなかった
PRINTFORMDW 彼女を言を信じるならば、あるいは人手が欲しいのなら彼女の言葉にのってもよいが……
CALL ASK_YN("雇う","やめておく")
IF !RESULT
    IF MONEY < 7000
        PRINTFORMDW お金が足りないようだ……
        RETURN
    ENDIF
    PRINTFORMDW ………………
    PRINTFORMDW …………
    PRINTFORMDW ……
    PRINTL
    PRINTFORMW 「ありがとう！それじゃあこのお金は研究資材その他諸々を揃えるのに使わせてもうらうよ！」
    PRINTFORMDW そう言い残すと彼女は矢のように飛び出していってしまった
    PRINTFORMDW あとに残された%ANAME(MASTER)%はひとまずテーブルの上の飲み物を飲み干す
    PRINTL
    PRINTFORMDW 何はともあれ少し賑やかになりそうだ……
    CALL COLOR_PRINTW("―― 魔導工学者のエルが仲間になった！", カラー_注意)
    CFLAG:NAME_TO_CHARA("エル"):所属 = 所属_プレイヤー
    MONEY -= 7000
    QST_SV_QUEST_FLAG:QST_有効クエストID = 1
ELSE
    PRINTFORMW 「そう……、それは残念。まぁもう少しこの辺りに居るつもりだから気が変わったら声をかけてよ」
ENDIF

CFLAG:NAME_TO_CHARA("エル"):面識 = 1
TFLAG:クエスト_完了フラグ = 1
CALL TRAIN_EXIT()