guihandler.cpp

来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 2,423 行 · 第 1/5 页

CPP
2,423
字号
			return;
		}
	}
}


void CGuiHandler::LayoutIcons(bool useSelectionPage)
{
	const bool defCmd =
		(mouse->buttons[SDL_BUTTON_RIGHT].pressed &&
		 (defaultCmdMemory >= 0) && (inCommand < 0) &&
		 ((activeReceiver == this) || (minimap->ProxyMode())));

	const int activeCmd = defCmd ? defaultCmdMemory : inCommand;

	// copy the current command state
	const bool validInCommand = (activeCmd >= 0) && (activeCmd < commands.size());
	CommandDescription cmdDesc;
	if (validInCommand) {
		cmdDesc = commands[activeCmd];
	}
	const bool samePage = validInCommand && (activePage == FindInCommandPage());
	useSelectionPage = useSelectionPage && !samePage;

	// reset some of our state
	inCommand = -1;
	defaultCmdMemory = -1;
	commands.clear();
	forceLayoutUpdate = false;

	// try using the custom layout handler
	if (firstLayout) {
		firstLayout = false;
		if (!!configHandler.GetInt("LuaUI", 0)) {
			CLuaUI::LoadHandler();
		}
	}
	if ((luaUI != NULL) && luaUI->HasLayoutButtons()) {
		if (LayoutCustomIcons(useSelectionPage)) {
			if (validInCommand) {
				RevertToCmdDesc(cmdDesc, defCmd, samePage);
			}
			return; // we're done here
		}
		else {
			CLuaUI::FreeHandler();
			LoadConfig("ctrlpanel.txt");
		}
	}

	// get the commands to process
	CSelectedUnits::AvailableCommandsStruct ac;
	ac = selectedUnits.GetAvailableCommands();
	ConvertCommands(ac.commands);

	vector<CommandDescription> hidden;
	vector<CommandDescription>::const_iterator cdi;

	// separate the visible/hidden icons
	for (cdi = ac.commands.begin(); cdi != ac.commands.end(); ++cdi){
		if (cdi->onlyKey) {
			hidden.push_back(*cdi);
		} else {
			commands.push_back(*cdi);
		}
	}

	// assign extra icons for internal commands
	int extraIcons = 0;
	if (deadIconSlot >= 0) { extraIcons++; }
	if (prevPageSlot >= 0) { extraIcons++; }
	if (nextPageSlot >= 0) { extraIcons++; }

	const int cmdCount        = (int)commands.size();
	const int cmdIconsPerPage = (iconsPerPage - extraIcons);
	const int pageCount       = ((cmdCount + (cmdIconsPerPage - 1)) / cmdIconsPerPage);

	const bool multiPage = (pageCount > 1);

	const int prevPageCmd = cmdCount + 0;
	const int nextPageCmd = cmdCount + 1;

	maxPage    = max(0, pageCount - 1);
	iconsCount = pageCount * iconsPerPage;

	// resize the icon array if required
	ResizeIconArray(iconsCount);

	int ci = 0; // command index

	for (int ii = 0; ii < iconsCount; ii++) {

		// map the icon order
		const int tmpSlot = (ii % iconsPerPage);
		const int mii = ii - tmpSlot + fillOrder[tmpSlot]; // mapped icon index

		IconInfo& icon = icons[mii];
		const int slot = (mii % iconsPerPage);

		if (slot == deadIconSlot) {
			icon.commandsID = -1;
		}
		else if (slot == nextPageSlot) {
			icon.commandsID = multiPage ? nextPageCmd : -1;
		}
		else if (slot == prevPageSlot) {
			icon.commandsID = multiPage ? prevPageCmd : -1;
		}
		else if (ci >= cmdCount) {
			icon.commandsID = -1;
		}
		else {
			icon.commandsID = ci;
			ci++;
		}

		// setup the geometry
		if (icon.commandsID >= 0) {
			const float fx = (float)(slot % xIcons);
			const float fy = (float)(slot / xIcons);

			const float fullBorder = frameBorder + iconBorder;
			icon.visual.x1 = buttonBox.x1 + (fullBorder + (fx * xIconStep));
			icon.visual.x2 = icon.visual.x1 + xIconSize;
			icon.visual.y1 = buttonBox.y2 - (fullBorder + (fy * yIconStep));
			icon.visual.y2 = icon.visual.y1 - yIconSize;

			const float noGap = selectGaps ? 0.0f : (iconBorder + 0.0005f);
			icon.selection.x1 = icon.visual.x1 - noGap;
			icon.selection.x2 = icon.visual.x2 + noGap;
			icon.selection.y1 = icon.visual.y1 + noGap;
			icon.selection.y2 = icon.visual.y2 - noGap;
		}
		else {
			// make sure this icon does not get selected
			icon.selection.x1 = icon.selection.x2 = -1.0f;
			icon.selection.y1 = icon.selection.y2 = -1.0f;
		}
	}

	// append the Prev and Next commands  (if required)
	if (multiPage) {
		AppendPrevAndNext(commands);
	}

	// append the hidden commands
	for (cdi = hidden.begin(); cdi != hidden.end(); ++cdi) {
		commands.push_back(*cdi);
	}

	// try to setup the old command state
	// (inCommand, activePage, showingMetal)
	if (validInCommand) {
		RevertToCmdDesc(cmdDesc, defCmd, samePage);
	} else if (useSelectionPage) {
		activePage = min(maxPage, ac.commandPage);
	}
	activePage = min(maxPage, activePage);
}


