392 lines
12 KiB
Go
392 lines
12 KiB
Go
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)
|
|
}
|
|
} |