src/player-intel.ts
import hivemind from 'hivemind';
import {getRoomIntel} from 'room-intel';
type CreepIntel = {
body: Partial<Record<BodyPartConstant, number>>;
boosts?: Partial<Record<ResourceConstant, number>>;
pos: {
x: number;
y: number;
roomName: string;
};
lastSeen: number;
expires: number;
};
export type PlayerIntelMemory = {
lastSeen: number;
creeps: Record<Id<Creep>, CreepIntel>;
rooms: Record<string, number>;
remotes: Record<string, number>;
lastCleanup?: number;
};
const CLEANUP_INTERVAL = 120;
export default class PlayerIntel {
protected memory: PlayerIntelMemory;
protected readonly memoryKey: string;
constructor(readonly userName: string) {
this.memoryKey = 'u-intel:' + userName;
if (!this.hasMemory()) {
this.setMemory({
lastSeen: Game.time,
creeps: {},
rooms: {},
remotes: {},
});
}
this.memory = this.getMemory();
if (!this.memory.lastCleanup || Game.time - this.memory.lastCleanup > CLEANUP_INTERVAL) {
this.cleanupMemory();
}
}
hasMemory() {
return hivemind.segmentMemory.has(this.memoryKey);
}
setMemory(memory: PlayerIntelMemory) {
hivemind.segmentMemory.set(this.memoryKey, memory);
}
getMemory(): PlayerIntelMemory {
return hivemind.segmentMemory.get(this.memoryKey);
}
cleanupMemory() {
for (const roomName in this.memory.rooms) {
const roomIntel = getRoomIntel(roomName);
if (!roomIntel || roomIntel.getOwner() !== this.userName) {
delete this.memory.rooms[roomName];
}
}
for (const roomName in this.memory.remotes) {
if (Game.time - this.memory.remotes[roomName] > CREEP_LIFE_TIME) {
delete this.memory.remotes[roomName];
}
}
for (const id in this.memory.creeps) {
const creepIntel = this.memory.creeps[id];
// @todo Also delete creeps we can be sure have died. We could check
// tombstones, for example.
if (Game.time > creepIntel.expires) delete this.memory.creeps[id];
}
}
isNpc(): boolean {
return this.userName === SYSTEM_USERNAME || this.userName === 'Invader';
}
getAllOwnedRooms(): string[] {
return _.keys(this.memory.rooms);
}
updateOwnedRoom(roomName: string) {
this.memory.rooms[roomName] = Game.time;
}
getAllRemotes(): string[] {
return _.keys(this.memory.remotes);
}
updateRemote(roomName: string) {
this.memory.remotes[roomName] = Game.time;
}
updateCreeps(creeps: Creep[]) {
if (!this.memory.creeps) this.memory.creeps = {};
for (const creep of creeps) {
if (!this.memory.creeps[creep.id]) {
// Record some info about this creep.
this.memory.creeps[creep.id] = {
body: _.countBy(creep.body, 'type'),
boosts: _.countBy(creep.body, 'boost'),
pos: null,
lastSeen: Game.time,
expires: Game.time + creep.ticksToLive,
};
}
// Update some information.
const creepIntel = this.memory.creeps[creep.id];
creepIntel.lastSeen = Game.time;
const {x, y, roomName} = creep.pos;
creepIntel.pos = {x, y, roomName};
}
}
}