bool CGuiHandler::LayoutCustomIcons(bool useSelectionPage)
{
	if (luaUI == NULL) {
		return false;
	}

	// get the commands to process
	CSelectedUnits::AvailableCommandsStruct ac;
	ac = selectedUnits.GetAvailableCommands();
	vector<CommandDescription> cmds = ac.commands;
	if (cmds.size() > 0) {
		ConvertCommands(cmds);
		AppendPrevAndNext(cmds);
	}

	// call for a custom layout
	int tmpXicons = xIcons;
	int tmpYicons = yIcons;
	vector<int> removeCmds;
	vector<CommandDescription> customCmds;
	vector<int> onlyTextureCmds;
	vector<CLuaUI::ReStringPair> reTextureCmds;
	vector<CLuaUI::ReStringPair> reNamedCmds;
	vector<CLuaUI::ReStringPair> reTooltipCmds;
	vector<CLuaUI::ReParamsPair> reParamsCmds;
	map<int, int> iconMap;

	if (!luaUI->LayoutButtons(tmpXicons, tmpYicons, cmds,
	                          removeCmds, customCmds,
	                          onlyTextureCmds, reTextureCmds,
	                          reNamedCmds, reTooltipCmds, reParamsCmds,
	                          iconMap, menuName)) {
		return false;
	}

	if ((tmpXicons < 2) || (tmpYicons < 2)) {
		logOutput.Print("LayoutCustomIcons() bad xIcons or yIcons (%i, %i)\n",
		                tmpXicons, tmpYicons);
		return false;
	}

	unsigned int i;
	const int tmpIconsPerPage = (tmpXicons * tmpYicons);

	// build a set to better find unwanted commands
	set<int> removeIDs;
	for (i = 0; i < removeCmds.size(); i++) {
		const int index = removeCmds[i];
		if ((index >= 0) || (index < cmds.size())) {
			removeIDs.insert(index);
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad removeCmd (%i)\n",
			                index);
		}
	}
	// remove unwanted commands  (and mark all as onlyKey)
	vector<CommandDescription> tmpCmds;
	for (i = 0; i < cmds.size(); i++) {
		if (removeIDs.find(i) == removeIDs.end()) {
			cmds[i].onlyKey = true;
			tmpCmds.push_back(cmds[i]);
		}
	}
	cmds = tmpCmds;

	// add the custom commands
	for (i = 0; i < customCmds.size(); i++) {
		customCmds[i].onlyKey = true;
		cmds.push_back(customCmds[i]);
	}
	const int cmdCount = (int)cmds.size();

	// set commands to onlyTexture
	for (i = 0; i < onlyTextureCmds.size(); i++) {
		const int index = onlyTextureCmds[i];
		if ((index >= 0) && (index < cmdCount)) {
			cmds[index].onlyTexture = true;
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad onlyTexture (%i)\n",
			                index);
		}
	}

	// retexture commands
	for (i = 0; i < reTextureCmds.size(); i++) {
		const int index = reTextureCmds[i].cmdIndex;
		if ((index >= 0) && (index < cmdCount)) {
			cmds[index].iconname = reTextureCmds[i].texture;
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad reTexture (%i)\n",
			                index);
		}
	}

	// reNamed commands
	for (i = 0; i < reNamedCmds.size(); i++) {
		const int index = reNamedCmds[i].cmdIndex;
		if ((index >= 0) && (index < cmdCount)) {
			cmds[index].name = reNamedCmds[i].texture;
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad reNamed (%i)\n",
			                index);
		}
	}

	// reTooltip commands
	for (i = 0; i < reTooltipCmds.size(); i++) {
		const int index = reTooltipCmds[i].cmdIndex;
		if ((index >= 0) && (index < cmdCount)) {
			cmds[index].tooltip = reTooltipCmds[i].texture;
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad reNamed (%i)\n",
			                index);
		}
	}

	// reParams commands
	for (i = 0; i < reParamsCmds.size(); i++) {
		const int index = reParamsCmds[i].cmdIndex;
		if ((index >= 0) && (index < cmdCount)) {
			const map<int, string>& params = reParamsCmds[i].params;
			map<int, string>::const_iterator pit;
			for (pit = params.begin(); pit != params.end(); ++pit) {
				const int p = pit->first;
				if ((p >= 0) && (p < (int)cmds[index].params.size())) {
					cmds[index].params[p] = pit->second;
				}
			}
		} else {
			logOutput.Print("LayoutCustomIcons() skipping bad reParams (%i)\n",
			                index);
		}
	}

	// build the iconList from the map
	vector<int> iconList;
	int nextPos = 0;
	map<int, int>::iterator mit;
	for (mit = iconMap.begin(); mit != iconMap.end(); ++mit) {
		const int iconPos = mit->first;
		if (iconPos < nextPos) {
			continue;
		}
		else if (iconPos > nextPos) {
			// fill in the blanks
			for (int p = nextPos; p < iconPos; p++) {
				iconList.push_back(-1);
			}
		}
		iconList.push_back(mit->second); // cmdIndex
		nextPos = iconPos + 1;
	}

	const int iconListCount = (int)iconList.size();
	const int pageCount = ((iconListCount + (tmpIconsPerPage - 1)) / tmpIconsPerPage);
	const int tmpIconsCount = (pageCount * tmpIconsPerPage);

	// resize the icon array if required
	ResizeIconArray(tmpIconsCount);

	// build the iconList
	for (int ii = 0; ii < tmpIconsCount; ii++) {
		IconInfo& icon = icons[ii];

		const int index = (ii < (int)iconList.size()) ? iconList[ii] : -1;

		if ((index >= 0) && (index < cmdCount)) {

			icon.commandsID = index;
			cmds[index].onlyKey = false;

			const int slot = (ii % tmpIconsPerPage);
			const float fx = (float)(slot % tmpXicons);
			const float fy = (float)(slot / tmpXicons);

			const float fullBorder = frameBorder + iconBorder;
			icon.visual.x1 = buttonBox.x1 + (fullBorder + (fx * xIconStep));
			icon.visual.x2 = icon.visual.x1 + xIconSize;
			icon.visual.y1 = buttonBox.y2 - (fullBorder + (fy * yIconStep));
			icon.visual.y2 = icon.visual.y1 - yIconSize;

			const float noGap = selectGaps ? 0.0f : (iconBorder + 0.0005f);
			icon.selection.x1 = icon.visual.x1 - noGap;
			icon.selection.x2 = icon.visual.x2 + noGap;
			icon.selection.y1 = icon.visual.y1 + noGap;
			icon.selection.y2 = icon.visual.y2 - noGap;
		}
		else {
			// make sure this icon does not get selected
			icon.commandsID = -1;
			icon.selection.x1 = icon.selection.x2 = -1.0f;
			icon.selection.y1 = icon.selection.y2 = -1.0f;
		}
	}

	commands = cmds;

	xIcons       = tmpXicons;
	yIcons       = tmpYicons;
	iconsCount   = tmpIconsCount;
	iconsPerPage = tmpIconsPerPage;

	maxPage = max(0, pageCount - 1);
	if (useSelectionPage) {
		activePage = min(maxPage, ac.commandPage);
	} else {
		activePage = min(maxPage, activePage);
	}

	buttonBox.x1 = xPos;
	buttonBox.x2 = xPos + (frameBorder * 2.0f) + (xIcons * xIconStep);
	buttonBox.y1 = yPos;
	buttonBox.y2 = yPos + (frameBorder * 2.0f) + (yIcons * yIconStep);

	return true;
}


