[Request] VGUI: An Inventory Tutorial

Grab your favourite IDE and tinker with the innards of game engines

[Request] VGUI: An Inventory Tutorial

Postby staberas on Thu Jul 30, 2009 11:44 am

Original Post
**Self explanatory title, i would be greatful if someone could create a tutorial on how to create a simple basic inventory step by step.**

THIS TUTORIAL IS NOT FINISHED YET
i still need help to create at least a pseudo-inventory source code. What i wrote only is how to create a vgui panel.

Tutorial WIP
For this tutorial you need to have basic programming knowledge and Visual C++ 2008 Express Edition or better installed.

After you have created your Source SDK, source code.You open Game_Episodic-2008, after the conversion is done, in the solution explorer you open the Source Files folder in the client episodic project.Create a folder(filter) named MyPanel.Create inside the folder a header file named IMyPanel.h with the following code
Code: Select all
// IMyPanel.h
class IMyPanel
{
public:
   virtual void      Create( vgui::VPANEL parent ) = 0;
   virtual void      Destroy( void ) = 0;
};

extern IMyPanel* mypanel;

After this create in the same folder a C++ File (.cpp) named MyPanel.cpp with the following code

Code: Select all
//The following include files are necessary to allow your MyPanel.cpp to compile.
#include "cbase.h"
#include "IMyPanel.h"
using namespace vgui;
#include <vgui/IVGui.h>
#include <vgui_controls/Frame.h>
#include "iconvar.h"
#include "ienginevgui.h"

//CMyPanel class: Tutorial example class
class CMyPanel : public vgui::Frame
{
   DECLARE_CLASS_SIMPLE(CMyPanel, vgui::Frame);
   //CMyPanel : This Class / vgui::Frame : BaseClass

   CMyPanel(vgui::VPANEL parent);    // Constructor
   ~CMyPanel(){};            // Destructor
   //stb new input
   virtual void OnTick();
    virtual void OnCommand(const char *command);
   //stb new input end

private:
   //Other used VGUI control Elements:

};
// Constuctor: Initializes the Panel
CMyPanel::CMyPanel(vgui::VPANEL parent)
: BaseClass(NULL, "MyPanel")
{
   SetParent( parent );
   
   SetKeyBoardInputEnabled( true );
   SetMouseInputEnabled( true );
   
   SetProportional( true );
   SetTitleBarVisible( true );
   SetMinimizeButtonVisible( false );
   SetMaximizeButtonVisible( false );
   SetCloseButtonVisible( false );
   SetSizeable( false );
   SetMoveable( true );
   SetVisible( true );


   SetScheme(vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "SourceScheme"));

   LoadControlSettings("resource/UI/MyPanel.res");

   vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
   
   DevMsg("MyPanel has been constructed\n");
}
//Class: CMyPanelInterface Class. Used for construction.
class CMyPanelInterface : public IMyPanel
{
private:
   CMyPanel *MyPanel;
public:
   CMyPanelInterface()
   {
      MyPanel = NULL;
   }
   void Create(vgui::VPANEL parent)
   {
      MyPanel = new CMyPanel(parent);
   }
   void Destroy()
   {
      if (MyPanel)
      {
         MyPanel->SetParent( (vgui::Panel *)NULL);
         delete MyPanel;
      }
   }
};
static CMyPanelInterface g_MyPanel;
IMyPanel* mypanel = (IMyPanel*)&g_MyPanel;


ConVar cl_showmypanel("cl_showmypanel", "0", FCVAR_CLIENTDLL, "Sets the state of myPanel <state>");


CON_COMMAND(ToggleMyPanel, "Toggles myPanel on or off")
{
   cl_showmypanel.SetValue(!cl_showmypanel.GetBool());

};

void CMyPanel::OnTick()
{
   BaseClass::OnTick();
   SetVisible(cl_showmypanel.GetBool()); //CL_SHOWMYPANEL / 1 BY DEFAULT
}

//from here you add the inventory code

}



Next, replace the following vgui_int.cpp with this code

Code: Select all
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "vgui_int.h"
#include "ienginevgui.h"
#include "itextmessage.h"
#include "vguicenterprint.h"
#include "iloadingdisc.h"
#include "ifpspanel.h"
#include "imessagechars.h"
#include "inetgraphpanel.h"
#include "idebugoverlaypanel.h"
#include <vgui/isurface.h>
#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include "tier0/vprof.h"
#include "iclientmode.h"
#include <vgui_controls/Panel.h>
#include <KeyValues.h>
#include "FileSystem.h"
#include "matsys_controls/matsyscontrols.h"
//Tony; so we can load localization at initialize
#include <vgui/ILocalize.h>
#include <tier3/tier3.h>
//your new panel
#include "IMyPanel.h"


using namespace vgui;

void MP3Player_Create( vgui::VPANEL parent );
void MP3Player_Destroy();

#include <vgui/IInputInternal.h>
vgui::IInputInternal *g_InputInternal = NULL;

#include <vgui_controls/Controls.h>

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

void GetVGUICursorPos( int& x, int& y )
{
   vgui::input()->GetCursorPos(x, y);
}

void SetVGUICursorPos( int x, int y )
{
   if ( !g_bTextMode )
   {
      vgui::input()->SetCursorPos(x, y);
   }
}

class CHudTextureHandleProperty : public vgui::IPanelAnimationPropertyConverter
{
public:
   virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
   {
      void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
      CHudTextureHandle *pHandle = ( CHudTextureHandle * )data;

      // lookup texture name for id
      if ( pHandle->Get() )
      {
         kv->SetString( entry->name(), pHandle->Get()->szShortName );
      }
      else
      {
         kv->SetString( entry->name(), "" );
      }
   }
   
   virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
   {
      void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
      
      CHudTextureHandle *pHandle = ( CHudTextureHandle * )data;

      const char *texturename = kv->GetString( entry->name() );
      if ( texturename && texturename[ 0 ] )
      {
         CHudTexture *currentTexture = gHUD.GetIcon( texturename );
         pHandle->Set( currentTexture );
      }
      else
      {
         pHandle->Set( NULL );
      }
   }

   virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
   {
      void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );

      CHudTextureHandle *pHandle = ( CHudTextureHandle * )data;

      const char *texturename = entry->defaultvalue();
      if ( texturename && texturename[ 0 ] )
      {
         CHudTexture *currentTexture = gHUD.GetIcon( texturename );
         pHandle->Set( currentTexture );
      }
      else
      {
         pHandle->Set( NULL );
      }
   }
};

static CHudTextureHandleProperty textureHandleConverter;

static void VGui_OneTimeInit()
{
   static bool initialized = false;
   if ( initialized )
      return;
   initialized = true;

   vgui::Panel::AddPropertyConverter( "CHudTextureHandle", &textureHandleConverter );

}

