h
This commit is contained in:
parent
2cc2f003df
commit
61718e2981
18 changed files with 572 additions and 190 deletions
|
|
@ -4,6 +4,22 @@
|
|||
// Owns zunchi item motion, high-speed collision, and lifecycle stage ticking.
|
||||
// Prototype methods delegate here.
|
||||
(function (global) {
|
||||
function burstOwnerHitRadius(item, tarinai) {
|
||||
return (tarinai?.radius || 20) * 0.72 + (item?.r || 14);
|
||||
}
|
||||
|
||||
function updateBurstOwnerClearance(item, worldRef) {
|
||||
if (!item?.achievementBurstOwnerId || item.achievementBurstClearedOwner === true || !worldRef) return false;
|
||||
const owner = worldRef.liveTarinaiById?.(String(item.achievementBurstOwnerId))
|
||||
|| (worldRef.tarinai || []).find(candidate => candidate && !candidate.dead && String(candidate.id || "") === String(item.achievementBurstOwnerId))
|
||||
|| null;
|
||||
if (!owner) return false;
|
||||
const clearance = burstOwnerHitRadius(item, owner) + 3;
|
||||
if (distXY(item.x, item.y, owner.x, owner.y) <= clearance) return false;
|
||||
item.achievementBurstClearedOwner = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateMotion(item, dt, worldRef) {
|
||||
if (!item || item.dead || item.type !== "zunchi") return false;
|
||||
if (item.playerHeld || item._heldByPlayer) {
|
||||
|
|
@ -37,6 +53,7 @@
|
|||
worldRef.drawListDirty = true;
|
||||
}
|
||||
global.TarinaiItemDynamicBallSystem.resolveObstacleCollisions(item, dt, worldRef);
|
||||
updateBurstOwnerClearance(item, worldRef);
|
||||
const collisionSpeed = Math.hypot(item.vx || 0, item.vy || 0);
|
||||
if (collisionSpeed < 0.08 && item.achievementBurstOwnerId) item.achievementBurstNeverStopped = false;
|
||||
resolveHighSpeedTarinaiCollision(item, dt, worldRef, collisionSpeed);
|
||||
|
|
@ -50,7 +67,13 @@
|
|||
for (const t of worldRef.nearbyTarinai?.(item.x, item.y, search, true) || []) {
|
||||
if (!t || t.dead || worldRef.isTarinaiHiddenInNestBox?.(t)) continue;
|
||||
const d = distXY(item.x, item.y, t.x, t.y);
|
||||
if (d > (t.radius || 20) * 0.72 + (item.r || 14)) continue;
|
||||
if (d > burstOwnerHitRadius(item, t)) continue;
|
||||
const hitTarinaiIdBeforeDamage = String(t.id || t.releasedLiveId || "");
|
||||
const isBurstOwner = Boolean(item.achievementBurstOwnerId && String(item.achievementBurstOwnerId) === hitTarinaiIdBeforeDamage);
|
||||
// Burst zunchi spawn inside their owner. Ignore that initial overlap
|
||||
// completely; only a projectile that has first cleared the owner can
|
||||
// return and become a valid self-collision.
|
||||
if (isBurstOwner && item.achievementBurstClearedOwner !== true) continue;
|
||||
const now = worldRef.time || 0;
|
||||
if ((item.lastHitTarinaiAt || {})[t.id] && item.lastHitTarinaiAt[t.id] + 0.55 > now) continue;
|
||||
item.lastHitTarinaiAt = item.lastHitTarinaiAt || {};
|
||||
|
|
@ -62,8 +85,15 @@
|
|||
t.vy = (t.vy || 0) + ny * impulse * 0.72 + rand(-18, 10);
|
||||
if (speed >= 185) {
|
||||
const damage = Math.min(18, Math.max(1, (speed - 185) / 22));
|
||||
// A fatal damage call releases the tarinai live ID before control returns here.
|
||||
// Capture ownership eligibility first so a valid self-zunchi death is not lost.
|
||||
const eligibleSelfZunchiDeath = Boolean(
|
||||
isBurstOwner
|
||||
&& item.achievementBurstClearedOwner === true
|
||||
&& item.achievementBurstNeverStopped !== false
|
||||
);
|
||||
worldRef.applyImpactDamage?.(t, damage, "\u885d\u7a81", { source: item }) || t.damage?.(damage, "\u885d\u7a81");
|
||||
if (t.dead && item.achievementBurstOwnerId === t.id && item.achievementBurstNeverStopped !== false) {
|
||||
if (t.dead && eligibleSelfZunchiDeath) {
|
||||
globalThis.TarinaiAchievements?.recordSelfZunchiDeath?.({ world: worldRef, tarinai: t, zunchi: item, speed });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue