This commit is contained in:
33333-33333 2026-07-05 18:01:36 +09:00
commit 8f9f5b5100
108 changed files with 2139 additions and 1500 deletions

View file

@ -93,9 +93,11 @@
const items = worldRef.nearbyItems(item.x, item.y, searchRadius) || [];
const seen = new Set(items);
// 大きな機構は中心が近傍セル外でも当たる可能性がある。
// 中心ではなく外接半径で追加走査して、長い棒・往復幅にも衝突させる。
if (Array.isArray(worldRef.items)) {
for (const it of worldRef.items) {
// 全item走査ではなく、機構type bucketだけを追加確認する。
const mechanicalTypes = ["rotator", "poison_block", "reciprocator"];
for (const type of mechanicalTypes) {
const bucket = typeof worldRef.itemsOfType === "function" ? worldRef.itemsOfType(type) : (worldRef.items || []);
for (const it of bucket || []) {
if (!it || it.dead || it === item || !global.TarinaiMechanicalSystem.isMechanicalType(it.type) || seen.has(it)) continue;
const reach = global.TarinaiMechanicalSystem.reach(it) || worldRef.rotatorExtent?.(it) || Math.max(64, it.r || 64);
if (distXY(item.x, item.y, it.x, it.y) <= searchRadius + reach + 36) {
@ -258,6 +260,30 @@
return true;
}
const FAN_WIND_ITEM_TYPES = Object.freeze(["balloon", "ball", "pushpin", "oshibyo", "water", "zunda_juice", "mercury", "zunchi", "fire"]);
function fanWindItemCandidates(fan, worldRef, cx, cy, radius) {
if (!worldRef) return [];
if (typeof worldRef.itemsOfType === "function") {
const out = [];
const seen = new Set();
const r2 = Math.max(1, Number(radius || 0) || 0) ** 2;
for (const type of FAN_WIND_ITEM_TYPES) {
for (const it of worldRef.itemsOfType(type) || []) {
if (!it || it.dead || it === fan || seen.has(it.id || it)) continue;
const dx = Number(it.x || 0) - cx;
const dy = Number(it.y || 0) - cy;
const reach = radius + Math.max(0, Number(it.r || it.radius || 0) || 0);
if (dx * dx + dy * dy > Math.max(r2, reach * reach)) continue;
seen.add(it.id || it);
out.push(it);
}
}
return out;
}
return worldRef.nearbyItems?.(cx, cy, radius) || worldRef.items || [];
}
function fanWindAt(fan, x, y, opts = {}) {
if (!fan || fan.dead || fan.type !== "fan") return null;
const range = Math.max(80, Number(opts.range || 300) || 300);
@ -295,7 +321,9 @@
const ay = Math.sin(angle);
const range = 320;
const searchRadius = range + 40;
const nearbyItems = worldRef?.nearbyItems?.(item.x + ax * range * 0.45, item.y + ay * range * 0.45, searchRadius) || [];
const queryX = item.x + ax * range * 0.45;
const queryY = item.y + ay * range * 0.45;
const nearbyItems = fanWindItemCandidates(item, worldRef, queryX, queryY, searchRadius);
for (const target of nearbyItems) {
if (!target || target.dead || target === item) continue;
const wind = fanWindAt(item, target.x, target.y, { range });
@ -303,7 +331,7 @@
applyFanToItem(item, target, wind, frameDt, worldRef);
}
const nearbyTarinai = worldRef?.nearbyTarinai?.(item.x + ax * range * 0.45, item.y + ay * range * 0.45, searchRadius) || [];
const nearbyTarinai = worldRef?.nearbyTarinai?.(queryX, queryY, searchRadius) || [];
for (const t of nearbyTarinai) {
if (!t || t.dead || worldRef?.isTarinaiHiddenInNestBox?.(t)) continue;
const wind = fanWindAt(item, t.x, t.y, { range });
@ -616,7 +644,6 @@
update,
updateFan,
updateWaterDropMotion,
fanWindAt,
resolveObstacleCollisions,
popBalloon,
});