Enhance NPC behavior: implement home return functionality for stationary NPCs when pushed away from their starting position

This commit is contained in:
Z. Cliffe Schreuders
2025-11-23 01:27:20 +00:00
parent 279cc0125d
commit 98104b59a8
2 changed files with 81 additions and 5 deletions

View File

@@ -2717,15 +2717,20 @@ function createNPCSpritesForRoom(roomId, roomData) {
// Set up NPC-to-NPC collisions with all other NPCs in this room
NPCSpriteManager.setupNPCToNPCCollisions(gameRef, sprite, roomId, roomData.npcSprites);
// Register behavior if configured
// Only for sprite-based NPCs (not phone-only)
if (window.npcBehaviorManager && npc.behavior) {
// Register behavior for all sprite-based NPCs
// Even NPCs without explicit behavior get registered to enable
// home return behavior when pushed by player
if (window.npcBehaviorManager) {
window.npcBehaviorManager.registerBehavior(
npc.id,
sprite,
npc.behavior
npc.behavior || {} // Use empty config if no behavior specified
);
console.log(`🤖 Behavior registered for ${npc.id}`);
if (npc.behavior) {
console.log(`🤖 Behavior registered for ${npc.id}`);
} else {
console.log(`🏠 Default behavior (home return) registered for ${npc.id}`);
}
}
console.log(`✅ NPC sprite created: ${npc.id} in room ${roomId}`);

View File

@@ -172,6 +172,13 @@ class NPCBehavior {
this.lastAnimationKey = null;
this.isMoving = false;
// Home position tracking for stationary NPCs
// When stationary NPCs are pushed away from their starting position,
// they will automatically return home
this.homePosition = { x: this.sprite.x, y: this.sprite.y };
this.homeReturnThreshold = 32; // Distance in pixels before returning home
this.returningHome = false;
// Apply initial hostile visual if needed
if (this.hostile) {
this.setHostile(true);
@@ -447,6 +454,9 @@ class NPCBehavior {
return;
}
// Check if NPC has been pushed from home position (for stationary NPCs)
this.checkAndHandleHomePush();
// Main behavior update logic
// 1. Determine highest priority state
const state = this.determineState(playerPos);
@@ -1086,6 +1096,67 @@ class NPCBehavior {
this.sprite.setDepth(depth);
}
/**
* Check if NPC has been pushed away from home and trigger return if needed
* For stationary NPCs (no patrol configured), automatically return home if pushed
* Returns true if NPC should be in return-home mode
*/
checkAndHandleHomePush() {
// Only apply to stationary NPCs (no patrol configured originally)
if (this.config.patrol.enabled && !this.returningHome) {
return false; // Already has patrol behavior
}
const distanceFromHome = Math.sqrt(
Math.pow(this.sprite.x - this.homePosition.x, 2) +
Math.pow(this.sprite.y - this.homePosition.y, 2)
);
// If we're already returning home, check if we've arrived
if (this.returningHome) {
if (distanceFromHome < 8) {
// Arrived home! Disable patrol and return to normal behavior
console.log(`🏠 [${this.npcId}] Arrived home, resuming normal behavior`);
this.returningHome = false;
this.config.patrol.enabled = false;
this.patrolTarget = null;
this.currentPath = [];
this.pathIndex = 0;
return false;
}
return true; // Still returning
}
// Check if pushed beyond threshold
if (distanceFromHome > this.homeReturnThreshold) {
// NPC has been pushed away! Enable temporary patrol mode to return home
console.log(`🔄 [${this.npcId}] Pushed ${distanceFromHome.toFixed(0)}px from home, returning...`);
this.returningHome = true;
this.config.patrol.enabled = true;
// Set home as a single waypoint
this.config.patrol.waypoints = [{
tileX: Math.floor(this.homePosition.x / TILE_SIZE),
tileY: Math.floor(this.homePosition.y / TILE_SIZE),
worldX: this.homePosition.x,
worldY: this.homePosition.y,
dwellTime: 0
}];
this.config.patrol.waypointMode = 'sequential';
this.config.patrol.waypointIndex = 0;
// Clear any existing patrol state to force re-pathing
this.patrolTarget = null;
this.currentPath = [];
this.pathIndex = 0;
this.lastPatrolChange = 0;
return true;
}
return false;
}
setState(property, value) {
switch (property) {
case 'hostile':