stable
This commit is contained in:
parent
fbdac9ebf1
commit
86226ccc94
97 changed files with 5790 additions and 2307 deletions
66
js/item_lifecycle_decay_system.js
Normal file
66
js/item_lifecycle_decay_system.js
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
|
||||
// Layer: entity-runtime/items/decay-system
|
||||
// Owns passive amount decay and spoilage side effects for water, food,
|
||||
// transient traces, splats, and ant corpses. The lifecycle step is now only a
|
||||
// thin pipeline adapter.
|
||||
(function (global) {
|
||||
const MEDICINE_LIKE_FOOD_TYPES = Object.freeze([
|
||||
"sweet", "love_mochi", "fight_mochi", "sleep_drug", "laxative", "protein",
|
||||
"niteropu", "ammo", "mystery_drug", "mercury", "giant_drug", "dwarf_drug", "zunda_juice",
|
||||
]);
|
||||
|
||||
function decayServingFood(item, dt, worldRef) {
|
||||
if (typeof isServingFoodType !== "function" || !isServingFoodType(item.type)) return false;
|
||||
const interval = passiveFoodDecayInterval(worldRef);
|
||||
item.passiveFoodDecayTimer = (item.passiveFoodDecayTimer || 0) + dt;
|
||||
let changed = false;
|
||||
let ticks = 0;
|
||||
while (item.passiveFoodDecayTimer >= interval && ticks < 3) {
|
||||
item.passiveFoodDecayTimer -= interval;
|
||||
ticks++;
|
||||
if (Number.isFinite(item.foodServingsRemaining)) {
|
||||
const before = Math.max(0, item.foodServingsRemaining || 0);
|
||||
const lost = Math.min(before, interval * passiveFoodDecayRate(item));
|
||||
if (lost > 0) {
|
||||
changed = true;
|
||||
item.foodServingsRemaining = Math.max(0, before - lost);
|
||||
item.amount = item.foodServingsRemaining;
|
||||
const penalty = global.TarinaiItemRegistry?.food?.hygienePenalty?.(item.type) ?? PASSIVE_FOOD_HYGIENE_PENALTY_PER_SERVING;
|
||||
worldRef?.registerFoodSpoilage?.(lost * penalty, item);
|
||||
worldRef?.markTerrainDirty?.("food-passive-decay");
|
||||
worldRef?.emit?.("item:decayed", { item, type: item.type, amount: lost, passive: true });
|
||||
if (item.foodServingsRemaining <= 0.015) item.amount = 0;
|
||||
}
|
||||
} else if (MEDICINE_LIKE_FOOD_TYPES.includes(item.type)) {
|
||||
const before = item.amount || 0;
|
||||
const lost = Math.min(before, interval * 0.12);
|
||||
item.amount -= lost;
|
||||
if (lost > 0) {
|
||||
changed = true;
|
||||
const penalty = global.TarinaiItemRegistry?.food?.hygienePenalty?.(item.type) ?? 0.002;
|
||||
worldRef?.registerFoodSpoilage?.(lost * penalty, item);
|
||||
worldRef?.markTerrainDirty?.("food-passive-decay");
|
||||
worldRef?.emit?.("item:decayed", { item, type: item.type, amount: lost, passive: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
function update(item, dt, worldRef) {
|
||||
if (!item || item.dead) return { done: true };
|
||||
if (item.type === "water") item.amount -= dt * 0.9;
|
||||
decayServingFood(item, dt, worldRef);
|
||||
if (item.type === "trace") item.amount -= dt * 1.35;
|
||||
if (item.type === "splat") item.amount -= dt * 1.05;
|
||||
if (item.type === "ant_corpse") item.amount -= dt * 0.018;
|
||||
return { done: false };
|
||||
}
|
||||
|
||||
global.TarinaiItemDecaySystem = Object.freeze({
|
||||
MEDICINE_LIKE_FOOD_TYPES,
|
||||
decayServingFood,
|
||||
update,
|
||||
});
|
||||
})(typeof window !== "undefined" ? window : globalThis);
|
||||
Loading…
Add table
Add a link
Reference in a new issue