286 lines
20 KiB
JavaScript
286 lines
20 KiB
JavaScript
"use strict";
|
||
|
||
|
||
function tarinaiRoundRectPath(ctx, x, y, w, h, r) {
|
||
const rr = Math.max(0, Math.min(r || 0, Math.abs(w) / 2, Math.abs(h) / 2));
|
||
ctx.beginPath();
|
||
ctx.moveTo(x + rr, y);
|
||
ctx.lineTo(x + w - rr, y);
|
||
ctx.quadraticCurveTo(x + w, y, x + w, y + rr);
|
||
ctx.lineTo(x + w, y + h - rr);
|
||
ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h);
|
||
ctx.lineTo(x + rr, y + h);
|
||
ctx.quadraticCurveTo(x, y + h, x, y + h - rr);
|
||
ctx.lineTo(x, y + rr);
|
||
ctx.quadraticCurveTo(x, y, x + rr, y);
|
||
}
|
||
|
||
function tarinaiChampionName(name = "") {
|
||
const raw = String(name || "");
|
||
if (/おちび(?:の王)?$/.test(raw)) return raw.endsWith("の王") ? raw : `${raw}の王`;
|
||
const map = { "は": "覇", "う": "宇", "ぅ": "ゥ", "っ": "!" };
|
||
return raw.replace(/[はうぅっ]/g, ch => map[ch] || ch);
|
||
}
|
||
if (typeof window !== "undefined") window.tarinaiChampionName = tarinaiChampionName;
|
||
if (typeof globalThis !== "undefined") globalThis.tarinaiChampionName = tarinaiChampionName;
|
||
|
||
const ACQUIRED_TARINAI_NAME_PREFIXES = ["かしこい", "すごい", "たくましい", "げんきな", "わんぱくな", "ぴかぴかあにゃるの", "しゅーるすとれみんぐ・", "つよい", "もちもちほっぺの", "でかずんぽの", "ちびずんぽの", "すばらしい", "かわいい", "ずんちがくさい", "やさしい", "ゆうかんな", "いいにおいの"];
|
||
function acquiredTarinaiBaseName(seed = "", name = "") {
|
||
const raw = String(name || "").trim();
|
||
if (raw && raw !== "ずんちどれい") return raw.replace(/の王$/, "");
|
||
const pick = typeof stableChoice === "function" ? stableChoice(seed || raw || "acquired", "acquired-name-prefix", ACQUIRED_TARINAI_NAME_PREFIXES) : (ACQUIRED_TARINAI_NAME_PREFIXES[0] || "");
|
||
return `${pick || ACQUIRED_TARINAI_NAME_PREFIXES[0] || ""}おちび`;
|
||
}
|
||
|
||
class Tarinai { constructor(world, opts = {}) {
|
||
if (world && !opts.birthSeed && !opts.familyKey && !opts.id && globalThis.TarinaiSeedFactory.prepareAddOptions) {
|
||
opts = globalThis.TarinaiSeedFactory.prepareAddOptions(world, opts) || opts;
|
||
}
|
||
this.world = world;
|
||
this.isAcquiredTarinai = Boolean(opts.isAcquiredTarinai);
|
||
this.birthSeed = opts.birthSeed || opts.familyKey || opts.id || (globalThis.TarinaiSeedFactory.childSeed(world?.worldSeed || "", Number(world?.birthSerial || 0) + 1, []) || (crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`));
|
||
this.birthSerial = Number.isFinite(opts.birthSerial) ? Number(opts.birthSerial) : (globalThis.TarinaiSeedFactory.serialFromBirthSeed(this.birthSeed) || 0);
|
||
const birthProfile = globalThis.TarinaiSeedFactory.birthProfile(this.birthSeed, opts) || {};
|
||
this.familyKey = opts.familyKey || this.birthSeed;
|
||
this.id = opts.id || "";
|
||
this.liveToken = opts.liveToken || 0;
|
||
this.name = opts.name || birthProfile.name || makeName(world);
|
||
this.acquiredBaseName = opts.acquiredBaseName || null;
|
||
this.type = opts.type || birthProfile.type || baseSpriteId();
|
||
const typeMeta = SPRITES.find(s => s.id === this.type);
|
||
if (typeMeta?.actionOnly || typeMeta?.displayOnly) this.type = birthProfile.type || baseSpriteId();
|
||
this.birthPersonality = normalizePersonality(opts.birthPersonality || birthProfile.birthPersonality);
|
||
this.currentPersonality = normalizePersonality(opts.currentPersonality || this.birthPersonality);
|
||
this.personalityDaily = opts.personalityDaily && typeof opts.personalityDaily === "object" ? JSON.parse(JSON.stringify(opts.personalityDaily)) : null;
|
||
ensurePersonality(this);
|
||
this.genetics = normalizeGenetics(opts.genetics || birthProfile.genetics, this.birthSeed);
|
||
this.trait = makeTrait(this.type);
|
||
this.trait.speed *= this.genetics.speedMul || 1;
|
||
this.birthTime = opts.birthTime ?? this.world.time;
|
||
const generationOpt = opts.generation ?? 1;
|
||
const growthAtConstruct = generationOpt > 1 ? clamp(((this.world?.time || 0) - this.birthTime) / Math.max(1, CONFIG.childGrowTime || 120), 0, 1) : 1;
|
||
this.x = opts.x ?? rand(100, world.w - 100);
|
||
this.y = opts.y ?? rand(100, world.h - 100);
|
||
this._lastValidX = Number.isFinite(this.x) ? this.x : null;
|
||
this._lastValidY = Number.isFinite(this.y) ? this.y : null;
|
||
this._lastSunbathDrawX = Number.isFinite(opts._lastSunbathDrawX) ? opts._lastSunbathDrawX : null;
|
||
this._lastSunbathDrawY = Number.isFinite(opts._lastSunbathDrawY) ? opts._lastSunbathDrawY : null;
|
||
this._activeSunbathSpriteId = typeof opts._activeSunbathSpriteId === "string" ? opts._activeSunbathSpriteId : "";
|
||
this.vx = opts.vx ?? rand(-12, 12);
|
||
this.vy = opts.vy ?? rand(-12, 12);
|
||
this.impulseVx = opts.impulseVx ?? 0;
|
||
this.impulseVy = opts.impulseVy ?? 0;
|
||
this.adultScale = Number.isFinite(opts.adultScale) ? opts.adultScale : (Number.isFinite(opts.baseAdultScale) ? opts.baseAdultScale : (Number.isFinite(opts.scale) && growthAtConstruct >= 1 ? opts.scale : (Number.isFinite(birthProfile.adultScale) ? birthProfile.adultScale : adultScaleFromGenetics(this.birthSeed, this.genetics))));
|
||
this.scale = Number.isFinite(opts.scale) ? opts.scale : (generationOpt > 1 ? scaleForGrowth(this.adultScale, growthAtConstruct) : this.adultScale);
|
||
this.radius = 56 * this.scale;
|
||
this.age = opts.age ?? rand(0, 20);
|
||
this.lifeSpan = opts.lifeSpan ?? (Number.isFinite(birthProfile.lifeSpan) ? birthProfile.lifeSpan : rand(1400, 2200) * (this.genetics.lifeSpanMul || 1));
|
||
if (this.lifeSpan < 900) this.lifeSpan = Number.isFinite(birthProfile.lifeSpan) ? birthProfile.lifeSpan : rand(1200, 1800) * (this.genetics.lifeSpanMul || 1);
|
||
this.generation = generationOpt;
|
||
this.hasPaired = opts.hasPaired ?? false;
|
||
this.hunger = opts.hunger ?? rand(16, 45);
|
||
this.loneliness = opts.loneliness ?? rand(18, 62);
|
||
const initialDayP = world?.dayProgress?.() || 0;
|
||
const initialNight = initialDayP >= 0.66 || initialDayP < 0.18;
|
||
const initialAfternoon = initialDayP >= 0.46 && initialDayP < 0.58;
|
||
this.energy = opts.energy ?? (initialNight ? rand(34, 68) : (initialAfternoon ? rand(50, 82) : rand(66, 98)));
|
||
this.circadianSleepPressure = Number.isFinite(opts.circadianSleepPressure) ? opts.circadianSleepPressure : (initialNight ? rand(58, 78) : (initialAfternoon ? rand(8, 18) : rand(0, 5)));
|
||
const defaultNeeds = typeof createDefaultNeeds === "function" ? createDefaultNeeds() : { food: 0, sleep: 0, health: 0, safety: 0, social: 0, fulfill: 0 };
|
||
this.needs = opts.needs && typeof opts.needs === "object" ? { ...defaultNeeds, ...opts.needs } : { ...defaultNeeds };
|
||
this.needDisplay = opts.needDisplay && typeof opts.needDisplay === "object" ? { ...defaultNeeds, ...opts.needDisplay } : { ...this.needs };
|
||
this.needRaw = opts.needRaw && typeof opts.needRaw === "object" ? { ...defaultNeeds, ...opts.needRaw } : { ...this.needs };
|
||
this.needRawBase = opts.needRawBase && typeof opts.needRawBase === "object" ? { ...defaultNeeds, ...opts.needRawBase } : { ...this.needRaw };
|
||
this.needSatisfaction = opts.needSatisfaction && typeof opts.needSatisfaction === "object" ? { ...defaultNeeds, ...opts.needSatisfaction } : { ...defaultNeeds };
|
||
this.stress = typeof calculateStressFromNeeds === "function" ? calculateStressFromNeeds(this.needRaw || this.needs) : 0;
|
||
this.previousNeeds = opts.previousNeeds && typeof opts.previousNeeds === "object" ? { ...defaultNeeds, ...opts.previousNeeds } : { ...this.needs };
|
||
this.need = "";
|
||
this.state = opts.state || "idle";
|
||
this.behaviorSerial = opts.behaviorSerial ?? 0;
|
||
this.behavior = typeof globalThis.normalizeTarinaiBehaviorState === "function"
|
||
? globalThis.normalizeTarinaiBehaviorState(opts, this)
|
||
: (opts.behavior && typeof opts.behavior === "object" ? { ...opts.behavior } : null);
|
||
this.forcedBehaviorQueue = Array.isArray(opts.forcedBehaviorQueue) ? opts.forcedBehaviorQueue.map(v => ({ ...(v || {}) })).slice(-8) : [];
|
||
this.actionCooldowns = opts.actionCooldowns && typeof opts.actionCooldowns === "object" ? { ...opts.actionCooldowns } : {};
|
||
this.needShock = opts.needShock && typeof opts.needShock === "object" ? { ...opts.needShock } : {};
|
||
this.buildPlan = opts.buildPlan && typeof opts.buildPlan === "object" ? { ...opts.buildPlan } : null;
|
||
this.sleepSession = opts.sleepSession && typeof opts.sleepSession === "object" ? { ...opts.sleepSession } : null;
|
||
this.hpBarTimer = opts.hpBarTimer ?? 0;
|
||
this.stressBarTimer = opts.stressBarTimer ?? 0;
|
||
this.affection = opts.affection ?? rand(0, 30);
|
||
this.dead = !!opts.dead;
|
||
this.deathReason = opts.deathReason || "";
|
||
this.deathTime = opts.deathTime != null && Number.isFinite(Number(opts.deathTime)) ? Number(opts.deathTime) : null;
|
||
this.lastDamageCause = opts.lastDamageCause || "";
|
||
this.lastDamageAmount = opts.lastDamageAmount ?? 0;
|
||
this.lastDamageAt = opts.lastDamageAt ?? -999;
|
||
this.lastMajorDamageCause = opts.lastMajorDamageCause || "";
|
||
this.lastMajorDamageAt = opts.lastMajorDamageAt ?? -999;
|
||
this.thought = "";
|
||
this.target = null;
|
||
this.targetKey = "";
|
||
this.targetSince = 0;
|
||
this.targetBestDist = Infinity;
|
||
this.targetGiveupKey = opts.targetGiveupKey || "";
|
||
this.targetGiveupUntil = opts.targetGiveupUntil ?? 0;
|
||
this.panicTarget = opts.panicTarget || null;
|
||
this.panicTargetUntil = opts.panicTargetUntil ?? 0;
|
||
this.panicStuckTimer = opts.panicStuckTimer ?? 0;
|
||
this.wanderAngle = rand(0, Math.PI * 2);
|
||
this.wanderTarget = opts.wanderTarget && typeof opts.wanderTarget === "object" ? { ...opts.wanderTarget } : null;
|
||
this.reproductionTimer = rand(4, CONFIG.reproductionCooldown);
|
||
this.lastLog = 0;
|
||
this.sleeping = false;
|
||
this.awakeLockTimer = opts.awakeLockTimer ?? 0;
|
||
this.goodMode = opts.goodMode ?? birthProfile.goodMode ?? stableChoice(this.birthSeed || this.familyKey, "good-mode", displayNormalSprites()) ?? "smile";
|
||
if (this.isAcquiredTarinai) {
|
||
const explicitAcquiredName = this.acquiredBaseName || (Object.prototype.hasOwnProperty.call(opts, "name") ? this.name : "");
|
||
this.acquiredBaseName = acquiredTarinaiBaseName(this.birthSeed || this.familyKey, explicitAcquiredName);
|
||
this.name = this.acquiredBaseName;
|
||
}
|
||
if (this.isAcquiredTarinai) {
|
||
const acquiredNeeds = { food: 22, sleep: 34, health: 78, safety: 100, social: 90, fulfill: 82 };
|
||
const hasExplicitNeedState = Boolean((opts.needs && typeof opts.needs === "object") || (opts.needRaw && typeof opts.needRaw === "object") || (opts.needDisplay && typeof opts.needDisplay === "object") || (opts.needRawBase && typeof opts.needRawBase === "object") || (opts.previousNeeds && typeof opts.previousNeeds === "object"));
|
||
if (!hasExplicitNeedState) {
|
||
this.needs = { ...acquiredNeeds };
|
||
this.needDisplay = { ...acquiredNeeds };
|
||
this.needRaw = { ...acquiredNeeds };
|
||
this.needRawBase = { ...acquiredNeeds };
|
||
this.previousNeeds = { ...acquiredNeeds };
|
||
}
|
||
if (!Object.prototype.hasOwnProperty.call(opts, "loneliness")) this.loneliness = Math.max(Number(this.loneliness) || 0, 90);
|
||
if (!Object.prototype.hasOwnProperty.call(opts, "hunger")) this.hunger = Math.max(Number(this.hunger) || 0, 22);
|
||
if (!Object.prototype.hasOwnProperty.call(opts, "energy")) this.energy = Math.min(Number(this.energy) || 0, 45);
|
||
if (!Object.prototype.hasOwnProperty.call(opts, "goodMode") && Array.isArray(SPRITES) && SPRITES.some(s => s.id === "jito")) this.goodMode = "jito";
|
||
this.stress = typeof calculateStressFromNeeds === "function" ? calculateStressFromNeeds(this.needRaw || this.needs) : this.stress;
|
||
this.acquiredStressSpeechAt = Number.isFinite(opts.acquiredStressSpeechAt) ? opts.acquiredStressSpeechAt : ((this.world?.time || 0) + rand(2.8, 6.5));
|
||
this.acquiredStressSpeechCooldownUntil = Number.isFinite(opts.acquiredStressSpeechCooldownUntil) ? opts.acquiredStressSpeechCooldownUntil : 0;
|
||
}
|
||
this.facing = opts.facing ?? (stableUnit(this.familyKey, "facing") < 0.5 ? -1 : 1);
|
||
this.visualFacing = opts.visualFacing ?? this.facing;
|
||
this.facingLockUntil = opts.facingLockUntil ?? 0;
|
||
this.eatTimer = opts.eatTimer ?? 0;
|
||
this.eatCooldown = opts.eatCooldown ?? 0;
|
||
this.mealCooldownUntil = Number.isFinite(opts.mealCooldownUntil) ? opts.mealCooldownUntil : 0;
|
||
this.foodReactTimer = opts.foodReactTimer ?? 0;
|
||
this.surpriseTimer = opts.surpriseTimer ?? 0;
|
||
this.fearTimer = opts.fearTimer ?? 0;
|
||
this.sunbathTimer = opts.sunbathTimer ?? 0;
|
||
this.sunbathCooldown = opts.sunbathCooldown ?? 0;
|
||
this.sunbathFrameTimer = opts.sunbathFrameTimer ?? 0;
|
||
this.sunbathSpriteVariant = opts.sunbathSpriteVariant ?? 1;
|
||
this.sunbathAnchorX = Number.isFinite(opts.sunbathAnchorX) ? opts.sunbathAnchorX : null;
|
||
this.sunbathAnchorY = Number.isFinite(opts.sunbathAnchorY) ? opts.sunbathAnchorY : null;
|
||
this.intimidateTimer = opts.intimidateTimer ?? 0;
|
||
this.intimidateTargetId = opts.intimidateTargetId || null;
|
||
this.intimidatedTimer = opts.intimidatedTimer ?? 0;
|
||
this.intimidationCooldown = opts.intimidationCooldown ?? 0;
|
||
this.birthRitualTimer = opts.birthRitualTimer ?? 0;
|
||
this.birthRitualMax = opts.birthRitualMax ?? 0;
|
||
this.birthPartnerId = opts.birthPartnerId || null;
|
||
this.birthRitualRole = opts.birthRitualRole || 0;
|
||
this.birthRitualLeader = !!opts.birthRitualLeader;
|
||
this.pokeFlashTimer = opts.pokeFlashTimer ?? 0;
|
||
this.zunchiStain = opts.zunchiStain ?? 0;
|
||
this.zunchiStainSeed = opts.zunchiStainSeed ?? stableUnit(this.familyKey, "zunchi-stain");
|
||
this.zunchiDisease = Boolean(opts.zunchiDisease);
|
||
this.zunchiDiseaseSeverity = opts.zunchiDiseaseSeverity ?? (this.zunchiDisease ? 1 : 0);
|
||
this.zunchiDiseaseCooldown = opts.zunchiDiseaseCooldown ?? 0;
|
||
this.totalFightLosses = opts.totalFightLosses || 0;
|
||
this.totalFightWins = opts.totalFightWins || 0;
|
||
this.isTarinaiChampion = !!opts.isTarinaiChampion;
|
||
this.tarinaiChampionSince = Number.isFinite(opts.tarinaiChampionSince) ? opts.tarinaiChampionSince : 0;
|
||
this.isZunchiSlave = Boolean(opts.isZunchiSlave || opts.zunchiSlaveLocked);
|
||
this.zunchiSlaveLocked = Boolean(opts.zunchiSlaveLocked || this.isZunchiSlave);
|
||
this.formerName = opts.formerName || null;
|
||
this.loveMochiTimer = opts.loveMochiTimer ?? 0;
|
||
this.fightMochiTimer = opts.fightMochiTimer ?? 0;
|
||
this.sleepDisease = Boolean(opts.sleepDisease);
|
||
this.sleepDiseaseCooldown = opts.sleepDiseaseCooldown ?? 0;
|
||
this.explosionDisease = Boolean(opts.explosionDisease);
|
||
this.explosionDiseaseTimer = opts.explosionDiseaseTimer ?? (this.explosionDisease ? 60 : 0);
|
||
this.fightDisease = Boolean(opts.fightDisease);
|
||
this.mamekusaredakeDisease = Boolean(opts.mamekusaredakeDisease);
|
||
this.mamekusaredakeGrowth = Number.isFinite(opts.mamekusaredakeGrowth) ? opts.mamekusaredakeGrowth : 0;
|
||
this.mamekusaredakeSpeechAt = Number.isFinite(opts.mamekusaredakeSpeechAt) ? opts.mamekusaredakeSpeechAt : 0;
|
||
this.fightDiseaseCooldown = opts.fightDiseaseCooldown ?? 0;
|
||
this.lastBleedAt = opts.lastBleedAt ?? -999;
|
||
this.favorite = Boolean(opts.favorite);
|
||
this.insideNestBoxId = opts.insideNestBoxId || null;
|
||
this.nestFade = opts.nestFade ?? (this.insideNestBoxId ? 1 : 0);
|
||
this.nestBoxStayUntil = opts.nestBoxStayUntil ?? (this.insideNestBoxId ? ((world?.time || 0) + 10) : -Infinity);
|
||
this.focusPulseTimer = opts.focusPulseTimer ?? 0;
|
||
if (this.isZunchiSlave) {
|
||
this.zunchiSlaveLocked = true;
|
||
this.name = "\u305a\u3093\u3061\u3069\u308c\u3044";
|
||
applyZunchiSlavePersonality(this, { record: false, birth: false });
|
||
this.visibleSpriteId = "zunchi_slave";
|
||
}
|
||
if (this.isTarinaiChampion) this.name = tarinaiChampionName(this.name);
|
||
this.tempComfort = opts.tempComfort ?? (CONFIG.standardTemperature ?? 15);
|
||
this.feltTemperature = opts.feltTemperature ?? this.tempComfort;
|
||
this.temperatureStatus = null;
|
||
this.tempTimer = opts.tempTimer ?? stableUnit(this.familyKey, "temp-start") * 0.55;
|
||
this.parents = opts.parents || [];
|
||
this.parentNames = opts.parentNames || [];
|
||
this.children = opts.children || [];
|
||
this.nextEatSound = opts.nextEatSound ?? 0;
|
||
this.fightTimer = opts.fightTimer ?? 0;
|
||
this.fightCooldown = opts.fightCooldown ?? deterministicRange(world, "initial-fight-cooldown", 0, CONFIG.fightCooldown, this.familyKey || this.id || opts.birthSeed);
|
||
this.fightTargetId = opts.fightTargetId || null;
|
||
this.fightTargetIds = Array.isArray(opts.fightTargetIds) ? [...opts.fightTargetIds] : (this.fightTargetId ? [this.fightTargetId] : []);
|
||
this.nextHeadbutt = opts.nextHeadbutt ?? 0;
|
||
const savedDigest = Number(opts.digest);
|
||
this.digest = Number.isFinite(savedDigest)
|
||
? (savedDigest > 3 ? Math.min(2.99, savedDigest / 12.4 * 3) : Math.max(0, savedDigest))
|
||
: 0;
|
||
this.poopCount = opts.poopCount ?? 0;
|
||
this.oshiriByoZunchiStock = opts.oshiriByoZunchiStock ?? 0;
|
||
this.lastMealColor = opts.lastMealColor || "#f7cf67";
|
||
this.grassEatTimer = opts.grassEatTimer ?? 0;
|
||
this.hurtTimer = opts.hurtTimer ?? 0;
|
||
this.stuckPushpinId = opts.stuckPushpinId || null;
|
||
this.defeatedTimer = opts.defeatedTimer ?? 0;
|
||
this.defeatedById = opts.defeatedById || null;
|
||
this.fightWinnerId = opts.fightWinnerId || null;
|
||
this.relationships = opts.relationships && typeof opts.relationships === "object" ? JSON.parse(JSON.stringify(opts.relationships)) : {};
|
||
this.fallTimer = opts.fallTimer ?? 0;
|
||
this.fallMax = opts.fallMax ?? 1.15;
|
||
this.fallDir = opts.fallDir ?? (stableUnit(this.familyKey, "fall-dir") < 0.5 ? -1 : 1);
|
||
this.blastSpinTimer = opts.blastSpinTimer ?? 0;
|
||
this.blastSpinMax = opts.blastSpinMax ?? 0;
|
||
this.postBirthPeaceTimer = opts.postBirthPeaceTimer ?? 0;
|
||
this.sleepFacing = stableUnit(this.familyKey, "sleep-facing") < 0.5 ? -1 : 1;
|
||
this.nextBubbleAt = 0;
|
||
this.nextSleepBubbleAt = 0;
|
||
this.nextCursorHeartAt = opts.nextCursorHeartAt ?? 0;
|
||
this.cursorPetting = opts.cursorPetting ?? 0;
|
||
this.aiTimer = opts.aiTimer ?? stableUnit(this.familyKey, "ai-start") * 0.22;
|
||
this.envTimer = opts.envTimer ?? stableUnit(this.familyKey, "env-start") * 0.55;
|
||
this.visibleSpriteId = opts.visibleSpriteId || null;
|
||
this.zunchiSlaveSpriteVariant = opts.zunchiSlaveSpriteVariant || (opts.isZunchiSlave ? (Math.random() < 0.5 ? "zunchi_slave" : "zunchi_slave_alt") : "");
|
||
this.spriteLockUntil = opts.spriteLockUntil ?? 0;
|
||
this.entryTimer = opts.entryTimer ?? 0;
|
||
const effectTimers = opts.itemEffectTimers && typeof opts.itemEffectTimers === "object" ? opts.itemEffectTimers : {};
|
||
this.itemEffectTimers = {
|
||
laxative: Math.max(0, Number(effectTimers.laxative || opts.laxativeTimer || 0) || 0),
|
||
ammo: Math.max(0, Number(effectTimers.ammo || opts.ammoTimer || 0) || 0),
|
||
sedative: Math.max(0, Number(effectTimers.sedative || opts.sedativeTimer || 0) || 0),
|
||
};
|
||
this.laxativePoopTimer = Number.isFinite(opts.laxativePoopTimer) ? opts.laxativePoopTimer : 3;
|
||
this.ammoBumpCooldown = opts.ammoBumpCooldown || 0;
|
||
this.powerItemMode = opts.powerItemMode === "protein" || opts.powerItemMode === "niteropu" ? opts.powerItemMode : "";
|
||
this.sizeItemMode = opts.sizeItemMode === "giant_drug" || opts.sizeItemMode === "dwarf_drug" ? opts.sizeItemMode : "";
|
||
this.lifeItemMode = opts.lifeItemMode === "mercury" ? opts.lifeItemMode : "";
|
||
this.mercuryLifeSpanBase = Number.isFinite(opts.mercuryLifeSpanBase) ? opts.mercuryLifeSpanBase : null;
|
||
this.mercuryLifeMultiplier = Number.isFinite(opts.mercuryLifeMultiplier) ? Math.max(1, opts.mercuryLifeMultiplier) : (this.lifeItemMode === "mercury" ? 1.3 : 1);
|
||
this.itemDamageTimer = Number.isFinite(opts.itemDamageTimer) ? opts.itemDamageTimer : 1;
|
||
this.powerEffectPulse = opts.powerEffectPulse || 0;
|
||
this.powerEffectKind = opts.powerEffectKind || this.powerItemMode || this.sizeItemMode || this.lifeItemMode || "";
|
||
this.mysteryDrugHistory = Array.isArray(opts.mysteryDrugHistory) ? opts.mysteryDrugHistory.slice(-8) : [];
|
||
this.recentChangeCauses = Array.isArray(opts.recentChangeCauses) ? opts.recentChangeCauses.slice(-8) : [];
|
||
if (this.refreshEffectiveSize) this.refreshEffectiveSize();
|
||
}
|
||
}
|
||
|
||
if (typeof window !== "undefined") window.Tarinai = Tarinai;
|
||
if (typeof globalThis !== "undefined") globalThis.Tarinai = Tarinai;
|