mousehandler.cpp

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

CPP
805
字号
						unit->unitDef->sounds.select.getVolume(soundIdx));
				}
			}
			else if(addedunits) //more than one unit selected
				sound->PlaySample(soundMultiselID);
		} else {
			CUnit* unit;
			helper->GuiTraceRay(camera->pos,dir,gu->viewRange*1.4f,unit,20,false);
			if(unit && ((unit->team == gu->myTeam) || gu->spectatingFullSelect)){
				if(buttons[button].lastRelease < (gu->gameTime - doubleClickTime)){
					if (keys[SDLK_LCTRL] && selectedUnits.selectedUnits.find(unit) != selectedUnits.selectedUnits.end()) {
						selectedUnits.RemoveUnit(unit);
					} else {
						selectedUnits.AddUnit(unit);
					}
				}
				else {
					//double click
					if (unit->group && !keys[SDLK_LCTRL]) {
						//select the current unit's group if it has one
						selectedUnits.SelectGroup(unit->group->id);
					} else {
						//select all units of same type (on screen, unless CTRL is pressed)
						int team, lastTeam;
						if (gu->spectatingFullSelect) {
							team = 0;
							lastTeam = gs->activeTeams - 1;
						} else {
							team = gu->myTeam;
							lastTeam = gu->myTeam;
						}
						for (; team <= lastTeam; team++) {
							CUnitSet::iterator ui;
							CUnitSet& teamUnits = gs->Team(team)->units;
							for (ui = teamUnits.begin(); ui != teamUnits.end(); ++ui) {
								if (((*ui)->aihint == unit->aihint) &&
										(camera->InView((*ui)->midPos) || keys[SDLK_LCTRL])) {
									selectedUnits.AddUnit(*ui);
								}
							}
						}
					}
				}
				buttons[button].lastRelease=gu->gameTime;

				int soundIdx = unit->unitDef->sounds.select.getRandomIdx();
				if (soundIdx >= 0) {
					sound->PlayUnitReply(
						unit->unitDef->sounds.select.getID(soundIdx), unit,
						unit->unitDef->sounds.select.getVolume(soundIdx));
				}
			}
		}
	}
}


void CMouseHandler::MouseWheel(bool up)
{
	const float value = up ? +scrollWheelSpeed : -scrollWheelSpeed;
	if (luaUI && luaUI->MouseWheel(up, value)) {
		return;
	}
	camCtrl->MouseWheelMove(value);
}


void CMouseHandler::Draw()
{
	dir = hide ? camera->forward : camera->CalcPixelDir(lastx, lasty);
	if (activeReceiver) {
		return;
	}

#ifdef DIRECT_CONTROL_ALLOWED
	if (gu->directControl) {
		return;
	}
#endif
	if (buttons[SDL_BUTTON_LEFT].pressed && !buttons[SDL_BUTTON_LEFT].chorded &&
	   (buttons[SDL_BUTTON_LEFT].movement > 4) &&
	   (!inMapDrawer || !inMapDrawer->keyPressed)) {

		float dist=ground->LineGroundCol(buttons[SDL_BUTTON_LEFT].camPos,
		                                 buttons[SDL_BUTTON_LEFT].camPos
		                                 + buttons[SDL_BUTTON_LEFT].dir*gu->viewRange*1.4f);
		if(dist<0)
			dist=gu->viewRange*1.4f;
		float3 pos1=buttons[SDL_BUTTON_LEFT].camPos+buttons[SDL_BUTTON_LEFT].dir*dist;

		dist=ground->LineGroundCol(camera->pos,camera->pos+dir*gu->viewRange*1.4f);
		if(dist<0)
			dist=gu->viewRange*1.4f;
		float3 pos2=camera->pos+dir*dist;

		float3 dir1=pos1-camera->pos;
		dir1.Normalize();
		float3 dir2=pos2-camera->pos;
		dir2.Normalize();

		float3 dir1S=camera->right*(dir1.dot(camera->right))/dir1.dot(camera->forward);
		float3 dir1U=camera->up*(dir1.dot(camera->up))/dir1.dot(camera->forward);

		float3 dir2S=camera->right*(dir2.dot(camera->right))/dir2.dot(camera->forward);
		float3 dir2U=camera->up*(dir2.dot(camera->up))/dir2.dot(camera->forward);

		glColor4fv(cmdColors.mouseBox);

		glPushAttrib(GL_ENABLE_BIT);

		glDisable(GL_FOG);
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_TEXTURE_2D);

		glEnable(GL_BLEND);
		glBlendFunc((GLenum)cmdColors.MouseBoxBlendSrc(),
		            (GLenum)cmdColors.MouseBoxBlendDst());

		glLineWidth(cmdColors.MouseBoxLineWidth());
		glBegin(GL_LINE_LOOP);
		glVertexf3(camera->pos+dir1U*30+dir1S*30+camera->forward*30);
		glVertexf3(camera->pos+dir2U*30+dir1S*30+camera->forward*30);
		glVertexf3(camera->pos+dir2U*30+dir2S*30+camera->forward*30);
		glVertexf3(camera->pos+dir1U*30+dir2S*30+camera->forward*30);
		glEnd();
		glLineWidth(1.0f);


		glPopAttrib();
	}
}

