eq2go/internal/sign/interfaces.go
2025-08-06 12:31:24 -05:00

242 lines
6.2 KiB
Go

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 ...any)
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 ...any)
LogError(message string, args ...any)
LogDebug(message string, args ...any)
LogWarning(message string, args ...any)
}
// 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()
// TODO: Enable when spawn.Copy() method is implemented
// newSpawn := ss.Spawn.Copy()
// For now, create a new spawn and copy basic properties
newSpawn := spawn.NewSpawn()
if ss.Spawn != nil {
newSpawn.SetDatabaseID(ss.Spawn.GetDatabaseID())
newSpawn.SetName(ss.Spawn.GetName())
newSpawn.SetLevel(ss.Spawn.GetLevel())
newSpawn.SetX(ss.Spawn.GetX())
newSpawn.SetY(ss.Spawn.GetY(), false)
newSpawn.SetZ(ss.Spawn.GetZ())
newSpawn.SetSpawnType(ss.Spawn.GetSpawnType())
newSpawn.SetFactionID(ss.Spawn.GetFactionID())
newSpawn.SetSize(ss.Spawn.GetSize())
}
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()
}