y
This commit is contained in:
parent
61718e2981
commit
f657b6a4a4
94 changed files with 3970 additions and 1241 deletions
|
|
@ -167,7 +167,12 @@
|
|||
function compactWorld(worldRef) {
|
||||
const config = typeof CONFIG !== "undefined" ? CONFIG : (global.CONFIG || {});
|
||||
const dayLength = Math.max(1, Number(config.dayLength || 120));
|
||||
const worldTick10 = q((Math.max(1, worldRef?.day || 1) - 1) * dayLength + (Number(worldRef?.time) || 0), 10);
|
||||
const rawTime = Math.max(0, Number(worldRef?.time) || 0);
|
||||
const elapsedDays = Number.isFinite(Number(worldRef?.elapsedDays))
|
||||
? Math.max(0, Math.floor(Number(worldRef.elapsedDays) || 0))
|
||||
: Math.max(0, Math.floor(rawTime / dayLength));
|
||||
const timeOfDay = ((rawTime % dayLength) + dayLength) % dayLength;
|
||||
const worldTick10 = q(elapsedDays * dayLength + timeOfDay, 10);
|
||||
return [
|
||||
enumIndex(FIELD_IDS, worldRef?.fieldType || "garden"),
|
||||
enumIndex(GROUND_IDS, worldRef?.groundType || "soil"),
|
||||
|
|
@ -187,26 +192,42 @@
|
|||
q(worldRef?.achievementLastInterventionAt, 10, 0),
|
||||
q(worldRef?.achievementNoDeathStartAt, 10, -10),
|
||||
q(worldRef?.achievementDirectFeedCount, 1, 0),
|
||||
elapsedDays,
|
||||
q(worldRef?.achievementManualTarinaiAddedCount, 1, 0),
|
||||
];
|
||||
}
|
||||
function applyCompactWorld(worldRef, arr = []) {
|
||||
function applyCompactWorld(worldRef, arr = [], meta = []) {
|
||||
const config = typeof CONFIG !== "undefined" ? CONFIG : (global.CONFIG || {});
|
||||
const dayLength = Math.max(1, Number(config.dayLength || 120));
|
||||
const totalTime = u(arr[3], 10, 0);
|
||||
const encodedTotalTime = Math.max(0, u(arr[3], 10, 0));
|
||||
const hasEncodedElapsedDays = arr[18] !== null && arr[18] !== undefined && Number.isFinite(Number(arr[18]));
|
||||
const hasMetaElapsedDays = meta[3] !== null && meta[3] !== undefined && Number.isFinite(Number(meta[3]));
|
||||
const hasMetaDay = meta[0] !== null && meta[0] !== undefined && Number.isFinite(Number(meta[0]));
|
||||
const encodedElapsedDays = hasEncodedElapsedDays
|
||||
? Math.max(0, Math.floor(Number(arr[18]) || 0))
|
||||
: (hasMetaElapsedDays
|
||||
? Math.max(0, Math.floor(Number(meta[3]) || 0))
|
||||
: (hasMetaDay
|
||||
? Math.max(0, Math.floor((Number(meta[0]) || 1) - 1))
|
||||
: Math.max(0, Math.floor(encodedTotalTime / dayLength / 2))));
|
||||
const timeOfDay = ((encodedTotalTime % dayLength) + dayLength) % dayLength;
|
||||
const totalTime = encodedElapsedDays * dayLength + timeOfDay;
|
||||
worldRef.fieldType = enumValue(FIELD_IDS, arr[0], "garden");
|
||||
worldRef.weather = enumValue(WEATHER_IDS, arr[4], "sunny");
|
||||
worldRef.worldSeed = String(arr[8] || "") || global.TarinaiSeedFactory.createWorldSeed() || `w${Date.now().toString(36)}`;
|
||||
worldRef.birthSerial = Math.max(0, u(arr[9], 1, 0));
|
||||
worldRef.tarinaiPopulationLimit = Math.max(0, u(arr[10], 1, 0));
|
||||
worldRef.objectLimit = Math.max(0, u(arr[11], 1, 0));
|
||||
worldRef.tarinaiPopulationLimit = worldRef.normalizeColonyLimit?.(u(arr[10], 1, 0)) ?? Math.min(300, Math.max(0, u(arr[10], 1, 0)));
|
||||
worldRef.objectLimit = worldRef.normalizeColonyLimit?.(u(arr[11], 1, 0)) ?? Math.min(300, Math.max(0, u(arr[11], 1, 0)));
|
||||
worldRef.achievementNaturalSlaveGenerations = Array.isArray(arr[12]) ? [...new Set(arr[12].map(value => Math.max(1, Math.floor(Number(value) || 1))))].sort((a, b) => a - b) : [];
|
||||
worldRef.achievementNaturalKingGenerations = Array.isArray(arr[13]) ? [...new Set(arr[13].map(value => Math.max(1, Math.floor(Number(value) || 1))))].sort((a, b) => a - b) : [];
|
||||
worldRef.achievementPlayerPlacementCount = Math.max(0, u(arr[14], 1, 0));
|
||||
worldRef.achievementLastInterventionAt = Math.max(0, u(arr[15], 10, totalTime));
|
||||
worldRef.achievementNoDeathStartAt = u(arr[16], 10, -1);
|
||||
worldRef.achievementDirectFeedCount = Math.max(0, u(arr[17], 1, 0));
|
||||
worldRef.day = Math.max(1, Math.floor(totalTime / dayLength) + 1);
|
||||
worldRef.time = totalTime - (worldRef.day - 1) * dayLength;
|
||||
worldRef.achievementManualTarinaiAddedCount = Math.min(100, Math.max(0, u(arr[19], 1, 0)));
|
||||
worldRef.time = Math.max(0, totalTime);
|
||||
worldRef.elapsedDays = encodedElapsedDays;
|
||||
worldRef.day = worldRef.elapsedDays + 1;
|
||||
worldRef.nextWeatherChange = rand(CONFIG.weatherChangeMin, CONFIG.weatherChangeMax);
|
||||
worldRef.deadCount = u(arr[7], 1, 0);
|
||||
worldRef.liveIdNext = 1;
|
||||
|
|
@ -235,6 +256,8 @@
|
|||
const needOverprotective = !isUnlocked("overprotective");
|
||||
const needSauna = !isUnlocked("sauna_cold_plunge");
|
||||
const needQuickDelete = !isUnlocked("unplanned_city_30");
|
||||
const needMinimalist = !isUnlocked("minimalist_happy");
|
||||
const needPlayerPlacedMetadata = needQuickDelete || needMinimalist;
|
||||
const metadata = {
|
||||
w: [
|
||||
needSlaveGenerations ? [...new Set((worldRef?.achievementNaturalSlaveGenerations || []).map(value => Math.max(1, Math.floor(Number(value) || 1))))].sort((a, b) => a - b) : [],
|
||||
|
|
@ -256,7 +279,7 @@
|
|||
needSauna ? finiteOrNull(t?._achievementSaunaHotAt) : null,
|
||||
]),
|
||||
i: itemRecords.map(rec => [
|
||||
needQuickDelete && rec?.item?._achievementPlayerPlaced ? 1 : 0,
|
||||
needPlayerPlacedMetadata && rec?.item?._achievementPlayerPlaced ? 1 : 0,
|
||||
needQuickDelete ? finiteOrNull(rec?.item?._achievementPlacedAt) : null,
|
||||
]),
|
||||
};
|
||||
|
|
@ -587,7 +610,7 @@
|
|||
return {
|
||||
v: SNAPSHOT_VERSION,
|
||||
a: "tj1",
|
||||
m: [worldRef.day || 1, tarinaiLive.length, worldRef.fieldType || "garden"],
|
||||
m: [worldRef.day || 1, tarinaiLive.length, worldRef.fieldType || "garden", Math.max(0, Math.floor(Number(worldRef.elapsedDays ?? ((Number(worldRef.day || 1) || 1) - 1)) || 0))],
|
||||
w: compactWorld(worldRef),
|
||||
t: tarinaiLive.map((t, i) => compactTarinai(t, i, familyIndex, tarinaiIndex, itemIndex)),
|
||||
i: itemRows,
|
||||
|
|
@ -608,7 +631,7 @@
|
|||
worldRef.selected = null;
|
||||
worldRef.events = global.TarinaiEvents || null;
|
||||
worldRef.liveTarinai = new Map();
|
||||
applyCompactWorld(worldRef, snapshot.w || []);
|
||||
applyCompactWorld(worldRef, snapshot.w || [], snapshot.m || []);
|
||||
|
||||
const tarRows = Array.isArray(snapshot.t) ? snapshot.t : [];
|
||||
for (let idx = 0; idx < tarRows.length; idx++) {
|
||||
|
|
@ -681,6 +704,23 @@
|
|||
if (typeof updateNeedsRuntime === "function") {
|
||||
for (const t of worldRef.tarinai) updateNeedsRuntime(t, worldRef, 0);
|
||||
}
|
||||
|
||||
// Velocity is not serialized. Start restored bodies from a neutral physical
|
||||
// state, but do not grant a timed collision/damage immunity period.
|
||||
delete worldRef._restoreSettleUntil;
|
||||
for (const t of worldRef.tarinai) {
|
||||
if (!t || t.dead) continue;
|
||||
t.vx = 0;
|
||||
t.vy = 0;
|
||||
t.impulseVx = 0;
|
||||
t.impulseVy = 0;
|
||||
t.prevX = t.x;
|
||||
t.prevY = t.y;
|
||||
t._lastPhysicalVelocityX = 0;
|
||||
t._lastPhysicalVelocityY = 0;
|
||||
t.lastVelocityShockDamageAt = -999;
|
||||
t.lastPhysicalCollisionDamageAt = -999;
|
||||
}
|
||||
worldRef.liveIdNext = Math.max(1, worldRef.tarinai.length + 1);
|
||||
worldRef.liveIdSerial = Math.max(1, worldRef.tarinai.length + 1);
|
||||
worldRef.birthSerial = Math.max(Number(worldRef.birthSerial) || 0, ...worldRef.tarinai.map(t => Number(t.birthSerial) || 0));
|
||||
|
|
@ -694,11 +734,13 @@
|
|||
worldRef.relationNotices = {};
|
||||
worldRef.resolvedFightIds = {};
|
||||
worldRef.eventCounters = {};
|
||||
worldRef.rebuildTarinaiCountCache?.("restore");
|
||||
worldRef.updateItemCounts?.();
|
||||
worldRef.enforceGrassLimit?.("load-grass-limit");
|
||||
worldRef.compactItems?.();
|
||||
worldRef.updateItemCounts?.();
|
||||
worldRef.updateEffectCounts?.();
|
||||
global.TarinaiAchievements?.evaluateEvent?.(worldRef, "restore", { source: "snapshot" });
|
||||
worldRef.rebuildSpatial?.(true);
|
||||
worldRef.markTerrainDirty?.("load");
|
||||
worldRef.clampCamera?.();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue