many
This commit is contained in:
parent
0b9ff1363b
commit
0a6148c73f
67 changed files with 2653 additions and 1519 deletions
|
|
@ -13,7 +13,7 @@
|
|||
]);
|
||||
|
||||
function effectLabel(id = "") {
|
||||
return EFFECT_REGISTRY?.label?.(id) || ITEM_EFFECT_LABELS[id] || id || "不明";
|
||||
return EFFECT_REGISTRY?.label?.(id) || ITEM_EFFECT_LABELS[id] || id || "\u4e0d\u660e";
|
||||
}
|
||||
|
||||
function sizeDurationScale(item = null) {
|
||||
|
|
@ -23,6 +23,10 @@
|
|||
return 1;
|
||||
}
|
||||
|
||||
function recordItemChange(tarinai, id = "", reason = "\u30a2\u30a4\u30c6\u30e0\u52b9\u679c") {
|
||||
tarinai?.recordChangeCause?.(reason, effectLabel(id));
|
||||
}
|
||||
|
||||
function pickRandomEffects(count = 2) {
|
||||
const pool = [...RANDOM_EFFECT_POOL];
|
||||
const out = [];
|
||||
|
|
@ -64,12 +68,15 @@
|
|||
if (!(id in this.itemEffectTimers)) this.itemEffectTimers[id] = 0;
|
||||
this.itemEffectTimers[id] = Math.max(this.itemEffectTimers[id] || 0, Number(seconds) || 0);
|
||||
if (id === "laxative") this.laxativePoopTimer = Math.min(Math.max(this.laxativePoopTimer || 3, 0.2), 3);
|
||||
this.world?.emit?.("effect:applied", { tarinai: this, effectId: id, duration: this.itemEffectTimers[id] || 0 });
|
||||
recordItemChange(this, id, "\u6642\u9593\u52b9\u679c");
|
||||
return true;
|
||||
},
|
||||
|
||||
itemSizeMultiplier() {
|
||||
this.ensureItemEffectState();
|
||||
if (this.sizeItemMode === "giant_drug") return 3;
|
||||
if (this.sizeItemMode === "dwarf_drug") return 0.25;
|
||||
if (this.sizeItemMode === "giant_drug") return EFFECT_REGISTRY?.modifier?.("giant_drug", "sizeMultiplier", 3) ?? 3;
|
||||
if (this.sizeItemMode === "dwarf_drug") return EFFECT_REGISTRY?.modifier?.("dwarf_drug", "sizeMultiplier", 0.25) ?? 0.25;
|
||||
return 1;
|
||||
},
|
||||
|
||||
|
|
@ -90,6 +97,8 @@
|
|||
this.powerEffectKind = mode;
|
||||
this.powerEffectPulse = Math.max(this.powerEffectPulse || 0, 3.2);
|
||||
this.spawnPowerItemEffect(mode, 1.5);
|
||||
this.world?.emit?.("effect:applied", { tarinai: this, effectId: mode, permanent: true });
|
||||
recordItemChange(this, mode, "\u80fd\u529b\u5909\u5316");
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
@ -102,6 +111,8 @@
|
|||
this.powerEffectKind = mode;
|
||||
this.powerEffectPulse = Math.max(this.powerEffectPulse || 0, 4.0);
|
||||
this.spawnPowerItemEffect(mode, mode === "giant_drug" ? 1.9 : 1.2);
|
||||
this.world?.emit?.("effect:applied", { tarinai: this, effectId: mode, permanent: true });
|
||||
recordItemChange(this, mode, "\u4f53\u683c\u5909\u5316");
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
@ -117,6 +128,8 @@
|
|||
this.powerEffectKind = "mercury";
|
||||
this.powerEffectPulse = Math.max(this.powerEffectPulse || 0, 2.7);
|
||||
this.spawnPowerItemEffect("mercury", 0.95);
|
||||
this.world?.emit?.("effect:applied", { tarinai: this, effectId: "mercury", permanent: true, multiplier: this.mercuryLifeMultiplier });
|
||||
recordItemChange(this, "mercury", "\u5bff\u547d\u5909\u5316");
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
@ -140,6 +153,8 @@
|
|||
this.powerEffectPulse = Math.max(this.powerEffectPulse || 0, 2.2);
|
||||
this.refreshEffectiveSize();
|
||||
this.spawnPowerItemEffect("zunda_juice", 1.4);
|
||||
this.world?.emit?.("effect:removed", { tarinai: this, effectId: "all_removable", source: "zunda_juice" });
|
||||
recordItemChange(this, "zunda_juice", "\u52b9\u679c\u89e3\u9664");
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
@ -147,101 +162,61 @@
|
|||
this.ensureItemEffectState();
|
||||
const scale = sizeDurationScale(item);
|
||||
let applied = [];
|
||||
if (type === "laxative") {
|
||||
this.setTimedItemEffect("laxative", Math.round(60 * scale));
|
||||
this.spawnPowerItemEffect("laxative", 0.75);
|
||||
applied.push("laxative");
|
||||
} else if (type === "protein") {
|
||||
this.setPowerItemMode("protein");
|
||||
applied.push("protein");
|
||||
} else if (type === "niteropu") {
|
||||
this.setPowerItemMode("niteropu");
|
||||
applied.push("niteropu");
|
||||
} else if (type === "ammo") {
|
||||
this.setTimedItemEffect("ammo", Math.round(18 * scale));
|
||||
this.spawnPowerItemEffect("ammo", 1.1);
|
||||
applied.push("ammo");
|
||||
} else if (type === "mercury") {
|
||||
this.setMercuryEffect();
|
||||
applied.push("mercury");
|
||||
} else if (type === "giant_drug") {
|
||||
this.setSizeItemMode("giant_drug");
|
||||
applied.push("giant_drug");
|
||||
} else if (type === "dwarf_drug") {
|
||||
this.setSizeItemMode("dwarf_drug");
|
||||
applied.push("dwarf_drug");
|
||||
} else if (type === "zunda_juice") {
|
||||
this.clearAllItemEffects();
|
||||
applied.push("zunda_juice");
|
||||
} else if (type === "mystery_drug") {
|
||||
if (type === "mystery_drug") {
|
||||
const picks = pickRandomEffects(2);
|
||||
for (const effect of picks) this.applyRandomizedBehaviorEffect(effect, item);
|
||||
this.mysteryDrugHistory = [...(this.mysteryDrugHistory || []), `${picks.map(effectLabel).join(" + ")}`].slice(-8);
|
||||
this.bubble("???", 1.2, ITEM_EFFECT_COLORS.mystery_drug);
|
||||
this.spawnPowerItemEffect("mystery_drug", 1.0);
|
||||
applied = picks;
|
||||
} else if (EFFECT_REGISTRY?.apply?.(type, this, { item, scale, source: "item" })) {
|
||||
applied.push(type);
|
||||
if (type === "laxative") {
|
||||
this.spawnPowerItemEffect("laxative", 0.75);
|
||||
} else if (type === "ammo") {
|
||||
this.spawnPowerItemEffect("ammo", 1.1);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (!options.silentLog && this.world?.log) {
|
||||
const label = type === "mystery_drug" ? `怪しい薬(${applied.map(effectLabel).join(" + ")})` : effectLabel(type);
|
||||
this.world.log(`${this.name}に${label}の効果が出た。`, "food", { participants: [this] });
|
||||
const label = type === "mystery_drug" ? `\u602a\u3057\u3044\u85ac(${applied.map(effectLabel).join(" + ")})` : effectLabel(type);
|
||||
this.world.log(`${this.name}\u306b${label}\u306e\u52b9\u679c\u304c\u51fa\u305f\u3002`, "food", { participants: [this] });
|
||||
}
|
||||
this.recordChangeCause?.("\u30a2\u30a4\u30c6\u30e0\u6442\u53d6", applied.map(effectLabel).join(" + ") || effectLabel(type));
|
||||
return true;
|
||||
},
|
||||
|
||||
applyRandomizedBehaviorEffect(effect = "", item = null) {
|
||||
const scale = sizeDurationScale(item);
|
||||
if (effect === "love_mochi") {
|
||||
this.loveMochiTimer = Math.max(this.loveMochiTimer || 0, 42 * scale + rand(4, 12));
|
||||
this.stress = clamp(this.stress - 8, 0, 130);
|
||||
return true;
|
||||
}
|
||||
if (effect === "fight_mochi") {
|
||||
this.fightMochiTimer = Math.max(this.fightMochiTimer || 0, 52 * scale + rand(10, 18));
|
||||
this.stress = clamp(this.stress + 10, 0, 130);
|
||||
return true;
|
||||
}
|
||||
if (effect === "sleep_drug") return this.infectSleepDisease?.(item) || true;
|
||||
if (effect === "laxative") { this.setTimedItemEffect("laxative", Math.round(60 * scale)); return true; }
|
||||
if (effect === "ammo") { this.setTimedItemEffect("ammo", Math.round(18 * scale)); return true; }
|
||||
if (effect === "protein") return this.setPowerItemMode("protein");
|
||||
if (effect === "niteropu") return this.setPowerItemMode("niteropu");
|
||||
if (effect === "mercury") return this.setMercuryEffect();
|
||||
if (effect === "giant_drug") return this.setSizeItemMode("giant_drug");
|
||||
if (effect === "dwarf_drug") return this.setSizeItemMode("dwarf_drug");
|
||||
if (effect === "disease_zunchi") return this.infectZunchiDisease?.(item, true) || true;
|
||||
if (effect === "disease_sleep") return this.infectSleepDisease?.(item) || true;
|
||||
if (effect === "disease_explosion") return this.infectExplosionDisease?.(item) || true;
|
||||
if (effect === "disease_fight") return this.infectFightDisease?.(item) || true;
|
||||
return false;
|
||||
return Boolean(EFFECT_REGISTRY?.apply?.(effect, this, { item, scale, source: "mystery_drug" }));
|
||||
},
|
||||
|
||||
diseaseChance(base = 0) {
|
||||
const b = Math.max(0, Number(base) || 0);
|
||||
if (this.powerItemMode === "protein") return b * 0.5;
|
||||
if (this.powerItemMode === "niteropu") return b * 2.0;
|
||||
if (this.powerItemMode === "protein") return b * (EFFECT_REGISTRY?.modifier?.("protein", "diseaseChanceMultiplier", 0.5) ?? 0.5);
|
||||
if (this.powerItemMode === "niteropu") return b * (EFFECT_REGISTRY?.modifier?.("niteropu", "diseaseChanceMultiplier", 2.0) ?? 2.0);
|
||||
return b;
|
||||
},
|
||||
|
||||
outgoingDamage(amount = 0) {
|
||||
let value = Number(amount) || 0;
|
||||
if (this.powerItemMode === "protein") value *= 1.75;
|
||||
if (this.powerItemMode === "niteropu") value *= 0.5;
|
||||
if (this.sizeItemMode === "giant_drug") value *= 2.0;
|
||||
if (this.sizeItemMode === "dwarf_drug") value *= 0.25;
|
||||
let value = (Number(amount) || 0) * (this.geneticStatRatio ? this.geneticStatRatio("attack") : 1);
|
||||
if (this.powerItemMode === "protein") value *= EFFECT_REGISTRY?.modifier?.("protein", "damageMultiplier", 1.75) ?? 1.75;
|
||||
if (this.powerItemMode === "niteropu") value *= EFFECT_REGISTRY?.modifier?.("niteropu", "damageMultiplier", 0.5) ?? 0.5;
|
||||
if (this.sizeItemMode === "giant_drug") value *= EFFECT_REGISTRY?.modifier?.("giant_drug", "damageMultiplier", 2.0) ?? 2.0;
|
||||
if (this.sizeItemMode === "dwarf_drug") value *= EFFECT_REGISTRY?.modifier?.("dwarf_drug", "damageMultiplier", 0.25) ?? 0.25;
|
||||
return value;
|
||||
},
|
||||
|
||||
itemSpeedMultiplier() {
|
||||
let value = this.hasItemEffect("ammo") ? 10 : 1;
|
||||
if (this.sizeItemMode === "giant_drug") value *= 1.5;
|
||||
if (this.sizeItemMode === "dwarf_drug") value *= 0.5;
|
||||
let value = this.hasItemEffect("ammo") ? (EFFECT_REGISTRY?.modifier?.("ammo", "speedMultiplier", 10) ?? 10) : 1;
|
||||
if (this.sizeItemMode === "giant_drug") value *= EFFECT_REGISTRY?.modifier?.("giant_drug", "speedMultiplier", 1.5) ?? 1.5;
|
||||
if (this.sizeItemMode === "dwarf_drug") value *= EFFECT_REGISTRY?.modifier?.("dwarf_drug", "speedMultiplier", 0.5) ?? 0.5;
|
||||
return value;
|
||||
},
|
||||
|
||||
applyFoodHungerRelief(amount = 0) {
|
||||
if (this.hasItemEffect("laxative")) return 0;
|
||||
if (this.hasItemEffect("laxative")) return (Number(amount) || 0) * (EFFECT_REGISTRY?.modifier?.("laxative", "hungerReliefMultiplier", 0) ?? 0);
|
||||
this.hunger -= Number(amount) || 0;
|
||||
return amount;
|
||||
},
|
||||
|
|
@ -256,8 +231,8 @@
|
|||
if (this.hasItemEffect("laxative")) {
|
||||
this.laxativePoopTimer = Math.max(0, (this.laxativePoopTimer || 3) - step);
|
||||
while (this.laxativePoopTimer <= 0 && this.hasItemEffect("laxative")) {
|
||||
this.laxativePoopTimer += 3;
|
||||
this.forceLaxativePoop();
|
||||
this.laxativePoopTimer += EFFECT_REGISTRY?.get?.("laxative")?.tickInterval || 3;
|
||||
EFFECT_REGISTRY?.tick?.("laxative", this, step);
|
||||
}
|
||||
} else {
|
||||
this.laxativePoopTimer = Math.min(Math.max(this.laxativePoopTimer || 3, 0.2), 3);
|
||||
|
|
@ -266,8 +241,7 @@
|
|||
this.itemDamageTimer = Math.max(0, (this.itemDamageTimer || 1) - step);
|
||||
while (this.itemDamageTimer <= 0 && !this.dead && (this.sizeItemMode === "giant_drug" || this.sizeItemMode === "dwarf_drug")) {
|
||||
this.itemDamageTimer += 1;
|
||||
this.damage?.(1, this.sizeItemMode === "giant_drug" ? "巨大薬" : "矮小薬");
|
||||
if (this.world?.effects) this.spawnPowerItemEffect(this.sizeItemMode, 0.25);
|
||||
EFFECT_REGISTRY?.tick?.(this.sizeItemMode, this, step);
|
||||
}
|
||||
} else {
|
||||
this.itemDamageTimer = Math.min(Math.max(this.itemDamageTimer || 1, 0.08), 1);
|
||||
|
|
@ -289,10 +263,14 @@
|
|||
this.world.spawnZunchi?.(x, y);
|
||||
this.poopCount = (this.poopCount || 0) + 1;
|
||||
this.digest = Math.max(0, (this.digest || 0) - 3.0);
|
||||
this.bubble("ぶりゅっ", 1.2, ITEM_EFFECT_COLORS.laxative);
|
||||
const now = this.world?.time || 0;
|
||||
if (now >= (this.nextPoopBubbleAt || -999)) {
|
||||
this.nextPoopBubbleAt = now + 2.2;
|
||||
this.bubble("\u3076\u308a\u3085\u3063", 1.2, ITEM_EFFECT_COLORS.laxative);
|
||||
}
|
||||
if ((this.world.time || 0) > (this.nextLaxativeLogAt || -999)) {
|
||||
this.nextLaxativeLogAt = (this.world.time || 0) + 9;
|
||||
this.world.log?.(`${this.name}は下剤の効果でずんちを放出した。`, "accident", { participants: [this] });
|
||||
this.world.log?.(`${this.name}\u306f\u4e0b\u5264\u306e\u52b9\u679c\u3067\u305a\u3093\u3061\u3092\u653e\u51fa\u3057\u305f\u3002`, "accident", { participants: [this] });
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -338,6 +316,9 @@
|
|||
o.vy += py * 160;
|
||||
o.hurtTimer = Math.max(o.hurtTimer || 0, 1.1);
|
||||
o.fallTimer = Math.max(o.fallTimer || 0, 0.72);
|
||||
const bumpDamage = Math.max(0.6, Math.min(3.0, speed / 260));
|
||||
o.damage?.(bumpDamage, "\u5f3e\u85ac\u885d\u7a81");
|
||||
this.adjustPersonality?.("aggression", 0.012, "after ammo knockback");
|
||||
this.world.spawnFallEffect?.(o.x, o.y + o.radius * 0.45, 1.05);
|
||||
audio.damage?.(12);
|
||||
this.ammoBumpCooldown = 0.12;
|
||||
|
|
@ -363,22 +344,8 @@
|
|||
|
||||
activeItemEffectSummary() {
|
||||
this.ensureItemEffectState();
|
||||
const rows = [];
|
||||
const add = (id, timer = 0) => {
|
||||
const label = effectLabel(id);
|
||||
const detail = EFFECT_REGISTRY?.display?.(id, timer, this) || "";
|
||||
rows.push({ id, label, detail });
|
||||
};
|
||||
if (this.powerItemMode === "protein") add("protein");
|
||||
if (this.powerItemMode === "niteropu") add("niteropu");
|
||||
if (this.lifeItemMode === "mercury") add("mercury");
|
||||
if (this.sizeItemMode === "giant_drug") add("giant_drug");
|
||||
if (this.sizeItemMode === "dwarf_drug") add("dwarf_drug");
|
||||
if ((this.itemEffectTimers.laxative || 0) > 0.04) add("laxative", this.itemEffectTimers.laxative);
|
||||
if ((this.itemEffectTimers.ammo || 0) > 0.04) add("ammo", this.itemEffectTimers.ammo);
|
||||
if ((this.loveMochiTimer || 0) > 0.1) add("love_mochi", this.loveMochiTimer);
|
||||
if ((this.fightMochiTimer || 0) > 0.1) add("fight_mochi", this.fightMochiTimer);
|
||||
return rows;
|
||||
if (EFFECT_REGISTRY?.activeSummary) return EFFECT_REGISTRY.activeSummary(this);
|
||||
return [];
|
||||
},
|
||||
}));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue