-- Smart Object Radial Menu -- Author: Jeff the Intern -- Reivision -- New Script - 7/03/08 - J.McNab -- Update - 7/30/08 - J.McNab -- CONSTANTS RADIAL_MENU_TOOLTIPS = {} MAX_NUMBER = 8 Define Properties() registered_commands = {} IncludeScript('13197:21') -- ui_library radial_menu = 0 script_description = 'Radial Menu' end -- Triggers Trigger destroyed() if(self.radial_menu ~= 0) then UiDelete(self.radial_menu) end end Trigger attach() SendTo(self, 'radial_menu_registration', 1) end Trigger detach() SendTo(self, 'radial_menu_unregistration', 1) end Trigger select(user, ...) Debug("%s selected %s", user.name, self.name) SendTo(self, 'draw_radial_menu', 10, self, user.id) end Trigger draw_radial_menu(caller, user_id, offset) local user = GetObjectById(user_id) if(IsSuperuser(user) == 0) then return end if(#self.registered_commands <= 0) then return end -- Clear the user UI clear_user_ui(user) if(offset == nil) then offset = 1 end if(self.spriteScaleX > self.spriteScaleY) then size = self.spriteScaleX end if(self.spriteScaleY > self.spriteScaleX) then size = self.spriteScaleY end if(self.spriteScaleX == self.spriteScaleY) then size = self.spriteScaleX end local window_w = 150 local window_h = 150 if(self.spriteOrigin == 1) then offset_y = 0 offset_x = 0 end if(self.spriteOrigin == 2) then offset_y = (self.spriteScaleY * 32)/2 offset_x = 0 end if(self.spriteOrigin == 3) then offset_y = (-self.spriteScaleY * 32)/2 offset_x = (-self.spriteScaleX * 32)/2 end -- Create the window local radial_window = UiElement(0, 'radial_menu_' .. self.name, -window_w/2, -window_h/2) local max = math.min(MAX_NUMBER, #self.registered_commands) local angle = (math.pi * 2)/ MAX_NUMBER local radius = window_w/2 local count = offset local draw_table = {} -- Sort registered Commands table.sort(self.registered_commands, function(a,b) return a.order < b.order end) if(#self.registered_commands > MAX_NUMBER - 1) then if(count + 6 < #self.registered_commands) then next_page = count + 6 else next_page = count end prev_page = math.max(count - 6, 1) index = 1 -- Pull items out for num = count, 5 + count, 1 do table.insert(draw_table, index, self.registered_commands[num]) index = index + 1 end -- Paginate Next Button local command_info = {name = 'Next', command = string.format('/event draw_radial_menu %d %d %d', self.id, user_id, next_page), normal = '13197:129', hover = '13197:128', press = '13197:127', state = 0} Debug(command_info.command) table.insert(draw_table, 1, command_info) -- Paginate Prev Button local command_info = {name = 'Previous', command = string.format('/event draw_radial_menu %d %d %d', self.id, user_id, prev_page), normal = '13197:126', hover = '13197:125', press = '13197:138', state = 0} table.insert(draw_table, 5, command_info) else draw_table = table.deepcopy(self.registered_commands) end local radial_index = 0 for _, action in pairs(draw_table) do local action_x = math.cos(radial_index * angle) * radius + window_w/2 - 16 - offset_x local action_y = math.sin(radial_index * angle) * radius + window_h/2 - 16 - offset_y if(action.state == 0) then command = string.format('/event radial_menu_run_command %d %d \'%s %d\'', self.id, user.id, action.command, user.id) else command = string.format('/event radial_menu_state_command %d %d \'%s %d\'', self.id, user.id, action.command, user.id) end if(action.name ~= 'Next' and action.name ~= 'Previous') then action_btn = UiImageButton(radial_window, 'action_btn_' .. radial_index, action_x, action_y, 32, 32, action.normal, action.hover, action.press, command) else action_btn = UiImageButton(radial_window, 'menu_btn_' .. radial_index, action_x, action_y, 32, 32, action.normal, action.hover, action.press, command) end local tooltip = ui_tooltip(action_btn, action.name, 500, 'above') table.insert(RADIAL_MENU_TOOLTIPS, tooltip) -- local num = UiLabel(action_btn, 'number', 40, 0, radial_index) radial_index = radial_index + 1 end --Attach the Window to the Object for the User user.smart_object_window = radial_window self.radial_menu = radial_window UiAttachUserObject(user, self, user.smart_object_window) end Trigger radial_menu_register(caller, name, command, normal, hover, press, order, state) -- information must be present to continue if(name == nil or command == nil or normal == nil or order == nil) then Debug("Invalid Info") return end -- Command already registered for index, command in pairs(self.registered_commands) do if(name == command.name) then Debug("Command already exists") return end end -- Set command info local command_info = {name = name, command = command, normal = normal, order = order} -- Set a hover state if it exists if(hover ~= nil) then command_info.hover = hover else command_info.hover = normal end -- Set a press state if it exists if(press ~= nil) then command_info.press = press else command_info.press = normal end -- Set the state if(press ~= nil) then command_info.press= press else command_info.press = noraml end if(state ~= nil) then command_info.state = 0 else command_info.state = 1 end command_info.order = order -- update the table table.insert(self.registered_commands, command_info) end Trigger radial_menu_unregister(caller, name) for index, command in pairs(self.registered_commands) do if(command.name == name) then table.remove(self.registered_commands, index) end end end Trigger radial_menu_run_command(caller, user_id, action) local user = get_user(user_id) clear_tooltips(user) radial_menu = 0 SendTo(self, 'radial_menu_state_command', 0, caller, user_id, action) end Trigger radial_menu_state_command(caller, user_id, action) local user = get_user(user_id) local command_elements = string.split(action, ' ') local command = command_elements[1] table.remove(command_elements, 1) DoCommand(user, command, unpack(command_elements)) end -- Functions function clear_user_ui(user) if(user.smart_object_window ~= 0) then UiDelete(user.smart_object_window) user.smart_object_window = 0 end end function clear_tooltips() for id, tooltip in pairs(RADIAL_MENU_TOOLTIPS) do UiDelete(tooltip) RADIAL_MENU_TOOLTIPS[id] = nil end end function get_user(user_id) local w = GetWorld() for _, user in pairs(w.users) do if(user_id == user.id) then return user end end return nil end