diff --git a/2.05-custom-gx/action.hsp b/2.05-custom-gx/action.hsp index aa625cc4..b7ef19f6 100644 --- a/2.05-custom-gx/action.hsp +++ b/2.05-custom-gx/action.hsp @@ -814,7 +814,9 @@ ********** ORIGINAL - ENDING **********/ - snd SOUNDLIST_GETGOLD1 + if ( locvar_is_autopick == FALSE | cfg_autopicksound ) { + snd SOUNDLIST_GETGOLD1 + } ti = ci in = inv(INV_ITEM_NUM, ci) inv(INV_ITEM_NUM, ci) = 0 @@ -895,7 +897,7 @@ } } } - if ( inv(INV_ITEM_PROPERTY, ci) == PROP_CONSTRUCT ) { + if ( inv(INV_ITEM_PROPERTY, ci) == PROP_CONSTRUCT & locvar_is_autopick == FALSE ) { txt lang(itemname(ci) + "を撤去する? ", "Do you want to remove " + itemname(ci) + "? ") promptYesNo if ( rtval == 0 ) { @@ -919,6 +921,9 @@ } } if ( inv_getfreeid(cc) == (-1) ) { + if ( locvar_is_autopick ) { + txt lang("[自動拾い]", "[Autopickup]") + } txt_invfull2 return 0 } @@ -982,6 +987,9 @@ txt lang("店の倉庫が一杯のため売れない。", "Shopkeeper's inventory is full.") } else { + if ( locvar_is_autopick ) { + txt lang("[自動拾い]", "[Autopickup]") + } txt_invfull2 } return 0 @@ -1107,7 +1115,12 @@ else { cell_refresh inv(INV_ITEM_X, ci), inv(INV_ITEM_Y, ci) map(inv(INV_ITEM_X, ci), inv(INV_ITEM_Y, ci), 5) = map(inv(INV_ITEM_X, ci), inv(INV_ITEM_Y, ci), 4) - snd SOUNDLIST_GET1 + rnd(2) + if( locvar_is_autopick == FALSE | cfg_autopicksound ) { + snd SOUNDLIST_GET1 + rnd(2) + } + if ( locvar_is_autopick ) { + txt lang("[自動拾い]", "[Autopickup]") + } msgkeep = 1 txt lang(name(cc) + "は" + itemname(ti, in) + "を拾った。", name(cc) + " pick" + _s(cc) + " up " + itemname(ti, in) + ".") } @@ -2375,7 +2388,19 @@ } if ( map(x, y, 4) != 0 ) { if ( cdata(CDATA_CONDITION_BLIND, CHARA_PLAYER) == 0 ) { - txt txtitemoncell(x, y) + if ( cfg_autopick ) { + if ( adata(ADATA_TYPE, gdata(GDATA_AREA)) != MAP_TYPE_HOME | adata(ADATA_TYPE, gdata(GDATA_AREA)) == AREA_RANCH | adata(ADATA_TYPE, gdata(GDATA_AREA)) == AREA_SHELTER ) { + if ( key_ctrl != 1 ) { + x = cdata(CDATA_X, CHARA_PLAYER) + y = cdata(CDATA_Y, CHARA_PLAYER) + cnt3 = 0 + gosub *AutoPickTest + } + } + } + if ( map(x, y, 4) != 0 ) { + txt txtitemoncell(x, y) + } } else { txt lang("地面に何かがあるようだ。", "You sense something under your foot.") diff --git a/2.05-custom-gx/config.hsp b/2.05-custom-gx/config.hsp index 054edb01..a65af0ad 100644 --- a/2.05-custom-gx/config.hsp +++ b/2.05-custom-gx/config.hsp @@ -286,6 +286,12 @@ cfgRead "dmgPopupFontSize.", cfg_dmgfont = int(rtvaln) cfgRead "dmgPopupSpeed.", cfg_dmgspeed = int(rtvaln) + // Autopickup options + + cfgRead "autopick.", cfg_autopick = int(rtvaln) + cfgRead "autopick_sound.", cfg_autopicksound = int(rtvaln) + cfgRead "autodestroy_sound.", cfg_autodestroysound = int(rtvaln) + // Other options cfgRead "showFps.", cfg_showfps = int(rtvaln) @@ -468,7 +474,7 @@ dim monitorInfo, 10 + 8 ; MONITORINFOEX monitorInfo(0) = 40 + 32 - dim devMode, 44 ; DEVMODEA + dim devMode, 44 ; DEVMODEA MonitorFromPoint 0, 0, 0 ; Get primary monitor at (0, 0) if ( stat ) { GetMonitorInfo stat, varptr(monitorInfo) @@ -543,7 +549,7 @@ } if ( submenu == 0 ) { q = lang("オプション", "Option") - s = lang("ゲームの設定", "Game Setting"), lang("画面と音の設定", "Screen & Sound"), lang("ネット機能の設定", "Network Setting"), lang("詳細な設定", "Detailed Setting"), lang("ゲームパッド", "Game Pad"), lang("メッセージとログ", "Message & Log"), lang("言語(Language)", "Language"), lang("拡張設定1(表示)", "EX Setting 1 (Display)"), "" + s = lang("ゲームの設定", "Game Setting"), lang("画面と音の設定", "Screen & Sound"), lang("ネット機能の設定", "Network Setting"), lang("詳細な設定", "Detailed Setting"), lang("ゲームパッド", "Game Pad"), lang("メッセージとログ", "Message & Log"), lang("言語(Language)", "Language"), lang("拡張設定1", "EX Setting 1"), lang("拡張設定2(表示)", "EX Setting 2 (Display)"), "" dx = 370 dy = 290 @@ -591,7 +597,13 @@ dy = 300 } if ( submenu == 8 ) { - q = lang("拡張設定1(表示)", "EX Setting 1 (Display)") + q = lang("拡張設定1", "EX Setting 1") + s = lang("自動拾い&自動破壊", "Auto pickup & destroy"), lang("自動拾い時の効果音", "Autopick sound"), lang("自動破壊時の効果音", "Autodestroy sound"), "" + dx = 440 + dy = 300 + } + if ( submenu == 9 ) { + q = lang("拡張設定2(表示)", "EX Setting 2 (Display)") s = lang("ダメージ表示", "Damage Popups"), lang(" HEX+バフ", " Hexes/Buffs"), lang(" 状態異常", " Ailments"), lang(" 回避", " Evade"), lang(" フォントサイズ", " Font Size"), lang(" 表示速度", " Display Duration"), "" dx = 440 dy = 300 @@ -891,6 +903,20 @@ } } if ( submenu == 8 ) { + if ( cnt == 0 ) { + s = lang("使わない", "Disable"), lang("使う", "Enable") + mes s(cfg_autopick) + } + if ( cnt == 1 ) { + s = lang("なし", "Off"), lang("あり", "On") + mes s(cfg_autopicksound) + } + if ( cnt == 2 ) { + s = lang("なし", "Off"), lang("あり", "On") + mes s(cfg_autodestroysound) + } + } + if ( submenu == 9 ) { if ( cnt == 0 ) { s = lang("しない", "Off"), lang("する", "On") mes s(cfg_dmgpopups) @@ -1720,7 +1746,19 @@ } } if ( submenu == 8 ) { - snd SOUNDLIST_OK1 + snd SOUNDLIST_OK1 + if ( cs == 0 ) { + setBoolOption cfg_autopick, "autopick" + } + if ( cs == 1 ) { + setBoolOption cfg_autopicksound, "autopick_sound" + } + if ( cs == 2 ) { + setBoolOption cfg_autodestroysound, "autodestroy_sound" + } + } + if ( submenu == 9 ) { + snd SOUNDLIST_OK1 if ( cs == 0 ) { setBoolOption cfg_dmgpopups, "dmgPopups" } diff --git a/2.05-custom-gx/custom_autopick.hsp b/2.05-custom-gx/custom_autopick.hsp new file mode 100644 index 00000000..b66c49c0 --- /dev/null +++ b/2.05-custom-gx/custom_autopick.hsp @@ -0,0 +1,640 @@ +// Ports omake's autopickup. + +#deffunc AutoPickLoadSettingsFile int locvar_autopick_file_index + sdim autopickbuff, 256, 500 + if ( locvar_autopick_file_index == 0 ) { + exist exedir + "save\\" + playerid + "\\" + "autopick.txt" + if ( strsize != (-1) ) { + notesel autopickbuff + noteload exedir + "save\\" + playerid + "\\" + "autopick.txt" + noteunsel + } + } + else { + exist exedir + "save\\" + playerid + "\\" + "autopick_" + locvar_autopick_file_index + ".txt" + if ( strsize != (-1) ) { + notesel autopickbuff + noteload exedir + "save\\" + playerid + "\\" + "autopick_" + locvar_autopick_file_index + ".txt" + noteunsel + } + } + AutoPickCurrentSettingsFileIndex = locvar_autopick_file_index + return + +#deffunc AutoPickOpenSettingsFile int locvar_autopick_file_index + if ( locvar_autopick_file_index == 0 ) { + exist exedir + "save\\" + playerid + "\\" + "autopick.txt" + if ( strsize != (-1) ) { + exec exedir + "save\\" + playerid + "\\" + "autopick.txt", 16 + } + } + else { + exist exedir + "save\\" + playerid + "\\" + "autopick_" + locvar_autopick_file_index + ".txt" + if ( strsize != (-1) ) { + exec exedir + "save\\" + playerid + "\\" + "autopick_" + locvar_autopick_file_index + ".txt", 16 + } + } + return + +#deffunc AutoPickWriteDefaultSettingsFile + notesel locvar_autopick_notebuff + noteload exedir + "data\\autopick.txt" + notesave exedir + "save\\" + playerid + "\\" + "autopick.txt" + noteunsel + return + +*AutoPickReloadSettingsFile + promptmax = 0 + exist exedir + "save\\" + playerid + "\\" + "autopick.txt" + if ( strsize != (-1) ) { + promptl(0, promptmax) = "autopick.txt", "null", "" + 0 + promptmax++ + } + repeat 9, 1 + exist exedir + "save\\" + playerid + "\\" + "autopick_" + cnt + ".txt" + if ( strsize != (-1) ) { + promptl(0, promptmax) = "autopick_" + cnt + ".txt", "null", "" + cnt + promptmax++ + } + loop + if ( promptmax == 0 ) { + txt lang("autopick.txtは見つかりませんでした。作成する?", "There's no autopick.txt for this save. Create one?") + promptYesNo + if ( rtval == 0 ) { + AutoPickWriteDefaultSettingsFile + exec exedir + "save\\" + playerid + "\\" + "autopick.txt", 16 + } + else { + gosub *screen_draw + return + } + promptmax = 0 + rtval = 0 + } + else { + if ( promptmax > 1 ) { + txt lang("どのファイルを再読み込みする?", "Which autopickup file do you want to load?") + val = promptx, prompty, 220, 1 + gosub *prompt_key + if ( rtval == (-1) ) { + rtval = 0 + } + } + else { + promptmax = 0 + rtval = 0 + } + } + AutoPickLoadSettingsFile rtval + if ( rtval == 0 ) { + txt lang("autopick.txtを再読み込みした。", "Reloaded autopick.txt.") + } + else { + txt lang("autopick_" + rtval + ".txtを再読み込みした。", "Reloaded autopick_" + rtval + ".txt.") + } + await 200 + gosub *screen_draw + return + +*AutoPickTest + inv_getheader -1 + repeat invrange, invhead + notesel autopickbuff + if ( inv(INV_ITEM_NUM, cnt) <= 0 ) { + continue + } + if ( inv(INV_ITEM_PROPERTY, cnt) >= PROP_NPC ) { + continue + } + if ( inv(INV_ITEM_X, cnt) != x | inv(INV_ITEM_Y, cnt) != y ) { + continue + } + item_checkknown cnt + cnt2 = cnt + locvar_autopick_itemtype = refitem(inv(INV_ITEM_ID, cnt2), DBSPEC_TYPE) + repeat noteinfo(0) + p = 0 + p(1) = 0 + noteget buff, cnt + locvar_autopick_commentpos = instr(buff, 0, "#") + if ( locvar_autopick_commentpos != (-1) ) { + buff = strmid(buff, 0, locvar_autopick_commentpos) + } + s = buff + if ( instr(s, 0, "!!") != (-1) ) { + getstr s, s, 2 + } + else { + if ( instr(s, 0, "!") != (-1) | instr(s, 0, "~") != (-1) ) { + getstr s, s, 1 + } + } + locvar_autopick_charpos = instr(s, 0, "?") + locvar_autopick_prompt = FALSE + if ( locvar_autopick_charpos != (-1) ) { + locvar_autopick_prompt = TRUE + s = strmid(s, 0, locvar_autopick_charpos) + } + locvar_autopick_charpos = instr(s, 0, ":sound") + if ( locvar_autopick_charpos != (-1)) { + s = strmid(s, 0, locvar_autopick_charpos) + } + s = strtrim(s, 0, 32) + while instr(s, 0, " ") != (-1) != 0 + sreplace s, s, " ", " " + wend + if ( s == "" | s == " " ) { + continue + } + s = " " + s + " " + if ( instr(s, 0, lang("すべての", " all ")) != (-1) ) { + p(1) = 1 + delstr s, lang("すべての", " all ") + sreplace s, s, lang("すべての", " all "), " " + } + if ( instr(s, 0, lang("名称不明の", " unknown ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) != ITEM_KNOWN_NONE ) { + continue + } + sreplace s, s, lang("名称不明の", " unknown "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("鑑定段階1の", " name identified ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) != ITEM_KNOWN_NAME ) { + continue + } + sreplace s, s, lang("鑑定段階1の", " name identified "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("鑑定段階2の", " quality identified ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) != ITEM_KNOWN_QUALITY ) { + continue + } + sreplace s, s, lang("鑑定段階2の", " quality identified "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("鑑定段階3の", " fully identified ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) != ITEM_KNOWN_FULL ) { + continue + } + sreplace s, s, lang("鑑定段階3の", " fully identified "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("無価値の", " worthless ")) != (-1) ) { + if ( inv(INV_ITEM_VALUE, cnt2) > 10 ) { + continue + } + sreplace s, s, lang("無価値の", " worthless "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("腐った", " rotten ")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_FOOD ) { + continue + } + if ( inv(INV_ITEM_PARAM3, cnt2) >= 0 ) { + continue + } + sreplace s, s, lang("腐った", " rotten "), " " + p(1) = 1 + } + // if ( instr(s, 0, lang("腐りきった", " zombie ")) != (-1) ) { + // if ( locvar_autopick_itemtype != FILTER_ITEM_FOOD ) { + // continue + // } + // if ( inv(INV_ITEM_SUB_NAME, cnt2) != 21 & inv(INV_ITEM_SUB_NAME, cnt2) != 47 & inv(INV_ITEM_SUB_NAME, cnt2) != 48 & inv(INV_ITEM_SUB_NAME, cnt2) != 49 & inv(INV_ITEM_SUB_NAME, cnt2) != 99 & inv(INV_ITEM_SUB_NAME, cnt2) != 100 & inv(INV_ITEM_SUB_NAME, cnt2) != 101 & inv(INV_ITEM_SUB_NAME, cnt2) != 257 & inv(INV_ITEM_SUB_NAME, cnt2) != 254 ) { + // continue + // } + // sreplace s, s, lang("腐りきった", " zombie "), " " + // p(1) = 1 + // } + // if ( instr(s, 0, lang("ドラゴンの", " dragon's ")) != (-1) ) { + // if ( inv(INV_ITEM_ID, cnt2) != ITEM_ID_CORPSE & locvar_autopick_itemtype != FILTER_REMAINS ) { + // continue + // } + // if ( inv(INV_ITEM_SUB_NAME, cnt2) != 120 & inv(INV_ITEM_SUB_NAME, cnt2) != 121 & inv(INV_ITEM_SUB_NAME, cnt2) != 122 & inv(INV_ITEM_SUB_NAME, cnt2) != 123 & inv(INV_ITEM_SUB_NAME, cnt2) != 124 & inv(INV_ITEM_SUB_NAME, cnt2) != 125 ) { + // continue + // } + // sreplace s, s, lang("ドラゴンの", " dragon's "), " " + // p(1) = 1 + // } + if ( instr(s, 0, lang("空っぽの", " empty ")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_CONTAINER ) { + continue + } + if ( inv(INV_ITEM_PARAM1, cnt2) != 0 ) { + continue + } + sreplace s, s, lang("空っぽの", " empty "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("粗悪な", " bad ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_BAD ) { + continue + } + sreplace s, s, lang("粗悪な", " bad "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("良質な", " good ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_GOOD ) { + continue + } + sreplace s, s, lang("良質な", " good "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("高品質な", " great ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_GREAT ) { + continue + } + sreplace s, s, lang("高品質な", " great "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("奇跡の", " miracle ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_MIRACLE ) { + continue + } + sreplace s, s, lang("奇跡の", " miracle "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("神器の", " godly ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_GODLY ) { + continue + } + sreplace s, s, lang("神器の", " godly "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("特別な", " special ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_QUALITY, cnt2) != FIX_QUALITY_UNIQUE ) { + continue + } + sreplace s, s, lang("特別な", " special "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("貴重な", " precious ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( ibit(ITEM_BIT_PRECIOUS, cnt2) != TRUE ) { + continue + } + sreplace s, s, lang("貴重な", " precious "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("祝福された", " blessed ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_STATUS, cnt2) != ITEM_STATUS_BLESSED ) { + continue + } + sreplace s, s, lang("祝福された", " blessed "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("呪われた", " cursed ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_STATUS, cnt2) != ITEM_STATUS_CURSED ) { + continue + } + sreplace s, s, lang("呪われた", " cursed "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("堕落した", " doomed ")) != (-1) ) { + if ( inv(INV_ITEM_KNOWN, cnt2) < ITEM_KNOWN_QUALITY ) { + continue + } + if ( inv(INV_ITEM_STATUS, cnt2) != ITEM_STATUS_DOOMED ) { + continue + } + sreplace s, s, lang("堕落した", " doomed "), " " + p(1) = 1 + } + if ( instr(s, 0, lang("生きている", " alive ")) != (-1) ) { + if ( ibit(ITEM_BIT_ALIVE, cnt2) != TRUE ) { + continue + } + sreplace s, s, lang("生きている", " alive "), " " + p(1) = 1 + } + s = strtrim(s, 0, 32) + while instr(s, 0, " ") != (-1) != 0 + sreplace s, s, " ", " " + wend + s(1) = cnvitemname(inv(INV_ITEM_ID, cnt2)) + if ( instr(s(1), 0, s) != (-1) & inv(INV_ITEM_KNOWN, cnt2) != ITEM_KNOWN_NONE ) { + p = 1 + } + else { + if ( p(1) == 0 ) { ; At least one modifier must match to match by type. + continue + } + if ( instr(s, 0, lang("アイテム", "item")) != (-1) ) { + p = 1 + } + if ( instr(s, 0, lang("装備品", "equipment")) != (-1) ) { + if ( locvar_autopick_itemtype >= FILTER_ITEM_MIN ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("近接武器", "melee weapon")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_WEAPON ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("兜", "helm")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_HELM ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("盾", "shield")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_SHIELD ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("鎧", "armor")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ARMOR ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("靴", "boot")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_BOOTS ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("腰当", "belt")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_GIRDLE ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("マント", "cloak")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_CLOAK ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("グローブ", "glove")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_GLOVES ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("遠隔武器", "ranged weapon")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_RANGE ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("矢弾", "ammo")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_AMMO ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("指輪", "ring")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ACCESSORY_RING ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("首輪", "necklace")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ACCESSORY_AMULET ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("ポーション", "potion")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_POTION ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("巻物", "scroll")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_SCROLL ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("魔法書", "spellbook")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_SPELLBOOK ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("本", "book")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_BOOK ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("魔法の杖", "rod")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_ROD ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("食べ物", "food")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_FOOD & (inv(INV_ITEM_ID, cnt2) == ITEM_ID_BOTTLE_MILK & inv(INV_ITEM_PARAM2, cnt2) != 0) == 0 ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("道具", "tool")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ITEM_TOOL ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("家具", "furniture")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_FURNITURE ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("井戸", "well")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_FURNITURE_WELL ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("祭壇", "altar")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_FURNITURE_ALTAR ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("残骸", "remains")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_REMAINS ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("ジャンク", "junk")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_JUNK ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("金貨", "gold piece")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_GOLD ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("プラチナ硬貨", "platinum coin")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_PLATINUM ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("宝箱", "chest")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_CONTAINER ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("鉱石", "ore")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ORE ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("樹木", "tree")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_ENVIRONMENT ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("旅糧", "traveler's food")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_CARGO_FOOD ) { + continue + } + p = 1 + } + if ( instr(s, 0, lang("交易品", "cargo")) != (-1) ) { + if ( locvar_autopick_itemtype != FILTER_CARGO_TRADE ) { + continue + } + p = 1 + } + } + if ( p == 1 ) { ; Item name/type match? + if ( instr(buff, 0, "!") != (-1) ) { ; Autodestroy (!/!!) + if ( ibit(ITEM_BIT_PRECIOUS, cnt2) == FALSE | instr(buff, 0, "!!") != (-1) ) { + if ( locvar_autopick_prompt ) { ; Prompting (?) + if ( cnt3 == 0 ) { + txt lang(itemname(cnt2) + "を破壊する?", "Destroy " + itemname(cnt2) + "?") + promptl(0, 0) = stryes, "y", "0" + promptl(0, 1) = strno, "n", "1" + promptmax = 2 + val = promptx, prompty, 160, 1 + gosub *prompt_key + if ( rtval != 0 ) { + gosub *screen_draw + break + } + } + else { + txt lang(name(cnt3) + "に" + itemname(cnt2) + "を破壊してもらう?", "Let" + name(cnt3) + " destroy " + itemname(cnt2) + "?") + promptl(0, 0) = stryes, "y", "0" + promptl(0, 1) = strno, "n", "1" + promptmax = 2 + val = promptx, prompty, 160, 1 + gosub *prompt_key + if ( rtval != 0 ) { + gosub *screen_draw + break + } + } + } + if ( cfg_autodestroysound ) { + snd SOUNDLIST_CRUSH1 + } + inv(INV_ITEM_NUM, cnt2) = 0 + if ( synccheck(cnt3, -1) ) { + txt lang(name(cnt3) + "は" + itemname(cnt2) + "を破壊した。", itemname(cnt2) + " was destroyed. ") + } + cell_refresh x, y + map(x, y, MAP_ITEM_CHIPS_MEMORY) = map(x, y, MAP_ITEM_CHIPS) + } + break + } + if ( instr(buff, 0, "~") != (-1) ) { ; Ignore (~) + break + } + if ( locvar_autopick_prompt ) { ; Prompting (?) + if ( cnt3 == 0 ) { + txt lang(itemname(cnt2) + "を拾う?", "Pick up " + itemname(cnt2) + "?") + promptl(0, 0) = stryes, "y", "0" + promptl(0, 1) = strno, "n", "1" + promptmax = 2 + val = promptx, prompty, 160, 1 + gosub *prompt_key + if ( rtval != 0 ) { + gosub *screen_draw + break + } + } + else { + txt lang(name(cnt3) + "に" + itemname(cnt2) + "を拾ってもらう?", "Let " + name(cnt3) + " pick up " + itemname(cnt2) + "?") + promptl(0, 0) = stryes, "y", "0" + promptl(0, 1) = strno, "n", "1" + promptmax = 2 + val = promptx, prompty, 160, 1 + gosub *prompt_key + if ( rtval != 0 ) { + gosub *screen_draw + break + } + } + } + in = inv(INV_ITEM_NUM, cnt2) + ci = cnt2 + cc = cnt3 + locvar_is_autopick = TRUE + gosub *act_get + locvar_is_autopick = FALSE + notesel autopickbuff + if ( stat == 1 | stat == (-1) ) { ; Only if pickup succeeded + if ( instr(buff, 0, "%") != (-1) ) { ; Autosave (%) + autosave = 1 * (gdata(GDATA_AREA) != AREA_SHOW_HOUSE) + } + if ( instr(buff, 0, "=") != (-1) ) { ; Set no-drop (=) + txt lang(itemname(cnt2) + "を大事なものに指定した。", "You set " + itemname(cnt2) + " as no-drop.") + ibitmod ITEM_BIT_NO_DROP, cnt2, TRUE + } + locvar_autopick_charpos = instr(buff, 0, ":sound") + if ( locvar_autopick_charpos != (-1) ) { ; Play sound (:sound123) + snd int(strmid(buff, locvar_autopick_charpos + strlen(":sound"), strlen(buff))) + } + } + break + } + loop + loop + noteunsel + return diff --git a/2.05-custom-gx/init.hsp b/2.05-custom-gx/init.hsp index db4b8a1e..6fcabd0f 100644 --- a/2.05-custom-gx/init.hsp +++ b/2.05-custom-gx/init.hsp @@ -76,6 +76,7 @@ if instr(s,0,%1)!-1{ %c\ /********** RUIN0X11 CUSTOM - BEGINNING **********/ #include "custom_dmgpop.hsp" +#include "custom_autopick.hsp" /********** RUIN0X11 CUSTOM - ENDING **********/ diff --git a/2.05-custom-gx/main.hsp b/2.05-custom-gx/main.hsp index 54734804..36540316 100644 --- a/2.05-custom-gx/main.hsp +++ b/2.05-custom-gx/main.hsp @@ -2976,6 +2976,34 @@ if ( a ) { goto *game_debug } + getkey a, 8 ; Backspace + if ( a ) { + getkey a, 16 ; Shift + if ( a ) { + gosub *AutoPickReloadSettingsFile + goto *pc_turn + } + if ( key_ctrl ) { + AutoPickOpenSettingsFile AutoPickCurrentSettingsFileIndex + await 200 + gosub *screen_draw + goto *pc_turn + } + if ( key_alt ) { + snd SOUNDLIST_AMMO + if ( cfg_autopick ) { + cfg_autopick = FALSE + txt lang("自動拾いは無効になっている。", "Autopickup is now disabled.") + } + else { + cfg_autopick = TRUE + txt lang("自動拾いは有効になっている。", "Autopickup is now enabled.") + } + await 200 + gosub *screen_draw + goto *pc_turn + } + } if ( key == "" ) { goto *pc_turn } diff --git a/2.05-custom-gx/module.hsp b/2.05-custom-gx/module.hsp index 09e024de..2120fb4c 100644 --- a/2.05-custom-gx/module.hsp +++ b/2.05-custom-gx/module.hsp @@ -5718,3 +5718,27 @@ } } +#deffunc sreplace var sreplace_prm0, str sreplace_prm1, str sreplace_prm2, str sreplace_prm3 + sdim srep_array, 512, 1 + srep_str = sreplace_prm1 + split srep_str, sreplace_prm2, srep_array + if ( length(srep_array) >= 2 ) { + srep_str = srep_array(0) + repeat length(srep_array) - 1, 1 + srep_str = srep_str + sreplace_prm3 + srep_array(cnt) + loop + sreplace_prm0 = srep_str + } + return length(srep_array) - 1 + +#deffunc delstr var delstr_prm0, str delstr_prm1 + repeat + if ( instr(delstr_prm0, 0, delstr_prm1) == (-1) ) { + break + } + else { + memcpy delstr_prm0, delstr_prm0, strlen(delstr_prm0) - (instr(delstr_prm0, 0, delstr_prm1) + strlen(delstr_prm1)), instr(delstr_prm0, 0, delstr_prm1), instr(delstr_prm0, 0, delstr_prm1) + strlen(delstr_prm1) + memset delstr_prm0, 0, strlen(delstr_prm1), strlen(delstr_prm0) - strlen(delstr_prm1) + } + loop + return diff --git a/2.05-custom-gx/screen.hsp b/2.05-custom-gx/screen.hsp index 4c19a40d..dd4b651a 100644 --- a/2.05-custom-gx/screen.hsp +++ b/2.05-custom-gx/screen.hsp @@ -921,6 +921,16 @@ mes _burden(cdata(CDATA_BURDEN, CHARA_PLAYER)) sy -= 20 } + if ( cfg_autopick ) { + if ( adata(ADATA_TYPE, gdata(GDATA_AREA)) != MAP_TYPE_HOME | adata(ADATA_TYPE, gdata(GDATA_AREA)) == AREA_RANCH | adata(ADATA_TYPE, gdata(GDATA_AREA)) == AREA_SHELTER ) { + color 0, 0, 0 + pos sx, sy + gcopy 3, 0, 416, 65 + en * 15, 15 + pos sx + 6, sy + 1 + mes lang("自動拾い", "Autopickup") + sy -= 20 + } + } color 0 if ( navi == (-1) ) { navi = 0 diff --git a/2.05-custom-gx/system.hsp b/2.05-custom-gx/system.hsp index 827c1e25..cf790c0f 100644 --- a/2.05-custom-gx/system.hsp +++ b/2.05-custom-gx/system.hsp @@ -2768,6 +2768,7 @@ if ( strsize != (-1) ) { delete folder + "filelist.txt" } + AutoPickLoadSettingsFile AutoPickCurrentSettingsFileIndex fmode = 7 gosub *game_ctrlFile gosub *fixSave diff --git a/CHANGELOG.md b/CHANGELOG.md index 391d9865..50e5e125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ - Added a tweak to revert changes to the experience formula after Elona+ 2.13. + Addresses "increased experience multipliers when defeating enemies above the player character's (PC) level". + Toggling this also reverts the change to taxation coming into effect after New Year's. +- Ported omake's autopickup feature. + + Enable this feature in the `EX Setting 1` subsection of the settings menu. + + Press Shift+Backspace while in-game to create or reload the current autopickup settings file. + + Press Ctrl+Backspace to open the currently loaded autopickup settings file in your text editor. + + Press Alt+Backspace to quickly toggle autopickup on and off. + + A detailed tutorial is included in the autogenerated settings file. ## Fixed - Fixed the incorrect sprite being used for the laser bazooka attack animation. diff --git a/dist/2.05-custom-gx/data/autopick.txt b/dist/2.05-custom-gx/data/autopick.txt new file mode 100644 index 00000000..eb26794f --- /dev/null +++ b/dist/2.05-custom-gx/data/autopick.txt @@ -0,0 +1,168 @@ +### Elona+ Custom-GX Autopickup Settings ### + +# To use this, enable the autopickup feature in EX Setting 1 from the settings menu. +# This file should be saved as "autopick.txt" in your character's save folder. +# Press [Shift+Backspace] while in-game to reload this file. +# Press [Ctrl+Backspace] to open the currently loaded autopickup settings file in your text editor. +# Press [Alt+Backspace] to quickly toggle autopickup on/off. +# Hold [Ctrl] while moving to temporarily disable autopickup. +# +# Syntax: +# '#' denotes a comment. +# '~' before an entry means to not pick it up and ignore any following matchers. +# '!' before an entry means to destroy it. +# '!!' before an entry means to destroy it, even if it's precious. +# '?' after an entry means to prompt for picking/destroying it first. +# '%' after an entry means to autosave when it's picked up. +# '=' after an entry means to set the item as no-drop when it's picked up. +# ':sound123' after an entry means to play the sound with ID 123 when it's picked up. +# +# You can store up to 10 sets of autopickup rules in each save folder, +# named autopick.txt, autopick_1.txt, autopick_2.txt, and so on. +# +# NOTE: Autopickup will not trigger inside player-owned locations (except ranches and shelters). +# +# See the wiki for more information: https://elona.fandom.com/wiki/Autopickup +# (Note however that there are some differences from omake's syntax.) + +### Example usage ### + +# Ignore cursed items. +# If a matcher higher up in the file matches, the rest of the matchers will be prevented from running. +~cursed item +~doomed item + +# Pick up precious items, then autosave and set as no-drop. +precious item%= + +# Pick up gold, platinum, and small medals. +gold piece +platinum coin +small medal + +# Pick up bottles of water, but prompt the player first. +bottle of water? + +# Destroy worthless fake gold bars. +# Item name matchers will only work if the item's name has been identified. +!worthless fake gold bar + +# Destroy corpses, but prompt the player first. +!corpse? + +# Multiple matchers can be chained together. +# Quality and curse state matchers will only work if the item's quality has been identified. +blessed fully identified potion + +# Play a sound if a piece of ore is picked up. +all ore:sound24 + +### All supported matchers ### + +# all item +# unknown item +# name identified item +# quality identified item +# fully identified item +# worthless item +# rotten item +# empty item +# bad item +# good item +# great item +# miracle item +# godly item +# special item +# precious item +# blessed item +# cursed item +# doomed item +# alive item + +# all equipment +# all melee weapon +# all helm +# all shield +# all armor +# all boot +# all belt +# all cloak +# all glove +# all ranged weapon +# all ammo +# all ring +# all necklace +# all potion +# all scroll +# all spellbook +# all book +# all rod +# all food +# all tool +# all furniture +# all well +# all altar +# all remain +# all junk +# all gold piece +# all platinum coin +# all chest +# all ore +# all tree +# all traveler's food +# all cargo + +### 日本語 ### + +# すべてのアイテム +# 名称不明のアイテム +# 鑑定段階 1 のアイテム +# 鑑定段階 2 のアイテム +# 鑑定段階 3 のアイテム +# 無価値のアイテム +# 腐ったアイテム +# 空っぽのアイテム +# 粗悪なアイテム +# 良質なアイテム +# 高品質なアイテム +# 奇跡のアイテム +# 神器のアイテム +# 特別なアイテム +# 貴重なアイテム +# 祝福されたアイテム +# 呪われたアイテム +# 堕落したアイテム +# 生きているアイテム + +# すべての装備品 +# すべての近接武器 +# すべての兜 +# すべての盾 +# すべての鎧 +# すべての靴 +# すべての腰当 +# すべてのマント +# すべてのグローブ +# すべての遠隔武器 +# すべての矢弾 +# すべての指輪 +# すべての首輪 +# すべてのポーション +# すべての巻物 +# すべての魔法書 +# すべての本 +# すべての魔法の杖 +# すべての食べ物 +# すべての道具 +# すべての家具 +# すべての井戸 +# すべての祭壇 +# すべての残骸 +# すべてのジャンク +# すべての金貨 +# すべてのプラチナ硬貨 +# すべての宝箱 +# すべての鉱石 +# すべての樹木 +# すべての旅糧 +# すべての交易品