bool VGui_Startup( CreateInterfaceFn appSystemFactory )
{
   if ( !vgui::VGui_InitInterfacesList( "CLIENT", &appSystemFactory, 1 ) )
      return false;

   if ( !vgui::VGui_InitMatSysInterfacesList( "CLIENT", &appSystemFactory, 1 ) )
      return false;

   g_InputInternal = (IInputInternal *)appSystemFactory( VGUI_INPUTINTERNAL_INTERFACE_VERSION,  NULL );
   if ( !g_InputInternal )
   {
      return false; // c_vguiscreen.cpp needs this!
   }

   VGui_OneTimeInit();

   // Create any root panels for .dll
   VGUI_CreateClientDLLRootPanel();

   // Make sure we have a panel
   VPANEL root = VGui_GetClientDLLRootPanel();
   if ( !root )
   {
      return false;
   }

      //Tony; add localization for the specific SDK.
#if defined( SP_SDK )
   g_pVGuiLocalize->AddFile( "resource/ep2_%language%.txt", "GAME" );
#elif defined( MP_SDK )
   g_pVGuiLocalize->AddFile( "resource/hl2mp_%language%.txt", "GAME" );
#elif defined ( SDK_DLL )
   //Tony; for the sdk template, just check for SDK_DLL
   g_pVGuiLocalize->AddFile( "resource/sdktemplate_%language%.txt", "MOD" );
#endif
   return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void VGui_CreateGlobalPanels( void )
{
   VPANEL gameToolParent = enginevgui->GetPanel( PANEL_CLIENTDLL_TOOLS );
   VPANEL toolParent = enginevgui->GetPanel( PANEL_TOOLS );
   VPANEL gameParent = enginevgui->GetPanel( PANEL_INGAMESCREENS );
#if defined( TRACK_BLOCKING_IO )
   VPANEL gameDLLPanel = enginevgui->GetPanel( PANEL_GAMEDLL );
#endif
   // Part of game
   internalCenterPrint->Create( gameToolParent );
   loadingdisc->Create( gameToolParent );
   messagechars->Create( gameToolParent );
    mypanel->Create( gameParent );

   // Debugging or related tool
   fps->Create( toolParent );
#if defined( TRACK_BLOCKING_IO )
   iopanel->Create( gameDLLPanel );
#endif
   netgraphpanel->Create( toolParent );
   debugoverlaypanel->Create( gameToolParent );

#ifndef _X360
   // Create mp3 player off of tool parent panel
   MP3Player_Create( toolParent );
#endif
}

void VGui_Shutdown()
{
   VGUI_DestroyClientDLLRootPanel();

#ifndef _X360
   MP3Player_Destroy();
#endif

   netgraphpanel->Destroy();
   debugoverlaypanel->Destroy();
#if defined( TRACK_BLOCKING_IO )
   iopanel->Destroy();
#endif
   fps->Destroy();

   messagechars->Destroy();
   loadingdisc->Destroy();
   internalCenterPrint->Destroy();
   mypanel->Destroy();

   if ( g_pClientMode )
   {
      g_pClientMode->VGui_Shutdown();
   }

   // Make sure anything "marked for deletion"
   //  actually gets deleted before this dll goes away
   vgui::ivgui()->RunFrame();
}

static ConVar cl_showpausedimage( "cl_showpausedimage", "1", 0, "Show the 'Paused' image when game is paused." );

//-----------------------------------------------------------------------------
// Things to do before rendering vgui stuff...
//-----------------------------------------------------------------------------
void VGui_PreRender()
{
   VPROF( "VGui_PreRender" );

   // 360 does not use these plaques
   if ( IsPC() )
   {
      loadingdisc->SetLoadingVisible( engine->IsDrawingLoadingImage() && !engine->IsPlayingDemo() );
      loadingdisc->SetPausedVisible( !enginevgui->IsGameUIVisible() && cl_showpausedimage.GetBool() && engine->IsPaused() && !engine->IsTakingScreenshot() && !engine->IsPlayingDemo() );
   }
}

void VGui_PostRender()
{
}

//-----------------------------------------------------------------------------
// Purpose:
// Input  : cl_panelanimation -
//-----------------------------------------------------------------------------
CON_COMMAND( cl_panelanimation, "Shows panel animation variables: <panelname | blank for all panels>." )
{
   if ( args.ArgC() == 2 )
   {
      PanelAnimationDumpVars( args[1] );
   }
   else
   {
      PanelAnimationDumpVars( NULL );
   }
}

void GetHudSize( int& w, int &h )
{
   vgui::surface()->GetScreenSize( w, h );

   VPANEL hudParent = enginevgui->GetPanel( PANEL_CLIENTDLL );
   if ( hudParent )
   {
      vgui::ipanel()->GetSize( hudParent, w, h );
   }
}



What i have just created now is just a Vgui Panel that will serve as a window where buttons and items will be displayed. The panel will be displayed with this command on the console " cl_showmypanel 1 " without the " .

Press Ctrl+F7 to compile , it will create a dll in the your-mod-source-code\game\client\bin file & your-mod-source-code\game\server\bin file, copy/paste both of those dll's to your \Steam\SteamApps\SourceMods\your-mod\bin

This tutorial hasn't been finished yet
coming up the inventory coding , and UI inventory manipulation

UI Manipulation.

In the Previous topic we created a blank panel . To interact with it and that panel with the game we will need to create a basic User Interface.Return to the MyPanel.cpp on the visual C++ and read the following code ,

Code: Select all
CMyPanel::CMyPanel(vgui::VPANEL parent)
: BaseClass(NULL, "MyPanel")
{
   SetParent( parent );
   
   SetKeyBoardInputEnabled( true );
   SetMouseInputEnabled( true );
   
   SetProportional( true );
   SetTitleBarVisible( true );
   SetMinimizeButtonVisible( false );
   SetMaximizeButtonVisible( false );
   SetCloseButtonVisible( false );
   SetSizeable( false );
   SetMoveable( true );
   SetVisible( true );


   SetScheme(vgui::scheme()->LoadSchemeFromFile("resource/SourceScheme.res", "SourceScheme"));

   LoadControlSettings("resource/UI/MyPanel.res");

   vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
   
   DevMsg("MyPanel has been constructed\n");


As you can understand here you can choose if the panel will be visible , movable will accept inputs from keyboards or mouse and what schemes will load from file. Scheme are the look & feel of your panel by specifying colors, fonts & icons of control elements. Schemes are defined in resource files , for example hl2\resource\clientscheme.res .A new panel inherits by default the scheme settings used by its parent.

The most common way to define the layout of your panel elements is to describe all elements in an external resource file ie hl2\resource\UI\classmenu.res (a KeyValues text file). When the parent panel is created, this file is loaded and executed with LoadControlSettings(char* dialogResourceName). Do note, however, that this function is only defined for EditablePanel (or an EditablePanel derivative such as Frame). In this resource file each control element is defined in a separate section. A typical control definition looks like this:

MyControlName
{
ControlName Label // control class
fieldName MyControlName // name of the control element
xpos 8 // x position
ypos 72 // y position
wide 160 // width in pixels
tall 24 // height in pixels
visible 1 // it's visible...
enabled 1 // ...and enabled
labelText "Hello world" // display this unlocalized text
textAlignment west // left text alignment
}


Build mode

An even simpler way to edit panel and control layouts is the VGUI Build Mode. This allows you to modify and save the layout of a panel resource file while the application is running. To edit a panel, just start the game and open this panel, so it gets the input focus. Then press SHIFT+CTRL+ALT+B to open the VGUI Build Mode editor. In Build Mode you can easily rearrange existing elements and change their control properties (press 'Apply' to update changes). To add a new control element, just choose the desired class from the combo-box on the lower right side and an empty control object of that class will be place in your panel for further editing. To save the current layout in the associated resource file press the 'Save' button (make sure the resource file is not write-protected).

For more info about vgui read here

Now we will add & create 3 buttons on our panel. 1 close button , 1 start new map button and 1 button that triggers an entity/button in-game.

Return to the MyPanel.cpp on the visual C++ and add the following code under this
//from here you add the inventory code


Code: Select all
void CMyPanel::OnCommand(const char *command)
{
    if (!stricmp(command, "ToggleNewGame"))
   {
        cl_showmypanel.SetValue(0);
    }
    // User wants to start a new game, loading intro map
    if (!stricmp(command, "StartNewGame"))
    {
        // Set up loading bar, disable panel, and load the map
       engine->ClientCmd("progress_enable");
        cl_showmypanel.SetValue(0);
        engine->ClientCmd("map prototype");
   }
    if (!stricmp(command, "entfire"))
    {
        // commands to turn on a light or button
        cl_showmypanel.SetValue(0);
        engine->ClientCmd("ent_fire light1 turnon");
   if (!stricmp(command, "entfire2"))
    {
        // more commands
        cl_showmypanel.SetValue(0);
        engine->ClientCmd("ent_fire light1 trigger");
   }


Press Ctrl+F7 to compile , copy/paste the dll's .

There are 2 ways to create the buttons the easy one in-game & the hardcore one through the resource files.
We will take the easy road, Run your mod and open a map. Press SHIFT+CTRL+ALT+B .Open the console
type cl_showmypanel 1 .

Image

Image
Add the buttons, move them & named them

Image

Image

Image

To be continued...
This tutorial hasn't been finished yet
Last edited by staberas on Sun Sep 27, 2009 4:44 pm, edited 3 times in total.
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby ghost12332 on Thu Jul 30, 2009 1:20 pm

I don't think anyone will do this, simply because I don't think you realize how hard this is to do. Just setting up a simple VGUI panel is a hassle :/
Ryder: i see ghost as a evil scientest who wants to kill everyone for the good of humanity
User avatar
ghost12332
Senior Member
Senior Member
 
Joined: Sun Jul 15, 2007 11:25 pm
Location: Guitar Center

Re: [Request] VGUI: An Inventory Tutorial

Postby staberas on Thu Jul 30, 2009 2:25 pm

Yes, its a pain n the butt to write it but its very usefull for an inexperient modder.
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby Surfa on Thu Jul 30, 2009 2:26 pm

So nobody will do it. Maybe if you were three years earlier when all the coders were still around.
Surfa
May Contain Skills
May Contain Skills
 
Joined: Sun Dec 30, 2007 3:04 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby staberas on Thu Aug 06, 2009 10:25 am

I manage yesterday to setup an vgui panel, i would like to know how i can make a button to trigger an entity/command in-game (do i need a new C++ or header file? ).After that i will post a full tutorial.

EDIT: nevermind found it
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby staberas on Sat Sep 26, 2009 12:39 pm

small update i still need help to complete it.any help is welcome
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby dark_veil on Sat Sep 26, 2009 1:43 pm

to be honest i like the idea, might be useful for my mod. but might be a pain in the arse lol
User avatar
dark_veil
Pheropod
Pheropod
 
Joined: Mon Nov 19, 2007 6:10 pm
Location: England

Re: [Request] VGUI: An Inventory Tutorial

Postby Jordash on Tue Oct 06, 2009 2:35 pm

If you finish this tutorial it will be awesome

Keep up the good work
User avatar
Jordash
Been Here A While
Been Here A While
 
Joined: Mon Sep 21, 2009 10:36 am
Location: Perth, Australia

Re: [Request] VGUI: An Inventory Tutorial

Postby The Doctor on Tue Oct 06, 2009 4:09 pm

I'd like to give this a try if/when it's finished.
"We're the Moe Syzlak experience featuring Homer."
User avatar
The Doctor
Pheropod
Pheropod
 
Joined: Mon Jul 02, 2007 3:40 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby staberas on Sat Oct 10, 2009 3:56 pm

It will take a while to update since i'm trying to incorporate it in my mod, test it and then clean up the code.
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby staberas on Fri Oct 23, 2009 1:31 pm

Good news, everyone!

I made a prototype!

i have modified this tutorial map so that when you pick up the key, it will be added in your inventory.(Press mouse 2 to open it)

http://rapidshare.com/files/296838905/I ... ototype.7z
vmf , dll's , bsp are added . btw need testers

Video for anyone bored to download it
User avatar
staberas
Been Here A While
Been Here A While
 
Joined: Sat Apr 18, 2009 5:30 pm

Re: [Request] VGUI: An Inventory Tutorial

Postby JLea on Sat Oct 24, 2009 2:53 pm

This is an excellent idea, I know many mods who could certainly use this.
User avatar
JLea
May Contain Skills
May Contain Skills
 
Joined: Mon Jan 02, 2006 1:19 pm
Location: Melbourne, Australia

Re: [Request] VGUI: An Inventory Tutorial

Postby thefoofighter on Tue Nov 10, 2009 10:15 am

This is a very nice tutorial dude, its nice to see someone trying to work on the UI, well done and keep it up dude
:)
User avatar
thefoofighter
Member
Member
 
Joined: Thu Jul 16, 2009 12:27 pm
Location: Ireland

Re: [Request] VGUI: An Inventory Tutorial

Postby Meathead on Fri Nov 13, 2009 2:04 am

Could you add a VGUI of were the item is on the map? as in like they did on the car in ep2?
Meathead
Regular
Regular
 
Joined: Tue Oct 20, 2009 9:20 pm
Location: Australia

Re: [Request] VGUI: An Inventory Tutorial

Postby DJMidKnight on Fri Nov 13, 2009 3:02 am

Nice tutorial well check into it once I get the rest of my code figured out
nothing like code that compiles without errors and still doesnt work lol
DJMidKnight
Dumpling
Dumpling
 
Joined: Thu Nov 12, 2009 5:57 am
Next

Return to Programming

Who is online

Users browsing this forum: No registered users

cron