package languages import ( "fmt" "testing" ) // This file demonstrates how to integrate the languages package with entity systems // ExamplePlayer shows how a Player struct might embed the language adapter type ExamplePlayer struct { id int32 name string characterID int32 languageAdapter *PlayerLanguageAdapter } // NewExamplePlayer creates a new example player with language support func NewExamplePlayer(id int32, name string, languageManager *Manager, logger Logger) *ExamplePlayer { return &ExamplePlayer{ id: id, name: name, characterID: id, // In real implementation, this might be different languageAdapter: NewPlayerLanguageAdapter(languageManager, logger), } } // Implement the Entity interface func (ep *ExamplePlayer) GetID() int32 { return ep.id } func (ep *ExamplePlayer) GetName() string { return ep.name } func (ep *ExamplePlayer) IsPlayer() bool { return true } func (ep *ExamplePlayer) IsNPC() bool { return false } func (ep *ExamplePlayer) IsBot() bool { return false } // Implement the Player interface func (ep *ExamplePlayer) GetCharacterID() int32 { return ep.characterID } func (ep *ExamplePlayer) SendMessage(message string) { // In real implementation, this would send a message to the client } // Implement the LanguageAware interface by delegating to the adapter func (ep *ExamplePlayer) GetKnownLanguages() *PlayerLanguagesList { return ep.languageAdapter.GetKnownLanguages() } func (ep *ExamplePlayer) KnowsLanguage(languageID int32) bool { return ep.languageAdapter.KnowsLanguage(languageID) } func (ep *ExamplePlayer) GetPrimaryLanguage() int32 { return ep.languageAdapter.GetPrimaryLanguage() } func (ep *ExamplePlayer) SetPrimaryLanguage(languageID int32) { ep.languageAdapter.SetPrimaryLanguage(languageID) } func (ep *ExamplePlayer) CanUnderstand(languageID int32) bool { return ep.languageAdapter.CanUnderstand(languageID) } func (ep *ExamplePlayer) LearnLanguage(languageID int32) error { return ep.languageAdapter.LearnLanguage(languageID) } func (ep *ExamplePlayer) ForgetLanguage(languageID int32) error { return ep.languageAdapter.ForgetLanguage(languageID) } // Database integration methods func (ep *ExamplePlayer) LoadLanguagesFromDatabase(database Database) error { return ep.languageAdapter.LoadPlayerLanguages(database, ep.characterID) } func (ep *ExamplePlayer) SaveLanguagesToDatabase(database Database) error { return ep.languageAdapter.SavePlayerLanguages(database, ep.characterID) } // ExampleNPC shows how an NPC might implement basic language interfaces type ExampleNPC struct { id int32 name string knownLanguageIDs []int32 primaryLanguage int32 } func NewExampleNPC(id int32, name string, knownLanguages []int32) *ExampleNPC { primaryLang := int32(LanguageIDCommon) if len(knownLanguages) > 0 { primaryLang = knownLanguages[0] } return &ExampleNPC{ id: id, name: name, knownLanguageIDs: knownLanguages, primaryLanguage: primaryLang, } } // Implement the Entity interface func (en *ExampleNPC) GetID() int32 { return en.id } func (en *ExampleNPC) GetName() string { return en.name } func (en *ExampleNPC) IsPlayer() bool { return false } func (en *ExampleNPC) IsNPC() bool { return true } func (en *ExampleNPC) IsBot() bool { return false } // Implement the Player interface (NPCs can also be treated as players for some language operations) func (en *ExampleNPC) GetCharacterID() int32 { return en.id } func (en *ExampleNPC) SendMessage(message string) { // NPCs don't typically receive messages, but implement for interface compatibility } // Simple language support for NPCs (they don't learn/forget languages) func (en *ExampleNPC) KnowsLanguage(languageID int32) bool { for _, id := range en.knownLanguageIDs { if id == languageID { return true } } return languageID == LanguageIDCommon // NPCs always understand common } func (en *ExampleNPC) GetPrimaryLanguage() int32 { return en.primaryLanguage } func (en *ExampleNPC) CanUnderstand(languageID int32) bool { return en.KnowsLanguage(languageID) } // TestEntityIntegration demonstrates how entities work with the language system func TestEntityIntegration(t *testing.T) { // Set up language system database := NewMockDatabase() logger := NewMockLogger() manager := NewManager(database, logger) // Add some languages languages := []*Language{ createLanguage(LanguageIDCommon, "Common"), createLanguage(LanguageIDElvish, "Elvish"), createLanguage(LanguageIDDwarven, "Dwarven"), createLanguage(LanguageIDOgrish, "Ogrish"), } for _, lang := range languages { manager.AddLanguage(lang) } // Create a player player := NewExamplePlayer(1, "TestPlayer", manager, logger) // Player should know Common language by default if !player.KnowsLanguage(LanguageIDCommon) { t.Error("Player should know Common language by default") } // Test learning a language err := player.LearnLanguage(LanguageIDElvish) if err != nil { t.Fatalf("Failed to learn Elvish: %v", err) } if !player.KnowsLanguage(LanguageIDElvish) { t.Error("Player should know Elvish after learning") } // Test setting primary language player.SetPrimaryLanguage(LanguageIDElvish) if player.GetPrimaryLanguage() != LanguageIDElvish { t.Error("Primary language should be Elvish") } // Test database persistence err = player.SaveLanguagesToDatabase(database) if err != nil { t.Fatalf("Failed to save languages to database: %v", err) } // Create new player and load languages newPlayer := NewExamplePlayer(1, "TestPlayer", manager, logger) err = newPlayer.LoadLanguagesFromDatabase(database) if err != nil { t.Fatalf("Failed to load languages from database: %v", err) } if !newPlayer.KnowsLanguage(LanguageIDElvish) { t.Error("New player should know Elvish after loading from database") } // Create an NPC with specific languages npc := NewExampleNPC(100, "Elven Merchant", []int32{LanguageIDCommon, LanguageIDElvish}) if !npc.KnowsLanguage(LanguageIDElvish) { t.Error("Elven NPC should know Elvish") } if npc.KnowsLanguage(LanguageIDDwarven) { t.Error("Elven NPC should not know Dwarven") } // Test chat processing processor := NewChatLanguageProcessor(manager, logger) // Player speaking in Elvish message := "Mae govannen!" // Elvish greeting processed, err := processor.ProcessMessage(player, message, LanguageIDElvish) if err != nil { t.Fatalf("Failed to process Elvish message: %v", err) } if processed != message { t.Errorf("Expected message '%s', got '%s'", message, processed) } // Test message filtering for understanding filtered := processor.FilterMessage(npc, message, LanguageIDElvish) if filtered != message { t.Errorf("NPC should understand Elvish message, got '%s'", filtered) } } // TestLanguageSystemIntegration demonstrates a complete language system workflow func TestLanguageSystemIntegration(t *testing.T) { // Set up a complete language system database := NewMockDatabase() logger := NewMockLogger() // Create manager and initialize with standard EQ2 languages manager := NewManager(database, logger) eq2Languages := map[int32]string{ LanguageIDCommon: "Common", LanguageIDElvish: "Elvish", LanguageIDDwarven: "Dwarven", LanguageIDHalfling: "Halfling", LanguageIDGnomish: "Gnomish", LanguageIDIksar: "Iksar", LanguageIDTrollish: "Trollish", LanguageIDOgrish: "Ogrish", LanguageIDFae: "Fae", LanguageIDArasai: "Arasai", LanguageIDSarnak: "Sarnak", LanguageIDFroglok: "Froglok", } for id, name := range eq2Languages { lang := createLanguage(id, name) manager.AddLanguage(lang) } if err := manager.Initialize(); err != nil { t.Fatalf("Failed to initialize manager: %v", err) } // Create players of different races (represented by knowing different racial languages) humanPlayer := NewExamplePlayer(1, "Human", manager, logger) elfPlayer := NewExamplePlayer(2, "Elf", manager, logger) dwarfPlayer := NewExamplePlayer(3, "Dwarf", manager, logger) // Elven player learns Elvish at creation (racial language) elfPlayer.LearnLanguage(LanguageIDElvish) elfPlayer.SetPrimaryLanguage(LanguageIDElvish) // Dwarven player learns Dwarven dwarfPlayer.LearnLanguage(LanguageIDDwarven) dwarfPlayer.SetPrimaryLanguage(LanguageIDDwarven) // Test cross-racial communication processor := NewChatLanguageProcessor(manager, logger) // Elf speaks in Elvish elvishMessage := "Elen sila lumenn omentielvo" processed, _ := processor.ProcessMessage(elfPlayer, elvishMessage, LanguageIDElvish) // Human doesn't understand Elvish (would be scrambled in real implementation) humanHeard := processor.FilterMessage(humanPlayer, processed, LanguageIDElvish) _ = humanHeard // In real implementation, this would be scrambled // Dwarf doesn't understand Elvish either dwarfHeard := processor.FilterMessage(dwarfPlayer, processed, LanguageIDElvish) _ = dwarfHeard // In real implementation, this would be scrambled // Everyone understands Common commonMessage := "Hello everyone!" processed, _ = processor.ProcessMessage(humanPlayer, commonMessage, LanguageIDCommon) humanHeardCommon := processor.FilterMessage(humanPlayer, processed, LanguageIDCommon) if humanHeardCommon != commonMessage { t.Error("All players should understand Common") } elfHeardCommon := processor.FilterMessage(elfPlayer, processed, LanguageIDCommon) if elfHeardCommon != commonMessage { t.Error("All players should understand Common") } dwarfHeardCommon := processor.FilterMessage(dwarfPlayer, processed, LanguageIDCommon) if dwarfHeardCommon != commonMessage { t.Error("All players should understand Common") } // Test statistics stats := manager.GetStatistics() if stats.TotalLanguages != len(eq2Languages) { t.Errorf("Expected %d languages, got %d", len(eq2Languages), stats.TotalLanguages) } // Test validation issues := manager.ValidateAllLanguages() if len(issues) > 0 { t.Errorf("Expected no validation issues, got: %v", issues) } } // Helper function to create languages func createLanguage(id int32, name string) *Language { lang := NewLanguage() lang.SetID(id) lang.SetName(name) return lang } // TestLanguageAwareInterface demonstrates the LanguageAware interface usage func TestLanguageAwareInterface(t *testing.T) { database := NewMockDatabase() logger := NewMockLogger() manager := NewManager(database, logger) // Add languages manager.AddLanguage(createLanguage(LanguageIDCommon, "Common")) manager.AddLanguage(createLanguage(LanguageIDElvish, "Elvish")) // Create a player that implements LanguageAware player := NewExamplePlayer(1, "TestPlayer", manager, logger) // Test LanguageAware interface methods var languageAware LanguageAware = player // Should know Common by default if !languageAware.KnowsLanguage(LanguageIDCommon) { t.Error("LanguageAware entity should know Common by default") } // Learn a new language err := languageAware.LearnLanguage(LanguageIDElvish) if err != nil { t.Fatalf("Failed to learn language through LanguageAware interface: %v", err) } // Check understanding if !languageAware.CanUnderstand(LanguageIDElvish) { t.Error("Should understand Elvish after learning") } // Set primary language languageAware.SetPrimaryLanguage(LanguageIDElvish) if languageAware.GetPrimaryLanguage() != LanguageIDElvish { t.Error("Primary language should be Elvish") } // Get known languages knownLanguages := languageAware.GetKnownLanguages() if knownLanguages.Size() != 2 { // Common + Elvish t.Errorf("Expected 2 known languages, got %d", knownLanguages.Size()) } } // Benchmark integration performance func BenchmarkIntegratedPlayerLanguageOperations(b *testing.B) { database := NewMockDatabase() logger := NewMockLogger() manager := NewManager(database, logger) // Add languages for i := 0; i < 50; i++ { lang := createLanguage(int32(i), fmt.Sprintf("Language_%d", i)) manager.AddLanguage(lang) } player := NewExamplePlayer(1, "BenchmarkPlayer", manager, logger) b.ResetTimer() for i := 0; i < b.N; i++ { langID := int32(i % 50) if !player.KnowsLanguage(langID) { player.LearnLanguage(langID) } player.CanUnderstand(langID) } }