AstroCol/src/lib/classes/managers/abstract/ResourceManager.ts

97 lines
3.3 KiB
TypeScript

import DBResource from "../../../../types/db/DBResource";
export type Resource = {
id: string,
amount: number,
lastUpdated: Date | null,
data: DBResource
}
export default abstract class ResourceManager {
resources: Resource[] = [];
resourcesDB: DBResource[] = [];
abstract sync(): Promise<void>;
abstract getPerHourMiningRate(): { id: string, rate: number }[];
abstract getStorageCapacities(): { id: string, capacity: number }[];
getResourceById(resId: string) {
return this.resources.find(res => res.id === resId);
}
async calculateCurrentAvailableResources() {
const storage = this.getStorageCapacities();
const miningRates = this.getPerHourMiningRate();
for(const res of this.resources) {
if(!res.lastUpdated) continue;
const miningRate = miningRates.find(r => r.id === res.id)?.rate ?? 0;
const maxStorage = 10_000 + (storage.find(s => s.id === res.id)?.capacity ?? 0);
const timeDiff = Math.abs((new Date()).getTime() - res.lastUpdated.getTime());
const hours = timeDiff / (1000 * 60 * 60);
let amountToAdd = hours * miningRate;
if(res.amount + amountToAdd > maxStorage) amountToAdd = Math.max(0, maxStorage - res.amount);
res.amount += amountToAdd;
res.lastUpdated = new Date();
};
await this.sync();
return this.resources;
}
async getDifference(resources: { id: string, amount: number }[]): Promise<Array<Resource>> {
const currentResources = await this.calculateCurrentAvailableResources();
const difference: Resource[] = [];
currentResources.forEach(res => {
const currentRes = resources.find(r => r.id === res.id);
if(currentRes) difference.push({
id: res.id,
amount: res.amount - currentRes.amount,
lastUpdated: res.lastUpdated,
data: res.data
});
else difference.push(res);
});
return difference;
}
add(resources: Resource[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
else this.resources.push(res);
}
}
async updateAmount(resources: { id: string, amount: number }[]) {
await this.calculateCurrentAvailableResources();
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
else this.resources.push({
id: res.id,
amount: res.amount,
lastUpdated: new Date(),
data: this.resourcesDB.find(r => r.id === res.id) as DBResource
});
}
}
setAmount(resources: { id: string, amount: number }[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount = res.amount;
else this.resources.push({
id: res.id,
amount: res.amount,
lastUpdated: new Date(),
data: this.resourcesDB.find(r => r.id === res.id) as DBResource
});
}
}
}