guihandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 2,423 行 · 第 1/5 页
CPP
2,423 行
}
}
depth--;
}
bool CGuiHandler::AboveGui(int x, int y)
{
if (iconsCount <= 0) {
return false;
}
if (!selectThrough) {
const float fx = MouseX(x);
const float fy = MouseY(y);
if ((fx > buttonBox.x1) && (fx < buttonBox.x2) &&
(fy > buttonBox.y1) && (fy < buttonBox.y2)) {
return true;
}
}
return (IconAtPos(x,y) >= 0);
}
void CGuiHandler::CreateOptions(Command& c, bool rmb)
{
c.options = 0;
if (rmb) {
c.options |= RIGHT_MOUSE_KEY;
}
if (GetQueueKeystate()) {
// allow mouse button 'rocker' movements to force
// immediate mode (when queuing is the default mode)
if (!invertQueueKey ||
(!mouse->buttons[SDL_BUTTON_LEFT].pressed &&
!mouse->buttons[SDL_BUTTON_RIGHT].pressed)) {
c.options |= SHIFT_KEY;
}
}
if (keys[SDLK_LCTRL]) {
c.options |= CONTROL_KEY;
}
if (keys[SDLK_LALT] || keys[SDLK_LMETA]) {
c.options |= ALT_KEY;
}
//logOutput << (int)c.options << "\n";
}
float CGuiHandler::GetNumberInput(const CommandDescription& cd) const
{
float minV = 0.0f;
float maxV = 100.0f;
if (cd.params.size() >= 1) { minV = atof(cd.params[0].c_str()); }
if (cd.params.size() >= 2) { maxV = atof(cd.params[1].c_str()); }
const int minX = (gu->viewSizeX * 1) / 4;
const int maxX = (gu->viewSizeX * 3) / 4;
const int effX = max(min(mouse->lastx, maxX), minX);
const float factor = float(effX - minX) / float(maxX - minX);
return (minV + (factor * (maxV - minV)));
}
int CGuiHandler::GetDefaultCommand(int x,int y) const
{
CInputReceiver* ir = NULL;
if (!game->hideInterface) {
ir = GetReceiverAt(x, y);
}
if ((ir != NULL) && (ir != minimap)) {
return -1;
}
CUnit* unit = NULL;
CFeature* feature = NULL;
if ((ir == minimap) && (minimap->FullProxy())) {
unit = minimap->GetSelectUnit(minimap->GetMapPosition(x, y));
}
else {
const float3 camPos = camera->pos;
const float3 camDir = mouse->dir;
const float viewRange = gu->viewRange*1.4f;
const float dist = helper->GuiTraceRay(camPos, camDir, viewRange, unit, 20, true);
const float dist2 = helper->GuiTraceRayFeature(camPos, camDir, viewRange, feature);
const float3 hit = camPos + camDir*dist;
// make sure the ray hit in the map
if (unit == NULL && (hit.x < 0.f || hit.x > gs->mapx*SQUARE_SIZE
|| hit.z < 0.f || hit.z > gs->mapy*SQUARE_SIZE))
return -1;
if ((dist > viewRange - 300) && (dist2 > viewRange - 300) && (unit == NULL)) {
return -1;
}
if (dist > dist2) {
unit = NULL;
} else {
feature = NULL;
}
}
// make sure the command is currently available
const int cmd_id = selectedUnits.GetDefaultCmd(unit, feature);
for (int c = 0; c < (int)commands.size(); c++) {
if (cmd_id == commands[c].id) {
return c;
}
}
return -1;
}
bool CGuiHandler::ProcessLocalActions(const CKeyBindings::Action& action)
{
// do not process these actions if the control panel is not visible
if (iconsCount <= 0) {
return false;
}
// only process the build options while building
// (conserve the keybinding space where we can)
if ((inCommand >= 0) && (inCommand < commands.size()) &&
(commands[inCommand].type == CMDTYPE_ICON_BUILDING)) {
if (ProcessBuildActions(action)) {
return true;
}
}
if (action.command == "buildiconsfirst") {
activePage = 0;
selectedUnits.SetCommandPage(activePage);
selectedUnits.ToggleBuildIconsFirst();
LayoutIcons(false);
return true;
}
else if (action.command == "firstmenu") {
activePage = 0;
selectedUnits.SetCommandPage(activePage);
return true;
}
else if (action.command == "hotbind") {
const int iconPos = IconAtPos(mouse->lastx, mouse->lasty);
const int iconCmd = (iconPos >= 0) ? icons[iconPos].commandsID : -1;
if ((iconCmd >= 0) && (iconCmd < commands.size())) {
game->SetHotBinding(commands[iconCmd].action);
}
return true;
}
else if (action.command == "hotunbind") {
const int iconPos = IconAtPos(mouse->lastx, mouse->lasty);
const int iconCmd = (iconPos >= 0) ? icons[iconPos].commandsID : -1;
if ((iconCmd >= 0) && (iconCmd < commands.size())) {
string cmd = "unbindaction " + commands[iconCmd].action;
keyBindings->Command(cmd);
logOutput.Print("%s", cmd.c_str());
}
return true;
}
else if (action.command == "showcommands") {
// bonus command for debugging
logOutput.Print("Available Commands:\n");
for(int i = 0; i < commands.size(); ++i){
logOutput.Print(" command: %i, id = %i, action = %s\n",
i, commands[i].id, commands[i].action.c_str());
}
// show the icon/command linkage
logOutput.Print("Icon Linkage:\n");
for(int ii = 0; ii < iconsCount; ++ii){
logOutput.Print(" icon: %i, commandsID = %i\n",
ii, icons[ii].commandsID);
}
logOutput.Print("maxPage = %i\n", maxPage);
logOutput.Print("activePage = %i\n", activePage);
logOutput.Print("iconsSize = %i\n", iconsSize);
logOutput.Print("iconsCount = %i\n", iconsCount);
logOutput.Print("commands.size() = %i\n", commands.size());
return true;
}
else if (action.command == "luaui") {
RunLayoutCommand(action.extra);
return true;
}
else if (action.command == "invqueuekey") {
if (action.extra.empty()) {
invertQueueKey = !invertQueueKey;
} else {
invertQueueKey = !!atoi(action.extra.c_str());
}
needShift = false;
configHandler.SetInt("InvertQueueKey", invertQueueKey ? 1 : 0);
return true;
}
return false;
}
void CGuiHandler::RunLayoutCommand(const string& command)
{
if (command.find("reload") == 0) {
if (CLuaHandle::GetActiveHandle() != NULL) {
// NOTE: causes a SEGV through RunCallIn()
logOutput.Print("Can not reload from within LuaUI, yet");
return;
}
if (luaUI == NULL) {
logOutput.Print("Loading: \"%s\"\n", luaUiFile);
CLuaUI::LoadHandler();
if (luaUI == NULL) {
LoadConfig("ctrlpanel.txt");
logOutput.Print("Loading failed\n");
}
} else {
logOutput.Print("Reloading: \"%s\"\n", luaUiFile);
CLuaUI::FreeHandler();
CLuaUI::LoadHandler();
if (luaUI == NULL) {
LoadConfig("ctrlpanel.txt");
logOutput.Print("Reloading failed\n");
}
}
}
else if (command == "disable") {
if (CLuaHandle::GetActiveHandle() != NULL) {
// NOTE: might cause a SEGV through RunCallIn()
logOutput.Print("Can not disable from within LuaUI, yet");
return;
}
if (luaUI != NULL) {
CLuaUI::FreeHandler();
LoadConfig("ctrlpanel.txt");
logOutput.Print("Disabled LuaUI\n");
}
}
else {
if (luaUI != NULL) {
luaUI->ConfigCommand(command);
} else {
logOutput.Print("LuaUI is not loaded\n");
}
}
LayoutIcons(false);
return;
}
bool CGuiHandler::ProcessBuildActions(const CKeyBindings::Action& action)
{
const string arg = StringToLower(action.extra);
if (action.command == "buildspacing") {
if (arg == "inc") {
buildSpacing++;
return true;
}
else if (arg == "dec") {
if (buildSpacing > 0) {
buildSpacing--;
}
return true;
}
}
else if (action.command == "buildfacing") {
const char* buildFaceDirs[] = { "South", "East", "North", "West" };
if (arg == "inc") {
buildFacing++;
if (buildFacing > 3) {
buildFacing = 0;
}
logOutput.Print("Buildings set to face %s", buildFaceDirs[buildFacing]);
return true;
}
else if (arg == "dec") {
buildFacing--;
if (buildFacing < 0) {
buildFacing = 3;
}
logOutput.Print("Buildings set to face %s", buildFaceDirs[buildFacing]);
return true;
}
else if (arg == "south") {
buildFacing = 0;
logOutput.Print("Buildings set to face South");
return true;
}
else if (arg == "east") {
buildFacing = 1;
logOutput.Print("Buildings set to face East");
return true;
}
else if (arg == "north") {
buildFacing = 2;
logOutput.Print("Buildings set to face North");
return true;
}
else if (arg == "west") {
buildFacing = 3;
logOutput.Print("Buildings set to face West");
return true;
}
}
return false;
}
int CGuiHandler::GetIconPosCommand(int slot) const
{
if (slot < 0) {
return -1;
}
const int iconPos = slot + (activePage * iconsPerPage);
if (iconPos < iconsCount) {
return icons[iconPos].commandsID;
}
return -1;
}
bool CGuiHandler::KeyPressed(unsigned short key, bool isRepeat)
{
if (luaUI != NULL) {
if (luaUI->KeyPress(key, isRepeat)) {
return true;
}
}
if (key == SDLK_ESCAPE && activeMousePress) {
activeMousePress = false;
inCommand = -1;
SetShowingMetal(false);
return true;
}
if (key == SDLK_ESCAPE && inCommand > 0) {
inCommand=-1;
SetShowingMetal(false);
return true;
}
CKeySet ks(key, false);
const CKeyBindings::ActionList& al = keyBindings->GetActionList(ks);
// setup actionOffset
int tmpActionOffset = actionOffset;
if ((inCommand < 0) || (lastKeySet.Key() < 0)){
actionOffset = 0;
tmpActionOffset = 0;
lastKeySet.Reset();
}
else if (!keyCodes->IsModifier(ks.Key()) &&
(ks.Key() != keyBindings->GetFakeMetaKey())) {
// not a modifier
if ((ks == lastKeySet) && (ks.Key() >= 0)) {
actionOffset++;
tmpActionOffset = actionOffset;
} else {
tmpActionOffset = 0;
}
}
for (int ali = 0; ali < (int)al.size(); ++ali) {
const int actionIndex = (ali + tmpActionOffset) % (int)al.size();
const CKeyBindings::Action& action = al[actionIndex];
if (SetActiveCommand(action, ks, actionIndex)) {
return true;
}
}
return false;
}
bool CGuiHandler::SetActiveCommand(const CKeyBindings::Action& action,
const CKeySet& ks, int actionIndex)
{
if (ProcessLocalActions(action)) {
return true;
}
// See if we have a positional icon command
int iconCmd = -1;
if (!action.extra.empty() && (action.command == "iconpos")) {
const int iconSlot = ParseIconSlot(action.extra);
iconCmd = GetIconPosCommand(iconSlot);
}
for (int a = 0; a < commands.size(); ++a) {
CommandDescription& cmdDesc = commands[a];
if ((a != iconCmd) && (cmdDesc.action != action.command)) {
continue; // not a match
}
if (cmdDesc.disabled) {
continue; // can not use this command
}
const int cmdType = cmdDesc.type;
// set the activePage
if (!cmdDesc.onlyKey &&
(((cmdType == CMDTYPE_ICON) &&
((cmdDesc.id < 0) ||
(cmdDesc.id == CMD_STOCKPILE))) ||
(cmdType == CMDTYPE_ICON_MODE) ||
(cmdType == CMDTYPE_ICON_BUILDING))) {
for (int ii = 0; ii < iconsCount; ii++) {
if (icons[ii].commandsID == a) {
activePage = min(maxPage, (ii / iconsPerPage));
selectedUnits.SetCommandPage(activePage);
}
}
}
switch (cmdType) {
case CMDTYPE_ICON:{
Command c;
c.options = 0;
c.id = cmdDesc.id;
if ((c.id < 0) || (c.id == CMD_STOCKPILE)) {
if (action.extra == "+5") {
c.options = SHIFT_KEY;
} else if (action.extra == "+20") {
c.options = CONTROL_KEY;
} else if (action.extra == "+100") {
c.options = SHIFT_KEY | CONTROL_KEY;
} else if (action.extra == "-1") {
c.options = RIGHT_MOUSE_KEY;
} else if (action.extra == "-5") {
c.options = RIGHT_MOUSE_KEY | SHIFT_KEY;
} else if (action.extra == "-20") {
c.options = RIGHT_MOUSE_KEY | CONTROL_KEY;
} else if (action.extra == "-100") {
c.options = RIGHT_MOUSE_KEY | SHIFT_KEY | CONTROL_KEY;
}
}
else if ((c.id == CMD_WAIT) || (c.id == CMD_SELFD)) {
if (action.extra.find("queued") != string::npos) {
c.options |= SHIFT_KEY;
}
}
GiveCommand(c);
break;
}
case CMDTYPE_ICON_MODE: {
int newMode;
if (!action.extra.empty() && (iconCmd < 0)) {
newMode = atoi(action.extra.c_str());
} else {
newMode = atoi(cmdDesc.params[0].c_str()) + 1;
}
if ((newMode < 0) || (newMode > (cmdDesc.params.size() - 2))) {
newMode = 0;
}
// not really required
char t[10];
SNPRINTF(t, 10, "%d", newMode);
cmdDesc.params[0] = t;
Command c;
c.options = 0;
c.id = cmdDesc.id;
c.params.push_back(newMode);
GiveCommand(c);
forceLayoutUpdate = true;
break;
}
case CMDTYPE_NUMBER:{
if (!action.extra.empty()) {
const CommandDescription& cd = cmdDesc;
float value = atof(action.extra.c_str());
float minV = 0.0f;
float maxV = 100.0f;
if (cd.params.size() >= 1) { minV = atof(cd.params[0].c_str()); }
if (cd.params.size() >= 2) { maxV = atof(cd.params[1].c_str()); }
value = max(min(value, maxV), minV);
Command c;
c.options = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?