void CMouseHandler::ShowMouse()
{
	if(hide){
		SDL_ShowCursor(SDL_DISABLE);
		hide=false;
	}
}


void CMouseHandler::HideMouse()
{
	if (!hide) {
		lastx = gu->viewSizeX / 2 + gu->viewPosX;
		lasty = gu->viewSizeY / 2 + gu->viewPosY;
    	SDL_ShowCursor(SDL_DISABLE);
		mouseInput->SetPos(int2(lastx, lasty));
		hide = true;
	}
}

void CMouseHandler::ToggleState()
{
	if(locked){
		locked=false;
		ShowMouse();
	} else {
		locked=true;
		HideMouse();
}
}

void CMouseHandler::WarpMouse(int x, int y)
{
	if (!locked) {
		lastx = x;
		lasty = y;
		mouseInput->SetPos(int2(x, y));
	}
}


std::string CMouseHandler::GetCurrentTooltip(void)
{
	std::string s;
	std::deque<CInputReceiver*>& inputReceivers = GetInputReceivers();
	std::deque<CInputReceiver*>::iterator ri;
	for (ri = inputReceivers.begin(); ri != inputReceivers.end(); ++ri) {
		if ((*ri) && (*ri)->IsAbove(lastx, lasty)) {
			s = (*ri)->GetTooltip(lastx, lasty);
			if (s != "") {
				return s;
			}
		}
	}

	const string buildTip = guihandler->GetBuildTooltip();
	if (!buildTip.empty()) {
		return buildTip;
	}

	const float range = (gu->viewRange * 1.4f);
	CUnit* unit = NULL;
	CFeature* feature = NULL;
	float udist = helper->GuiTraceRay(camera->pos, dir, range, unit, 20, true);
	float fdist = helper->GuiTraceRayFeature(camera->pos, dir, range, feature);

	if ((udist > (range - 300.0f)) &&
	    (fdist > (range - 300.0f)) && (unit == NULL)) {
		return "";
	}

	if (udist > fdist) {
		unit = NULL;
	} else {
		feature = NULL;
	}

	if (unit) {
		return CTooltipConsole::MakeUnitString(unit);
	}

	if (feature) {
		return CTooltipConsole::MakeFeatureString(feature);
	}

	const string selTip = selectedUnits.GetTooltip();
	if (selTip != "") {
		return selTip;
	}

	if (udist < (range - 100.0f)) {
		const float3 pos = camera->pos + (dir * udist);
		return CTooltipConsole::MakeGroundString(pos);
	}

	return "";
}

void CMouseHandler::EmptyMsgQueUpdate(void)
{
	if (!hide) {
		return;
	}

	int dx = lastx - (gu->viewSizeX / 2 + gu->viewPosX);
	int dy = lasty - (gu->viewSizeY / 2 + gu->viewPosY);
	lastx = gu->viewSizeX / 2 + gu->viewPosX;
	lasty = gu->viewSizeY / 2 + gu->viewPosY;

	float3 move;
	move.x = dx;
	move.y = dy;
	move.z = invertMouse? -1.0f : 1.0f;
	camCtrl->MouseMove(move);

	if (gu->active) {
		mouseInput->SetPos(int2(lastx, lasty));
	}
}

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

