1.4
This commit is contained in:
parent
ad2cc76429
commit
7455d630fc
82 changed files with 2179 additions and 900 deletions
|
|
@ -54,6 +54,14 @@ function foodInteractionDistance(tarinai, item) {
|
|||
}
|
||||
|
||||
function foodInteractionReach(tarinai, item, role = "food") {
|
||||
if (item?.type === "slave_chain" || item?.type === "golden_crown") {
|
||||
// \u738B\u51A0\u30FB\u9396\u306F\u7DDA\u753B/\u6A2A\u9577\u306E\u5916\u89B3\u306A\u306E\u3067\u3001\u901A\u5E38\u306E\u98DF\u7269\u5224\u5B9A\u3088\u308A\u898B\u305F\u76EE\u57FA\u6E96\u3067\u5E83\u304F\u53D6\u308B\u3002
|
||||
// \u4E2D\u5FC3\u70B9\u304C\u5C11\u3057\u96E2\u308C\u3066\u3044\u3066\u3082\u3001\u305F\u308A\u306A\u3044\u306E\u4F53\u8868\u3068\u30A2\u30A4\u30C6\u30E0\u5916\u89B3\u304C\u89E6\u308C\u305F\u6642\u70B9\u3067\u53D6\u5F97\u3067\u304D\u308B\u3002
|
||||
const bodyR = Math.max(16, Number(tarinai?.radius || 20) || 20);
|
||||
const itemR = Math.max(item.type === "slave_chain" ? 15 : 16, Number(item?.r || 0) || 0);
|
||||
const visualPad = item.type === "slave_chain" ? 14 : 12;
|
||||
return Math.max(46, bodyR * 0.94 + itemR * 1.28 + visualPad);
|
||||
}
|
||||
if (item?.type === "duplicator") return Math.max(30, (tarinai?.radius || 20) * 0.72 + (item?.r || 34) * 0.36);
|
||||
if (role === "drink") return Math.max(16, (tarinai?.radius || 20) * 0.58 + (item?.r || 12) * 0.40);
|
||||
return Math.max(13, (tarinai?.radius || 20) * 0.50 + (item?.r || 12) * 0.28);
|
||||
|
|
@ -98,42 +106,36 @@ function foodPriorityScore(tarinai, item, distance = 0) {
|
|||
|
||||
function hasBetterFoodThanZunchiNearby(tarinai, world, maxDist = 180) {
|
||||
if (!tarinai || !world) return false;
|
||||
for (const it of world.nearbyItems?.(tarinai.x, tarinai.y, maxDist) || world.items || []) {
|
||||
if (!it || it.dead || it.type === "zunchi") continue;
|
||||
const source = world.nearbyItems?.(tarinai.x, tarinai.y, maxDist, true) || world.items || [];
|
||||
for (const it of source) {
|
||||
if (!it || it.dead) continue;
|
||||
const type = effectiveFoodTypeForItem(it);
|
||||
if (!type || type === "zunchi") continue;
|
||||
if (!roleMatches(it, "food")) continue;
|
||||
if (tarinai.shouldAvoidTarget?.(it)) continue;
|
||||
if (tarinaiTargetBlockedByObstacle(world, tarinai, it, "food")) continue;
|
||||
const type = effectiveFoodTypeForItem(it);
|
||||
if (!type) continue;
|
||||
if (["sweet", "food", "grass", "water", "zunda_juice", "ant_corpse"].includes(type) || (isServingFoodType(type))) {
|
||||
if (it.type === "grass" && (it.amount || 0) <= 0) continue;
|
||||
if (typeof tarinai.foodItemHasServingLeft === "function" && ["sweet", "food", "zunda_juice"].includes(type) && !tarinai.foodItemHasServingLeft(it)) continue;
|
||||
return true;
|
||||
if (it.type === "grass" && (it.amount || 0) <= 0) continue;
|
||||
if (it.type === "duplicator" || isServingFoodType(type) || ["sweet", "food", "zunda_juice"].includes(type)) {
|
||||
if (typeof tarinai.foodItemHasServingLeft === "function" && !tarinai.foodItemHasServingLeft(it)) continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function zunchiEatingBlocked(tarinai, item, world) {
|
||||
if (!tarinai || !item || item.type !== "zunchi") return false;
|
||||
const itemAge = Number(item.age || 0) || 0;
|
||||
const worldAge = Number.isFinite(item.producedAt) ? Math.max(0, (world?.time || 0) - item.producedAt) : itemAge;
|
||||
const protectedAge = Math.max(itemAge, worldAge);
|
||||
if ((Number(item.amount || 0) || 0) <= 0) return true;
|
||||
const protectedUntil = Number(item.eatProtectedUntil || 0) || 0;
|
||||
if (protectedUntil > 0 && (world?.time || 0) < protectedUntil) return true;
|
||||
const foodNeed = Number(tarinai.needRaw?.food ?? tarinai.needs?.food ?? 0) || 0;
|
||||
const hunger = Number(tarinai.hunger || 0) || 0;
|
||||
// \u6392\u6cc4\u76f4\u5f8c\u306e\u305a\u3093\u3061\u306f\u89b3\u5bdf\u30fb\u63a5\u89e6\u5bfe\u8c61\u3067\u3042\u308a\u3001\u901a\u5e38\u98df\u3068\u3057\u3066\u5373\u6d88\u8cbb\u3055\u305b\u306a\u3044\u3002
|
||||
// \u305a\u3093\u3061\u3069\u308c\u3044\u3082\u6570\u79d2\u306f\u5f85\u3064\u3002\u901a\u5e38\u500b\u4f53\u306f\u6975\u9650\u98e2\u9913\u3067\u3082\u6700\u4f4e90\u79d2\u306f\u98df\u3079\u306a\u3044\u3002
|
||||
const emergency = hunger >= 104 || foodNeed >= 94;
|
||||
const grace = tarinai.isZunchiSlave ? (emergency ? 4 : 18) : (emergency ? 20 : 90);
|
||||
if (protectedAge < grace) return true;
|
||||
if (!emergency && !tarinai.isZunchiSlave && item.stage === "fresh" && protectedAge < 150 && foodNeed < 94 && hunger < 104) return true;
|
||||
// \u305A\u3093\u3061\u306F\u98DF\u7269\u306E\u6700\u4E0B\u4F4D\u5019\u88DC\u3002\u307B\u304B\u306B\u98DF\u3079\u7269\u304C\u3042\u308B\u9593\u3060\u3051\u4FDD\u8B77\u3057\u3001
|
||||
// \u307B\u304B\u306B\u98DF\u3079\u7269\u304C\u7121\u3044\u5834\u5408\u306F\u512A\u5148\u9806\u3069\u304A\u308A\u6700\u5F8C\u306E\u98DF\u6599\u3068\u3057\u3066\u98DF\u3079\u3089\u308C\u308B\u3002
|
||||
if (protectedUntil > 0 && (world?.time || 0) < protectedUntil && hasBetterFoodThanZunchiNearby(tarinai, world, 900)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function tarinaiTargetBlockedByObstacle(world, tarinai, item, role = "") {
|
||||
if (!world || !tarinai || !item) return false;
|
||||
// ずんだ餅だけは障害物越しでも食べに行く。
|
||||
// \u305A\u3093\u3060\u9905\u3060\u3051\u306F\u969C\u5BB3\u7269\u8D8A\u3057\u3067\u3082\u98DF\u3079\u306B\u884C\u304F\u3002
|
||||
if ((role === "food" || role === "medicine") && effectiveFoodTypeForItem(item) === "sweet") return false;
|
||||
return Boolean(world.targetBlockedByObstacle?.(tarinai, item, Math.max(18, (tarinai.radius || 20) * 0.65)));
|
||||
}
|
||||
|
|
@ -164,8 +166,8 @@ function findNearestItemWithRole(world, tarinai, role, maxDist = 520) {
|
|||
if (it && !it.dead && !candidates.includes(it)) candidates.push(it);
|
||||
};
|
||||
|
||||
// 食料・水・薬は、通常時から空間インデックスだけに依存しない。
|
||||
// 生成直後/移動直後のアイテムが nearbyFood のキャッシュから漏れても、距離と roleMatches で最終判定する。
|
||||
// \u98DF\u6599\u30FB\u6C34\u30FB\u85AC\u306F\u3001\u901A\u5E38\u6642\u304B\u3089\u7A7A\u9593\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3060\u3051\u306B\u4F9D\u5B58\u3057\u306A\u3044\u3002
|
||||
// \u751F\u6210\u76F4\u5F8C/\u79FB\u52D5\u76F4\u5F8C\u306E\u30A2\u30A4\u30C6\u30E0\u304C nearbyFood \u306E\u30AD\u30E3\u30C3\u30B7\u30E5\u304B\u3089\u6F0F\u308C\u3066\u3082\u3001\u8DDD\u96E2\u3068 roleMatches \u3067\u6700\u7D42\u5224\u5B9A\u3059\u308B\u3002
|
||||
if (foodLikeRole) {
|
||||
if (Array.isArray(world?.items)) for (const it of world.items) addCandidate(it);
|
||||
if (world?.itemsOfType) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue