mirror of
https://github.com/sortedcord/omnia.git
synced 2026-07-22 03:52:48 +05:30
refactor: Serializers include available location attributes
This commit is contained in:
@@ -4,6 +4,8 @@ import { AttributableObject, AttributeVisibility } from "./attribute.js";
|
||||
import { Entity } from "./entity.js";
|
||||
import { WorldState } from "./world.js";
|
||||
|
||||
class GenericObject extends AttributableObject {}
|
||||
|
||||
export class SQLiteRepository {
|
||||
private db: Database.Database;
|
||||
|
||||
@@ -195,6 +197,9 @@ export class SQLiteRepository {
|
||||
for (const entity of worldState.entities.values()) {
|
||||
this.saveEntity(entity, worldState.id);
|
||||
}
|
||||
for (const location of worldState.locations.values()) {
|
||||
this.saveLocation(location, worldState.id);
|
||||
}
|
||||
});
|
||||
saveWorldTx();
|
||||
}
|
||||
@@ -288,6 +293,25 @@ export class SQLiteRepository {
|
||||
const worldState = new WorldState(id, startTime);
|
||||
this.reconstituteAttributes(worldState);
|
||||
|
||||
// Reconstitute all locations belonging to this world
|
||||
const locationRows = this.db
|
||||
.prepare(
|
||||
`
|
||||
SELECT id, location_id, connections_json FROM objects WHERE type = 'location' AND world_id = ?
|
||||
`,
|
||||
)
|
||||
.all(id) as { id: string; location_id: string | null; connections_json: string | null }[];
|
||||
|
||||
for (const row of locationRows) {
|
||||
const loc = new GenericObject(row.id);
|
||||
(loc as { parentId?: string | null }).parentId = row.location_id;
|
||||
if (row.connections_json) {
|
||||
(loc as { connections?: unknown[] }).connections = JSON.parse(row.connections_json);
|
||||
}
|
||||
this.reconstituteAttributes(loc);
|
||||
worldState.addLocation(loc);
|
||||
}
|
||||
|
||||
// Reconstitute all entities belonging to this world
|
||||
const entityRows = this.db
|
||||
.prepare(
|
||||
|
||||
@@ -8,6 +8,7 @@ export class WorldState extends AttributableObject {
|
||||
* Universe's current state (distinct from how it started)
|
||||
*/
|
||||
readonly entities: Map<string, Entity> = new Map();
|
||||
readonly locations: Map<string, AttributableObject> = new Map();
|
||||
readonly clock: WorldClock;
|
||||
|
||||
constructor(id?: string, startTime?: Date) {
|
||||
@@ -27,6 +28,19 @@ export class WorldState extends AttributableObject {
|
||||
getEntity(id: string): Entity | undefined {
|
||||
return this.entities.get(id);
|
||||
}
|
||||
|
||||
addLocation(location: AttributableObject): void {
|
||||
if (this.locations.has(location.id)) {
|
||||
throw new Error(
|
||||
`Location with ID ${location.id} already exists in the world`,
|
||||
);
|
||||
}
|
||||
this.locations.set(location.id, location);
|
||||
}
|
||||
|
||||
getLocation(id: string): AttributableObject | undefined {
|
||||
return this.locations.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,6 +57,45 @@ export function serializeObjectiveWorldState(worldState: WorldState): string {
|
||||
lines.push(worldAttrsStr.split("\n").map(l => " " + l).join("\n"));
|
||||
}
|
||||
|
||||
// Serialize locations and their attributes/portals
|
||||
lines.push("Locations:");
|
||||
if (worldState.locations.size > 0) {
|
||||
for (const loc of worldState.locations.values()) {
|
||||
lines.push(` - Location [ID: ${loc.id}]:`);
|
||||
|
||||
const parentId = (loc as { parentId?: string | null }).parentId;
|
||||
if (parentId) {
|
||||
lines.push(` * Parent Location ID: ${parentId}`);
|
||||
}
|
||||
|
||||
if (loc.attributes.size > 0) {
|
||||
const locAttrsStr = serializeAttributes(Array.from(loc.attributes.values()));
|
||||
lines.push(locAttrsStr.split("\n").map(l => " " + l).join("\n"));
|
||||
} else {
|
||||
lines.push(" * (No attributes)");
|
||||
}
|
||||
|
||||
const connections = (loc as { connections?: unknown[] }).connections as {
|
||||
targetId: string;
|
||||
portalName?: string;
|
||||
portalStateDescriptor?: string;
|
||||
visionProp: number;
|
||||
soundProp: number;
|
||||
bidirectional: boolean;
|
||||
}[] | undefined;
|
||||
|
||||
if (connections && connections.length > 0) {
|
||||
lines.push(" * Connections:");
|
||||
for (const conn of connections) {
|
||||
const portalStr = conn.portalName ? ` via ${conn.portalName} (${conn.portalStateDescriptor || "normal"})` : "";
|
||||
lines.push(` -> To: ${conn.targetId}${portalStr} (Vision: ${conn.visionProp}, Sound: ${conn.soundProp})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push(" (No locations)");
|
||||
}
|
||||
|
||||
// Serialize entities and their attributes
|
||||
lines.push("Entities:");
|
||||
if (worldState.entities.size > 0) {
|
||||
@@ -129,6 +182,14 @@ export function serializeSubjectiveWorldState(
|
||||
lines.push("What you perceive around you:");
|
||||
if (viewer.locationId) {
|
||||
lines.push(` You are at location: ${viewer.locationId}`);
|
||||
const location = worldState.getLocation(viewer.locationId);
|
||||
if (location) {
|
||||
const locVisible = location.getVisibleAttributesFor(viewerId);
|
||||
if (locVisible.length > 0) {
|
||||
lines.push(" Location attributes:");
|
||||
lines.push(serializeVisibleAttributes(locVisible).split("\n").map((l) => " " + l).join("\n"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push(" You are not located anywhere in particular.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user