void CMouseHandler::UpdateCursors()
{
	map<string, CMouseCursor *>::iterator it;
	for (it = cursorFileMap.begin(); it != cursorFileMap.end(); ++it) {
		if (it->second != NULL) {
			it->second->Update();
		}
	}
}


void CMouseHandler::DrawCursor(void)
{
	if (guihandler) {
		guihandler->DrawCentroidCursor();
	}

	if (hide || (cursorText == "none")) {
		return;
	}

	CMouseCursor* mc;
	map<string, CMouseCursor*>::iterator it = cursorCommandMap.find(cursorText);
	if (it != cursorCommandMap.end()) {
		mc = it->second;
	} else {
		mc = cursorFileMap["cursornormal"];
	}

	if (mc == NULL) {
		return;
	}

	if (cursorScale >= 0.0f) {
		mc->Draw(lastx, lasty, cursorScale);
	}
	else {
		CMouseCursor* nc = cursorFileMap["cursornormal"];
		if (nc == NULL) {
			mc->Draw(lastx, lasty, -cursorScale);
		}
		else {
			nc->Draw(lastx, lasty, 1.0f);
			if (mc != nc) {
				mc->Draw(lastx + nc->GetMaxSizeX(),
								 lasty + nc->GetMaxSizeY(), -cursorScale);
			}
		}
	}
}


bool CMouseHandler::AssignMouseCursor(const std::string& cmdName,
                                      const std::string& fileName,
                                      CMouseCursor::HotSpot hotSpot,
                                      bool overwrite)
{
	std::map<std::string, CMouseCursor*>::iterator cmdIt;
	cmdIt = cursorCommandMap.find(cmdName);
	const bool haveCmd  = (cmdIt  != cursorCommandMap.end());

	std::map<std::string, CMouseCursor*>::iterator fileIt;
	fileIt = cursorFileMap.find(fileName);
	const bool haveFile = (fileIt != cursorFileMap.end());

	if (haveCmd && !overwrite) {
		return false; // already assigned
	}

	if (haveFile) {
		cursorCommandMap[cmdName] = fileIt->second;
		return true;
	}

	CMouseCursor* oldCursor = haveCmd ? cmdIt->second : NULL;

	CMouseCursor* cursor = CMouseCursor::New(fileName, hotSpot);
	if (cursor == NULL) {
		return false; // invalid cursor
	}
	cursorFileMap[fileName] = cursor;

	// assign the new cursor
	cursorCommandMap[cmdName] = cursor;

	SafeDeleteCursor(oldCursor);

	return true;
}


bool CMouseHandler::ReplaceMouseCursor(const string& oldName,
                                       const string& newName,
                                       CMouseCursor::HotSpot hotSpot)
{
	std::map<std::string, CMouseCursor*>::iterator fileIt;
	fileIt = cursorFileMap.find(oldName);
	if (fileIt == cursorFileMap.end()) {
		return false;
	}

	CMouseCursor* newCursor = CMouseCursor::New(newName, hotSpot);
	if (newCursor == NULL) {
		return false; // leave the old one
	}

	CMouseCursor* oldCursor = fileIt->second;

	std::map<std::string, CMouseCursor*>& cmdMap = cursorCommandMap;
	std::map<std::string, CMouseCursor*>::iterator cmdIt;
	for (cmdIt = cmdMap.begin(); cmdIt != cmdMap.end(); ++cmdIt) {
		if (cmdIt->second == oldCursor) {
			cmdIt->second = newCursor;
		}
	}

	fileIt->second = newCursor;

	delete oldCursor;

	return true;
}


void CMouseHandler::SafeDeleteCursor(CMouseCursor* cursor)
{
	std::map<std::string, CMouseCursor*>::iterator it;

	for (it = cursorCommandMap.begin(); it != cursorCommandMap.end(); ++it) {
		if (it->second == cursor) {
			return; // being used
		}
	}

	for (it = cursorFileMap.begin(); it != cursorFileMap.end(); ++it) {
		if (it->second == cursor) {
			cursorFileMap.erase(it);
			delete cursor;
			return;
		}
	}

	delete cursor;
}


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

⌨️ 快捷键说明

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