--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local PANEL = {} local PLUGIN = PLUGIN ICON_RENDER_QUEUE = ICON_RENDER_QUEUE or {} local s100 = SScaleMin(100 / 3) local s10 = SScaleMin(10 / 3) local s800 = SScaleMin(800 / 3) function PANEL:Init() self:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) self:MakePopup() self:Center() self:SetTitle("Créateur de vêtements Willard") DFrameFixer(self) self:CreateBaseSelector() end local function PaintButton(self, w, h, noAlpha) surface.SetDrawColor(Color(0, 0, 0, noAlpha and 255 or 100)) surface.DrawRect(0, 0, w, h) surface.SetDrawColor(Color(111, 111, 136, noAlpha and 255 or (255 / 100 * 30))) surface.DrawOutlinedRect(0, 0, w, h) end function PANEL:CreateBaseSelector() self.baseSelectorPanel = self:Add("DScrollPanel") self.baseSelectorPanel:Dock(FILL) self.title = self:Add("DLabel") self.title:SetFont("LargerTitlesFontNoClamp") self.title:SetText("Sélectionner Base") self.title:SizeToContents() self.title:Dock(TOP) self.title:SetContentAlignment(5) for base, info in pairs(PLUGIN.baseList) do local iBaseListKeys = #table.GetKeys(PLUGIN.baseList) local dFrameRectH = SScaleMin(25 / 3) local dFrameDivider = (dFrameRectH / iBaseListKeys) local baseSelector = self.baseSelectorPanel:Add("DButton") baseSelector:SetText(base) baseSelector:SetFont("TitlesFontNoClamp") baseSelector:SetTall((self:GetTall() / iBaseListKeys) - (s10 * 2) - (self.title:GetTall() / iBaseListKeys) - dFrameDivider) baseSelector:Dock(TOP) baseSelector:DockMargin(0, s10, 0, s10) if info.explainer then baseSelector:SetHelixTooltip(function(tooltip) local infoText = tooltip:AddRow("infoText") infoText:SetText(info.explainer) infoText:SizeToContents() tooltip:SizeToContents() end) end baseSelector.Paint = function(this, w, h) PaintButton(this, w, h) end baseSelector.DoClick = function() self:OnBaseSelected(base, info) end local showItemsWithinBase = baseSelector:Add("DButton") showItemsWithinBase:Dock(RIGHT) showItemsWithinBase:DockMargin(s10, s10, s10, s10) showItemsWithinBase:SetFont("MenuFontNoClamp") showItemsWithinBase:SetText("Afficher les éléments de la base") showItemsWithinBase:SizeToContents() showItemsWithinBase:SetWide(showItemsWithinBase:GetWide() + SScaleMin(10 / 3)) showItemsWithinBase.DoClick = function() self:ShowItemsWithinBase(base, 1) end end end function PANEL:OnBaseSelected(base, info, itemTemplate) if !self.baseSelectorPanel or self.baseSelectorPanel and !IsValid(self.baseSelectorPanel) then return end self.baseSelectorPanel:SetVisible(false) self.title:SetText("Créer des vêtements sur la base : "..base..".") self.title:SizeToContents() local desc = self:Add("DLabel") desc:SetText(info.explainer) desc:SetFont("MenuFont") desc:Dock(TOP) desc:SetTextColor(Color(200, 200, 200, 255)) desc:DockMargin(0, 0, 0, s10 * 2) desc:SetContentAlignment(5) desc:SizeToContents() local back = self:Add("DButton") back:SetText("Retour") back:SetFont("TitlesFontNoClamp") back:SetTall(SScaleMin(50 / 3)) back:Dock(BOTTOM) back:DockMargin(0, s10, 0, 0) back.DoClick = function() Derma_Query("Vous êtes sûr de vouloir revenir ?", "Votre article sera perdu !", "Confirmer", function() if self.creatorPanel and IsValid(self.creatorPanel) then self.creatorPanel:SetVisible(false) end self.title:SetText("Sélectionner Base") self.title:SizeToContents() self.baseSelectorPanel:SetVisible(true) back:Remove() desc:Remove() self.previewItemTable = nil end, "Annuler") end self.creatorPanel = self:CreateTheCreator(base, info, itemTemplate) end function PANEL:GetBodygroupsFromTemplate(template, entity) local bodygroups = {} for k, value in pairs(template.bodyGroups) do local index = entity:FindBodygroupByName(k) if (index > -1) then bodygroups[index] = value end end return bodygroups end function PANEL:CreateTheCreator(base, info, itemTemplate) local creatorPanel = self:Add("Panel") creatorPanel:Dock(FILL) local previewPanel = creatorPanel:Add("Panel") previewPanel:Dock(LEFT) local previewTitle = previewPanel:Add("DLabel") previewTitle:SetFont("LargerTitlesFontNoClamp") previewTitle:SetText("Prévisualiser") previewTitle:SizeToContents() previewTitle:Dock(TOP) previewTitle:DockMargin(s10, s10, s10, s10) previewTitle:SetContentAlignment(5) local previewTitleW = previewTitle:GetWide() local previewPanelW = previewTitleW + (s10 * 2) + SScaleMin(100 / 3) previewPanel:SetWide(previewPanelW) creatorPanel.Paint = function(this, w, h) surface.SetDrawColor(Color(0, 0, 0, 50)) surface.DrawRect(0, 0, previewPanelW, h) end self.previewItemTable = itemTemplate or self:GetItemTemplate(base) if info.parent then self.previewItemTable = self:GetItemTemplate(info.parent, self.previewItemTable) info.vars = self:MergeVars(info.vars, PLUGIN.baseList[info.parent].vars) end self.previewItemTable.model = itemTemplate and itemTemplate.model or "models/props_junk/watermelon01.mdl" self.preview = self:CreateItemShowcase(false, self.previewItemTable) self.preview:SetParent(previewPanel) self.preview:Dock(TOP) local previewM = previewPanelW * 0.5 - self.preview:GetWide() * 0.5 self.preview:DockMargin(previewM, 0, previewM, 0) if self.previewItemTable.OnInventoryDraw then local entity = self.preview:GetEntity() self.previewItemTable:OnInventoryDraw(entity, self.previewItemTable.proxy or false) end if self.previewItemTable.PaintOver then self.preview.PaintOver = function(this, w, h) self.previewItemTable.PaintOver(this, self.previewItemTable, w, h) end end local optionPanel = creatorPanel:Add("DScrollPanel") optionPanel:Dock(FILL) optionPanel:DockMargin(s10 * 2, 0, 0, 0) self.previewModel = self:CreatePlayermodelPreview(previewPanel, PLUGIN:GetModelsByBase(base), function() local entity = self.previewModel and self.previewModel.Entity if self.previewModel and IsValid(self.previewModel) then for key, value in pairs(self.curBodygroups) do entity:SetBodygroup(key, value) end end end) self.curBodygroups = itemTemplate and itemTemplate.bodyGroups and self:GetBodygroupsFromTemplate(itemTemplate, self.previewModel.Entity) or {} for index, value in pairs(self.curBodygroups) do self.previewModel.Entity:SetBodygroup(index, value) end local getCode = previewPanel:Add("DButton") getCode:SetFont("TitlesFontNoClamp") getCode:SetTall(SScaleMin(50 / 3)) getCode:Dock(BOTTOM) getCode:SetText("Voir Code") getCode:DockMargin(0, s10, 0, 0) getCode.Paint = function(this, w, h) PaintButton(this, w, h) end getCode.DoClick = function() local frame = vgui.Create("DFrame") frame:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) frame:MakePopup() frame:Center() frame:SetTitle("Voir Code") DFrameFixer(frame) local textEntry = frame:Add("DTextEntry") textEntry:Dock(FILL) textEntry:SetMultiline( true ) textEntry:SetVerticalScrollbarEnabled( true ) textEntry:SetEnterAllowed( true ) textEntry:SetTextColor(Color(200, 200, 200, 255)) textEntry:SetCursorColor(Color(200, 200, 200, 255)) textEntry:SetFont("MenuFontNoClamp") textEntry.Paint = function(this, w, h) surface.SetDrawColor(Color(0, 0, 0, 100)) surface.DrawRect(0, 0, w, h) surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30))) surface.DrawOutlinedRect(0, 0, w, h) this:DrawTextEntryText( this:GetTextColor(), this:GetHighlightColor(), this:GetCursorColor() ) end local str = self:FillOutString(base) textEntry:SetText(str) local copy = frame:Add("DButton") copy:SetFont("MenuFontNoClamp") copy:SetTall(SScaleMin(50 / 3)) copy:SetText("Copier") copy:Dock(BOTTOM) copy:DockMargin(0, s10, 0, 0) copy.Paint = function(this, w, h) PaintButton(this, w, h) end copy.DoClick = function() SetClipboardText(str) end end self:CreateOptions(optionPanel, base) local curProxy = self.previewItemTable and self.previewItemTable.proxy or {} self:UpdateProxyValues(curProxy) return creatorPanel end -- want to sort strings -> numbers -> bool first function PANEL:FillOutString(base) local newString = "" local toAvoid = {"name", "description", "category", "model"} for _, key in pairs(toAvoid) do newString = newString..'ITEM.'..key..' = "'..self.previewItemTable[key]..'"\n' end --string for key, value in pairs(self.previewItemTable) do if !PLUGIN.baseList[base].vars[key] then continue end if table.HasValue(toAvoid, key) then continue end if !isstring(value) then continue end if value == "" then continue end newString = newString..'ITEM.'..key..' = "'..value..'"\n' end --number for key, value in pairs(self.previewItemTable) do if !PLUGIN.baseList[base].vars[key] then continue end if !isnumber(value) then continue end if value == 0 then continue end newString = newString..'ITEM.'..key.." = "..tostring(value)..'\n' end --bool for key, value in pairs(self.previewItemTable) do if !PLUGIN.baseList[base].vars[key] then continue end if !isbool(value) then continue end if value == false then continue end newString = newString..'ITEM.'..key.." = "..tostring(value)..'\n' end --tables for key, value in pairs(self.previewItemTable) do if !PLUGIN.baseList[base].vars[key] then continue end if key:find("Color") then if istable(value) and value.r then local color = "Color("..value.r..", "..value.g.. ", "..value.b..")" newString = newString..'ITEM.'..key.." = "..color..'\n' continue end end if key:find("proxy") then local addonString = 'ITEM.'..key.." = {" for proxy, color in pairs(value) do local isTable = istable(color) if !isTable or isTable and !color.r then continue end if (color.r == 255 and color.g == 255 and color.b == 255) then continue end local vectorColor = "Vector("..color.r.." / 255, "..color.g.. " / 255, "..color.b.." / 255)" addonString = addonString..'\n'..proxy.." = "..vectorColor..',' end if addonString != 'ITEM.'..key.." = {" then addonString = addonString.."\n}\n" newString = newString..addonString end end if istable(value) and !key:find("proxy") then for key2, v in pairs(value) do if v == 0 or v == "" then value[key2] = nil end end if table.IsEmpty(value) then continue end local tableString = table.ToString( value, 'ITEM.'..key, true ) newString = newString..tableString..'\n' end end return newString end function PANEL:GetContentType(type, var) return (isstring(type) and "ixSettingsRowString" or isnumber(type) and "ixSettingsRowNumber" or var:find("Color") and "ixSettingsRowColor" or istable(type) and "DButton" or isbool(type) and "ixSettingsRowBool") end function PANEL:GetContentZPos(type, var) if var == "name" then return 1 end if var == "description" then return 2 end if var == "model" then return 3 end if var == "category" then return 4 end return (isstring(type) and 5 or isnumber(type) and 6 or isbool(type) and 7 or var:find("Color") and 8 or istable(type) and 9) end function PANEL:UpdateProxyValues(newValue) if !newValue then return end if self.previewModel and IsValid(self.previewModel) then self.previewModel.overrideProxyColors = newValue end end function PANEL:CreateOptions(parent, base) local baseTable = PLUGIN.baseList[base] if !PLUGIN.baseList or PLUGIN.baseList and !baseTable then return end self.options = {} for var, contentTable in pairs(baseTable.vars) do local type = contentTable.type local contentType = self:GetContentType(type, var) local zPos = self:GetContentZPos(type, var) if !contentType then return end local option = parent:Add(contentType) option:Dock(TOP) option:SetText(Schema:FirstToUpper(var or "")) option:SetZPos(zPos) if contentType == "ixSettingsRowString" then option.setting.OnTextChanged = function() self:UpdateItemShowcase(var, option:GetValue()) end if self.previewItemTable[var] then option:SetValue(self.previewItemTable[var]) end end if var == "width" or var == "height" then option:SetVisible(false) end -- this is always 1 if contentType == "ixSettingsRowNumber" then option:SetMin(contentTable.min or 0) option:SetMax(contentTable.max or 0) if contentTable.decimals then option:SetDecimals(1) end option:SetValue(self.previewItemTable[var] or contentTable.min or 0) option.OnValueChanged = function() local newValue = option:GetValue() self:UpdateItemShowcase(var, newValue) end end if contentType == "ixSettingsRowColor" then option.OnValueChanged = function() local newValue = option:GetValue() self:UpdateItemShowcase(var, newValue) end if self.previewItemTable[var] then option:SetValue(self.previewItemTable[var]) end end if contentType == "ixSettingsRowBool" then option.OnValueChanged = function() local newValue = option:GetValue() self:UpdateItemShowcase(var, newValue) end if self.previewItemTable[var] then option:SetValue(self.previewItemTable[var]) end end if contentType == "DButton" then option:SetFont("MenuFontNoClamp") option:SetTall(SScaleMin(50 / 3)) option:Dock(TOP) option:DockMargin(0, s10, 0, 0) option.Paint = function(this, w, h) PaintButton(this, w, h) end option.DoClick = function() if contentTable.altChoices then return contentTable.altChoices() end if contentTable.altMenu then return contentTable.altMenu() end end end if contentTable.description then option:SetHelixTooltip(function(tooltip) local notif1 = tooltip:AddRow("description") notif1:SetText(contentTable.description or "") notif1:SizeToContents() end) end if (contentTable.altChoices or contentTable.altMenu) and contentType != "DButton" then local helper = option:Add("DButton") helper:Dock(RIGHT) helper:SetFont("MenuFontNoClamp") helper:SetText("Aide") helper:SetTall(SScaleMin(50 / 3)) helper:DockMargin(0, 0, s10, 0) helper:SizeToContents() local sizeW, sizeH = helper:GetSize() helper:SetSize(sizeW + (s10 * 2), sizeH) helper.DoClick = function() self.curHelper = var if contentTable.altChoices then local altChoicesSelector = vgui.Create("DFrame") altChoicesSelector:SetSize(SScaleMin(300 / 3), SScaleMin(400 / 3)) altChoicesSelector:MakePopup() altChoicesSelector:Center() altChoicesSelector:SetTitle("Choix possibles dans la base") DFrameFixer(altChoicesSelector) local scroll = altChoicesSelector:Add("DScrollPanel") scroll:Dock(FILL) local choices = contentTable.altChoices() if choices and istable(choices) then for _, choice in pairs(choices) do local choiceButton = scroll:Add("DButton") choiceButton:SetText(Schema:FirstToUpper(choice or "")) choiceButton:SetFont("MenuFontNoClamp") choiceButton:SetTall(SScaleMin(50 / 3)) choiceButton:Dock(TOP) choiceButton:DockMargin(0, 0, 0, s10) choiceButton.DoClick = function() option:SetValue(choice) self:UpdateItemShowcase(var, choice) altChoicesSelector:Remove() end end end end if contentTable.altMenu then return contentTable.altMenu() end end end self.options[var] = option end end function PANEL:OpenProxyChooser() local frame = vgui.Create("DFrame") frame:SetSize(SScaleMin(600 / 3), SScaleMin(400 / 3)) frame:Center() frame:MakePopup() frame:SetTitle("Sélecteur de choix multiples") DFrameFixer(frame, false, true, true) frame.Paint = function(this, w, h) surface.SetDrawColor(Color(40, 40, 40, 255)) surface.DrawRect(0, 0, w, h) surface.SetDrawColor(Color(111, 111, 136, 255 / 100 * 30)) surface.DrawOutlinedRect(0, 0, w, h) surface.DrawRect(0, 0, w, this.lblTitle:GetTall() + SScaleMin(5 / 3)) return true end local curProxy = self.previewItemTable and self.previewItemTable.proxy or {} for _, proxy in pairs(PLUGIN:GetProxyList()) do local color = curProxy and curProxy[proxy] or false local colorChooser = frame:Add("ixSettingsRowColor") colorChooser:Dock(TOP) colorChooser:SetText(proxy or "") colorChooser:SetValue(color or color_white) colorChooser.OnValueChanged = function() local newColor = colorChooser:GetValue() curProxy[proxy] = newColor self:UpdateItemShowcase("proxy", curProxy) self:UpdateProxyValues(curProxy) end end end function PANEL:MergeVars(curVars, newVars) for k, v in pairs(newVars) do if (curVars[k] == nil) then curVars[k] = v end end local mergeTable = table.Copy(newVars) curVars = table.Merge(mergeTable, curVars) return curVars end function PANEL:GetItemTemplate(base, itemTable) local template = itemTable or {} local baseTable = ix.item.base[base] for k, v in pairs(baseTable) do if (template[k] == nil) then template[k] = v end template.baseTable = baseTable end local mergeTable = table.Copy(baseTable) template = table.Merge(mergeTable, template) return template end function PANEL:UpdateItemShowcase(var, value) local itemTable = self.previewItemTable if !itemTable then return end if !self.preview or self.preview and !IsValid(self.preview) then return end itemTable[var] = value if var == "model" then self.preview:SetModel(value, itemTable:GetSkin(), itemTable:GetModelBodygroups()) end self.preview:SetHelixTooltip(function(tooltip) ix.hud.PopulateItemTooltip(tooltip, itemTable, true) end) if itemTable.PaintOver and var == "outlineColor" then self.preview.PaintOver = function(this, w, h) itemTable.PaintOver(this, itemTable, w, h) end end if itemTable.OnInventoryDraw then local entity = self.preview:GetEntity() itemTable:OnInventoryDraw(entity, self.previewItemTable.proxy or false) end if var == "iconCam" then local camData = { cam_pos = value.pos, cam_ang = value.ang, cam_fov = value.fov } if !itemTable.OnInventoryDraw then self.preview.Icon:RebuildSpawnIconEx(camData) else self.preview:SetCamPos(itemTable.iconCam.pos) self.preview:SetFOV(itemTable.iconCam.fov) self.preview:SetLookAng(itemTable.iconCam.ang) local entity = self.preview:GetEntity() itemTable:OnInventoryDraw(entity, self.previewItemTable.proxy or false) end end end function PANEL:CreateItemShowcase(grid, itemTable) local panelType = itemTable.OnInventoryDraw and "ixItemIconAdvanced" or "ixItemIcon" local itemIcon = vgui.Create(panelType) itemIcon:SetModel(itemTable:GetModel(), itemTable:GetSkin(), itemTable:GetModelBodygroups()) itemIcon:SetSize(s100, s100) if itemTable.OnInventoryDraw then local entity = itemIcon:GetEntity() itemTable:OnInventoryDraw(entity, itemTable.proxy or self.previewItemTable and self.previewItemTable.proxy or false) itemIcon.LayoutEntity = function() end if (itemTable.iconCam) then itemIcon:SetCamPos(itemTable.iconCam.pos) itemIcon:SetFOV(itemTable.iconCam.fov) itemIcon:SetLookAng(itemTable.iconCam.ang) else local pos = entity:GetPos() local camData = PositionSpawnIcon(entity, pos) if (camData) then itemIcon:SetCamPos(camData.origin) itemIcon:SetFOV(camData.fov) itemIcon:SetLookAng(camData.angles) end end end itemIcon:SetHelixTooltip(function(tooltip) ix.hud.PopulateItemTooltip(tooltip, itemTable, true) end) if (grid) then grid:AddItem( itemIcon ) self.items[#self.items + 1] = itemIcon end return itemIcon end function PANEL:SearchBarPaint(this, w, h) PaintButton(this, w, h) if ( !this:GetText() or this:GetText() == "" ) then local oldText = this:GetText() local str = this:GetPlaceholderText() if ( str:StartWith( "#" ) ) then str = str:utf8sub( 2 ) end str = language.GetPhrase( str ) this:SetText( str ) this:DrawTextEntryText( this:GetPlaceholderColor(), this:GetHighlightColor(), this:GetCursorColor() ) this:SetText( oldText ) return end this:DrawTextEntryText( this:GetTextColor(), this:GetHighlightColor(), this:GetCursorColor() ) end function PANEL:ShowItemsWithinBase(base, page) local defaultW, defaultH = SScaleMin(500 / 3), SScaleMin(550 / 3) self.baseItemsPanel = vgui.Create("DFrame") self.baseItemsPanel:SetSize(SScaleMin(500 / 3), SScaleMin(550 / 3)) self.baseItemsPanel:MakePopup() self.baseItemsPanel:Center() self.baseItemsPanel:SetTitle("Articles sur la base "..base) DFrameFixer(self.baseItemsPanel) local tableView = self.baseItemsPanel:Add("DButton") tableView:SetText("Vue de la table") tableView:SetFont("MenuFontNoClamp") tableView:SetTall(SScaleMin(50 / 3)) tableView:Dock(TOP) tableView:DockMargin(0, 0, 0, s10) tableView.Paint = function(this, w, h) PaintButton(this, w, h) end local gridView = self.baseItemsPanel:Add("DButton") gridView:SetText("Vue en grille") gridView:SetFont("MenuFontNoClamp") gridView:SetTall(SScaleMin(50 / 3)) gridView:Dock(TOP) gridView:DockMargin(0, 0, 0, s10) gridView.Paint = function(this, w, h) PaintButton(this, w, h) end gridView:SetVisible(false) local itemGrid = self.baseItemsPanel:Add("DGrid") itemGrid:Dock(FILL) itemGrid:SetCols(5) itemGrid:SetColWide(s100) itemGrid:SetRowHeight(s100) self.items = {} self.currentPage = math.Clamp(page, 1, 9999) for _, itemTable in pairs(self:GetItemsByPage(base, self.currentPage)) do local itemIcon = self:CreateItemShowcase(itemGrid, itemTable) itemIcon.OnMousePressed = function(this, code) if (code == MOUSE_LEFT) then Derma_Query("Utiliser comme base de l'article ?", "Modèle d'article", "Confirmer", function() self.baseItemsPanel:Remove() self:OnBaseSelected(base, PLUGIN.baseList[base], self:GetItemTemplate(base, itemTable)) end, "Annuler") end end end local backForwardPanel = self.baseItemsPanel:Add("Panel") backForwardPanel:Dock(BOTTOM) backForwardPanel:SetTall(SScaleMin(50 / 3)) local back = backForwardPanel:Add("DButton") back:Dock(LEFT) back:SetWide(self.baseItemsPanel:GetWide() / 2) back:SetText("") self:CreateArrow(back, "back_arrow") back.Paint = function(this, w ,h) PaintButton(this, w, h) end back.DoClick = function() self:ChangePage(itemGrid, base) end local next = backForwardPanel:Add("DButton") next:Dock(FILL) next:SetText("") self:CreateArrow(next, "right-arrow") next.Paint = function(this, w ,h) PaintButton(this, w, h) end next.DoClick = function() self:ChangePage(itemGrid, base, true) end tableView.DoClick = function() self.baseItemsPanel:SetSize(s800, s800) self.baseItemsPanel:Center() itemGrid:SetVisible(false) gridView:SetVisible(true) tableView:SetVisible(false) backForwardPanel:SetVisible(false) self.searchBar = self.baseItemsPanel:Add("DTextEntry") self.searchBar:Dock(TOP) self.searchBar:DockMargin(0, 0, 0, s10) self.searchBar:SetTall(SScaleMin(50 / 3)) self.searchBar:SetTextColor(Color(200, 200, 200, 255)) self.searchBar:SetCursorColor(Color(200, 200, 200, 255)) self.searchBar:SetFont("MenuFontNoClamp") self.searchBar:SetUpdateOnType(true) self.searchBar:SetPlaceholderText("Recherche...") self.searchBar:SetPlaceholderColor(Color(200, 200, 200, 255)) self.searchBar.OnValueChange = function(this, value) self:ReloadItemList(value, base) end self.searchBar.Paint = function(this, w, h) PANEL:SearchBarPaint(this, w, h) end if self.itemListView and IsValid(self.itemListView) then self.itemListView:Remove() end self.itemListView = self.baseItemsPanel:Add("DListView") self.itemListView:Dock( FILL ) self.itemListView:AddColumn( "Nom" ) self.itemListView:AddColumn( "Description" ) self.itemListView:AddColumn( "uniqueID" ) for key, itemTable in SortedPairsByMemberValue(ix.item.list, "name") do if !itemTable.base or !PLUGIN.baseList[itemTable.base] then continue end if itemTable.base != base then continue end local line = self.itemListView:AddLine( itemTable.name or "", itemTable.description or "", key ) line:SetHelixTooltip(function(tooltip) ix.hud.PopulateItemTooltip(tooltip, itemTable, true) end) line.OnSelect = function() Derma_Query("Utiliser comme base d'élément ?", "Modèle d'élément", "Confirmer", function() self:OnBaseSelected(base, PLUGIN.baseList[base], self:GetItemTemplate(base, itemTable)) self.baseItemsPanel:Remove() end, "Annuler") end end self:DListViewDarkMode(self.itemListView) end gridView.DoClick = function() self.baseItemsPanel:SetSize(defaultW, defaultH) self.baseItemsPanel:Center() if self.itemListView and IsValid(self.itemListView) then self.itemListView:Remove() end if self.searchBar and IsValid(self.searchBar) then self.searchBar:Remove() end itemGrid:SetVisible(true) gridView:SetVisible(false) tableView:SetVisible(true) backForwardPanel:SetVisible(true) end end function PANEL:ReloadItemList(filter, base) if !self.itemListView or self.itemListView and !IsValid(self.itemListView) then return end self.itemListView:Clear() for key, itemTable in SortedPairsByMemberValue(ix.item.list, "name") do if !itemTable.base or !PLUGIN.baseList[itemTable.base] then continue end if itemTable.base != base then continue end local v = ix.item.list[key] local itemName = v.GetName and v:GetName() or L(v.name) if (filter and !itemName:lower():find(filter:lower(), 1, false)) then continue end local line = self.itemListView:AddLine( itemTable.name or "", itemTable.description or "", key ) line:SetHelixTooltip(function(tooltip) ix.hud.PopulateItemTooltip(tooltip, itemTable, true) end) line.OnSelect = function() Derma_Query("Utiliser comme base d'élément ?", "Modèle d'élément", "Confirmer", function() self:OnBaseSelected(base, PLUGIN.baseList[base], self:GetItemTemplate(base, itemTable)) self.baseItemsPanel:Remove() end, "Annuler") end end self:DListViewDarkMode(self.itemListView) end function PANEL:DListViewDarkMode(dListView) dListView:DockMargin(4, 4, 4, 4) dListView:SetHeaderHeight(SScaleMin(20 / 3)) dListView:SetDataHeight(SScaleMin(20 / 3)) dListView.Paint = function() end for _, v4 in pairs(dListView.Columns) do for _, v5 in pairs(v4:GetChildren()) do v5:SetFont("MenuFontNoClamp") end v4.Paint = function(this, w, h) PaintButton(this, w, h, true) end end for _, v in ipairs(dListView.Lines) do for _, v3 in pairs(v:GetChildren()) do v3:SetFont("MenuFontNoClamp") end v.Paint = function(panel, width, height) if (panel:IsSelected()) then --luacheck: ignore 1 SKIN.tex.Input.ListBox.Hovered(0, 0, width, height) elseif (panel.Hovered) then surface.SetDrawColor(34, 58, 112) surface.DrawRect(0, 0, width, height) elseif (panel.m_bAlt) then SKIN.tex.Input.ListBox.EvenLine(0, 0, width, height) end end for _, v2 in ipairs(v.Columns) do v2:SetTextColor(Color(200, 200, 200)) end end end function PANEL:ChangePage(itemGrid, base, bForward) local newPage = math.Clamp(self.currentPage + (bForward and 1 or -1), 1, 9999) local newItems = self:GetItemsByPage(base, newPage) if #table.GetKeys(newItems) <= 0 then return end self.currentPage = newPage self:ClearItems(itemGrid) for _, itemTable in pairs(self:GetItemsByPage(base, self.currentPage)) do local itemIcon = self:CreateItemShowcase(itemGrid, itemTable) itemIcon.OnMousePressed = function(this, code) if (code == MOUSE_LEFT) then Derma_Query("Utiliser comme base d'élément ?", "Modèle d'élément", "Confirmer", function() self.baseItemsPanel:Remove() self:OnBaseSelected(base, PLUGIN.baseList[base], self:GetItemTemplate(base, itemTable)) end, "Annuler") end end end end function PANEL:ClearItems(grid) if self.items then for _, v in pairs(self.items) do if IsValid(v) then grid:RemoveItem(v) end end self.items = {} end end function PANEL:CreateArrow(parent, path) local s5 = SScaleMin(5 / 3) local s40 = SScaleMin(40 / 3) local imgbgWD2 = self.baseItemsPanel:GetWide() / 2 local lrMargin = (imgbgWD2 - s40) * 0.5 local arrow = parent:Add("DImage") arrow:Dock(FILL) arrow:DockMargin(lrMargin, s5, lrMargin, s5) arrow:SetImage("willardnetworks/mainmenu/"..path..".png") end function PANEL:Think() if self.baseItemsPanel and IsValid(self.baseItemsPanel) then self.baseItemsPanel:MoveToFront() end end function PANEL:GetItemsByPage(base, page) local itemList = {} for key, itemTable in pairs(ix.item.list) do if !itemTable.base or !PLUGIN.baseList[itemTable.base] then continue end if itemTable.base != base then continue end itemList[key] = itemTable end local itemListKeys = table.GetKeys(itemList) local items = {} local endInt = 20 * (page == 1 and 1 or page) local startInt = page == 1 and 1 or endInt - 19 for i = startInt, endInt do if i > #itemListKeys then break end local key = itemListKeys[i] items[key] = ix.item.list[key] end return items end function PANEL:GetChoicesInBaseFromVar(base, var) local choices = {} for _, itemTable in pairs(ix.item.list) do if !itemTable.base or !PLUGIN.baseList[itemTable.base] then continue end if itemTable.base != base then continue end if !itemTable[var] then continue end if choices[var] then continue end choices[var] = itemTable[var] end return choices end function PANEL:GetChoicesInBaseFromVarTable(base, var) local choices = {} for _, itemTable in pairs(ix.item.list) do if !itemTable.base or !PLUGIN.baseList[itemTable.base] then continue end if itemTable.base != base then continue end if !itemTable[var] then continue end for _, choice in pairs(itemTable[var]) do if table.HasValue(choices, choice) then continue end choices[#choices + 1] = choice end end return choices end function PANEL:OpenColorAppendixMenu() local frame = vgui.Create("DFrame") frame:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) frame:MakePopup() frame:Center() frame:SetTitle("Créateur d'appendices de couleurs") DFrameFixer(frame) local colorAppendixList = ix.hud.appendixColors or {} local curItemTable = self.previewItemTable local curColors = curItemTable and curItemTable.colorAppendix and table.GetKeys(curItemTable.colorAppendix) or false local selectorPanel = frame:Add("Panel") selectorPanel:Dock(TOP) selectorPanel:SetTall(SScaleMin(50 / 3)) selectorPanel:DockMargin(0, 0, 0, s10 * 2) local colorSelector = selectorPanel:Add("DComboBox") colorSelector:SetFont("MenuFontNoClamp") colorSelector:Dock(LEFT) colorSelector:SetWide(SScaleMin(150 / 3)) colorSelector:DockMargin(0, 0, s10 * 2, 0) colorSelector:SetValue( curColors and istable(curColors) and Schema:FirstToUpper(curColors[1] or "") or "Sélectionnez la couleur" ) colorSelector:AddChoice( "Aucun" ) colorSelector:SetSortItems( false ) for colorKey, _ in pairs(colorAppendixList) do colorSelector:AddChoice( Schema:FirstToUpper(colorKey) ) end colorSelector.Paint = function(this, w, h) surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30))) surface.DrawRect(0, 0, w, h) end local textEntry = selectorPanel:Add("DTextEntry") textEntry:Dock(FILL) textEntry:SetTextColor(Color(200, 200, 200, 255)) textEntry:SetCursorColor(Color(200, 200, 200, 255)) textEntry:SetFont("MenuFontNoClamp") textEntry:SetPlaceholderText("Ajouter du texte ici...") textEntry:SetPlaceholderColor(Color(200, 200, 200, 255)) textEntry:SetText(curColors and curItemTable.colorAppendix[curColors[1]] or "") textEntry.Paint = function(this, w, h) PANEL:SearchBarPaint(this, w, h) end for key, color in pairs(colorAppendixList) do local colorShowcase = frame:Add("DLabel") colorShowcase:Dock(TOP) colorShowcase:SetText((Schema:FirstToUpper(key or "") or "N/A")..": Lorem ipsum dolor sit amet") colorShowcase:SetTextColor(color or color_white) colorShowcase:DockMargin(0, s10 * 2, 0, 0) colorShowcase:SetContentAlignment(5) colorShowcase:SetFont("ixSmallFont") colorShowcase:SizeToContents() end local save = frame:Add("DButton") save:SetText("Sauvegarder") save:SetFont("TitlesFontNoClamp") save:SetTall(SScaleMin(50 / 3)) save:Dock(BOTTOM) save.Paint = function(this, w, h) PaintButton(this, w, h) end save.DoClick = function() local colorAppendix = {} local color = colorSelector:GetValue() if color and color != "None" and color != "Select Color" and color != "" then colorAppendix[string.lower(color)] = textEntry:GetText() or "" end self:UpdateItemShowcase("colorAppendix", colorAppendix) frame:Remove() end end function PANEL:CreatePlayermodelPreview(parent, models, buttonCallback) local model = parent:Add("ixModelPanel") model:Dock(FILL) model:SetFOV(60) model:SetModel(models.male) local genderPanel = parent:Add("Panel") genderPanel:Dock(BOTTOM) genderPanel:SetTall(SScaleMin(50 / 3)) genderPanel:SetZPos(999) local male = genderPanel:Add("DButton") male:Dock(LEFT) male:SetWide(parent:GetWide() / 2) male:SetText("Mâle") male:SetFont("TitlesFontNoClamp") male:DockMargin(0, 0, SScaleMin(5 / 3), 0) male.Paint = function(this, w, h) PaintButton(this, w, h) end local female = genderPanel:Add("DButton") female:Dock(FILL) female:SetText("Femelle") female:DockMargin(SScaleMin(5 / 3), 0, 0, 0) female:SetFont("TitlesFontNoClamp") female.Paint = function(this, w, h) PaintButton(this, w, h) end male.DoClick = function() model:SetModel(models.male) buttonCallback() end female.DoClick = function() model:SetModel(models.female) buttonCallback() end return model end function PANEL:OpenBodygroupChooser(models) local frame = vgui.Create("DFrame") frame:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) frame:MakePopup() frame:Center() frame:SetTitle("Sélecteur de groupe de corps d'éléments") DFrameFixer(frame) local leftColumn = frame:Add("Panel") leftColumn:SetWide(frame:GetWide() * 0.5) leftColumn:Dock(LEFT) leftColumn:DockMargin(0, 0, s10 * 2, 0) local rightColumn = frame:Add("DScrollPanel") rightColumn:Dock(FILL) local function UpdateBodyGroups( type, val ) if PANEL.model and IsValid(PANEL.model) then PANEL.model.Entity:SetBodygroup( type, math.Round( val ) ) PANEL.model:SetCorrectHair() end end PANEL.model = self:CreatePlayermodelPreview(leftColumn, models, function() for _, v in pairs(PANEL.sliderPanels) do UpdateBodyGroups(v.bg, v:GetValue()) end end) if self.previewItemTable and self.previewItemTable.OnInventoryDraw then self.previewItemTable:OnInventoryDraw(PANEL.model.Entity, self.previewItemTable.proxy or false) end PANEL.sliderPanels = {} for k = 0, PANEL.model.Entity:GetNumBodyGroups() - 1 do if ( PANEL.model.Entity:GetBodygroupCount( k ) <= 1 ) then continue end local bgName = PANEL.model.Entity:GetBodygroupName( k ) if (bgName == "hair" or bgName == "beard") then continue end local bgTransfer = self.curBodygroups local sliderPanel = rightColumn:Add("ixNumSlider") sliderPanel:Dock(TOP) sliderPanel:DockMargin(0, SScaleMin(10 / 3), 0, SScaleMin(10 / 3)) sliderPanel:SetTall(SScaleMin(50 / 3)) sliderPanel:SetMax(PANEL.model.Entity:GetBodygroupCount( k ) - 1) sliderPanel:SetValue(bgTransfer and bgTransfer[k] or 0) if bgTransfer then UpdateBodyGroups(k, sliderPanel:GetValue()) end sliderPanel:SetDecimals( 0 ) sliderPanel.label:SetText(bgTransfer and bgTransfer[k] or "0") sliderPanel.bg = k sliderPanel.slider.OnValueChanged = function(panel) UpdateBodyGroups(k, sliderPanel:GetValue()) sliderPanel.label:SetText(sliderPanel:GetValue()) end local label = sliderPanel:Add("DLabel") label:SetFont("TitlesFontNoClamp") label:SetText(Schema:FirstToUpper(bgName)) label:Dock(FILL) label:SetContentAlignment(5) sliderPanel.slider.OnValueUpdated = function(panel) UpdateBodyGroups(k, sliderPanel:GetValue()) sliderPanel.label:SetText(sliderPanel:GetValue()) end PANEL.sliderPanels[#PANEL.sliderPanels + 1] = sliderPanel end local save = leftColumn:Add("DButton") save:Dock(BOTTOM) save:SetZPos(998) save:SetText("Save") save:SetTall(SScaleMin(50 / 3)) save:DockMargin(0, s10 * 2, 0, 0) save:SetFont("TitlesFontNoClamp") save.Paint = function(this, w, h) PaintButton(this, w, h) end save.DoClick = function() if self.previewModel and IsValid(self.previewModel) then local bodyGroups = {} for _, v in pairs(PANEL.sliderPanels) do self.previewModel.Entity:SetBodygroup(v.bg, v:GetValue()) self.curBodygroups[v.bg] = v:GetValue() bodyGroups[self.previewModel.Entity:GetBodygroupName(v.bg)] = v:GetValue() self.previewModel:SetCorrectHair() end self.previewItemTable["bodyGroups"] = bodyGroups end frame:Remove() end end function PANEL:OpenItemModelChoices() PANEL.spawnMenu = vgui.Create("DFrame") PANEL.spawnMenu:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) PANEL.spawnMenu:MakePopup() PANEL.spawnMenu:Center() PANEL.spawnMenu:SetTitle("Sélecteur de modèle") DFrameFixer(PANEL.spawnMenu) local content = PANEL.spawnMenu:Add("SpawnmenuContentPanel") content.OldSpawnlists = content.ContentNavBar.Tree:AddNode( "#spawnmenu.category.browse", "icon16/cog.png" ) content:Dock(FILL) content:EnableModify() hook.Call( "PopulatePropMenu", GAMEMODE ) content:CallPopulateHook( "PopulateContent" ) content.OldSpawnlists:MoveToFront() content.OldSpawnlists:SetExpanded( true ) end function PANEL:OpenItemPicker() PANEL.itemMenu = vgui.Create("DFrame") PANEL.itemMenu:SetSize(SScaleMin(1000 / 3), SScaleMin(700 / 3)) PANEL.itemMenu:MakePopup() PANEL.itemMenu:Center() PANEL.itemMenu:SetTitle("Sélecteur d'items") DFrameFixer(PANEL.itemMenu) local itemListPlugin = ix.plugin.list["itemlist"] if itemListPlugin then if itemListPlugin.CreateItemsPanel then local base = itemListPlugin:CreateItemsPanel() base:SetParent(PANEL.itemMenu) base:Dock(FILL) base:EnableModify() local p1 = base.ContentNavBar and IsValid(base.ContentNavBar) and base.ContentNavBar:GetChildren() local p2 = p1[4] and IsValid(p1[4]) and p1[4]:GetChildren() local defSearchEntry = p2[1] or false if defSearchEntry and IsValid(defSearchEntry) then defSearchEntry:Remove() end end end end -- called in cl_whitelistedspawnmenu.lua, whitelistedprops plugin, edited it to support this due to it overriding spawnmenu. function PANEL:SaveSpawnMenuChoice(model, bodygroups, skin) if PANEL.spawnMenu and IsValid(PANEL.spawnMenu) then PANEL.spawnMenu:Remove() end if self.options["model"] and IsValid(self.options["model"]) then self.options["model"]:SetValue(model) end self:UpdateItemShowcase("model", model) end -- called in sh_plugin.lua, itemlist plugin, edited it to support this. function PANEL:SaveItemMenuChoice(uniqueID) if PANEL.itemMenu and IsValid(PANEL.itemMenu) then PANEL.itemMenu:Remove() end local option = self.curHelper if !option then return end if self.options[self.curHelper] and IsValid(self.options[self.curHelper]) then self.options[self.curHelper]:SetValue(uniqueID) end self:UpdateItemShowcase(self.curHelper, uniqueID) end function PANEL:OpenMultipleChoice(list, var) local frame = vgui.Create("DFrame") frame:SetSize(SScaleMin(300 / 3), SScaleMin(400 / 3)) frame:Center() frame:MakePopup() frame:SetTitle("Sélecteur de choix multiples") DFrameFixer(frame) frame.checkboxes = {} local checkBoxPanel = frame:Add("DScrollPanel") checkBoxPanel:Dock(FILL) if !istable(list) then return end for _, value in SortedPairs(list) do local checkbox = checkBoxPanel:Add( "DCheckBoxLabel" ) checkbox:Dock(TOP) checkbox:SetText(value or "") checkbox:SetValue( self.previewItemTable[var] and table.HasValue(self.previewItemTable[var], value) and true or false ) checkbox:SetFont("MenuFontNoClamp") checkbox:SizeToContents() checkbox.PerformLayout = function(panel) local x = panel.m_iIndent or 0 panel.Button:SetSize(SScaleMin(15 / 3), SScaleMin(15 / 3)) panel.Button:SetPos(x, math.floor((panel:GetTall() - panel.Button:GetTall()) / 2)) panel.Label:SizeToContents() panel.Label:SetPos(x + panel.Button:GetWide() + SScaleMin(9 / 3), 0) end frame.checkboxes[#frame.checkboxes + 1] = checkbox end local save = frame:Add("DButton") save:SetText("Sauvegarder") save:SetFont("TitlesFontNoClamp") save:SetTall(SScaleMin(50 / 3)) save:Dock(BOTTOM) save.Paint = function(this, w, h) PaintButton(this, w, h) end save.DoClick = function() frame:Remove() local checked = {} for _, panel in pairs(frame.checkboxes) do if panel:GetChecked() then checked[#checked + 1] = panel:GetText() end end self:UpdateItemShowcase(var, checked) end end function PANEL:OpenIconEditor() local data = self.previewItemTable ix.gui.iconEditor = vgui.Create('ixIconEditor') local iconEditor = ix.gui.iconEditor DFrameFixer(iconEditor) if iconEditor.model and IsValid(iconEditor.model) then if data.model then iconEditor.model:SetModel(data.model) if data.OnInventoryDraw then data:OnInventoryDraw(iconEditor.model.Entity, self.previewItemTable.proxy or false) end end end if iconEditor.width and IsValid(iconEditor.width) then if data.width then iconEditor.width:SetMinMax(1, data.width) end end if iconEditor.height and IsValid(iconEditor.height) then if data.height then iconEditor.height:SetMinMax(1, data.height) end end if iconEditor.modelPath and IsValid(iconEditor.modelPath) then iconEditor.modelPath:Remove() end if iconEditor.copy and IsValid(iconEditor.copy) then iconEditor.copy:SetText("Sauvegarder") iconEditor.copy.DoClick = function() local camPos = iconEditor.model:GetCamPos() local camAng = iconEditor.model:GetLookAng() local iconCam = { pos = Vector(math.Round(-camPos.x, 2), math.Round(-camPos.y, 2), math.Round(camPos.z, 2)), ang = Angle(math.Round(camAng.p, 2), math.Round(camAng.y + 180, 2), math.Round(camAng.r, 2)), fov = math.Round(iconEditor.model:GetFOV(), 2) } if data.OnInventoryDraw then iconCam.pos = Vector(math.Round(camPos.x, 2), math.Round(camPos.y, 2), math.Round(camPos.z, 2)) iconCam.ang = Angle(math.Round(camAng.p, 2), math.Round(camAng.y, 2), math.Round(camAng.r, 2)) end self:UpdateItemShowcase("iconCam", iconCam) end end local advanced = data.OnInventoryDraw if advanced then iconEditor.item:SetVisible(false) iconEditor.itemAdvanced = vgui.Create("ixItemIconAdvanced", iconEditor.itemPanel) iconEditor.itemAdvanced:SetModel(data:GetModel(), data:GetSkin(), data:GetModelBodygroups()) iconEditor.itemAdvanced:SetSize(s100, s100) local entity = iconEditor.itemAdvanced:GetEntity() iconEditor.itemAdvanced.LayoutEntity = function() end local pos = entity:GetPos() local camData = PositionSpawnIcon(entity, pos) if (camData) then iconEditor.itemAdvanced:SetCamPos(camData.origin) iconEditor.itemAdvanced:SetFOV(camData.fov) iconEditor.itemAdvanced:SetLookAng(camData.angles) end iconEditor.item.Rebuild = function(pnl, forceRebuild) iconEditor.itemAdvanced:SetFOV(iconEditor.model:GetFOV()) iconEditor.itemAdvanced:SetCamPos(iconEditor.model:GetCamPos()) iconEditor.itemAdvanced:SetLookAng(iconEditor.model:GetLookAng()) end data:OnInventoryDraw(entity, self.previewItemTable.proxy or false) end if data and data.iconCam then local curPos = data.iconCam.pos local curAng = data.iconCam.ang local pos = Vector((!advanced and -curPos.x or curPos.x), (!advanced and -curPos.y or curPos.y), curPos.z) local ang = Angle(curAng.p, curAng.y + (!advanced and 180 or 0), curAng.r) iconEditor.model:SetCamPos(pos) iconEditor.model:SetFOV(data.iconCam.fov) iconEditor.model:SetLookAng(ang) end timer.Simple(0.5, function() iconEditor.item:Rebuild(true) end) end vgui.Register("ixClothingCreator", PANEL, "DFrame")