You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
11 KiB
380 lines
11 KiB
1 year ago
|
#include <vgui/IVGui.h>
|
||
|
#include <vgui/IInput.h>
|
||
|
#include "vgui_controls/Controls.h"
|
||
|
#include <vgui/IScheme.h>
|
||
|
#include <vgui_controls/Label.h>
|
||
|
#include <vgui_controls/Menu.h>
|
||
|
#include <vgui_controls/MessageBox.h>
|
||
|
#include <KeyValues.h>
|
||
|
#include <vgui_controls/Tooltip.h>
|
||
|
#include "vgui/missionchooser_tgaimagepanel.h"
|
||
|
|
||
|
#include "TileGenDialog.h"
|
||
|
#include "RoomTemplatePanel.h"
|
||
|
#include "RoomTemplateEditDialog.h"
|
||
|
#include "TileSource/RoomTemplate.h"
|
||
|
#include "TileSource/LevelTheme.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include <tier0/memdbgon.h>
|
||
|
|
||
|
using namespace vgui;
|
||
|
|
||
|
CUtlVector<CRoomTemplatePanel*> g_pRoomTemplatePanels;
|
||
|
|
||
|
CRoomTemplatePanel::CRoomTemplatePanel( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||
|
{
|
||
|
m_pRoomTemplate = NULL;
|
||
|
m_hMenu = NULL;
|
||
|
|
||
|
m_pRoomTGAPanel = new CMissionChooserTGAImagePanel(this, "RoomTGAPanel" );
|
||
|
m_pRoomTGAPanel->SetMouseInputEnabled(false);
|
||
|
|
||
|
m_pSelectedOutline = new vgui::Panel(this, "SelectedBorder");
|
||
|
m_pSelectedOutline->SetVisible(false);
|
||
|
m_pSelectedOutline->SetMouseInputEnabled(false);
|
||
|
m_pSelectedOutline->SetZPos(10); // make sure the border stays above exits/tile squares
|
||
|
|
||
|
m_iLastTilesX = -1;
|
||
|
m_iLastTilesY = -1;
|
||
|
|
||
|
m_bRoomTemplateEditMode = false;
|
||
|
m_bRoomTemplateBrowserMode = false;
|
||
|
|
||
|
m_bForceShowExits = false;
|
||
|
m_bForceShowTileSquares = false;
|
||
|
|
||
|
m_pTagsLabel = new vgui::Label( this, "TagsLabel", "" );
|
||
|
m_pTagsLabel->SetMouseInputEnabled( false );
|
||
|
m_pTagsLabel->SetContentAlignment( vgui::Label::a_northwest );
|
||
|
m_pTagsLabel->SetZPos( 2 );
|
||
|
|
||
|
SetMouseInputEnabled(true);
|
||
|
|
||
|
g_pRoomTemplatePanels.AddToTail(this);
|
||
|
}
|
||
|
|
||
|
CRoomTemplatePanel::~CRoomTemplatePanel( void )
|
||
|
{
|
||
|
g_pRoomTemplatePanels.FindAndRemove(this);
|
||
|
}
|
||
|
|
||
|
void CRoomTemplatePanel::SetRoomTemplate( const CRoomTemplate* pTemplate )
|
||
|
{
|
||
|
m_pRoomTemplate = pTemplate;
|
||
|
UpdateImages();
|
||
|
|
||
|
if (pTemplate)
|
||
|
{
|
||
|
GetTooltip()->SetText( pTemplate->GetFullName() );
|
||
|
GetTooltip()->SetTooltipFormatToSingleLine();
|
||
|
|
||
|
char buffer[2048];
|
||
|
buffer[0] = 0;
|
||
|
for ( int i = 0; i < pTemplate->GetNumTags(); i++ )
|
||
|
{
|
||
|
Q_snprintf( buffer, sizeof( buffer ), "%s\n%s", buffer, pTemplate->GetTag( i ) );
|
||
|
}
|
||
|
m_pTagsLabel->SetText( buffer );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pTagsLabel->SetText( "" );
|
||
|
}
|
||
|
//else
|
||
|
//pLabel->GetTooltip()->SetText( m_pShader->GetParamHelp( i ) );
|
||
|
}
|
||
|
|
||
|
void CRoomTemplatePanel::UpdateImages()
|
||
|
{
|
||
|
for (int i=0;i<m_pExitImagePanels.Count();i++)
|
||
|
{
|
||
|
m_pExitImagePanels[i]->MarkForDeletion();
|
||
|
}
|
||
|
m_pExitImagePanels.RemoveAll();
|
||
|
|
||
|
char buffer[MAX_PATH];
|
||
|
buffer[0] = 0;
|
||
|
if ( m_pRoomTemplate && m_pRoomTemplate->m_pLevelTheme )
|
||
|
{
|
||
|
Q_snprintf( buffer, sizeof(buffer), "tilegen/roomtemplates/%s/%s.tga", m_pRoomTemplate->m_pLevelTheme->m_szName, m_pRoomTemplate->GetFullName() );
|
||
|
}
|
||
|
m_pRoomTGAPanel->SetTGA( buffer );
|
||
|
|
||
|
if ( !m_pRoomTemplate || !m_pRoomTemplate->m_pLevelTheme )
|
||
|
return;
|
||
|
|
||
|
// check for updating our grid images
|
||
|
//if (m_pRoomTemplate->GetTilesX() != m_iLastTilesX || m_pRoomTemplate->GetTilesY() != m_iLastTilesY)
|
||
|
{
|
||
|
m_iLastTilesX = m_pRoomTemplate->GetTilesX();
|
||
|
m_iLastTilesY = m_pRoomTemplate->GetTilesY();
|
||
|
|
||
|
// clear our grid images
|
||
|
for (int i=0;i<m_pGridImagePanels.Count();i++)
|
||
|
{
|
||
|
m_pGridImagePanels[i]->SetVisible(false);
|
||
|
m_pGridImagePanels[i]->MarkForDeletion();
|
||
|
}
|
||
|
m_pGridImagePanels.RemoveAll();
|
||
|
|
||
|
// create enough grid image panels for each square
|
||
|
if (g_pTileGenDialog->m_bShowTileSquares || m_bForceShowTileSquares)
|
||
|
{
|
||
|
int iGrids = m_pRoomTemplate->GetArea();
|
||
|
for (int i=0;i<iGrids;i++)
|
||
|
{
|
||
|
CMissionChooserTGAImagePanel *pGridImagePanel = new CMissionChooserTGAImagePanel(this, "GridImagePanel");
|
||
|
pGridImagePanel->SetMouseInputEnabled(false);
|
||
|
pGridImagePanel->SetTGA("tilegen/roomtemplates/gridsquare.tga");
|
||
|
m_pGridImagePanels.AddToTail(pGridImagePanel);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (g_pTileGenDialog->m_bShowExits || m_bForceShowExits)
|
||
|
{
|
||
|
// create enough exit image panels for each exit in the room
|
||
|
int iExits = m_pRoomTemplate->m_Exits.Count();
|
||
|
for (int i=0;i<iExits;i++)
|
||
|
{
|
||
|
CRoomTemplateExit *pExit = m_pRoomTemplate->m_Exits[i];
|
||
|
CMissionChooserTGAImagePanel *pExitImagePanel = new CMissionChooserTGAImagePanel(this, "ExitImagePanel");
|
||
|
pExitImagePanel->SetMouseInputEnabled(false);
|
||
|
switch (pExit->m_ExitDirection)
|
||
|
{
|
||
|
case EXITDIR_NORTH:
|
||
|
pExitImagePanel->SetTGA("tilegen/roomtemplates/exitnorth.tga");
|
||
|
break;
|
||
|
case EXITDIR_EAST:
|
||
|
pExitImagePanel->SetTGA("tilegen/roomtemplates/exiteast.tga");
|
||
|
break;
|
||
|
case EXITDIR_SOUTH:
|
||
|
pExitImagePanel->SetTGA("tilegen/roomtemplates/exitsouth.tga");
|
||
|
break;
|
||
|
case EXITDIR_WEST:
|
||
|
default:
|
||
|
pExitImagePanel->SetTGA("tilegen/roomtemplates/exitwest.tga");
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
m_pExitImagePanels.AddToTail(pExitImagePanel);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InvalidateLayout(true, true);
|
||
|
Repaint();
|
||
|
}
|
||
|
|
||
|
void CRoomTemplatePanel::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings(pScheme);
|
||
|
|
||
|
m_pSelectedOutline->SetBorder(pScheme->GetBorder("SelectedRoomBorder"));
|
||
|
m_pSelectedOutline->SetPaintBackgroundEnabled(false);
|
||
|
|
||
|
m_pTagsLabel->SetPaintBackgroundEnabled(false);
|
||
|
m_pTagsLabel->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
|
||
|
|
||
|
if (m_bRoomTemplateBrowserMode)
|
||
|
{
|
||
|
if (g_pTileGenDialog && g_pTileGenDialog->m_pCursorTemplate == m_pRoomTemplate)
|
||
|
{
|
||
|
//SetPaintBackgroundEnabled(true);
|
||
|
//SetPaintBackgroundType(0);
|
||
|
//SetBgColor(Color(255,255,255,255));
|
||
|
//InvalidateLayout(true);
|
||
|
m_pSelectedOutline->SetVisible(true);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//SetPaintBackgroundEnabled(false);
|
||
|
m_pSelectedOutline->SetVisible(false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CRoomTemplatePanel::PerformLayout()
|
||
|
{
|
||
|
BaseClass::PerformLayout();
|
||
|
|
||
|
if (!m_pRoomTemplate || !g_pTileGenDialog)
|
||
|
return;
|
||
|
|
||
|
int tile_size = g_pTileGenDialog->RoomTemplatePanelTileSize();
|
||
|
|
||
|
SetSize(m_pRoomTemplate->GetTilesX() * tile_size , m_pRoomTemplate->GetTilesY() * tile_size);
|
||
|
|
||
|
m_pRoomTGAPanel->SetBounds(0, 0, GetWide(), GetTall());
|
||
|
m_pSelectedOutline->SetBounds(0, 0, GetWide(), GetTall());
|
||
|
|
||
|
// arrange the grid squares across our size
|
||
|
for (int y=0; y<m_pRoomTemplate->GetTilesY(); y++)
|
||
|
{
|
||
|
for (int x=0; x<m_pRoomTemplate->GetTilesX(); x++)
|
||
|
{
|
||
|
int iGridImage = x + m_pRoomTemplate->GetTilesX() * y;
|
||
|
if (m_pGridImagePanels.Count() > iGridImage)
|
||
|
{
|
||
|
m_pGridImagePanels[iGridImage]->SetBounds(x * tile_size, y * tile_size, tile_size, tile_size);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// arrange exits
|
||
|
for (int i=0;i<m_pRoomTemplate->m_Exits.Count();i++)
|
||
|
{
|
||
|
CRoomTemplateExit *pExit = m_pRoomTemplate->m_Exits[i];
|
||
|
if (!pExit || m_pExitImagePanels.Count() <= i)
|
||
|
continue;
|
||
|
|
||
|
int x = pExit->m_iXPos;
|
||
|
//int y = (m_pRoomTemplate->GetTilesY()-1) - pExit->m_iYPos; // reverse the y-axis to match hammer's coord style
|
||
|
int y = pExit->m_iYPos;
|
||
|
m_pExitImagePanels[i]->SetBounds(x * tile_size, y * tile_size, tile_size, tile_size);
|
||
|
}
|
||
|
|
||
|
m_pTagsLabel->SizeToContents();
|
||
|
m_pTagsLabel->SetPos( 4, 0 );
|
||
|
m_pTagsLabel->InvalidateLayout( true );
|
||
|
}
|
||
|
|
||
|
void CRoomTemplatePanel::OnMouseReleased(vgui::MouseCode code)
|
||
|
{
|
||
|
if (m_bRoomTemplateEditMode && code == MOUSE_RIGHT)
|
||
|
{
|
||
|
// find which tile we clicked in
|
||
|
int rx, ry;
|
||
|
rx = ry = 0;
|
||
|
LocalToScreen( rx, ry );
|
||
|
int mx, my;
|
||
|
input()->GetCursorPos(mx, my);
|
||
|
mx = mx - rx;
|
||
|
my = my - ry;
|
||
|
if (mx < 0 || my < 0)
|
||
|
return;
|
||
|
|
||
|
if ( m_hMenu.Get() != NULL )
|
||
|
{
|
||
|
m_hMenu->MarkForDeletion();
|
||
|
m_hMenu = NULL;
|
||
|
}
|
||
|
|
||
|
int tile_size = g_pTileGenDialog->RoomTemplatePanelTileSize();
|
||
|
int iTileX = mx / tile_size;
|
||
|
int iTileY = my / tile_size;
|
||
|
|
||
|
vgui::Panel *parent = GetParent();
|
||
|
CRoomTemplateEditDialog *pEdit = dynamic_cast<CRoomTemplateEditDialog*>(parent);
|
||
|
if (pEdit)
|
||
|
{
|
||
|
pEdit->m_iSelectedTileX = iTileX;
|
||
|
pEdit->m_iSelectedTileY = iTileY; //(m_pRoomTemplate->GetTilesY()-1) - iTileY; // reverse y axis
|
||
|
|
||
|
// find exits in this tile at this spot
|
||
|
const CRoomTemplate *pTemplate = pEdit->m_pRoomTemplate;
|
||
|
int iExits = pEdit->m_pRoomTemplate->m_Exits.Count();
|
||
|
bool bHasNorthExit = false, bHasEastExit = false, bHasSouthExit = false, bHasWestExit = false;
|
||
|
for (int i=iExits-1;i>=0;i--)
|
||
|
{
|
||
|
CRoomTemplateExit *pExit = pTemplate->m_Exits[i];
|
||
|
if (pExit->m_iXPos == iTileX && pExit->m_iYPos == iTileY)
|
||
|
{
|
||
|
switch( pExit->m_ExitDirection )
|
||
|
{
|
||
|
case EXITDIR_NORTH: bHasNorthExit = true; break;
|
||
|
case EXITDIR_EAST: bHasEastExit = true; break;
|
||
|
case EXITDIR_SOUTH: bHasSouthExit = true; break;
|
||
|
case EXITDIR_WEST: bHasWestExit = true; break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
vgui::Menu *pEditExitMenu = new Menu(this, "EditExitMenu");
|
||
|
|
||
|
if ( bHasNorthExit )
|
||
|
{
|
||
|
pEditExitMenu->AddMenuItem("North exit", "EditExitNorth", parent);
|
||
|
}
|
||
|
if ( bHasEastExit )
|
||
|
{
|
||
|
pEditExitMenu->AddMenuItem("East exit", "EditExitEast", parent);
|
||
|
}
|
||
|
if ( bHasSouthExit )
|
||
|
{
|
||
|
pEditExitMenu->AddMenuItem("South exit", "EditExitSouth", parent);
|
||
|
}
|
||
|
if ( bHasWestExit )
|
||
|
{
|
||
|
pEditExitMenu->AddMenuItem("West exit", "EditExitWest", parent);
|
||
|
}
|
||
|
|
||
|
vgui::Menu *pAddExitMenu = new Menu(this, "AddExitMenu");
|
||
|
if ( !bHasNorthExit )
|
||
|
{
|
||
|
pAddExitMenu->AddMenuItem("To the north", "AddExitNorth", parent);
|
||
|
}
|
||
|
if ( !bHasEastExit )
|
||
|
{
|
||
|
pAddExitMenu->AddMenuItem("To the east", "AddExitEast", parent);
|
||
|
}
|
||
|
if ( !bHasSouthExit )
|
||
|
{
|
||
|
pAddExitMenu->AddMenuItem("To the south", "AddExitSouth", parent);
|
||
|
}
|
||
|
if ( !bHasWestExit )
|
||
|
{
|
||
|
pAddExitMenu->AddMenuItem("To the west", "AddExitWest", parent);
|
||
|
}
|
||
|
|
||
|
vgui::Menu *pRightClickMenu = new Menu(this, "RightClickMenu");
|
||
|
pRightClickMenu->AddMenuItem("Clear all exits from this tile", "ClearExitsFromTile" , parent);
|
||
|
pRightClickMenu->AddMenuItem("Clear all exits from this room template", "ClearAllExits", parent);
|
||
|
pRightClickMenu->AddCascadingMenuItem( "AddExit", "Add exit to this tile...", "", this, pAddExitMenu );
|
||
|
pRightClickMenu->AddCascadingMenuItem( "EditExit", "Exit properties...", "", this, pEditExitMenu );
|
||
|
pRightClickMenu->SetPos( mx+rx, my+ry );
|
||
|
pRightClickMenu->SetVisible( true );
|
||
|
m_hMenu = pRightClickMenu;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MessageBox *pMessage = new MessageBox ("Error", "Couldn't cast RoomTemplatePanel's parent to RoomTemplateEditDialog", this);
|
||
|
pMessage->DoModal();
|
||
|
}
|
||
|
|
||
|
//char buffer[256];
|
||
|
//Q_snprintf(buffer, sizeof(buffer), "tilex = %d tiley = %d\n", iTileX, iTileY);
|
||
|
//MessageBox *pMessage = new MessageBox ("Right clicked roomtemplatepanel", buffer, this);
|
||
|
//pMessage->DoModal();
|
||
|
return;
|
||
|
}
|
||
|
if (m_bRoomTemplateBrowserMode)
|
||
|
{
|
||
|
if (code == MOUSE_LEFT)
|
||
|
{
|
||
|
g_pTileGenDialog->SetCursorRoomTemplate( m_pRoomTemplate );
|
||
|
}
|
||
|
else if (code == MOUSE_RIGHT)
|
||
|
{
|
||
|
if (m_pRoomTemplate)
|
||
|
{
|
||
|
// The convoluted FindRoom() call is so we can get a non-const pointer to the room template for the edit dialog to modify.
|
||
|
CRoomTemplateEditDialog *pDialog = new CRoomTemplateEditDialog( g_pTileGenDialog, "RoomTemplateEditDialog", m_pRoomTemplate->m_pLevelTheme->FindRoom( m_pRoomTemplate->GetFullName() ), false );
|
||
|
|
||
|
pDialog->AddActionSignalTarget( g_pTileGenDialog );
|
||
|
pDialog->DoModal();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
BaseClass::OnMouseReleased(code);
|
||
|
}
|
||
|
void CRoomTemplatePanel::UpdateAllImages()
|
||
|
{
|
||
|
int iCount = g_pRoomTemplatePanels.Count();
|
||
|
for (int i=0;i<iCount;i++)
|
||
|
{
|
||
|
CRoomTemplatePanel *pPanel = g_pRoomTemplatePanels[i];
|
||
|
if (pPanel)
|
||
|
pPanel->UpdateImages();
|
||
|
}
|
||
|
}
|