示例#1
0
TechTreeWindow *TechTreeWindow::Constructor(Window *underlyingWindow, int unknownGameAndPlayerData, int selectedCivId)
{
	// Needed for window management and proper cleanup in other places
	base::Constructor("One Button Tech Tree Screen");

	// Save underlying window
	_underlyingWindow = underlyingWindow;

	// Save game data
	_unknownGameAndPlayerData = unknownGameAndPlayerData;

	// Set virtual function table address
	_VTable = reinterpret_cast<ControlVTable *>(0x00645118);

	// Cast virtual function table to be able to access all functions
	PanelVTable *vTable = static_cast<PanelVTable *>(_VTable);

	// Get design data
	_designData = _staticNewTechTreeDataObject->GetDesignData();

	// Load style file
	DirectDrawBufferData *backBuffer = underlyingWindow->_VTable->GetBackBufferData(underlyingWindow);
	if(!PrepareParentWindowAndLoadStyleData(backBuffer, "scr6", 50007, 1))
		_initializationError = 1;

	// Start with top left corner
	_horizontalScrollOffset = 0;
	_verticalScrollOffset = 0;
	_lastScrollActionTime = 0;

	// Create vanilla style tech tree renderer
	// TODO: May be changed to allow various renderers using completely different layout approaches
	_renderer = new VanillaTechTreeRenderer((*_staticGameObjectPointer)->GetGameDataHandler(), Size(_width1, _height1), unknownGameAndPlayerData);

	// Get the renderer's age count
	_ageCount = _renderer->GetAgeCount();

	// Create close button and its buffer
	static_cast<PanelVTable *>(_VTable)->CreateButtonWithOneFontWithTextFromDll(this, this, &_closeButton, 20101, 0, _width1 - _designData->_closeButtonRelativeRectangle.X, _height1 - _designData->_closeButtonRelativeRectangle.Y, _designData->_closeButtonRelativeRectangle.Width, _designData->_closeButtonRelativeRectangle.Height, 9, 0, 0);
	_closeButton->_VTable->InvalidateAndRedrawControl1(_closeButton, 1);
	_closeButton->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_closeButton->SetHotKey(VK_ESCAPE, 0, 0, 0);
	_closeButtonDrawBuffer = new DirectDrawBufferData("TechTree Close Button Buffer", 1);
	_closeButtonDrawBuffer->InsertIntoBufferListAndCreateSurfaceAndDoUnknownStuff(_backBufferData->GetDirectDrawHandler(), _designData->_closeButtonRelativeRectangle.Width, _designData->_closeButtonRelativeRectangle.Height, 0, 0);
	_closeButtonDrawBuffer->sub_5A30A0(0, 0, _designData->_closeButtonRelativeRectangle.Width, _designData->_closeButtonRelativeRectangle.Height);
	UpdateSelectedSubControl(_closeButton);

	// Create scroll buttons and their buffers
	static_cast<PanelVTable *>(_VTable)->CreateButton(this, this, &_scrollLeftButton, "<-", 0, _width1 - _designData->_scrollLeftButtonRelativeRectangle.X, _height1 - _designData->_scrollLeftButtonRelativeRectangle.Y, _designData->_scrollLeftButtonRelativeRectangle.Width, _designData->_scrollLeftButtonRelativeRectangle.Height, 9, 0, 0);
	_scrollLeftButton->_VTable->InvalidateAndRedrawControl1(_scrollLeftButton, 1);
	_scrollLeftButton->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_scrollLeftButtonDrawBuffer = new DirectDrawBufferData("TechTree ScrollLeft Button Buffer", 1);
	_scrollLeftButtonDrawBuffer->InsertIntoBufferListAndCreateSurfaceAndDoUnknownStuff(_backBufferData->GetDirectDrawHandler(), _designData->_scrollLeftButtonRelativeRectangle.Width, _designData->_scrollLeftButtonRelativeRectangle.Height, 0, 0);
	_scrollLeftButtonDrawBuffer->sub_5A30A0(0, 0, _designData->_scrollLeftButtonRelativeRectangle.Width, _designData->_scrollLeftButtonRelativeRectangle.Height);
	static_cast<PanelVTable *>(_VTable)->CreateButton(this, this, &_scrollRightButton, "->", 0, _width1 - _designData->_scrollRightButtonRelativeRectangle.X, _height1 - _designData->_scrollRightButtonRelativeRectangle.Y, _designData->_scrollRightButtonRelativeRectangle.Width, _designData->_scrollRightButtonRelativeRectangle.Height, 9, 0, 0);
	_scrollRightButton->_VTable->InvalidateAndRedrawControl1(_scrollRightButton, 1);
	_scrollRightButton->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_scrollRightButtonDrawBuffer = new DirectDrawBufferData("TechTree ScrollRight Button Buffer", 1);
	_scrollRightButtonDrawBuffer->InsertIntoBufferListAndCreateSurfaceAndDoUnknownStuff(_backBufferData->GetDirectDrawHandler(), _designData->_scrollRightButtonRelativeRectangle.Width, _designData->_scrollRightButtonRelativeRectangle.Height, 0, 0);
	_scrollRightButtonDrawBuffer->sub_5A30A0(0, 0, _designData->_scrollRightButtonRelativeRectangle.Width, _designData->_scrollRightButtonRelativeRectangle.Height);

	// Load arrow SLP for scroll buttons and assign frames to them
	_arrowSlp = new SlpFileElement(_designData->_scrollSlpFileName, _designData->_scrollSlpId);
	_scrollLeftButton->SetBackgroundSlpAtIndex(0, _arrowSlp, 1);
	_scrollLeftButton->SetDisplayMode(9);
	_scrollLeftButton->AssignLabelString(0, "");
	_scrollRightButton->SetBackgroundSlpAtIndex(0, _arrowSlp, 0);
	_scrollRightButton->SetDisplayMode(9);
	_scrollRightButton->AssignLabelString(0, "");

	// Create civ bonus label
	/*static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &_civBonusLabel, 0, 2, 20, 100, 20, 10, 0, 0, 1);
	_civBonusLabel->_VTable->InvalidateAndRedrawControl1(_civBonusLabel, 0);
	_civBonusLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_civBonusLabel->SetStyleText2Colors(0, 0);
	_civBonusLabel->sub_545D70(0);*/
	FontData *civBonusLabelBaseFont = (*_staticGameObjectPointer)->GetFontWithIndex(10);
	HFONT civBonusLabelFonts[4];
	civBonusLabelFonts[0] = civBonusLabelBaseFont->GetFontHandle();
	civBonusLabelFonts[1] = (*_staticGameObjectPointer)->GetFontWithIndex(17)->GetFontHandle();
	civBonusLabelFonts[2] = (*_staticGameObjectPointer)->GetFontWithIndex(18)->GetFontHandle();
	civBonusLabelFonts[3] = (*_staticGameObjectPointer)->GetFontWithIndex(19)->GetFontHandle();
	_civBonusLabel = new LabelControl();
	_civBonusLabel->sub_5444B0(_backBufferData, this, 2, 20, 100, 20, civBonusLabelFonts, civBonusLabelBaseFont->GetAverageCharWidth(), civBonusLabelBaseFont->GetCharHeightWithRowSpace(), nullptr, 0, 0, 0, 0, 0, nullptr);
	_civBonusLabel->SetTextAlignment(3, 1);
	_civBonusLabel->sub_545D50(1);
	_civBonusLabel->sub_545D70(0);
	_civBonusLabel->SetStyleText2Colors(0x000000, 0x00E7E7);

	// Create civ selection combo box
	static_cast<PanelVTable *>(_VTable)->CreateComboBox(this, this, &_civSelectionComboBox, 230, 0, 2, 20, 200, 25, 10);
	_civSelectionComboBox->_VTable->InvalidateAndRedrawControl1(_civSelectionComboBox, 1);
	_civSelectionComboBox->SetDropDownListSortingMode(1);
	_civSelectionComboBox->AssignIdToControlAndMoveInParentChildrenList(1, 1);
	_civSelectionComboBox->SetStyleText2Colors(0, 0);
	_civSelectionComboBox->GetDropDownScrollBar()->SetFillBackground(-1);
	_civSelectionComboBox->GetValueLabel()->SetBackgroundSlp("tech_tile.slp", 50343);
	_civSelectionComboBox->GetDropDownList()->SetBackgroundSlp("tech_tile.slp", 50343);

	// Create "game civs" label
	static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &_gameCivsLabel, 0, 2, 20, 200, 25, 10, 0, 0, 1);
	_gameCivsLabel->_VTable->InvalidateAndRedrawControl1(_gameCivsLabel, 0);
	_gameCivsLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_gameCivsLabel->SetStyleText2Colors(0, 0);
	_gameCivsLabel->sub_545D70(0);
	static_cast<LabelControlVTable *>(_gameCivsLabel->_VTable)->AssignTextFromLanguageDlls(_gameCivsLabel, 20125);

	// Create "Not researched" label
	static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &_legendNotResearchedLabel, 0, 2, 2, 160, 25, 13, 0, 0, 0);
	_legendNotResearchedLabel->_VTable->InvalidateAndRedrawControl1(_legendNotResearchedLabel, 0);
	_legendNotResearchedLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_legendNotResearchedLabel->SetStyleText2Colors(0, 0);
	_legendNotResearchedLabel->sub_545D70(0);
	static_cast<LabelControlVTable *>(_legendNotResearchedLabel->_VTable)->AssignTextFromLanguageDlls(_legendNotResearchedLabel, 20124);

	// Create "Researched" label
	static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &_legendResearchedLabel, 0, 2, 2, 160, 25, 13, 0, 0, 0);
	_legendResearchedLabel->_VTable->InvalidateAndRedrawControl1(_legendResearchedLabel, 0);
	_legendResearchedLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_legendResearchedLabel->SetStyleText2Colors(0, 0);
	_legendResearchedLabel->sub_545D70(0);
	static_cast<LabelControlVTable *>(_legendResearchedLabel->_VTable)->AssignTextFromLanguageDlls(_legendResearchedLabel, 20128);

	// Create node type labels
	_legendNodeTypeLabels = new std::vector<LabelControl *>();
	int nodeTypeLabelCount = _renderer->GetLegendNodeTypeCount();
	for(int i = 0; i < nodeTypeLabelCount; ++i)
	{
		// Create label
		LabelControl *legendNodeTypeLabel;
		static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &legendNodeTypeLabel, 0, 2, 2, 160, 25, 13, 0, 0, 0);
		legendNodeTypeLabel->_VTable->InvalidateAndRedrawControl1(legendNodeTypeLabel, 0);
		legendNodeTypeLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
		legendNodeTypeLabel->SetStyleText2Colors(0, 0);
		legendNodeTypeLabel->sub_545D70(0);
		static_cast<LabelControlVTable *>(legendNodeTypeLabel->_VTable)->AssignTextFromLanguageDlls(legendNodeTypeLabel, _renderer->GetLegendNodeTypeLabelDllId(i));
		_legendNodeTypeLabels->push_back(legendNodeTypeLabel);
	}

	// Create "Disabled" label
	static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, &_legendDisabledLabel, 0, 2, 2, 160, 25, 13, 0, 0, 0);
	_legendDisabledLabel->_VTable->InvalidateAndRedrawControl1(_legendDisabledLabel, 0);
	_legendDisabledLabel->AssignIdToControlAndMoveInParentChildrenList(1, 0);
	_legendDisabledLabel->SetStyleText2Colors(0, 0);
	_legendDisabledLabel->sub_545D70(0);
	static_cast<LabelControlVTable *>(_legendDisabledLabel->_VTable)->AssignTextFromLanguageDlls(_legendDisabledLabel, 20119);

	// Fill civ selection combo box
	int civCount = (*_staticGameObjectPointer)->GetGameDataHandler()->_civCount;
	char civNameBuffer[128];
	char civNameSuffixBuffer[128];
	char civNameMergedBuffer[256];
	for(int c = 1; c < civCount; ++c)
	{
		// Clear strings
		civNameBuffer[0] = '\0';
		civNameSuffixBuffer[0] = '\0';
		civNameMergedBuffer[0] = '\0';

		// Load civ name
		(*_staticGameObjectPointer)->GetIndexedDllString(105, c, 0, civNameBuffer, sizeof(civNameBuffer));

		// Load civ suffix " (Player)" or " (Ally)", if neccessary
		if(_unknownGameAndPlayerData != 0)
			if(reinterpret_cast<char *>(_unknownGameAndPlayerData)[349] == c) // Check player
				(*_staticGameObjectPointer)->GetStringFromLanguageDllsWithBuffer(20126, civNameSuffixBuffer, sizeof(civNameSuffixBuffer));
			else
			{
				// Check allies
				GameDataHandler *gdh = (*_staticGameObjectPointer)->GetGameDataHandler();
				for(int p = 1; p < 9; ++p)
					if(reinterpret_cast<char *>(_unknownGameAndPlayerData + 6458)[p] == 4 && reinterpret_cast<char *>(gdh->_dword4C[p])[349] == c)
					{
						// Get suffix and break
						(*_staticGameObjectPointer)->GetStringFromLanguageDllsWithBuffer(20127, civNameSuffixBuffer, sizeof(civNameSuffixBuffer));
						break;
					}
			}

		// Merge civ name and suffix
		sprintf(civNameMergedBuffer, "%s%s", civNameBuffer, civNameSuffixBuffer);

		// Add civ to list
		_civSelectionComboBox->AddItem(civNameMergedBuffer, c);
	}
	_civSelectionComboBox->SetSelectedIndex(0);

	// Create age labels
	_ageLabels = new LabelControl*[_ageCount][2][2];
	for(int i = 0; i < _ageCount; ++i)
	{
		// Create 4 labels for this age
		for(int j = 0; j < 4; ++j)
		{
			// Create and initialize label
			LabelControl **currAgeLabelPointer = &_ageLabels[i][j >> 1][j & 1];
			static_cast<PanelVTable *>(_VTable)->CreateLabelWithOneFontWithTextFromDll(this, this, currAgeLabelPointer, 0, 2, 2, 150, 25, 11, 1, 0, 1);
			(*currAgeLabelPointer)->_VTable->InvalidateAndRedrawControl1(*currAgeLabelPointer, 0);
			(*currAgeLabelPointer)->AssignIdToControlAndMoveInParentChildrenList(1, 0);
			(*currAgeLabelPointer)->SetStyleText2Colors(0, 0);
			(*currAgeLabelPointer)->sub_545D70(0);
		}

		// Set label texts
		static_cast<LabelControlVTable *>(_ageLabels[i][0][0]->_VTable)->AssignTextFromLanguageDlls(_ageLabels[i][0][0], _designData->_firstLineBaseDllId + i);
		static_cast<LabelControlVTable *>(_ageLabels[i][0][1]->_VTable)->AssignTextFromLanguageDlls(_ageLabels[i][0][1], _designData->_secondLineDllId + (_designData->_incrementSecondLineDllId ? i : 0));
		static_cast<LabelControlVTable *>(_ageLabels[i][1][0]->_VTable)->AssignTextFromLanguageDlls(_ageLabels[i][1][0], _designData->_firstLineBaseDllId + i);
		static_cast<LabelControlVTable *>(_ageLabels[i][1][1]->_VTable)->AssignTextFromLanguageDlls(_ageLabels[i][1][1], _designData->_secondLineDllId + (_designData->_incrementSecondLineDllId ? i : 0));
	}

	// Create popup label
	_popupLabelBaseFont = (*_staticGameObjectPointer)->GetFontWithIndex(10);
	HFONT popupLabelFonts[4];
	popupLabelFonts[0] = _popupLabelBaseFont->GetFontHandle();
	popupLabelFonts[1] = (*_staticGameObjectPointer)->GetFontWithIndex(17)->GetFontHandle();
	popupLabelFonts[2] = (*_staticGameObjectPointer)->GetFontWithIndex(18)->GetFontHandle();
	popupLabelFonts[3] = (*_staticGameObjectPointer)->GetFontWithIndex(19)->GetFontHandle();
	_popupLabel = new LabelControl();
	_popupLabel->sub_5444B0(_backBufferData, this, 0, 0, _designData->_popupLabelWidth, 50, popupLabelFonts, _popupLabelBaseFont->GetAverageCharWidth(), _popupLabelBaseFont->GetCharHeightWithRowSpace(), nullptr, 0, 0, 0, 0, 0, nullptr);
	_popupLabel->SetTextAlignment(3, 1);
	_popupLabel->sub_545D50(1);
	_popupLabel->sub_545D70(0);
	_popupLabel->SetStyleText2Colors(0x000000, 0x00E7E7);

	// Set current civ
	if(unknownGameAndPlayerData != 0)
		selectedCivId = reinterpret_cast<char *>(unknownGameAndPlayerData)[349];
	if(selectedCivId < 1)
		selectedCivId = 1;
	_civSelectionComboBox->SetSelectedItemId(selectedCivId);
	SetCurrentCiv(selectedCivId);

	// No element is selected
	_selectedElement = nullptr;
	_drawPopupLabelBox = false;
	_selectedElementChangedTime = 0;

	// Issue redraw
	_VTable->InvalidateAndRedrawControl2(this, 2);

	// Return reference to self
	return this;
}