Improved support for Linnea (#3133)

This commit is contained in:
Jamis
2026-04-17 03:03:41 +10:00
committed by GitHub
parent 45786c05e7
commit 904c13e146
7 changed files with 319 additions and 138 deletions

View File

@@ -30,6 +30,10 @@
## ChangeLog
### 0.31
- 优化了莉奈娅挖矿的逻辑
### 0.30
- 修复若干bug

View File

@@ -1,4 +1,4 @@
{
{
"info": {
"authors": [
{
@@ -9,7 +9,7 @@
"bgi_version": "0.45.0",
"description": "",
"enable_monster_loot_split": false,
"last_modified_time": 1776064533678,
"last_modified_time": 1776314892488,
"map_match_method": "",
"map_name": "TheChasm",
"name": "01-水晶块-层岩巨渊·地下矿区-地下水泽-南-6个",
@@ -141,8 +141,8 @@
"id": 14,
"move_mode": "walk",
"type": "target",
"x": 592.4976806640625,
"y": 719.0479736328125
"x": 591.9713134765625,
"y": 719.3077392578125
},
{
"action": "mining",

View File

@@ -1,13 +1,25 @@
{
"01-水晶块-层岩巨渊·地下矿区-地下水泽-南-6个.json": {
"file": "01-水晶块-层岩巨渊·地下矿区-地下水泽-南-6个.json"
},
"06-水晶块-层岩巨渊·地下矿区-巨渊主矿区-东-3个.json": {
"mining_dist_threshold": 6
},
"10-水晶块-层岩巨渊·地下矿区-临时主矿道-南-2个.json": {
"preserve_mining_points": [
0
]
}
}
{
"01-水晶块-层岩巨渊·地下矿区-地下水泽-南-6个.json": {
"file": "01-水晶块-层岩巨渊·地下矿区-地下水泽-南-6个.json"
},
"06-水晶块-层岩巨渊·地下矿区-巨渊主矿区-东-3个.json": {
"mining_dist_threshold": 6
},
"10-水晶块-层岩巨渊·地下矿区-临时主矿道-南-2个.json": {
"fallback_mining_points": [
1
]
},
"12-水晶块-层岩巨渊·地下矿区-临时主矿道-西-2个.json": {
"fallback_mining_points": [
0,
1
]
},
"B15-萃凝晶-纳塔-祖遗庙宇3火神赶路-5个.json": {
"pinned_mining_points": [
0,
1
]
}
}

View File

@@ -1,4 +1,4 @@
{
{
"info": {
"authors": [
{
@@ -6,10 +6,10 @@
"name": "火山"
}
],
"bgi_version": "0.59.0",
"bgi_version": "0.45.0",
"description": "",
"enable_monster_loot_split": false,
"last_modified_time": 1776075119082,
"last_modified_time": 1776321960265,
"map_match_method": "",
"map_name": "TheChasm",
"name": "04-水晶块-层岩巨渊·地下矿区-巨蛇岩洞-9个",
@@ -32,6 +32,7 @@
"action": "stop_flying",
"action_params": "",
"id": 2,
"locked": false,
"move_mode": "fly",
"type": "path",
"x": 962.189,
@@ -41,6 +42,7 @@
"action": "",
"action_params": "",
"id": 3,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 986.1289,
@@ -50,6 +52,7 @@
"action": "",
"action_params": "",
"id": 4,
"locked": false,
"move_mode": "jump",
"type": "path",
"x": 990.4896,
@@ -59,6 +62,7 @@
"action": "",
"action_params": "",
"id": 5,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 1025.8376,
@@ -92,14 +96,23 @@
"move_mode": "walk",
"type": "target",
"x": 1047.28,
"y": 702.0
"y": 702
},
{
"action": "",
"action_params": "",
"id": 9,
"move_mode": "jump",
"type": "path",
"x": 1067.448974609375,
"y": 700.509521484375
},
{
"action": "mining",
"action_params": "",
"id": 9,
"id": 10,
"locked": false,
"move_mode": "jump",
"move_mode": "walk",
"type": "target",
"x": 1056.79,
"y": 699.55
@@ -107,7 +120,7 @@
{
"action": "mining",
"action_params": "",
"id": 10,
"id": 11,
"locked": false,
"move_mode": "walk",
"type": "target",
@@ -117,7 +130,7 @@
{
"action": "",
"action_params": "",
"id": 11,
"id": 12,
"locked": false,
"move_mode": "walk",
"type": "teleport",
@@ -127,7 +140,7 @@
{
"action": "",
"action_params": "",
"id": 12,
"id": 13,
"locked": false,
"move_mode": "fly",
"type": "path",
@@ -137,7 +150,7 @@
{
"action": "stop_flying",
"action_params": "",
"id": 13,
"id": 14,
"locked": false,
"move_mode": "fly",
"type": "path",
@@ -147,7 +160,7 @@
{
"action": "combat_script",
"action_params": "s(0.2),dash,wait(0.2),dash",
"id": 14,
"id": 15,
"locked": false,
"move_mode": "walk",
"type": "path",
@@ -157,7 +170,7 @@
{
"action": "",
"action_params": "",
"id": 15,
"id": 16,
"locked": false,
"move_mode": "dash",
"type": "path",
@@ -167,7 +180,7 @@
{
"action": "mining",
"action_params": "",
"id": 16,
"id": 17,
"locked": false,
"move_mode": "dash",
"type": "target",
@@ -177,7 +190,7 @@
{
"action": "combat_script",
"action_params": "s(0.2),dash",
"id": 17,
"id": 18,
"locked": false,
"move_mode": "dash",
"type": "path",
@@ -187,7 +200,7 @@
{
"action": "",
"action_params": "",
"id": 18,
"id": 19,
"locked": false,
"move_mode": "dash",
"type": "path",
@@ -197,7 +210,7 @@
{
"action": "combat_script",
"action_params": "s(0.2),dash,wait(0.2),dash",
"id": 19,
"id": 20,
"locked": false,
"move_mode": "walk",
"type": "path",
@@ -207,7 +220,7 @@
{
"action": "",
"action_params": "",
"id": 20,
"id": 21,
"locked": false,
"move_mode": "dash",
"type": "path",
@@ -217,7 +230,7 @@
{
"action": "mining",
"action_params": "",
"id": 21,
"id": 22,
"locked": false,
"move_mode": "walk",
"type": "target",
@@ -227,7 +240,7 @@
{
"action": "mining",
"action_params": "",
"id": 22,
"id": 23,
"locked": false,
"move_mode": "walk",
"type": "target",
@@ -237,7 +250,7 @@
{
"action": "mining",
"action_params": "",
"id": 23,
"id": 24,
"locked": false,
"move_mode": "walk",
"type": "target",
@@ -247,7 +260,7 @@
{
"action": "mining",
"action_params": "",
"id": 24,
"id": 25,
"locked": false,
"move_mode": "walk",
"type": "target",
@@ -255,4 +268,4 @@
"y": 788.16
}
]
}
}

View File

@@ -1,15 +1,15 @@
{
{
"info": {
"authors": [
{
"name": "芝士贝果",
"links": "https://github.com/cheese-bagel"
"links": "https://github.com/cheese-bagel",
"name": "芝士贝果"
}
],
"bgi_version": "0.50.0",
"bgi_version": "0.45.0",
"description": "",
"enable_monster_loot_split": false,
"last_modified_time": 1760098491963,
"last_modified_time": 1776319871626,
"map_match_method": "",
"map_name": "Teyvat",
"name": "07-蓝珀湖下方-14个",
@@ -22,6 +22,7 @@
"action": "",
"action_params": "",
"id": 1,
"locked": false,
"move_mode": "walk",
"type": "teleport",
"x": 9351.5967,
@@ -31,6 +32,7 @@
"action": "",
"action_params": "",
"id": 2,
"locked": false,
"move_mode": "run",
"type": "path",
"x": 9271.4141,
@@ -40,6 +42,7 @@
"action": "",
"action_params": "",
"id": 3,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9261.917,
@@ -49,15 +52,27 @@
"action": "stop_flying",
"action_params": "2500",
"id": 4,
"locked": false,
"move_mode": "fly",
"type": "path",
"x": 9212.0176,
"y": 2135.6899
},
{
"action": "combat_script",
"action_params": "attack(2.0)",
"id": 5,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9212.0176,
"y": 2135.6899
},
{
"action": "mining",
"action_params": "",
"id": 5,
"id": 6,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9215.1055,
@@ -66,7 +81,8 @@
{
"action": "",
"action_params": "",
"id": 6,
"id": 7,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9211.4082,
@@ -75,7 +91,8 @@
{
"action": "mining",
"action_params": "",
"id": 7,
"id": 8,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9213.1035,
@@ -84,7 +101,8 @@
{
"action": "",
"action_params": "",
"id": 8,
"id": 9,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9189.1777,
@@ -93,7 +111,8 @@
{
"action": "",
"action_params": "",
"id": 9,
"id": 10,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9177.8652,
@@ -102,7 +121,8 @@
{
"action": "",
"action_params": "",
"id": 10,
"id": 11,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9163.043,
@@ -111,7 +131,8 @@
{
"action": "",
"action_params": "",
"id": 11,
"id": 12,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9141.9199,
@@ -120,7 +141,27 @@
{
"action": "",
"action_params": "",
"id": 12,
"id": 13,
"move_mode": "dash",
"type": "path",
"x": 9110.22265625,
"y": 2084.654296875
},
{
"action": "",
"action_params": "",
"id": 14,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9141.9199,
"y": 2082.4644
},
{
"action": "",
"action_params": "",
"id": 15,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9176.3672,
@@ -129,7 +170,8 @@
{
"action": "",
"action_params": "",
"id": 13,
"id": 16,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9187.4395,
@@ -138,7 +180,8 @@
{
"action": "mining",
"action_params": "",
"id": 14,
"id": 17,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9189.9277,
@@ -147,7 +190,8 @@
{
"action": "",
"action_params": "",
"id": 15,
"id": 18,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9187.1777,
@@ -156,7 +200,8 @@
{
"action": "mining",
"action_params": "",
"id": 16,
"id": 19,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9185.7773,
@@ -165,7 +210,8 @@
{
"action": "mining",
"action_params": "",
"id": 17,
"id": 20,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9186.1953,
@@ -174,7 +220,8 @@
{
"action": "",
"action_params": "",
"id": 18,
"id": 21,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9186.4795,
@@ -183,7 +230,8 @@
{
"action": "mining",
"action_params": "",
"id": 19,
"id": 22,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9184.1777,
@@ -192,7 +240,8 @@
{
"action": "",
"action_params": "",
"id": 20,
"id": 23,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9185.3164,
@@ -201,7 +250,8 @@
{
"action": "",
"action_params": "",
"id": 21,
"id": 24,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9155.3242,
@@ -210,7 +260,8 @@
{
"action": "mining",
"action_params": "",
"id": 22,
"id": 25,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9157.3359,
@@ -219,7 +270,8 @@
{
"action": "",
"action_params": "",
"id": 23,
"id": 26,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9153.6504,
@@ -228,7 +280,8 @@
{
"action": "mining",
"action_params": "",
"id": 24,
"id": 27,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9151.6123,
@@ -237,7 +290,8 @@
{
"action": "",
"action_params": "",
"id": 25,
"id": 28,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9153.6494,
@@ -246,7 +300,8 @@
{
"action": "mining",
"action_params": "",
"id": 26,
"id": 29,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9153.4336,
@@ -255,7 +310,8 @@
{
"action": "",
"action_params": "",
"id": 27,
"id": 30,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9156.7051,
@@ -264,7 +320,8 @@
{
"action": "mining",
"action_params": "",
"id": 28,
"id": 31,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9153.1738,
@@ -273,7 +330,8 @@
{
"action": "",
"action_params": "",
"id": 29,
"id": 32,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9140.376,
@@ -282,7 +340,8 @@
{
"action": "",
"action_params": "",
"id": 30,
"id": 33,
"locked": false,
"move_mode": "run",
"type": "path",
"x": 9083.2178,
@@ -291,7 +350,8 @@
{
"action": "",
"action_params": "",
"id": 31,
"id": 34,
"locked": false,
"move_mode": "dash",
"type": "path",
"x": 9071.5645,
@@ -300,7 +360,8 @@
{
"action": "mining",
"action_params": "",
"id": 32,
"id": 35,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9078.9971,
@@ -309,7 +370,8 @@
{
"action": "",
"action_params": "",
"id": 33,
"id": 36,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9072.5781,
@@ -318,7 +380,8 @@
{
"action": "mining",
"action_params": "",
"id": 34,
"id": 37,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9071.709,
@@ -327,7 +390,8 @@
{
"action": "",
"action_params": "",
"id": 35,
"id": 38,
"locked": false,
"move_mode": "walk",
"type": "path",
"x": 9070.8145,
@@ -336,11 +400,12 @@
{
"action": "mining",
"action_params": "",
"id": 36,
"id": 39,
"locked": false,
"move_mode": "walk",
"type": "target",
"x": 9069.7188,
"y": 2100.7827
}
]
}
}

View File

@@ -369,6 +369,7 @@ async function get_inventory() {
let last_script_end_pos = [null, null];
let last_script_normal_completion = true;
let mining_character = null;
let fallback_claymore_character = null;
function modify_script_for_claymores(json_content) {
const json_obj = JSON.parse(json_content);
@@ -396,9 +397,16 @@ function modify_script_for_claymores(json_content) {
async function modify_script_for_linnea(json_content, override_config) {
const linnea_mining_action = `${linnea_chs_name} moveby(0,2500),charge(0.6),click(middle)`;
const claymore_mining_actions = {
"诺艾尔": "attack(2.0)",
"迪希雅": "attack(0.6),mousedown,wait(2.1),mouseup,j",
"玛薇卡": "attack(0.20),j,wait(0.5),attack(0.6)",
};
const fallback_mining_action = fallback_claymore_character ? (fallback_claymore_character + " " + claymore_mining_actions[fallback_claymore_character]) : null;
let mining_dist_threshold = 7.5;
const additional_sleep_time_before_teleport = 1.2;
let preserve_mining_points = null;
let pinned_mining_points = null;
let fallback_mining_points = null;
if (override_config) {
if (override_config.hasOwnProperty("file")) {
@@ -407,87 +415,156 @@ async function modify_script_for_linnea(json_content, override_config) {
if (override_config.hasOwnProperty("mining_dist_threshold")) {
mining_dist_threshold = override_config["mining_dist_threshold"];
}
if (override_config.hasOwnProperty("preserve_mining_points")) {
preserve_mining_points = override_config["preserve_mining_points"];
if (override_config.hasOwnProperty("pinned_mining_points")) {
pinned_mining_points = override_config["pinned_mining_points"];
}
if (override_config.hasOwnProperty("fallback_mining_points") && fallback_mining_action !== null) {
fallback_mining_points = override_config["fallback_mining_points"];
}
}
const json_obj = JSON.parse(json_content);
// Skip some mining points
if (preserve_mining_points === null) {
let last_linnea_mining_pos = null;
const path_segments = [];
{
let segment = [];
let mining_counter = 0;
for (const i of json_obj.positions) {
if (i.type === "teleport") {
if (segment.length !== 0) {
path_segments.push(segment);
segment = [];
}
}
if (i.action === "mining") {
const is_pinned = pinned_mining_points !== null && pinned_mining_points.includes(mining_counter);
const is_fallback = fallback_mining_action !== null && fallback_mining_points !== null && fallback_mining_points.includes(mining_counter);
i.internal = {
"mining_point_id": mining_counter,
"is_pinned": is_pinned || is_fallback,
"is_fallback": is_fallback,
};
mining_counter += 1;
}
segment.push(JSON.parse(JSON.stringify(i)));
}
if (segment.length !== 0) {
path_segments.push(segment);
segment = [];
}
}
const process_segment = (segment) => {
// Drop mining points around the pinned ones
const pinned_mining_pos = [];
for (const i of segment) {
if (i.action === "mining" && i.internal.is_pinned) {
pinned_mining_pos.push({
x: i.x,
y: i.y,
});
}
}
for (const i of segment) {
if (i.action === "mining" && !i.internal.is_pinned) {
for (const j of pinned_mining_pos) {
const dist = Math.hypot(i.x - j.x, i.y - j.y);
if (dist < mining_dist_threshold) {
i.type = "path";
i.action = "";
i.action_params = "";
break;
}
}
}
}
// Skip some mining points
let last_linnea_mining_pos = null;
for (const i of segment) {
if (i.action !== "mining") {
continue;
}
const dist_from_last_mining_pos = last_linnea_mining_pos === null ? 9999 :
Math.hypot(i.x - last_linnea_mining_pos.x, i.y - last_linnea_mining_pos.y);
if (dist_from_last_mining_pos < mining_dist_threshold) {
if (i.internal.is_pinned) {
if (!i.internal.is_fallback) {
last_linnea_mining_pos = {
x: i.x,
y: i.y
};
}
continue;
}
const dist = last_linnea_mining_pos === null ? 9999 : Math.hypot(i.x - last_linnea_mining_pos.x, i.y - last_linnea_mining_pos.y);
if (dist < mining_dist_threshold) {
i.type = "path";
i.action = "";
i.action_params = "";
} else {
last_linnea_mining_pos = {
x: i.x,
y: i.y
y: i.y,
};
}
}
} else {
let counter = 0;
for (const i of json_obj.positions) {
if (i.action === "mining") {
if (!preserve_mining_points.includes(counter)) {
i.type = "path";
i.action = "";
i.action_params = "";
// Skip useless waypoints
for (let i = 0; i < segment.length; ++i) {
const wi = segment[i];
if (wi.action === "mining" && !wi.internal.is_fallback) {
let j = i + 1;
for (; j < segment.length; ++j) {
const wj = segment[j];
if (wj.type === "path" && wj.action === "" && Math.hypot(wj.x - wi.x, wj.y - wi.y) <= 10 ||
wj.type === "target" && wj.action === "" && Math.hypot(wj.x - wi.x, wj.y - wi.y) <= 10 ||
wj.action === "combat_script" && wj.action_params.match(/^wait\([0-9.]+\)$/g) ||
wj.action === "pick_around") {} else {
break;
}
}
for (let k = i + 1; k < j; ++k) {
if (!segment[k].internal) {
segment[k].internal = {};
}
segment[k].internal.useless = true;
}
counter += 1;
}
}
}
// Drop useless waypoints
const new_positions = [];
const stashed_positions = [];
let has_mining_since_last_teleport = false;
for (const i of json_obj.positions) {
if (i.type === "teleport") {
if (!has_mining_since_last_teleport) {
new_positions.push(...stashed_positions);
}
stashed_positions.length = 0;
stashed_positions.push(i);
has_mining_since_last_teleport = false;
} else if (i.action === "mining") {
new_positions.push(...stashed_positions);
new_positions.push(i);
stashed_positions.length = 0;
has_mining_since_last_teleport = true;
} else {
stashed_positions.push(i);
}
}
// Patch mining actions
for (const [id, i] of new_positions.entries()) {
if (i.action === "mining") {
i.action = "combat_script";
i.action_params = linnea_mining_action;
if (additional_sleep_time_before_teleport > 0 && (id === new_positions.length - 1 || new_positions[id + 1].type === "teleport")) {
i.action_params += `;wait(${additional_sleep_time_before_teleport})`;
for (let i = segment.length - 1; i >= 0; --i) {
if (segment[i].internal?.useless) {
segment.splice(i, 1);
}
}
}
// Correct indices
for (const [id, i] of new_positions.entries()) {
i.id = id + 1;
}
json_obj.positions = new_positions;
// patch mining actions
for (const [id, i] of segment.entries()) {
if (i.action === "mining") {
if (i.internal.is_fallback) {
i.action = "combat_script";
i.action_params = fallback_mining_action;
} else {
i.action = "combat_script";
i.action_params = linnea_mining_action;
if (additional_sleep_time_before_teleport > 0.0 && id === segment.length - 1) {
i.action_params += `;wait(${additional_sleep_time_before_teleport})`;
}
}
}
}
log.debug("Patched mining action");
};
const patched_positions = [];
for (const segment of path_segments) {
process_segment(segment);
for (const i of segment) {
const i_copy = JSON.parse(JSON.stringify(i));
delete i_copy.internal;
i_copy.id = patched_positions.length + 1;
patched_positions.push(i_copy);
}
}
json_obj.positions = patched_positions;
log.debug("Patched mining action for Linnea");
json_content = JSON.stringify(json_obj);
return json_content;
}
@@ -598,13 +675,15 @@ async function main() {
log.debug("Exclude regions: {a}, exclude types: {b}", settings.exclude_regions, settings.exclude_ore_types);
log.debug("Exclude tags: {a}", get_exclude_tags());
log.debug("Underwater only: {a}", underwater_only());
const preapproved_mining_characters = [linnea_chs_name, "诺艾尔"];
const characters = Array.from(getAvatars());
if (characters.includes(linnea_chs_name) && (use_global_mining_action || (settings.custom_mining_action || "").includes(linnea_chs_name))) {
log.error("{l}挖矿请{no}填写自定义挖矿动作", linnea_chs_name, "勿");
return;
}
if (!underwater_only() && !settings.custom_mining_action) {
const preapproved_mining_characters = [linnea_chs_name, "诺艾尔"];
const preapproved_fallback_claymore_characters = ["诺艾尔", "玛薇卡", "迪希雅"];
for (const i of preapproved_mining_characters) {
if (characters.includes(i)) {
mining_character = i;
@@ -615,6 +694,14 @@ async function main() {
log.error("地面挖矿请带{c}", preapproved_mining_characters.join("或"));
return;
}
if (mining_character === linnea_chs_name) {
for (const i of preapproved_fallback_claymore_characters) {
if (characters.includes(i)) {
fallback_claymore_character = i;
break;
}
}
}
}
const get_current_cst_hour = () => (Date.now() / 1000 + 8 * 3600) % 86400 / 3600;

View File

@@ -2,8 +2,8 @@
"bgi_version": "0.60.0",
"manifest_version": 1,
"name": "矿产资源批发",
"version": "0.30",
"description": "自动记录矿石刷新时间,优先选择效率最高的路线,支持按区域、种类、数量自动规划挖矿路线",
"version": "0.31",
"description": "自动记录矿石刷新时间,优先选择效率最高的路线,支持按区域、种类、数量自动规划挖矿路线,支持莉奈娅",
"authors": [
{
"name": "芝士贝果",