├── .gitattributes ├── .gitignore ├── .gmodignore ├── 3rdpartylegalnotices.txt ├── README.md ├── build.js ├── changelog_footer_template.hbs ├── images.weserv.nl.png ├── lua ├── autorun │ ├── pointshop2_build.lua │ ├── pointshop2_init.lua │ └── ps2_kinv_init.lua ├── ev_plugins │ └── sv_pointshop2.lua ├── kinv │ ├── client │ │ ├── cl_dermaskin.lua │ │ ├── cl_dinventory.lua │ │ ├── cl_dinventorypropertysheet.lua │ │ ├── cl_ditemdescriptionpanel.lua │ │ ├── cl_ditemscontainer.lua │ │ ├── cl_ditemslot.lua │ │ ├── cl_ditemstack.lua │ │ ├── cl_inventory.lua │ │ ├── cl_inventoryview.lua │ │ └── cl_item.lua │ ├── items │ │ └── pointshop │ │ │ ├── sh_0_base_pointshop_item.lua │ │ │ ├── sh_base_hat.lua │ │ │ ├── sh_base_playermodel.lua │ │ │ ├── sh_base_single_use.lua │ │ │ ├── sh_base_trail.lua │ │ │ ├── sh_jumppack.lua │ │ │ └── single_use │ │ │ ├── sh_base_points.lua │ │ │ └── sh_item_jump_power.lua │ ├── server │ │ ├── sv_inventory.lua │ │ ├── sv_inventorycontroller.lua │ │ ├── sv_item.lua │ │ └── sv_kinventory.lua │ └── shared │ │ ├── sh_0_kinventory.lua │ │ ├── sh_config.lua │ │ ├── sh_model_inventory.lua │ │ ├── sh_model_item.lua │ │ └── sh_z_itemloader.lua ├── ps2 │ ├── client │ │ ├── cl_0_bootstrap.lua │ │ ├── cl_0_pointshop2.lua │ │ ├── cl_DCreditWindow.lua │ │ ├── cl_DInfoPanel.lua │ │ ├── cl_DMaterialSelector.lua │ │ ├── cl_DPointshopSimpleItemIcon.lua │ │ ├── cl_DStepPanel.lua │ │ ├── cl_clientSettings.lua │ │ ├── cl_dermaskin_flatui.lua │ │ ├── cl_dloadingnotifier.lua │ │ ├── cl_dmultilinelabel.lua │ │ ├── cl_dpointshopframe.lua │ │ ├── cl_dpointshophaticon.lua │ │ ├── cl_dpointshopmenuedtab.lua │ │ ├── cl_dradiochoice.lua │ │ ├── cl_inyourface.lua │ │ ├── cl_pointshop2view.lua │ │ ├── icons │ │ │ ├── cl_dcsgoitemicon.lua │ │ │ ├── cl_dpointshopinventoryitemicon.lua │ │ │ ├── cl_dpointshopitemicon.lua │ │ │ ├── cl_haticon_prerender.lua │ │ │ ├── cl_itemqueue.lua │ │ │ └── cl_prerender.lua │ │ ├── notifications │ │ │ ├── cl_DItemReceivedNotification.lua │ │ │ ├── cl_KNotificationPanel.lua │ │ │ ├── cl_KNotificationPanelManager.lua │ │ │ ├── cl_dpointfeed.lua │ │ │ └── cl_pointfeed.lua │ │ └── tabs │ │ │ ├── inventory_tab │ │ │ ├── cl_0_dpointshopinventorytab.lua │ │ │ ├── cl_dpointshopequipmentslot.lua │ │ │ ├── cl_dpointshopgivepointsframe.lua │ │ │ ├── cl_dpointshopinventorypanel.lua │ │ │ ├── cl_dpointshopinventorypreviewpanel.lua │ │ │ ├── cl_dpointshopplayerselect.lua │ │ │ └── cl_z_DPointshopClientSettings.lua │ │ │ ├── management_tab │ │ │ ├── cl_dbigbutton.lua │ │ │ ├── cl_ddlcbutton.lua │ │ │ ├── cl_dpointshopmanagementtab.lua │ │ │ ├── cl_dpointshopmanagementtab_createitem.lua │ │ │ ├── cl_dpointshopmanagementtab_exportimport.lua │ │ │ ├── cl_dpointshopmanagementtab_items.lua │ │ │ ├── cl_dpointshopmanagementtab_servers.lua │ │ │ ├── cl_dpointshopmanagementtab_settings.lua │ │ │ ├── cl_dpointshopmanagementtab_users.lua │ │ │ ├── cl_dpointshopmanagementtab_z_dlc.lua │ │ │ ├── cl_hoverpanel.lua │ │ │ ├── create_item │ │ │ │ ├── cl_1_DItemCreator_Stage.lua │ │ │ │ ├── cl_DItemCreator_BasicSettings.lua │ │ │ │ ├── cl_dcreateitembutton.lua │ │ │ │ ├── cl_ditemcreator.lua │ │ │ │ └── cl_ditemcreator_steps.lua │ │ │ ├── manage_items │ │ │ │ ├── attribution.txt.lua │ │ │ │ ├── cl_DSelectRanks.lua │ │ │ │ ├── cl_DSelectServers.lua │ │ │ │ ├── cl_dpointshopcontentsidebar.lua │ │ │ │ ├── cl_dpointshopcontentsidebartoolbox.lua │ │ │ │ ├── content │ │ │ │ │ ├── cl_pointshop2content.lua │ │ │ │ │ ├── cl_rightclickmenu.lua │ │ │ │ │ └── cl_savecategories.lua │ │ │ │ ├── dpointshopcontentcontainer.lua │ │ │ │ └── dpointshopcontentpanel.lua │ │ │ ├── manage_users │ │ │ │ ├── DPointshopManageUser_GiveItemDialog.lua │ │ │ │ ├── dpointshopmanageuser_selectuser.lua │ │ │ │ └── dpointshopmanageuser_userdetails.lua │ │ │ └── settings │ │ │ │ ├── cl_dsettingseditor.lua │ │ │ │ ├── cl_dsettingspanel.lua │ │ │ │ ├── cl_dsettingssection.lua │ │ │ │ └── cl_dsetttingsbutton.lua │ │ │ └── shop_tab │ │ │ ├── cl_dnewitempopup.lua │ │ │ ├── cl_dpointshopcategorypanel.lua │ │ │ ├── cl_dpointshopitemdescription.lua │ │ │ ├── cl_dpointshoppreviewpanel.lua │ │ │ └── cl_dpointshopshoptab.lua │ ├── modules │ │ ├── calendar │ │ │ ├── cl_DCalendarItemPicker.lua │ │ │ ├── cl_DFixedGrid.lua │ │ │ └── sh_module.lua │ │ ├── dlc │ │ │ └── sh_module.lua │ │ ├── guesswho_integration │ │ │ ├── sh_module.lua │ │ │ └── sh_prevent_visuals.lua │ │ ├── mu_integration │ │ │ ├── cl_dmurderconfigurator.lua │ │ │ ├── cl_previewmodel.lua │ │ │ ├── sh_module.lua │ │ │ └── sv_muhooks.lua │ │ ├── pointshop2 │ │ │ ├── cl_DPointshopMaterialIcon.lua │ │ │ ├── cl_DPointshopMaterialInvIcon.lua │ │ │ ├── cl_DPointshopReset.lua │ │ │ ├── cl_DPointshopTextureIcon.lua │ │ │ ├── cl_DUsableItemDescription.lua │ │ │ ├── cl_dpointshop2configurator.lua │ │ │ ├── hat │ │ │ │ ├── cl_ForceHideOnDeath.lua │ │ │ │ ├── cl_dhatcreator.lua │ │ │ │ ├── cl_dhaticoneditor.lua │ │ │ │ ├── cl_dhatpositioner.lua │ │ │ │ ├── cl_dpointshophatinvicon.lua │ │ │ │ ├── cl_dpointshoppacview.lua │ │ │ │ ├── cl_dpointshopsimplehaticon.lua │ │ │ │ ├── cl_dprerenderedmodelpanel.lua │ │ │ │ ├── cl_hatpreview.lua │ │ │ │ ├── sh_model_hatpersistence.lua │ │ │ │ ├── sh_model_outfitmapping.lua │ │ │ │ ├── sh_slot.lua │ │ │ │ ├── sh_spawnmenu.lua │ │ │ │ └── spawnmenu │ │ │ │ │ ├── cl_creationmenu.lua │ │ │ │ │ ├── cl_modelsearch.lua │ │ │ │ │ ├── cl_spawnmenu.lua │ │ │ │ │ └── creationmenu │ │ │ │ │ └── content │ │ │ │ │ ├── cl_content.lua │ │ │ │ │ ├── cl_contentcontainer.lua │ │ │ │ │ ├── cl_contentheader.lua │ │ │ │ │ ├── cl_contenticon.lua │ │ │ │ │ ├── cl_contentsearch.lua │ │ │ │ │ ├── cl_contentsidebar.lua │ │ │ │ │ ├── cl_contentsidebartoolbox.lua │ │ │ │ │ └── contenttypes │ │ │ │ │ ├── cl_addonprops.lua │ │ │ │ │ ├── cl_custom.lua │ │ │ │ │ └── cl_gameprops.lua │ │ │ ├── item_factories │ │ │ │ ├── cl_DItemFactoryConfigurationFrame.lua │ │ │ │ ├── cl_DItemFactoryPicker.lua │ │ │ │ ├── factories │ │ │ │ │ ├── cl_DItemFactoryConfigurator.lua │ │ │ │ │ ├── cl_DItemFromFactoryConfigurator.lua │ │ │ │ │ ├── cl_DPointsFactoryConfigurator.lua │ │ │ │ │ ├── sh_ItemFromCategoryFactory.lua │ │ │ │ │ ├── sh_PointsFactory.lua │ │ │ │ │ └── sh_SingleItemFactory.lua │ │ │ │ └── sh_ItemFactory.lua │ │ │ ├── playermodel │ │ │ │ ├── cl_dmodelpanel_playermodel.lua │ │ │ │ ├── cl_dplayermodelcreator.lua │ │ │ │ ├── cl_dplayermodelselector.lua │ │ │ │ ├── cl_dpointshopplayermodelicon.lua │ │ │ │ ├── cl_dpointshopplayermodelinvicon.lua │ │ │ │ ├── sh_model_playermodelpersistence.lua │ │ │ │ └── sh_slot.lua │ │ │ ├── points_over_time │ │ │ │ ├── cl_DPointsOverTimeConfigurator.lua │ │ │ │ ├── cl_DPointsOverTimeConfigurator_AddRank.lua │ │ │ │ ├── sv_afkchecker.lua │ │ │ │ └── sv_pointsOverTime.lua │ │ │ ├── rarity │ │ │ │ ├── cl_DItemChanceTable.lua │ │ │ │ └── sh_rarities.lua │ │ │ ├── sh_module.lua │ │ │ └── trail │ │ │ │ ├── cl_dpointshoptraillicon.lua │ │ │ │ ├── cl_dtrailcreator.lua │ │ │ │ ├── cl_dtrailselector.lua │ │ │ │ ├── sh_model_trailpersistence.lua │ │ │ │ └── sh_slot.lua │ │ ├── prophunt_integration │ │ │ ├── cl_DPropHuntConfigurator.lua │ │ │ ├── cl_phpreview.lua │ │ │ ├── sh_module.lua │ │ │ ├── sh_prevent_visuals.lua │ │ │ ├── sv_ProphuntHooks.lua │ │ │ └── sv_propHuntPropHook.lua │ │ ├── thehidden_integration │ │ │ ├── cl_dthehiddenconfigurator.lua │ │ │ ├── sh_module.lua │ │ │ ├── sh_prevent_visuals.lua │ │ │ ├── sv_hooks.lua │ │ │ └── sv_pointsovertime.lua │ │ ├── ttt_integration │ │ │ ├── cl_dterrortownconfigurator.lua │ │ │ ├── cl_tttpreview.lua │ │ │ ├── sh_module.lua │ │ │ └── sv_ttthooks.lua │ │ └── zs_integration │ │ │ ├── cl_dzombiesurvivalconfigurator.lua │ │ │ ├── sh_module.lua │ │ │ ├── sh_prevent_visuals.lua │ │ │ └── sv_zshooks.lua │ ├── server │ │ ├── sv_0_bootstrap.lua │ │ ├── sv_fix_sqlite_to_mysql_2_25_0.lua │ │ ├── sv_playerextension.lua │ │ ├── sv_pointsbatch.lua │ │ ├── sv_pointshop2.lua │ │ ├── sv_pointshop2_defaults_categories.lua │ │ ├── sv_pointshop2_defaults_items.lua │ │ ├── sv_pointshopcontroller.lua │ │ ├── sv_pointshopcontroller_importexport.lua │ │ ├── sv_pointshopcontroller_outfits.lua │ │ ├── sv_pointshopcontroller_ranks.lua │ │ ├── sv_pointshopcontroller_servers.lua │ │ ├── sv_pointshopcontroller_settings.lua │ │ ├── sv_pointshopcontroller_shop.lua │ │ ├── sv_pointshopcontroller_userdetails.lua │ │ ├── sv_pointshopcontroller_wallet.lua │ │ └── sv_pts_fixer.lua │ ├── shared │ │ ├── sh_0_pointshop2.lua │ │ ├── sh_categorytree.lua │ │ ├── sh_config.lua │ │ ├── sh_equipmentslots.lua │ │ ├── sh_mixin_easyexport.lua │ │ ├── sh_model_categorysettings.lua │ │ ├── sh_model_equipmentslot.lua │ │ ├── sh_model_itemmapping.lua │ │ ├── sh_model_itempersistence.lua │ │ ├── sh_model_server.lua │ │ ├── sh_model_settings.lua │ │ ├── sh_model_storedoutfit.lua │ │ ├── sh_model_wallet.lua │ │ ├── sh_moduleloader.lua │ │ ├── sh_pacprotect.lua │ │ └── sh_playerextension.lua │ └── updatescripts │ │ ├── 2.1.0.lua │ │ ├── 2.13.0.lua │ │ ├── 2.14.0.lua │ │ ├── 2.19.0.lua │ │ ├── 2.2.0.lua │ │ ├── 2.22.0.lua │ │ ├── 2.25.0.lua │ │ ├── 2.26.0.lua │ │ ├── 2.3.0.lua │ │ ├── 2.6.0.lua │ │ └── 2.9.0.lua ├── sam │ └── modules │ │ └── sh_pointshop2.lua └── ulx │ └── modules │ ├── sh │ └── sh_pointshop2.lua │ └── sh_ulx_inventory.lua ├── package.json ├── wercker.yml └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gmodignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | package.json 3 | .gitignore 4 | .editorconfig 5 | .npmrc 6 | *.log 7 | .DS_Store 8 | *.tmp 9 | .gmodignore 10 | *.tmp.md 11 | .env 12 | yarn.lock 13 | build.js 14 | dist/* 15 | dist/ 16 | README.md 17 | changelog_footer_template.hbs 18 | wercker.yml 19 | bin/ 20 | bin/* 21 | sync.ps1 -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { 4 | cp, 5 | rm, 6 | mkdir, 7 | exec 8 | } = require('shelljs') 9 | const request = require('request-promise') 10 | const { writeFileSync, readFileSync } = require('fs') 11 | const glob = require('glob') 12 | 13 | module.exports = async function createRelease() { 14 | rm('-rf', 'dist') 15 | mkdir(['dist', 'dist/pointshop2']) 16 | 17 | const ignoreGlobs = readFileSync('.gmodignore', 'utf-8') 18 | .split(/[\r\n]+/) 19 | .filter(Boolean) 20 | 21 | const folders = glob.sync('**/', { 22 | ignore: ignoreGlobs 23 | }) 24 | folders.map(x => mkdir('dist/pointshop2/' + x)) 25 | 26 | const files = glob.sync('**', { 27 | ignore: ignoreGlobs, 28 | nodir: true 29 | }) 30 | files.map(file => cp(file, 'dist/pointshop2/' + file)) 31 | 32 | const pdf = await request({ 33 | url: 'http://media.readthedocs.org/pdf/pointshop2/latest/pointshop2.pdf', 34 | method: 'GET', 35 | encoding: null 36 | }) 37 | writeFileSync('dist/Installation, Guide and Developer.pdf', pdf) 38 | writeFileSync('dist/Don\'t forget to download PAC3.txt', 39 | `Please download PAC3 from https://github.com/CapsAdmin/pac3/ and install it as an addon. 40 | Check Installation, Guide and Developer.pdf for more information.`) 41 | 42 | const version = JSON.parse(readFileSync('package.json')).version 43 | writeFileSync('dist/pointshop2/lua/autorun/pointshop2_build.lua', `PS2_BUILD = "${version}"`) 44 | 45 | exec('git clone https://github.com/Kamshak/LibK.git dist/libk') 46 | rm('-rf', 'dist/libk/.git') 47 | 48 | cp('package.json', 'dist') 49 | cp('.gmodignore', 'dist') 50 | } 51 | 52 | if (require.main === module) { 53 | module.exports() 54 | } 55 | -------------------------------------------------------------------------------- /changelog_footer_template.hbs: -------------------------------------------------------------------------------- 1 | {{#if noteGroups}} 2 | {{#each noteGroups}} 3 | 4 | ### {{title}} 5 | 6 | {{#each notes}} 7 | * {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{text}} 8 | {{/each}} 9 | {{/each}} 10 | 11 | {{/if}} 12 | 13 | ### How to update 14 | 15 | - To update this addon simply remove your existing libk and pointshop2 folders and upload the new ones from the zip. 16 | - (If you are using mysql, please don't foget to reenter your mysql configuration into the libk config file) 17 | - Afterwards please restart your server. 18 | - Configuration and created items will stay the same. 19 | 20 | **Important**: When you upload files don't forget to check for failed transfers. (Tab at the bottom if using FileZilla) 21 | 22 | 23 | #### Pointshop on Steam 24 | 25 | To get updates, annoucements and news comfortably, join the Stream Group: [http://steamcommunity.com/groups/pointshop-2](http://steamcommunity.com/groups/pointshop-2) 26 | -------------------------------------------------------------------------------- /images.weserv.nl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValentinFunk/Pointshop2/c8a4b5bf2e134b2db3bc21071db4b4bdca79a33a/images.weserv.nl.png -------------------------------------------------------------------------------- /lua/autorun/pointshop2_build.lua: -------------------------------------------------------------------------------- 1 | PS2_BUILD = "git" -------------------------------------------------------------------------------- /lua/autorun/pointshop2_init.lua: -------------------------------------------------------------------------------- 1 | --Always AddCSLua the modules (needed for updater) 2 | local function addCsLuaRecursive( folder ) 3 | local files, folders = file.Find( folder .. "/*", "LUA" ) 4 | for k, filename in pairs( files ) do 5 | local realmPrefix = string.sub( filename, 1, 2 ) 6 | if ( realmPrefix != "sh" and realmPrefix != "cl" and realmPrefix != "sv" ) or filename[3] != "_" then 7 | KLogf( 2, "[ERROR] Couldn't determine realm of file %s! Please name your file sh_*/cl_*/sv_*.lua", filename ) 8 | continue 9 | end 10 | local fullpath = folder .. "/" .. filename 11 | if SERVER and ( realmPrefix == "sh" or realmPrefix == "cl" ) then 12 | AddCSLuaFile( fullpath ) 13 | end 14 | end 15 | 16 | for k, v in pairs( folders ) do 17 | addCsLuaRecursive( folder .. "/" .. v ) 18 | end 19 | end 20 | addCsLuaRecursive( "ps2/modules" ) 21 | LibK.AddCSLuaDir( "kinv/items" ) 22 | 23 | LibK.InitializeAddon{ 24 | addonName = "Pointshop2", --Name of the addon 25 | author = "Kamshak", --Name of the author 26 | luaroot = "ps2", --Folder that contains the client/shared/server structure relative to the lua folder, 27 | loadAfterGamemode = false, 28 | version = "2.26.0", 29 | requires = { "KInventory" } 30 | } 31 | 32 | LibK.addReloadFile( "autorun/pointshop2_init.lua" ) 33 | print( Format( "Pointshop2 Version %s : %s loaded", "{{ script_id }}", "{{ user_id }}" ) ) 34 | -------------------------------------------------------------------------------- /lua/autorun/ps2_kinv_init.lua: -------------------------------------------------------------------------------- 1 | LibK.InitializeAddon{ 2 | addonName = "KInventory", --Name of the addon 3 | author = "Kamshak", --Name of the author 4 | luaroot = "kinv", --Folder that contains the client/shared/server structure relative to the lua folder, 5 | loadAfterGamemode = false, 6 | } 7 | 8 | LibK.addReloadFile( "autorun/ps2_kinv_init.lua" ) -------------------------------------------------------------------------------- /lua/ev_plugins/sv_pointshop2.lua: -------------------------------------------------------------------------------- 1 | local PLUGIN = {} 2 | PLUGIN.Title = "Pointshop2 Management Access" 3 | PLUGIN.Description = "Allows rank access to the Management section of Pointshop 2" 4 | PLUGIN.Author = "Kamshak" 5 | PLUGIN.Privileges = { "pointshop2 manageitems", 6 | "pointshop2 createitems", 7 | "pointshop2 manageusers", 8 | "pointshop2 managemodules", 9 | "pointshop2 exportimport", 10 | "pointshop2 reset", 11 | "pointshop2 usepac" 12 | } 13 | PLUGIN.ChatCommand = "ps2_addpoints" 14 | PLUGIN.Usage = "steamid currency amount" 15 | 16 | function PLUGIN:Call( ply, args ) 17 | if not ply:EV_HasPrivilege( "pointshop2 manageusers" ) then 18 | evolve:Notify( ply, evolve.colors.red, evolve.constants.notallowed ) 19 | end 20 | 21 | Pointshop2Controller:getInstance( ):addPointsBySteamId( steamId, currencyType, amount ) 22 | :Fail( function( errid, err ) 23 | local errString = Format( "[Pointshop 2] ERROR: Couldn't give %i %s to %s, %i - %s", amount, currencyType, steamId, errid, err ) 24 | KLog( 2, errString ) 25 | evolve:Notify( ply, evolve.colors.red, errString ) 26 | end ) 27 | :Done( function( ) 28 | local succString = Format( "[Pointshop 2] %s gave %i %s to %s", calling_ply:Nick( ), amount, currencyType, steamId ) 29 | KLog( 4, succString ) 30 | evolve:Notify( ply, evolve.colors.blue, succString ) 31 | end ) 32 | end 33 | 34 | evolve:RegisterPlugin( PLUGIN ) -------------------------------------------------------------------------------- /lua/kinv/client/cl_ditemdescriptionpanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | function PANEL:Init( ) 3 | self:SetSkin( KInventory.Config.DermaSkin ) 4 | self:DockPadding( 5, 10, 5, 5 ) 5 | 6 | self.descriptionLabel = vgui.Create( "DPointshopItemDescription", self ) 7 | self.descriptionLabel._control = "DPointshopItemDescription" 8 | self.descriptionLabel:DockMargin( 0, 5, 0, 5 ) 9 | self.descriptionLabel:Dock( FILL ) 10 | self.descriptionLabel.Paint = function() end 11 | self.descriptionLabel.description.Paint = function(p, w, h) surface.SetDrawColor(68, 68, 68 , 240) surface.DrawRect(0, 0, w, h ) end 12 | 13 | derma.SkinHook( "Layout", "ItemDescriptionPanel", self ) 14 | end 15 | 16 | function PANEL:Think( ) 17 | self.descriptionLabel:SetToFullHeight( ) 18 | self.descriptionLabel:SetTall( self.descriptionLabel:GetTall( ) + 10 ) 19 | self:SetTall( 10 + self.descriptionLabel:GetTall( ) ) 20 | self:SizeToContents( ) 21 | end 22 | 23 | function PANEL:SetTargetPanel( pnl ) 24 | self.targetPanel = pnl 25 | end 26 | 27 | function PANEL:SetItem( item ) 28 | local control = item.class.GetPointshopDescriptionControl() 29 | if self.descriptionLabel._control == control then 30 | self.descriptionLabel:SetItem( item, true ) 31 | self.descriptionLabel:SizeToContents( ) 32 | else 33 | self.descriptionLabel:Remove() 34 | self.descriptionLabel = vgui.Create( control, self ) 35 | self.descriptionLabel._control = control 36 | self.descriptionLabel:DockMargin( 0, 5, 0, 5 ) 37 | self.descriptionLabel:Dock( FILL ) 38 | self.descriptionLabel.Paint = function() end 39 | self.descriptionLabel.description.Paint = function(p, w, h) surface.SetDrawColor(68, 68, 68 , 240) surface.DrawRect(0, 0, w, h ) end 40 | self.descriptionLabel:SetItem( item, true ) 41 | end 42 | end 43 | 44 | -- only for indexed tables! 45 | function table.reverse ( tab ) 46 | local size = #tab 47 | local newTable = {} 48 | 49 | for i,v in ipairs ( tab ) do 50 | newTable[size-i] = v 51 | end 52 | 53 | return newTable 54 | end 55 | 56 | Derma_Hook( PANEL, "Paint", "Paint", "ItemDescriptionPanel" ) 57 | vgui.Register( "DItemDescriptionPanel", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/kinv/client/cl_inventory.lua: -------------------------------------------------------------------------------- 1 | local Inventory = KInventory.Inventory 2 | 3 | function Inventory:addItem( item ) 4 | table.insert( self.Items, item ) 5 | end 6 | 7 | function Inventory:removeItem( item ) 8 | return self:removeItemById( item.id ) 9 | end 10 | 11 | function Inventory:removeItemById( itemId ) 12 | local removed = false 13 | for k, v in pairs( self.Items ) do 14 | if v.id == itemId then 15 | table.remove( self.Items, k ) 16 | removed = true 17 | end 18 | end 19 | 20 | return removed 21 | end 22 | -------------------------------------------------------------------------------- /lua/kinv/client/cl_item.lua: -------------------------------------------------------------------------------- 1 | local Item = KInventory.Item 2 | 3 | function Item:networkUse( ) 4 | net.Start( "PlayerUseItem" ) 5 | net.WriteInt( self.id, 32 ) 6 | net.SendToServer( ) 7 | end 8 | 9 | function Item:initialize( ) 10 | end 11 | 12 | function Item:getIcon( ) 13 | self.icon = vgui.Create( "DModelPanel" ) 14 | self.icon:SetModel( self.iconModel or self.class.iconModel or "models/props/cs_office/cardboard_box03.mdl" ) 15 | self.icon:SetSize( 64, 64 ) 16 | function self.icon:LayoutEntity( ent ) 17 | self:SetCamPos( Vector( 20, 20, 20 ) ) 18 | self:SetLookAt( ent:GetPos( ) + Vector( 0, 0, 5 ) ) 19 | if self.Hovered then 20 | ent:SetAngles( ent:GetAngles( ) + Angle( 0, FrameTime() * 50, 0) ) 21 | end 22 | end 23 | return self.icon 24 | end 25 | 26 | function Item:getHoverPanel( ) 27 | local panel = vgui.Create( "DItemDescriptionPanel" ) 28 | panel:SetSize( 220, 100 ) 29 | return panel 30 | end 31 | 32 | function Item:openMenu( ) 33 | local menu = DermaMenu( ) 34 | if self.droppable or self.class.droppable then 35 | menu:AddOption( "Drop", function( ) 36 | InventoryView:getInstance( ):dropItem( self ) 37 | end ) 38 | end 39 | 40 | if self.usable or self.class.usable then 41 | menu:AddOption( "Use", function( ) 42 | InventoryView:getInstance( ):useItem( self ) 43 | end ) 44 | end 45 | menu:Open( ) 46 | end -------------------------------------------------------------------------------- /lua/kinv/items/pointshop/sh_base_single_use.lua: -------------------------------------------------------------------------------- 1 | ITEM.PrintName = "Single Use Item Base" 2 | ITEM.baseClass = "base_pointshop_item" 3 | 4 | --CLIENTSIDE: When use button is clicked 5 | function ITEM:UseButtonClicked( ) 6 | self:ServerRPC( "InternalOnUse" ) 7 | return true --Disable Button 8 | end 9 | 10 | function ITEM:CanBeUsed( ) 11 | local servers = self.class.Servers 12 | if #servers > 0 and not table.HasValue( servers, Pointshop2.GetCurrentServerId( ) ) then 13 | return false, "This item cannot be used on this server" 14 | end 15 | return true 16 | end 17 | 18 | --SERVERSIDE: When button is clicked 19 | function ITEM:InternalOnUse( ) 20 | --Avoid double use 21 | if self.used or not self:CanBeUsed( ) then 22 | return 23 | end 24 | 25 | local succ, err = pcall( self.OnUse, self ) 26 | if not succ then 27 | LibK.GLib.Error( Format( "[ERROR] Item %s Use failed: %s", self.class.name, err ) ) 28 | return 29 | end 30 | self.used = true 31 | 32 | local ply = self:GetOwner( ) 33 | Promise.Resolve() 34 | :Then(function() 35 | -- Pcall returns either the argument or the returned value 36 | -- By wrapping the return value in a promise here we make sure 37 | -- that if a promise is returned we wait on it. 38 | return err 39 | end):Then( function( ) 40 | KLogf( 4, "Player %s used an item", ply:Nick( ) ) 41 | end, function( errid, err ) 42 | LibK.GLib.Error( Format( "Error using item: %s %s", tostring(errid), tostring(err) ) ) 43 | end ) 44 | :Always(function() 45 | return Pointshop2Controller:getInstance( ):removeItemFromPlayer( ply, self ) 46 | end) 47 | end 48 | ITEM.static.AllowRPC( "InternalOnUse" ) 49 | 50 | --SERVERSIDE: For override on item use 51 | function ITEM:OnUse( ) 52 | debug.Trace() 53 | end 54 | 55 | function ITEM.static.GetPointshopDescriptionControl( ) 56 | return "DUsableItemDescription" 57 | end 58 | 59 | function ITEM.static:GetPointshopIconControl( ) 60 | return "DPointshopMaterialIcon" 61 | end 62 | 63 | function ITEM.static:GetPointshopLowendIconControl( ) 64 | return "DPointshopMaterialIcon" 65 | end 66 | 67 | function ITEM:getIcon( ) 68 | self.icon = vgui.Create( "DPointshopMaterialInvIcon" ) 69 | self.icon:SetItem( self ) 70 | return self.icon 71 | end 72 | -------------------------------------------------------------------------------- /lua/kinv/items/pointshop/sh_base_trail.lua: -------------------------------------------------------------------------------- 1 | ITEM.PrintName = "Pointshop Playermodel Base" 2 | ITEM.baseClass = "base_pointshop_item" 3 | 4 | ITEM.material = "" 5 | 6 | ITEM.category = "Trails" 7 | ITEM.color = "" 8 | 9 | function ITEM:AttachTrail( ) 10 | if SERVER then 11 | if hook.Run( "PS2_VisualsShouldShow", self:GetOwner( ) ) == false then 12 | return 13 | end 14 | 15 | local ply = self:GetOwner() 16 | if (ply.IsSpec and ply:IsSpec()) then 17 | return 18 | end 19 | 20 | if not ply:Alive( ) then 21 | return 22 | end 23 | 24 | self.trailEnt = util.SpriteTrail( ply, 0, self.color, false, 15, 1, 4, 0.125, self.material .. ".vmt" ) 25 | timer.Simple( 1, function( ) 26 | self:ClientRPC( "TrailAdded", self.trailEnt ) 27 | end ) 28 | end 29 | end 30 | 31 | function ITEM:TrailAdded( trailEnt ) 32 | if Pointshop2.ClientSettings.GetSetting( "BasicSettings.VisualsDisabled" ) then 33 | if IsValid( trailEnt ) then 34 | trailEnt:SetNoDraw( true ) 35 | end 36 | end 37 | end 38 | 39 | function ITEM:RemoveTrail( ) 40 | if SERVER then 41 | SafeRemoveEntity( self.trailEnt ) 42 | end 43 | end 44 | 45 | function ITEM:OnEquip( ) 46 | self:AttachTrail( ) 47 | end 48 | 49 | function ITEM:PlayerSpawn( ply ) 50 | if ply == self:GetOwner( ) then 51 | self:AttachTrail( ) 52 | end 53 | end 54 | Pointshop2.AddItemHook( "PlayerSpawn", ITEM ) 55 | 56 | function ITEM:PlayerDeath( victim, inflictor, attacker ) 57 | if victim == self:GetOwner( ) then 58 | self:RemoveTrail( ) 59 | end 60 | end 61 | ITEM.PlayerSilentDeath = ITEM.PlayerDeath 62 | Pointshop2.AddItemHook( "PlayerDeath", ITEM ) 63 | Pointshop2.AddItemHook( "PlayerSilentDeath", ITEM ) 64 | 65 | function ITEM:OnHolster( ) 66 | self:RemoveTrail( ) 67 | end 68 | 69 | function ITEM.static:GetPointshopIconControl( ) 70 | return "DPointshopTrailIcon" 71 | end 72 | 73 | function ITEM.static:GetPointshopLowendIconControl( ) 74 | return "DPointshopSimpleTrailIcon" 75 | end 76 | 77 | function ITEM.static.getPersistence( ) 78 | return Pointshop2.TrailPersistence 79 | end 80 | 81 | function ITEM.static.generateFromPersistence( itemTable, persistenceItem ) 82 | ITEM.super.generateFromPersistence( itemTable, persistenceItem.ItemPersistence ) 83 | itemTable.material = persistenceItem.material 84 | end 85 | 86 | function ITEM.static.GetPointshopIconDimensions( ) 87 | return Pointshop2.GenerateIconSize( 2, 4 ) 88 | end 89 | 90 | /* 91 | Inventory icon 92 | */ 93 | function ITEM:getIcon( ) 94 | self.icon = vgui.Create( "DPointshopMaterialInvIcon" ) 95 | self.icon:SetItem( self ) 96 | self.icon:SetSize( 64, 64 ) 97 | return self.icon 98 | end 99 | -------------------------------------------------------------------------------- /lua/kinv/items/pointshop/single_use/sh_base_points.lua: -------------------------------------------------------------------------------- 1 | /* 2 | Instances of this type are created through the points factory. 3 | No persistence is available as it does not make sense (buy points for points?) 4 | */ 5 | 6 | ITEM.PrintName = "Points" 7 | ITEM.baseClass = "base_single_use" 8 | ITEM.category = "Misc" 9 | 10 | ITEM.material = "pointshop2/dollar103.png" 11 | ITEM.currencyType = "points" 12 | ITEM.amount = 100 13 | ITEM.stackCount = 8 14 | 15 | function ITEM:initialize( id ) 16 | KInventory.Items.base_pointshop_item.initialize( self, id ) 17 | 18 | --Fields that are JSON saved for each item 19 | self.saveFields = self.saveFields or {} 20 | table.insert(self.saveFields, "currencyType" ) 21 | table.insert(self.saveFields, "amount" ) 22 | end 23 | 24 | function ITEM:GetPrintName( ) 25 | local currencyStr 26 | if self.currencyType == "points" then 27 | currencyStr = "Points" 28 | else 29 | currencyStr = "Premium Points" 30 | end 31 | self.PrintName = self.amount .. " " .. currencyStr 32 | return self.PrintName 33 | end 34 | 35 | function ITEM:GetDescription( ) 36 | local currencyStr 37 | if self.currencyType == "points" then 38 | currencyStr = "Points" 39 | else 40 | currencyStr = "Premium Points" 41 | end 42 | self.Description = "Gives you " .. self.amount .. " " .. currencyStr .. " when used." 43 | return self.Description 44 | end 45 | 46 | function ITEM:GetSellPrice( ply ) 47 | return self.amount, self.currencyType 48 | end 49 | 50 | -- Can always redeem 51 | function ITEM:CanBeUsed( ) 52 | return true 53 | end 54 | 55 | --Give points on use 56 | function ITEM:OnUse( ) 57 | if self.currencyType == "points" then 58 | self:GetOwner( ):PS2_AddStandardPoints( self.amount, "Item Redeemed", false, true ) 59 | else 60 | self:GetOwner( ):PS2_AddPremiumPoints( self.amount, "Item Redeemed", false, true ) 61 | end 62 | end 63 | 64 | /* 65 | Inventory icon 66 | */ 67 | function ITEM:getIcon( ) 68 | if self.currencyType == "points" then 69 | self.material = "pointshop2/dollar103.png" 70 | else 71 | self.material = "pointshop2/donation.png" 72 | end 73 | 74 | self.icon = vgui.Create( "DPointshopMaterialInvIcon" ) 75 | self.icon:SetItem( self ) 76 | self.icon:SetSize( 64, 64 ) 77 | return self.icon 78 | end 79 | -------------------------------------------------------------------------------- /lua/kinv/items/pointshop/single_use/sh_item_jump_power.lua: -------------------------------------------------------------------------------- 1 | ITEM.baseClass = "base_single_use" 2 | ITEM.PrintName = "Jump Power" 3 | ITEM.Description = "Use to get 2x Jump Power!" 4 | ITEM.material = "pointshop2/small65.png" 5 | 6 | function ITEM:CanBeUsed( ) 7 | local canBeUsed, reason = ITEM.super.CanBeUsed( self ) 8 | if not canBeUsed then 9 | return false, reason 10 | end 11 | 12 | local ply = self:GetOwner( ) 13 | if not ply:Alive( ) or ( ply.IsSpec and ply:IsSpec( ) ) then 14 | return false, "You need to be alive to use this item" 15 | end 16 | return true 17 | end 18 | 19 | function ITEM:OnUse( ) 20 | self:GetOwner( ):SetJumpPower( self:GetOwner( ):GetJumpPower( ) * 2 ) 21 | end 22 | -------------------------------------------------------------------------------- /lua/kinv/server/sv_item.lua: -------------------------------------------------------------------------------- 1 | util.AddNetworkString( "PlayerUseItem" ) 2 | 3 | local Item = KInventory.Item 4 | 5 | net.Receive( "PlayerUseItem", function( len, ply ) 6 | local itemId = net.ReadInt( 32 ) 7 | 8 | KInventory.Item.findById( itemId ) 9 | :Then( function( item ) 10 | if not item then 11 | ply:Kick() -- People seem to exploit this msg to lagg servers 12 | return KLogf( 3, "[WARN] Player %s tried to use unknown item %i", ply:Nick( ), itemId ) 13 | end 14 | 15 | if item:getOwner( ) == ply then 16 | item:use( ply ) 17 | else 18 | KLogf( 3,"%s tried to use item he doesnt own(id %i, ower is %i)", ply:Nick( ), item.id, item.ownerId ) 19 | end 20 | end ) 21 | end ) 22 | 23 | function Item:handleDrop( ply ) 24 | KLogf( 4, "Item:handleDrop( " .. tostring( ply ) .. ")" ) 25 | local tr = util.TraceLine( util.GetPlayerTrace( ply ) ) 26 | 27 | local vec = ply:GetAimVector( ) * 10 + ply:GetUp( ) * 1 28 | if tr.Hit then 29 | local hit = tr.HitPos 30 | vec = ( hit - ply:EyePos( ) ) 31 | vec:Normalize( ) 32 | vec = vec * 100 33 | end 34 | 35 | local droppedItem = ents.Create( "spawned_item" ) 36 | droppedItem:setItem( self ) 37 | droppedItem:SetPos( ply:EyePos( ) + ply:GetForward( ) * 3 ) 38 | droppedItem:Spawn() 39 | droppedItem:Activate() 40 | droppedItem:GetPhysicsObject( ):ApplyForceCenter( vec * droppedItem:GetPhysicsObject( ):GetMass( ) ) 41 | end -------------------------------------------------------------------------------- /lua/kinv/server/sv_kinventory.lua: -------------------------------------------------------------------------------- 1 | //LibK.SetupDatabase( "KInventory", KInventory ) -------------------------------------------------------------------------------- /lua/kinv/shared/sh_0_kinventory.lua: -------------------------------------------------------------------------------- 1 | KInventory = {} 2 | KInventory.Mixins = {} 3 | 4 | -- Registers a class mixin (see middleclass docs). 5 | -- This can be used to extend/patch item classes and their definitions 6 | function KInventory.RegisterItemClassMixin( className, mixin ) 7 | -- Class already loaded, apply mixin now 8 | if KInventory.Items and KInventory.Items[className] then 9 | print(KInventory.Items[className]) 10 | KInventory.ApplyMixin( KInventory.Items[className], mixin ) 11 | end 12 | 13 | -- Class not yet loaded, apply once loaded 14 | KInventory.Mixins[className] = KInventory.Mixins[className] or {} 15 | table.insert( KInventory.Mixins[className], mixin ) 16 | end 17 | 18 | -- Apply all registered mixins to className 19 | function KInventory.ApplyMixins( className ) 20 | if KInventory.Mixins[className] then 21 | for _, mixin in pairs( KInventory.Mixins[className] ) do 22 | KInventory.ApplyMixin( KInventory.Items[className], mixin ) 23 | end 24 | end 25 | end 26 | 27 | -- Apply single mixin to a class if not already done 28 | function KInventory.ApplyMixin( klaas, mixin ) 29 | klaas.__mixinsApplied = klaas.__mixinsApplied or {} 30 | if not klaas.__mixinsApplied[mixin] then 31 | klaas:include( mixin ) 32 | klaas.__mixinsApplied[mixin] = true 33 | end 34 | end -------------------------------------------------------------------------------- /lua/kinv/shared/sh_config.lua: -------------------------------------------------------------------------------- 1 | INVCONFIG = {} 2 | INVCONFIG.startWeight = 10 --Weight the inventory has initially 3 | INVCONFIG.useCharacters = true 4 | INVCONFIG.dermaSkin = "KInventoryBasic" -------------------------------------------------------------------------------- /lua/kinv/shared/sh_model_inventory.lua: -------------------------------------------------------------------------------- 1 | KInventory.INVENTORIES = {} 2 | setmetatable(KInventory.INVENTORIES, { __mode = 'v' }) --weak table, allow collection if not referenced anywhere else 3 | 4 | local Inventory = class( "KInventory.Inventory" ) 5 | KInventory.Inventory = Inventory 6 | 7 | Inventory.static.DB = "Pointshop2" 8 | Inventory.static.model = { 9 | tableName = "inventories", 10 | fields = { 11 | ownerId = "int", 12 | numSlots = "int", 13 | parentInventory = "optKey" --INT(11), optional foreign key 14 | }, 15 | /*hasMany = { 16 | Items = { 17 | class = "KInventory.Item", 18 | foreignKey = "inventory_id" 19 | }, 20 | },*/ 21 | belongsTo = { 22 | ParentInventory = { 23 | class = "KInventory.Inventory", 24 | foreignKey = "parentInventory" 25 | } 26 | } 27 | } 28 | Inventory:include( DatabaseModel ) 29 | 30 | function Inventory:postLoad( ) 31 | local def = Deferred( ) 32 | 33 | KInventory.INVENTORIES[self.id] = self 34 | 35 | def:Resolve( ) 36 | return def:Promise( ) 37 | end 38 | 39 | function Inventory:getWeight( ) 40 | local weight = 0 41 | for k, v in pairs( self.Items ) do 42 | weight = weight + v:getWeight( ) 43 | end 44 | return weight 45 | end 46 | 47 | function Inventory:getOwner( ) 48 | for k, v in pairs( player.GetAll( ) ) do 49 | if tonumber( v:GetNWInt( "KPlayerId" ) ) == self.ownerId then 50 | return v 51 | end 52 | end 53 | end 54 | 55 | 56 | function Inventory:getItems( ) 57 | return self.Items 58 | end 59 | 60 | function Inventory:containsItem( item ) 61 | for k, v in pairs( self.Items ) do 62 | if v.id == item.id then 63 | return true 64 | end 65 | end 66 | return false 67 | end 68 | 69 | function Inventory:getNumSlots( ) 70 | return self.numSlots 71 | end -------------------------------------------------------------------------------- /lua/kinv/shared/sh_model_item.lua: -------------------------------------------------------------------------------- 1 | KInventory.ITEMS = {} 2 | setmetatable(KInventory.ITEMS, { __mode = "v" }) 3 | 4 | local Item = class( "KInventory.Item" ) 5 | KInventory.Item = Item 6 | 7 | Item.static.DB = "Pointshop2" 8 | Item.static.printName = "Basic Item" 9 | Item.static.description = { "This is a basic item." } 10 | Item.static.droppable = true 11 | Item.static.usable = false 12 | Item.static.stackCount = 1 13 | Item.static.validModifiers = 0 14 | Item.static.category = "Misc" 15 | Item.static.iconModel = "models/props/cs_office/cardboard_box03.mdl" 16 | Item.static.worldModel = "models/props/cs_office/cardboard_box03.mdl" 17 | Item.static.weight = 0 18 | 19 | Item.static.model = { 20 | tableName = "kinv_items", 21 | fields = { 22 | itemclass = "classname", 23 | itempersistence_id = "optKey", 24 | inventory_id = "optKey", --optional foreign key, if this doesnt exist item is dropped 25 | data = "table" --Table is a special field, saves all instance vars that weren't saved already 26 | }, 27 | belongsTo = { 28 | Inventory = { 29 | class = "KInventory.Inventory", 30 | foreignKey = "inventory_id", 31 | onDelete = "CASCADE" 32 | }, 33 | ItemPersistence = { 34 | class = "Pointshop2.ItemPersistence", 35 | foreignKey = "itempersistence_id", 36 | onDelete = "CASCADE" 37 | } 38 | } 39 | } 40 | Item:include( DatabaseModel ) 41 | 42 | 43 | function Item:postLoad( ) 44 | --i know this is disgusting :( a possible alternative would be no relationships 45 | local cached = KInventory.ITEMS[self.id] 46 | if cached then 47 | for k, v in pairs( self ) do 48 | if not cached[k] then 49 | cached[k] = self[k] 50 | end 51 | end 52 | Pointshop2.LogCacheEvent('ITEM_MODIFY', 'Item:postLoad', self.id) 53 | else 54 | KInventory.ITEMS[self.id] = self 55 | Pointshop2.LogCacheEvent('ADD', 'Item:postLoad', self.id) 56 | end 57 | 58 | 59 | local inv = KInventory.INVENTORIES[self.inventory_id] 60 | if inv then 61 | self.owner = inv:getOwner( ) 62 | end 63 | 64 | return Promise.Resolve() 65 | end 66 | 67 | function Item:getWeight( ) 68 | return self.weight or self.class.weight 69 | end 70 | 71 | function Item:getWorldModel( ) 72 | return self.worldModel or self.class.worldModel 73 | end 74 | 75 | function Item:getIconControl( ) 76 | return "DItemIcon" 77 | end 78 | 79 | -- Pre save we make sure to update the itempersistence_id field which is 80 | -- directly linked to the item persistence constraint of Pointshop 2 81 | -- to prevent DB corruption 82 | function Item:preSave() 83 | if self.class._persistenceId != "STATIC" then 84 | self.itempersistence_id = self.class.className 85 | end 86 | return Promise.Resolve() 87 | end 88 | 89 | function Item:canStack(item) 90 | return self.class.name == item.class.name 91 | end 92 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_0_bootstrap.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | # Include all item bases 3 | This includes all item bases in kinv/items, applying base classes 4 | and mixins and makes them available in KInventory.Items. 5 | ]]-- 6 | KInventory.loadAllItems( ) 7 | hook.Add( "OnReloaded", "PS2_ReloadItems", function() 8 | if LibK.Debug then 9 | KInventory.loadAllItems() 10 | end 11 | end ) 12 | 13 | --[[ 14 | # Load Modules 15 | This includes all of the ps2 modules files in "lua/ps2/modules" after InitPostEntity. 16 | ]]-- 17 | LibK.InitPostEntityPromise:Then( function( ) 18 | Pointshop2.LoadModules() 19 | hook.Run( "PS2_ModulesLoaded" ) 20 | Pointshop2.ClientSettings.LoadSettings( ) 21 | end ) 22 | hook.Add( "OnReloaded", "PS2_ReloadModules", function() 23 | if LibK.Debug then 24 | Pointshop2.LoadModules() 25 | hook.Run( "PS2_ModulesLoaded" ) 26 | end 27 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/cl_DInfoPanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.header = vgui.Create( "DPanel", self ) 5 | self.header:Dock( TOP ) 6 | self.header:DockPadding( 10, 10, 10, 10 ) 7 | self.header.Paint = function( ) end 8 | function self.header:PerformLayout( ) 9 | self.title:SizeToContents( ) 10 | self:SizeToChildren( false, true ) 11 | self.icon:SetWide( self.icon:GetTall( ) ) 12 | end 13 | 14 | local icon = vgui.Create( "DImage", self.header ) 15 | icon:Dock( LEFT ) 16 | icon:SetSize( 32, 32 ) 17 | self.header.icon = icon 18 | 19 | local title = vgui.Create( "DLabel", self.header ) 20 | title:Dock( TOP ) 21 | title:DockMargin( 5, 0, 0, 0 ) 22 | self.header.title = title 23 | 24 | self.content = vgui.Create( "DMultilineLabel", self ) 25 | self.content:DockMargin( 5, 0, 5, 0 ) 26 | self.content:Dock( TOP ) 27 | end 28 | 29 | function PANEL:SetSmall( small ) 30 | self.small = small 31 | end 32 | 33 | function PANEL:ApplySchemeSettings( ) 34 | if self.small then 35 | self.header.title:SetFont( self:GetSkin( ).fontName ) 36 | self.header.title:SetTextColor( self:GetSkin( ).Colours.Label.Bright ) 37 | self.header.icon:SetSize( 16, 16 ) 38 | self.content.font = "DermaDefault" 39 | else 40 | self.header.title:SetFont( self:GetSkin( ).SmallTitleFont ) 41 | self.header.title:SetTextColor( self:GetSkin( ).Colours.Label.Bright ) 42 | self.content.font = self:GetSkin( ).fontName 43 | end 44 | end 45 | 46 | function PANEL:SetInfo( title, description, icon ) 47 | icon = icon or "pointshop2/info20.png" 48 | 49 | self.header.icon:SetMaterial( Material( icon, "noclamp smooth" ) ) 50 | self.header.title:SetText( title ) 51 | self.content:SetText( description ) 52 | end 53 | 54 | function PANEL:PerformLayout( ) 55 | self:SizeToChildren( false, true ) 56 | end 57 | 58 | Derma_Hook( PANEL, "Paint", "Paint", "InnerPanel" ) 59 | 60 | vgui.Register( "DInfoPanel", PANEL, "DPanel" ) 61 | 62 | local PANEL = {} 63 | 64 | function PANEL:Init( ) 65 | self.content:Remove( ) 66 | self.content = vgui.Create( "DHTML", self ) 67 | self.content:DockMargin( 5, 0, 5, 0 ) 68 | self.content:Dock( TOP ) 69 | self.content:SetTall( 200 ) 70 | end 71 | function PANEL:SetInfo( title, description, icon ) 72 | icon = icon or "pointshop2/info20.png" 73 | 74 | self.header.icon:SetMaterial( Material( icon, "noclamp smooth" ) ) 75 | self.header.title:SetText( title ) 76 | self.content:SetHTML( '
' .. description ) 77 | self.content:SizeToContents( ) 78 | end 79 | 80 | vgui.Register( "DInfoPanelHTML", PANEL, "DInfoPanel" ) 81 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_DMaterialSelector.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetSize( 25 + 64*8+63*4, 400 ) 6 | 7 | self:SetTitle( "Select a Material" ) 8 | 9 | local scroll = vgui.Create( "DScrollPanel", self ) 10 | scroll:Dock( FILL ) 11 | 12 | self.layout = vgui.Create( "DIconLayout", scroll ) 13 | self.layout:SetSpaceX( 5 ) 14 | self.layout:SetSpaceY( 5 ) 15 | self.layout:DockMargin( 0, 2, 0, 5 ) 16 | self.layout:SetWide( 25 + 64*8+63*4 ) 17 | end 18 | 19 | function PANEL:SetMaterials( dir, files ) 20 | local materials = {} 21 | for k, v in pairs( files ) do 22 | v = string.Replace( v, ".vmt", "" ) 23 | v = string.Replace( v, ".vtf", "" ) 24 | v = dir .. "/" .. v 25 | if not table.HasValue( materials, v ) then 26 | table.insert( materials, v ) 27 | end 28 | end 29 | 30 | for k, v in pairs( materials ) do 31 | local btn = self.layout:Add( "DImageButton" ) 32 | btn:SetSize( 64, 64 ) 33 | btn:SetImage( v ) 34 | function btn.DoClick( ) 35 | self.matName = v 36 | self:OnChange( ) 37 | self:Close( ) 38 | end 39 | end 40 | self.layout:InvalidateLayout( true ) 41 | end 42 | 43 | function PANEL:OnChange( ) 44 | --for overwriting 45 | end 46 | 47 | vgui.Register( "DMaterialSelector", PANEL, "DFrame" ) 48 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_clientSettings.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.ClientSettings = {} 2 | 3 | Pointshop2.ClientSettings.SettingsTable = { 4 | BasicSettings = { 5 | info = { 6 | label = "General Settings" 7 | }, 8 | LowendMode = { 9 | tooltip = "This turns all icons into simple icons to save performance", 10 | label = "Lowend Mode", 11 | value = false 12 | }, 13 | DrawDistance = { 14 | value = 20000, 15 | tooltip = "Distance that PAC items are drawn", 16 | label = "Item Draw Distance", 17 | }, 18 | VisualsDisabled = { 19 | label = "Disable Visuals", 20 | tooltip = "Disables all Pointshop2 ingame visuals (trails, hats, pets etc.)", 21 | value = false 22 | }, 23 | AutoconfirmSale = { 24 | label = "Autoconfirm selling items", 25 | tooltip = "Disables the confirmation when selling an item", 26 | value = false 27 | }, 28 | HoverPanelEnabled = { 29 | label = "Show hover panel", 30 | tooltip = "Displays information in inventory on hover", 31 | value = false 32 | } 33 | }, 34 | } 35 | 36 | function Pointshop2.ClientSettings.SaveSettings( settings ) 37 | Pointshop2.ClientSettings.Settings = settings 38 | file.Write( "pointshop2-settings.txt", util.TableToJSON( settings ) ) 39 | end 40 | 41 | function Pointshop2.ClientSettings.LoadSettings( ) 42 | local settings = util.JSONToTable( file.Read( "pointshop2-settings.txt" ) or "{}" ) 43 | 44 | Pointshop2.ClientSettings.Settings = {} 45 | Pointshop2.recursiveSettingsInitialize( Pointshop2.ClientSettings.SettingsTable, settings, Pointshop2.ClientSettings.Settings ) 46 | hook.Run( "PS2_ClientSettingsUpdated" ) 47 | 48 | KLogf( 5, "[PS2] Loaded client settings" ) 49 | end 50 | 51 | function Pointshop2.ClientSettings.GetSetting( path ) 52 | return Pointshop2.ClientSettings.Settings[path] 53 | end 54 | 55 | hook.Add( "PS2_ClientSettingsUpdated", "UpdatePACConvars", function( ) 56 | RunConsoleCommand( "pac_draw_distance", Pointshop2.ClientSettings.GetSetting( "BasicSettings.DrawDistance" ) ) 57 | if IsValid( Pointshop2.Menu ) then 58 | if Pointshop2.Menu.LowendModeEnabled != Pointshop2.ClientSettings.GetSetting( "BasicSettings.LowendMode" ) then 59 | Pointshop2.Menu:Remove( ) 60 | Pointshop2.OpenMenu( ) 61 | end 62 | end 63 | end ) 64 | 65 | hook.Add("OnReloaded", "reloadsettingsclient", function() 66 | if LibK.Debug then 67 | Pointshop2.ClientSettings.LoadSettings( ) 68 | end 69 | end) -------------------------------------------------------------------------------- /lua/ps2/client/cl_dloadingnotifier.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | AccessorFunc( PANEL, "openSize", "OpenSize" ) 4 | 5 | function PANEL:Init( ) 6 | self:SetOpenSize( 50 ) 7 | 8 | self.loadingText = vgui.Create( "DLabel", self ) 9 | self.loadingText:Dock( FILL ) 10 | self.loadingText:SetText( "Loading..." ) 11 | self.loadingText:SetContentAlignment( 5 ) 12 | 13 | self:SetTall( 0 ) 14 | end 15 | 16 | function PANEL:Expand( ) 17 | self:SizeTo( self:GetWide( ), self:GetOpenSize( ), 0.3 ) 18 | end 19 | 20 | function PANEL:Collapse( ) 21 | self:SizeTo( self:GetWide( ), 0, 0.3 ) 22 | end 23 | 24 | function PANEL:Think( ) 25 | local dots = string.rep( ".", math.floor( CurTime( ) % 3 + 1 ) ) 26 | self.loadingText:SetText( "Loading" .. dots ) 27 | end 28 | 29 | function PANEL:Paint( w, h ) 30 | surface.SetDrawColor( self:GetSkin( ).Highlight ) 31 | surface.DrawRect( 4, self:GetTall() - 10, self:GetWide() - 8, 5 ) 32 | 33 | surface.SetDrawColor( 50, 50, 0, 255 ) 34 | surface.DrawRect( 5, self:GetTall() - 9, self:GetWide() - 10, 3 ) 35 | 36 | local w = self:GetWide() * 0.25 37 | local x = math.fmod( SysTime() * 200, self:GetWide() + w ) - w 38 | 39 | if ( x + w > self:GetWide() - 11 ) then w = ( self:GetWide() - 11 ) - x end 40 | if ( x < 0 ) then w = w + x; x = 0 end 41 | 42 | surface.SetDrawColor( self:GetSkin( ).Highlight ) 43 | surface.DrawRect( 5 + x, self:GetTall() - 9, w, 3 ) 44 | end 45 | 46 | 47 | derma.DefineControl( "DLoadingNotifier", "", PANEL, "DPanel" ) 48 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_dmultilinelabel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init() 4 | self:SetVerticalScrollbarEnabled( false ) 5 | self.maxHeight = false 6 | self._lastNumLines = 0 7 | self.textHeight = 12 8 | end 9 | 10 | function PANEL:SetMaxHeight( maxHeight ) 11 | self.maxHeight = maxHeight 12 | end 13 | 14 | function PANEL:Think() 15 | if self:GetNumLines() != self._lastNumLines then 16 | self._lastNumLines = self:GetNumLines() 17 | self:SizeToContents() 18 | self:SetFontInternal( self.font or self:GetSkin( ).TextFont or "Default" ) 19 | self:InvalidateParent() 20 | end 21 | self:SetFontInternal( self.font or self:GetSkin( ).TextFont or "Default" ) 22 | end 23 | 24 | function PANEL:Paint() 25 | self.textHeight = draw.GetFontHeight( self.font or self:GetSkin( ).TextFont or "Default" ) 26 | end 27 | 28 | function PANEL:SizeToContents() 29 | self:SetTall( math.max(self:GetNumLines( ) * self.textHeight * 1.2 + 5, self.textHeight * 1.2 * 2 ) ) 30 | 31 | if self.maxHeight then 32 | if self:GetTall( ) > self.maxHeight then 33 | self:SetTall( self.maxHeight ) 34 | self:SetVerticalScrollbarEnabled( true ) 35 | else 36 | self:SetVerticalScrollbarEnabled( false ) 37 | end 38 | end 39 | 40 | self:SetTall( self:GetTall() ) 41 | end 42 | 43 | vgui.Register( "DMultilineLabel", PANEL, "RichText" ) 44 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_dpointshophaticon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | end 5 | 6 | function PANEL:PerformLayout() 7 | self.BaseClass.PerformLayout(self) 8 | 9 | self.Label:SetWide(self:GetWide()) 10 | self.Label:SetPos(0, self:GetTall() - 25) 11 | self.Label:SetTall(25) 12 | end 13 | 14 | function PANEL:SetItemClass( itemClass ) 15 | if itemClass.iconInfo.shop.useMaterialIcon then 16 | DPointshopItemIcon.SetItemClass( self, itemClass ) 17 | if Material(itemClass.iconInfo.shop.iconMaterial) then 18 | self.image:SetImage( itemClass.iconInfo.shop.iconMaterial ) 19 | else 20 | self.image.Paint = function(p,w,h) 21 | surface.SetDrawColor(255, 0, 0) 22 | surface.DrawRect(0, 0, w, h) 23 | draw.SimpleTextOutlined( "Invalid Material", self:GetSkin().fontName, w / 2, h / 2, Color(0, 0, 0), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 0, color_white ) 24 | end 25 | LibK.GLib.Error("Invalid Material :" .. tostring(itemClass.iconInfo.shop.iconMaterial) .. " for item " .. itemClass:GetPrintName()) 26 | end 27 | else 28 | -- Delegate to DCsgoItemIcon 29 | self.BaseClass.SetItemClass( self, itemClass ) 30 | end 31 | end 32 | 33 | function PANEL:SetItem( item ) 34 | self:SetItemClass( item.class ) 35 | end 36 | 37 | function PANEL:OnSelected( ) 38 | hook.Run( "PACItemSelected", self.itemClass ) 39 | end 40 | 41 | function PANEL:OnDeselected( ) 42 | hook.Run( "PACItemDeSelected", self.itemClass ) 43 | end 44 | 45 | derma.DefineControl( "DPointshopHatIcon", "", PANEL, "DCsgoItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/client/cl_dradiochoice.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.Choices = {} 5 | end 6 | 7 | function PANEL:AddOption( optionText, forceNoCheck ) 8 | local choice = vgui.Create( "DCheckBoxLabel", self ) 9 | choice.ID = table.insert( self.Choices, choice ) 10 | choice:SetText( optionText ) 11 | Derma_Hook( choice.Button, "Paint", "Paint", "RadioButton" ) 12 | 13 | function choice.OnChange( pnl, val ) 14 | self:ChoiceSelected( pnl, val ) 15 | end 16 | 17 | local setValue = choice.Button.SetValue 18 | function choice.Button.SetValue( btn, value ) 19 | if self:GetSelectedOption( ) and self:GetSelectedOption( ).Button == btn then 20 | if not value then 21 | return 22 | end 23 | end 24 | setValue( btn, value ) 25 | end 26 | 27 | if #self.Choices > 1 then 28 | choice:DockMargin( 0, 5, 0, 0 ) 29 | end 30 | 31 | choice:Dock( TOP ) 32 | 33 | if #self:GetChildren( ) == 1 and not forceNoCheck then 34 | self:SelectChoice( 1 ) 35 | end 36 | 37 | return choice 38 | end 39 | 40 | function PANEL:SelectChoice( id ) 41 | self:GetChildren( )[id]:SetChecked( true ) 42 | self:GetChildren( )[id]:OnChange( true ) 43 | end 44 | 45 | function PANEL:ChoiceSelected( pnl, val ) 46 | if val == false then return end 47 | 48 | for k, v in pairs( self.Choices ) do 49 | if not IsValid( v ) then continue end 50 | 51 | if v == pnl then 52 | continue 53 | end 54 | 55 | v:SetChecked( false ) 56 | end 57 | self:OnChange( ) 58 | end 59 | 60 | function PANEL:OnChange( ) 61 | --for override 62 | end 63 | 64 | function PANEL:GetSelectedOption( ) 65 | for k, v in pairs( self:GetChildren( ) ) do 66 | if v:GetChecked( ) then 67 | return v 68 | end 69 | end 70 | end 71 | 72 | function PANEL:SelectChoiceByText( txt ) 73 | for k, v in pairs( self:GetChildren( ) ) do 74 | if v:GetText( ) == txt then 75 | self:SelectChoice( k ) 76 | end 77 | end 78 | end 79 | 80 | function PANEL:Paint( ) 81 | end 82 | 83 | derma.DefineControl( "DRadioChoice", "", PANEL, "DPanel" ) 84 | -------------------------------------------------------------------------------- /lua/ps2/client/cl_inyourface.lua: -------------------------------------------------------------------------------- 1 | function Pointshop2.ItemInYourFace(itemIcon) 2 | Pointshop2.InYourFaceItem = vgui.Create("DPanel") 3 | Pointshop2.InYourFaceItem:SetSize(128, 128) 4 | Pointshop2.InYourFaceItem:SetPaintedManually(true) 5 | function Pointshop2.InYourFaceItem:Paint(w, h) 6 | surface.SetDrawColor(color_white) 7 | surface.DrawRect(0, 0, w, h) 8 | end 9 | 10 | itemIcon:SetParent(Pointshop2.InYourFaceItem) 11 | itemIcon:Dock(FILL) 12 | 13 | local start = Pointshop2.InYourFaceItem:GetWide() 14 | local diff = math.min(ScrW(), ScrH()) - start 15 | local promise, tween = LibK.tween( easing.outQuart, 0.5, function( p ) 16 | if not IsValid(Pointshop2.InYourFaceItem) then return end 17 | Pointshop2.InYourFaceItem.size = { start + diff * p, start + diff * p } 18 | end ) 19 | Pointshop2.InYourFaceItem.tween1 = tween 20 | timer.Simple(0.25, function() 21 | local promise, tween = LibK.tween( easing.outQuart, 0.25, function( p ) 22 | if not IsValid(Pointshop2.InYourFaceItem) then return end 23 | Pointshop2.InYourFaceItem.blend = 1 - p 24 | end ) 25 | Pointshop2.InYourFaceItem.tween2 = tween 26 | end) 27 | end 28 | 29 | hook.Add("DrawOverlay", "drawinyourface", function() 30 | if not IsValid(Pointshop2.InYourFaceItem) then 31 | return 32 | end 33 | 34 | if Pointshop2.InYourFaceItem.tween1 then 35 | if Pointshop2.InYourFaceItem.tween1:update() then 36 | return Pointshop2.InYourFaceItem:Remove() 37 | end 38 | end 39 | if Pointshop2.InYourFaceItem.tween2 then 40 | if Pointshop2.InYourFaceItem.tween2:update() then 41 | return Pointshop2.InYourFaceItem:Remove() 42 | end 43 | end 44 | 45 | local itemIcon = Pointshop2.InYourFaceItem 46 | surface.SetAlphaMultiplier(itemIcon.blend or 1) 47 | DisableClipping(true) 48 | 49 | local w, h = unpack(Pointshop2.InYourFaceItem.size) 50 | itemIcon:SetSize(w, h) 51 | Pointshop2.InYourFaceItem:SetPaintedManually(false) 52 | render.SetBlend(itemIcon.blend or 1) 53 | itemIcon:PaintAt( ScrW() / 2 - w / 2, ScrH() / 2 - h / 2 ) 54 | if itemIcon.SetAlpha then 55 | itemIcon:SetAlpha((itemIcon.blend or 1) * 255) 56 | end 57 | render.SetBlend(1) 58 | Pointshop2.InYourFaceItem:SetPaintedManually(true) 59 | 60 | DisableClipping(false) 61 | surface.SetAlphaMultiplier(1.0) 62 | end) -------------------------------------------------------------------------------- /lua/ps2/client/icons/cl_dcsgoitemicon.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Base for CSGO Style item icons (prerendered) 3 | ]]-- 4 | local PANEL = {} 5 | 6 | function PANEL:Init( ) 7 | self.image = vgui.Create( "DImage", self ) 8 | self.image:SetSize( 128, 128 ) 9 | self.image:SetMouseInputEnabled( false ) 10 | self.image:SetPos( 0, 0 ) 11 | 12 | self.Label:Dock( NODOCK ) 13 | function self.Label:Paint(w, h) 14 | surface.SetDrawColor( 47, 47, 47, 200 ) 15 | surface.DrawRect(0, 0, w, h) 16 | end 17 | end 18 | 19 | function PANEL:PerformLayout() 20 | DPointshopItemIcon.PerformLayout(self) 21 | 22 | self.Label:SetWide(self:GetWide()) 23 | self.Label:SetPos(0, self:GetTall() - self:GetTall() * 0.234375) 24 | self.Label:SetTall(self:GetTall() * 0.234375) 25 | end 26 | 27 | function PANEL:SetItemClass( itemClass ) 28 | DPointshopItemIcon.SetItemClass( self, itemClass ) 29 | Pointshop2.RequestIcon(itemClass):Then(function(icon) 30 | if IsValid(self) then 31 | self.image:SetMaterial(icon) 32 | end 33 | end) 34 | 35 | -- Listen if the icons get regenerated 36 | hook.Add("PS2_ItemIconChanged", self, function( uid, icon ) 37 | if Pointshop2.GetIconPath( itemClass ) == uid then 38 | if IsValid(self) then 39 | self.image:SetMaterial(icon) 40 | end 41 | end 42 | end ) 43 | end 44 | 45 | function PANEL:SetItem( item ) 46 | self:SetItemClass( item.class ) 47 | end 48 | 49 | local function drawOutlinedBox( x, y, w, h, thickness, clr ) 50 | surface.SetDrawColor( clr ) 51 | for i=0, thickness - 1 do 52 | surface.DrawOutlinedRect( x + i, y + i, w - i * 2, h - i * 2 ) 53 | end 54 | end 55 | 56 | function PANEL:PaintOver(w, h) 57 | DPointshopItemIcon.PaintOver(self, w, h) 58 | 59 | self.Label:SetPaintedManually(true) 60 | self.Label:PaintManual() 61 | self.Label:SetPaintedManually(false) 62 | 63 | if self.noSelect then 64 | return 65 | end 66 | 67 | local isChildHovered = self.IsHoveredRecursive and self:IsHoveredRecursive() or self:IsChildHovered( 2 ) 68 | if self.Selected or self.Hovered or isChildHovered then 69 | drawOutlinedBox( 0, 0, w, h, 3, self:GetSkin().Highlight ) 70 | end 71 | end 72 | 73 | function PANEL:SetRarity(rarityInfo) 74 | DPointshopItemIcon.SetRarity(self, rarityInfo, true) 75 | 76 | local rc = rarityInfo.color 77 | local c = Color(rarityInfo.color.r, rarityInfo.color.g, rarityInfo.color.b, 220) 78 | function self.Label:Paint(w, h) 79 | surface.SetDrawColor(c) 80 | surface.DrawRect(0, 0, w, h) 81 | end 82 | end 83 | 84 | function PANEL.PreloadIcon(itemClass) 85 | return Pointshop2.RequestIcon(itemClass) 86 | end 87 | 88 | function PANEL:SetAlpha(alpha) 89 | self.image:SetAlpha(alpha) 90 | end 91 | 92 | derma.DefineControl( "DCsgoItemIcon", "", PANEL, "DPointshopItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/client/icons/cl_dpointshopinventoryitemicon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.isInventoryIcon = true 5 | self:SetSkin( Pointshop2.Config.DermaSkin ) 6 | 7 | self:SetSize( 64, 64 ) 8 | 9 | self:SetMouseInputEnabled( false ) 10 | 11 | hook.Add( "PS2_InvItemIconSelected", self, function( _self, itemIcon, item ) 12 | local selected = self.Selected or ( self.stackPanel and self.stackPanel.Selected ) 13 | if itemIcon != self and selected then 14 | self.Selected = false 15 | if self.stackPanel then 16 | self.stackPanel.Selected = false 17 | end 18 | self:OnDeselected( ) 19 | end 20 | end ) 21 | hook.Add( "KInv_ItemsSplit", self, function( _self, info ) 22 | hook.Run( "PS2_InvItemIconSelected" ) 23 | 24 | if info.toSlot.itemStack.icon == self then 25 | self:Select( ) 26 | end 27 | end ) 28 | end 29 | 30 | function PANEL:SetItem( item ) 31 | self.item = item 32 | end 33 | 34 | function PANEL:DoRightClick() 35 | self:OpenMenu() 36 | end 37 | 38 | function PANEL:PaintOver( w, h ) 39 | if not self.item.class:IsValidForServer( Pointshop2.GetCurrentServerId( ) ) then 40 | surface.SetDrawColor( Color( 150, 100, 100, 150 ) ) 41 | surface.DrawRect( 0, 0, w, h ) 42 | end 43 | end 44 | 45 | function PANEL:OnSelected( ) 46 | end 47 | 48 | function PANEL:OnDeselected( ) 49 | end 50 | 51 | function PANEL:Select( ) 52 | self.Selected = true 53 | 54 | local item = self.item 55 | if self.stackPanel then 56 | self.stackPanel.Selected = true 57 | item = self.stackPanel.items[1] 58 | end 59 | 60 | hook.Run( "PS2_InvItemIconSelected", self, item, self.stackPanel ) 61 | self:OnSelected( ) 62 | end 63 | 64 | function PANEL:OnMousePressed( mcode ) 65 | self:GetParent( ):OnMousePressed( mcode ) 66 | DPanel.OnMousePressed( self, mcode ) 67 | self:Select( ) 68 | end 69 | 70 | Derma_Hook( PANEL, "Paint", "Paint", "PointshopInvItemIcon" ) 71 | 72 | derma.DefineControl( "DPointshopInventoryItemIcon", "", PANEL, "DPanel" ) 73 | -------------------------------------------------------------------------------- /lua/ps2/client/notifications/cl_DItemReceivedNotification.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self.lbl = vgui.Create( "DLabel", self ) 7 | self.lbl:SetText( "You received an item" ) 8 | self.lbl:SetFont( self:GetSkin( ).SmallTitleFont ) 9 | self.lbl:SizeToContents( ) 10 | self.lbl:Dock( TOP ) 11 | self.lbl:DockMargin( 10, 10, 10, -5 ) 12 | self.lbl:SetColor( self:GetSkin().Highlight ) 13 | 14 | self.duration = 5 15 | self.targetHeight = 100 16 | end 17 | 18 | function PANEL:SetItem( item ) 19 | self.item = item 20 | 21 | self.infoPnl = vgui.Create( "DPanel", self ) 22 | self.infoPnl:Dock( TOP ) 23 | self.infoPnl.Paint = function( ) end 24 | function self.infoPnl:PerformLayout( ) 25 | if IsValid(self.desc) then 26 | self.desc:DockMargin( self.icon:GetWide() + 10, 5, 0, 5 ) 27 | end 28 | 29 | self:SizeToChildren( false, true ) 30 | end 31 | 32 | self.infoPnl.desc = vgui.Create( item.class.GetPointshopDescriptionControl( ), self.infoPnl ) 33 | self.infoPnl.desc:SetItem( item, true ) 34 | self.infoPnl.desc:Dock( TOP ) 35 | 36 | self.infoPnl.icon = item:getNewInventoryIcon( ) 37 | self.infoPnl.icon:SetParent( self.infoPnl ) 38 | self.infoPnl.icon:SetPos( 5, 5 ) 39 | self.infoPnl.icon:SetSize( 64, 64 ) 40 | end 41 | 42 | function PANEL:Think( ) 43 | self.done = self.done or 1 44 | if self.done < 10 then 45 | local x = self:GetTall( ) 46 | self:SetTall( 1000 ) 47 | self.infoPnl:InvalidateLayout( true ) 48 | local _, y = self.infoPnl:GetPos( ) 49 | self.targetHeight = y + self.infoPnl:GetTall( ) + 10 50 | self:SetTall( x ) 51 | self.done = self.done + 1 52 | end 53 | end 54 | 55 | function PANEL:Paint( ) 56 | 57 | end 58 | 59 | vgui.Register( "DItemReceivedNotification", PANEL, "DPanel" ) 60 | -------------------------------------------------------------------------------- /lua/ps2/client/notifications/cl_KNotificationPanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self.iconContainer = vgui.Create( "DPanel", self ) 7 | self.iconContainer:DockMargin( 5, 5, 5, 5 ) 8 | self.iconContainer:Dock( LEFT ) 9 | self.iconContainer:SetWide( 16 ) 10 | function self.iconContainer:Paint( ) end 11 | 12 | self.icon = vgui.Create( "DImage", self.iconContainer ) 13 | self.icon:Dock( TOP ) 14 | 15 | self.descriptionLabel = vgui.Create( "DMultilineLabel", self ) 16 | self.descriptionLabel.font = self:GetSkin( ).TextFont 17 | self.descriptionLabel:DockMargin( 5, 5, 5, 5 ) 18 | self.descriptionLabel:Dock( TOP ) 19 | 20 | self.targetHeight = 100 21 | self.duration = 10 22 | end 23 | 24 | function PANEL:setText( str ) 25 | self.descriptionLabel:SetText( str ) 26 | end 27 | 28 | function PANEL:PerformLayout() 29 | self:RecalculateTargetSize() 30 | end 31 | 32 | function PANEL:RecalculateTargetSize() 33 | local targetHeight = 0 34 | for k, v in ipairs( self:GetChildren( ) ) do 35 | local x, y = v:GetPos() 36 | targetHeight = math.max( targetHeight, y + v:GetTall() ) 37 | end 38 | 39 | self.targetHeight = targetHeight + 7 40 | end 41 | 42 | function PANEL:setIcon( icon ) 43 | self.icon:SetImage( icon ) 44 | self.icon:SizeToContents( ) 45 | end 46 | 47 | Derma_Hook( PANEL, "Paint", "Paint", "InnerPanelBright" ) 48 | 49 | derma.DefineControl( "KNotificationPanel", "Simple Notification panel", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/notifications/cl_pointfeed.lua: -------------------------------------------------------------------------------- 1 | local function createPointFeed( ) 2 | if IsValid( GAMEMODE.PS2_PF ) then 3 | GAMEMODE.PS2_PF:Remove( ) -- for reloads 4 | end 5 | 6 | Pointshop2.PointFeed = vgui.Create( "DPointFeed" ) 7 | Pointshop2.PointFeed:SetSize( ScrW( ) / 3, ScrH( ) / 5 ) 8 | Pointshop2.PointFeed:ParentToHUD( ) 9 | Pointshop2.PointFeed:SetPos( ScrW( ) / 2 - Pointshop2.PointFeed:GetWide( ) / 2, ScrH( ) - Pointshop2.PointFeed:GetTall( ) - 20 ) 10 | GAMEMODE.PS2_PF = Pointshop2.PointFeed 11 | end 12 | 13 | hook.Add( "InitPostEntity", "AddPointFeed", function( ) 14 | createPointFeed( ) 15 | end ) 16 | 17 | hook.Add( "OnReloaded", "AddPointFeed", function( ) 18 | if LibK.Debug then 19 | createPointFeed( ) 20 | end 21 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/inventory_tab/cl_0_dpointshopinventorytab.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.InventoryPanels = { } 2 | function Pointshop2:AddInventoryPanel( label, icon, controlName, shouldShow ) 3 | table.insert( Pointshop2.InventoryPanels, { label = label, icon = icon, controlName = controlName, shouldShow = shouldShow } ) 4 | end 5 | 6 | function Pointshop2:AddInventoryButton( label, icon, onClickFn, shouldShow ) 7 | table.insert( Pointshop2.InventoryPanels, { 8 | label = label, 9 | icon = icon, 10 | onClickFn = onClickFn, 11 | shouldShow = shouldShow 12 | } ) 13 | end 14 | 15 | local PANEL = {} 16 | 17 | function PANEL:Init( ) 18 | self.panels = {} 19 | for k, btnInfo in pairs( Pointshop2.InventoryPanels ) do 20 | if btnInfo.shouldShow and not btnInfo.shouldShow() then 21 | continue 22 | end 23 | 24 | if btnInfo.controlName then 25 | local panel = vgui.Create( btnInfo.controlName ) 26 | self:addMenuEntry( btnInfo.label, btnInfo.icon, panel ) 27 | self.panels[btnInfo.label] = panel 28 | else 29 | self:addMenuButton( btnInfo.label, btnInfo.icon, btnInfo.onClickFn ) 30 | end 31 | end 32 | end 33 | 34 | function PANEL:GetPanel(name) 35 | return self.panels[name] 36 | end 37 | 38 | Derma_Hook( PANEL, "Paint", "Paint", "PointshopInventoryTab" ) 39 | derma.DefineControl( "DPointshopInventoryTab", "", PANEL, "DPointshopMenuedTab" ) 40 | 41 | Pointshop2:AddTab( "Inventory", "DPointshopInventoryTab" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/inventory_tab/cl_dpointshopinventorypreviewpanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | hook.Call( "PS2_InvPreviewPanelPaint_Init", GAMEMODE, self ) 5 | end 6 | 7 | function PANEL:Paint( w, h ) 8 | --You can use this to overwrite the entire preview rendering 9 | if hook.Call( "PS2_InvPreviewPanelPaint", GAMEMODE, self ) == false then 10 | return 11 | end 12 | 13 | derma.SkinHook( "Paint", "InnerPanel", self, w, h ) 14 | 15 | if ( !IsValid( self.Entity ) ) then return end 16 | 17 | local x, y = self:LocalToScreen( 0, 0 ) 18 | 19 | self:LayoutEntity( self.Entity ) 20 | 21 | local ang = self.aLookAngle 22 | if ( !ang ) then 23 | ang = (self.vLookatPos-self.vCamPos):Angle() 24 | end 25 | 26 | hook.Call( "PS2_InvPreviewPanelPaint_PreStart3D", GAMEMODE, self ) 27 | 28 | local w, h = self:GetSize() 29 | cam.Start3D( self.vCamPos, ang, self.fFOV, x, y, w, h, 5, self.FarZ ) 30 | cam.IgnoreZ( true ) 31 | 32 | render.SuppressEngineLighting( true ) 33 | render.SetLightingOrigin( self.Entity:GetPos() ) 34 | render.ResetModelLighting( self.colAmbientLight.r/255, self.colAmbientLight.g/255, self.colAmbientLight.b/255 ) 35 | render.SetColorModulation( self.colColor.r/255, self.colColor.g/255, self.colColor.b/255 ) 36 | render.SetBlend( self.colColor.a/255 ) 37 | 38 | for i=0, 6 do 39 | local col = self.DirectionalLight[ i ] 40 | if ( col ) then 41 | render.SetModelLighting( i, col.r/255, col.g/255, col.b/255 ) 42 | end 43 | end 44 | 45 | hook.Run( "PS2_InvPreviewPanelPaint_PreDrawModel", self ) 46 | self.Entity:DrawModel() 47 | hook.Run( "PS2_InvPreviewPanelPaint_PostDrawModel", self ) 48 | 49 | render.SuppressEngineLighting( false ) 50 | cam.IgnoreZ( false ) 51 | cam.End3D() 52 | 53 | hook.Run( "PS2_InvPreviewPanelPaint_PostStart3D", self ) 54 | 55 | self.LastPaint = RealTime() 56 | end 57 | 58 | 59 | derma.DefineControl( "DPointshopInventoryPreviewPanel", "", PANEL, "DPointshopPreviewPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/inventory_tab/cl_z_DPointshopClientSettings.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self:DockPadding( 10, 0, 10, 10 ) 7 | 8 | local label = vgui.Create( "DLabel", self ) 9 | label:SetText( "Local Settings" ) 10 | label:SetColor( color_white ) 11 | label:SetFont( self:GetSkin( ).TabFont ) 12 | label:SizeToContents( ) 13 | label:Dock( TOP ) 14 | label:DockMargin( 0, 8, 0, 8 ) 15 | 16 | self.scroll = vgui.Create( "DScrollPanel", self ) 17 | self.scroll:Dock( FILL ) 18 | 19 | self.actualSettings = vgui.Create( "DSettingsPanel", self.scroll ) 20 | self.actualSettings:Dock( TOP ) 21 | self.actualSettings:AutoAddSettingsTable( Pointshop2.ClientSettings.SettingsTable ) 22 | self.actualSettings:DockMargin( 0, 0, 0, 5 ) 23 | self.actualSettings:SetWide( 250 ) 24 | self.actualSettings:SetData( Pointshop2.ClientSettings.Settings ) 25 | 26 | self.buttonBar = vgui.Create( "DIconLayout", self.scroll ) 27 | self.buttonBar:SetBorder( 0 ) 28 | self.buttonBar:SetSpaceX( 5 ) 29 | self.buttonBar:DockMargin( 0, 0, 0, 0 ) 30 | self.buttonBar:Dock( TOP ) 31 | 32 | self.saveButton = vgui.Create( "DButton", self.buttonBar ) 33 | self.saveButton:SetText( "Save" ) 34 | self.saveButton:SetSize( 80, 25 ) 35 | self.saveButton:PerformLayout( ) 36 | self.saveButton:Paint( 10, 10 ) 37 | function self.saveButton.DoClick( ) 38 | Pointshop2.ClientSettings.SaveSettings( self.actualSettings.settings ) 39 | Pointshop2.ClientSettings.LoadSettings( ) 40 | Derma_Message( "Your settings have been saved. Some settings may require a reconnect to apply." ) 41 | end 42 | 43 | self.infoPanel = vgui.Create( "DInfoPanel", self.scroll ) 44 | self.infoPanel:Dock( TOP ) 45 | self.infoPanel:SetInfo( "Regenerate Icons", 46 | [[If you have trouble with icons you can regenerate all shop icons here. 47 | 48 | ]] ) 49 | self.infoPanel:DockMargin( 0, 10, 0, 0 ) 50 | 51 | self.buttonBar2 = vgui.Create( "DIconLayout", self.scroll ) 52 | self.buttonBar2:SetBorder( 0 ) 53 | self.buttonBar2:SetSpaceX( 5 ) 54 | self.buttonBar2:DockMargin( 0, 5, 0, 0 ) 55 | self.buttonBar2:Dock( TOP ) 56 | 57 | self.newItemsButton = vgui.Create( "DButton", self.buttonBar2 ) 58 | self.newItemsButton:SetText( "Regenerate Icons" ) 59 | self.newItemsButton:PerformLayout( ) 60 | self.newItemsButton:Paint( 10, 10 ) 61 | self.newItemsButton:SizeToContents() 62 | self.newItemsButton:SetTall( 25 ) 63 | function self.newItemsButton.DoClick( ) 64 | Pointshop2View:getInstance():RegenerateIcons( ) 65 | end 66 | end 67 | 68 | function PANEL:Paint( ) 69 | end 70 | 71 | 72 | derma.DefineControl( "DPointshopClientSettings", "", PANEL, "DPanel" ) 73 | 74 | Pointshop2:AddInventoryPanel( "My Settings", "pointshop2/advanced.png", "DPointshopClientSettings" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_dbigbutton.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSize( 120, 144 ) 5 | 6 | self.icon = vgui.Create( "DImage", self ) 7 | self.icon:Dock( FILL ) 8 | self.icon:DockMargin( 10, 10, 10, 10 ) 9 | self.icon:SetTall( 100 - 24 ) 10 | 11 | self.label = vgui.Create( "DLabel", self ) 12 | 13 | self.label:Dock( BOTTOM ) 14 | self.label:SetContentAlignment( 5 ) 15 | self.label:SetTall( 24 ) 16 | Derma_Hook( self.label, "Paint", "Paint", "BigButtonLabel" ) 17 | 18 | self:SetMouseInputEnabled( true ) 19 | self:SetKeyboardInputEnabled( true ) 20 | 21 | derma.SkinHook( "Layout", "BigButton", self ) 22 | end 23 | 24 | function PANEL:ApplySchemeSettings( ) 25 | self.label:SetFont( self:GetSkin( ).textFont or "DermaDefault" ) 26 | end 27 | 28 | Derma_Hook( PANEL, "Paint", "Paint", "BigButton" ) 29 | 30 | derma.DefineControl( "DBigButton", "", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_ddlcbutton.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSize( 120, 144 ) 5 | 6 | self.icon:Remove( ) 7 | self.icon = vgui.Create( "DCenteredImage", self ) 8 | self.icon:Dock( FILL ) 9 | self.icon:DockMargin( 10, 10, 10, 10 ) 10 | self.icon:SetTall( 100 - 24 ) 11 | self.icon:SetMouseInputEnabled( false ) 12 | 13 | self.badge = vgui.Create( "DLabel", self ) 14 | self.badge:Dock( TOP ) 15 | self.badge:SetContentAlignment( 5 ) 16 | self.badge:SetTall( 24 ) 17 | Derma_Hook( self.badge, "Paint", "Paint", "BigButtonLabel" ) 18 | end 19 | 20 | function PANEL:SetDlc( dlc ) 21 | self.dlc = dlc 22 | 23 | self.label:SetText( dlc.name ) 24 | self.icon:SetMaterial( Material( dlc.icon, "noclamp smooth" ) ) 25 | 26 | if dlc.isOwned( ) then 27 | self.badge:SetText( "Owned" ) 28 | self.badge:SetFont( self:GetSkin().SmallTitleFont ) 29 | self.badge:SetColor( Color( 0, 255, 0 ) ) 30 | else 31 | self.badge:SetText( "Not Owned" ) 32 | self.badge:SetColor( Color( 255, 0, 0, 100 ) ) 33 | self.icon:SetImageColor( Color( 150, 150, 150 ) ) 34 | end 35 | end 36 | 37 | function PANEL:OnMousePressed( mcode ) 38 | gui.OpenURL( self.dlc.dlcLink ) 39 | end 40 | 41 | function PANEL:ApplySchemeSettings( ) 42 | self.badge:SetFont( self:GetSkin( ).TextFont or "DermaDefault" ) 43 | end 44 | 45 | Derma_Hook( PANEL, "Paint", "Paint", "BigButton" ) 46 | 47 | derma.DefineControl( "DDlcButton", "", PANEL, "DBigButton" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_dpointshopmanagementtab.lua: -------------------------------------------------------------------------------- 1 | --Interface 2 | Pointshop2.AdminPanels = { } 3 | 4 | function Pointshop2:AddManagementPanel( label, icon, controlName, shouldShow ) 5 | table.insert( Pointshop2.AdminPanels, { label = label, icon = icon, controlName = controlName, shouldShow = shouldShow } ) 6 | end 7 | 8 | --Tab Control 9 | local PANEL = {} 10 | 11 | function PANEL:Init( ) 12 | self:SetSkin( Pointshop2.Config.DermaSkin ) 13 | 14 | for k, btnInfo in pairs( Pointshop2.AdminPanels ) do 15 | if btnInfo.shouldShow and not btnInfo.shouldShow() then 16 | continue 17 | end 18 | 19 | local panel = vgui.Create( btnInfo.controlName ) 20 | self:addMenuEntry( btnInfo.label, btnInfo.icon, panel ) 21 | end 22 | end 23 | 24 | --Derma_Hook( PANEL, "Paint", "Paint", "PointshopManagementTab" ) 25 | derma.DefineControl( "DPointshopManagementTab", "", PANEL, "DPointshopMenuedTab" ) 26 | 27 | Pointshop2:AddTab( "Management", "DPointshopManagementTab", function( ) 28 | --Only show the management tab if user has access to at least on admin panel 29 | for k, v in pairs( Pointshop2.AdminPanels ) do 30 | if v.shouldShow( ) then 31 | return true 32 | end 33 | end 34 | return false 35 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_dpointshopmanagementtab_createitem.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | local scroll = vgui.Create( "DScrollPanel", self ) 7 | scroll:Dock( FILL ) 8 | scroll:GetCanvas( ):DockPadding( 0, 0, 5, 5 ) 9 | 10 | self:DockPadding( 10, 0, 10, 10 ) 11 | 12 | local label = vgui.Create( "DLabel", scroll:GetCanvas( ) ) 13 | label:SetText( "Select an item type" ) 14 | label:SetColor( color_white ) 15 | label:SetFont( self:GetSkin( ).TabFont ) 16 | label:DockMargin( 0, 8, 0, 8 ) 17 | label:SizeToContents( ) 18 | label:Dock( TOP ) 19 | 20 | self.panels = vgui.Create( "DPanel", scroll:GetCanvas( ) ) 21 | self.panels.Paint = function( a, w, h ) 22 | end 23 | function self.panels:PerformLayout( ) 24 | self:SizeToChildren( false, true ) 25 | end 26 | self.panels:Dock( TOP ) 27 | 28 | for k, mod in pairs( Pointshop2.Modules ) do 29 | if not mod.Blueprints or #mod.Blueprints == 0 then 30 | continue 31 | end 32 | 33 | local modPanel = vgui.Create( "DPanel", self.panels ) 34 | Derma_Hook( modPanel, "Paint", "Paint", "InnerPanel" ) 35 | modPanel:DockMargin( 0, 5, 0, 5 ) 36 | modPanel:DockPadding( 8, 8, 8, 8 ) 37 | modPanel:Dock( TOP ) 38 | function modPanel:PerformLayout( ) 39 | self.items:SizeToChildren( false, true ) 40 | self:SizeToChildren( false, true ) 41 | end 42 | 43 | modPanel.label = vgui.Create( "DLabel", modPanel ) 44 | modPanel.label:DockMargin( 0, -5, 0, 8 ) 45 | modPanel.label:SetFont( self:GetSkin( ).SmallTitleFont ) 46 | modPanel.label:SetText( mod.Name ) 47 | modPanel.label:SizeToContents( ) 48 | modPanel.label:Dock( TOP ) 49 | 50 | modPanel.items = vgui.Create( "DIconLayout", modPanel ) 51 | modPanel.items:SetSpaceX( 5 ) 52 | modPanel.items:SetSpaceY( 5 ) 53 | modPanel.items:DockMargin( 0, 0, 8, 0 ) 54 | modPanel.items:Dock( TOP ) 55 | 56 | for _, itemInfo in pairs( mod.Blueprints ) do 57 | local iconButton = modPanel.items:Add( "DCreateItemButton" ) 58 | iconButton:SetItemInfo( itemInfo ) 59 | end 60 | end 61 | derma.SkinHook( "Layout", "DPointshopManagementTab_CreateItem", self ) 62 | end 63 | 64 | function PANEL:Paint( ) 65 | end 66 | 67 | derma.DefineControl( "DPointshopManagementTab_CreateItem", "", PANEL, "DPanel" ) 68 | 69 | Pointshop2:AddManagementPanel( "Create Items", "pointshop2/wizard.png", "DPointshopManagementTab_CreateItem", function( ) 70 | return PermissionInterface.query( LocalPlayer(), "pointshop2 createitems" ) 71 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_dpointshopmanagementtab_exportimport.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self:DockPadding( 10, 0, 10, 10 ) 7 | 8 | local label = vgui.Create( "DLabel", self ) 9 | label:SetText( "Export or import Pointshop 2 data" ) 10 | label:SetColor( color_white ) 11 | label:DockMargin( 0, 8, 0, 8 ) 12 | label:SetFont( self:GetSkin( ).TabFont ) 13 | label:SizeToContents( ) 14 | label:Dock( TOP ) 15 | 16 | local modPanel = vgui.Create( "DPanel", self ) 17 | Derma_Hook( modPanel, "Paint", "Paint", "InnerPanel" ) 18 | modPanel:DockMargin( 0, 5, 0, 5 ) 19 | modPanel:DockPadding( 8, 8, 8, 8 ) 20 | modPanel:Dock( TOP ) 21 | function modPanel:PerformLayout( ) 22 | self.items:SizeToChildren( false, true ) 23 | self:SizeToChildren( false, true ) 24 | end 25 | 26 | modPanel.label = vgui.Create( "DLabel", modPanel ) 27 | modPanel.label:DockMargin( 0, -5, 0, 8 ) 28 | modPanel.label:SetFont( self:GetSkin( ).SmallTitleFont ) 29 | modPanel.label:SetText( "Select an action" ) 30 | modPanel.label:SizeToContents( ) 31 | modPanel.label:Dock( TOP ) 32 | 33 | modPanel.items = vgui.Create( "DIconLayout", modPanel ) 34 | modPanel.items:SetSpaceX( 5 ) 35 | modPanel.items:SetSpaceY( 5 ) 36 | modPanel.items:DockMargin( 0, 0, 8, 0 ) 37 | modPanel.items:Dock( TOP ) 38 | 39 | for label, btnInfo in pairs{ 40 | Export = { func = self.ExportItems, icon = "pointshop2/small65.png" }, 41 | Import = { func = self.ImportItems, icon = "pointshop2/download7.png" } 42 | } 43 | do 44 | local button = modPanel.items:Add( "DBigButton" ) 45 | button.icon:SetImage( btnInfo.icon ) 46 | button.label:SetText( label ) 47 | button.DoClick = function( ) 48 | func( self ) 49 | end 50 | end 51 | 52 | derma.SkinHook( "Layout", "DPointshopManagementTab_ExportImport", self ) 53 | end 54 | 55 | function PANEL:ExportItems( ) 56 | Pointshop2View:getInstance( ):exportItems( ) 57 | end 58 | 59 | function PANEL:ImportItems( itemFile ) 60 | Pointshop2View:getInstance( ):importItems( itemFile ) 61 | end 62 | 63 | function PANEL:Paint( ) 64 | end 65 | 66 | derma.DefineControl( "DPointshopManagementTab_ExportImport", "", PANEL, "DPanel" ) 67 | 68 | Pointshop2:AddManagementPanel( "Export / Import", "pointshop2/two259.png", "DPointshopManagementTab_ExportImport", function( ) 69 | --Experimental Feature, Currently hardcoded to devs 70 | return table.HasValue( { 71 | "STEAM_0:0:19299911", 72 | "STEAM_0:0:39587206" 73 | }, LocalPlayer():SteamID( ) ) 74 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/cl_dpointshopmanagementtab_items.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | local loading = vgui.Create( "DLoadingNotifier", self ) 7 | loading:Dock( TOP ) 8 | hook.Add( "PS2_PreReload", "Loading", function( ) 9 | loading:Expand( ) 10 | end ) 11 | 12 | self.contentPanel = vgui.Create( "DPointshopContentPanel", self ) 13 | self.contentPanel:Dock( FILL ) 14 | self.contentPanel:EnableModify( ) 15 | self.contentPanel:CallPopulateHook( "PS2_PopulateContent" ) 16 | 17 | --Recreate content panel if items change 18 | hook.Add( "PS2_DynamicItemsUpdated", self, function( ) 19 | self.contentPanel:Remove( ) 20 | self:Init( ) 21 | loading:Collapse( ) 22 | end ) 23 | 24 | derma.SkinHook( "Layout", "PointshopManagementTab_Items", self ) 25 | end 26 | 27 | function PANEL:Paint( ) 28 | end 29 | 30 | derma.DefineControl( "DPointshopManagementTab_Items", "", PANEL, "DPanel" ) 31 | 32 | Pointshop2:AddManagementPanel( "Manage Items", "pointshop2/settings12.png", "DPointshopManagementTab_Items", function( ) 33 | return PermissionInterface.query( LocalPlayer(), "pointshop2 manageitems" ) 34 | end ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/create_item/cl_1_DItemCreator_Stage.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self.items = {} 6 | end 7 | 8 | function PANEL:addFormItem( desc, panel ) 9 | local container = vgui.Create( "DPanel", self ) 10 | container:Dock( TOP ) 11 | container:DockMargin( 5, 5, 5, 5 ) 12 | function container:PerformLayout( ) 13 | self:SizeToChildren( false, true ) 14 | end 15 | function container:Paint( ) end 16 | 17 | local label = vgui.Create( "DLabel", container ) 18 | label:SetText( desc .. ":" ) 19 | label:Dock( LEFT ) 20 | label:SizeToContents( ) 21 | label:DockMargin( 0, 0, 5, 0 ) 22 | container.label = label 23 | 24 | function container:GetLabelWidth( ) 25 | return label:GetWide( ) 26 | end 27 | 28 | function container:SetLabelWidth( w ) 29 | label:SetWide( w ) 30 | end 31 | 32 | panel:SetParent( container ) 33 | panel:Dock( LEFT ) 34 | container.panel = panel 35 | 36 | table.insert( self.items, container ) 37 | 38 | return container 39 | end 40 | 41 | function PANEL:addSectionTitle( text ) 42 | local title = vgui.Create( "DLabel", self ) 43 | title:Dock( TOP ) 44 | title:SetFont( self:GetSkin().SmallTitleFont ) 45 | title:SetColor( self:GetSkin().Colours.Label.Bright ) 46 | title:SetText( text ) 47 | title:SizeToContents( ) 48 | title:DockMargin( 5, 5, 5, 10 ) 49 | end 50 | 51 | function PANEL:PerformLayout( ) 52 | local maxW = 0 53 | for k, v in pairs( self.items ) do 54 | if v:GetLabelWidth( ) > maxW then 55 | maxW = v:GetLabelWidth( ) 56 | end 57 | end 58 | 59 | for k, v in pairs( self.items ) do 60 | v:SetLabelWidth( maxW ) 61 | end 62 | 63 | local maxY = 0 64 | for k, v in pairs( self:GetChildren( ) ) do 65 | local x, y = v:GetPos( ) 66 | v:InvalidateLayout( true ) 67 | local endPos = y + v:GetTall( ) 68 | if endPos > maxY and v != self.buttonBar then 69 | maxY = endPos 70 | end 71 | end 72 | maxY = maxY + 5 --margin 73 | 74 | self:SetTall( maxY + 0 ) 75 | end 76 | 77 | function PANEL:NotifyLoading( bIsLoading ) 78 | self:GetParent( ):NotifyLoading( bIsLoading ) 79 | end 80 | 81 | derma.DefineControl( "DItemCreator_Stage", "Base for a item creator stage (step)", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/create_item/cl_dcreateitembutton.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | end 5 | 6 | function PANEL:OnMousePressed( ) 7 | local creator = vgui.Create( self.itemInfo.creator ) 8 | creator:MakePopup( ) 9 | creator:SetItemBase( self.itemInfo.base ) 10 | creator:SetSkin( Pointshop2.Config.DermaSkin ) 11 | creator:InvalidateLayout( true ) 12 | creator:Center( ) 13 | if not self.itemInfo.noModal then 14 | creator:DoModal() 15 | end 16 | end 17 | 18 | function PANEL:SetItemInfo( itemInfo ) 19 | self.icon:SetMaterial( Material( itemInfo.icon, "noclamp smooth" ) ) 20 | self.label:SetText( itemInfo.label ) 21 | self.itemInfo = itemInfo 22 | if itemInfo.tooltip then 23 | self:SetTooltip( itemInfo.tooltip ) 24 | end 25 | end 26 | 27 | derma.DefineControl( "DCreateItemButton", "", PANEL, "DBigButton" ) 28 | -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/attribution.txt.lua: -------------------------------------------------------------------------------- 1 | --Many of this stuff is a slightly modified copy of the Sandbox Spawn menu. 2 | --Because the addon needs to be usable outside of sandbox simple inheritance didn't do the job. 3 | -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/cl_DSelectRanks.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSize( 600, 400 ) 5 | self:SetSkin( Pointshop2.Config.DermaSkin ) 6 | self:SetTitle( "Item Rank Restrictions" ) 7 | 8 | self.infoPanel = vgui.Create( "DInfoPanel", self ) 9 | self.infoPanel:Dock( TOP ) 10 | self.infoPanel:SetInfo( "Rank Restriction", 11 | [[This can be used to restrict items to certain ranks. Items can only be purchased by users that have a rank from the list. 12 | 13 | Tick the ranks that you want ro restrict the item(s) to. If the item has no restriction (no boxes ticked) it can be bought by all ranks.]] ) 14 | self.infoPanel:DockMargin( 5, 5, 5, 5 ) 15 | 16 | self.scroll = vgui.Create( "DScrollPanel", self ) 17 | self.scroll:Dock( FILL ) 18 | self.scroll:DockMargin( 5, 5, 5, 5 ) 19 | 20 | Derma_Hook( self.scroll, "Paint", "Paint", "InnerPanel" ) 21 | 22 | self.ranksLayout = vgui.Create( "DIconLayout", self.scroll ) 23 | self.ranksLayout:Dock( TOP ) 24 | self.ranksLayout:DockMargin( 5, 5, 5, 5 ) 25 | self.ranksLayout:SetSpaceX( 10 ) 26 | self.ranksLayout:SetSpaceY( 5 ) 27 | 28 | self.checkBoxes = {} 29 | 30 | for k, rank in pairs( PermissionInterface.getRanks( ) ) do 31 | local chkBox = vgui.Create( "DCheckBoxLabel", self.ranksLayout ) 32 | chkBox:SetText( rank.title ) 33 | chkBox:SizeToContents( ) 34 | chkBox.OwnLine = true 35 | self.checkBoxes[rank.internalName] = chkBox 36 | end 37 | 38 | self.buttons = vgui.Create( "DPanel", self ) 39 | self.buttons:Dock( BOTTOM ) 40 | self.buttons:SetTall( 30 ) 41 | self.buttons.Paint = function( ) end 42 | self.buttons:DockMargin( 5, 5, 5, 5 ) 43 | 44 | self.save = vgui.Create( "DButton", self.buttons ) 45 | self.save:SetText( "Save" ) 46 | self.save:SetImage( "pointshop2/floppy1.png" ) 47 | self.save:SetWide( 180 ) 48 | self.save.m_Image:SetSize( 16, 16 ) 49 | self.save:Dock( RIGHT ) 50 | function self.save.DoClick( ) 51 | self:OnSave( ) 52 | self:Close( ) 53 | end 54 | end 55 | 56 | function PANEL:GetSelectedRanks( ) 57 | local rankNames = {} 58 | for internalName, box in pairs(self.checkBoxes) do 59 | if box:GetChecked( ) then 60 | table.insert( rankNames, internalName ) 61 | end 62 | end 63 | return rankNames 64 | end 65 | 66 | function PANEL:SetSelectedRanks( rankNames ) 67 | for k, name in pairs( rankNames ) do 68 | if self.checkBoxes[name] then 69 | self.checkBoxes[name]:SetValue( true ) 70 | end 71 | end 72 | end 73 | 74 | function PANEL:OnSave( ) 75 | --for override 76 | end 77 | 78 | vgui.Register( "DSelectRanks", PANEL, "DFrame" ) 79 | -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/cl_DSelectServers.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSize( 600, 400 ) 5 | self:SetSkin( Pointshop2.Config.DermaSkin ) 6 | self:SetTitle( "Item Server Restrictions" ) 7 | 8 | self.infoPanel = vgui.Create( "DInfoPanel", self ) 9 | self.infoPanel:Dock( TOP ) 10 | self.infoPanel:SetInfo( "Server Restriction", 11 | [[This can be used to restrict items to certain servers. Items are only equiped for the servers they are restricted to. 12 | 13 | Tick the servers that you want ro restrict the item(s) to. If the item has no restriction (no boxes ticked) it can be used on all servers.]] ) 14 | self.infoPanel:DockMargin( 5, 5, 5, 5 ) 15 | 16 | self.scroll = vgui.Create( "DScrollPanel", self ) 17 | self.scroll:Dock( FILL ) 18 | self.scroll:DockMargin( 5, 5, 5, 5 ) 19 | 20 | Derma_Hook( self.scroll, "Paint", "Paint", "InnerPanel" ) 21 | 22 | self.serversLayout = vgui.Create( "DIconLayout", self.scroll ) 23 | self.serversLayout:Dock( TOP ) 24 | self.serversLayout:DockMargin( 5, 5, 5, 5 ) 25 | self.serversLayout:SetSpaceX( 10 ) 26 | self.serversLayout:SetSpaceY( 5 ) 27 | 28 | self.checkBoxes = {} 29 | 30 | self.serverSelectPromise = Pointshop2View:getInstance( ):getServers( ) 31 | :Done( function( servers ) 32 | for k, server in pairs( servers ) do 33 | local chkBox = vgui.Create( "DCheckBoxLabel", self.serversLayout ) 34 | chkBox:SetText( server.name ) 35 | chkBox:SizeToContents( ) 36 | chkBox.OwnLine = true 37 | self.checkBoxes[server.id] = chkBox 38 | end 39 | end ) 40 | 41 | self.buttons = vgui.Create( "DPanel", self ) 42 | self.buttons:Dock( BOTTOM ) 43 | self.buttons:SetTall( 30 ) 44 | self.buttons.Paint = function( ) end 45 | self.buttons:DockMargin( 5, 5, 5, 5 ) 46 | 47 | self.save = vgui.Create( "DButton", self.buttons ) 48 | self.save:SetText( "Save" ) 49 | self.save:SetImage( "pointshop2/floppy1.png" ) 50 | self.save:SetWide( 180 ) 51 | self.save.m_Image:SetSize( 16, 16 ) 52 | self.save:Dock( RIGHT ) 53 | function self.save.DoClick( ) 54 | self:OnSave( ) 55 | self:Close( ) 56 | end 57 | end 58 | 59 | function PANEL:GetSelectedIds( ) 60 | local ids = {} 61 | for id, box in pairs(self.checkBoxes) do 62 | if box:GetChecked( ) then 63 | table.insert( ids, id ) 64 | end 65 | end 66 | return ids 67 | end 68 | 69 | function PANEL:SetSelectedServers( serverIds ) 70 | self.serverSelectPromise:Done( function( ) 71 | for k, id in pairs( serverIds ) do 72 | self.checkBoxes[id]:SetValue( true ) 73 | end 74 | end ) 75 | end 76 | 77 | function PANEL:OnSave( ) 78 | --for override 79 | end 80 | 81 | vgui.Register( "DSelectServers", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/content/cl_savecategories.lua: -------------------------------------------------------------------------------- 1 | function Pointshop2.DoSaveCategories( categoriesNode, notForSaleNode ) 2 | if IsValid( nodeToSelect ) then 3 | nodeToSelectText = nodeToSelect:GetText( ) 4 | end 5 | 6 | local function recursiveAddCategory( node, tbl ) 7 | if not IsValid( node ) then 8 | return 9 | end 10 | 11 | local nodeInTable = { 12 | self = { 13 | label = node:GetText( ), 14 | icon = node:GetIcon( ) 15 | }, 16 | subcategories = { }, 17 | items = { } 18 | } 19 | 20 | if node.ChildNodes then 21 | for k, childNode in pairs( node.ChildNodes:GetChildren( ) ) do 22 | recursiveAddCategory( childNode, nodeInTable.subcategories ) 23 | end 24 | end 25 | 26 | --make sure it has all items it should contain 27 | node:DoPopulate( ) 28 | for k, itemIcon in pairs( node.PropPanel:GetItems( ) ) do 29 | table.insert( nodeInTable.items, itemIcon.itemClass.className ) 30 | end 31 | 32 | table.insert( tbl, nodeInTable ) 33 | end 34 | 35 | local categoriesWithItems = { 36 | self = { 37 | label = "Root", 38 | icon = "Root", 39 | }, 40 | items = {}, 41 | subcategories = {}, 42 | } 43 | for k, v in ipairs( {categoriesNode, notForSaleNode} ) do 44 | recursiveAddCategory( v, categoriesWithItems.subcategories ) 45 | end 46 | 47 | if #categoriesWithItems == 1 then 48 | debug.Trace() 49 | Derma_Message( "Your changes cold not be saved. Please change something and save again", "Error") 50 | return 51 | end 52 | 53 | Pointshop2View:getInstance( ):saveCategoryOrganization( categoriesWithItems ) 54 | end 55 | -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/dpointshopcontentcontainer.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | DEFINE_BASECLASS( "DScrollPanel" ); 4 | 5 | AccessorFunc( PANEL, "m_pControllerPanel", "ControllerPanel" ) 6 | AccessorFunc( PANEL, "m_strCategoryName", "CategoryName" ) 7 | AccessorFunc( PANEL, "m_bTriggerSpawnlistChange", "TriggerSpawnlistChange" ) 8 | 9 | --[[--------------------------------------------------------- 10 | Name: Init 11 | -----------------------------------------------------------]] 12 | function PANEL:Init() 13 | self:SetPaintBackground( false ) 14 | 15 | self.IconList = vgui.Create( "DTileLayout", self:GetCanvas() ) 16 | self.IconList:SetBaseSize( 16 ) 17 | self.IconList:MakeDroppable( "SandboxContentPanel", true ) 18 | self.IconList:SetSelectionCanvas( true ) 19 | --self.IconList:SetUseLiveDrag( true ) 20 | self.IconList:Dock( TOP ) 21 | 22 | self.IconList.OnModified = function() self:OnModified() end 23 | end 24 | 25 | function PANEL:Add( pnl ) 26 | self.IconList:Add( pnl ) 27 | 28 | if ( pnl.InstallMenu ) then 29 | pnl:InstallMenu( self ) 30 | end 31 | 32 | self:Layout() 33 | end 34 | 35 | function PANEL:Layout() 36 | self.IconList:Layout() 37 | self:InvalidateLayout() 38 | end 39 | 40 | function PANEL:PerformLayout() 41 | BaseClass.PerformLayout( self ) 42 | self.IconList:SetMinHeight( self:GetTall() - 16 ) 43 | end 44 | 45 | --[[--------------------------------------------------------- 46 | Name: GetCount 47 | -----------------------------------------------------------]] 48 | function PANEL:GetCount() 49 | local items = self.IconList:GetChildren() 50 | return #items 51 | end 52 | 53 | function PANEL:Clear() 54 | self.IconList:Clear( true ) 55 | end 56 | 57 | function PANEL:OnModified() 58 | if ( !self:GetTriggerSpawnlistChange() ) then return end 59 | hook.Run( "PS2_SpawnlistContentChanged" ) 60 | end 61 | 62 | function PANEL:GetItems( ) 63 | return self.IconList:GetChildren( ) 64 | end 65 | 66 | 67 | function PANEL:Copy() 68 | local copy = vgui.Create( "DPointshopContentContainer", self:GetParent() ) 69 | copy:CopyBase( self ) 70 | 71 | copy.IconList:CopyContents( self.IconList ) 72 | 73 | return copy 74 | end 75 | 76 | derma.DefineControl( "DPointshopContentContainer", "", PANEL, "DScrollPanel" ) 77 | 78 | 79 | hook.Add( "PS2_SpawnlistOpenGenericMenu", "SpawnlistOpenGenericMenu", function( canvas ) 80 | local selected = canvas:GetSelectedChildren() 81 | local menu = DermaMenu() 82 | menu:SetSkin( self:GetSkin( ).Name ) 83 | menu:AddOption( "Delete", function() 84 | for k, v in pairs( selected ) do 85 | v:Remove(); 86 | end 87 | hook.Run( "PS2_SpawnlistContentChanged" ) 88 | end ) 89 | menu:Open() 90 | end) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_items/dpointshopcontentpanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | AccessorFunc( PANEL, "m_pSelectedPanel", "SelectedPanel" ) 4 | 5 | --[[--------------------------------------------------------- 6 | Name: Paint 7 | -----------------------------------------------------------]] 8 | function PANEL:Init() 9 | 10 | self:SetPaintBackground( false ) 11 | 12 | self.CategoryTable = {} 13 | 14 | self.ContentNavBar = vgui.Create( "DPointshopContentSidebar", self ); 15 | self.ContentNavBar:Dock( LEFT ); 16 | self.ContentNavBar:SetSize( 190, 10 ); 17 | self.ContentNavBar:DockMargin( 10, 0, 4, 0 ) 18 | 19 | end 20 | 21 | function PANEL:EnableModify() 22 | self.ContentNavBar:EnableModify() 23 | end 24 | 25 | function PANEL:CallPopulateHook( HookName, noEdit, rightClickNodeFunction, rightClickItemFunction ) 26 | 27 | hook.Call( HookName, GAMEMODE, self, self.ContentNavBar.Tree, self.OldSpawnlists, noEdit, rightClickNodeFunction, rightClickItemFunction ) 28 | 29 | end 30 | 31 | function PANEL:SwitchPanel( panel ) 32 | 33 | if ( IsValid( self.SelectedPanel ) ) then 34 | self.SelectedPanel:SetVisible( false ); 35 | self.SelectedPanel = nil; 36 | end 37 | 38 | self.SelectedPanel = panel 39 | 40 | self.SelectedPanel:Dock( FILL ) 41 | self.SelectedPanel:SetVisible( true ) 42 | self:InvalidateParent() 43 | 44 | end 45 | 46 | 47 | derma.DefineControl( "DPointshopContentPanel", "", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/manage_users/DPointshopManageUser_GiveItemDialog.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "Give Item" ) 6 | self:SetSize( 800, 600 ) 7 | 8 | self.loadingNotifier = vgui.Create( "DLoadingNotifier", self ) 9 | self.loadingNotifier:Dock( TOP ) 10 | 11 | self.contentPanel = vgui.Create( "DPointshopContentPanel", self ) 12 | self.contentPanel:Dock( FILL ) 13 | --self.contentPanel:EnableModify( ) 14 | self.contentPanel:CallPopulateHook( "PS2_PopulateContent", true ) 15 | self.contentPanel:DockMargin( -3, 10, 0, 5 ) 16 | 17 | hook.Add( "PS2_ItemIconSelected", self, function( _self, panel, itemClass ) 18 | if not itemClass then 19 | return 20 | end 21 | self.lbl:SetText( "Selected Item: " .. itemClass.PrintName ) 22 | self.lbl:SizeToContents( ) 23 | self.selectedClass = itemClass.className 24 | self.btn:SetDisabled( false ) 25 | end ) 26 | 27 | self.bottomPanel = vgui.Create( "DPanel", self ) 28 | self.bottomPanel:Dock( BOTTOM ) 29 | self.bottomPanel:DockMargin( 5, 5, 5, 5 ) 30 | self.bottomPanel:DockPadding( 5, 5, 5, 5 ) 31 | self.bottomPanel:SetTall( 50 ) 32 | Derma_Hook( self.bottomPanel, "Paint", "Paint", "InnerPanel" ) 33 | 34 | self.lbl = vgui.Create( "DLabel", self.bottomPanel ) 35 | self.lbl:SetText( "Selected Item: None" ) 36 | self.lbl:SetFont( self:GetSkin( ).SmallTitleFont ) 37 | self.lbl:SetColor( color_white ) 38 | self.lbl:SizeToContents( ) 39 | self.lbl:Dock( LEFT ) 40 | self.lbl:SetWide( 200 ) 41 | self.lbl:DockMargin( 10, 0, 0, 0 ) 42 | 43 | self.btn = vgui.Create( "DButton", self.bottomPanel ) 44 | self.btn:SetText( "Give" ) 45 | self.btn:SetFont( self:GetSkin( ).SmallTitleFont ) 46 | self.btn:SetColor( color_white ) 47 | self.btn:Dock( RIGHT ) 48 | self.btn:SizeToContents( ) 49 | self.btn:SetWide( 100 ) 50 | self.btn:SetDisabled( true ) 51 | 52 | function self.btn.DoClick( ) 53 | self.loadingNotifier:Expand( ) 54 | self.btn:SetDisabled( true ) 55 | Pointshop2View:getInstance( ):adminGiveItem( self.kPlayer.id, self.selectedClass ) 56 | :Fail( function( err ) 57 | Derma_Message( err, "Error" ) 58 | end ) 59 | :Always( function( ) 60 | if IsValid( self.parent ) then 61 | self.parent:RefreshInventory( ) 62 | end 63 | self:Remove( ) 64 | end ) 65 | end 66 | end 67 | 68 | function PANEL:SetKPlayer( ply ) 69 | self.kPlayer = ply 70 | self:SetTitle( "Give an item to " .. ply.name ) 71 | end 72 | 73 | vgui.Register( "DPointshopManageUser_GiveItemDialog", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/settings/cl_dsettingseditor.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetTitle( "Settings Editor" ) 5 | self.scroll = vgui.Create( "DScrollPanel", self ) 6 | self.scroll:Dock( FILL ) 7 | 8 | self.settings = {} 9 | self.settingsPanel = vgui.Create( "DSettingsPanel", self.scroll ) 10 | self.settingsPanel:Dock( FILL ) 11 | self.settingsPanel.settings = self.settings 12 | 13 | self.buttonBar = vgui.Create( "DIconLayout", self ) 14 | self.buttonBar:SetBorder( 0 ) 15 | self.buttonBar:SetSpaceX( 5 ) 16 | self.buttonBar:DockMargin( 0, 0, 0, 0 ) 17 | self.buttonBar:Dock( BOTTOM ) 18 | 19 | self.saveButton = self:AddFormButton( vgui.Create( "DButton", self ) ) 20 | self.saveButton:SetText( "Save" ) 21 | self.saveButton:SetSize( 80, 25 ) 22 | self.saveButton:PerformLayout( ) 23 | self.saveButton:Paint( 10, 10 ) 24 | function self.saveButton.DoClick( ) 25 | if self:DoSave( ) != false then 26 | self:Close( ) 27 | end 28 | end 29 | end 30 | 31 | function PANEL:OnValueChanged( path, value ) 32 | self.settings[path] = value 33 | end 34 | 35 | function PANEL:AddFormButton( btn ) 36 | btn:SetParent( self.buttonBar ) 37 | return btn 38 | end 39 | 40 | function PANEL:AutoAddSettingsTable( tbl, settingListener ) 41 | self.settingsPanel:AutoAddSettingsTable( tbl, settingListener ) 42 | end 43 | 44 | function PANEL:SetData( data ) 45 | self.settingsPanel:SetData( data ) 46 | end 47 | 48 | function PANEL:SetModule( mod ) 49 | self.mod = mod 50 | end 51 | 52 | function PANEL:DoSave( ) 53 | end 54 | 55 | derma.DefineControl( "DSettingsEditor", "", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/settings/cl_dsettingspanel.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.settings = {} 5 | end 6 | 7 | function PANEL:AddSection( name ) 8 | local section = vgui.Create( "DSettingsSection", self ) 9 | section:SetSettingsListener( self ) 10 | section:Dock( TOP ) 11 | section:DockMargin( 0, 5, 0, 5 ) 12 | section.title:SetText( name ) 13 | 14 | return section 15 | end 16 | 17 | function PANEL:SetData( data ) 18 | self.settings = data 19 | self:InitSettings( ) 20 | end 21 | 22 | function PANEL:InitSettings( ) 23 | for path, value in pairs( self.settings ) do 24 | if self.settingsLookup[path] then 25 | self.settingsLookup[path]:SetValue( value ) 26 | end 27 | end 28 | end 29 | 30 | function PANEL:OnValueChanged( path, value ) 31 | self.settings[path] = value 32 | end 33 | 34 | function PANEL:AutoAddSettingsTable( tbl, settingListener ) 35 | settingListener = settingListener or self 36 | 37 | self.settingsLookup = self.settingsLookup or {} 38 | for catPath, settingsTable in pairs( tbl ) do 39 | if settingsTable.info and settingsTable.info.isManualSetting then 40 | continue 41 | end 42 | 43 | self[catPath] = self:AddSection( settingsTable.info and settingsTable.info.label or catPath ) 44 | self[catPath]:SetSettingsListener( settingListener ) 45 | 46 | for settingPath, settingInfo in pairs( settingsTable ) do 47 | if settingPath == "info" then 48 | --Info about the category 49 | continue 50 | end 51 | 52 | local path = catPath .. "." .. settingPath 53 | local panel = self[catPath]:AddSettingByType( path, settingInfo ) 54 | self.settingsLookup[path] = panel 55 | end 56 | end 57 | end 58 | 59 | function PANEL:PerformLayout( ) 60 | self:SizeToChildren( false, true ) 61 | end 62 | 63 | function PANEL:Paint( w, h ) 64 | end 65 | 66 | derma.DefineControl( "DSettingsPanel", "", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/client/tabs/management_tab/settings/cl_dsetttingsbutton.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | local GLib = LibK.GLib 3 | GLib.Transfers.RegisterHandler( "Pointshop2.Settings", GLib.NullCallback ) 4 | 5 | function PANEL:Init( ) 6 | end 7 | 8 | function PANEL:OnMousePressed( ) 9 | self:OnLoad( ) -- Notify parent to show loading indicator 10 | Pointshop2.RequestSettings( self.mod.Name ) 11 | :Then( function( data ) 12 | self:OnLoadFinished( true ) -- Notify parent to hide loading indicator 13 | 14 | if self.settingsInfo.onClick then 15 | self.settingsInfo.onClick( ) 16 | else 17 | local creator = vgui.Create( self.settingsInfo.control ) 18 | creator:Center( ) 19 | creator:MakePopup( ) 20 | creator:SetSkin( Pointshop2.Config.DermaSkin ) 21 | creator:SetModule( self.mod ) 22 | creator:SetData( data ) 23 | end 24 | end, function( err ) 25 | self:OnLoadFinished( false, err ) -- Notify parent to hide loading indicator 26 | end ) 27 | end 28 | 29 | function PANEL:SetSettingsInfo( settingsInfo, mod ) 30 | self.icon:SetMaterial( Material( settingsInfo.icon, "noclamp smooth" ) ) 31 | self.label:SetText( settingsInfo.label ) 32 | self.settingsInfo = settingsInfo 33 | self.mod = mod 34 | end 35 | 36 | derma.DefineControl( "DSettingsButton", "", PANEL, "DBigButton" ) 37 | -------------------------------------------------------------------------------- /lua/ps2/client/tabs/shop_tab/cl_dnewitempopup.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self:SetTitle( "Item added" ) 7 | self:SetSize( 410, 308 ) 8 | 9 | self.lbl = vgui.Create( "DLabel", self ) 10 | self.lbl:SetText( "An item was added to your inventory" ) 11 | self.lbl:Dock( TOP ) 12 | end 13 | 14 | function PANEL:SetItem( item ) 15 | self.item = item 16 | 17 | self.infoPnl = vgui.Create( "DPanel", self ) 18 | self.infoPnl:Dock( TOP ) 19 | self.infoPnl.Paint = function( ) end 20 | function self.infoPnl:PerformLayout( ) 21 | self.desc:DockMargin( self.icon:GetWide( ) + 10, 5, 0, 0 ) 22 | self:SizeToChildren( false, true ) 23 | end 24 | 25 | self.infoPnl.desc = vgui.Create( item.class.GetPointshopDescriptionControl( ), self.infoPnl ) 26 | self.infoPnl.desc:SetItem( item, true ) 27 | self.infoPnl.desc:Dock( FILL ) 28 | 29 | self.infoPnl.icon = vgui.Create( item.class:GetConfiguredIconControl( ), self.infoPnl ) 30 | self.infoPnl.icon:SetPos( 5, 5 ) 31 | self.infoPnl.icon:SetItem( item ) 32 | self.infoPnl.icon:SetMouseInputEnabled( false ) 33 | end 34 | 35 | function PANEL:PerformLayout( ) 36 | DFrame.PerformLayout( self ) 37 | self:SizeToChildren( false, true ) 38 | end 39 | 40 | vgui.Register( "DNewItemPopup", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/modules/calendar/cl_DFixedGrid.lua: -------------------------------------------------------------------------------- 1 | -- Grid with gutter 2 | 3 | local PANEL = {} 4 | 5 | function PANEL:Init( ) 6 | --defaults 7 | self.tilesize = 10 8 | self.columnCount = 10 9 | self.gutter = 10 10 | self.AutoTilesize = false 11 | end 12 | 13 | function PANEL:SetTilesize( size ) 14 | self.tilesize = size 15 | end 16 | 17 | function PANEL:SetColumnCount( columnCount ) 18 | self.columnCount = columnCount 19 | end 20 | 21 | function PANEL:SetGutter( gutter ) 22 | self.gutter = gutter 23 | end 24 | 25 | function PANEL:SizeToContents( ) 26 | local elems = #self:GetChildren( ) 27 | 28 | local rows = math.ceil( elems / self.columnCount ) 29 | local height = rows * self.tilesize + ( rows - 1 ) * self.gutter 30 | local width = self.columnCount * self.tilesize + ( self.columnCount - 1) * self.gutter 31 | self:SetSize( width, height ) 32 | end 33 | 34 | function PANEL:PerformLayout( ) 35 | local gutter = self.gutter 36 | local size = self.AutoTilesize and ( self:GetWide( ) - self.gutter * ( self.columnCount - 1 ) ) / self.columnCount or self.tilesize 37 | 38 | local i = 0 39 | for k, v in pairs( self:GetChildren( ) ) do 40 | local row = math.floor( i / self.columnCount ) 41 | local col = i - row * self.columnCount 42 | 43 | local x = col * size + col * gutter 44 | local y = row * size + row * gutter 45 | 46 | v:SetPos( x, y ) 47 | 48 | if self.AutoTilesize then 49 | v:SetSize( size, size ) 50 | end 51 | 52 | i = i + 1 53 | end 54 | end 55 | 56 | function PANEL:Paint( ) 57 | end 58 | 59 | vgui.Register( "DFixedGrid", PANEL, "DPanel" ) 60 | -------------------------------------------------------------------------------- /lua/ps2/modules/calendar/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | MODULE.Name = "Daily Rewards / Advent Calendar" 4 | MODULE.Author = "Kamshak" 5 | 6 | MODULE.Blueprints = {} 7 | 8 | MODULE.SettingButtons = { 9 | } 10 | 11 | MODULE.Settings = {} 12 | 13 | MODULE.Settings.Shared = {} 14 | 15 | MODULE.Settings.Server = {} 16 | 17 | Pointshop2.RegisterModule( MODULE ) 18 | -------------------------------------------------------------------------------- /lua/ps2/modules/dlc/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | --Pointshop2 Basic Items 4 | MODULE.Name = "Pointshop 2 DLC" 5 | MODULE.Author = "Kamshak" 6 | 7 | --This defines blueprints that players can use to create items. 8 | --base is the name of the class that is used as a base 9 | --creator is the name of the derma control that is used to create new items from the blueprint 10 | MODULE.Blueprints = {} 11 | 12 | MODULE.SettingButtons = {} 13 | 14 | 15 | MODULE.Settings = { 16 | Shared = {}, 17 | Server = {} 18 | } 19 | 20 | Pointshop2.RegisterModule( MODULE ) -------------------------------------------------------------------------------- /lua/ps2/modules/guesswho_integration/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | --Pointshop2 Guess Who very basic integration. Only hides visuals on seekers. 4 | MODULE.Name = "Guess Who Integration" 5 | MODULE.Author = "Kamshak" 6 | MODULE.RestrictGamemodes = { "guesswho" } --Only load for Guess Who 7 | 8 | MODULE.Blueprints = {} 9 | 10 | MODULE.SettingButtons = {} 11 | 12 | MODULE.Settings = {} 13 | 14 | --These are sent to the client on join 15 | MODULE.Settings.Shared = { } 16 | 17 | --These are not sent 18 | MODULE.Settings.Server = { } 19 | 20 | -- For Drops integration: Returns players that can get a drop once the round ends 21 | function MODULE.GetPlayersForDrops( ) 22 | local players = {} 23 | for k, v in pairs( player.GetAll( ) ) do 24 | if v:Team() != TEAM_SPECTATOR then 25 | table.insert( players, v ) 26 | end 27 | end 28 | return players 29 | end 30 | 31 | Pointshop2.RegisterModule( MODULE ) 32 | --Pointshop2.NotifyGamemodeModuleLoaded( "prop_hunt", MODULE ) 33 | -------------------------------------------------------------------------------- /lua/ps2/modules/guesswho_integration/sh_prevent_visuals.lua: -------------------------------------------------------------------------------- 1 | local function hideOnProps(ply) 2 | if ply:Team() == TEAM_SEEKING then 3 | return false 4 | end 5 | end 6 | hook.Add( "PS2_VisualsShouldShow", "HideOnSeekers", hideOnProps ) 7 | hook.Add( "PS2_PlayermodelShouldShow", "HideOnSeekers", hideOnProps ) 8 | --hook.Add( "PS2_WeaponShouldSpawn", "HideOnSeekers", hideOnProps ) 9 | -------------------------------------------------------------------------------- /lua/ps2/modules/mu_integration/cl_dmurderconfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = { } 2 | 3 | function PANEL:Init() 4 | self:SetSkin(Pointshop2.Config.DermaSkin) 5 | self:SetTitle("Murder Reward Settings") 6 | self:SetSize(300, 600) 7 | 8 | self:AutoAddSettingsTable(Pointshop2.GetModule("Murder Integration").Settings.Server, self) 9 | end 10 | 11 | function PANEL:DoSave( ) 12 | Pointshop2View:getInstance():saveSettings(self.mod, "Server", self.settings) 13 | end 14 | 15 | derma.DefineControl("DMurderConfigurator", "", PANEL, "DSettingsEditor") -------------------------------------------------------------------------------- /lua/ps2/modules/mu_integration/cl_previewmodel.lua: -------------------------------------------------------------------------------- 1 | hook.Add("PS2_GetPreviewModel", "ForMurder", function() 2 | if GAMEMODE.Spectating then 3 | return { 4 | model = player_manager.TranslatePlayerModel("male03"), 5 | bodygroups = "0", 6 | skin = 0 7 | } 8 | end 9 | end) -------------------------------------------------------------------------------- /lua/ps2/modules/mu_integration/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | MODULE.Name = "Murder Integration" 4 | MODULE.Author = "Aragas (Pinkie Arg)" 5 | MODULE.RestrictGamemodes = { "murder", "murder-ex" } 6 | 7 | MODULE.Blueprints = { } 8 | 9 | MODULE.SettingButtons = { 10 | { 11 | label = "Point Rewards", 12 | icon = "pointshop2/hand129.png", 13 | control = "DMurderConfigurator" 14 | } 15 | } 16 | 17 | MODULE.Settings = { } 18 | 19 | MODULE.Settings.Shared = { } 20 | 21 | MODULE.Settings.Server = { 22 | Kills = { 23 | info = { 24 | label = "Murdering rewards" 25 | }, 26 | 27 | MurderKillsBystander = { 28 | value = 50, 29 | label = "Murderer killed a bystander", 30 | tooltip = "Reward for crime", 31 | }, 32 | 33 | MurderKillsBystanderWithWeapon = { 34 | value = 100, 35 | label = "Murder killed Bystander with a weapon", 36 | tooltip = "Reward for crime", 37 | }, 38 | 39 | BystanderKillsMurderer = { 40 | value = 200, 41 | label = "Bystander killed the Murderer", 42 | tooltip = "Reward for preventing the crime", 43 | }, 44 | PickupLoot = { 45 | value = 25, 46 | label = "Picked up loot", 47 | tooltip = "Reward for picking up Loot" 48 | } 49 | }, 50 | RoundWin = { 51 | info = { 52 | label = "Awards for winning the round" 53 | }, 54 | Bystander = { 55 | value = 50, 56 | label = "Bystanders won", 57 | tooltip = "Points awarded to each Bystander for winning the round" 58 | }, 59 | 60 | BystanderCleanRound = { 61 | value = 500, 62 | label = "Clean round", 63 | tooltip = "Not a single Bystander killed" 64 | }, 65 | 66 | BystanderAlive = { 67 | value = 100, 68 | label = "Bystander survived", 69 | tooltip = "Bonus for each survived Bystander", 70 | }, 71 | }, 72 | } 73 | 74 | -- For Drops integration: Returns players that can get a drop once the round ends 75 | function MODULE.GetPlayersForDrops( ) 76 | local players = {} 77 | for k, v in pairs( player.GetAll( ) ) do 78 | if v.HasMoved then 79 | table.insert( players, v ) 80 | end 81 | end 82 | return players 83 | end 84 | 85 | Pointshop2.RegisterModule(MODULE) 86 | 87 | Pointshop2.NotifyGamemodeModuleLoaded("murder", MODULE) 88 | Pointshop2.NotifyGamemodeModuleLoaded("murder-ex", MODULE) 89 | -------------------------------------------------------------------------------- /lua/ps2/modules/mu_integration/sv_muhooks.lua: -------------------------------------------------------------------------------- 1 | local MurderSetting = function(id) 2 | return Pointshop2.GetSetting("Murder Integration", id) 3 | end 4 | 5 | local playersInRound = { } 6 | hook.Add("OnStartRound", "PS2_MUBeginRound", function() 7 | for k, v in pairs(player.GetAll()) do 8 | if v:Alive() then 9 | playersInRound[k] = v 10 | end 11 | end 12 | end) 13 | 14 | hook.Add("PlayerPickupLoot", "PS2_PlayerPickupLoot", function(ply, ent) 15 | ply:PS2_AddStandardPoints( MurderSetting("Kills.PickupLoot"), "Found Loot", true) 16 | end) 17 | 18 | // Only if the hook is defined. Not defined by default. Be aware. 19 | // 1 Murderer wins 20 | // 2 Murderer loses 21 | // 3 Murderer rage quit 22 | hook.Add("OnEndRoundResult", "PS2_MUEndRound", function(result) 23 | if result == 2 then 24 | for k, v in pairs(player.GetAll()) do 25 | if not table.HasValue(playersInRound, v) then 26 | continue 27 | end 28 | 29 | if v:GetMurderer() then 30 | continue 31 | end 32 | 33 | if v:Alive() and MurderSetting("RoundWin.BystanderAlive") then 34 | v:PS2_AddStandardPoints(MurderSetting("RoundWin.BystanderAlive"), "Bonus for survival", true) 35 | end 36 | if MurderSetting("RoundWin.Bystander") then 37 | v:PS2_AddStandardPoints(MurderSetting("RoundWin.Bystander"), "Won the round") 38 | end 39 | 40 | end 41 | elseif result == 1 then 42 | for k, v in pairs( player.GetAll()) do 43 | if not v:GetMurderer() then 44 | continue 45 | end 46 | end 47 | end 48 | playersInRound = { } 49 | 50 | hook.Call("Pointshop2GmIntegration_RoundEnded") 51 | end) 52 | 53 | hook.Add("PlayerDeath", "PS2_PlayerDeath", function(victim, inflictor, attacker) 54 | if victim == attacker then 55 | return 56 | end 57 | 58 | if attacker:GetMurderer() then 59 | attacker:PS2_AddStandardPoints(MurderSetting("Kills.MurderKillsBystander"), "Killed Bystander") 60 | else -- Bystander 61 | if victim:GetMurderer() and MurderSetting("Kills.BystanderKillsMurderer") then 62 | attacker:PS2_AddStandardPoints(MurderSetting("Kills.BystanderKillsMurderer"), "Killed the Murderer") 63 | end 64 | 65 | end 66 | 67 | end) 68 | 69 | local function onlyMurderer(ply) 70 | if not ply:GetMurderer() then 71 | return false 72 | end 73 | end 74 | hook.Add( "PS2_WeaponShouldSpawn", "OnlyMurderer", onlyMurderer ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_DPointshopMaterialIcon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.image = vgui.Create( "DCenteredImage", self ) 5 | self.image:Dock( FILL ) 6 | self.image:SetMouseInputEnabled( false ) 7 | self.image:DockMargin( 5, 5, 5, 5 ) 8 | end 9 | 10 | function PANEL:SetItemClass( itemClass ) 11 | self.BaseClass.SetItemClass( self, itemClass ) 12 | if itemClass.material then 13 | self.image:SetImage( itemClass.material ) 14 | else 15 | ErrorNoHalt( "Invalid material on item class " .. tostring( itemClass.name ) ) 16 | end 17 | end 18 | 19 | function PANEL:SetItem( item ) 20 | self:SetItemClass( item.class ) 21 | end 22 | 23 | derma.DefineControl( "DPointshopMaterialIcon", "", PANEL, "DPointshopItemIcon" ) 24 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_DPointshopMaterialInvIcon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.image = vgui.Create( "DCenteredImage", self ) 5 | self.image:Dock( FILL ) 6 | self.image:DockMargin( 5, 5, 5, 5 ) 7 | end 8 | 9 | function PANEL:SetItem( item ) 10 | self.BaseClass.SetItem( self, item ) 11 | self.image:SetImage( item.material or item.class.material ) 12 | end 13 | 14 | 15 | vgui.Register( "DPointshopMaterialInvIcon", PANEL, "DPointshopInventoryItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_DPointshopReset.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSize( 300, 300 ) 5 | self:SetTitle( "Reset to defaults" ) 6 | 7 | self.warning = vgui.Create( "DMultilineLabel", self ) 8 | self.warning:InsertColorChange( 255, 0, 0, 255 ) 9 | self.warning:AppendText( "WARNING: This will permanently remove all items, inventories, points, settings and categories and reset your pointshop to the default installation! Once done, this step cannot be undone! The map will be changed after the reset!" ) 10 | self.warning:Dock( FILL ) 11 | self.warning.PerformLayout = function( ) end 12 | 13 | self.button = vgui.Create( "DButton", self ) 14 | self.button:Dock( BOTTOM ) 15 | self.button:SetText( "Reset Pointshop" ) 16 | function self.button.DoClick( ) 17 | Pointshop2View:getInstance( ):resetToDefaults( ) 18 | end 19 | end 20 | 21 | function PANEL:ApplySchemeSettings( ) 22 | self.warning.font = self:GetSkin().SmallTitleFont 23 | end 24 | 25 | --interface, has to be defined 26 | function PANEL:SetModule( ) 27 | end 28 | 29 | function PANEL:SetData( ) 30 | end 31 | 32 | 33 | vgui.Register( "DPointshopReset", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_DPointshopTextureIcon.lua: -------------------------------------------------------------------------------- 1 | local function paintCentered(texId, w, h) 2 | surface.SetTexture( texId ) 3 | surface.SetDrawColor( 255, 255, 255, 255 ) 4 | local tw, th = surface.GetTextureSize( texId ) 5 | local draw = math.min( w, h, math.max( tw, th ) ) 6 | 7 | local x = ( w - draw ) / 2 8 | local y = ( h - draw ) / 2 9 | surface.DrawTexturedRect( x, y, draw, draw ) 10 | end 11 | 12 | local PANEL = {} 13 | 14 | function PANEL:Init( ) 15 | self.image = vgui.Create( "DImage", self ) 16 | self.image:Dock( FILL ) 17 | self.image:SetMouseInputEnabled( false ) 18 | self.image:DockMargin( 5, 5, 5, 5 ) 19 | end 20 | 21 | function PANEL:SetItemClass( itemClass ) 22 | self.BaseClass.SetItemClass( self, itemClass ) 23 | if itemClass.texture then 24 | function self.image:Paint( w, h ) 25 | paintCentered( itemClass.texture, w, h ) 26 | end 27 | else 28 | ErrorNoHalt( "Invalid texture on item class " .. tostring( itemClass.name ) ) 29 | end 30 | end 31 | 32 | function PANEL:SetItem( item ) 33 | self:SetItemClass( item.class ) 34 | end 35 | 36 | derma.DefineControl( "DPointshopTextureIcon", "", PANEL, "DPointshopItemIcon" ) 37 | 38 | local PANEL = {} 39 | 40 | function PANEL:Init( ) 41 | self.image = vgui.Create( "DImage", self ) 42 | self.image:Dock( FILL ) 43 | self.image:SetMouseInputEnabled( false ) 44 | self.image:DockMargin( 5, 5, 5, 5 ) 45 | end 46 | 47 | function PANEL:SetItem( item ) 48 | self.BaseClass.SetItem( self, item ) 49 | if item.class.texture then 50 | function self.image:Paint( w, h ) 51 | paintCentered( item.class.texture, w, h ) 52 | end 53 | else 54 | ErrorNoHalt( "Invalid texture on item class " .. tostring( item.class.name ) ) 55 | end 56 | end 57 | 58 | derma.DefineControl( "DPointshopTextureInvIcon", "", PANEL, "DPointshopInventoryItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_DUsableItemDescription.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | local itemDesc = self 5 | function self.buttonsPanel:AddUseButton( ) 6 | self.useButton = vgui.Create( "DButton", self ) 7 | self.useButton:SetText( "Use" ) 8 | self.useButton:DockMargin( 0, 5, 0, 0 ) 9 | self.useButton:Dock( TOP ) 10 | function self.useButton:DoClick( ) 11 | if itemDesc.item:UseButtonClicked( ) then 12 | self:SetDisabled( true ) 13 | end 14 | end 15 | function self.useButton:Think( ) 16 | local canBeUsed, hint = itemDesc.item:CanBeUsed( ) 17 | if not canBeUsed then 18 | self:SetDisabled( true ) 19 | self:SetTooltip( hint ) 20 | else 21 | self:SetDisabled( false ) 22 | end 23 | end 24 | end 25 | end 26 | 27 | function PANEL:AddSingleUseInfo( ) 28 | if IsValid( self.singleUsePanel ) then 29 | self.singleUsePanel:Remove( ) 30 | end 31 | 32 | self.singleUsePanel = vgui.Create( "DPanel", self ) 33 | self.singleUsePanel:Dock( TOP ) 34 | self.singleUsePanel:DockMargin( 0, 8, 0, 0 ) 35 | Derma_Hook( self.singleUsePanel, "Paint", "Paint", "InnerPanelBright" ) 36 | self.singleUsePanel:SetTall( 50 ) 37 | self.singleUsePanel:DockPadding( 5, 5, 5, 5 ) 38 | function self.singleUsePanel:PerformLayout( ) 39 | self:SizeToChildren( false, true ) 40 | end 41 | 42 | local label = vgui.Create( "DLabel", self.singleUsePanel ) 43 | label:SetText( "This item is a single-use item" ) 44 | label:Dock( TOP ) 45 | label:SizeToContents( ) 46 | end 47 | 48 | function PANEL:SetItem( item, noButtons ) 49 | self.BaseClass.SetItem( self, item, noButtons ) 50 | self:AddSingleUseInfo( ) 51 | if not noButtons then 52 | self.buttonsPanel:AddUseButton( ) 53 | end 54 | end 55 | 56 | function PANEL:SetItemClass( itemClass, noBuyPanel ) 57 | self.BaseClass.SetItemClass( self, itemClass, noBuyPanel ) 58 | self:AddSingleUseInfo( ) 59 | end 60 | 61 | function PANEL:SelectionReset( ) 62 | self.BaseClass.SelectionReset( self ) 63 | if self.singleUsePanel then 64 | self.singleUsePanel:Remove( ) 65 | end 66 | end 67 | 68 | derma.DefineControl( "DUsableItemDescription", "", PANEL, "DPointshopItemDescription" ) 69 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/cl_dpointshop2configurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "Pointshop2 Basic Settings" ) 6 | self:SetSize( 300, 600 ) 7 | 8 | self:AutoAddSettingsTable( Pointshop2.GetModule( "Pointshop 2" ).Settings.Server, self ) 9 | self:AutoAddSettingsTable( Pointshop2.GetModule( "Pointshop 2" ).Settings.Shared, self ) 10 | end 11 | 12 | function PANEL:Validate( settings ) 13 | if self.settings["BasicSettings.SellRatio"] > 1 then 14 | return false, "Sell Ration should be smaller than 1. (e.g. return 50% of price -> sell ration 0.5)" 15 | end 16 | 17 | if self.settings["BasicSettings.SellRatio"] < 0 then 18 | return false, "Sell Ration should be greater or equal to 0" 19 | end 20 | 21 | if self.settings["BasicSettings.DefaultSlots"] > 500 then 22 | return false, "Inventory slots cannot be > 500" 23 | end 24 | 25 | if self.settings["BasicSettings.DefaultSlots"] < 1 then 26 | return false, "Inventory slots need to be at least 1" 27 | end 28 | 29 | if self.settings["BasicSettings.DefaultWallet.Points"] > 2000000000 then 30 | return false, "Default Points value is too large" 31 | end 32 | 33 | if self.settings["BasicSettings.DefaultWallet.Points"] < 0 then 34 | return false, "Default Points need to be >= 0" 35 | end 36 | 37 | if self.settings["BasicSettings.DefaultWallet.PremiumPoints"] < 0 then 38 | return false, "Default Donator need to be >= 0" 39 | end 40 | 41 | if self.settings["BasicSettings.DefaultWallet.PremiumPoints"] > 2000000000 then 42 | return false, "Default Donator Points value is too large" 43 | end 44 | 45 | return true 46 | end 47 | 48 | function PANEL:DoSave( ) 49 | local success, err = self:Validate( self.settings ) 50 | if not success then 51 | Derma_Message( err, "Cannot save settings" ) 52 | return false 53 | end 54 | 55 | Pointshop2View:getInstance( ):saveSettings( self.mod, "Shared", self.settings ) 56 | end 57 | 58 | derma.DefineControl( "DPointshop2Configurator", "", PANEL, "DSettingsEditor" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/cl_ForceHideOnDeath.lua: -------------------------------------------------------------------------------- 1 | -- Fallback solution of PlayerDeath hook is killed by another addon 2 | hook.Add("PS2_VisualsShouldShow", "ForceHideOnDeath", function( ply ) 3 | if not ply:Alive() or ply:Team() == TEAM_SPECTATOR then 4 | return false 5 | end 6 | end ) 7 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/cl_dpointshophatinvicon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.image = vgui.Create( "DPreRenderedModelPanel", self ) 5 | self.image:Dock( FILL ) 6 | self.image:SetSize( 64, 64 ) 7 | self.image:SetMouseInputEnabled( false ) 8 | end 9 | 10 | function PANEL:SetItem( item ) 11 | self.BaseClass.SetItem( self, item ) 12 | 13 | if item.class.iconInfo.inv.useMaterialIcon then 14 | self.image:Remove() 15 | self.image = vgui.Create( "DImage", self ) 16 | self.image:Dock( FILL ) 17 | self.image:SetSize( 64, 64 ) 18 | self.image:SetMouseInputEnabled( false ) 19 | if Material(item.class.iconInfo.inv.iconMaterial) then 20 | self.image:SetImage( item.class.iconInfo.inv.iconMaterial ) 21 | else 22 | LibK.GLib.Error("Invalid Material :" .. tostring(item.class.iconInfo.inv.iconMaterial) .. " for item " .. self:GetPrintName()) 23 | end 24 | else 25 | local model = Pointshop2:GetPreviewModel() 26 | self.image:ApplyModelInfo( model ) 27 | self.item = item 28 | self.image:SetPacOutfit( item:getOutfitForModel( model.model ) ) 29 | self.image:SetViewInfo( item.class.iconInfo.inv.iconViewInfo ) 30 | end 31 | end 32 | 33 | function PANEL:OnSelected( ) 34 | self.image.forceRender = true 35 | end 36 | 37 | function PANEL:OnDeselected( ) 38 | self.image.forceRender = false 39 | end 40 | 41 | function PANEL:Paint( w, h ) 42 | --surface.SetDrawColor( Color( 255, 0, 0 ) ) 43 | --surface.DrawRect( 0, 0, w, h ) 44 | end 45 | 46 | vgui.Register( "DPointshopHatInvIcon", PANEL, "DPointshopInventoryItemIcon" ) 47 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/cl_dpointshopsimplehaticon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:OnSelected( ) 4 | hook.Run( "PACItemSelected", self.itemClass ) 5 | end 6 | 7 | function PANEL:OnDeselected( ) 8 | hook.Run( "PACItemDeSelected", self.itemClass ) 9 | end 10 | 11 | derma.DefineControl( "DPointshopSimpleHatIcon", "", PANEL, "DPointshopSimpleItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/sh_model_outfitmapping.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.OutfitHatPersistenceMapping = class( "Pointshop2.OutfitHatPersistenceMapping" ) 2 | local OutfitHatPersistenceMapping = Pointshop2.OutfitHatPersistenceMapping 3 | 4 | OutfitHatPersistenceMapping.static.DB = "Pointshop2" 5 | 6 | OutfitHatPersistenceMapping.static.model = { 7 | tableName = "ps2_OutfitHatPersistenceMapping", 8 | fields = { 9 | hatPersistenceId = "int", 10 | outfitId = "int", 11 | model = "string", --can be a full model path or HatPersistence constants 12 | }, 13 | belongsTo = { 14 | HatPersistence = { 15 | class = "Pointshop2.HatPersistence", 16 | foreignKey = "hatPersistenceId", 17 | onDelete = "CASCADE", 18 | }, 19 | Outfit = { 20 | class = "Pointshop2.StoredOutfit", 21 | foreignKey = "outfitId", 22 | onDelete = "CASCADE" 23 | } 24 | } 25 | } 26 | 27 | OutfitHatPersistenceMapping:include( DatabaseModel ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/sh_slot.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.ValidHatSlots = { } 2 | 3 | function Pointshop2.AddHatSlot( name ) 4 | Pointshop2.AddEquipmentSlot( name, function( item ) 5 | local isHat = instanceOf( Pointshop2.GetItemClassByName( "base_hat" ), item ) 6 | 7 | if not isHat or not item:CanBeEquippedInSlot( name ) then 8 | return false 9 | end 10 | 11 | --Check for same class items: 12 | for _, slotName in pairs( Pointshop2.ValidHatSlots ) do 13 | local equipmentItem = Pointshop2.GetItemInSlot( item:GetOwner(), slotName ) 14 | if equipmentItem then 15 | --Allow to move items between slots 16 | if equipmentItem == item then 17 | continue 18 | end 19 | 20 | if equipmentItem.class.className == item.class.className then 21 | return false 22 | end 23 | end 24 | end 25 | 26 | return true 27 | end, 2 ) 28 | table.insert( Pointshop2.ValidHatSlots, name ) 29 | end 30 | 31 | Pointshop2.AddHatSlot( "Hat" ) 32 | Pointshop2.AddHatSlot( "Accessory" ) 33 | Pointshop2.AddHatSlot( "Accessory 2" ) 34 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/sh_spawnmenu.lua: -------------------------------------------------------------------------------- 1 | --Catches gm_spawn on gamemodes other than sandbox 2 | 3 | hook.Add( "Initialize", "AfterGM", function( ) 4 | if gmod.GetGamemode( ).IsSandboxDerived then return end 5 | 6 | if SERVER then 7 | util.AddNetworkString( "SpawnMenuItemSpawn" ) 8 | 9 | local old = concommand.GetTable( )["gm_spawn"] 10 | 11 | concommand.Add("gm_spawn", function( ply, cmd, args, mdl, flUnknown, iUnknown, ... ) 12 | if not ply:GetNWBool("in pac3 editor") then 13 | return old( ply, cmd, args, mdl, flUnknown, iUnknown, ... ) 14 | end 15 | 16 | net.Start( "SpawnMenuItemSpawn" ) 17 | net.WriteString( args[1] ) 18 | net.Send( ply ) 19 | end) 20 | 21 | else 22 | 23 | net.Receive( "SpawnMenuItemSpawn", function( len ) 24 | Pointshop2.SpawnMenu = g_SpawnMenu or Pointshop2.SpawnMenu 25 | 26 | local mdl = net.ReadString( ) 27 | if pace.close_spawn_menu then 28 | pace.Call("VariableChanged", pace.current_part, "Model", mdl) 29 | 30 | if Pointshop2.SpawnMenu:IsVisible() then 31 | Pointshop2.SpawnMenu:Close() 32 | end 33 | 34 | pace.close_spawn_menu = false 35 | elseif pace.current_part.ClassName ~= "model" then 36 | local name = mdl:match(".+/(.+)%.mdl") 37 | 38 | pace.Call("CreatePart", "model", name, nil, mdl) 39 | else 40 | pace.Call("VariableChanged", pace.current_part, "Model", mdl) 41 | end 42 | end ) 43 | 44 | end 45 | end ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/cl_creationmenu.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | --[[--------------------------------------------------------- 4 | Name: Paint 5 | -----------------------------------------------------------]] 6 | function PANEL:Init() 7 | 8 | self:Populate() 9 | self:SetFadeTime( 0 ) 10 | 11 | end 12 | 13 | 14 | --[[--------------------------------------------------------- 15 | Name: Paint 16 | -----------------------------------------------------------]] 17 | function PANEL:Populate() 18 | 19 | local tabs = spawnmenu.GetCreationTabs() 20 | 21 | for k, v in SortedPairsByMemberValue( tabs, "Order" ) do 22 | 23 | -- 24 | -- Here we create a panel and populate it on the first paint 25 | -- that way everything is created on the first view instead of 26 | -- being created on load. 27 | -- 28 | local pnl = vgui.Create( "Panel" ) 29 | 30 | self:AddSheet( k, pnl, v.Icon, nil, nil, v.Tooltip ) 31 | 32 | -- 33 | -- On paint, remove the paint function and populate the panel 34 | -- 35 | pnl.Paint = function() 36 | 37 | pnl.Paint = nil 38 | 39 | local childpnl = v.Function() 40 | childpnl:SetParent( pnl ) 41 | childpnl:Dock( FILL ) 42 | 43 | end 44 | 45 | 46 | end 47 | 48 | end 49 | 50 | vgui.Register( "DPS2_CreationMenu", PANEL, "DPropertySheet" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/cl_modelsearch.lua: -------------------------------------------------------------------------------- 1 | hook.Add( "Initialize", "onlyWhennotsb", function( ) 2 | if GAMEMODE.IsSandboxDerived then 3 | return false 4 | end 5 | 6 | local function GetAllFiles( tab, folder, extension, path ) 7 | 8 | local files, folders = file.Find( folder .. "/*", path ) 9 | 10 | for k, v in pairs( files ) do 11 | 12 | if ( v:EndsWith( extension ) ) then 13 | table.insert( tab, (folder .. v):lower() ) 14 | end 15 | 16 | end 17 | 18 | for k, v in pairs( folders ) do 19 | timer.Simple( k * 0.1, function() 20 | GetAllFiles( tab, folder .. v .. "/", extension, path ) 21 | end ) 22 | end 23 | 24 | if ( folder == "models/" ) then 25 | hook.Run( "SearchUpdate" ) 26 | end 27 | 28 | end 29 | 30 | 31 | local model_list = nil 32 | -- 33 | -- Model Search 34 | -- 35 | search.AddProvider( function( str ) 36 | 37 | if ( model_list == nil ) then 38 | 39 | model_list = {} 40 | GetAllFiles( model_list, "models/", ".mdl", "GAME" ) 41 | timer.Simple( 1, function() hook.Run( "SearchUpdate" ) end ) 42 | 43 | end 44 | 45 | local list = {} 46 | 47 | for k, v in pairs( model_list ) do 48 | 49 | if ( v:find( str ) ) then 50 | 51 | if ( UTIL_IsUselessModel( v ) ) then continue end 52 | 53 | local entry = 54 | { 55 | text = v:GetFileFromFilename(), 56 | func = function() RunConsoleCommand( "gm_spawn", v ) end, 57 | icon = spawnmenu.CreatePS2ContentIcon( "model", Pointshop2.SpawnMenu.SearchPropPanel, { model = v } ), 58 | words = { v } 59 | } 60 | 61 | table.insert( list, entry ) 62 | 63 | end 64 | 65 | if ( #list >= 128 ) then break end 66 | 67 | end 68 | 69 | return list 70 | 71 | end ); 72 | end ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/cl_content.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | AccessorFunc( PANEL, "m_pSelectedPanel", "SelectedPanel" ) 4 | 5 | --[[--------------------------------------------------------- 6 | Name: Paint 7 | -----------------------------------------------------------]] 8 | function PANEL:Init() 9 | 10 | self:SetPaintBackground( false ) 11 | 12 | self.CategoryTable = {} 13 | 14 | self.ContentNavBar = vgui.Create( "PS2ContentSidebar", self ); 15 | self.ContentNavBar:Dock( LEFT ); 16 | self.ContentNavBar:SetSize( 190, 10 ); 17 | self.ContentNavBar:DockMargin( 0, 0, 4, 0 ) 18 | 19 | 20 | self.HorizontalDivider = vgui.Create( "DHorizontalDivider", self ); 21 | self.HorizontalDivider:Dock( FILL ); 22 | self.HorizontalDivider:SetLeftWidth( 175 ) 23 | self.HorizontalDivider:SetLeftMin( 175 ) 24 | self.HorizontalDivider:SetRightMin( 450 ) 25 | 26 | self.HorizontalDivider:SetLeft( self.ContentNavBar ); 27 | 28 | end 29 | 30 | function PANEL:EnableModify() 31 | self.ContentNavBar:EnableModify() 32 | end 33 | 34 | function PANEL:CallPopulateHook( HookName ) 35 | 36 | hook.Call( HookName, GAMEMODE, self, self.ContentNavBar.Tree, self.OldSpawnlists ) 37 | 38 | end 39 | 40 | function PANEL:SwitchPanel( panel ) 41 | 42 | if ( IsValid( self.SelectedPanel ) ) then 43 | self.SelectedPanel:SetVisible( false ); 44 | self.SelectedPanel = nil; 45 | end 46 | 47 | self.SelectedPanel = panel 48 | 49 | self.SelectedPanel:Dock( FILL ) 50 | self.SelectedPanel:SetVisible( true ) 51 | self:InvalidateParent() 52 | 53 | self.HorizontalDivider:SetRight( self.SelectedPanel ); 54 | 55 | end 56 | 57 | 58 | vgui.Register( "DPS2_SpawnmenuContentPanel", PANEL, "DPanel" ) 59 | 60 | 61 | 62 | local function CreateContentPanel() 63 | 64 | local ctrl = vgui.Create( "DPS2_SpawnmenuContentPanel" ) 65 | 66 | ctrl.OldSpawnlists = ctrl.ContentNavBar.Tree:AddNode( "#spawnmenu.category.browse", "icon16/cog.png" ) 67 | 68 | ctrl:EnableModify() 69 | hook.Call( "PS2_PopulatePropMenu", GAMEMODE ) 70 | ctrl:CallPopulateHook( "PS2_SpawnMenu_PopulateContent" ); 71 | 72 | 73 | ctrl.OldSpawnlists:MoveToFront() 74 | ctrl.OldSpawnlists:SetExpanded( true ) 75 | 76 | return ctrl 77 | 78 | end 79 | 80 | local existing = spawnmenu.GetCreationTabs() 81 | if not existing["#spawnmenu.content_tab"] then 82 | spawnmenu.AddCreationTab( "#spawnmenu.content_tab", CreateContentPanel, "icon16/application_view_tile.png", -10 ) 83 | end -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/cl_contentcontainer.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | DEFINE_BASECLASS( "DScrollPanel" ); 4 | 5 | AccessorFunc( PANEL, "m_pControllerPanel", "ControllerPanel" ) 6 | AccessorFunc( PANEL, "m_strCategoryName", "CategoryName" ) 7 | AccessorFunc( PANEL, "m_bTriggerSpawnlistChange", "TriggerSpawnlistChange" ) 8 | 9 | --[[--------------------------------------------------------- 10 | Name: Init 11 | -----------------------------------------------------------]] 12 | function PANEL:Init() 13 | 14 | self:SetPaintBackground( false ) 15 | 16 | self.IconList = vgui.Create( "DTileLayout", self:GetCanvas() ) 17 | self.IconList:SetBaseSize( 16 ) 18 | self.IconList:MakeDroppable( "SandboxContentPanel", true ) 19 | self.IconList:SetSelectionCanvas( true ) 20 | --self.IconList:SetUseLiveDrag( true ) 21 | self.IconList:Dock( TOP ) 22 | self.IconList.OnModified = function() self:OnModified() end 23 | 24 | end 25 | 26 | function PANEL:Add( pnl ) 27 | 28 | self.IconList:Add( pnl ) 29 | 30 | if ( pnl.InstallMenu ) then 31 | pnl:InstallMenu( self ) 32 | end 33 | 34 | self:Layout() 35 | 36 | end 37 | 38 | function PANEL:Layout() 39 | 40 | self.IconList:Layout() 41 | self:InvalidateLayout() 42 | 43 | end 44 | 45 | function PANEL:PerformLayout() 46 | 47 | BaseClass.PerformLayout( self ) 48 | self.IconList:SetMinHeight( self:GetTall() - 16 ) 49 | 50 | end 51 | 52 | --[[--------------------------------------------------------- 53 | Name: RebuildAll 54 | -----------------------------------------------------------]] 55 | function PANEL:RebuildAll( proppanel ) 56 | 57 | local items = self.IconList:GetChildren() 58 | 59 | for k, v in pairs( items ) do 60 | 61 | v:RebuildSpawnIcon() 62 | 63 | end 64 | 65 | end 66 | 67 | --[[--------------------------------------------------------- 68 | Name: GetCount 69 | -----------------------------------------------------------]] 70 | function PANEL:GetCount() 71 | 72 | local items = self.IconList:GetChildren() 73 | return #items 74 | 75 | end 76 | 77 | 78 | function PANEL:Clear() 79 | 80 | self.IconList:Clear( true ) 81 | 82 | end 83 | 84 | function PANEL:ContentsToTable( contentpanel ) 85 | 86 | local tab = {} 87 | 88 | local items = self.IconList:GetChildren() 89 | 90 | for k, v in pairs( items ) do 91 | 92 | v:ToTable( tab ) 93 | 94 | end 95 | 96 | return tab 97 | 98 | end 99 | 100 | function PANEL:Copy() 101 | 102 | local copy = vgui.Create( "PS2_ContentContainer", self:GetParent() ) 103 | copy:CopyBase( self ) 104 | 105 | copy.IconList:CopyContents( self.IconList ) 106 | 107 | return copy 108 | 109 | end 110 | 111 | vgui.Register( "PS2_ContentContainer", PANEL, "DScrollPanel" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/cl_contentheader.lua: -------------------------------------------------------------------------------- 1 | surface.CreateFont( "PS2ContentHeader", 2 | { 3 | font = "Helvetica", 4 | size = 50, 5 | weight = 1000 6 | }) 7 | 8 | 9 | local PANEL = {} 10 | 11 | --[[-------------------------------------------------------- 12 | Name: Init 13 | ---------------------------------------------------------]] 14 | 15 | function PANEL:Init() 16 | 17 | self:SetFont( "PS2ContentHeader" ) 18 | self:SetBright( true ) 19 | self:SetExpensiveShadow( 2, Color( 0, 0, 0, 130 ) ) 20 | 21 | self:SetSize( 64, 64 ) 22 | 23 | self.OwnLine = true 24 | 25 | end 26 | 27 | function PANEL:PerformLayout() 28 | 29 | self:SizeToContents(); 30 | self:SetTall( 64 ); 31 | 32 | end 33 | 34 | function PANEL:ToTable( bigtable ) 35 | 36 | local tab = {} 37 | 38 | tab.type = "header" 39 | tab.text = self:GetText(); 40 | 41 | table.insert( bigtable, tab ) 42 | 43 | end 44 | 45 | function PANEL:Copy() 46 | 47 | local copy = vgui.Create( "PS2ContentHeader", self:GetParent() ) 48 | copy:SetText( self:GetText() ) 49 | copy:CopyBounds( self ) 50 | 51 | return copy; 52 | 53 | end 54 | 55 | function PANEL:PaintOver( w, h ) 56 | 57 | self:DrawSelections() 58 | 59 | end 60 | 61 | function PANEL:DoRightClick() 62 | local pCanvas = self:GetSelectionCanvas() 63 | if ( IsValid( pCanvas ) && pCanvas:NumSelectedChildren() > 0 ) then 64 | return hook.Run( "SpawnlistOpenGenericMenu", pCanvas ) 65 | end 66 | 67 | self:OpenMenu() 68 | end 69 | 70 | function PANEL:OpenMenu() 71 | local menu = DermaMenu() 72 | menu:AddOption( "Delete", function() self:Remove(); hook.Run( "SpawnlistContentChanged", self ) end ) 73 | menu:Open() 74 | end 75 | 76 | vgui.Register( "PS2ContentHeader", PANEL, "DLabelEditable" ) 77 | 78 | 79 | spawnmenu.AddContentType( "header", function( container, obj ) 80 | 81 | if ( !obj.text || type(obj.text) != "string" ) then return end 82 | 83 | local label = vgui.Create( "PS2ContentHeader", container ) 84 | label:SetText( obj.text ) 85 | 86 | container:Add( label ) 87 | 88 | end ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/cl_contentsidebar.lua: -------------------------------------------------------------------------------- 1 | if gmod.GetGamemode( ).IsSandboxDerived then return end 2 | 3 | local pnlSearch = vgui.RegisterFile( "cl_contentsearch.lua" ) 4 | 5 | 6 | local PANEL = {} 7 | 8 | function PANEL:Init() 9 | 10 | self.Tree = vgui.Create( "DTree", self ); 11 | self.Tree:SetClickOnDragHover( true ); 12 | self.Tree.OnNodeSelected = function( Tree, Node ) hook.Call( "PS2ContentSidebarSelection", GAMEMODE, self:GetParent(), Node ) end 13 | self.Tree:Dock( FILL ) 14 | self.Tree:SetBackgroundColor( Color( 240, 240, 240, 255 ) ) 15 | 16 | self:SetPaintBackground( false ) 17 | 18 | end 19 | 20 | function PANEL:EnableModify() 21 | 22 | self.Search = vgui.CreateFromTable( pnlSearch, self ) 23 | self:CreateSaveNotification() 24 | 25 | self.Toolbox = vgui.Create( "PS2PS2ContentSidebarToolbox", self ) 26 | 27 | hook.Add( "OpenToolbox", "OpenToolbox", function() 28 | 29 | if ( !IsValid( self.Toolbox ) ) then return end 30 | 31 | self.Toolbox:Open() 32 | 33 | end ) 34 | 35 | end 36 | 37 | function PANEL:CreateSaveNotification() 38 | 39 | local SavePanel = vgui.Create( "DButton", self ) 40 | SavePanel:Dock( TOP ) 41 | SavePanel:DockMargin( 32, 1, 32, 4 ) 42 | SavePanel:SetIcon( "icon16/disk.png" ) 43 | SavePanel:SetText( "Save changes" ) 44 | SavePanel:SetVisible( false ) 45 | 46 | SavePanel.DoClick = function() 47 | 48 | SavePanel:SlideUp( 0.2 ) 49 | hook.Run( "OnSaveSpawnlist" ); 50 | 51 | end 52 | 53 | hook.Add( "SpawnlistContentChanged", "ShowSaveButton", function() 54 | 55 | if ( SavePanel:IsVisible() ) then return end 56 | 57 | SavePanel:SlideDown( 0.2 ) 58 | 59 | 60 | end ) 61 | 62 | 63 | end 64 | 65 | vgui.Register( "PS2ContentSidebar", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/cl_contentsidebartoolbox.lua: -------------------------------------------------------------------------------- 1 | if gmod.GetGamemode( ).IsSandboxDerived then return end 2 | 3 | local PANEL = {} 4 | 5 | --[[--------------------------------------------------------- 6 | Name: Init 7 | -----------------------------------------------------------]] 8 | function PANEL:Init() 9 | 10 | self:SetOpenSize( 200 ) 11 | self:DockPadding( 5, 5, 5, 5 ) 12 | 13 | local panel = vgui.Create( "DPanel", self ) 14 | panel:Dock( TOP ) 15 | panel:SetSize( 24, 24 ) 16 | panel:DockPadding( 2, 2, 2, 2 ) 17 | 18 | local Button = vgui.Create( "DImageButton", panel ) 19 | Button:SetImage( "icon16/text_heading_1.png" ) 20 | Button:Dock( LEFT ) 21 | Button:SetStretchToFit( false ) 22 | Button:SetSize( 20, 20 ) 23 | local slot = Button:Droppable( "SandboxContentPanel" ); 24 | 25 | Button.OnDrop = function( self, target ) 26 | 27 | local label = vgui.Create( "PS2ContentHeader", target ) 28 | return label 29 | 30 | end 31 | 32 | local panel = vgui.Create( "DPanel", self ) 33 | panel:Dock( FILL ) 34 | panel:DockPadding( 5, 5, 5, 5 ) 35 | 36 | local label = vgui.Create( "DTextEntry", panel ) 37 | label:Dock( TOP ) 38 | 39 | local icons = vgui.Create( "DIconBrowser", panel ) 40 | icons:Dock( FILL ) 41 | 42 | -- 43 | -- If we select a node from the sidebar, update the text/icon/actions in the toolbox (at the bottom) 44 | -- 45 | hook.Add( "PS2ContentSidebarSelection", "SidebarToolboxSelection", function( pnlContent, node ) 46 | 47 | label:SetText( node:GetText() ) 48 | icons:SelectIcon( node:GetIcon() ) 49 | icons:ScrollToSelected() 50 | 51 | label.OnChange = function() 52 | node:SetText( label:GetText() ) 53 | hook.Run( "SpawnlistContentChanged" ) 54 | end 55 | 56 | icons.OnChange = function() 57 | node:SetIcon( icons:GetSelectedIcon() ) 58 | hook.Run( "SpawnlistContentChanged" ) 59 | end 60 | 61 | end ) 62 | 63 | end 64 | 65 | 66 | 67 | vgui.Register( "PS2PS2ContentSidebarToolbox", PANEL, "DDrawer" ) 68 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/contenttypes/cl_addonprops.lua: -------------------------------------------------------------------------------- 1 | local function AddRecursive( pnl, folder, path, wildcard ) 2 | 3 | local files, folders = file.Find( folder .. "*", path ) 4 | 5 | for k, v in pairs( files ) do 6 | 7 | if ( !string.EndsWith( v, ".mdl" ) ) then continue end 8 | 9 | local cp = spawnmenu.GetContentType( "model" ); 10 | if ( cp ) then 11 | cp( pnl, { model = folder .. v } ) 12 | end 13 | 14 | end 15 | 16 | for k, v in pairs( folders ) do 17 | 18 | AddRecursive( pnl, folder .. v .. "/", path, wildcard ) 19 | 20 | end 21 | 22 | end 23 | 24 | 25 | hook.Add( "PS2_SpawnMenu_PopulateContent", "AddonProps", function( pnlContent, tree, node ) 26 | 27 | local ViewPanel = vgui.Create( "PS2_ContentContainer", pnlContent ) 28 | ViewPanel:SetVisible( false ); 29 | 30 | local MyNode = node:AddNode( "#spawnmenu.category.addons", "icon16/folder_database.png" ); 31 | 32 | local addons = engine.GetAddons() 33 | for _, addon in SortedPairs( addons ) do 34 | 35 | if ( !addon.downloaded ) then continue end 36 | if ( !addon.mounted ) then continue end 37 | 38 | if ( addon.models <= 0 ) then continue end 39 | 40 | local models = MyNode:AddNode( addon.title .. " ("..addon.models..")", "icon16/bricks.png" ); 41 | models.DoClick = function() 42 | 43 | ViewPanel:Clear( true ) 44 | AddRecursive( ViewPanel, "models/", addon.title, "*.mdl" ) 45 | pnlContent:SwitchPanel( ViewPanel ) 46 | 47 | end 48 | 49 | end 50 | 51 | end ) 52 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/hat/spawnmenu/creationmenu/content/contenttypes/cl_gameprops.lua: -------------------------------------------------------------------------------- 1 | local function AddBrowseContent( ViewPanel, node, name, icon, path, pathid, pnlContent ) 2 | 3 | local models = node:AddFolder( name, path .. "models", pathid, false ); 4 | models:SetIcon( icon ) 5 | models.BrowseContentType = "models"; 6 | models.BrowseExtension = "*.mdl"; 7 | models.ContentType = "model"; 8 | models.ViewPanel = ViewPanel; 9 | 10 | -- 11 | -- If we click on a subnode of this tree, it gets reported upwards (to us) 12 | -- 13 | models.OnNodeSelected = function( slf, node ) 14 | 15 | -- Already viewing this panel 16 | if ( ViewPanel && ViewPanel.CurrentNode && ViewPanel.CurrentNode == node ) then return end 17 | 18 | -- Clear the viewpanel in preperation for displaying it 19 | ViewPanel:Clear( true ) 20 | ViewPanel.CurrentNode = node; 21 | 22 | -- 23 | -- Fill the viewpanel with models that are in this node's folder 24 | -- 25 | local Path = node:GetFolder() 26 | local SearchString = Path .. "/*.mdl"; 27 | 28 | local Models = file.Find( SearchString, node:GetPathID() ) 29 | for k, v in pairs( Models ) do 30 | 31 | local cp = spawnmenu.GetContentType( "model" ); 32 | if ( cp ) then 33 | cp( ViewPanel, { model = Path .. "/" .. v } ) 34 | end 35 | 36 | end 37 | 38 | -- 39 | -- Switch to it 40 | -- 41 | pnlContent:SwitchPanel( ViewPanel ) 42 | ViewPanel.CurrentNode = node 43 | 44 | end 45 | 46 | end 47 | 48 | -- 49 | -- Called when setting up the sidebar on the spawnmenu - to populate the tree 50 | -- 51 | hook.Add( "PS2_SpawnMenu_PopulateContent", "GameProps", function( pnlContent, tree, node ) 52 | 53 | -- 54 | -- Create a node in the `other` category on the tree 55 | -- 56 | local MyNode = node:AddNode( "#spawnmenu.category.games", "icon16/folder_database.png" ); 57 | 58 | local ViewPanel = vgui.Create( "PS2_ContentContainer", pnlContent ) 59 | ViewPanel:SetVisible( false ); 60 | 61 | AddBrowseContent( ViewPanel, MyNode, "All", "games/16/all.png", "", "GAME", pnlContent ); 62 | AddBrowseContent( ViewPanel, MyNode, "Garry's Mod", "games/16/garrysmod.png", "", "garrysmod", pnlContent ); 63 | 64 | -- 65 | -- Create a list of mounted games, allowing us to browse them 66 | -- 67 | local games = engine.GetGames() 68 | for _, game in SortedPairs( games ) do 69 | 70 | if ( !game.mounted ) then continue end 71 | 72 | AddBrowseContent( ViewPanel, MyNode, game.title, "games/16/" .. game.folder .. ".png", "", game.folder, pnlContent ) 73 | 74 | end 75 | 76 | end ) 77 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/cl_DItemFactoryConfigurationFrame.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetTitle( "Add an Item Type" ) 5 | 6 | self:SetSkin( Pointshop2.Config.DermaSkin ) 7 | self:SetSize( 800, math.Clamp( ScrH( ), 0, 768 ) ) 8 | 9 | self.steps = vgui.Create( "DStepPanel", self ) 10 | self.steps:Dock( FILL ) 11 | 12 | self.bottomPnl = vgui.Create( "DPanel", self ) 13 | self.bottomPnl:Dock( BOTTOM ) 14 | Derma_Hook( self.bottomPnl, "Paint", "Paint", "InnerPanel" ) 15 | self.bottomPnl:SetTall( 40 ) 16 | self.bottomPnl:DockPadding( 5, 5, 5, 5 ) 17 | 18 | self.finishBtn = vgui.Create( "DButton", self.bottomPnl ) 19 | self.finishBtn:SetText( "Finish" ) 20 | self.finishBtn:Dock( RIGHT ) 21 | self.finishBtn:DockMargin( 5, 0, 0, 0 ) 22 | self.finishBtn:SetDisabled( true ) 23 | function self.finishBtn.DoClick( ) 24 | self:OnFinish( self.selectedFactory, self.configurator:GetSettingsForSave( ) ) 25 | end 26 | 27 | self.backBtn = vgui.Create( "DButton", self.bottomPnl ) 28 | self.backBtn:SetText( "Back" ) 29 | self.backBtn:Dock( RIGHT ) 30 | self.backBtn:SetDisabled( true ) 31 | function self.backBtn.DoClick( ) 32 | self.steps:PopStep( ) 33 | end 34 | 35 | self.picker = vgui.Create( "DItemFactoryPicker", self ) 36 | self.steps:AddStep( "Pick a creator", self.picker ) 37 | function self.picker.OnChange( ) 38 | self.selectedFactory = self.picker.selectedFactory 39 | 40 | self.configurator = vgui.Create( self.selectedFactory.GetConfiguratorControl( ) ) 41 | self.steps:AddStep( "Configuration", self.configurator ) 42 | 43 | self.steps:NextStep( ) 44 | self.backBtn:SetDisabled( false ) 45 | end 46 | 47 | function self.steps.OnStepChanged( ) 48 | if self.steps.currentStep == 1 then 49 | self.backBtn:SetDisabled( true ) 50 | self.finishBtn:SetDisabled( true ) 51 | elseif self.steps.currentStep == 2 then 52 | self.finishBtn:SetDisabled( false ) 53 | end 54 | end 55 | end 56 | 57 | function PANEL:OnFinish( settings ) 58 | end 59 | 60 | vgui.Register( "DItemFactoryConfigurationFrame", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/cl_DItemFactoryPicker.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self.scroll = vgui.Create( "DScrollPanel", self ) 7 | self.scroll:Dock( FILL ) 8 | 9 | for k, factory in pairs( Pointshop2.ItemFactory.GetItemFactories( ) ) do 10 | local pnl = vgui.Create( "DButton", self.scroll ) 11 | pnl:SetTall( 75 ) 12 | pnl:Dock( TOP ) 13 | pnl:DockPadding( 5, 5, 5, 5 ) 14 | pnl:SetText( "" ) 15 | pnl:DockMargin( 0, 5, 5, 5 ) 16 | 17 | pnl.icon = vgui.Create( "DImage", pnl ) 18 | pnl.icon:SetSize( 64, 64 ) 19 | pnl.icon:Dock( LEFT ) 20 | pnl.icon:SetTooltip( "Click to Select" ) 21 | pnl.icon:SetImage( factory.Icon ) 22 | pnl.icon:SetMouseInputEnabled( false ) 23 | 24 | pnl.title = vgui.Create( "DLabel", pnl ) 25 | pnl.title:Dock( TOP ) 26 | pnl.title:DockMargin( 5, 0, 5, 0 ) 27 | pnl.title:SetFont( self:GetSkin().SmallTitleFont ) 28 | pnl.title:SetColor( self:GetSkin().Colours.Label.Bright ) 29 | pnl.title:SetText( factory.Name ) 30 | pnl.title:SizeToContents( ) 31 | 32 | pnl.desc = vgui.Create( "DMultilineLabel", pnl ) 33 | pnl.desc:Dock( TOP ) 34 | pnl.desc:DockMargin( 5, 0, 5, 0 ) 35 | pnl.desc:SetText( factory.Description ) 36 | pnl.desc:SetMouseInputEnabled( false ) 37 | 38 | function pnl.DoClick( ) 39 | self.selectedFactory = factory 40 | self:OnChange() 41 | end 42 | 43 | Derma_Hook( pnl, "Paint", "Paint", "Button" ) 44 | end 45 | end 46 | 47 | function PANEL:OnChange( ) 48 | --for overwriting 49 | end 50 | 51 | Derma_Hook( PANEL, "Paint", "Paint", "InnerPanel" ) 52 | 53 | vgui.Register( "DItemFactoryPicker", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/factories/cl_DItemFactoryConfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self.settings = {} 6 | 7 | self.infoPanel = vgui.Create( "DInfoPanel", self ) 8 | self.infoPanel:Dock( TOP ) 9 | self.infoPanel:SetInfo( "Single Item", 10 | [[This item factory is used to create a single item from the shop. Pick the item below.]] 11 | ) 12 | self.infoPanel:DockMargin( 0, 0, 0, 5 ) 13 | 14 | self.contentPanel = vgui.Create( "DPointshopContentPanel", self ) 15 | self.contentPanel:Dock( FILL ) 16 | --self.contentPanel:EnableModify( ) 17 | self.contentPanel:CallPopulateHook( "PS2_PopulateContent", true ) 18 | 19 | hook.Add( "PS2_ItemIconSelected", self, function( self, panel, itemClass ) 20 | self.lbl:SetText( "Selected Item: " .. itemClass.PrintName ) 21 | self.lbl:SizeToContents( ) 22 | self.settings["BasicSettings.ItemClass"] = itemClass.className 23 | end ) 24 | 25 | self.bottomPanel = vgui.Create( "DPanel", self ) 26 | self.bottomPanel:Dock( BOTTOM ) 27 | self.bottomPanel:SetTall( 40 ) 28 | Derma_Hook( self.bottomPanel, "Paint", "Paint", "InnerPanelBright" ) 29 | 30 | self.lbl = vgui.Create( "DLabel", self.bottomPanel ) 31 | self.lbl:SetText( "Selected Item: None" ) 32 | self.lbl:SetFont( self:GetSkin( ).TabFont ) 33 | self.lbl:SetColor( color_white ) 34 | self.lbl:DockMargin( 0, 5, 0, 5 ) 35 | self.lbl:SizeToContents( ) 36 | end 37 | 38 | function PANEL:Edit( settingsTbl ) 39 | --Ignore 40 | end 41 | 42 | function PANEL:GetSettingsForSave( ) 43 | if self.settings["BasicSettings.ItemClass"] == nil then 44 | Derma_Message( "Please select an item", "Error" ) 45 | return 46 | end 47 | return self.settings 48 | end 49 | 50 | function PANEL:PerformLayout( ) 51 | end 52 | 53 | function PANEL:Paint( w, h ) 54 | 55 | end 56 | 57 | vgui.Register( "DSingleItemFactoryConfigurator", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/factories/cl_DItemFromFactoryConfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self.settings = {} 6 | 7 | self.infoPanel = vgui.Create( "DInfoPanel", self ) 8 | self.infoPanel:Dock( TOP ) 9 | self.infoPanel:SetInfo( "Random Item from Category", 10 | [[This item factory is used to create a random item from a category. Pick the category below. 11 | 12 | You can choose to weight the item by price: This means that items with a higher price get chosen less frequently. The chance is automatically calculated to match the price differences. 13 | If you leave the option unticked all items have the same chance. Premium points are valued as 10 times normal points. 14 | ]] 15 | ) 16 | self.infoPanel:DockMargin( 0, 0, 0, 5 ) 17 | 18 | self.contentPanel = vgui.Create( "DPointshopContentPanel", self ) 19 | self.contentPanel:Dock( FILL ) 20 | --self.contentPanel:EnableModify( ) 21 | self.contentPanel:CallPopulateHook( "PS2_PopulateContent", true ) 22 | 23 | hook.Add( "PS2_CategorySelected", self, function( self, node, categoryInfo ) 24 | if node.specialNode or not categoryInfo then 25 | --Uncategorized or root node 26 | return 27 | end 28 | 29 | self.actualSettings.settings["ManualSettings.CategoryName"] = categoryInfo.self.label 30 | self.lbl:SetText( "Selected Category: " .. categoryInfo.self.label ) 31 | self.lbl:SizeToContents( ) 32 | end ) 33 | 34 | self.actualSettings = vgui.Create( "DSettingsPanel", self ) 35 | self.actualSettings:Dock( TOP ) 36 | self.actualSettings:AutoAddSettingsTable( Pointshop2.ItemFromCategoryFactory.Settings ) 37 | self.actualSettings:DockMargin( 0, 0, 0, 5 ) 38 | self:InvalidateLayout() 39 | 40 | self.bottomPanel = vgui.Create( "DPanel", self ) 41 | self.bottomPanel:Dock( BOTTOM ) 42 | self.bottomPanel:SetTall( 40 ) 43 | Derma_Hook( self.bottomPanel, "Paint", "Paint", "InnerPanelBright" ) 44 | 45 | self.lbl = vgui.Create( "DLabel", self.bottomPanel ) 46 | self.lbl:SetText( "Selected Category: None" ) 47 | self.lbl:SetFont( self:GetSkin( ).TabFont ) 48 | self.lbl:SetColor( color_white ) 49 | self.lbl:DockMargin( 0, 5, 0, 5 ) 50 | self.lbl:SizeToContents( ) 51 | end 52 | 53 | function PANEL:Edit( settingsTbl ) 54 | self.actualSettings:SetData( settingsTbl ) 55 | --Ignore 56 | end 57 | 58 | function PANEL:GetSettingsForSave( ) 59 | if self.actualSettings.settings["ManualSettings.CategoryName"] == nil then 60 | Derma_Message( "Please select a category", "Error" ) 61 | return 62 | end 63 | return self.actualSettings.settings 64 | end 65 | 66 | function PANEL:PerformLayout( ) 67 | end 68 | 69 | function PANEL:Paint( w, h ) 70 | 71 | end 72 | 73 | vgui.Register( "DItemFromCategoryFactoryConfigurator", PANEL, "DPanel" ) 74 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/factories/cl_DPointsFactoryConfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | 6 | self.infoPanel = vgui.Create( "DInfoPanel", self ) 7 | self.infoPanel:Dock( TOP ) 8 | self.infoPanel:SetInfo( "Points Giver", 9 | [[This item factory is used to create items that give points to players when redeemed. ]] 10 | ) 11 | self.infoPanel:DockMargin( 0, 0, 0, 5 ) 12 | 13 | self.actualSettings = vgui.Create( "DSettingsPanel", self ) 14 | self.actualSettings:Dock( FILL ) 15 | self.actualSettings:AutoAddSettingsTable( Pointshop2.PointsFactory.Settings ) 16 | self:InvalidateLayout() 17 | end 18 | 19 | function PANEL:OnDone( ) 20 | 21 | end 22 | 23 | function PANEL:Edit( settingsTbl ) 24 | self.actualSettings:SetData( settingsTbl ) 25 | end 26 | 27 | function PANEL:GetSettingsForSave( ) 28 | return self.actualSettings.settings 29 | end 30 | 31 | function PANEL:Paint( w, h ) 32 | end 33 | 34 | function PANEL:PerformLayout( ) 35 | if IsValid( self.actualSettings ) then 36 | self.actualSettings:SizeToChildren( false, true ) 37 | end 38 | end 39 | 40 | function PANEL:Paint( w, h ) 41 | 42 | end 43 | 44 | vgui.Register( "DPointsFactoryConfigurator", PANEL, "DPanel" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/item_factories/factories/sh_SingleItemFactory.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.SingleItemFactory = class( "Pointshop2.SingleItemFactory", Pointshop2.ItemFactory ) 2 | local SingleItemFactory = Pointshop2.SingleItemFactory 3 | 4 | SingleItemFactory.Name = "Item" 5 | SingleItemFactory.Icon = "pointshop2/cowboy5.png" 6 | SingleItemFactory.Description = "Pick a single item from the shop." 7 | 8 | SingleItemFactory.Settings = { 9 | BasicSettings = { 10 | info = { 11 | label = "Item Settings", 12 | }, 13 | ItemClass = "" 14 | } 15 | } 16 | 17 | /* 18 | Creates an item as needed 19 | */ 20 | function SingleItemFactory:CreateItem( temporaryInstance ) 21 | local class = Pointshop2.GetItemClassByName( self.settings["BasicSettings.ItemClass"] ) 22 | if not class then 23 | return Promise.Reject( "Invalid item class " .. self.settings["BasicSettings.ItemClass"] ) 24 | end 25 | 26 | local item = class:new( ) 27 | return temporaryInstance and item or item:save( ) 28 | end 29 | 30 | function SingleItemFactory:GetChanceTable( ) 31 | local itemClass = Pointshop2.GetItemClassByName( self.settings["BasicSettings.ItemClass"] ) 32 | if not itemClass then 33 | error( "Invalid item class " .. self.settings["BasicSettings.ItemClass"] ) 34 | end 35 | 36 | return { 37 | { chance = 1, itemOrInfo = itemClass } 38 | } 39 | end 40 | 41 | function SingleItemFactory:IsValid( ) 42 | local class = Pointshop2.GetItemClassByName( self.settings["BasicSettings.ItemClass"] ) 43 | return class != nil 44 | end 45 | 46 | /* 47 | Name of the control used to configurate this factory 48 | */ 49 | function SingleItemFactory:GetConfiguratorControl( ) 50 | return "DSingleItemFactoryConfigurator" 51 | end 52 | 53 | function SingleItemFactory:GetShortDesc( ) 54 | local class = Pointshop2.GetItemClassByName( self.settings["BasicSettings.ItemClass"] ) 55 | if not class then 56 | return "" 57 | end 58 | return class.PrintName 59 | end 60 | 61 | Pointshop2.ItemFactory.RegisterFactory( SingleItemFactory ) 62 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/playermodel/cl_dpointshopplayermodelinvicon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.modelPanel = vgui.Create( "DModelPanel_PlayerModel", self ) 5 | self.modelPanel:Dock( FILL ) 6 | self.modelPanel:SetDragParent( self ) 7 | self.modelPanel:SetMouseInputEnabled( false ) 8 | end 9 | 10 | function PANEL:SetItem( item ) 11 | self.BaseClass.SetItem( self, item ) 12 | 13 | self.modelPanel:SetModel( item.playerModel ) 14 | self.modelPanel.Entity:SetPos( Vector( -100, 0, -61 ) ) 15 | 16 | local groups = string.Explode( " ", item.bodygroups ) 17 | for k = 0, self.modelPanel.Entity:GetNumBodyGroups( ) - 1 do 18 | if ( self.modelPanel.Entity:GetBodygroupCount( k ) <= 1 ) then continue end 19 | self.modelPanel.Entity:SetBodygroup( k, groups[ k + 1 ] or 0 ) 20 | end 21 | 22 | if self.modelPanel.Entity:SkinCount( ) - 1 > 0 then 23 | self.modelPanel.Entity:SetSkin( item.skin ) 24 | end 25 | end 26 | 27 | function PANEL:Think( ) 28 | if self.Selected or self:IsHovered( ) or self:IsChildHovered( 2 ) then 29 | self.modelPanel.drawHover = true 30 | else 31 | self.modelPanel.drawHover = false 32 | end 33 | end 34 | 35 | vgui.Register( "DPointshopPlayerModelInvIcon", PANEL, "DPointshopInventoryItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/playermodel/sh_model_playermodelpersistence.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.PlayermodelPersistence = class( "Pointshop2.PlayermodelPersistence" ) 2 | local PlayermodelPersistence = Pointshop2.PlayermodelPersistence 3 | 4 | PlayermodelPersistence.static.DB = "Pointshop2" 5 | 6 | PlayermodelPersistence.static.model = { 7 | tableName = "ps2_playermodelpersistence", 8 | fields = { 9 | itemPersistenceId = "int", 10 | playerModel = "string", 11 | skin = "int", 12 | bodygroups = "string" 13 | }, 14 | belongsTo = { 15 | ItemPersistence = { 16 | class = "Pointshop2.ItemPersistence", 17 | foreignKey = "itemPersistenceId", 18 | onDelete = "CASCADE", 19 | } 20 | } 21 | } 22 | 23 | PlayermodelPersistence:include( DatabaseModel ) 24 | PlayermodelPersistence:include( Pointshop2.EasyExport ) 25 | 26 | function PlayermodelPersistence.static.createOrUpdateFromSaveTable( saveTable, doUpdate ) 27 | return Pointshop2.ItemPersistence.createOrUpdateFromSaveTable( saveTable, doUpdate ) 28 | :Then( function( itemPersistence ) 29 | if doUpdate then 30 | return PlayermodelPersistence.findByItemPersistenceId( itemPersistence.id ) 31 | else 32 | local playermodelPersistence = PlayermodelPersistence:new( ) 33 | playermodelPersistence.itemPersistenceId = itemPersistence.id 34 | return playermodelPersistence 35 | end 36 | end ) 37 | :Then( function( playermodelPersistence ) 38 | playermodelPersistence.playerModel = saveTable.playerModel 39 | playermodelPersistence.bodygroups = saveTable.bodygroups 40 | playermodelPersistence.skin = saveTable.skin 41 | return playermodelPersistence:save( ) 42 | end ) 43 | end -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/playermodel/sh_slot.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.AddEquipmentSlot( "Model", function( item ) 2 | --Check if the item is a playermodel 3 | return instanceOf( Pointshop2.GetItemClassByName( "base_playermodel" ), item ) 4 | end, 0 ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/points_over_time/sv_afkchecker.lua: -------------------------------------------------------------------------------- 1 | -- Kindly provided by [HDG]2Sneaky 2 | 3 | local gametimer = SysTime() 4 | function Wintermute() 5 | if (SysTime() - gametimer) < 60 then 6 | return 7 | end 8 | 9 | gametimer = SysTime() 10 | for k, v in pairs( player.GetAll() ) do 11 | if not v:Alive() then 12 | continue 13 | end 14 | 15 | local oldafkpos = v:GetNWInt("afkpos", Vector(0,0,0)) 16 | local curafkpos = v:GetPos() 17 | if oldafkpos == curafkpos then 18 | local afktimer = v:GetNWInt("afktimer", 0) 19 | local newafktimer = afktimer + 1 20 | if newafktimer == 5 then 21 | v:PS2_DisplayInformation( "You are AFK, you will no longer receive points. Move to receive points again." ) 22 | v:SetNWBool("playerafk", true) 23 | end 24 | v:SetNWInt("afktimer", (newafktimer) ) 25 | else 26 | v:SetNWInt("afkpos", v:GetPos()) 27 | v:SetNWInt("afktimer", 0 ) 28 | v:SetNWBool("playerafk", false) 29 | end 30 | end 31 | end 32 | 33 | function Pointshop2.AfkCheckInit( ) 34 | for k, v in pairs( player.GetAll( ) ) do 35 | v:SetNWInt( "afkpos", v:GetPos( ) ) 36 | v:SetNWInt( "afktimer", 0 ) 37 | v:SetNWBool( "playerafk", false ) 38 | end 39 | 40 | if Pointshop2.GetSetting( "Pointshop 2", "BasicSettings.PotAfkCheck" ) then 41 | hook.Add( "Tick", "afk think", Wintermute ) 42 | else 43 | hook.Remove( "Tick", "afk think" ) 44 | end 45 | end 46 | 47 | hook.Add( "PS2_OnSettingsUpdate", "POTTimerUpdate", function( ) 48 | Pointshop2.AfkCheckInit( ) 49 | end ) 50 | Pointshop2.SettingsLoadedPromise:Done( function( ) 51 | Pointshop2.AfkCheckInit( ) 52 | end ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/points_over_time/sv_pointsOverTime.lua: -------------------------------------------------------------------------------- 1 | function Pointshop2.UpdatePointsOverTime( ) 2 | Pointshop2.StandardPointsBatch:begin( ) 3 | 4 | local groupMultipliers = Pointshop2.GetSetting( "Pointshop 2", "PointsOverTime.GroupMultipliers" ) 5 | local points = Pointshop2.GetSetting( "Pointshop 2", "PointsOverTime.Points" ) 6 | for k, ply in pairs( player.GetAll( ) ) do 7 | if groupMultipliers[ply:GetUserGroup( )] then 8 | local bonus = groupMultipliers[ply:GetUserGroup( )] * points - points 9 | 10 | --Try to find a nice rank name 11 | local titleLookup = {} 12 | for k, v in pairs( PermissionInterface.getRanks( ) ) do 13 | titleLookup[v.internalName] = v.title 14 | end 15 | 16 | local rank = titleLookup[ply:GetUserGroup()] or ply:GetUserGroup( ) 17 | -- Give points only if player is not afk 18 | if not ( Pointshop2.GetSetting( "Pointshop 2", "BasicSettings.PotAfkCheck" ) and ply:GetNWBool( "playerafk", false ) ) then 19 | ply:PS2_AddStandardPoints( bonus, rank .. " Bonus", true ) 20 | end 21 | end 22 | 23 | -- Give points only if player is not afk 24 | if not ( Pointshop2.GetSetting( "Pointshop 2", "BasicSettings.PotAfkCheck" ) and ply:GetNWBool( "playerafk", false ) ) then 25 | ply:PS2_AddStandardPoints( points, "Playing on the Server" ) 26 | end 27 | end 28 | 29 | Pointshop2.StandardPointsBatch:finish( ) 30 | end 31 | 32 | function Pointshop2.RegisterPOTtimer( ) 33 | --Points over time is disabled for gamemodes with integration plugins 34 | if Pointshop2.IsCurrentGamemodePluginPresent( ) and not Pointshop2.GetSetting( "Pointshop 2", "PointsOverTime.ForceEnable" ) then 35 | return 36 | end 37 | 38 | local delayInSeconds = Pointshop2.GetSetting( "Pointshop 2", "PointsOverTime.Delay" ) * 60 39 | timer.Create( "Pointshop2_POT", delayInSeconds, 0, function( ) 40 | Pointshop2.UpdatePointsOverTime( ) 41 | end ) 42 | end 43 | hook.Add( "PS2_OnSettingsUpdate", "POTTimerUpdate", function( ) 44 | Pointshop2.RegisterPOTtimer( ) 45 | end ) 46 | Pointshop2.SettingsLoadedPromise:Done( function( ) 47 | Pointshop2.RegisterPOTtimer( ) 48 | end ) 49 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/trail/cl_dpointshoptraillicon.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self.image = vgui.Create( "DCenteredImage", self ) 5 | self.image:Dock( FILL ) 6 | self.image:SetMouseInputEnabled( false ) 7 | end 8 | 9 | function PANEL:SetItemClass( itemClass ) 10 | self.BaseClass.SetItemClass( self, itemClass ) 11 | 12 | self.NormalTexture = Material( itemClass.material ) 13 | if not self.NormalTexture then 14 | KLogf(2, "Item " .. itemClass.PrintName .. " there is an error with the texture " .. itemClass.material .. ": it could not be loaded") 15 | self.ScrollingTexture = self.NormalTexture 16 | return 17 | end 18 | if not self.NormalTexture:GetTexture( "$basetexture" ) then 19 | KLogf(2, "Item " .. itemClass.PrintName .. " there is an error with the texture " .. itemClass.material .. ": $basetexture could not be found") 20 | self.ScrollingTexture = self.NormalTexture 21 | return 22 | end 23 | 24 | self.ScrollingTexture = CreateMaterial( "PS2_MatScrollingTrailIcn" .. itemClass.material, "UnlitGeneric", { 25 | ["$basetexture"] = self.NormalTexture:GetTexture( "$basetexture" ):GetName( ), 26 | ["$translucent"] = 1, 27 | Proxies = { 28 | TextureScroll = { 29 | textureScrollVar = "$basetexturetransform", 30 | textureScrollRate = "0.8", 31 | textureScrollAngle = "90", 32 | } 33 | } 34 | } ) 35 | end 36 | 37 | function PANEL:SetItem( item ) 38 | self:SetItemClass( item.class ) 39 | end 40 | 41 | function PANEL:Think( ) 42 | if not self.NormalTexture then 43 | return 44 | end 45 | 46 | if not self.noSelect and ( self.Hovered or self:IsChildHovered( 1 ) or self.Selected ) then 47 | self.image:SetMaterial( self.ScrollingTexture ) 48 | else 49 | self.image:SetMaterial( self.NormalTexture ) 50 | end 51 | end 52 | 53 | derma.DefineControl( "DPointshopTrailIcon", "", PANEL, "DPointshopItemIcon" ) 54 | 55 | local PANEL = {} 56 | 57 | function PANEL:Init( ) 58 | self.image = vgui.Create( "DCenteredImage", self ) 59 | self.image:Dock( FILL ) 60 | self.image:SetMouseInputEnabled( false ) 61 | end 62 | 63 | function PANEL:SetItemClass( itemClass ) 64 | self.BaseClass.SetItemClass( self, itemClass ) 65 | 66 | self.image:SetImage( itemClass.material ) 67 | end 68 | 69 | function PANEL:SetItem( item ) 70 | self:SetItemClass( item.class ) 71 | end 72 | 73 | derma.DefineControl( "DPointshopSimpleTrailIcon", "", PANEL, "DPointshopItemIcon" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/trail/cl_dtrailcreator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:addSectionTitle( "Trail Selection" ) 5 | 6 | self.selectPlayerElem = vgui.Create( "DPanel" ) 7 | self.selectPlayerElem:SetTall( 64 ) 8 | self.selectPlayerElem:SetWide( self:GetWide( ) ) 9 | function self.selectPlayerElem:Paint( ) end 10 | 11 | self.materialPanel = vgui.Create( "DImage", self.selectPlayerElem ) 12 | self.materialPanel:SetSize( 64, 64 ) 13 | self.materialPanel:Dock( LEFT ) 14 | self.materialPanel:SetMouseInputEnabled( true ) 15 | self.materialPanel:SetTooltip( "Click to Select" ) 16 | self.materialPanel:SetMaterial( "trails/musicalnotes" ) 17 | local frame = self 18 | function self.materialPanel:OnMousePressed( ) 19 | --Open model selector 20 | local window = vgui.Create( "DTrailSelector" ) 21 | window:Center( ) 22 | window:MakePopup( ) 23 | window:DoModal() 24 | function window:OnChange( ) 25 | frame.manualEntry:SetText( window.matName ) 26 | frame.materialPanel:SetMaterial( window.selectedMaterial ) 27 | end 28 | end 29 | 30 | local rightPnl = vgui.Create( "DPanel", self.selectPlayerElem ) 31 | rightPnl:Dock( FILL ) 32 | function rightPnl:Paint( ) 33 | end 34 | 35 | self.manualEntry = vgui.Create( "DTextEntry", rightPnl ) 36 | self.manualEntry:Dock( TOP ) 37 | self.manualEntry:DockMargin( 5, 0, 5, 5 ) 38 | self.manualEntry:SetText( "trails/musicalnotes" ) 39 | self.manualEntry:SetTooltip( "Click on the icon or manually enter the material path here and press enter" ) 40 | function self.manualEntry:OnEnter( ) 41 | frame.materialPanel:SetMaterial( self:GetText( ) ) 42 | end 43 | 44 | local cont = self:addFormItem( "Material", self.selectPlayerElem ) 45 | cont:SetTall( 64 ) 46 | end 47 | 48 | function PANEL:SaveItem( saveTable ) 49 | self.BaseClass.SaveItem( self, saveTable ) 50 | saveTable.material = self.manualEntry:GetText( ) 51 | end 52 | 53 | function PANEL:EditItem( persistence, itemClass ) 54 | self.BaseClass.EditItem( self, persistence.ItemPersistence, itemClass ) 55 | 56 | self.manualEntry:SetText( persistence.material ) 57 | self.materialPanel:SetMaterial( persistence.material ) 58 | end 59 | 60 | vgui.Register( "DTrailCreator", PANEL, "DItemCreator" ) 61 | -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/trail/cl_dtrailselector.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetSize( 25 + 64*8+63*4, 400 ) 6 | 7 | self:SetTitle( "Select a Material" ) 8 | 9 | local scroll = vgui.Create( "DScrollPanel", self ) 10 | scroll:Dock( FILL ) 11 | 12 | self.layout = vgui.Create( "DIconLayout", scroll ) 13 | self.layout:SetSpaceX( 5 ) 14 | self.layout:SetSpaceY( 5 ) 15 | self.layout:DockMargin( 0, 2, 0, 5 ) 16 | self.layout:SetWide( 25 + 64*8+63*4 ) 17 | 18 | Pointshop2View:getInstance( ):requestMaterials( "trails" ) 19 | :Then( function( files ) 20 | self:SetTrails( files ) 21 | end ) 22 | end 23 | 24 | function PANEL:SetTrails( files ) 25 | local materials = {} 26 | for k, v in pairs( files ) do 27 | v = string.Replace( v, ".vmt", "" ) 28 | v = string.Replace( v, ".vtf", "" ) 29 | v = "trails/" .. v 30 | if not table.HasValue( materials, v ) then 31 | table.insert( materials, v ) 32 | end 33 | end 34 | 35 | for k, v in pairs( materials ) do 36 | local mat = Material( v ) 37 | if not mat then continue end 38 | 39 | local btn = self.layout:Add( "DImageButton" ) 40 | btn:SetSize( 64, 64 ) 41 | btn:SetImage( v ) 42 | btn.NormalMat = mat 43 | if mat:GetTexture( "$basetexture" ) then 44 | btn.ScrollingTexture = CreateMaterial( "PS2_MatScrollingTrail" .. v, "UnlitGeneric", { 45 | ["$basetexture"] = mat:GetTexture( "$basetexture" ):GetName( ), 46 | ["$translucent"] = 1, 47 | Proxies = { 48 | TextureScroll = { 49 | textureScrollVar = "$basetexturetransform", 50 | textureScrollRate = "0.8", 51 | textureScrollAngle = "90", 52 | } 53 | } 54 | } ) 55 | else 56 | btn.ScrollingTexture = mat 57 | end 58 | function btn:Think( ) 59 | if self.Hovered then 60 | self.m_Image:SetMaterial( self.ScrollingTexture ) 61 | else 62 | self.m_Image:SetMaterial( self.NormalMat ) 63 | end 64 | end 65 | function btn.DoClick( ) 66 | self.selectedMaterial = btn.ScrollingTexture 67 | self.matName = v 68 | self:OnChange( ) 69 | self:Close( ) 70 | end 71 | end 72 | self.layout:InvalidateLayout( true ) 73 | end 74 | 75 | function PANEL:OnChange( ) 76 | --for overwriting 77 | end 78 | 79 | vgui.Register( "DTrailSelector", PANEL, "DFrame" ) -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/trail/sh_model_trailpersistence.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.TrailPersistence = class( "Pointshop2.TrailPersistence" ) 2 | local TrailPersistence = Pointshop2.TrailPersistence 3 | 4 | TrailPersistence.static.DB = "Pointshop2" 5 | 6 | TrailPersistence.static.model = { 7 | tableName = "ps2_trailpersistence", 8 | fields = { 9 | itemPersistenceId = "int", 10 | material = "string" 11 | }, 12 | belongsTo = { 13 | ItemPersistence = { 14 | class = "Pointshop2.ItemPersistence", 15 | foreignKey = "itemPersistenceId", 16 | onDelete = "CASCADE" 17 | } 18 | } 19 | } 20 | 21 | TrailPersistence:include( DatabaseModel ) 22 | TrailPersistence:include( Pointshop2.EasyExport ) 23 | 24 | 25 | function TrailPersistence.static.createOrUpdateFromSaveTable( saveTable, doUpdate ) 26 | return Pointshop2.ItemPersistence.createOrUpdateFromSaveTable( saveTable, doUpdate ) 27 | :Then( function( itemPersistence ) 28 | if doUpdate then 29 | return TrailPersistence.findByItemPersistenceId( itemPersistence.id ) 30 | else 31 | local trail = TrailPersistence:new( ) 32 | trail.itemPersistenceId = itemPersistence.id 33 | return trail 34 | end 35 | end ) 36 | :Then( function( trail ) 37 | trail.material = saveTable.material 38 | return trail:save( ) 39 | end ) 40 | end -------------------------------------------------------------------------------- /lua/ps2/modules/pointshop2/trail/sh_slot.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.AddEquipmentSlot( "Trail", function( item ) 2 | --Check if the item is a trail 3 | return instanceOf( Pointshop2.GetItemClassByName( "base_trail" ), item ) 4 | end, 1 ) 5 | -------------------------------------------------------------------------------- /lua/ps2/modules/prophunt_integration/cl_DPropHuntConfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "Prop Hunt Reward Settings" ) 6 | self:SetSize( 300, 600 ) 7 | 8 | self:AutoAddSettingsTable( Pointshop2.GetModule( "Prop Hunt Integration" ).Settings.Server, self ) 9 | end 10 | 11 | function PANEL:DoSave( ) 12 | Pointshop2View:getInstance( ):saveSettings( self.mod, "Server", self.settings ) 13 | end 14 | 15 | derma.DefineControl( "DPropHuntConfigurator", "", PANEL, "DSettingsEditor" ) 16 | -------------------------------------------------------------------------------- /lua/ps2/modules/prophunt_integration/cl_phpreview.lua: -------------------------------------------------------------------------------- 1 | --If player is in spec and has no model equipped use a Combine as preview 2 | hook.Add( "PS2_GetPreviewModel", "DefaultToHunter", function( ) 3 | if LocalPlayer():Team() == TEAM_PROPS or LocalPlayer():Team() == TEAM_SPECTATOR then 4 | return { 5 | model = player_manager.TranslatePlayerModel( 'combine' ), 6 | bodygroups = "0", 7 | skin = 0 8 | } 9 | end 10 | end ) 11 | -------------------------------------------------------------------------------- /lua/ps2/modules/prophunt_integration/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | --Pointshop2 PH integration 4 | MODULE.Name = "Prop Hunt Integration" 5 | MODULE.Author = "Kamshak" 6 | MODULE.RestrictGamemodes = { "prop_hunt" } --Only load for TTT 7 | 8 | MODULE.Blueprints = {} 9 | 10 | MODULE.SettingButtons = { 11 | { 12 | label = "Point Rewards", 13 | icon = "pointshop2/hand129.png", 14 | control = "DPropHuntConfigurator" 15 | } 16 | } 17 | 18 | MODULE.Settings = {} 19 | 20 | --These are sent to the client on join 21 | MODULE.Settings.Shared = { } 22 | 23 | --These are not sent 24 | MODULE.Settings.Server = { 25 | Kills = { 26 | info = { 27 | label = "Kill Rewards" 28 | }, 29 | 30 | HunterKillsProp = { 31 | value = 100, 32 | label = "Hunter kills Prop", 33 | tooltip = "Points a hunter gets when killing a prop", 34 | }, 35 | }, 36 | RoundWin = { 37 | info = { 38 | label = "Round Win Rewards" 39 | }, 40 | 41 | MinimumPlayers = { 42 | value = 3, 43 | label = "Minimum Players", 44 | tooltip = "Minimum amount of players online for round awards to be given" 45 | }, 46 | 47 | PropsWin = { 48 | value = 100, 49 | label = "Props Win: Points given", 50 | tooltip = "Points given to each prop when props win." 51 | }, 52 | 53 | TimeJackpotPerPlayer = { 54 | value = 130, 55 | label = "Hunters Win: Time Jackpot per Player", 56 | tooltip = "This amount is multiplied with the amount of players to get the time jackpot. The time jackpot decreases with each minute that passed. When hunters win the time jackpot is distributed to the hunters." 57 | }, 58 | 59 | AliveBonus = { 60 | value = 100, 61 | label = "Alive Bonus", 62 | tooltip = "Points given to props/hunters that are still alive at the end of a round." 63 | }, 64 | } 65 | } 66 | 67 | -- For Drops integration: Returns players that can get a drop once the round ends 68 | function MODULE.GetPlayersForDrops( ) 69 | local players = {} 70 | for k, v in pairs( player.GetAll( ) ) do 71 | if v:Team() != TEAM_SPECTATOR then 72 | table.insert( players, v ) 73 | end 74 | end 75 | return players 76 | end 77 | 78 | Pointshop2.RegisterModule( MODULE ) 79 | Pointshop2.NotifyGamemodeModuleLoaded( "prop_hunt", MODULE ) 80 | -------------------------------------------------------------------------------- /lua/ps2/modules/prophunt_integration/sh_prevent_visuals.lua: -------------------------------------------------------------------------------- 1 | local function hideOnProps(ply) 2 | if ply:Team() != TEAM_HUNTERS then 3 | return false 4 | end 5 | end 6 | hook.Add( "PS2_VisualsShouldShow", "OnlyHunters", hideOnProps ) 7 | hook.Add( "PS2_PlayermodelShouldShow", "OnlyHunters", hideOnProps ) 8 | hook.Add( "PS2_WeaponShouldSpawn", "OnlyHunters", hideOnProps ) 9 | -------------------------------------------------------------------------------- /lua/ps2/modules/prophunt_integration/sv_propHuntPropHook.lua: -------------------------------------------------------------------------------- 1 | local function hookProp() 2 | if PHX and PHX ~= nil then return end 3 | 4 | local ENT = scripted_ents.GetStored( 'ph_prop' ) 5 | -- Called when we take damge 6 | function ENT:OnTakeDamage(dmg) 7 | local pl = self:GetOwner() 8 | local attacker = dmg:GetAttacker() 9 | local inflictor = dmg:GetInflictor() 10 | 11 | -- Health 12 | if pl && pl:IsValid() && pl:Alive() && pl:IsPlayer() && attacker:IsPlayer() && dmg:GetDamage() > 0 then 13 | self.health = self.health - dmg:GetDamage() 14 | pl:SetHealth(self.health) 15 | 16 | if self.health <= 0 then 17 | pl:KillSilent() 18 | 19 | if inflictor && inflictor == attacker && inflictor:IsPlayer() then 20 | inflictor = inflictor:GetActiveWeapon() 21 | if !inflictor || inflictor == NULL then inflictor = attacker end 22 | end 23 | 24 | net.Start( "PlayerKilledByPlayer" ) 25 | 26 | net.WriteEntity( pl ) 27 | net.WriteString( inflictor:GetClass() ) 28 | net.WriteEntity( attacker ) 29 | 30 | net.Broadcast() 31 | hook.Run( "PS2_PH_PropKilled", pl, inflictor, attacker ) 32 | 33 | MsgAll(attacker:Name() .. " found and killed " .. pl:Name() .. "\n") 34 | 35 | attacker:AddFrags(1) 36 | pl:AddDeaths(1) 37 | attacker:SetHealth(math.Clamp(attacker:Health() + GetConVar("HUNTER_KILL_BONUS"):GetInt(), 1, 100)) 38 | 39 | pl:RemoveProp() 40 | end 41 | end 42 | end 43 | end 44 | 45 | LibK.WhenAddonsLoaded{ "Pointshop2" }:Then( hookProp ) -------------------------------------------------------------------------------- /lua/ps2/modules/thehidden_integration/cl_dthehiddenconfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "The Hidden Reward Settings" ) 6 | self:SetSize( 300, 600 ) 7 | 8 | self:AutoAddSettingsTable( Pointshop2.GetModule( "Hidden Integration" ).Settings.Server, self ) 9 | self:AutoAddSettingsTable( Pointshop2.GetModule( "Hidden Integration" ).Settings.Shared, self ) 10 | end 11 | 12 | function PANEL:DoSave( ) 13 | Pointshop2View:getInstance( ):saveSettings( self.mod, "Shared", self.settings ) 14 | end 15 | 16 | derma.DefineControl( "DTheHiddenConfigurator", "", PANEL, "DSettingsEditor" ) -------------------------------------------------------------------------------- /lua/ps2/modules/thehidden_integration/sh_module.lua: -------------------------------------------------------------------------------- 1 | local MODULE = {} 2 | 3 | --Pointshop2 The Hidden integration 4 | MODULE.Name = "Hidden Integration" 5 | MODULE.Author = "Kamshak" 6 | MODULE.RestrictGamemodes = { "thehidden" } --Only load for Hidden 7 | 8 | MODULE.Blueprints = {} 9 | 10 | MODULE.SettingButtons = { 11 | { 12 | label = "Reward Settings", 13 | icon = "pointshop2/small43.png", 14 | control = "DTheHiddenConfigurator" 15 | }, 16 | } 17 | 18 | MODULE.Settings = {} 19 | 20 | --These are sent to the client on join 21 | MODULE.Settings.Shared = { } 22 | 23 | --These are not sent 24 | MODULE.Settings.Server = { 25 | PointsOverTime = { 26 | info = { 27 | label = "Survival Points over Time" 28 | }, 29 | 30 | Enable = { 31 | value = true, 32 | label = "Enable", 33 | tooltip = "Gives players that are not The Hidden survival points over time.", 34 | }, 35 | 36 | Points = { 37 | value = 20, 38 | label = "Points", 39 | tooltip = "Points awarded for staying alive", 40 | }, 41 | 42 | Delay = { 43 | value = 1, 44 | label = "Interval in minutes", 45 | tooltip = "Interval in which points are given", 46 | }, 47 | }, 48 | Rewards = { 49 | info = { 50 | label = "Rewards" 51 | }, 52 | 53 | HiddenKilled = { 54 | value = 500, 55 | label = "Points given for killing the Hidden", 56 | tooltip = "Points awarded to the player when killing the Hidden" 57 | }, 58 | 59 | HiddenPointsPerHP = { 60 | value = 5, 61 | label = "Hidden assist bonus", 62 | tooltip = "Points given per Damage done to the Hidden (excludes Killer of the Hidden)" 63 | }, 64 | 65 | HumanKilled = { 66 | value = 100, 67 | label = "Hidden kills human", 68 | tooltip = "Points given to The Hidden when killing a human" 69 | }, 70 | 71 | HumansWin = { 72 | value = 200, 73 | label = "I.R.I.S. Wins", 74 | tooltip = "Points given to each player when humans win a round" 75 | }, 76 | 77 | HiddenWins = { 78 | value = 500, 79 | label = "Hidden wins", 80 | tooltip = "Points given to The Hidden when winning a round" 81 | } 82 | }, 83 | } 84 | 85 | function MODULE:GetPlayersForDrops( ) 86 | return player.GetAll( ) 87 | end 88 | 89 | Pointshop2.RegisterModule( MODULE ) 90 | Pointshop2.NotifyGamemodeModuleLoaded( "thehidden", MODULE ) 91 | -------------------------------------------------------------------------------- /lua/ps2/modules/thehidden_integration/sh_prevent_visuals.lua: -------------------------------------------------------------------------------- 1 | local function hideOnHidden(ply) 2 | if ply:Team() == TEAM_HIDDEN then 3 | return false 4 | end 5 | end 6 | hook.Add( "PS2_VisualsShouldShow", "Hide; TEAM_HIDDEN", hideOnHidden ) 7 | hook.Add( "PS2_PlayermodelShouldShow", "Hide; TEAM_HIDDEN", hideOnHidden ) 8 | -------------------------------------------------------------------------------- /lua/ps2/modules/thehidden_integration/sv_hooks.lua: -------------------------------------------------------------------------------- 1 | local S = function( id ) 2 | return Pointshop2.GetSetting( "Hidden Integration", id ) 3 | end 4 | 5 | hook.Add( "HDN_OnRoundChange", "HiddenPS2", function( state ) 6 | if state == ROUND_ENDED then 7 | hook.Call( "Pointshop2GmIntegration_RoundEnded" ) 8 | end 9 | end ) 10 | 11 | hook.Add( "HDN_OnHiddenDeath", "HiddenPs2", function( hidden, attacker, dmginfo ) 12 | Pointshop2.StandardPointsBatch:begin( ) 13 | 14 | if IsValid( attacker ) then 15 | attacker:PS2_AddStandardPoints( S("Rewards.HiddenKilled"), "Killed the Hidden" ) 16 | end 17 | 18 | if S("Player.RewardHiddenDamage") then 19 | for k, v in pairs( player.GetAll( ) ) do 20 | if IsValid( v ) and v != attacker then 21 | v:PS2_AddStandardPoints( S("Player.HiddenPointsPerHP") * v:GetHiddenDamage(), "Damaged the Hidden (" + v:GetHiddenDamage() + " HP)" ) 22 | end 23 | end 24 | end 25 | 26 | Pointshop2.StandardPointsBatch:finish( ) 27 | end ) 28 | 29 | hook.Add( "HDN_OnWin", "HiddenPS2", function( team ) 30 | Pointshop2.StandardPointsBatch:begin( ) 31 | 32 | if team == TEAM_HUMAN then 33 | for k, v in pairs( player.GetAll( ) ) do 34 | if not v:IsHidden( ) then 35 | v:PS2_AddStandardPoints( S("Rewards.HumansWin"), "Winning the round" ) 36 | end 37 | end 38 | end 39 | 40 | if team == TEAM_HIDDEN then 41 | for k, v in pairs( player.GetAll( ) ) do 42 | if v:IsHidden( ) then 43 | v:PS2_AddStandardPoints( S("Rewards.HiddenWins"), "Winning the round" ) 44 | end 45 | end 46 | end 47 | 48 | Pointshop2.StandardPointsBatch:finish( ) 49 | end ) 50 | 51 | hook.Add( "HDN_GetScoreValue", "HiddenPs2", function( victim, killer ) 52 | if killer:IsHidden( ) then 53 | killer:PS2_AddStandardPoints( S("Rewards.HumanKilled"), "Killed a Human" ) 54 | end 55 | end ) 56 | 57 | old = nil 58 | local function ApplyHook_PlayerSetUpForRound( ) 59 | local meta = FindMetaTable( "Player" ) 60 | old = old or meta.SetUpForRound 61 | function meta:SetUpForRound( team ) 62 | old( self, team ) 63 | hook.Run( "PlayerSetModel", self ) 64 | print( "SetUpForRound; PlaerSetModel") 65 | end 66 | 67 | GAMEMODE.PlayerSetModel = function() end 68 | KLog( 4, "Hooked TheHidden Player:SetUpForRound@" .. tostring( old ) ) 69 | end 70 | 71 | LibK.WhenAddonsLoaded{ "Pointshop2" }:Then( ApplyHook_PlayerSetUpForRound ) 72 | hook.Add( "OnReloaded", "Replace", ApplyHook_PlayerSetUpForRound ) 73 | -------------------------------------------------------------------------------- /lua/ps2/modules/thehidden_integration/sv_pointsovertime.lua: -------------------------------------------------------------------------------- 1 | local S = function( id ) 2 | return Pointshop2.GetSetting( "Hidden Integration", id ) 3 | end 4 | 5 | function Pointshop2.UpdateHiddenPointsOverTime( ) 6 | local points = S( "PointsOverTime.Points" ) 7 | for k, ply in pairs( player.GetAll( ) ) do 8 | if not ply:IsHidden() and ply:Alive() and ply:Team( ) != TEAM_SPECTATOR then 9 | ply:PS2_AddStandardPoints( points, "Alive Bonus", true ) 10 | end 11 | end 12 | end 13 | 14 | function Pointshop2.RegisterHiddenPOTtimer( ) 15 | --Points over time is disabled for gamemodes with integration plugins 16 | if not S( "PointsOverTime.Enable" ) then 17 | return 18 | end 19 | 20 | local delayInSeconds = S( "PointsOverTime.Delay" ) * 60 21 | timer.Create( "Pointshop2_POTTheHidden", delayInSeconds, 0, function( ) 22 | Pointshop2.UpdateHiddenPointsOverTime( ) 23 | end ) 24 | end 25 | hook.Add( "PS2_OnSettingsUpdate", "POTHiddenTimerUpdate", function( ) 26 | Pointshop2.RegisterHiddenPOTtimer( ) 27 | end ) 28 | Pointshop2.SettingsLoadedPromise:Done( function( ) 29 | Pointshop2.RegisterHiddenPOTtimer( ) 30 | end ) 31 | -------------------------------------------------------------------------------- /lua/ps2/modules/ttt_integration/cl_dterrortownconfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "TTT Reward Settings" ) 6 | self:SetSize( 300, 600 ) 7 | 8 | self:AutoAddSettingsTable( Pointshop2.GetModule( "TTT Integration" ).Settings.Server, self ) 9 | end 10 | 11 | function PANEL:DoSave( ) 12 | Pointshop2View:getInstance( ):saveSettings( self.mod, "Server", self.settings ) 13 | end 14 | 15 | derma.DefineControl( "DTerrortownConfigurator", "", PANEL, "DSettingsEditor" ) -------------------------------------------------------------------------------- /lua/ps2/modules/ttt_integration/cl_tttpreview.lua: -------------------------------------------------------------------------------- 1 | --If player is in spec and has no model equipped use a Terrorist as preview model 2 | hook.Add( "PS2_GetPreviewModel", "DefaultToTerrorist", function( ) 3 | if LocalPlayer():IsSpec() and not Pointshop2:IsPlayerModelEquipped( ) then 4 | return { 5 | model = GAMEMODE.playermodel or "models/player/phoenix.mdl", 6 | bodygroups = "0", 7 | skin = 0 8 | } 9 | end 10 | end ) 11 | 12 | hook.Add( "TTTPlayerColor", "FixTTTModel", function( ) 13 | hook.Run( "PS2_DoUpdatePreviewModel" ) 14 | end ) 15 | 16 | /* 17 | Lebofly: one more thing for you, for TTT the preview model usually sticks being whatever playermodel you had equipped on say DR. Which is a problem if the servers don't both use custom player models 18 | */ 19 | hook.Add( "PlayerSpawn", "FixTTTPlayerModel", function( ) 20 | hook.Run( "PS2_DoUpdatePreviewModel" ) 21 | end ) 22 | -------------------------------------------------------------------------------- /lua/ps2/modules/zs_integration/cl_dzombiesurvivalconfigurator.lua: -------------------------------------------------------------------------------- 1 | local PANEL = {} 2 | 3 | function PANEL:Init( ) 4 | self:SetSkin( Pointshop2.Config.DermaSkin ) 5 | self:SetTitle( "ZS Reward Settings" ) 6 | self:SetSize( 300, 600 ) 7 | 8 | self:AutoAddSettingsTable( Pointshop2.GetModule( "ZS Integration" ).Settings.Server, self ) 9 | end 10 | 11 | function PANEL:DoSave( ) 12 | Pointshop2View:getInstance( ):saveSettings( self.mod, "Server", self.settings ) 13 | end 14 | 15 | derma.DefineControl( "DZombiesurvivalConfigurator", "", PANEL, "DSettingsEditor" ) -------------------------------------------------------------------------------- /lua/ps2/modules/zs_integration/sh_prevent_visuals.lua: -------------------------------------------------------------------------------- 1 | local function disableForZombies(ply) 2 | if ply:Team() == TEAM_UNDEAD then 3 | return false 4 | end 5 | if ply:GetObserverMode() != OBS_MODE_NONE then 6 | return false 7 | end 8 | end 9 | hook.Add( "PS2_PlayermodelShouldShow", "Hide; TEAM_UNDEAD", disableForZombies ) 10 | hook.Add( "PS2_WeaponShouldSpawn", "Hide; TEAM_UNDEAD", disableForZombies ) -------------------------------------------------------------------------------- /lua/ps2/server/sv_playerextension.lua: -------------------------------------------------------------------------------- 1 | local Player = FindMetaTable( "Player" ) 2 | 3 | function Player:PS2_AddStandardPoints( points, message, small, suppressEvent ) 4 | if points == 0 then return end 5 | 6 | if suppressEvent == nil then 7 | suppressEvent = points < 0 8 | end 9 | 10 | if not suppressEvent then 11 | hook.Run( "PS2_PointsAwarded", self, points, "points" ) 12 | end 13 | 14 | if Pointshop2.StandardPointsBatch:isInProgress( ) then 15 | Pointshop2.StandardPointsBatch:addPoints( self, points ) 16 | else 17 | Pointshop2Controller:getInstance( ):addToPlayerWallet( self, "points", points ) 18 | end 19 | 20 | if message then 21 | Pointshop2Controller:getInstance( ):addToPointFeed( self, message, points, small ) 22 | end 23 | end 24 | 25 | function Player:PS2_AddPremiumPoints( points) 26 | if points == 0 then return end 27 | 28 | hook.Run( "PS2_PointsAwarded", self, points, "premiumPoints" ) 29 | 30 | if Pointshop2.PremiumPointsBatch:isInProgress( ) then 31 | Pointshop2.PremiumPointsBatch:addPoints( self, points ) 32 | else 33 | Pointshop2Controller:getInstance( ):addToPlayerWallet( self, "premiumPoints", points ) 34 | end 35 | end 36 | 37 | function Player:PS2_EasyAddItem( itemClassName, purchaseData, suppressNotify ) 38 | if not self:PS2_HasInventorySpace( 1 ) then 39 | return Promise.Reject( 1, "No space in Inventory" ) 40 | end 41 | return Pointshop2Controller:getInstance():easyAddItem( self, itemClassName, purchaseData, suppressNotify ) 42 | end 43 | 44 | function Player:PS2_DisplayInformation( text, time ) 45 | Pointshop2Controller:getInstance( ):startView( "Pointshop2View", "displayInformation", self, text, time ) 46 | end 47 | 48 | function Player:PS2_DisplayError( text, time ) 49 | if isstring( time ) then 50 | time = nil 51 | end 52 | Pointshop2Controller:getInstance( ):startView( "Pointshop2View", "displayError", self, text, time ) 53 | end 54 | -------------------------------------------------------------------------------- /lua/ps2/server/sv_pointshopcontroller_outfits.lua: -------------------------------------------------------------------------------- 1 | function Pointshop2Controller:loadOutfits( ) 2 | return WhenAllFinished{ Pointshop2.StoredOutfit.getAll( ) } 3 | :Then( function( outfits ) 4 | 5 | local outfitsAssoc = {} 6 | for k, v in pairs( outfits ) do 7 | outfitsAssoc[v.id] = v.outfitData 8 | end 9 | Pointshop2.Outfits = outfitsAssoc 10 | 11 | local data = util.TableToJSON( { outfitsAssoc } ) 12 | local resource = LibK.GLib.Resources.RegisterData( "Pointshop2", "outfits", data ) 13 | resource:GetCompressedData( ) --Force compression now 14 | local versionHash = resource:GetVersionHash( ) 15 | KLogf( 4, "[Pointshop2] Outfit package loaded, version " .. versionHash .. " " .. #outfitsAssoc .. " outfits." ) 16 | end ) 17 | end 18 | 19 | function Pointshop2Controller:SendInitialOutfitPackage( ply ) 20 | local resource = LibK.GLib.Resources.Resources["Pointshop2/outfits"] 21 | if not resource then 22 | KLogf( 4, "[Pointshop2] Outfit package not loaded yet, trying again later" ) 23 | end 24 | 25 | Pointshop2.OutfitsLoadedPromise:Then( function( resource ) 26 | self:startView( "Pointshop2View", "loadOutfits", ply, resource:GetVersionHash( ) ) 27 | end ) 28 | end 29 | 30 | --Player notifies us that he has loaded and decoded all PAC outfits 31 | function Pointshop2Controller:outfitsReceived( ply ) 32 | KLogf( 5, "Received outfits from %s", ply:Name( ) ) 33 | if ply.outfitsReceivedPromise._promise._state == "pending" then 34 | ply.outfitsReceivedPromise:Resolve( ) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lua/ps2/server/sv_pointshopcontroller_ranks.lua: -------------------------------------------------------------------------------- 1 | -- Update the base ps2_itempsersistences table ranks and reload the item class. 2 | function Pointshop2Controller:updateRankRestrictions( ply, itemClassNames, ranks ) 3 | local saveTbl = {} 4 | for k, v in pairs( itemClassNames ) do 5 | saveTbl[k]= tonumber(v) 6 | end 7 | local saveStr = table.concat( saveTbl, "," ) 8 | 9 | local dbEntries = Pointshop2.ItemPersistence.getDbEntries( "WHERE id IN (" .. saveStr .. ")" ) 10 | :Then( function( itemPersistences ) 11 | return Promise.Map( itemPersistences, function( persistence ) 12 | -- Update the ranks 13 | persistence.ranks = ranks 14 | return persistence:save () 15 | end ) 16 | end ) 17 | :Then( function( persistences ) 18 | PrintTable(persistences) 19 | local persistenceIds = LibK._.map( persistences, function( p ) return tostring( p.id ) end ) 20 | self:notifyItemsChanged( persistenceIds ) 21 | end ) 22 | end 23 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_config.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.Config = {} 2 | local Config = Pointshop2.Config 3 | 4 | /* 5 | Skin to use 6 | */ 7 | Config.DermaSkin = "PS2FlatUI" -------------------------------------------------------------------------------- /lua/ps2/shared/sh_equipmentslots.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.EquipmentSlots = { } -- { { name = validationFunction }, ... } 2 | Pointshop2.EquipmentSlotLookup = {} 3 | 4 | function Pointshop2.IsItemValidForSlot( item, slotName ) 5 | return Pointshop2.EquipmentSlotLookup[slotName]( item ) 6 | end 7 | 8 | function Pointshop2.RemoveEquipmentSlot( slotName ) 9 | Pointshop2.EquipmentSlotLookup[slotName] = nil 10 | for k, v in pairs(Pointshop2.EquipmentSlots) do 11 | if v.name == slotName then 12 | Pointshop2.EquipmentSlots[k] = nil 13 | end 14 | end 15 | end 16 | 17 | function Pointshop2.FindEquipmentSlot( slotName ) 18 | for k, v in pairs( Pointshop2.EquipmentSlots ) do 19 | if v.name == slotName then 20 | return Pointshop2.EquipmentSlots[k] 21 | end 22 | end 23 | end 24 | 25 | function Pointshop2.AddEquipmentSlotEx( slot ) 26 | table.insert( Pointshop2.EquipmentSlots, slot ) 27 | Pointshop2.EquipmentSlotLookup[slot.name] = slot.canHoldItem 28 | 29 | Pointshop2.EquipmentSlots[#Pointshop2.EquipmentSlots].order2 = #Pointshop2.EquipmentSlots 30 | table.sort( Pointshop2.EquipmentSlots, function( a, b ) 31 | if a.order < b.order then 32 | return true 33 | end 34 | if a.order > b.order then 35 | return false 36 | end 37 | return a.order2 < b.order2 38 | end ) 39 | end 40 | 41 | function Pointshop2.AddEquipmentSlot( slotName, func, order ) 42 | local slot = { 43 | name = slotName, 44 | canHoldItem = func, 45 | order = order or math.huge 46 | } 47 | Pointshop2.AddEquipmentSlotEx(slot) 48 | end 49 | 50 | function Pointshop2.IsValidEquipmentSlot( slotName ) 51 | return Pointshop2.EquipmentSlotLookup[slotName] != nil 52 | end 53 | 54 | if CLIENT then 55 | function Pointshop2.FindSlotThatContains(item) 56 | for slotName, itemInSlot in pairs(LocalPlayer().PS2_Slots) do 57 | if itemInSlot == item then 58 | return slotName 59 | end 60 | end 61 | end 62 | else 63 | function Pointshop2.FindSlotThatContains(ply, item) 64 | for name, slot in pairs(ply.PS2_Slots) do 65 | if slot.itemId and slot.itemId == item.id then 66 | return slot.slotName 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_mixin_easyexport.lua: -------------------------------------------------------------------------------- 1 | --Easy export mixin 2 | --It would be possible to do more automagic by detecting libk joins etc through the models 3 | --this is not done to give the user more control and avoid complex solutions 4 | 5 | Pointshop2.EasyExport = {} 6 | local EasyExport = Pointshop2.EasyExport 7 | 8 | local function generateExportTable( class ) 9 | return class.getDbEntries( "WHERE 1" ) 10 | :Then( function( instances ) 11 | local exportTable = {} 12 | 13 | for _, instance in pairs( instances ) do 14 | local export = instance:generateInstanceExportTable( ) 15 | table.insert( exportTable, export ) 16 | end 17 | 18 | return exportTable 19 | end ) 20 | end 21 | 22 | local copyModelFields = LibK.copyModelFields 23 | local function importDataFromTable( class, exportTable ) 24 | local promises = {} 25 | 26 | for _, instanceExport in pairs( exportTable ) do 27 | local itemPersistence = Pointshop2.ItemPersistence:new( ) 28 | copyModelFields( itemPersistence, instanceExport.ItemPersistence, Pointshop2.ItemPersistence.model ) 29 | itemPersistence.uuid = LibK.GetUUID() 30 | 31 | local promise = itemPersistence:save( ) 32 | :Then( function( itemPersistence ) 33 | local actualPersistence = class:new( ) 34 | copyModelFields( actualPersistence, instanceExport, class.model ) 35 | actualPersistence.itemPersistenceId = itemPersistence.id 36 | return actualPersistence:save( ) 37 | end ) 38 | table.insert( promises, promise ) 39 | end 40 | 41 | return WhenAllFinished( promises ) 42 | end 43 | 44 | function EasyExport:included( class ) 45 | --Bind generateExportTable to class 46 | class.generateExportTable = function( ) 47 | return generateExportTable( class ) 48 | end 49 | 50 | class.importDataFromTable = function( exportTable ) 51 | return importDataFromTable( class, exportTable ) 52 | end 53 | end 54 | 55 | --This one works only for simple classes with only one ItemPersistence relationship! 56 | function EasyExport:generateInstanceExportTable( ) 57 | --Serialize all info but remove id and class fields 58 | local cleanTable = generateNetTable( self ) 59 | cleanTable.id = nil 60 | cleanTable.itemPersistenceId = nil 61 | cleanTable._classname = nil 62 | 63 | cleanTable.ItemPersistence = self.ItemPersistence:generateInstanceExportTable( ) 64 | 65 | return cleanTable 66 | end -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_categorysettings.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.Category = class( "Pointshop2.Category" ) 2 | local Category = Pointshop2.Category 3 | 4 | Category.static.DB = "Pointshop2" 5 | 6 | Category.static.model = { 7 | tableName = "ps2_categories", 8 | fields = { 9 | parent = "optKey", 10 | label = "string", 11 | icon = "string" 12 | } 13 | } 14 | 15 | Category:include( DatabaseModel ) 16 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_equipmentslot.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.EquipmentSlot = class( "Pointshop2.EquipmentSlot" ) 2 | local EquipmentSlot = Pointshop2.EquipmentSlot 3 | 4 | EquipmentSlot.static.DB = "Pointshop2" 5 | 6 | EquipmentSlot.static.model = { 7 | tableName = "ps2_equipmentslot", 8 | fields = { 9 | itemId = "optKey", --Contained item 10 | slotName = "string", 11 | ownerId = "int" --Owning player id 12 | }, 13 | belongsTo = { 14 | Item = { 15 | class = "KInventory.Item", 16 | foreignKey = "itemId", 17 | onDelete = "SET NULL" 18 | }, 19 | /*Owner = { 20 | class = "LibK.Player", 21 | foreignKey = "ownerId" 22 | }*/ 23 | } 24 | } 25 | 26 | EquipmentSlot:include( DatabaseModel ) 27 | 28 | function EquipmentSlot:removeItem( item ) 29 | local def = Deferred( ) 30 | 31 | if self.itemId != item.id then 32 | def:Reject( -1, "Slot doesn't hold this item" ) 33 | return def:Promise( ) 34 | end 35 | 36 | self.itemId = nil 37 | self.Item = nil 38 | return self:save( ) 39 | end 40 | 41 | function EquipmentSlot:getOwner( ) 42 | for k, v in pairs( player.GetAll( ) ) do 43 | if tonumber( v:GetNWInt( "KPlayerId" ) ) == self.ownerId or 44 | tonumber( v.kPlayerId or -1 ) == self.ownerId then 45 | return v 46 | end 47 | end 48 | end 49 | 50 | function EquipmentSlot:postLoad( ) 51 | local def = Deferred( ) 52 | 53 | if self.Item then 54 | self.Item.owner = self:getOwner( ) 55 | end 56 | 57 | def:Resolve( ) 58 | return def:Promise( ) 59 | end -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_itemmapping.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.ItemMapping = class( "Pointshop2.ItemMapping" ) 2 | local ItemMapping = Pointshop2.ItemMapping 3 | 4 | ItemMapping.static.DB = "Pointshop2" 5 | 6 | ItemMapping.static.model = { 7 | tableName = "ps2_itemmapping", 8 | fields = { 9 | categoryId = "int", 10 | itemClass = "string" 11 | }, 12 | belongsTo = { 13 | Category = { 14 | class = "Pointshop2.Category", 15 | foreignKey = "categoryId", 16 | onDelete = "CASCADE" 17 | } 18 | } 19 | } 20 | 21 | ItemMapping:include( DatabaseModel ) -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_itempersistence.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.ItemPersistence = class( "Pointshop2.ItemPersistence" ) 2 | local ItemPersistence = Pointshop2.ItemPersistence 3 | 4 | ItemPersistence.static.DB = "Pointshop2" 5 | 6 | ItemPersistence.static.model = { 7 | tableName = "ps2_itempersistence", 8 | fields = { 9 | baseClass = "string", --Controller 10 | price = "optKey", --INT NULL 11 | pricePremium = "optKey", --INT NULL 12 | ranks = "json", 13 | name = "string", 14 | uuid = "string", 15 | description = "text", 16 | createdAt = "createdTime", 17 | updatedAt = "updatedTime", 18 | servers = "luadata" 19 | } 20 | } 21 | 22 | ItemPersistence:include( DatabaseModel ) 23 | 24 | function ItemPersistence.static.createOrUpdateFromSaveTable( saveTable, doUpdate ) 25 | local def = Deferred( ) 26 | if doUpdate then 27 | ItemPersistence.findById( saveTable.persistenceId ) 28 | :Done( function( persistence ) 29 | def:Resolve( persistence ) 30 | end ) 31 | :Fail( function( errid, err ) 32 | def:Reject( errid, err ) 33 | end ) 34 | else 35 | local instance = ItemPersistence:new( ) 36 | instance.uuid = LibK.GetUUID() 37 | def:Resolve( instance ) 38 | end 39 | 40 | return def:Then( function( instance ) 41 | instance.price = saveTable.price 42 | instance.pricePremium = saveTable.pricePremium 43 | instance.ranks = {} 44 | instance.name = saveTable.name 45 | instance.baseClass = saveTable.baseClass 46 | instance.description = saveTable.description 47 | return instance:save( ) 48 | end ) 49 | end 50 | 51 | function ItemPersistence:generateInstanceExportTable( ) 52 | local cleanTable = generateNetTable( self ) 53 | cleanTable.id = nil 54 | cleanTable._classname = nil 55 | return cleanTable 56 | end 57 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_server.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.Server = class( "Pointshop2.Server" ) 2 | local Server = Pointshop2.Server 3 | 4 | Server.static.DB = "Pointshop2" 5 | 6 | Server.static.model = { 7 | tableName = "ps2_servers", 8 | fields = { 9 | serverHash = "string", 10 | ip = "string", 11 | port = "int", 12 | name = "string", 13 | } 14 | } 15 | 16 | Server:include( DatabaseModel ) 17 | 18 | function Server:setToCurrentServer( ) 19 | local ip, port = Pointshop2.GetServerIpAndPort( ) 20 | self.ip = ip 21 | self.port = port 22 | self.serverHash = Pointshop2.CalculateServerHash( ) 23 | self.name = GetConVarString( "hostname" ) 24 | end 25 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_settings.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.StoredSetting = class( "Pointshop2.StoredSetting" ) 2 | local StoredSetting = Pointshop2.StoredSetting 3 | 4 | StoredSetting.static.DB = "Pointshop2" 5 | 6 | StoredSetting.static.model = { 7 | tableName = "ps2_settings", 8 | fields = { 9 | plugin = "string", 10 | path = "string", 11 | value = "json", 12 | serverId = "optKey" 13 | } 14 | } 15 | 16 | StoredSetting:include( DatabaseModel ) -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_storedoutfit.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.StoredOutfit = class( "Pointshop2.StoredOutfit" ) 2 | local StoredOutfit = Pointshop2.StoredOutfit 3 | 4 | StoredOutfit.static.DB = "Pointshop2" 5 | 6 | StoredOutfit.static.model = { 7 | tableName = "ps2_outfits", 8 | fields = { 9 | outfitData = "luadata", --contains lua data encoded outfits that are decoded on the client 10 | updatedAt = "updatedTime" 11 | } 12 | } 13 | 14 | StoredOutfit:include( DatabaseModel ) 15 | 16 | function StoredOutfit.static.getVersionHash( ) 17 | return DATABASES[StoredOutfit.DB].DoQuery( "SELECT MAX( updatedAt ) AS updatedAt FROM " .. StoredOutfit.model.tableName ) 18 | :Then( function( rows ) 19 | if rows[1].updatedAt == "NULL" then 20 | rows[1].updatedAt = nil 21 | end 22 | local versionHash = rows[1].updatedAt and tostring( rows[1].updatedAt ) or "-1" 23 | return util.CRC( versionHash ) 24 | end ) 25 | end -------------------------------------------------------------------------------- /lua/ps2/shared/sh_model_wallet.lua: -------------------------------------------------------------------------------- 1 | Pointshop2.Wallet = class( "Pointshop2.Wallet" ) 2 | local Wallet = Pointshop2.Wallet 3 | 4 | Wallet.static.DB = "Pointshop2" 5 | 6 | Wallet.static.model = { 7 | tableName = "ps2_wallet", 8 | fields = { 9 | ownerId = "int", 10 | points = "intUnsigned", 11 | premiumPoints = "intUnsigned" 12 | }, 13 | belongsTo = { 14 | Owner = { 15 | class = "KPlayer", 16 | foreignKey = "ownerId", 17 | onDelete = "CASCADE" 18 | } 19 | } 20 | } 21 | 22 | Wallet:include( DatabaseModel ) 23 | 24 | function Wallet:GetOwner( ) 25 | local walletOwner 26 | for k, v in pairs( player.GetAll( ) ) do 27 | if v.kPlayerId == self.ownerId then 28 | walletOwner = v 29 | end 30 | end 31 | return walletOwner 32 | end 33 | 34 | function Wallet:broacastChanges( ) 35 | return Pointshop2Controller:getInstance( ):broadcastWalletChanges( self ) 36 | end 37 | -------------------------------------------------------------------------------- /lua/ps2/shared/sh_pacprotect.lua: -------------------------------------------------------------------------------- 1 | function Pointshop2.ApplyPacSettings( ) 2 | // Disallow saving/applying outfits 3 | hook.Add("PrePACConfigApply", "Pointshop2CheckPACAccess", function( owner, data, bPac3 ) 4 | if not IsValid( owner ) or not owner:IsPlayer( ) then 5 | return false, "invalid player" 6 | end 7 | if Pointshop2.GetSetting( "Pointshop 2", "BasicSettings.LimitPACAccess" ) then 8 | if not PermissionInterface.query( owner, "pointshop2 usepac" ) then 9 | return false, "Permission Denied" 10 | end 11 | end 12 | return true, "" 13 | end ) 14 | 15 | // Disallow opening the editor 16 | hook.Add( "PrePACEditorOpen", "Pointshop2CheckPACAccess", function( ply ) 17 | if Pointshop2.GetSetting( "Pointshop 2", "BasicSettings.LimitPACAccess" ) then 18 | if not PermissionInterface.query( ply, "pointshop2 usepac" ) then 19 | return false 20 | end 21 | end 22 | end ) 23 | end 24 | 25 | hook.Add( "PS2_OnSettingsUpdate", "ProtectPAC", function( ) 26 | Pointshop2.ApplyPacSettings( ) 27 | end ) 28 | -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.1.0.lua: -------------------------------------------------------------------------------- 1 | /* 2 | This update script is ran when pointshop2 is updated from a version before the update system was in place. 3 | It is also run on a clean install so some checks are required. 4 | */ 5 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 6 | 7 | local function addSettingsField( ) 8 | return DB.FieldExistsInTable( "ps2_settings", "serverId" ) 9 | :Then( function( exists ) 10 | if not exists then 11 | return DB.DoQuery( "ALTER TABLE `ps2_settings` ADD `serverId` INT NULL" ) 12 | end 13 | end ) 14 | :Then( function( ) 15 | print( "\t Added column serverId to settings" ) 16 | end ) 17 | end 18 | 19 | local function addServersField( ) 20 | return DB.FieldExistsInTable( "ps2_itempersistence", "servers" ) 21 | :Then( function( exists ) 22 | if not exists then 23 | DB.DoQuery( "ALTER TABLE `ps2_itempersistence` ADD `servers` TEXT" ) 24 | end 25 | end ) 26 | :Done( function( ) 27 | print( "\t Added column servers to persistence" ) 28 | end ) 29 | end 30 | 31 | return DB.ConnectionPromise 32 | :Then( function( ) 33 | return DB.TableExists( 'ps2_itempersistence' ) 34 | end ) 35 | :Then( function( shouldUpdate ) 36 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "not need" ) 37 | if shouldUpdate then 38 | return WhenAllFinished{ addSettingsField(), addServersField() } 39 | else 40 | return Promise.Resolve( ) 41 | end 42 | end ) 43 | :Then( function( ) end, function( errid, err ) 44 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 45 | return Promise.Reject( errid, err ) 46 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.14.0.lua: -------------------------------------------------------------------------------- 1 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 2 | 3 | return DB.ConnectionPromise:Then( function( ) 4 | return DB.TableExists('kinv_items') 5 | end ) 6 | :Then( function( shouldUpdate ) 7 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "don't need" ) 8 | if not shouldUpdate then 9 | return 10 | end 11 | 12 | if DB.CONNECTED_TO_MYSQL then 13 | return DB.DoQuery([[ 14 | UPDATE kinv_items SET itempersistence_id = IF(CAST(SUBSTRING(itemclass, 18) AS SIGNED) = 0, NULL, CAST(SUBSTRING(itemclass, 18) AS SIGNED)) 15 | WHERE itemclass REGEXP "^KInventory\\.Items\\.[0-9]+$" 16 | ]]) 17 | end 18 | end ) 19 | :Then( function() end, function( errid, err ) 20 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 21 | return Promise.Reject( errid, err ) 22 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.19.0.lua: -------------------------------------------------------------------------------- 1 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 2 | 3 | local function generateUpdateQuery(dataObjects) 4 | local query = "UPDATE kinv_items SET data = CASE id " 5 | local affectedIds = {} 6 | local parts = {} 7 | for id, json in pairs( dataObjects ) do 8 | table.insert( affectedIds, tonumber( id ) ) 9 | table.insert( parts, Format( 'WHEN "%i" THEN %s', id, DB.SQLStr(json) ) ) 10 | end 11 | query = query .. table.concat( parts, " " ) 12 | query = query .. ' ELSE data END WHERE id IN (' .. table.concat( affectedIds, ', ' ) .. ')' 13 | return query 14 | end 15 | 16 | --[[ 17 | There was a bug in previous versions where Inventory and ItemPersistence would be serialized 18 | because saveFields was not set. This is quite bad for performance as items become pretty big. 19 | This fixes it. 20 | ]] 21 | return DB.ConnectionPromise:Then( function( ) 22 | return DB.TableExists('kinv_items') 23 | end ) 24 | :Then( function( shouldUpdate ) 25 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "don't need" ) 26 | if not shouldUpdate then 27 | return 28 | end 29 | 30 | return DB.DoQuery("SELECT id, data FROM kinv_items") 31 | :Then( function(data) 32 | if not data or #data == 0 then 33 | return 34 | end 35 | 36 | -- Update data in chunks of 50 items 37 | local splitted = LibK.splitTable( data, 50 ) 38 | local promises = { } 39 | for k, chunk in pairs(splitted) do 40 | local dataObjects = {} 41 | for _, item in pairs(chunk) do 42 | local decoded = util.JSONToTable(item.data) or {} 43 | if decoded['ItemPersistence'] or decoded['Inventory'] then 44 | decoded['ItemPersistence'] = nil 45 | decoded['Inventory'] = nil 46 | dataObjects[item.id] = util.TableToJSON(decoded) 47 | end 48 | end 49 | 50 | if table.Count(dataObjects) > 0 then 51 | local query = generateUpdateQuery(dataObjects) 52 | table.insert(promises, DB.DoQuery(query)) 53 | end 54 | end 55 | 56 | return WhenAllFinished(promises, { noUnpack = true }) 57 | end ) 58 | end ) 59 | :Then( function() end, function( errid, err ) 60 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 61 | return Promise.Reject( errid, err ) 62 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.2.0.lua: -------------------------------------------------------------------------------- 1 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 2 | 3 | local function convertCategoryOrganization( ) 4 | Pointshop2 = {} 5 | include( "ps2/shared/sh_model_categorysettings.lua" ) 6 | Pointshop2.Category.static.DB = "Update" 7 | 8 | return Pointshop2.Category.getDbEntries( "WHERE parent IS NULL" ) 9 | :Then( function( categories ) 10 | if #categories == 1 and categories[1].label == "Root" then 11 | -- Already updated 12 | print( "Already updated to new format: Root node exists" ) 13 | return 14 | end 15 | 16 | local rootNode = Pointshop2.Category:new( ) 17 | rootNode.label = "Root" 18 | rootNode.icon = "Root" 19 | 20 | return rootNode:save( ) 21 | :Then( function( rootNode ) 22 | local notForSale = Pointshop2.Category:new( ) 23 | notForSale.label = "Not for sale Items" 24 | notForSale.icon = "pointshop2/circle14.png" 25 | notForSale.parent = rootNode.id 26 | 27 | local shopCategories = Pointshop2.Category:new( ) 28 | shopCategories.label = "Shop Categories" 29 | shopCategories.icon = "pointshop2/folder62.png" 30 | shopCategories.parent = rootNode.id 31 | 32 | return WhenAllFinished{ notForSale:save( ), shopCategories:save( ) } 33 | end ) 34 | :Then( function( notForSale, shopCategories ) 35 | print( "NotForSale: ", notForSale.id ) 36 | print( "Shop:", shopCategories.id ) 37 | local promises = {} 38 | for k, v in pairs( categories ) do 39 | v.parent = shopCategories.id 40 | table.insert( promises, v:save( ) ) 41 | print( "Updated ", v.label ) 42 | end 43 | return WhenAllFinished( promises ) 44 | end ) 45 | end ) 46 | end 47 | 48 | return DB.ConnectionPromise 49 | :Then( function( ) 50 | return DB.TableExists( 'ps2_itempersistence' ) 51 | end ) 52 | :Then( function( shouldUpdate ) 53 | KLogf( 2, "[INFO] We are on %s, %s", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", tostring(shouldUpdate) ) 54 | if shouldUpdate then 55 | return convertCategoryOrganization( ) 56 | end 57 | end ) 58 | :Then( function( ) end, function( errid, err ) 59 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 60 | return Promise.Reject( errid, err ) 61 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.22.0.lua: -------------------------------------------------------------------------------- 1 | local function sqliteUseAutoincrement( DB ) 2 | local res = sql.Query([[ 3 | PRAGMA foreign_keys = OFF; 4 | BEGIN; 5 | DROP TABLE IF EXISTS new_kinv_items; 6 | CREATE TABLE `new_kinv_items` ( 7 | `itemclass` VARCHAR(255) NOT NULL, 8 | `data` MEDIUMTEXT, 9 | `inventory_id` INT(11), 10 | `id` INTEGER PRIMARY KEY AUTOINCREMENT, 11 | `itempersistence_id` INT(11), 12 | CONSTRAINT `FK_428461545` 13 | FOREIGN KEY (`inventory_id`) 14 | REFERENCES `inventories` (`id`) 15 | ON DELETE SET NULL 16 | ON UPDATE SET NULL, 17 | CONSTRAINT `FK_3675580661` 18 | FOREIGN KEY (`itempersistence_id`) 19 | REFERENCES `ps2_itempersistence` (`id`) 20 | ON DELETE CASCADE 21 | ON UPDATE SET NULL 22 | ); 23 | INSERT INTO new_kinv_items SELECT `itemclass`, `data`, `inventory_id`, `id`, `itempersistence_id` FROM kinv_items; 24 | DROP TABLE kinv_items; 25 | ALTER TABLE new_kinv_items RENAME TO kinv_items; 26 | COMMIT; 27 | PRAGMA foreign_keys = ON; 28 | ]]) 29 | 30 | if res == false then 31 | local res = Promise.Reject(0, sql.LastError()) 32 | sql.Query("ROLLBACK") 33 | return res 34 | end 35 | return Promise.Resolve() 36 | end 37 | 38 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 39 | 40 | return DB.ConnectionPromise:Then( function( ) 41 | return DB.TableExists('kinv_items') 42 | end ) 43 | :Then( function( shouldUpdate ) 44 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "don't need" ) 45 | if not shouldUpdate then 46 | return 47 | end 48 | 49 | if DB.CONNECTED_TO_MYSQL then 50 | return 51 | else 52 | return sqliteUseAutoincrement( DB ) 53 | end 54 | end ) 55 | :Then( function() end, function( errid, err ) 56 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 57 | return Promise.Reject( errid, err ) 58 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.25.0.lua: -------------------------------------------------------------------------------- 1 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 2 | 3 | local function performUpdate() 4 | -- Fix: make sure that itempersistence_id field matches the classname filed 5 | if DB.CONNECTED_TO_MYSQL then 6 | return DB.DoQuery([[ 7 | UPDATE kinv_items SET itempersistence_id = IF(CAST(SUBSTRING(itemclass, 18) AS SIGNED) = 0, NULL, CAST(SUBSTRING(itemclass, 18) AS SIGNED)) 8 | WHERE itemclass REGEXP "^KInventory\\.Items\\.[0-9]+$" 9 | ]]) 10 | else 11 | return DB.DoQuery([[ 12 | UPDATE kinv_items SET itempersistence_id = CASE WHEN CAST(substr(itemclass, 18) AS NUMERIC) = 0 THEN NULL ELSE CAST(substr(itemclass, 18) AS NUMERIC) END 13 | ]]) 14 | end 15 | end 16 | 17 | return DB.ConnectionPromise:Then( function( ) 18 | return DB.TableExists('kinv_items') 19 | end ) 20 | :Then( function( shouldUpdate ) 21 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "don't need" ) 22 | if not shouldUpdate then 23 | return 24 | end 25 | 26 | return DB.DisableForeignKeyChecks( true ):Then( function() 27 | return performUpdate() 28 | end ) 29 | end ) 30 | :Then( function() 31 | return DB.DisableForeignKeyChecks( false ) 32 | end, function( errid, err ) 33 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 34 | return Promise.Reject( errid, err ) 35 | end ) 36 | 37 | -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.26.0.lua: -------------------------------------------------------------------------------- 1 | -- Fix for a concurrency bug 2 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 3 | 4 | return DB.ConnectionPromise:Then( function( ) 5 | return DB.TableExists('ps2_wallet') 6 | end ) 7 | :Then( function( shouldUpdate ) 8 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "don't need" ) 9 | if not shouldUpdate then 10 | return 11 | end 12 | 13 | return Promise.Resolve():Then(function() 14 | if DB.CONNECTED_TO_MYSQL then 15 | return DB.DoQuery("UPDATE ps2_wallet SET points = GREATEST(points, 0), premiumPoints = GREATEST(premiumPoints, 0)") 16 | else 17 | return DB.DoQuery("UPDATE ps2_wallet SET points = MAX(points, 0), premiumPoints = MAX(premiumPoints, 0)") 18 | end 19 | end):Then(function() 20 | -- Since SQLite is single threaded this bug only happens in mysql 21 | if DB.CONNECTED_TO_MYSQL then 22 | return DB.DoQuery([[ 23 | ALTER TABLE ps2_wallet MODIFY COLUMN points INT(11) UNSIGNED NOT NULL AFTER ownerId; 24 | ALTER TABLE ps2_wallet MODIFY COLUMN premiumPoints INT(11) UNSIGNED NOT NULL AFTER ownerId; 25 | ]]) 26 | end 27 | end) 28 | end ) 29 | :Fail( function( errid, err ) 30 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 31 | return Promise.Reject( errid, err ) 32 | end ) 33 | 34 | -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.3.0.lua: -------------------------------------------------------------------------------- 1 | local tables = { 2 | "ps2_trailpersistence", 3 | "ps2_settings", 4 | "ps2_wallet", 5 | "ps2_itempersistence", 6 | "ps2_categories", 7 | "ps2_outfits", 8 | "ps2_equipmentslot", 9 | "ps2_itemmapping", 10 | "ps2_weaponpersistence", 11 | "ps2_instatswitchweaponpersistence", 12 | "ps2_weaponpersistence", 13 | "ps2_playermodelpersistence", 14 | "ps2_OutfitHatPersistenceMapping", 15 | "ps2_HatPersistence", 16 | "ps2_servers", 17 | "inventories", 18 | "kinv_items", 19 | "libk_player" 20 | } 21 | 22 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 23 | return DB.ConnectionPromise 24 | :Then(function() 25 | if not DB.CONNECTED_TO_MYSQL then 26 | return 27 | end 28 | 29 | local promises = {} 30 | for k, v in pairs( tables ) do 31 | local promise = DB.TableExists( v ) 32 | :Then( function( exists ) 33 | if exists then 34 | KLogf(4, "Converted to InnoDB: %s", v) 35 | return DB.DoQuery("ALTER TABLE " .. v .. " ENGINE=InnoDB;") 36 | end 37 | end ) 38 | 39 | table.insert( promises, promise ) 40 | end 41 | 42 | return WhenAllFinished(promises) 43 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.6.0.lua: -------------------------------------------------------------------------------- 1 | /* 2 | This update script is ran when pointshop2 is updated from a version before the update system was in place. 3 | It is also run on a clean install so some checks are required. 4 | */ 5 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 6 | 7 | local function addYearField( ) 8 | return DB.FieldExistsInTable( "ps2_adventcalendaruses", "year" ) 9 | :Then( function( exists ) 10 | if not exists then 11 | return DB.DoQuery( "ALTER TABLE `ps2_adventcalendaruses` ADD `year` INT NULL" ) 12 | :Then(function() 13 | return DB.DoQuery( "UPDATE `ps2_adventcalendaruses` SET `year` = 2015 WHERE 1" ) 14 | end) 15 | :Then(function() 16 | return DB.DoQuery( 'UPDATE ps2_settings SET plugin="Daily Rewards / Advent Calendar" WHERE plugin="Advent Calendar"' ) 17 | end ) 18 | end 19 | end ) 20 | :Then( function( ) 21 | print( "\t Added column year to ps2_adventcalendaruses" ) 22 | end ) 23 | end 24 | 25 | return DB.ConnectionPromise 26 | :Then( function( ) 27 | return DB.TableExists('ps2_adventcalendaruses') 28 | end ) 29 | :Then( function( tableExists ) 30 | if tableExists then 31 | return DB.FieldExistsInTable( "ps2_adventcalendaruses", "year" ):Then(function (exists) 32 | return not exists 33 | end) 34 | end 35 | return false 36 | end ) 37 | :Then( function( shouldUpdate ) 38 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "not need" ) 39 | if shouldUpdate then 40 | return addYearField() 41 | end 42 | end ) 43 | :Then( function() end, function( errid, err ) 44 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 45 | return Promise.Reject( errid, err ) 46 | end ) -------------------------------------------------------------------------------- /lua/ps2/updatescripts/2.9.0.lua: -------------------------------------------------------------------------------- 1 | local DB = LibK.getDatabaseConnection( LibK.SQL, "Update" ) 2 | 3 | local function forceValidUuids() 4 | return DB.DoQuery('SELECT id FROM ps2_itempersistence WHERE uuid IS NULL') 5 | :Then(function(rows) 6 | if not rows then 7 | return 8 | end 9 | 10 | local query = "UPDATE ps2_itempersistence SET uuid = CASE id " 11 | local ids = LibK._.pluck(rows, 'id') 12 | local parts = {} 13 | for _, id in pairs( ids ) do 14 | table.insert( parts, Format( 'WHEN "%i" THEN "%s"', id, LibK.GetUUID() ) ) 15 | end 16 | query = query .. table.concat( parts, " " ) 17 | query = query .. ' ELSE uuid END WHERE id IN (' .. table.concat( ids, ', ' ) .. ')' 18 | return DB.DoQuery(query) 19 | end) 20 | end 21 | 22 | local function addUuidField( ) 23 | return DB.FieldExistsInTable( "ps2_itempersistence", "uuid" ) 24 | :Then( function( exists ) 25 | if not exists then 26 | return DB.DoQuery( "ALTER TABLE `ps2_itempersistence` ADD `uuid` VARCHAR(255) NOT NULL DEFAULT \"NOTSET\"" ) 27 | :Then(function() 28 | return DB.DoQuery( "SELECT id FROM `ps2_itempersistence`" ) 29 | end) 30 | :Then(function(rows) 31 | if not rows then 32 | return 33 | end 34 | 35 | local query = "UPDATE ps2_itempersistence SET uuid = CASE id " 36 | local ids = LibK._.pluck(rows, 'id') 37 | local parts = {} 38 | for _, id in pairs( ids ) do 39 | table.insert( parts, Format( 'WHEN "%i" THEN "%s"', id, LibK.GetUUID() ) ) 40 | end 41 | query = query .. table.concat( parts, " " ) 42 | query = query .. ' ELSE uuid END WHERE id IN (' .. table.concat( ids, ', ' ) .. ')' 43 | return DB.DoQuery(query) 44 | end) 45 | end 46 | end ) 47 | :Then( function( ) 48 | print( "\t Added column uuid to ps2_itempersistence" ) 49 | end ) 50 | end 51 | 52 | return DB.ConnectionPromise 53 | :Then( function( ) 54 | return DB.TableExists('ps2_itempersistence') 55 | end ) 56 | :Then( function( shouldUpdate ) 57 | KLogf( 2, "[INFO] We are on %s and %s to update", DB.CONNECTED_TO_MYSQL and "MySQL" or "SQLite", shouldUpdate and "need" or "not need" ) 58 | if shouldUpdate then 59 | return addUuidField() 60 | :Then(function() 61 | return forceValidUuids() 62 | end) 63 | end 64 | end ) 65 | :Then( function() end, function( errid, err ) 66 | KLogf( 2, "[ERROR] Error during update: %i, %s.", errid, err ) 67 | return Promise.Reject( errid, err ) 68 | end ) -------------------------------------------------------------------------------- /lua/ulx/modules/sh/sh_pointshop2.lua: -------------------------------------------------------------------------------- 1 | if SERVER then 2 | ULib.ucl.registerAccess("pointshop2 manageitems", ULib.ACCESS_SUPERADMIN, "Permission to modify item categories", "Pointshop 2" ) 3 | ULib.ucl.registerAccess("pointshop2 createitems", ULib.ACCESS_SUPERADMIN, "Permission to create new items", "Pointshop 2" ) 4 | ULib.ucl.registerAccess("pointshop2 manageusers", ULib.ACCESS_SUPERADMIN, "Permission to manage users(give points, items)", "Pointshop 2" ) 5 | ULib.ucl.registerAccess("pointshop2 managemodules", ULib.ACCESS_SUPERADMIN, "Permission to manage modules and use settings", "Pointshop 2" ) 6 | ULib.ucl.registerAccess("pointshop2 exportimport", ULib.ACCESS_SUPERADMIN, "Permission to export/import items", "Pointshop 2" ) 7 | ULib.ucl.registerAccess("pointshop2 manageservers", ULib.ACCESS_SUPERADMIN, "Permission to manage servers", "Pointshop 2" ) 8 | ULib.ucl.registerAccess("pointshop2 reset", ULib.ACCESS_SUPERADMIN, "Permission to reset the shop", "Pointshop 2" ) 9 | ULib.ucl.registerAccess("pointshop2 usepac", ULib.ACCESS_SUPERADMIN, "Permission to use the PAC editor", "Pointshop 2" ) 10 | end 11 | 12 | local function addPointsBySteamid( calling_ply, steamId, currencyType, amount ) 13 | Pointshop2Controller:getInstance( ):addPointsBySteamId( steamId, currencyType, amount ) 14 | :Fail( function( errid, err ) 15 | KLogf( 2, "[Pointshop 2] ERROR: Couldn't give %i %s to %s, %i - %s", amount, currencyType, steamId, errid, err ) 16 | end ) 17 | :Done( function( ) 18 | ulx.fancyLogAdmin( calling_ply, true, "#A gave #i #s to #s", amount, currencyType, steamId ) 19 | KLogf( 4, "[Pointshop 2] %s gave %i %s to %s", calling_ply:IsValid( ) and calling_ply:Nick( ) or "CONSOLE", amount, currencyType, steamId ) 20 | end ) 21 | end 22 | local giveItemCmd = ulx.command( "Pointshop 2", "ps2_addpoints", addPointsBySteamid, "!addpts" ) 23 | giveItemCmd:defaultAccess( ULib.ACCESS_SUPERADMIN ) 24 | giveItemCmd:addParam{ type=ULib.cmds.StringArg, hint = "Steam ID to give poins to" } 25 | giveItemCmd:addParam{ type=ULib.cmds.StringArg, hint="Currency Type", completes = {"points", "premiumPoints" }, error="invalid currency \"%s\" specified", ULib.cmds.restrictToCompletes } 26 | giveItemCmd:addParam{ type=ULib.cmds.NumArg, min=1, default=1, hint="Amount" } 27 | giveItemCmd:help( "Give Pointshop 2 points to a player by SteamID" ) -------------------------------------------------------------------------------- /lua/ulx/modules/sh_ulx_inventory.lua: -------------------------------------------------------------------------------- 1 | local function giveItem( calling_ply, target_ply, itemName, amount ) 2 | KInventory.Inventory.findByOwnerId( target_ply.kPlayerId ) 3 | :Then( function( inv ) 4 | if not inv then 5 | ULib.tsayError( calling_ply, target_ply:Nick( ) .. " does not have a valid inventory!" ) 6 | return 7 | end 8 | 9 | local itemClass = KInventory.Items[itemName] 10 | if not itemClass then 11 | ULib.tsayError( calling_ply, "Item " .. item .. " does not exist!" ) 12 | return 13 | end 14 | 15 | --Chain, TODO: Look for a better way to do this, add something to model for multiple inserts 16 | --Make sure to check weight and stuff beforehand 17 | local itemsGiven = 0 18 | local item = itemClass:new( ) 19 | local promise = inv:addItem( item ):Then( function( ) itemsGiven = itemsGiven + 1 end ) 20 | for i =2, amount do 21 | local item = itemClass:new( ) 22 | promise = promise:Then( function( ) 23 | inv:addItem( item ) 24 | end ) 25 | :Then( function( ) 26 | itemsGiven = itemsGiven + 1 27 | end ) 28 | end 29 | 30 | promise:Then( function( ) 31 | local str = "#A gave #T #i #s" 32 | ulx.fancyLogAdmin( calling_ply, str, target_ply, amount, itemName ) 33 | end, 34 | function( errid, err ) 35 | if errid > 0 then 36 | ULib.tsayError( calling_ply, "There was an error giving the items: " .. err ..", " .. itemsGiven .. " items were given to the player" ) 37 | else 38 | ULib.tsayError( calling_ply, "There was an internal giving the items: " .. errid ) 39 | error( "Error giving items (ulx command): " .. errid .. ", " .. err ) 40 | end 41 | end ) 42 | end ) 43 | end 44 | local giveItemCmd = ulx.command( "Inventory", "inv giveitem", giveItem, "!give" ) 45 | giveItemCmd:defaultAccess( ULib.ACCESS_ADMIN ) 46 | giveItemCmd:addParam{ type=ULib.cmds.PlayerArg } 47 | giveItemCmd:addParam{ type=ULib.cmds.StringArg, hint="Item" } 48 | giveItemCmd:addParam{ type=ULib.cmds.NumArg, min=1, default=1, hint="Amount", ULib.cmds.optional } 49 | giveItemCmd:help( "Give an item to a player" ) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pointshop2", 3 | "version": "2.26.0", 4 | "main": "index.js", 5 | "repository": "git@github.com:Kamshak/Pointshop2.git", 6 | "author": "Valentin Funk ", 7 | "license": "ISC", 8 | "devDependencies": { 9 | "dotenv": "^4.0.0", 10 | "last-release-git": "^0.0.2", 11 | "scriptfodder-publish": "^1.7.2", 12 | "semantic-release": "^6.3.2", 13 | "semantic-release-noop": "^1.1.0", 14 | "semantic-sf-release": "2.2.2", 15 | "shx": "^0.2.2" 16 | }, 17 | "release": { 18 | "getLastRelease": "last-release-git", 19 | "verifyConditions": "semantic-release-noop" 20 | }, 21 | "scripts": { 22 | "build": "node build.js", 23 | "upload": "scriptfodder-publish --version-from-package --relative-to=dist", 24 | "sf-release": "semantic-sf-release pre && semantic-sf-release genlog && npm run build && npm run upload && semantic-sf-release post", 25 | "local-pkg": "npm run build && scriptfodder-publish --version-from-package --relative-to=dist --zip-only && shx rm -rf dist", 26 | "local-release": "semantic-sf-release pre --debug=false && semantic-sf-release genlog --debug=false && npm run build && npm run upload && semantic-sf-release post --debug=false", 27 | "upload:staging": "shipit staging" 28 | }, 29 | "publishConfig": { 30 | "access": "restricted" 31 | }, 32 | "dependencies": { 33 | "glob": "^7.1.1", 34 | "last-release-git": "^0.0.2", 35 | "request-promise": "^4.2.0" 36 | }, 37 | "generateNotes": { 38 | "footerPartial": "changelog_footer_template.hbs" 39 | } 40 | } -------------------------------------------------------------------------------- /wercker.yml: -------------------------------------------------------------------------------- 1 | box: node:7 2 | build: 3 | steps: 4 | - npm-install 5 | deploy: 6 | steps: 7 | - npm-install 8 | - script: 9 | name: update version 10 | code: | 11 | npm run sf-release 12 | after-steps: 13 | - slack-notifier: 14 | url: $SLACK_URL 15 | channel: general 16 | username: DeployBot 17 | branch: master 18 | --------------------------------------------------------------------------------