package widget import ( "eq2emu/internal/spawn" ) // ClientInterface represents the minimal client interface needed by widgets type ClientInterface interface { GetPlayer() *spawn.Spawn SetTemporaryTransportID(id int32) ProcessTeleport(widget *Widget, destinations []any, transporterID int32) GetVersion() int32 GetCurrentZone() ZoneInterface } // ZoneInterface represents the minimal zone interface needed by widgets type ZoneInterface interface { HasWidgetTimer(widget *Widget) bool AddWidgetTimer(widget *Widget, duration float32) SendSpawnChanges(s *spawn.Spawn) PlaySoundFile(unknown int32, soundFile string, x, y, z float32) CallSpawnScript(s *spawn.Spawn, scriptType string, caller *spawn.Spawn, extra string, state bool) bool GetSpawnByDatabaseID(id int32) *spawn.Spawn GetTransporters(client ClientInterface, transporterID int32) []any ProcessEntityCommand(command any, player *spawn.Spawn, target *spawn.Spawn) GetInstanceID() int32 GetInstanceType() int32 SendHouseItems(client ClientInterface) } // WidgetSpawn provides integration between Widget and Spawn systems type WidgetSpawn struct { *spawn.Spawn *Widget } // NewWidgetSpawn creates a new widget spawn wrapper func NewWidgetSpawn() *WidgetSpawn { widget := NewWidget() return &WidgetSpawn{ Spawn: widget.Spawn, Widget: widget, } } // IsWidget returns true for widget spawns func (ws *WidgetSpawn) IsWidget() bool { return true } // Copy creates a copy of the widget spawn func (ws *WidgetSpawn) Copy() *WidgetSpawn { newWidget := ws.Widget.Copy() return &WidgetSpawn{ Spawn: newWidget.Spawn, Widget: newWidget, } } // WidgetManager interface for managing widgets in a zone type WidgetManager interface { AddWidget(widget *Widget) RemoveWidget(widgetID int32) GetWidget(widgetID int32) *Widget GetWidgetByDatabaseID(databaseID int32) *Widget GetAllWidgets() []*Widget ProcessWidgetTimers() } // WidgetTimer represents a timer for widget actions type WidgetTimer struct { Widget *Widget Duration float32 Callback func(*Widget) } // WidgetState represents the current state of a widget type WidgetState struct { IsOpen bool X float32 Y float32 Z float32 Heading float32 ActivityStatus int32 } // GetState returns the current state of the widget func (w *Widget) GetState() WidgetState { w.mutex.RLock() defer w.mutex.RUnlock() return WidgetState{ IsOpen: w.isOpen, X: w.GetX(), Y: w.GetY(), Z: w.GetZ(), Heading: w.GetHeading(), ActivityStatus: w.GetActivityStatus(), } } // RestoreState restores the widget to a previous state func (w *Widget) RestoreState(state WidgetState) { w.mutex.Lock() defer w.mutex.Unlock() w.isOpen = state.IsOpen w.SetX(state.X) w.SetY(state.Y, false) w.SetZ(state.Z) w.SetHeadingFromFloat(state.Heading) w.SetActivityStatus(state.ActivityStatus) }