Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/NPCSettlementSystem.js
2026-01-16 02:43:46 +01:00

342 lines
11 KiB
JavaScript

/**
* NPC SETTLEMENT SYSTEM (Magic Helpers)
* NPCs auto-assist with tasks
* Worker efficiency, happiness, housing
*/
export class NPCSettlementSystem {
constructor(scene) {
this.scene = scene;
// Settled NPCs
this.settledNPCs = new Map();
// Worker assignments
this.assignments = new Map(); // npcId → task
// NPC stats
this.npcHappiness = new Map(); // npcId → happiness (0-100)
this.npcEfficiency = new Map(); // npcId → efficiency (0.5-2.0)
// Housing
this.npcHomes = new Map(); // npcId → buildingId
this.housingCapacity = 0;
// Task types
this.taskTypes = ['farming', 'building', 'crafting', 'defense', 'gathering'];
this.init();
}
init() {
// Update worker tasks periodically
this.scene.time.addEvent({
delay: 5000, // Every 5s
callback: () => this.updateWorkers(),
loop: true
});
// Update happiness hourly
this.scene.time.addEvent({
delay: 3600000, // 1 hour
callback: () => this.updateHappiness(),
loop: true
});
}
/**
* Settle an NPC (they join the town)
*/
settleNPC(npcId, npcData) {
if (this.settledNPCs.has(npcId)) return false;
//Check housing availability
if (this.settledNPCs.size >= this.housingCapacity) {
console.warn('No housing available');
return false;
}
this.settledNPCs.set(npcId, {
id: npcId,
name: npcData.name,
skills: npcData.skills || [],
assignedTask: null,
...npcData
});
// Initial stats
this.npcHappiness.set(npcId, 75); // Start at 75% happiness
this.npcEfficiency.set(npcId, 1.0); // Base efficiency
// Notification
this.scene.uiSystem?.showNotification(
`${npcData.name} has joined the settlement!`,
'success',
{ icon: 'npc_join' }
);
console.log(`🏘️ ${npcData.name} settled in town`);
return true;
}
/**
* Assign NPC to task
*/
assignTask(npcId, taskType, taskData) {
const npc = this.settledNPCs.get(npcId);
if (!npc) return false;
// Check if NPC has skill for task
if (!npc.skills.includes(taskType)) {
console.warn(`${npc.name} lacks skill: ${taskType}`);
return false;
}
// Assign
npc.assignedTask = taskType;
this.assignments.set(npcId, {
type: taskType,
data: taskData,
startTime: Date.now()
});
console.log(`👷 ${npc.name} assigned to ${taskType}`);
return true;
}
/**
* Unassign NPC from task
*/
unassignTask(npcId) {
const npc = this.settledNPCs.get(npcId);
if (!npc) return false;
npc.assignedTask = null;
this.assignments.delete(npcId);
console.log(`${npc.name} unassigned`);
return true;
}
/**
* Update all worker tasks
*/
updateWorkers() {
this.assignments.forEach((assignment, npcId) => {
const npc = this.settledNPCs.get(npcId);
const efficiency = this.npcEfficiency.get(npcId) || 1.0;
switch (assignment.type) {
case 'farming':
this.performFarming(npc, efficiency, assignment.data);
break;
case 'building':
this.performBuilding(npc, efficiency, assignment.data);
break;
case 'crafting':
this.performCrafting(npc, efficiency, assignment.data);
break;
case 'defense':
this.performDefense(npc, efficiency);
break;
case 'gathering':
this.performGathering(npc, efficiency);
break;
}
});
}
/**
* WORKER TASKS
*/
performFarming(npc, efficiency, data) {
// Auto-tend crops
const crops = this.scene.crops || [];
const tendsPerCycle = Math.floor(2 * efficiency);
for (let i = 0; i < tendsPerCycle && i < crops.length; i++) {
const crop = crops[i];
crop.water?.();
crop.fertilize?.();
}
// Chance to auto-harvest
if (Math.random() < 0.1 * efficiency) {
const harvestable = crops.find(c => c.isHarvestable);
if (harvestable) {
this.scene.farmingSystem?.harvestCrop(harvestable);
console.log(`${npc.name} harvested crop`);
}
}
}
performBuilding(npc, efficiency, data) {
// Speed up construction
const building = data.buildingId ? this.scene.buildingSystem?.getBuilding(data.buildingId) : null;
if (building && building.isUnderConstruction) {
const progressBonus = 5 * efficiency;
building.constructionProgress += progressBonus;
if (building.constructionProgress >= 100) {
this.scene.buildingSystem?.completeConstruction(building.id);
console.log(`${npc.name} completed building: ${building.name}`);
}
}
}
performCrafting(npc, efficiency, data) {
// Auto-craft items
if (data.recipe) {
const canCraft = this.scene.craftingSystem?.canCraft(data.recipe);
if (canCraft && Math.random() < 0.2 * efficiency) {
this.scene.craftingSystem?.craft(data.recipe);
console.log(`${npc.name} crafted ${data.recipe}`);
}
}
}
performDefense(npc, efficiency) {
// Patrol and defend
// Increased detection range for raids
this.scene.gameState.buffs.raid_detection_range = (this.scene.gameState.buffs.raid_detection_range || 1.0) + (0.1 * efficiency);
// Auto-repair walls/defenses
const defenses = this.scene.defenseSystem?.getAllDefenses() || [];
defenses.forEach(defense => {
if (defense.health < defense.maxHealth && Math.random() < 0.05 * efficiency) {
defense.health = Math.min(defense.maxHealth, defense.health + 10);
console.log(`${npc.name} repaired ${defense.name}`);
}
});
}
performGathering(npc, efficiency) {
// Auto-gather resources
const gatherChance = 0.15 * efficiency;
if (Math.random() < gatherChance) {
const resources = ['wood', 'stone', 'berries', 'herbs'];
const resource = Phaser.Utils.Array.GetRandom(resources);
const amount = Math.floor(Phaser.Math.Between(1, 3) * efficiency);
this.scene.inventorySystem?.addItem(resource, amount);
console.log(`${npc.name} gathered ${amount} ${resource}`);
}
}
/**
* Update NPC happiness
*/
updateHappiness() {
this.settledNPCs.forEach((npc, npcId) => {
let happiness = this.npcHappiness.get(npcId) || 50;
// Factors affecting happiness
const hasHome = this.npcHomes.has(npcId);
const hasTask = npc.assignedTask !== null;
const isOverworked = hasTask && this.assignments.get(npcId)?.overworked;
// Adjustments
if (hasHome) happiness += 5;
if (hasTask) happiness += 2;
if (isOverworked) happiness -= 10;
if (!hasHome && this.settledNPCs.size > this.housingCapacity) happiness -= 15;
// Natural decay
happiness -= 1;
// Clamp
happiness = Math.max(0, Math.min(100, happiness));
this.npcHappiness.set(npcId, happiness);
// Update efficiency based on happiness
const efficiency = 0.5 + (happiness / 100) * 1.5; // 0.5-2.0
this.npcEfficiency.set(npcId, efficiency);
// Low happiness warning
if (happiness < 30) {
this.scene.uiSystem?.showNotification(
`${npc.name} is unhappy!`,
'warning'
);
console.warn(`${npc.name} happiness: ${happiness}`);
}
});
}
/**
* Assign NPC to home
*/
assignHome(npcId, buildingId) {
this.npcHomes.set(npcId, buildingId);
// Happiness boost
const happiness = this.npcHappiness.get(npcId) || 50;
this.npcHappiness.set(npcId, Math.min(100, happiness + 20));
console.log(`${this.settledNPCs.get(npcId).name} moved into home`);
}
/**
* Increase housing capacity
*/
addHousing(capacity) {
this.housingCapacity += capacity;
console.log(`Housing capacity: ${this.housingCapacity}`);
}
/**
* Get settlement statistics
*/
getSettlementStats() {
const npcs = Array.from(this.settledNPCs.values());
const avgHappiness = npcs.reduce((sum, npc) => sum + (this.npcHappiness.get(npc.id) || 0), 0) / npcs.length || 0;
const avgEfficiency = npcs.reduce((sum, npc) => sum + (this.npcEfficiency.get(npc.id) || 1), 0) / npcs.length || 1;
return {
population: npcs.length,
housingCapacity: this.housingCapacity,
averageHappiness: Math.round(avgHappiness),
averageEfficiency: avgEfficiency.toFixed(2),
assignedWorkers: this.assignments.size,
unemployed: npcs.length - this.assignments.size
};
}
/**
* Get NPCs by skill
*/
getNPCsBySkill(skill) {
return Array.from(this.settledNPCs.values()).filter(npc => npc.skills.includes(skill));
}
/**
* Save/Load
*/
getSaveData() {
return {
settledNPCs: Array.from(this.settledNPCs.entries()),
assignments: Array.from(this.assignments.entries()),
npcHappiness: Array.from(this.npcHappiness.entries()),
npcHomes: Array.from(this.npcHomes.entries()),
housingCapacity: this.housingCapacity
};
}
loadSaveData(data) {
this.settledNPCs = new Map(data.settledNPCs || []);
this.assignments = new Map(data.assignments || []);
this.npcHappiness = new Map(data.npcHappiness || []);
this.npcHomes = new Map(data.npcHomes || []);
this.housingCapacity = data.housingCapacity || 0;
// Recalculate efficiency
this.npcHappiness.forEach((happiness, npcId) => {
const efficiency = 0.5 + (happiness / 100) * 1.5;
this.npcEfficiency.set(npcId, efficiency);
});
}
}