void CGuiHandler::GiveCommand(const Command& cmd, bool fromUser) const
{
	if (luaUI != NULL) {
		if (luaUI->CommandNotify(cmd)) {
			return;
		}
	}

	selectedUnits.GiveCommand(cmd, fromUser);

	if (gatherMode) {
		if ((cmd.id == CMD_MOVE) || (cmd.id == CMD_FIGHT)) {
			Command gatherCmd;
			gatherCmd.id = CMD_GATHERWAIT;
			GiveCommand(gatherCmd, false);
		}
	}
}


void CGuiHandler::ConvertCommands(vector<CommandDescription>& cmds)
{
	if (newAttackMode) {
		const int count = (int)cmds.size();
		for (int i = 0; i < count; i++) {
			CommandDescription& cd = cmds[i];
			if ((cd.id == CMD_ATTACK) && (cd.type == CMDTYPE_ICON_UNIT_OR_MAP)) {
				if (attackRect) {
					cd.type = CMDTYPE_ICON_UNIT_OR_RECTANGLE;
				} else {
					cd.type = CMDTYPE_ICON_UNIT_OR_AREA;
				}
			}
		}
	}
}


void CGuiHandler::SetShowingMetal(bool show)
{
	CBaseGroundDrawer* gd = readmap->GetGroundDrawer();
	if (!show) {
		if (showingMetal) {
			gd->DisableExtraTexture();
			showingMetal = false;
		}
	}
	else {
		if (autoShowMetal) {
			if (gd->drawMode != CBaseGroundDrawer::drawMetal) {
				CMetalMap* mm = readmap->metalMap;
				gd->SetMetalTexture(mm->metalMap, &mm->extractionMap.front(), mm->metalPal, false);
				showingMetal = true;
			}
		}
	}
}


void CGuiHandler::Update()
{
	SetCursorIcon();

	// Notify LuaUI about groups that have changed
	if (!changedGroups.empty()) {
		if (luaUI != NULL) {
			set<int>::const_iterator it;
			for (it = changedGroups.begin(); it != changedGroups.end(); ++it) {
				luaUI->GroupChanged(*it);
			}
		}
		changedGroups.clear();
	}

	if (!invertQueueKey && (needShift && !keys[SDLK_LSHIFT])) {
		SetShowingMetal(false);
		inCommand=-1;
		needShift=false;
	}

	const bool commandsChanged = selectedUnits.CommandsChanged();

	if (commandsChanged) {
		SetShowingMetal(false);
		LayoutIcons(true);
		fadein = 100;
	}
	else if (forceLayoutUpdate) {
		LayoutIcons(false);
	}

	if (fadein > 0) {
		fadein -= 5;
	}
}


/******************************************************************************/
/******************************************************************************/

void CGuiHandler::SetCursorIcon() const
{
	mouse->cursorText = "";
	mouse->cursorScale = 1.0f;

	CInputReceiver* ir = NULL;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?