Fix craft parsing, sustained combat, combat cooldown
- Craft regex now captures only 1-2 words (not entire sentence) - Mine regex same fix - Combat is now sustained: bridge keeps attacking every 500ms until target dies, leaves range, or 10s timeout - Combat has 12-second cooldown to prevent spam - Bot chases target if too far for melee during combat Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3832094a5c
commit
9c7ae89dd2
3 changed files with 56 additions and 8 deletions
|
|
@ -583,8 +583,50 @@ async function handleAction(action, params = {}) {
|
|||
if (hostiles.length === 0) return { attacked: false, reason: 'no_hostiles' };
|
||||
hostiles.sort((a, b) => a.dist - b.dist);
|
||||
const target = hostiles[0].entity;
|
||||
bot.attack(target);
|
||||
return { attacked: true, target: target.name || target.type, distance: hostiles[0].dist };
|
||||
|
||||
// Sustained combat: keep attacking until target is dead or out of range
|
||||
let hits = 0;
|
||||
const maxHits = 20;
|
||||
const combatPromise = new Promise((resolve) => {
|
||||
const attackInterval = setInterval(() => {
|
||||
// Check if target is still alive and in range
|
||||
const ent = bot.entities[target.id];
|
||||
if (!ent || !ent.position) {
|
||||
clearInterval(attackInterval);
|
||||
resolve({ attacked: true, hits, result: 'target_gone' });
|
||||
return;
|
||||
}
|
||||
const d = ent.position.distanceTo(bot.entity.position);
|
||||
if (d > range + 2) {
|
||||
clearInterval(attackInterval);
|
||||
resolve({ attacked: true, hits, result: 'out_of_range' });
|
||||
return;
|
||||
}
|
||||
if (hits >= maxHits) {
|
||||
clearInterval(attackInterval);
|
||||
resolve({ attacked: true, hits, result: 'max_hits' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Look at target and attack
|
||||
bot.lookAt(ent.position.offset(0, ent.height * 0.8, 0)).then(() => {
|
||||
try { bot.attack(ent); hits++; } catch (e) {}
|
||||
});
|
||||
|
||||
// Move toward target if too far for melee
|
||||
if (d > 3) {
|
||||
bot.pathfinder.setGoal(new GoalNear(ent.position.x, ent.position.y, ent.position.z, 2));
|
||||
}
|
||||
}, 500); // Attack every 500ms
|
||||
|
||||
// Safety timeout
|
||||
setTimeout(() => {
|
||||
clearInterval(attackInterval);
|
||||
resolve({ attacked: true, hits, result: 'timeout' });
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
return await combatPromise;
|
||||
}
|
||||
|
||||
// --- Crafting ---
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class BehaviorEngine:
|
|||
self._last_scan_time = 0.0
|
||||
self._last_chat_time = 0.0
|
||||
self._last_wander_time = 0.0
|
||||
self._last_combat_time = 0.0
|
||||
self._explored_positions: list[dict] = [] # Places we've been
|
||||
self._known_containers: list[dict] = [] # Containers we've found
|
||||
self._relationships: dict[str, float] = {} # Player name → fondness (-1 to 1)
|
||||
|
|
@ -215,19 +216,24 @@ class BehaviorEngine:
|
|||
if bravery < 30:
|
||||
return None # Too scared to fight
|
||||
|
||||
# Cooldown — don't spam combat tasks
|
||||
if time.time() - self._last_combat_time < 12:
|
||||
return None
|
||||
|
||||
# Find attackable hostile within melee range
|
||||
for hostile in self.nearby_hostiles:
|
||||
dist = hostile.get("distance", 99)
|
||||
if dist < 4 and self.health > 8:
|
||||
if dist < 5 and self.health > 8:
|
||||
# Brave Dougs attack, others might not
|
||||
if bravery > 60 or (bravery > 40 and self.health > 14):
|
||||
self._last_combat_time = time.time()
|
||||
return Task(
|
||||
name=f"attack_{hostile['type']}",
|
||||
name="combat",
|
||||
priority=Priority.HIGH,
|
||||
action="attack_nearest_hostile",
|
||||
params={"range": 5},
|
||||
params={"range": 6},
|
||||
description=f"Fighting a {hostile['type']}!",
|
||||
timeout=10,
|
||||
timeout=15,
|
||||
)
|
||||
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ class CommandParser:
|
|||
]
|
||||
|
||||
CRAFT_PATTERNS = [
|
||||
r"(?:craft|make|build|create)\s+(?:a\s+|an\s+|some\s+)?(.+)",
|
||||
r"(?:craft|make|build|create)\s+(?:a\s+|an\s+|some\s+|me\s+)?(\w+(?:\s+\w+)?)",
|
||||
]
|
||||
|
||||
MINE_PATTERNS = [
|
||||
r"(?:mine|dig|break|destroy)\s+(?:that|this|the)?\s*(.+)",
|
||||
r"(?:mine|dig|break|destroy)\s+(?:that|this|the|some)?\s*(\w+(?:\s+\w+)?)",
|
||||
]
|
||||
|
||||
GIVE_PATTERNS = [
|
||||
|
|
|
|||
Loading…
Reference in a new issue