package sign import "eq2emu/internal/spawn" // Player interface for sign interactions type Player interface { GetDistance(target *spawn.Spawn) float32 SetX(x float32) SetY(y float32) SetZ(z float32) SetHeading(heading float32) GetZone() Zone GetTarget() *spawn.Spawn } // Client interface for sign interactions type Client interface { GetPlayer() Player GetCharacterID() int32 GetDatabase() Database GetCurrentZone() Zone SetTemporaryTransportID(id int32) SimpleMessage(channel int32, message string) Message(channel int32, format string, args ...interface{}) CheckZoneAccess(zoneName string) bool TryZoneInstance(zoneID int32, useDefaults bool) bool Zone(zoneName string, useDefaults bool) error ProcessTeleport(sign *Sign, destinations []TransportDestination, transporterID int32) error } // Zone interface for sign interactions type Zone interface { GetTransporters(client Client, transporterID int32) ([]TransportDestination, error) ProcessEntityCommand(command *EntityCommand, player Player, target *spawn.Spawn) error } // Database interface for sign persistence type Database interface { GetZoneName(zoneID int32) (string, error) GetCharacterName(charID int32) (string, error) SaveSignMark(charID int32, widgetID int32, charName string, client Client) error LoadSigns(zoneID int32) ([]*Sign, error) SaveSign(sign *Sign) error DeleteSign(signID int32) error } // TransportDestination represents a transport destination type TransportDestination struct { ID int32 Name string Description string ZoneID int32 X float32 Y float32 Z float32 Heading float32 } // EntityCommand represents a command that can be executed on an entity type EntityCommand struct { ID int32 Command string Name string Description string } // Logger interface for sign logging type Logger interface { LogInfo(message string, args ...interface{}) LogError(message string, args ...interface{}) LogDebug(message string, args ...interface{}) LogWarning(message string, args ...interface{}) } // SignSpawn provides sign functionality for spawn entities type SignSpawn struct { *spawn.Spawn *Sign } // NewSignSpawn creates a new sign spawn wrapper func NewSignSpawn(baseSpawn *spawn.Spawn) *SignSpawn { sign := NewSign() sign.Spawn = baseSpawn return &SignSpawn{ Spawn: baseSpawn, Sign: sign, } } // IsSign returns true since this is a sign func (ss *SignSpawn) IsSign() bool { return true } // HandleUse delegates to the sign's HandleUse method func (ss *SignSpawn) HandleUse(client Client, command string) error { return ss.Sign.HandleUse(client, command) } // Copy creates a copy of the sign spawn func (ss *SignSpawn) Copy() *SignSpawn { newSign := ss.Sign.Copy() newSpawn := ss.Spawn.Copy() return &SignSpawn{ Spawn: newSpawn, Sign: newSign, } } // SignAware interface for entities that can interact with signs type SignAware interface { GetSign() *Sign IsSign() bool HandleSignUse(client Client, command string) error } // SignAdapter provides sign functionality for any entity type SignAdapter struct { entity Entity sign *Sign logger Logger } // Entity interface for things that can have sign functionality type Entity interface { GetID() int32 GetName() string GetDatabaseID() int32 } // NewSignAdapter creates a new sign adapter func NewSignAdapter(entity Entity, logger Logger) *SignAdapter { return &SignAdapter{ entity: entity, sign: NewSign(), logger: logger, } } // GetSign returns the sign func (sa *SignAdapter) GetSign() *Sign { return sa.sign } // IsSign returns true since this has sign functionality func (sa *SignAdapter) IsSign() bool { return true } // HandleSignUse handles sign usage func (sa *SignAdapter) HandleSignUse(client Client, command string) error { if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Handling sign use with command '%s'", sa.entity.GetID(), sa.entity.GetName(), command) } return sa.sign.HandleUse(client, command) } // SetSignTitle sets the sign title func (sa *SignAdapter) SetSignTitle(title string) { sa.sign.SetSignTitle(title) if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Set sign title to '%s'", sa.entity.GetID(), sa.entity.GetName(), title) } } // SetSignDescription sets the sign description func (sa *SignAdapter) SetSignDescription(description string) { sa.sign.SetSignDescription(description) if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Set sign description", sa.entity.GetID(), sa.entity.GetName()) } } // SetSignType sets the sign type func (sa *SignAdapter) SetSignType(signType int8) { sa.sign.SetSignType(signType) if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Set sign type to %d", sa.entity.GetID(), sa.entity.GetName(), signType) } } // SetZoneTransport configures the sign for zone transport func (sa *SignAdapter) SetZoneTransport(zoneID int32, x, y, z, heading float32) { sa.sign.SetSignType(SignTypeZone) sa.sign.SetSignZoneID(zoneID) sa.sign.SetSignZoneX(x) sa.sign.SetSignZoneY(y) sa.sign.SetSignZoneZ(z) sa.sign.SetSignZoneHeading(heading) if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Configured zone transport to zone %d at (%.2f, %.2f, %.2f)", sa.entity.GetID(), sa.entity.GetName(), zoneID, x, y, z) } } // SetSignDistance sets the interaction distance func (sa *SignAdapter) SetSignDistance(distance float32) { sa.sign.SetSignDistance(distance) if sa.logger != nil { sa.logger.LogDebug("Entity %d (%s): Set sign distance to %.2f", sa.entity.GetID(), sa.entity.GetName(), distance) } } // Validate validates the sign configuration func (sa *SignAdapter) Validate() []string { return sa.sign.Validate() } // IsValid returns true if the sign is valid func (sa *SignAdapter) IsValid() bool { return sa.sign.IsValid() }