package ai import ( "fmt" ) // CustomAI defines a Go-based custom AI behavior interface type CustomAI interface { // Think is called every AI tick for custom behavior Think(npc NPC, target Entity, brain Brain) error // OnCombatStart is called when entering combat OnCombatStart(npc NPC, target Entity, brain Brain) error // OnCombatEnd is called when leaving combat OnCombatEnd(npc NPC, brain Brain) error // OnDamageReceived is called when NPC takes damage OnDamageReceived(npc NPC, attacker Entity, damage int32, brain Brain) error // OnTargetChanged is called when NPC changes target OnTargetChanged(npc NPC, oldTarget, newTarget Entity, brain Brain) error } // CustomBrain allows AI to be controlled by Go-based custom AI implementations type CustomBrain struct { *BaseBrain customAI CustomAI } // NewCustomBrain creates a new custom AI brain func NewCustomBrain(npc NPC, logger Logger, customAI CustomAI) *CustomBrain { brain := &CustomBrain{ BaseBrain: NewBaseBrain(npc, logger), customAI: customAI, } brain.brainType = BrainTypeCustom return brain } // Think calls the custom AI's Think function func (cb *CustomBrain) Think() error { if cb.customAI == nil { // Fall back to default behavior if no custom AI return cb.BaseBrain.Think() } if cb.npc == nil { return fmt.Errorf("brain has no body") } target := cb.npc.GetTarget() err := cb.customAI.Think(cb.npc, target, cb) if err != nil { if cb.logger != nil { cb.logger.LogError("Custom AI Think function failed: %v", err) } return fmt.Errorf("custom AI Think function failed: %w", err) } return nil } // SetCustomAI sets the custom AI implementation func (cb *CustomBrain) SetCustomAI(customAI CustomAI) { cb.customAI = customAI } // GetCustomAI returns the custom AI implementation func (cb *CustomBrain) GetCustomAI() CustomAI { return cb.customAI } // NotifyCombatStart notifies custom AI of combat start func (cb *CustomBrain) NotifyCombatStart(target Entity) { if cb.customAI != nil { if err := cb.customAI.OnCombatStart(cb.npc, target, cb); err != nil && cb.logger != nil { cb.logger.LogError("Custom AI OnCombatStart failed: %v", err) } } } // NotifyCombatEnd notifies custom AI of combat end func (cb *CustomBrain) NotifyCombatEnd() { if cb.customAI != nil { if err := cb.customAI.OnCombatEnd(cb.npc, cb); err != nil && cb.logger != nil { cb.logger.LogError("Custom AI OnCombatEnd failed: %v", err) } } } // NotifyDamageReceived notifies custom AI of damage received func (cb *CustomBrain) NotifyDamageReceived(attacker Entity, damage int32) { if cb.customAI != nil { if err := cb.customAI.OnDamageReceived(cb.npc, attacker, damage, cb); err != nil && cb.logger != nil { cb.logger.LogError("Custom AI OnDamageReceived failed: %v", err) } } } // NotifyTargetChanged notifies custom AI of target change func (cb *CustomBrain) NotifyTargetChanged(oldTarget, newTarget Entity) { if cb.customAI != nil { if err := cb.customAI.OnTargetChanged(cb.npc, oldTarget, newTarget, cb); err != nil && cb.logger != nil { cb.logger.LogError("Custom AI OnTargetChanged failed: %v", err) } } } // Example Custom AI implementations for demonstration // AggressiveAI implements CustomAI for aggressive behavior type AggressiveAI struct{} // Think implements aggressive AI behavior func (a *AggressiveAI) Think(npc NPC, target Entity, brain Brain) error { // Always try to attack if we have a target if target != nil { distance := npc.GetDistance(target) if distance <= 25.0 { // Within range // Force attack more frequently than normal if npc.PrimaryWeaponReady() { npc.MeleeAttack(target, distance, true) } } } // Fall back to base brain behavior for movement, spells, etc. return brain.(*CustomBrain).BaseBrain.Think() } // OnCombatStart implements aggressive combat start func (a *AggressiveAI) OnCombatStart(npc NPC, target Entity, brain Brain) error { // Add extra hate when combat starts if target != nil { brain.AddHate(target.GetID(), DefaultHateValue*2) } return nil } // OnCombatEnd implements aggressive combat end func (a *AggressiveAI) OnCombatEnd(npc NPC, brain Brain) error { // Stay alert longer after combat brain.SetThinkTick(FastThinkTick) return nil } // OnDamageReceived implements aggressive damage response func (a *AggressiveAI) OnDamageReceived(npc NPC, attacker Entity, damage int32, brain Brain) error { // Add extra hate when damaged if attacker != nil { brain.AddHate(attacker.GetID(), damage*2) } return nil } // OnTargetChanged implements aggressive target change func (a *AggressiveAI) OnTargetChanged(npc NPC, oldTarget, newTarget Entity, brain Brain) error { // No special behavior for target changes in aggressive AI return nil } // DefensiveAI implements CustomAI for defensive behavior type DefensiveAI struct { fleeThreshold int32 // HP threshold to flee at } // NewDefensiveAI creates a defensive AI with flee threshold func NewDefensiveAI(fleeThreshold int32) *DefensiveAI { return &DefensiveAI{ fleeThreshold: fleeThreshold, } } // Think implements defensive AI behavior func (d *DefensiveAI) Think(npc NPC, target Entity, brain Brain) error { // Check if we should flee if npc.GetHP() <= d.fleeThreshold { // Try to run back to spawn point if npc.ShouldCallRunback() { npc.Runback(npc.GetRunbackDistance()) } return nil } // Otherwise use normal behavior but with slower think tick brain.SetThinkTick(SlowThinkTick) return brain.(*CustomBrain).BaseBrain.Think() } // OnCombatStart implements defensive combat start func (d *DefensiveAI) OnCombatStart(npc NPC, target Entity, brain Brain) error { // No special behavior for defensive AI return nil } // OnCombatEnd implements defensive combat end func (d *DefensiveAI) OnCombatEnd(npc NPC, brain Brain) error { // Slow down thinking after combat brain.SetThinkTick(SlowThinkTick) return nil } // OnDamageReceived implements defensive damage response func (d *DefensiveAI) OnDamageReceived(npc NPC, attacker Entity, damage int32, brain Brain) error { // Check if we should start fleeing if npc.GetHP() <= d.fleeThreshold && attacker != nil { // Remove hate and try to flee brain.ClearHateForEntity(attacker.GetID()) } return nil } // OnTargetChanged implements defensive target change func (d *DefensiveAI) OnTargetChanged(npc NPC, oldTarget, newTarget Entity, brain Brain) error { // No special behavior for target changes in defensive AI return nil } // CreateAggressiveBrain creates a brain with aggressive AI behavior func CreateAggressiveBrain(npc NPC, logger Logger) Brain { return NewCustomBrain(npc, logger, &AggressiveAI{}) } // CreateDefensiveBrain creates a brain with defensive AI behavior func CreateDefensiveBrain(npc NPC, logger Logger, fleeThreshold int32) Brain { return NewCustomBrain(npc, logger, NewDefensiveAI(fleeThreshold)) }