-
commit 2da7acd2b3073da8e96a430cce61a37a4799705b
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 23 10:44:06 2012 +0200
This complements the last patch.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 8f58262..64259d5 100644
a
|
b
|
InReaction CGameView::HandleEvent(const SDL_Event_* ev)
|
1124 | 1124 | else if (hotkey == "click.left") |
1125 | 1125 | { |
1126 | 1126 | g_TouchInput.PressEvent(SDL_BUTTON_LEFT, g_mouse_x, g_mouse_y); |
| 1127 | return IN_HANDLED; |
1127 | 1128 | } |
1128 | 1129 | else if (hotkey == "click.right") |
1129 | 1130 | { |
1130 | 1131 | g_TouchInput.PressEvent(SDL_BUTTON_RIGHT, g_mouse_x, g_mouse_y); |
| 1132 | return IN_HANDLED; |
1131 | 1133 | } |
1132 | 1134 | } |
1133 | 1135 | |
-
commit 42b476aa1cca8ec7fc81eccbea8d5227848baea5
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 23 10:30:24 2012 +0200
Actually this is a better location for the button simulation events. Due
to the frequent call of Update() a click was always treated as doubleclick.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 542bec2..8f58262 100644
a
|
b
|
void CGameView::Update(const float deltaRealTime)
|
744 | 744 | moveRightward = moveForward = 0; |
745 | 745 | } |
746 | 746 | |
747 | | if (HotkeyIsPressed("click.left")) |
748 | | g_TouchInput.PressEvent(SDL_BUTTON_LEFT, g_mouse_x, g_mouse_y); |
749 | | else if (HotkeyIsPressed("click.right")) |
750 | | g_TouchInput.PressEvent(SDL_BUTTON_RIGHT, g_mouse_x, g_mouse_y); |
751 | | |
752 | 747 | if (g_Joystick.IsEnabled()) |
753 | 748 | { |
754 | 749 | // This could all be improved with extra speed and sensitivity settings |
… |
… |
InReaction CGameView::HandleEvent(const SDL_Event_* ev)
|
1126 | 1121 | ResetCameraAngleZoom(); |
1127 | 1122 | return IN_HANDLED; |
1128 | 1123 | } |
| 1124 | else if (hotkey == "click.left") |
| 1125 | { |
| 1126 | g_TouchInput.PressEvent(SDL_BUTTON_LEFT, g_mouse_x, g_mouse_y); |
| 1127 | } |
| 1128 | else if (hotkey == "click.right") |
| 1129 | { |
| 1130 | g_TouchInput.PressEvent(SDL_BUTTON_RIGHT, g_mouse_x, g_mouse_y); |
| 1131 | } |
1129 | 1132 | } |
1130 | 1133 | |
1131 | 1134 | return IN_PASS; |
-
commit 20cfa97a1857decb9f220438075047a973b3fb2b
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 23 02:03:23 2012 +0200
With this patch, when shift is pressed, or while building the A/W/D/S
hotkeys steer the location of the build site or mouse pointer. Z and C
act as left and right mouse buttons.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 6d9bfaa..55c4941 100644
a
|
b
|
hotkey.selection.group.select.9 = 9
|
193 | 193 | hotkey.selection.group.save.9 = "Ctrl+9" |
194 | 194 | hotkey.selection.group.add.9 = "Shift+9" |
195 | 195 | |
| 196 | ; action buttons |
196 | 197 | hotkey.selection.group.action.0 = G |
197 | 198 | hotkey.selection.group.action.1 = H |
198 | 199 | hotkey.selection.group.action.2 = J |
… |
… |
hotkey.selection.group.formation.0 = B
|
213 | 214 | hotkey.selection.group.garrison.0 = N |
214 | 215 | hotkey.selection.group.ungarrison.0 = M |
215 | 216 | |
| 217 | hotkey.click.left = "Z" |
| 218 | hotkey.click.right = "C" |
| 219 | |
216 | 220 | ; > SESSION CONTROLS |
217 | 221 | hotkey.session.kill = Delete ; Destroy selected units |
218 | 222 | hotkey.session.garrison = Ctrl ; Modifier to garrison when clicking on building |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index a2cdc0a..f4cc878 100644
a
|
b
|
function updateCursorAndTooltip()
|
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
| 107 | function CancelBuilding() { |
| 108 | placementSupport.Reset(); |
| 109 | Engine.EndPreview(); |
| 110 | } |
| 111 | |
107 | 112 | function updateBuildingPlacementPreview() |
108 | 113 | { |
109 | 114 | // The preview should be recomputed every turn, so that it responds to obstructions/fog/etc moving underneath it, or |
… |
… |
function tryPlaceBuilding(queued)
|
535 | 540 | // TODO: play a sound? |
536 | 541 | return false; |
537 | 542 | } |
| 543 | Engine.EndPreview(); |
538 | 544 | |
539 | 545 | // Start the construction |
540 | 546 | Engine.PostNetworkCommand({ |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
838 | 844 | case "mousebuttondown": |
839 | 845 | if (ev.button == SDL_BUTTON_RIGHT) |
840 | 846 | { |
841 | | // Cancel building |
842 | | placementSupport.Reset(); |
843 | | updateBuildingPlacementPreview(); |
844 | | |
| 847 | CancelBuilding(); |
845 | 848 | inputState = INPUT_NORMAL; |
846 | 849 | return true; |
847 | 850 | } |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
897 | 900 | |
898 | 901 | inputState = INPUT_BUILDING_WALL_CLICK; |
899 | 902 | } |
900 | | else |
901 | | { |
902 | | placementSupport.Reset(); |
| 903 | else |
| 904 | { |
| 905 | CancelBuilding(); |
903 | 906 | inputState = INPUT_NORMAL; |
904 | 907 | } |
905 | 908 | } |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
914 | 917 | else if (ev.button == SDL_BUTTON_RIGHT) |
915 | 918 | { |
916 | 919 | // reset to normal input mode |
917 | | placementSupport.Reset(); |
918 | | updateBuildingPlacementPreview(); |
| 920 | CancelBuilding(); |
919 | 921 | |
920 | 922 | inputState = INPUT_NORMAL; |
921 | 923 | return true; |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
982 | 984 | if (ev.button == SDL_BUTTON_RIGHT) |
983 | 985 | { |
984 | 986 | // Cancel building |
985 | | placementSupport.Reset(); |
| 987 | CancelBuilding(); |
986 | 988 | inputState = INPUT_NORMAL; |
987 | 989 | return true; |
988 | 990 | } |
… |
… |
function handleInputAfterGui(ev)
|
1162 | 1164 | else if (ev.button == SDL_BUTTON_RIGHT) |
1163 | 1165 | { |
1164 | 1166 | // Cancel building |
1165 | | placementSupport.Reset(); |
| 1167 | CancelBuilding(); |
1166 | 1168 | resetPreselectedAction(); |
1167 | 1169 | return true; |
1168 | 1170 | } |
… |
… |
function startBuildingPlacement(buildTemplate)
|
1402 | 1404 | // to start building a structure, then the highlight selection rings are kept during the construction of the building. |
1403 | 1405 | // Gives the impression that somehow the hovered-over entity has something to do with the building you're constructing. |
1404 | 1406 | |
1405 | | placementSupport.Reset(); |
| 1407 | CancelBuilding(); |
1406 | 1408 | |
1407 | 1409 | // find out if we're building a wall, and change the entity appropriately if so |
1408 | 1410 | var templateData = GetTemplateData(buildTemplate); |
-
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index bcba4bb..542bec2 100644
a
|
b
|
|
58 | 58 | #include "simulation2/Simulation2.h" |
59 | 59 | #include "simulation2/components/ICmpPosition.h" |
60 | 60 | #include "simulation2/components/ICmpRangeManager.h" |
| 61 | #include "simulation2/components/ICmpTemplateManager.h" |
61 | 62 | #include "lib/external_libraries/libsdl.h" |
62 | 63 | |
63 | 64 | extern int g_xres, g_yres; |
| 65 | extern CStrW g_CursorName; |
64 | 66 | |
65 | 67 | // Maximum distance outside the edge of the map that the camera's |
66 | 68 | // focus point can be moved |
… |
… |
void CGameView::Update(const float deltaRealTime)
|
737 | 739 | moveForward += m->ViewScrollSpeed * deltaRealTime; |
738 | 740 | if (HotkeyIsPressed("camera.down")) |
739 | 741 | moveForward -= m->ViewScrollSpeed * deltaRealTime; |
740 | | if (HotkeyIsPressed("session.queue")) { |
741 | | SDL_WarpMouse(g_mouse_x + moveRightward*2, g_mouse_y - moveForward*2); |
| 742 | if (ICmpTemplateManager::isPreviewActive || HotkeyIsPressed("session.queue")) { |
| 743 | SDL_WarpMouse(g_mouse_x + moveRightward*4, g_mouse_y - moveForward*4); |
742 | 744 | moveRightward = moveForward = 0; |
743 | 745 | } |
744 | 746 | |
| 747 | if (HotkeyIsPressed("click.left")) |
| 748 | g_TouchInput.PressEvent(SDL_BUTTON_LEFT, g_mouse_x, g_mouse_y); |
| 749 | else if (HotkeyIsPressed("click.right")) |
| 750 | g_TouchInput.PressEvent(SDL_BUTTON_RIGHT, g_mouse_x, g_mouse_y); |
| 751 | |
745 | 752 | if (g_Joystick.IsEnabled()) |
746 | 753 | { |
747 | 754 | // This could all be improved with extra speed and sensitivity settings |
-
diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp
index d2be90a..eacc01b 100644
a
|
b
|
|
51 | 51 | #include "simulation2/components/ICmpGuiInterface.h" |
52 | 52 | #include "simulation2/components/ICmpRangeManager.h" |
53 | 53 | #include "simulation2/components/ICmpTemplateManager.h" |
| 54 | #include "simulation2/components/CCmpTemplateManager.h" |
54 | 55 | #include "simulation2/components/ICmpSelectable.h" |
55 | 56 | #include "simulation2/helpers/Selection.h" |
56 | 57 | |
… |
… |
CScriptVal GetProfilerState(void* cbdata)
|
462 | 463 | return g_ProfileViewer.SaveToJS(guiManager->GetScriptInterface()); |
463 | 464 | } |
464 | 465 | |
| 466 | void EndPreview(void* UNUSED(cbdata)) |
| 467 | { |
| 468 | ICmpTemplateManager::isPreviewActive = false; |
| 469 | } |
| 470 | |
465 | 471 | |
466 | 472 | bool IsUserReportEnabled(void* UNUSED(cbdata)) |
467 | 473 | { |
… |
… |
void GuiScriptingInit(ScriptInterface& scriptInterface)
|
629 | 635 | scriptInterface.RegisterFunction<bool, std::string, &HotkeyIsPressed_>("HotkeyIsPressed"); |
630 | 636 | scriptInterface.RegisterFunction<void, std::wstring, &DisplayErrorDialog>("DisplayErrorDialog"); |
631 | 637 | scriptInterface.RegisterFunction<CScriptVal, &GetProfilerState>("GetProfilerState"); |
| 638 | scriptInterface.RegisterFunction<void, &EndPreview>("EndPreview"); |
632 | 639 | |
633 | 640 | // User report functions |
634 | 641 | scriptInterface.RegisterFunction<bool, &IsUserReportEnabled>("IsUserReportEnabled"); |
-
diff --git a/source/ps/TouchInput.cpp b/source/ps/TouchInput.cpp
index c9f2b80..3b4ff58 100644
a
|
b
|
void CTouchInput::OnFingerDown(int id, int x, int y)
|
78 | 78 | } |
79 | 79 | } |
80 | 80 | |
| 81 | void CTouchInput::PressEvent(int button, int x, int y) |
| 82 | { |
| 83 | SDL_Event_ ev; |
| 84 | ev.ev.button.button = button; |
| 85 | ev.ev.button.x = x; |
| 86 | ev.ev.button.y = y; |
| 87 | |
| 88 | ev.ev.type = SDL_MOUSEBUTTONDOWN; |
| 89 | ev.ev.button.state = SDL_PRESSED; |
| 90 | SDL_PushEvent(&ev.ev); |
| 91 | |
| 92 | ev.ev.type = SDL_MOUSEBUTTONUP; |
| 93 | ev.ev.button.state = SDL_RELEASED; |
| 94 | SDL_PushEvent(&ev.ev); |
| 95 | } |
| 96 | |
81 | 97 | void CTouchInput::OnFingerUp(int id, int x, int y) |
82 | 98 | { |
83 | 99 | debug_printf(L"finger up %d %d %d; state %d\n", id, x, y, m_State); |
… |
… |
void CTouchInput::OnFingerUp(int id, int x, int y)
|
87 | 103 | if (m_State == STATE_FIRST_TOUCH && id == 0 && timer_Time() < m_FirstTouchTime + 0.5) |
88 | 104 | { |
89 | 105 | m_State = STATE_INACTIVE; |
90 | | |
91 | | SDL_Event_ ev; |
92 | | ev.ev.button.button = SDL_BUTTON_LEFT; |
93 | | ev.ev.button.x = m_Pos[0].X; |
94 | | ev.ev.button.y = m_Pos[0].Y; |
95 | | |
96 | | ev.ev.type = SDL_MOUSEBUTTONDOWN; |
97 | | ev.ev.button.state = SDL_PRESSED; |
98 | | SDL_PushEvent(&ev.ev); |
99 | | |
100 | | ev.ev.type = SDL_MOUSEBUTTONUP; |
101 | | ev.ev.button.state = SDL_RELEASED; |
102 | | SDL_PushEvent(&ev.ev); |
| 106 | PressEvent(SDL_BUTTON_LEFT, m_Pos[0].X, m_Pos[0].Y); |
103 | 107 | } |
104 | 108 | else if (m_State == STATE_ZOOMING && id == 1) |
105 | 109 | { |
… |
… |
void CTouchInput::Frame()
|
166 | 170 | if (m_State == STATE_FIRST_TOUCH && t > m_FirstTouchTime + 1.0) |
167 | 171 | { |
168 | 172 | m_State = STATE_INACTIVE; |
169 | | |
170 | | SDL_Event_ ev; |
171 | | ev.ev.button.button = SDL_BUTTON_RIGHT; |
172 | | ev.ev.button.x = m_Pos[0].X; |
173 | | ev.ev.button.y = m_Pos[0].Y; |
174 | | |
175 | | ev.ev.type = SDL_MOUSEBUTTONDOWN; |
176 | | ev.ev.button.state = SDL_PRESSED; |
177 | | SDL_PushEvent(&ev.ev); |
178 | | |
179 | | ev.ev.type = SDL_MOUSEBUTTONUP; |
180 | | ev.ev.button.state = SDL_RELEASED; |
181 | | SDL_PushEvent(&ev.ev); |
| 173 | PressEvent(SDL_BUTTON_RIGHT, m_Pos[0].X, m_Pos[0].Y); |
182 | 174 | } |
183 | 175 | } |
184 | 176 | |
-
diff --git a/source/ps/TouchInput.h b/source/ps/TouchInput.h
index 876ed20..2d9ff7b 100644
a
|
b
|
|
28 | 28 | */ |
29 | 29 | class CTouchInput |
30 | 30 | { |
| 31 | friend class CGameView; |
31 | 32 | public: |
32 | 33 | CTouchInput(); |
33 | 34 | ~CTouchInput(); |
… |
… |
private:
|
48 | 49 | void OnFingerDown(int id, int x, int y); |
49 | 50 | void OnFingerUp(int id, int x, int y); |
50 | 51 | void OnFingerMotion(int id, int x, int y); |
| 52 | void PressEvent(int, int, int); |
51 | 53 | |
52 | 54 | // Mouse emulation state: |
53 | 55 | enum |
-
diff --git a/source/simulation2/components/CCmpTemplateManager.cpp b/source/simulation2/components/CCmpTemplateManager.cpp
index d69cc36..f25bff4 100644
a
|
b
|
std::string CCmpTemplateManager::GetCurrentTemplateName(entity_id_t ent)
|
261 | 261 | |
262 | 262 | bool CCmpTemplateManager::LoadTemplateFile(const std::string& templateName, int depth) |
263 | 263 | { |
| 264 | if (templateName.find("preview|") == 0) |
| 265 | ICmpTemplateManager::isPreviewActive = true; |
| 266 | |
264 | 267 | // If this file was already loaded, we don't need to do anything |
265 | 268 | if (m_TemplateFileData.find(templateName) != m_TemplateFileData.end()) |
266 | 269 | return true; |
-
diff --git a/source/simulation2/components/ICmpTemplateManager.cpp b/source/simulation2/components/ICmpTemplateManager.cpp
index 6792180..3acd67e 100644
a
|
b
|
|
21 | 21 | |
22 | 22 | #include "simulation2/system/InterfaceScripted.h" |
23 | 23 | |
| 24 | bool ICmpTemplateManager::isPreviewActive = false; |
| 25 | |
24 | 26 | BEGIN_INTERFACE_WRAPPER(TemplateManager) |
25 | 27 | DEFINE_INTERFACE_METHOD_1("GetTemplate", const CParamNode*, ICmpTemplateManager, GetTemplate, std::string) |
26 | 28 | DEFINE_INTERFACE_METHOD_1("GetCurrentTemplateName", std::string, ICmpTemplateManager, GetCurrentTemplateName, entity_id_t) |
-
diff --git a/source/simulation2/components/ICmpTemplateManager.h b/source/simulation2/components/ICmpTemplateManager.h
index 1a4ffbb..0b21c89 100644
a
|
b
|
public:
|
115 | 115 | * their new CParamNode), then automatically updating this.template of scripted components. |
116 | 116 | */ |
117 | 117 | |
| 118 | /* |
| 119 | * is true if there is currently a preview active. |
| 120 | */ |
| 121 | static bool isPreviewActive; |
| 122 | |
118 | 123 | DECLARE_INTERFACE_TYPE(TemplateManager) |
119 | 124 | }; |
120 | 125 | |
-
commit 692949243792b178d429ae5cd3207aa043fbd4c1
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Fri Jun 22 20:33:22 2012 +0200
decrease indentation (no functional change)
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp
index bfb1282..f0ec3f1 100644
a
|
b
|
static void LoadConfigBindings()
|
74 | 74 | for( CConfigValueSet::iterator it = bindingsIt->second.begin(); it != bindingsIt->second.end(); ++it ) |
75 | 75 | { |
76 | 76 | std::string hotkey; |
77 | | if( it->GetString( hotkey ) ) |
78 | | { |
79 | | std::vector<SKey> keyCombination; |
80 | | |
81 | | CParserLine multikeyIdentifier; |
82 | | multikeyIdentifier.ParseString( multikeyParser, hotkey ); |
83 | | |
84 | | // Iterate through multiple-key bindings (e.g. Ctrl+I) |
| 77 | if( !it->GetString( hotkey ) ) |
| 78 | continue; |
85 | 79 | |
86 | | bool negateNext = false; |
| 80 | std::vector<SKey> keyCombination; |
87 | 81 | |
88 | | for( size_t t = 0; t < multikeyIdentifier.GetArgCount(); t++ ) |
89 | | { |
| 82 | CParserLine multikeyIdentifier; |
| 83 | multikeyIdentifier.ParseString( multikeyParser, hotkey ); |
90 | 84 | |
91 | | if( multikeyIdentifier.GetArgString( (int)t, hotkey ) ) |
92 | | { |
93 | | if( hotkey == "_negate" ) |
94 | | { |
95 | | negateNext = true; |
96 | | continue; |
97 | | } |
| 85 | // Iterate through multiple-key bindings (e.g. Ctrl+I) |
98 | 86 | |
99 | | // Attempt decode as key name |
100 | | int mapping = FindKeyCode( hotkey ); |
| 87 | bool negateNext = false; |
101 | 88 | |
102 | | // Attempt to decode as a negation of a keyname |
103 | | // Yes, it's going a bit far, perhaps. |
104 | | // Too powerful for most uses, probably. |
105 | | // However, it got some hardcoding out of the engine. |
106 | | // Thus it makes me happy. |
| 89 | for( size_t t = 0; t < multikeyIdentifier.GetArgCount(); t++ ) |
| 90 | { |
| 91 | if( !multikeyIdentifier.GetArgString( (int)t, hotkey ) ) |
| 92 | continue; |
107 | 93 | |
108 | | if( !mapping ) |
109 | | { |
110 | | LOGWARNING(L"Hotkey mapping used invalid key '%hs'", hotkey.c_str() ); |
111 | | continue; |
112 | | } |
| 94 | if( hotkey == "_negate" ) |
| 95 | { |
| 96 | negateNext = true; |
| 97 | continue; |
| 98 | } |
113 | 99 | |
114 | | SKey key = { (SDLKEY)mapping, negateNext }; |
115 | | keyCombination.push_back(key); |
| 100 | // Attempt decode as key name |
| 101 | int mapping = FindKeyCode( hotkey ); |
116 | 102 | |
117 | | negateNext = false; |
| 103 | // Attempt to decode as a negation of a keyname |
| 104 | // Yes, it's going a bit far, perhaps. |
| 105 | // Too powerful for most uses, probably. |
| 106 | // However, it got some hardcoding out of the engine. |
| 107 | // Thus it makes me happy. |
118 | 108 | |
119 | | } |
| 109 | if( !mapping ) |
| 110 | { |
| 111 | LOGWARNING(L"Hotkey mapping used invalid key '%hs'", hotkey.c_str() ); |
| 112 | continue; |
120 | 113 | } |
121 | 114 | |
122 | | std::vector<SKey>::iterator itKey, itKey2; |
| 115 | SKey key = { (SDLKEY)mapping, negateNext }; |
| 116 | keyCombination.push_back(key); |
123 | 117 | |
124 | | for( itKey = keyCombination.begin(); itKey != keyCombination.end(); ++itKey ) |
125 | | { |
126 | | SHotkeyMapping bindCode; |
| 118 | negateNext = false; |
| 119 | } |
127 | 120 | |
128 | | bindCode.name = hotkeyName; |
129 | | bindCode.negated = itKey->negated; |
| 121 | std::vector<SKey>::iterator itKey, itKey2; |
130 | 122 | |
131 | | for( itKey2 = keyCombination.begin(); itKey2 != keyCombination.end(); ++itKey2 ) |
132 | | { |
133 | | // Push any auxiliary keys. |
134 | | if( itKey != itKey2 ) |
135 | | bindCode.requires.push_back( *itKey2 ); |
136 | | } |
| 123 | for( itKey = keyCombination.begin(); itKey != keyCombination.end(); ++itKey ) |
| 124 | { |
| 125 | SHotkeyMapping bindCode; |
137 | 126 | |
138 | | g_HotkeyMap[itKey->code].push_back( bindCode ); |
| 127 | bindCode.name = hotkeyName; |
| 128 | bindCode.negated = itKey->negated; |
| 129 | |
| 130 | for( itKey2 = keyCombination.begin(); itKey2 != keyCombination.end(); ++itKey2 ) |
| 131 | { |
| 132 | // Push any auxiliary keys. |
| 133 | if( itKey != itKey2 ) |
| 134 | bindCode.requires.push_back( *itKey2 ); |
139 | 135 | } |
| 136 | |
| 137 | g_HotkeyMap[itKey->code].push_back( bindCode ); |
140 | 138 | } |
141 | 139 | } |
142 | 140 | } |
-
commit ee6f4c47b12346c7cea449b45cf651e8ffec4c71
Merge: 044c58a 1d0a7c8
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Fri Jun 22 18:27:59 2012 +0200
Merge branch 'master' of git://gitorious.org/0ad/0ad
commit 044c58a829c704157bdb14fbbdcd643dd14cb15c
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Thu Jun 21 01:08:42 2012 +0200
With shift button ASWD move the mouse cursor, e.g. useful for building
placement
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 0062b44..bcba4bb 100644
a
|
b
|
|
58 | 58 | #include "simulation2/Simulation2.h" |
59 | 59 | #include "simulation2/components/ICmpPosition.h" |
60 | 60 | #include "simulation2/components/ICmpRangeManager.h" |
| 61 | #include "lib/external_libraries/libsdl.h" |
61 | 62 | |
62 | 63 | extern int g_xres, g_yres; |
63 | 64 | |
… |
… |
void CGameView::Update(const float deltaRealTime)
|
736 | 737 | moveForward += m->ViewScrollSpeed * deltaRealTime; |
737 | 738 | if (HotkeyIsPressed("camera.down")) |
738 | 739 | moveForward -= m->ViewScrollSpeed * deltaRealTime; |
| 740 | if (HotkeyIsPressed("session.queue")) { |
| 741 | SDL_WarpMouse(g_mouse_x + moveRightward*2, g_mouse_y - moveForward*2); |
| 742 | moveRightward = moveForward = 0; |
| 743 | } |
739 | 744 | |
740 | 745 | if (g_Joystick.IsEnabled()) |
741 | 746 | { |
-
commit 23689b0de0482557d0419b2b1024b983695fa8d8
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Tue Jun 19 22:21:27 2012 +0200
pushing the buttons sent it into band-boxing
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 4889b79..a2cdc0a 100644
a
|
b
|
function performCommand(entity, commandName)
|
1540 | 1540 | openDeleteDialog(selection); |
1541 | 1541 | break; |
1542 | 1542 | case "garrison": |
1543 | | inputState = INPUT_SELECTING; |
| 1543 | inputState = INPUT_PRESELECTEDACTION; |
1544 | 1544 | preSelectedAction = ACTION_GARRISON; |
1545 | 1545 | break; |
1546 | 1546 | case "repair": |
1547 | | inputState = INPUT_SELECTING; |
| 1547 | inputState = INPUT_PRESELECTEDACTION; |
1548 | 1548 | preSelectedAction = ACTION_BUILD; |
1549 | 1549 | break; |
1550 | 1550 | case "unload-all": |
-
commit 72653544c017a44fe52df44c87c4f4af386962d5
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Tue Jun 19 22:20:01 2012 +0200
fixes buttons after a recent commit
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 58b6f9d..a55a7bd 100644
a
|
b
|
|
776 | 776 | <object name="unitCommandPanel" |
777 | 777 | size="0 100%-36 100% 100%-4" |
778 | 778 | type="image" |
779 | | z="30" |
| 779 | z="50" |
780 | 780 | > |
781 | 781 | <object size="0 0 100% 100%"> |
782 | 782 | <repeat count="6"> |
-
commit b8af7852f082c7f288904468d306cf66e226a40e
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Tue Jun 19 17:57:17 2012 +0200
reapply these changes for find idle unit hotkeys and friends
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 3ff530a..58b6f9d 100644
a
|
b
|
|
85 | 85 | </object> |
86 | 86 | |
87 | 87 | <!-- Find idle warrior - TODO: Potentially move this to own UI button? --> |
88 | | <object hotkey="selection.idlewarrior"> |
89 | | <action on="Press">findIdleUnit(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action> |
90 | | </object> |
| 88 | <object hotkey="selection.idlewarrior"> |
| 89 | <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"], 1);</action> |
| 90 | </object> |
| 91 | |
| 92 | <!-- Select civilcenter --> |
| 93 | <object hotkey="selection.civilcenter"> |
| 94 | <action on="Press">findEntity(["CivCentre"], 0);</action> |
| 95 | </object> |
| 96 | <!-- Select market --> |
| 97 | <object hotkey="selection.market"> |
| 98 | <action on="Press">findEntity(["BarterMarket", "Market", "NavalMarket"], 0);</action> |
| 99 | </object> |
| 100 | <!-- Select dropsitefood --> |
| 101 | <object hotkey="selection.dropsitefood"> |
| 102 | <action on="Press">findEntity(["CivCentre", "DropsiteFood"], 0);</action> |
| 103 | </object> |
| 104 | <!-- Select dropsitewood --> |
| 105 | <object hotkey="selection.dropsiteres"> |
| 106 | <action on="Press">findEntity(["CivCentre", "DropsiteWood", "DropsiteStone", "DropsiteMetal"], 0);</action> |
| 107 | </object> |
| 108 | <!-- Select structure --> |
| 109 | <object hotkey="selection.structure"> |
| 110 | <action on="Press">findEntity(["Structure"], 0);</action> |
| 111 | </object> |
91 | 112 | |
92 | 113 | <!-- ================================ ================================ --> |
93 | 114 | <!-- Developer / Debug items --> |
… |
… |
|
527 | 548 | > |
528 | 549 | <!-- TODO: should highlight the button if there's non-zero idle workers --> |
529 | 550 | <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" /> |
530 | | <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> |
| 551 | <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"], 1);</action> |
531 | 552 | </object> |
532 | 553 | </object> |
533 | 554 | </object> |
… |
… |
|
586 | 607 | </repeat> |
587 | 608 | </object> |
588 | 609 | </object> |
589 | | |
590 | 610 | <!-- Stance Selection --> |
591 | 611 | <object name="unitStancePanel" |
592 | 612 | style="TranslucentPanel" |
-
commit 28f4c47308285284a095b152881f75022c09f7a2
Merge: 4953e92 78a92ff
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Tue Jun 19 17:49:39 2012 +0200
Merge branch 'master' of git://gitorious.org/0ad/0ad
Conflicts:
binaries/data/mods/public/gui/session/session.xml
commit 4953e92e36023c2839617f99ac10b0207de580c6
Merge: 6ab9e41 4d551ff
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Mon Jun 18 20:16:29 2012 +0200
Merge branch 'master' of git://gitorious.org/0ad/0ad
Conflicts:
binaries/data/mods/public/gui/session/session.xml
commit 6ab9e4126e9d27531f2ce9e92799d02bf591ee33
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 17 23:45:42 2012 +0200
There's no need to cast to float and then back again to uint
Don't calculate average height in every iteration
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp
index f05da71..237b502 100644
a
|
b
|
|
44 | 44 | |
45 | 45 | bool g_GameRestarted = false; |
46 | 46 | |
47 | | static unsigned int ScaleColor(unsigned int color, float x) |
| 47 | static unsigned int ScaleColor(unsigned int color, unsigned int val, unsigned int div) |
48 | 48 | { |
49 | | unsigned int r = unsigned(float(color & 0xff) * x); |
50 | | unsigned int g = unsigned(float((color>>8) & 0xff) * x); |
51 | | unsigned int b = unsigned(float((color>>16) & 0xff) * x); |
| 49 | unsigned int r = (color & 0xff) * val / div; |
| 50 | unsigned int g = ((color>>8) & 0xff) * val / div; |
| 51 | unsigned int b = ((color>>16) & 0xff) * val / div; |
52 | 52 | return (0xff000000 | r | g<<8 | b<<16); |
53 | 53 | } |
54 | 54 | |
… |
… |
void CMiniMap::RebuildTerrainTexture()
|
483 | 483 | u32 y = 0; |
484 | 484 | u32 w = m_MapSize - 1; |
485 | 485 | u32 h = m_MapSize - 1; |
486 | | float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight; |
| 486 | float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight * 4.0f; |
487 | 487 | |
488 | 488 | m_TerrainDirty = false; |
489 | 489 | |
… |
… |
void CMiniMap::RebuildTerrainTexture()
|
492 | 492 | u32 *dataPtr = m_TerrainData + ((y + j) * (m_MapSize - 1)) + x; |
493 | 493 | for(u32 i = 0; i < w; i++) |
494 | 494 | { |
495 | | float avgHeight = ( m_Terrain->GetVertexGroundLevel((int)i, (int)j) |
| 495 | float avgHeight = m_Terrain->GetVertexGroundLevel((int)i, (int)j) |
496 | 496 | + m_Terrain->GetVertexGroundLevel((int)i+1, (int)j) |
497 | 497 | + m_Terrain->GetVertexGroundLevel((int)i, (int)j+1) |
498 | | + m_Terrain->GetVertexGroundLevel((int)i+1, (int)j+1) |
499 | | ) / 4.0f; |
| 498 | + m_Terrain->GetVertexGroundLevel((int)i+1, (int)j+1); |
500 | 499 | |
501 | 500 | if(avgHeight < waterHeight) |
502 | 501 | { |
… |
… |
void CMiniMap::RebuildTerrainTexture()
|
525 | 524 | } |
526 | 525 | } |
527 | 526 | |
528 | | *dataPtr++ = ScaleColor(color, float(val) / 255.0f); |
| 527 | *dataPtr++ = ScaleColor(color, val, 255); |
529 | 528 | } |
530 | 529 | } |
531 | 530 | } |
-
commit 3057bbac81a788796465daa2a85179cef1b56370
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 17 09:44:08 2012 +0200
The fall trough causes obj.caption to be overwritten
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js
index d77b4c9..b681ac9 100644
a
|
b
|
function handleNetMessage(message)
|
90 | 90 | case "connected": |
91 | 91 | obj.caption = "Connected to the server."; |
92 | 92 | obj.hidden = false; |
| 93 | break; |
93 | 94 | case "authenticated": |
94 | 95 | obj.caption = "Connection to the server has been authenticated."; |
95 | 96 | obj.hidden = false; |
| 97 | break; |
96 | 98 | case "disconnected": |
97 | 99 | obj.caption = "Connection to the server has been lost.\n\nThe game has ended."; |
98 | 100 | obj.hidden = false; |
-
commit 4824e759a2f2af86ca012c8d156abc8e143c0dc5
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 16 23:19:21 2012 +0200
_len == _max is out of bounds for _data[]
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/libraries/spidermonkey/include-win32/js/jstracer.h b/libraries/spidermonkey/include-win32/js/jstracer.h
index 76921cc..bd992c2 100644
a
|
b
|
public:
|
106 | 106 | |
107 | 107 | void add(T a) { |
108 | 108 | ensure(_len + 1); |
109 | | JS_ASSERT(_len <= _max); |
| 109 | JS_ASSERT(_len < _max); |
110 | 110 | _data[_len++] = a; |
111 | 111 | } |
112 | 112 | |
113 | 113 | void add(T* chunk, unsigned size) { |
114 | 114 | ensure(_len + size); |
115 | | JS_ASSERT(_len <= _max); |
| 115 | JS_ASSERT(_len < _max); |
116 | 116 | memcpy(&_data[_len], chunk, size * sizeof(T)); |
117 | 117 | _len += size; |
118 | 118 | } |
-
commit 27fb5efe94c15254701744292c7f9d8dab37db5d
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 16 16:25:50 2012 +0200
this patch implements double click of . for select all villagers. Same
goes for comma and friends.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 743bdf8..4889b79 100644
a
|
b
|
function determineAction(x, y, fromMinimap)
|
467 | 467 | { |
468 | 468 | target = targets[0]; |
469 | 469 | } |
| 470 | if (Engine.HotkeyIsPressed("session.garrison")) |
| 471 | preSelectedAction = ACTION_GARRISON; |
470 | 472 | |
471 | | if (preSelectedAction != ACTION_NONE) |
| 473 | if (preSelectedAction & (ACTION_GARRISON|ACTION_BUILD)) |
472 | 474 | { |
473 | 475 | switch (preSelectedAction) |
474 | 476 | { |
… |
… |
function determineAction(x, y, fromMinimap)
|
486 | 488 | break; |
487 | 489 | } |
488 | 490 | } |
489 | | else if (Engine.HotkeyIsPressed("session.garrison") || preSelectedAction == ACTION_GARRISON) |
490 | | { |
491 | | if (getActionInfo("garrison", target).possible) |
492 | | return {"type": "garrison", "cursor": "action-garrison", "target": target}; |
493 | | else |
494 | | return {"type": "none", "cursor": "action-garrison-disabled", "target": undefined}; |
495 | | } |
496 | 491 | else |
497 | 492 | { |
498 | 493 | var actionInfo = undefined; |
… |
… |
function handleInputAfterGui(ev)
|
1123 | 1118 | resetPreselectedAction(); |
1124 | 1119 | return true; |
1125 | 1120 | } |
1126 | | |
1127 | 1121 | var selectedEntity = ents[0]; |
1128 | | var now = new Date(); |
1129 | 1122 | |
1130 | 1123 | // If camera following and we select different unit, stop |
1131 | 1124 | if (Engine.GetFollowedEntity() != selectedEntity) |
1132 | 1125 | { |
1133 | 1126 | Engine.CameraFollow(0); |
1134 | 1127 | } |
1135 | | |
1136 | | if ((now.getTime() - doubleClickTimer < doubleClickTime) && (selectedEntity == prevClickedEntity)) |
1137 | | { |
1138 | | // Double click or triple click has occurred |
1139 | | var showOffscreen = Engine.HotkeyIsPressed("selection.offscreen"); |
1140 | | var matchRank = true; |
1141 | | var templateToMatch; |
1142 | | |
1143 | | // Check for double click or triple click |
1144 | | if (!doubleClicked) |
1145 | | { |
1146 | | // If double click hasn't already occurred, this is a double click. |
1147 | | // Select similar units regardless of rank |
1148 | | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).identity.selectionGroupName; |
1149 | | if (templateToMatch) |
1150 | | { |
1151 | | matchRank = false; |
1152 | | } |
1153 | | else |
1154 | | { // No selection group name defined, so fall back to exact match |
1155 | | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).template; |
1156 | | } |
1157 | | |
1158 | | doubleClicked = true; |
1159 | | // Reset the timer so the user has an extra period 'doubleClickTimer' to do a triple-click |
1160 | | doubleClickTimer = now.getTime(); |
1161 | | } |
1162 | | else |
1163 | | { |
1164 | | // Double click has already occurred, so this is a triple click. |
1165 | | // Select units matching exact template name (same rank) |
1166 | | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).template; |
1167 | | } |
1168 | | |
1169 | | // TODO: Should we handle "control all units" here as well? |
1170 | | ents = Engine.PickSimilarFriendlyEntities(templateToMatch, showOffscreen, matchRank, false); |
1171 | | } |
1172 | | else |
1173 | | { |
1174 | | // It's single click right now but it may become double or triple click |
1175 | | doubleClicked = false; |
1176 | | doubleClickTimer = now.getTime(); |
1177 | | prevClickedEntity = selectedEntity; |
1178 | | |
1179 | | // We only want to include the first picked unit in the selection |
1180 | | ents = [ents[0]]; |
1181 | | } |
1182 | | |
1183 | | // Update the list of selected units |
1184 | | if (Engine.HotkeyIsPressed("selection.add")) |
1185 | | { |
1186 | | g_Selection.addList(ents); |
1187 | | } |
1188 | | else if (Engine.HotkeyIsPressed("selection.remove")) |
1189 | | { |
1190 | | g_Selection.removeList(ents); |
1191 | | } |
1192 | | else |
1193 | | { |
1194 | | g_Selection.reset(); |
1195 | | g_Selection.addList(ents); |
1196 | | } |
1197 | | resetPreselectedAction(); |
| 1128 | ClickSelected(ents, (selectedEntity == prevClickedEntity)); |
1198 | 1129 | return true; |
1199 | 1130 | } |
1200 | 1131 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1262 | 1193 | return false; |
1263 | 1194 | } |
1264 | 1195 | |
| 1196 | function ClickSelected(ents, is_same) |
| 1197 | { |
| 1198 | var selectedEntity = ents[0]; |
| 1199 | var now = new Date(); |
| 1200 | |
| 1201 | if ((now.getTime() - doubleClickTimer < doubleClickTime) && is_same) |
| 1202 | { |
| 1203 | // Double click or triple click has occurred |
| 1204 | var showOffscreen = Engine.HotkeyIsPressed("selection.offscreen"); |
| 1205 | var matchRank = true; |
| 1206 | var templateToMatch; |
| 1207 | |
| 1208 | // Check for double click or triple click |
| 1209 | if (!doubleClicked) |
| 1210 | { |
| 1211 | // If double click hasn't already occurred, this is a double click. |
| 1212 | // Select similar units regardless of rank |
| 1213 | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).identity.selectionGroupName; |
| 1214 | if (templateToMatch) |
| 1215 | { |
| 1216 | matchRank = false; |
| 1217 | } |
| 1218 | else |
| 1219 | { // No selection group name defined, so fall back to exact match |
| 1220 | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).template; |
| 1221 | } |
| 1222 | |
| 1223 | doubleClicked = true; |
| 1224 | // Reset the timer so the user has an extra period 'doubleClickTimer' to do a triple-click |
| 1225 | doubleClickTimer = now.getTime(); |
| 1226 | } |
| 1227 | else |
| 1228 | { |
| 1229 | // Double click has already occurred, so this is a triple click. |
| 1230 | // Select units matching exact template name (same rank) |
| 1231 | templateToMatch = Engine.GuiInterfaceCall("GetEntityState", selectedEntity).template; |
| 1232 | } |
| 1233 | |
| 1234 | // TODO: Should we handle "control all units" here as well? |
| 1235 | ents = Engine.PickSimilarFriendlyEntities(templateToMatch, showOffscreen, matchRank, false); |
| 1236 | } |
| 1237 | else |
| 1238 | { |
| 1239 | // It's single click right now but it may become double or triple click |
| 1240 | doubleClicked = false; |
| 1241 | doubleClickTimer = now.getTime(); |
| 1242 | prevClickedEntity = selectedEntity; |
| 1243 | |
| 1244 | // We only want to include the first picked unit in the selection |
| 1245 | ents = [ents[0]]; |
| 1246 | } |
| 1247 | |
| 1248 | // Update the list of selected units |
| 1249 | if (Engine.HotkeyIsPressed("selection.add")) |
| 1250 | { |
| 1251 | g_Selection.addList(ents); |
| 1252 | } |
| 1253 | else if (Engine.HotkeyIsPressed("selection.remove")) |
| 1254 | { |
| 1255 | g_Selection.removeList(ents); |
| 1256 | } |
| 1257 | else |
| 1258 | { |
| 1259 | g_Selection.reset(); |
| 1260 | g_Selection.addList(ents); |
| 1261 | } |
| 1262 | resetPreselectedAction(); |
| 1263 | } |
| 1264 | |
1265 | 1265 | function doAction(action, ev) |
1266 | 1266 | { |
1267 | 1267 | var selection = g_Selection.toList(); |
… |
… |
function findAllVisibleEntities(classes, mode)
|
1910 | 1910 | } |
1911 | 1911 | } |
1912 | 1912 | |
| 1913 | // mode 0 is to search for idle, 1 to search for any |
1913 | 1914 | function findEntity(classes, mode) |
1914 | 1915 | { |
1915 | 1916 | var queued = Engine.HotkeyIsPressed("session.queue"); |
… |
… |
function findEntity(classes, mode)
|
1918 | 1919 | return; |
1919 | 1920 | } |
1920 | 1921 | var player = Engine.GetPlayerID(); |
| 1922 | |
1921 | 1923 | // Cycle through idling classes before giving up |
1922 | 1924 | for (var i = 0; i <= classes.length; ++i) |
1923 | 1925 | { |
… |
… |
function findEntity(classes, mode)
|
1929 | 1931 | resetPreselectedAction(); |
1930 | 1932 | else if (preSelectedAction == ACTION_BUILD) |
1931 | 1933 | updateBuildingPlacementPreview(); |
1932 | | |
1933 | 1934 | lastEntity = newEntity; |
1934 | | g_Selection.reset(); |
1935 | | g_Selection.addList([lastEntity]); |
1936 | | Engine.CameraFollow(lastEntity); |
| 1935 | ClickSelected([newEntity], 1); |
1937 | 1936 | return; |
1938 | 1937 | } |
1939 | 1938 | lastEntity = 0; |
-
commit 8667be2fa976064e67569141734d319c8401d385
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Thu Jun 14 00:54:35 2012 +0200
This implements the V, B, N and M hotkeys for
Stance, Formation, garrison, ungarrison respectively
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 5015b15..9e7c9aa 100644
a
|
b
|
hotkey.selection.group.action.10 = "Ctrl+K"
|
203 | 203 | hotkey.selection.group.action.11 = "Ctrl+L" |
204 | 204 | hotkey.selection.group.action.12 = "Ctrl+Semicolon" |
205 | 205 | hotkey.selection.group.action.13 = "Ctrl+SingleQuote" |
206 | | hotkey.selection.group.action.reset = ForwardSlash |
| 206 | hotkey.selection.group.reset.0 = ForwardSlash |
| 207 | hotkey.selection.group.stance.0 = V |
| 208 | hotkey.selection.group.formation.0 = B |
| 209 | hotkey.selection.group.garrison.0 = N |
| 210 | hotkey.selection.group.ungarrison.0 = M |
207 | 211 | |
208 | 212 | ; > SESSION CONTROLS |
209 | 213 | hotkey.session.kill = Delete ; Destroy selected units |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index adb7bb5..743bdf8 100644
a
|
b
|
const INPUT_BATCHTRAINING = 6;
|
35 | 35 | const INPUT_PRESELECTEDACTION = 7; |
36 | 36 | const INPUT_BUILDING_WALL_CLICK = 8; |
37 | 37 | const INPUT_BUILDING_WALL_PATHING = 9; |
| 38 | const INPUT_ACTION_STATE = 10; |
38 | 39 | |
39 | 40 | var inputState = INPUT_NORMAL; |
40 | 41 | var placementSupport = new PlacementSupport(); |
… |
… |
function handleInputAfterGui(ev)
|
1028 | 1029 | switch (inputState) |
1029 | 1030 | { |
1030 | 1031 | case INPUT_NORMAL: |
| 1032 | case INPUT_ACTION_STATE: |
1031 | 1033 | switch (ev.type) |
1032 | 1034 | { |
1033 | 1035 | case "mousemotion": |
… |
… |
function performCommand(entity, commandName)
|
1538 | 1540 | openDeleteDialog(selection); |
1539 | 1541 | break; |
1540 | 1542 | case "garrison": |
1541 | | inputState = INPUT_PRESELECTEDACTION; |
| 1543 | inputState = INPUT_SELECTING; |
1542 | 1544 | preSelectedAction = ACTION_GARRISON; |
1543 | 1545 | break; |
1544 | 1546 | case "repair": |
1545 | | inputState = INPUT_PRESELECTEDACTION; |
| 1547 | inputState = INPUT_SELECTING; |
1546 | 1548 | preSelectedAction = ACTION_BUILD; |
1547 | 1549 | break; |
1548 | 1550 | case "unload-all": |
… |
… |
function handleHotkey(ev)
|
1593 | 1595 | { |
1594 | 1596 | var sptr = ev.hotkey.split("."); |
1595 | 1597 | var now = new Date(); |
1596 | | if (inputState = INPUT_NORMAL && (ev.hotkey == prevHotkey) && |
| 1598 | if ((inputState == INPUT_NORMAL) && (ev.hotkey == prevHotkey) && |
1597 | 1599 | ev.hotkey.indexOf("selection.group.select.") == 0 && |
1598 | 1600 | (now.getTime() - doublePressTimer < doublePressTime)) { |
1599 | 1601 | performGroup("snap", sptr[3]); |
… |
… |
function handleHotkey(ev)
|
1608 | 1610 | } |
1609 | 1611 | |
1610 | 1612 | // Performs the specified group |
1611 | | function performGroup(action, nr) |
| 1613 | function performGroup(action, x) |
1612 | 1614 | { |
1613 | | if (nr == "reset") |
1614 | | { |
1615 | | resetPreselectedAction(); |
1616 | | return; |
1617 | | } |
1618 | 1615 | switch (action) |
1619 | 1616 | { |
1620 | 1617 | case "snap": |
… |
… |
function performGroup(action, nr)
|
1622 | 1619 | case "add": |
1623 | 1620 | var toSelect = []; |
1624 | 1621 | g_Groups.update(); |
1625 | | for (var ent in g_Groups.groups[nr].ents) |
| 1622 | for (var ent in g_Groups.groups[x].ents) |
1626 | 1623 | toSelect.push(+ent); |
1627 | 1624 | |
1628 | 1625 | if (action != "add") |
… |
… |
function performGroup(action, nr)
|
1632 | 1629 | |
1633 | 1630 | if (action == "snap" && toSelect.length) |
1634 | 1631 | Engine.CameraFollow(toSelect[0]); |
1635 | | break; |
| 1632 | return; |
1636 | 1633 | case "save": |
1637 | 1634 | var selection = g_Selection.toList(); |
1638 | | g_Groups.groups[nr].reset(); |
1639 | | g_Groups.addEntities(nr, selection); |
| 1635 | g_Groups.groups[x].reset(); |
| 1636 | g_Groups.addEntities(x, selection); |
1640 | 1637 | updateGroups(); |
1641 | | break; |
| 1638 | return; |
1642 | 1639 | case "action": |
1643 | 1640 | var selection = g_Selection.toList(); |
1644 | 1641 | var player = Engine.GetPlayerID(); |
| 1642 | if (inputState != INPUT_ACTION_STATE) |
| 1643 | preSelectedAction = getDefaultActionForSelection(player, selection); |
| 1644 | break; |
| 1645 | case "reset": |
| 1646 | resetPreselectedAction(); |
| 1647 | return; |
| 1648 | case "garrison": |
| 1649 | preSelectedAction = ACTION_GARRISON; |
| 1650 | inputState = INPUT_PRESELECTEDACTION; |
| 1651 | return; |
| 1652 | case "ungarrison": |
| 1653 | preSelectedAction = ACTION_UNGARRISON; |
| 1654 | inputState = INPUT_ACTION_STATE; |
| 1655 | return; |
| 1656 | case "stance": |
| 1657 | preSelectedAction = ACTION_STANCE; |
| 1658 | inputState = INPUT_ACTION_STATE; |
| 1659 | return; |
| 1660 | case "formation": |
| 1661 | preSelectedAction = ACTION_FORMATION; |
| 1662 | inputState = INPUT_ACTION_STATE; |
| 1663 | return; |
| 1664 | } |
| 1665 | if (inputState == INPUT_ACTION_STATE) |
| 1666 | inputState = INPUT_NORMAL; |
| 1667 | if (preSelectedAction == ACTION_NONE) |
| 1668 | return; |
1645 | 1669 | |
1646 | | preSelectedAction = getDefaultActionForSelection(player, selection); |
1647 | | if (preSelectedAction == ACTION_NONE) |
1648 | | break; |
| 1670 | var lst = selectAction(player, selection); |
| 1671 | if (!lst) // shouldn't happen |
| 1672 | return; |
1649 | 1673 | |
1650 | | var lst = selectAction(player, selection); |
1651 | | if (!lst) // shouldn't happen |
1652 | | break; |
| 1674 | if (preSelectedAction & ACTION_GARRISON) |
| 1675 | { |
| 1676 | if (++x > lst.length) |
| 1677 | x = lst.length; |
| 1678 | } else if (preSelectedAction != ACTION_UNGARRISON) { |
| 1679 | if (x >= lst.length) |
| 1680 | return; |
| 1681 | lst = lst[x]; |
| 1682 | } |
1653 | 1683 | |
1654 | | if (preSelectedAction & ACTION_GARRISON) |
1655 | | { |
1656 | | if (++nr > lst.length) |
1657 | | nr = lst.length; |
1658 | | } else if (preSelectedAction != ACTION_UNGARRISON) { |
1659 | | if (nr >= lst.length) |
1660 | | break; |
1661 | | lst = lst[nr]; |
| 1684 | switch (preSelectedAction) |
| 1685 | { |
| 1686 | case ACTION_BUILD: |
| 1687 | var tmpl = GetTemplateData(lst); |
| 1688 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1689 | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
| 1690 | startBuildingPlacement(lst); |
| 1691 | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
| 1692 | initBuildingPlacementView(); |
1662 | 1693 | } |
1663 | | |
1664 | | switch (preSelectedAction) |
1665 | | { |
1666 | | case ACTION_BUILD: |
1667 | | var tmpl = GetTemplateData(lst); |
1668 | | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
1669 | | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
1670 | | startBuildingPlacement(lst); |
1671 | | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
1672 | | initBuildingPlacementView(); |
1673 | | } |
1674 | | break; |
1675 | | case ACTION_TRAIN: |
1676 | | var tmpl = GetTemplateData(lst); |
1677 | | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
1678 | | var ents = g_Selection.toList(); |
1679 | | addTrainingToQueue(ents, lst); |
1680 | | } |
1681 | | break; |
1682 | | case ACTION_GARRISON: // we garison nr+1 count |
1683 | | g_Selection.reset(); |
1684 | | lst.splice(nr, lst.length - nr) |
1685 | | g_Selection.addList(lst); |
1686 | | inputState = INPUT_PRESELECTEDACTION; |
1687 | | break; |
1688 | | case ACTION_UNGARRISON: |
1689 | | if (lst.length > 1 || nr == 0) { |
1690 | | if (nr >= lst.length) |
1691 | | nr = lst.length - 1; |
1692 | | if (lst.length != 1 && nr == 0) { |
1693 | | // unload all from all buildings |
1694 | | for each (var gh in lst) |
1695 | | unloadAll(gh); |
1696 | | } else { |
1697 | | if (lst.length != 1) |
1698 | | nr--; |
1699 | | unloadAll(lst[nr]); |
1700 | | } |
1701 | | g_Selection.reset(); |
1702 | | break; |
| 1694 | break; |
| 1695 | case ACTION_TRAIN: |
| 1696 | var tmpl = GetTemplateData(lst); |
| 1697 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1698 | var ents = g_Selection.toList(); |
| 1699 | addTrainingToQueue(ents, lst); |
| 1700 | } |
| 1701 | break; |
| 1702 | case ACTION_GARRISON: // we garison x+1 count |
| 1703 | g_Selection.reset(); |
| 1704 | lst.splice(x, lst.length - x) |
| 1705 | g_Selection.addList(lst); |
| 1706 | inputState = INPUT_PRESELECTEDACTION; |
| 1707 | break; |
| 1708 | case ACTION_UNGARRISON: |
| 1709 | if (lst.length > 1 || x == 0) { |
| 1710 | if (x >= lst.length) |
| 1711 | x = lst.length - 1; |
| 1712 | if (lst.length != 1 && x == 0) { |
| 1713 | // unload all from all buildings |
| 1714 | for each (var gh in lst) |
| 1715 | unloadAll(gh); |
1703 | 1716 | } else { |
1704 | | lst = lst[0]; |
1705 | | var state = GetEntityState(lst); |
1706 | | var gents = state.garrisonHolder.entities; |
1707 | | if (nr > gents.length) |
1708 | | nr = gents.length; |
1709 | | while (nr--) |
1710 | | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[nr]], "garrisonHolder": lst}); |
1711 | | // we could assign a key to follow them here |
1712 | | break; |
| 1717 | if (lst.length != 1) |
| 1718 | x--; |
| 1719 | unloadAll(lst[x]); |
1713 | 1720 | } |
1714 | | break; |
1715 | | case ACTION_FORMATION: |
1716 | | ents = g_Selection.toList(); |
1717 | | var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", { |
1718 | | "ents": g_Selection.toList(), |
1719 | | "formationName": lst |
1720 | | }); |
1721 | | if (formationOk) |
1722 | | performFormation(ents, lst); |
1723 | | break |
1724 | | case ACTION_STANCE: |
1725 | | ents = g_Selection.toList(); |
1726 | | performStance(ents, lst); |
1727 | | break; |
1728 | | case ACTION_BARTER: //TODO |
1729 | | break; |
1730 | | case ACTION_TRADER: //TODO |
1731 | | break; |
| 1721 | g_Selection.reset(); |
| 1722 | } else { |
| 1723 | lst = lst[0]; |
| 1724 | var state = GetEntityState(lst); |
| 1725 | var gents = state.garrisonHolder.entities; |
| 1726 | if (x > gents.length) |
| 1727 | x = gents.length; |
| 1728 | while (x--) |
| 1729 | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[x]], "garrisonHolder": lst}); |
| 1730 | // we could assign a key to follow them here |
1732 | 1731 | } |
1733 | 1732 | break; |
| 1733 | case ACTION_FORMATION: |
| 1734 | ents = g_Selection.toList(); |
| 1735 | var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", { |
| 1736 | "ents": g_Selection.toList(), |
| 1737 | "formationName": lst |
| 1738 | }); |
| 1739 | if (formationOk) |
| 1740 | performFormation(ents, lst); |
| 1741 | break |
| 1742 | case ACTION_STANCE: |
| 1743 | ents = g_Selection.toList(); |
| 1744 | performStance(ents, lst); |
| 1745 | break; |
| 1746 | case ACTION_BARTER: //TODO |
| 1747 | break; |
| 1748 | case ACTION_TRADER: //TODO |
| 1749 | break; |
1734 | 1750 | } |
1735 | 1751 | } |
1736 | 1752 | |
1737 | 1753 | // This returns a list of actions. Caller still has to check Technology availability |
1738 | 1754 | function selectAction(player, selection) |
1739 | 1755 | { |
1740 | | var ret = []; |
1741 | 1756 | if (preSelectedAction == ACTION_FORMATION) |
1742 | | { |
1743 | 1757 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
1744 | | } else if (preSelectedAction == ACTION_STANCE) |
1745 | | { |
| 1758 | else if (preSelectedAction == ACTION_STANCE) |
1746 | 1759 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1747 | | } |
| 1760 | |
| 1761 | var ret = []; |
1748 | 1762 | for each (var ent in selection) |
1749 | 1763 | { |
1750 | 1764 | var state = GetEntityState(ent); |
-
commit 286f76f2aa3bf8259fe4de6edb279e89d6215484
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 23:41:05 2012 +0200
don't mix up function argument and global
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 37508f3..adb7bb5 100644
a
|
b
|
function handleInputAfterGui(ev)
|
1066 | 1066 | switch (ev.type) |
1067 | 1067 | { |
1068 | 1068 | case "mousebuttondown": |
1069 | | if (ev.button == SDL_BUTTON_LEFT && preSelectedAction) |
| 1069 | if (ev.button == SDL_BUTTON_LEFT && preSelectedAction != ACTION_NONE) |
1070 | 1070 | { |
1071 | 1071 | var action = determineAction(ev.x, ev.y); |
1072 | 1072 | resetPreselectedAction(); |
… |
… |
function performGroup(action, nr)
|
1647 | 1647 | if (preSelectedAction == ACTION_NONE) |
1648 | 1648 | break; |
1649 | 1649 | |
1650 | | var lst = selectAction(player, selection, action); |
| 1650 | var lst = selectAction(player, selection); |
1651 | 1651 | if (!lst) // shouldn't happen |
1652 | 1652 | break; |
1653 | 1653 | |
… |
… |
function performGroup(action, nr)
|
1734 | 1734 | } |
1735 | 1735 | } |
1736 | 1736 | |
1737 | | function selectAction(player, selection, action) |
| 1737 | // This returns a list of actions. Caller still has to check Technology availability |
| 1738 | function selectAction(player, selection) |
1738 | 1739 | { |
1739 | 1740 | var ret = []; |
1740 | | if (action == ACTION_FORMATION) |
| 1741 | if (preSelectedAction == ACTION_FORMATION) |
1741 | 1742 | { |
1742 | 1743 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
1743 | | } else if (action == ACTION_STANCE) |
| 1744 | } else if (preSelectedAction == ACTION_STANCE) |
1744 | 1745 | { |
1745 | 1746 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1746 | 1747 | } |
… |
… |
function selectAction(player, selection, action)
|
1786 | 1787 | return ret; |
1787 | 1788 | } |
1788 | 1789 | |
1789 | | // This returns a list of actions. Caller still has to check Technology availability |
1790 | 1790 | function getDefaultActionForSelection(player, selection) |
1791 | 1791 | { |
1792 | 1792 | var action; |
… |
… |
function findEntity(classes, mode)
|
1911 | 1911 | var newEntity = Engine.GuiInterfaceCall("FindEntity", data); |
1912 | 1912 | if (newEntity && newEntity != lastEntity) |
1913 | 1913 | { |
1914 | | if (!selectAction(player, [newEntity], preSelectedAction).length) |
| 1914 | if (!selectAction(player, [newEntity]).length) |
1915 | 1915 | resetPreselectedAction(); |
1916 | 1916 | else if (preSelectedAction == ACTION_BUILD) |
1917 | 1917 | updateBuildingPlacementPreview(); |
-
commit 92ad5f0b42b98f9d7beae0c884af378a99bc60e9
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 23:31:36 2012 +0200
reorder a bit (no functional change)
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 7e12d39..37508f3 100644
a
|
b
|
function handleInputAfterGui(ev)
|
1057 | 1057 | break; |
1058 | 1058 | |
1059 | 1059 | case "hotkeydown": |
1060 | | if (ev.hotkey && ev.hotkey.indexOf("selection.group.") == 0) |
1061 | | { |
1062 | | var sptr = ev.hotkey.split("."); |
1063 | | var now = new Date(); |
1064 | | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey) && ev.hotkey.indexOf("selection.group.select.") == 0) { |
1065 | | performGroup("snap", sptr[3]); |
1066 | | } |
1067 | | else |
1068 | | { |
1069 | | performGroup(sptr[2], sptr[3]); |
1070 | | |
1071 | | doublePressTimer = now.getTime(); |
1072 | | prevHotkey = ev.hotkey; |
1073 | | } |
1074 | | } |
| 1060 | handleHotkey(ev); |
1075 | 1061 | break; |
1076 | 1062 | } |
1077 | 1063 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1094 | 1080 | break; |
1095 | 1081 | } |
1096 | 1082 | case "hotkeydown": |
1097 | | if (ev.hotkey && ev.hotkey.indexOf("selection.group.action.") == 0) |
1098 | | { |
1099 | | var sptr = ev.hotkey.split("."); |
1100 | | performGroup(sptr[2], sptr[3]); |
1101 | | } |
| 1083 | handleHotkey(ev); |
1102 | 1084 | break; |
1103 | 1085 | default: |
1104 | 1086 | // Slight hack: If selection is empty, reset the input state |
… |
… |
function handleInputAfterGui(ev)
|
1268 | 1250 | updateBuildingPlacementPreview(); |
1269 | 1251 | break; |
1270 | 1252 | default: |
1271 | | if (ev.hotkey.indexOf("selection.group.action.") == 0) |
1272 | | { // can switch buildings |
1273 | | var sptr = ev.hotkey.split("."); |
1274 | | performGroup(sptr[2], sptr[3]); |
1275 | | } |
| 1253 | handleHotkey(ev); // to switch buildings |
1276 | 1254 | } |
1277 | 1255 | break; |
1278 | 1256 | |
… |
… |
function performFormation(entity, formationName)
|
1609 | 1587 | } |
1610 | 1588 | } |
1611 | 1589 | |
1612 | | function selectAction(player, selection, action) |
| 1590 | function handleHotkey(ev) |
1613 | 1591 | { |
1614 | | var ret = []; |
1615 | | if (action == ACTION_FORMATION) |
1616 | | { |
1617 | | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
1618 | | } else if (action == ACTION_STANCE) |
1619 | | { |
1620 | | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1621 | | } |
1622 | | for each (var ent in selection) |
| 1592 | if (ev.hotkey && ev.hotkey.indexOf("selection.group.") == 0) |
1623 | 1593 | { |
1624 | | var state = GetEntityState(ent); |
1625 | | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
1626 | | continue; |
1627 | | |
1628 | | switch (preSelectedAction) |
| 1594 | var sptr = ev.hotkey.split("."); |
| 1595 | var now = new Date(); |
| 1596 | if (inputState = INPUT_NORMAL && (ev.hotkey == prevHotkey) && |
| 1597 | ev.hotkey.indexOf("selection.group.select.") == 0 && |
| 1598 | (now.getTime() - doublePressTimer < doublePressTime)) { |
| 1599 | performGroup("snap", sptr[3]); |
| 1600 | } |
| 1601 | else |
1629 | 1602 | { |
1630 | | case ACTION_GARRISON: |
1631 | | if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder)) { |
1632 | | inputState = INPUT_PRESELECTEDACTION; |
1633 | | ret.push(ent); |
1634 | | } |
1635 | | break; |
1636 | | case ACTION_BUILD: |
1637 | | if (state.buildEntities && state.buildEntities.length) { |
1638 | | if (inputState != INPUT_BUILDING_PLACEMENT) |
1639 | | inputState = INPUT_PRESELECTEDACTION; |
1640 | | return state.buildEntities; |
1641 | | } |
1642 | | break; |
1643 | | case ACTION_TRAIN: |
1644 | | if (state.production && state.production.entities.length) |
1645 | | return state.production.entities; |
1646 | | break; |
1647 | | case ACTION_UNGARRISON: |
1648 | | if (state.garrisonHolder && state.garrisonHolder.entities && state.garrisonHolder.entities.length) |
1649 | | ret.push(ent); |
1650 | | break; |
1651 | | case ACTION_BARTER: |
1652 | | if (state.barterMarket) |
1653 | | ret.push(ent); |
1654 | | break; |
1655 | | case ACTION_TRADER: |
1656 | | if (state.trader) |
1657 | | ret.push([ent, state]); |
1658 | | break; |
| 1603 | performGroup(sptr[2], sptr[3]); |
| 1604 | doublePressTimer = now.getTime(); |
| 1605 | prevHotkey = ev.hotkey; |
1659 | 1606 | } |
1660 | 1607 | } |
1661 | | return ret; |
1662 | | } |
1663 | | |
1664 | | // This returns a list of actions. Caller still has to check Technology availability |
1665 | | function getDefaultActionForSelection(player, selection) |
1666 | | { |
1667 | | var action; |
1668 | | var count = 0; |
1669 | | for each (var ent in selection) |
1670 | | { |
1671 | | var state = GetEntityState(ent); |
1672 | | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
1673 | | continue; |
1674 | | |
1675 | | if (state.buildEntities && state.buildEntities.length) |
1676 | | return ACTION_BUILD; // by default |
1677 | | |
1678 | | if (state.production && state.production.entities.length) |
1679 | | action |= ACTION_TRAIN; |
1680 | | else if (!hasClass(state, "Unit") || hasClass(state, "Animal") || |
1681 | | !state.garrisonHolder) { |
1682 | | if (++count > 1) //only works with at least two units |
1683 | | action |= ACTION_FORMATION; |
1684 | | } else if (state.barterMarket) |
1685 | | action |= ACTION_BARTER; |
1686 | | else if (state.trader) |
1687 | | action |= ACTION_TRADER; |
1688 | | } |
1689 | | if (action & ACTION_TRAIN) |
1690 | | return ACTION_TRAIN; |
1691 | | else if (action & ACTION_FORMATION) |
1692 | | return ACTION_FORMATION; |
1693 | | else if (action & ACTION_BARTER) { |
1694 | | setupUnitBarterPanel(state); |
1695 | | return ACTION_BARTER; |
1696 | | } else if (action & ACTION_TRADER) { |
1697 | | setupUnitTradingPanel(state, selection); |
1698 | | return ACTION_TRADER; |
1699 | | } |
1700 | | return 0; //shouldn't happen |
1701 | 1608 | } |
1702 | 1609 | |
1703 | 1610 | // Performs the specified group |
… |
… |
function performGroup(action, nr)
|
1827 | 1734 | } |
1828 | 1735 | } |
1829 | 1736 | |
| 1737 | function selectAction(player, selection, action) |
| 1738 | { |
| 1739 | var ret = []; |
| 1740 | if (action == ACTION_FORMATION) |
| 1741 | { |
| 1742 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
| 1743 | } else if (action == ACTION_STANCE) |
| 1744 | { |
| 1745 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
| 1746 | } |
| 1747 | for each (var ent in selection) |
| 1748 | { |
| 1749 | var state = GetEntityState(ent); |
| 1750 | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
| 1751 | continue; |
| 1752 | |
| 1753 | switch (preSelectedAction) |
| 1754 | { |
| 1755 | case ACTION_GARRISON: |
| 1756 | if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder)) { |
| 1757 | inputState = INPUT_PRESELECTEDACTION; |
| 1758 | ret.push(ent); |
| 1759 | } |
| 1760 | break; |
| 1761 | case ACTION_BUILD: |
| 1762 | if (state.buildEntities && state.buildEntities.length) { |
| 1763 | if (inputState != INPUT_BUILDING_PLACEMENT) |
| 1764 | inputState = INPUT_PRESELECTEDACTION; |
| 1765 | return state.buildEntities; |
| 1766 | } |
| 1767 | break; |
| 1768 | case ACTION_TRAIN: |
| 1769 | if (state.production && state.production.entities.length) |
| 1770 | return state.production.entities; |
| 1771 | break; |
| 1772 | case ACTION_UNGARRISON: |
| 1773 | if (state.garrisonHolder && state.garrisonHolder.entities && state.garrisonHolder.entities.length) |
| 1774 | ret.push(ent); |
| 1775 | break; |
| 1776 | case ACTION_BARTER: |
| 1777 | if (state.barterMarket) |
| 1778 | ret.push(ent); |
| 1779 | break; |
| 1780 | case ACTION_TRADER: |
| 1781 | if (state.trader) |
| 1782 | ret.push([ent, state]); |
| 1783 | break; |
| 1784 | } |
| 1785 | } |
| 1786 | return ret; |
| 1787 | } |
| 1788 | |
| 1789 | // This returns a list of actions. Caller still has to check Technology availability |
| 1790 | function getDefaultActionForSelection(player, selection) |
| 1791 | { |
| 1792 | var action; |
| 1793 | var count = 0; |
| 1794 | for each (var ent in selection) |
| 1795 | { |
| 1796 | var state = GetEntityState(ent); |
| 1797 | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
| 1798 | continue; |
| 1799 | |
| 1800 | if (state.buildEntities && state.buildEntities.length) |
| 1801 | return ACTION_BUILD; // by default |
| 1802 | |
| 1803 | if (state.production && state.production.entities.length) |
| 1804 | action |= ACTION_TRAIN; |
| 1805 | else if (!hasClass(state, "Unit") || hasClass(state, "Animal") || |
| 1806 | !state.garrisonHolder) { |
| 1807 | if (++count > 1) //only works with at least two units |
| 1808 | action |= ACTION_FORMATION; |
| 1809 | } else if (state.barterMarket) |
| 1810 | action |= ACTION_BARTER; |
| 1811 | else if (state.trader) |
| 1812 | action |= ACTION_TRADER; |
| 1813 | } |
| 1814 | if (action & ACTION_TRAIN) |
| 1815 | return ACTION_TRAIN; |
| 1816 | else if (action & ACTION_FORMATION) |
| 1817 | return ACTION_FORMATION; |
| 1818 | else if (action & ACTION_BARTER) { |
| 1819 | setupUnitBarterPanel(state); |
| 1820 | return ACTION_BARTER; |
| 1821 | } else if (action & ACTION_TRADER) { |
| 1822 | setupUnitTradingPanel(state, selection); |
| 1823 | return ACTION_TRADER; |
| 1824 | } |
| 1825 | return 0; //shouldn't happen |
| 1826 | } |
| 1827 | |
1830 | 1828 | // Performs the specified stance |
1831 | 1829 | function performStance(entity, stanceName) |
1832 | 1830 | { |
-
commit a459d5e2b2413a021e01bb7dd9ef4f16468778b3
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 23:25:14 2012 +0200
Generalize All unloaded following
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 8897d01..7e12d39 100644
a
|
b
|
function handleInputBeforeGui(ev, hoveredObject)
|
666 | 666 | mouseY = ev.y; |
667 | 667 | break; |
668 | 668 | } |
669 | | if (followQueue.lenght) |
| 669 | if (followQueue.length) |
670 | 670 | { |
671 | 671 | var gents = followQueue; |
672 | 672 | var state = GetEntityState(gents[0]); |
673 | | // FIXME this stalls until the selection actually occurs |
674 | 673 | if (state.visibility == "hidden") |
675 | 674 | return true; |
676 | 675 | Engine.CameraFollow(0); |
677 | 676 | Engine.CameraFollow(gents[0]); |
678 | 677 | g_Selection.addList(gents); |
679 | 678 | resetPreselectedAction(); |
680 | | followQueue = []; |
| 679 | followQueue = []; // for next time. |
681 | 680 | } |
682 | 681 | // Remember whether the mouse is over a GUI object or not |
683 | 682 | mouseIsOverObject = (hoveredObject != null); |
… |
… |
function performGroup(action, nr)
|
1784 | 1783 | if (nr >= lst.length) |
1785 | 1784 | nr = lst.length - 1; |
1786 | 1785 | if (lst.length != 1 && nr == 0) { |
1787 | | followQueue = []; |
1788 | 1786 | // unload all from all buildings |
1789 | | for each (var gh in lst) { |
1790 | | var s = GetEntityState(gh); |
1791 | | var gs = s.garrisonHolder.entities; |
1792 | | followQueue = followQueue.concat(gs); |
| 1787 | for each (var gh in lst) |
1793 | 1788 | unloadAll(gh); |
1794 | | } |
1795 | 1789 | } else { |
1796 | 1790 | if (lst.length != 1) |
1797 | 1791 | nr--; |
1798 | | lst = lst[nr]; |
1799 | | |
1800 | | var state = GetEntityState(lst); |
1801 | | var gents = state.garrisonHolder.entities; |
1802 | | followQueue = gents; |
1803 | | unloadAll(lst); |
| 1792 | unloadAll(lst[nr]); |
1804 | 1793 | } |
1805 | 1794 | g_Selection.reset(); |
1806 | 1795 | break; |
… |
… |
function unload(garrisonHolder, entities)
|
1953 | 1942 | |
1954 | 1943 | function unloadAll(garrisonHolder) |
1955 | 1944 | { |
| 1945 | var state = GetEntityState(garrisonHolder); |
| 1946 | var gents = state.garrisonHolder.entities; |
| 1947 | followQueue = followQueue.concat(gents); |
1956 | 1948 | Engine.PostNetworkCommand({"type": "unload-all", "garrisonHolder": garrisonHolder}); |
1957 | 1949 | } |
-
commit b89368e8dede26f9b2a412c1c62bde5aceefed9a
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 22:45:44 2012 +0200
This patch makes a default choice active. e.g. for a worker the default
action is to build, for a building to train. keys G to singlequote are
implemented as choices. Setting non-default options aren't available
anymore but a next patch will implement hotkeys for that.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index eb6d59a..8897d01 100644
a
|
b
|
const ACTION_BARTER = 64;
|
23 | 23 | const ACTION_TRADER =128; |
24 | 24 | var preSelectedAction = ACTION_NONE; |
25 | 25 | |
26 | | // N.B. reset this after selecting different units or buildings |
27 | | var _optionsOfpreSelected = []; |
| 26 | var followQueue = []; |
28 | 27 | |
29 | 28 | const INPUT_NORMAL = 0; |
30 | 29 | const INPUT_SELECTING = 1; |
… |
… |
const INPUT_BATCHTRAINING = 6;
|
36 | 35 | const INPUT_PRESELECTEDACTION = 7; |
37 | 36 | const INPUT_BUILDING_WALL_CLICK = 8; |
38 | 37 | const INPUT_BUILDING_WALL_PATHING = 9; |
39 | | const INPUT_FOLLOW_UNGARRISON = 10; |
40 | 38 | |
41 | 39 | var inputState = INPUT_NORMAL; |
42 | 40 | var placementSupport = new PlacementSupport(); |
… |
… |
function resetPreselectedAction()
|
188 | 186 | { |
189 | 187 | preSelectedAction = ACTION_NONE; |
190 | 188 | inputState = INPUT_NORMAL; |
191 | | _optionsOfpreSelected = []; |
192 | 189 | placementSupport.Reset(); // or a hotkey may leave a building snapshot |
193 | 190 | updateCursorAndTooltip(); |
194 | 191 | |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
669 | 666 | mouseY = ev.y; |
670 | 667 | break; |
671 | 668 | } |
672 | | if (inputState == INPUT_FOLLOW_UNGARRISON) |
| 669 | if (followQueue.lenght) |
673 | 670 | { |
674 | | var gents = _optionsOfpreSelected; |
| 671 | var gents = followQueue; |
675 | 672 | var state = GetEntityState(gents[0]); |
676 | 673 | // FIXME this stalls until the selection actually occurs |
677 | 674 | if (state.visibility == "hidden") |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
680 | 677 | Engine.CameraFollow(gents[0]); |
681 | 678 | g_Selection.addList(gents); |
682 | 679 | resetPreselectedAction(); |
| 680 | followQueue = []; |
683 | 681 | } |
684 | 682 | // Remember whether the mouse is over a GUI object or not |
685 | 683 | mouseIsOverObject = (hoveredObject != null); |
… |
… |
function handleInputAfterGui(ev)
|
1044 | 1042 | return false; |
1045 | 1043 | |
1046 | 1044 | case "mousebuttondown": |
1047 | | _optionsOfpreSelected = []; |
1048 | 1045 | if (ev.button == SDL_BUTTON_LEFT) |
1049 | 1046 | { |
1050 | 1047 | dragStart = [ ev.x, ev.y ]; |
… |
… |
function handleInputAfterGui(ev)
|
1245 | 1242 | placementSupport.position = Engine.GetTerrainAtScreenPoint(ev.x, ev.y); |
1246 | 1243 | dragStart = [ ev.x, ev.y ]; |
1247 | 1244 | inputState = INPUT_BUILDING_CLICK; |
1248 | | _optionsOfpreSelected = []; |
1249 | 1245 | } |
1250 | 1246 | return true; |
1251 | 1247 | } |
… |
… |
function performFormation(entity, formationName)
|
1614 | 1610 | } |
1615 | 1611 | } |
1616 | 1612 | |
1617 | | // This returns a list of actions. Caller still has to check Technology availability |
1618 | | function getActionForSelection(player, selection) |
| 1613 | function selectAction(player, selection, action) |
1619 | 1614 | { |
1620 | 1615 | var ret = []; |
1621 | | |
| 1616 | if (action == ACTION_FORMATION) |
| 1617 | { |
| 1618 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
| 1619 | } else if (action == ACTION_STANCE) |
| 1620 | { |
| 1621 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
| 1622 | } |
1622 | 1623 | for each (var ent in selection) |
1623 | 1624 | { |
1624 | 1625 | var state = GetEntityState(ent); |
… |
… |
function getActionForSelection(player, selection)
|
1648 | 1649 | if (state.garrisonHolder && state.garrisonHolder.entities && state.garrisonHolder.entities.length) |
1649 | 1650 | ret.push(ent); |
1650 | 1651 | break; |
1651 | | case ACTION_FORMATION: |
1652 | | case ACTION_STANCE: |
1653 | | if (!hasClass(state, "Unit") || hasClass(state, "Animal") || state.garrisonHolder) |
1654 | | break; |
1655 | | |
1656 | | if (preSelectedAction == ACTION_STANCE) |
1657 | | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1658 | | if (ret.length) // minimimum is 2 units for formation to be enabled |
1659 | | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
1660 | | ret.push(1); |
1661 | | break; |
1662 | 1652 | case ACTION_BARTER: |
1663 | 1653 | if (state.barterMarket) |
1664 | 1654 | ret.push(ent); |
… |
… |
function getActionForSelection(player, selection)
|
1667 | 1657 | if (state.trader) |
1668 | 1658 | ret.push([ent, state]); |
1669 | 1659 | break; |
1670 | | default: |
1671 | | return ret; //shouldn't happen |
1672 | 1660 | } |
1673 | 1661 | } |
1674 | 1662 | return ret; |
1675 | 1663 | } |
1676 | 1664 | |
| 1665 | // This returns a list of actions. Caller still has to check Technology availability |
| 1666 | function getDefaultActionForSelection(player, selection) |
| 1667 | { |
| 1668 | var action; |
| 1669 | var count = 0; |
| 1670 | for each (var ent in selection) |
| 1671 | { |
| 1672 | var state = GetEntityState(ent); |
| 1673 | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
| 1674 | continue; |
| 1675 | |
| 1676 | if (state.buildEntities && state.buildEntities.length) |
| 1677 | return ACTION_BUILD; // by default |
| 1678 | |
| 1679 | if (state.production && state.production.entities.length) |
| 1680 | action |= ACTION_TRAIN; |
| 1681 | else if (!hasClass(state, "Unit") || hasClass(state, "Animal") || |
| 1682 | !state.garrisonHolder) { |
| 1683 | if (++count > 1) //only works with at least two units |
| 1684 | action |= ACTION_FORMATION; |
| 1685 | } else if (state.barterMarket) |
| 1686 | action |= ACTION_BARTER; |
| 1687 | else if (state.trader) |
| 1688 | action |= ACTION_TRADER; |
| 1689 | } |
| 1690 | if (action & ACTION_TRAIN) |
| 1691 | return ACTION_TRAIN; |
| 1692 | else if (action & ACTION_FORMATION) |
| 1693 | return ACTION_FORMATION; |
| 1694 | else if (action & ACTION_BARTER) { |
| 1695 | setupUnitBarterPanel(state); |
| 1696 | return ACTION_BARTER; |
| 1697 | } else if (action & ACTION_TRADER) { |
| 1698 | setupUnitTradingPanel(state, selection); |
| 1699 | return ACTION_TRADER; |
| 1700 | } |
| 1701 | return 0; //shouldn't happen |
| 1702 | } |
| 1703 | |
1677 | 1704 | // Performs the specified group |
1678 | 1705 | function performGroup(action, nr) |
1679 | 1706 | { |
… |
… |
function performGroup(action, nr)
|
1707 | 1734 | updateGroups(); |
1708 | 1735 | break; |
1709 | 1736 | case "action": |
1710 | | if (!_optionsOfpreSelected.length) { |
1711 | | // action hotkey (first pass): With current selection, check possible |
1712 | | // ACTION_XXX's and set preSelectedAction when applicable |
1713 | | preSelectedAction = (1 << nr); |
1714 | | |
1715 | | var selection = g_Selection.toList(); |
1716 | | var player = Engine.GetPlayerID(); |
| 1737 | var selection = g_Selection.toList(); |
| 1738 | var player = Engine.GetPlayerID(); |
1717 | 1739 | |
1718 | | var actions = getActionForSelection(player, selection); |
1719 | | if (!actions || !actions.length) { |
1720 | | preSelectedAction = ACTION_NONE; |
1721 | | break; |
1722 | | } |
| 1740 | preSelectedAction = getDefaultActionForSelection(player, selection); |
| 1741 | if (preSelectedAction == ACTION_NONE) |
| 1742 | break; |
1723 | 1743 | |
1724 | | if (preSelectedAction == ACTION_BARTER) |
1725 | | setupUnitBarterPanel(state); |
1726 | | else if (preSelectedAction == ACTION_TRADER) |
1727 | | setupUnitTradingPanel(state, selection); |
| 1744 | var lst = selectAction(player, selection, action); |
| 1745 | if (!lst) // shouldn't happen |
| 1746 | break; |
1728 | 1747 | |
1729 | | _optionsOfpreSelected = actions; |
1730 | | } |
1731 | | else |
| 1748 | if (preSelectedAction & ACTION_GARRISON) |
1732 | 1749 | { |
1733 | | // 2nd action hotkey. Do preselectedAction[nr] |
1734 | | // The result depends on the action. |
1735 | | |
1736 | | var lst = _optionsOfpreSelected; |
1737 | | if (!lst) // shouldn't happen |
| 1750 | if (++nr > lst.length) |
| 1751 | nr = lst.length; |
| 1752 | } else if (preSelectedAction != ACTION_UNGARRISON) { |
| 1753 | if (nr >= lst.length) |
1738 | 1754 | break; |
| 1755 | lst = lst[nr]; |
| 1756 | } |
1739 | 1757 | |
1740 | | if (preSelectedAction & ACTION_GARRISON) |
1741 | | { |
1742 | | if (++nr > lst.length) |
1743 | | nr = lst.length; |
1744 | | } else if (preSelectedAction != ACTION_UNGARRISON) { |
1745 | | if (nr >= lst.length) |
1746 | | break; |
1747 | | lst = lst[nr]; |
| 1758 | switch (preSelectedAction) |
| 1759 | { |
| 1760 | case ACTION_BUILD: |
| 1761 | var tmpl = GetTemplateData(lst); |
| 1762 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1763 | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
| 1764 | startBuildingPlacement(lst); |
| 1765 | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
| 1766 | initBuildingPlacementView(); |
1748 | 1767 | } |
1749 | | |
1750 | | switch (preSelectedAction) |
1751 | | { |
1752 | | case ACTION_BUILD: |
1753 | | var tmpl = GetTemplateData(lst); |
1754 | | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
1755 | | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
1756 | | startBuildingPlacement(lst); |
1757 | | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
1758 | | initBuildingPlacementView(); |
1759 | | } |
1760 | | break; |
1761 | | case ACTION_TRAIN: |
1762 | | var tmpl = GetTemplateData(lst); |
1763 | | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
1764 | | var ents = g_Selection.toList(); |
1765 | | addTrainingToQueue(ents, lst); |
1766 | | } |
1767 | | break; |
1768 | | case ACTION_GARRISON: // we garison nr+1 count |
1769 | | g_Selection.reset(); |
1770 | | lst.splice(nr, lst.length - nr) |
1771 | | g_Selection.addList(lst); |
1772 | | inputState = INPUT_PRESELECTEDACTION; |
1773 | | break; |
1774 | | case ACTION_UNGARRISON: |
1775 | | if (lst.length > 1 || nr == 0) { |
1776 | | if (nr >= lst.length) |
1777 | | nr = lst.length - 1; |
1778 | | if (lst.length != 1 && nr == 0) { |
1779 | | // unload all from all buildings |
1780 | | _optionsOfpreSelected = []; |
1781 | | for each (var gh in lst) { |
1782 | | var s = GetEntityState(gh); |
1783 | | var gs = s.garrisonHolder.entities; |
1784 | | _optionsOfpreSelected = _optionsOfpreSelected.concat(gs); |
1785 | | unloadAll(gh); |
1786 | | } |
1787 | | } else { |
1788 | | if (lst.length != 1) |
1789 | | nr--; |
1790 | | lst = lst[nr]; |
1791 | | |
1792 | | var state = GetEntityState(lst); |
1793 | | var gents = state.garrisonHolder.entities; |
1794 | | _optionsOfpreSelected = gents; |
1795 | | unloadAll(lst); |
| 1768 | break; |
| 1769 | case ACTION_TRAIN: |
| 1770 | var tmpl = GetTemplateData(lst); |
| 1771 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1772 | var ents = g_Selection.toList(); |
| 1773 | addTrainingToQueue(ents, lst); |
| 1774 | } |
| 1775 | break; |
| 1776 | case ACTION_GARRISON: // we garison nr+1 count |
| 1777 | g_Selection.reset(); |
| 1778 | lst.splice(nr, lst.length - nr) |
| 1779 | g_Selection.addList(lst); |
| 1780 | inputState = INPUT_PRESELECTEDACTION; |
| 1781 | break; |
| 1782 | case ACTION_UNGARRISON: |
| 1783 | if (lst.length > 1 || nr == 0) { |
| 1784 | if (nr >= lst.length) |
| 1785 | nr = lst.length - 1; |
| 1786 | if (lst.length != 1 && nr == 0) { |
| 1787 | followQueue = []; |
| 1788 | // unload all from all buildings |
| 1789 | for each (var gh in lst) { |
| 1790 | var s = GetEntityState(gh); |
| 1791 | var gs = s.garrisonHolder.entities; |
| 1792 | followQueue = followQueue.concat(gs); |
| 1793 | unloadAll(gh); |
1796 | 1794 | } |
1797 | | g_Selection.reset(); |
1798 | | inputState = INPUT_FOLLOW_UNGARRISON; |
1799 | | break; |
1800 | 1795 | } else { |
1801 | | lst = lst[0]; |
| 1796 | if (lst.length != 1) |
| 1797 | nr--; |
| 1798 | lst = lst[nr]; |
| 1799 | |
1802 | 1800 | var state = GetEntityState(lst); |
1803 | 1801 | var gents = state.garrisonHolder.entities; |
1804 | | if (nr > gents.length) |
1805 | | nr = gents.length; |
1806 | | while (nr--) |
1807 | | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[nr]], "garrisonHolder": lst}); |
1808 | | // we could assign a key to follow them here |
1809 | | break; |
| 1802 | followQueue = gents; |
| 1803 | unloadAll(lst); |
1810 | 1804 | } |
| 1805 | g_Selection.reset(); |
1811 | 1806 | break; |
1812 | | case ACTION_FORMATION: |
1813 | | ents = g_Selection.toList(); |
1814 | | var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", { |
1815 | | "ents": g_Selection.toList(), |
1816 | | "formationName": lst |
1817 | | }); |
1818 | | if (formationOk) |
1819 | | performFormation(ents, lst); |
1820 | | break |
1821 | | case ACTION_STANCE: |
1822 | | ents = g_Selection.toList(); |
1823 | | performStance(ents, lst); |
1824 | | break; |
1825 | | case ACTION_BARTER: //TODO |
1826 | | break; |
1827 | | case ACTION_TRADER: //TODO |
| 1807 | } else { |
| 1808 | lst = lst[0]; |
| 1809 | var state = GetEntityState(lst); |
| 1810 | var gents = state.garrisonHolder.entities; |
| 1811 | if (nr > gents.length) |
| 1812 | nr = gents.length; |
| 1813 | while (nr--) |
| 1814 | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[nr]], "garrisonHolder": lst}); |
| 1815 | // we could assign a key to follow them here |
1828 | 1816 | break; |
1829 | 1817 | } |
| 1818 | break; |
| 1819 | case ACTION_FORMATION: |
| 1820 | ents = g_Selection.toList(); |
| 1821 | var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", { |
| 1822 | "ents": g_Selection.toList(), |
| 1823 | "formationName": lst |
| 1824 | }); |
| 1825 | if (formationOk) |
| 1826 | performFormation(ents, lst); |
| 1827 | break |
| 1828 | case ACTION_STANCE: |
| 1829 | ents = g_Selection.toList(); |
| 1830 | performStance(ents, lst); |
| 1831 | break; |
| 1832 | case ACTION_BARTER: //TODO |
| 1833 | break; |
| 1834 | case ACTION_TRADER: //TODO |
| 1835 | break; |
1830 | 1836 | } |
1831 | 1837 | break; |
1832 | 1838 | } |
… |
… |
function findAllVisibleEntities(classes, mode)
|
1895 | 1901 | } |
1896 | 1902 | |
1897 | 1903 | if (visibleEnts.length) { |
1898 | | if (!getActionForSelection(player, visibleEnts).length) |
| 1904 | if (!getDefaultActionForSelection(player, visibleEnts).length) |
1899 | 1905 | resetPreselectedAction(); |
1900 | 1906 | g_Selection.reset(); |
1901 | 1907 | g_Selection.addList(visibleEnts); |
… |
… |
function findEntity(classes, mode)
|
1918 | 1924 | var newEntity = Engine.GuiInterfaceCall("FindEntity", data); |
1919 | 1925 | if (newEntity && newEntity != lastEntity) |
1920 | 1926 | { |
1921 | | if (!getActionForSelection(player, [newEntity]).length) |
| 1927 | if (!selectAction(player, [newEntity], preSelectedAction).length) |
1922 | 1928 | resetPreselectedAction(); |
1923 | 1929 | else if (preSelectedAction == ACTION_BUILD) |
1924 | 1930 | updateBuildingPlacementPreview(); |
-
commit 273d868803cecf5e17938e49a2a0b6944327257e
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 20:35:27 2012 +0200
as suggested by historic_bruno the backslash isn't always in line
Also use Ctrl rather than shift for the 7+ keys (we may want to use shift
for batchtrain later).
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 5201210..5015b15 100644
a
|
b
|
hotkey.selection.group.select.9 = 9
|
189 | 189 | hotkey.selection.group.save.9 = "Ctrl+9" |
190 | 190 | hotkey.selection.group.add.9 = "Shift+9" |
191 | 191 | |
192 | | hotkey.selection.group.action.0 = H |
193 | | hotkey.selection.group.action.1 = J |
194 | | hotkey.selection.group.action.2 = K |
195 | | hotkey.selection.group.action.3 = L |
196 | | hotkey.selection.group.action.4 = Semicolon |
197 | | hotkey.selection.group.action.5 = SingleQuote |
198 | | hotkey.selection.group.action.6 = BackSlash |
199 | | hotkey.selection.group.action.7 = "Shift+H" |
200 | | hotkey.selection.group.action.8 = "Shift+J" |
201 | | hotkey.selection.group.action.9 = "Shift+K" |
202 | | hotkey.selection.group.action.10 = "Shift+L" |
203 | | hotkey.selection.group.action.11 = Colon |
204 | | hotkey.selection.group.action.12 = DoubleQuote |
| 192 | hotkey.selection.group.action.0 = G |
| 193 | hotkey.selection.group.action.1 = H |
| 194 | hotkey.selection.group.action.2 = J |
| 195 | hotkey.selection.group.action.3 = K |
| 196 | hotkey.selection.group.action.4 = L |
| 197 | hotkey.selection.group.action.5 = Semicolon |
| 198 | hotkey.selection.group.action.6 = SingleQuote |
| 199 | hotkey.selection.group.action.7 = "Ctrl+G" |
| 200 | hotkey.selection.group.action.8 = "Ctrl+H" |
| 201 | hotkey.selection.group.action.9 = "Ctrl+J" |
| 202 | hotkey.selection.group.action.10 = "Ctrl+K" |
| 203 | hotkey.selection.group.action.11 = "Ctrl+L" |
| 204 | hotkey.selection.group.action.12 = "Ctrl+Semicolon" |
| 205 | hotkey.selection.group.action.13 = "Ctrl+SingleQuote" |
205 | 206 | hotkey.selection.group.action.reset = ForwardSlash |
206 | 207 | |
207 | 208 | ; > SESSION CONTROLS |
-
commit 97150316bb560554c7f1e5d3f45f90a71d574191
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 20:16:55 2012 +0200
Unload all from all selected buildings
ensure selection occurs
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index bc48d73..eb6d59a 100644
a
|
b
|
function handleInputBeforeGui(ev, hoveredObject)
|
671 | 671 | } |
672 | 672 | if (inputState == INPUT_FOLLOW_UNGARRISON) |
673 | 673 | { |
674 | | gents = _optionsOfpreSelected; |
| 674 | var gents = _optionsOfpreSelected; |
| 675 | var state = GetEntityState(gents[0]); |
| 676 | // FIXME this stalls until the selection actually occurs |
| 677 | if (state.visibility == "hidden") |
| 678 | return true; |
675 | 679 | Engine.CameraFollow(0); |
676 | 680 | Engine.CameraFollow(gents[0]); |
677 | 681 | g_Selection.addList(gents); |
… |
… |
function performGroup(action, nr)
|
1771 | 1775 | if (lst.length > 1 || nr == 0) { |
1772 | 1776 | if (nr >= lst.length) |
1773 | 1777 | nr = lst.length - 1; |
1774 | | if (lst.length != 1) // TODO: uload all from all |
1775 | | lst = lst[nr]; // selected buildings |
1776 | | else |
1777 | | lst = lst[0]; |
1778 | | var state = GetEntityState(lst); |
1779 | | var gents = state.garrisonHolder.entities; |
1780 | | _optionsOfpreSelected = gents; |
1781 | | unloadAll(lst); |
| 1778 | if (lst.length != 1 && nr == 0) { |
| 1779 | // unload all from all buildings |
| 1780 | _optionsOfpreSelected = []; |
| 1781 | for each (var gh in lst) { |
| 1782 | var s = GetEntityState(gh); |
| 1783 | var gs = s.garrisonHolder.entities; |
| 1784 | _optionsOfpreSelected = _optionsOfpreSelected.concat(gs); |
| 1785 | unloadAll(gh); |
| 1786 | } |
| 1787 | } else { |
| 1788 | if (lst.length != 1) |
| 1789 | nr--; |
| 1790 | lst = lst[nr]; |
| 1791 | |
| 1792 | var state = GetEntityState(lst); |
| 1793 | var gents = state.garrisonHolder.entities; |
| 1794 | _optionsOfpreSelected = gents; |
| 1795 | unloadAll(lst); |
| 1796 | } |
1782 | 1797 | g_Selection.reset(); |
1783 | 1798 | inputState = INPUT_FOLLOW_UNGARRISON; |
1784 | 1799 | break; |
… |
… |
function performGroup(action, nr)
|
1786 | 1801 | lst = lst[0]; |
1787 | 1802 | var state = GetEntityState(lst); |
1788 | 1803 | var gents = state.garrisonHolder.entities; |
1789 | | if (nr >= gents.length) |
| 1804 | if (nr > gents.length) |
1790 | 1805 | nr = gents.length; |
1791 | 1806 | while (nr--) |
1792 | 1807 | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[nr]], "garrisonHolder": lst}); |
-
commit a40750c24a7bf9faa84b7e45c4a465c1dafa96c9
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 19:37:50 2012 +0200
actually the INPUT_REPEATED_UNGARRISON state is not needed
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index eb0f140..bc48d73 100644
a
|
b
|
const INPUT_PRESELECTEDACTION = 7;
|
37 | 37 | const INPUT_BUILDING_WALL_CLICK = 8; |
38 | 38 | const INPUT_BUILDING_WALL_PATHING = 9; |
39 | 39 | const INPUT_FOLLOW_UNGARRISON = 10; |
40 | | const INPUT_REPEATED_UNGARRISON = 11; |
41 | 40 | |
42 | 41 | var inputState = INPUT_NORMAL; |
43 | 42 | var placementSupport = new PlacementSupport(); |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
677 | 676 | Engine.CameraFollow(gents[0]); |
678 | 677 | g_Selection.addList(gents); |
679 | 678 | resetPreselectedAction(); |
680 | | } else if (inputState == INPUT_REPEATED_UNGARRISON) { |
681 | | var garrisonHolder = _optionsOfpreSelected[0]; |
682 | | var state = GetEntityState(garrisonHolder); |
683 | | var gents = state.garrisonHolder.entities; |
684 | | var gent = gents[_optionsOfpreSelected[1]] |
685 | | Engine.PostNetworkCommand({"type": "unload", "entities": [gent], "garrisonHolder": garrisonHolder}); |
686 | | if (_optionsOfpreSelected[1]-- > 0) |
687 | | return true; |
688 | | resetPreselectedAction(); |
689 | 679 | } |
690 | 680 | // Remember whether the mouse is over a GUI object or not |
691 | 681 | mouseIsOverObject = (hoveredObject != null); |
… |
… |
function performGroup(action, nr)
|
1797 | 1787 | var state = GetEntityState(lst); |
1798 | 1788 | var gents = state.garrisonHolder.entities; |
1799 | 1789 | if (nr >= gents.length) |
1800 | | nr = gents.length - 1; |
1801 | | // unload nr times, requires some update. |
1802 | | _optionsOfpreSelected = [lst, nr]; |
1803 | | inputState = INPUT_REPEATED_UNGARRISON; |
| 1790 | nr = gents.length; |
| 1791 | while (nr--) |
| 1792 | Engine.PostNetworkCommand({"type": "unload", "entities": [gents[nr]], "garrisonHolder": lst}); |
| 1793 | // we could assign a key to follow them here |
| 1794 | break; |
1804 | 1795 | } |
1805 | 1796 | break; |
1806 | 1797 | case ACTION_FORMATION: |
-
commit fc698a3c4a64e556b20cfdf904b001987282aaeb
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Wed Jun 13 01:59:38 2012 +0200
This allows two actions: to follow units when unload all hotkey is pressed
and to ungarrison n units. hotkey J = 1, K = 2, etc.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 43cc741..eb0f140 100644
a
|
b
|
const INPUT_BATCHTRAINING = 6;
|
36 | 36 | const INPUT_PRESELECTEDACTION = 7; |
37 | 37 | const INPUT_BUILDING_WALL_CLICK = 8; |
38 | 38 | const INPUT_BUILDING_WALL_PATHING = 9; |
| 39 | const INPUT_FOLLOW_UNGARRISON = 10; |
| 40 | const INPUT_REPEATED_UNGARRISON = 11; |
39 | 41 | |
40 | 42 | var inputState = INPUT_NORMAL; |
41 | 43 | var placementSupport = new PlacementSupport(); |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
668 | 670 | mouseY = ev.y; |
669 | 671 | break; |
670 | 672 | } |
671 | | |
| 673 | if (inputState == INPUT_FOLLOW_UNGARRISON) |
| 674 | { |
| 675 | gents = _optionsOfpreSelected; |
| 676 | Engine.CameraFollow(0); |
| 677 | Engine.CameraFollow(gents[0]); |
| 678 | g_Selection.addList(gents); |
| 679 | resetPreselectedAction(); |
| 680 | } else if (inputState == INPUT_REPEATED_UNGARRISON) { |
| 681 | var garrisonHolder = _optionsOfpreSelected[0]; |
| 682 | var state = GetEntityState(garrisonHolder); |
| 683 | var gents = state.garrisonHolder.entities; |
| 684 | var gent = gents[_optionsOfpreSelected[1]] |
| 685 | Engine.PostNetworkCommand({"type": "unload", "entities": [gent], "garrisonHolder": garrisonHolder}); |
| 686 | if (_optionsOfpreSelected[1]-- > 0) |
| 687 | return true; |
| 688 | resetPreselectedAction(); |
| 689 | } |
672 | 690 | // Remember whether the mouse is over a GUI object or not |
673 | 691 | mouseIsOverObject = (hoveredObject != null); |
674 | 692 | |
… |
… |
function performGroup(action, nr)
|
1725 | 1743 | if (!lst) // shouldn't happen |
1726 | 1744 | break; |
1727 | 1745 | |
1728 | | if (preSelectedAction & (ACTION_UNGARRISON | ACTION_GARRISON)) |
| 1746 | if (preSelectedAction & ACTION_GARRISON) |
1729 | 1747 | { |
1730 | | if (preSelectedAction & ACTION_GARRISON) |
1731 | | ++nr; |
1732 | | if (nr > lst.length) |
| 1748 | if (++nr > lst.length) |
1733 | 1749 | nr = lst.length; |
1734 | | } else if (preSelectedAction != (ACTION_BUILD|ACTION_TRAIN)) { |
| 1750 | } else if (preSelectedAction != ACTION_UNGARRISON) { |
1735 | 1751 | if (nr >= lst.length) |
1736 | 1752 | break; |
1737 | 1753 | lst = lst[nr]; |
… |
… |
function performGroup(action, nr)
|
1763 | 1779 | break; |
1764 | 1780 | case ACTION_UNGARRISON: |
1765 | 1781 | if (lst.length > 1 || nr == 0) { |
| 1782 | if (nr >= lst.length) |
| 1783 | nr = lst.length - 1; |
1766 | 1784 | if (lst.length != 1) // TODO: uload all from all |
1767 | 1785 | lst = lst[nr]; // selected buildings |
1768 | 1786 | else |
1769 | 1787 | lst = lst[0]; |
1770 | 1788 | var state = GetEntityState(lst); |
1771 | 1789 | var gents = state.garrisonHolder.entities; |
| 1790 | _optionsOfpreSelected = gents; |
1772 | 1791 | unloadAll(lst); |
1773 | | // FIXME: follow when ungarrisoning all |
1774 | | // sadly these gents cannot be viewed after ungarissoning: |
1775 | | if (gents) |
1776 | | { |
1777 | | //Engine.CameraFollow(0); |
1778 | | g_Selection.reset(); |
1779 | | g_Selection.addList(gents); |
1780 | | Engine.CameraFollow(gents); |
1781 | | } |
| 1792 | g_Selection.reset(); |
| 1793 | inputState = INPUT_FOLLOW_UNGARRISON; |
| 1794 | break; |
1782 | 1795 | } else { |
1783 | 1796 | lst = lst[0]; |
1784 | 1797 | var state = GetEntityState(lst); |
1785 | 1798 | var gents = state.garrisonHolder.entities; |
1786 | | // FIXME unload nr times, requires some update. |
1787 | | unload(lst, gents); |
| 1799 | if (nr >= gents.length) |
| 1800 | nr = gents.length - 1; |
| 1801 | // unload nr times, requires some update. |
| 1802 | _optionsOfpreSelected = [lst, nr]; |
| 1803 | inputState = INPUT_REPEATED_UNGARRISON; |
1788 | 1804 | } |
1789 | 1805 | break; |
1790 | 1806 | case ACTION_FORMATION: |
-
commit 0e369958e9c17997d7e77c3e2aae28c5971ff7a0
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Tue Jun 12 01:24:00 2012 +0200
Find all visible idle workers,warriors,buildings with Shift ./,/U/etc
revert behavior and leave view to garrisonholder as the ungarrisoned
cannot be followed.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 24f32a5..43cc741 100644
a
|
b
|
function performGroup(action, nr)
|
1767 | 1767 | lst = lst[nr]; // selected buildings |
1768 | 1768 | else |
1769 | 1769 | lst = lst[0]; |
1770 | | // FIXME: follow when ungarrisoning all |
1771 | 1770 | var state = GetEntityState(lst); |
1772 | 1771 | var gents = state.garrisonHolder.entities; |
1773 | 1772 | unloadAll(lst); |
1774 | | Engine.CameraFollow(0); |
1775 | | g_Selection.reset(); |
1776 | | g_Selection.addList(gents); |
1777 | | Engine.CameraFollow(gents[0]); |
| 1773 | // FIXME: follow when ungarrisoning all |
| 1774 | // sadly these gents cannot be viewed after ungarissoning: |
| 1775 | if (gents) |
| 1776 | { |
| 1777 | //Engine.CameraFollow(0); |
| 1778 | g_Selection.reset(); |
| 1779 | g_Selection.addList(gents); |
| 1780 | Engine.CameraFollow(gents); |
| 1781 | } |
1778 | 1782 | } else { |
1779 | 1783 | lst = lst[0]; |
1780 | 1784 | var state = GetEntityState(lst); |
… |
… |
function resetEntitySearch()
|
1847 | 1851 | currEntClass = 0; |
1848 | 1852 | } |
1849 | 1853 | |
| 1854 | function findAllVisibleEntities(classes, mode) |
| 1855 | { |
| 1856 | var player = Engine.GetPlayerID(); |
| 1857 | var plEnts = Engine.PickFriendlyEntitiesOnScreen(player); |
| 1858 | // Or we could do somthing alike the below, but this is resolution dependent |
| 1859 | //var plEnts = Engine.PickFriendlyEntitiesInRect(250, 250, 1400, 750, player); |
| 1860 | if (!plEnts.length) |
| 1861 | return; |
| 1862 | var visibleEnts = []; |
| 1863 | for each (cls in classes) |
| 1864 | { |
| 1865 | var data = { |
| 1866 | entClass: cls, |
| 1867 | searchMode: mode, |
| 1868 | playerEnts: plEnts, |
| 1869 | }; |
| 1870 | var entities = Engine.GuiInterfaceCall("SubsetMatchedEnts", data); |
| 1871 | if (entities.length) |
| 1872 | visibleEnts = visibleEnts.concat(entities); |
| 1873 | } |
| 1874 | |
| 1875 | if (visibleEnts.length) { |
| 1876 | if (!getActionForSelection(player, visibleEnts).length) |
| 1877 | resetPreselectedAction(); |
| 1878 | g_Selection.reset(); |
| 1879 | g_Selection.addList(visibleEnts); |
| 1880 | Engine.CameraFollow(visibleEnts[0]); |
| 1881 | } |
| 1882 | } |
| 1883 | |
1850 | 1884 | function findEntity(classes, mode) |
1851 | 1885 | { |
| 1886 | var queued = Engine.HotkeyIsPressed("session.queue"); |
| 1887 | if (queued) { |
| 1888 | findAllVisibleEntities(classes, mode) |
| 1889 | return; |
| 1890 | } |
1852 | 1891 | var player = Engine.GetPlayerID(); |
1853 | 1892 | // Cycle through idling classes before giving up |
1854 | 1893 | for (var i = 0; i <= classes.length; ++i) |
-
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
index a2c29ba..6fd71d9 100644
a
|
b
|
GuiInterface.prototype.PlaySound = function(player, data)
|
1426 | 1426 | PlaySound(data.name, data.entity); |
1427 | 1427 | }; |
1428 | 1428 | |
| 1429 | GuiInterface.prototype.MatchEnt = function(ent, data) |
| 1430 | { |
| 1431 | var ret; |
| 1432 | var cmpId = Engine.QueryInterface(ent, IID_Identity); |
| 1433 | if (cmpId && cmpId.HasClass(data.entClass)) { |
| 1434 | if (data.searchMode == 0) { |
| 1435 | ret = ent; |
| 1436 | } else if (data.searchMode == 1) { // Search idle villager/soldier |
| 1437 | var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); |
| 1438 | if (cmpUnitAI && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned()) |
| 1439 | ret = ent; |
| 1440 | } |
| 1441 | } |
| 1442 | return ret; |
| 1443 | } |
| 1444 | |
| 1445 | GuiInterface.prototype.SubsetMatchedEnts = function(player, data) |
| 1446 | { |
| 1447 | var ret = []; |
| 1448 | for each (var ent in data.playerEnts) |
| 1449 | { |
| 1450 | var match = this.MatchEnt(ent, data); |
| 1451 | if (match) |
| 1452 | ret.push(match); |
| 1453 | } |
| 1454 | return ret; |
| 1455 | } |
| 1456 | |
1429 | 1457 | GuiInterface.prototype.FindEntity = function(player, data) |
1430 | 1458 | { |
1431 | 1459 | var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); |
… |
… |
GuiInterface.prototype.FindEntity = function(player, data)
|
1435 | 1463 | // so that we cycle around in a predictable order |
1436 | 1464 | for each (var ent in playerEntities) |
1437 | 1465 | { |
1438 | | var cmpId = Engine.QueryInterface(ent, IID_Identity); |
1439 | | if (ent > data.prevEntity && cmpId && cmpId.HasClass(data.entClass)) { |
1440 | | if (data.searchMode == 0) { |
1441 | | return ent; |
1442 | | } else if (data.searchMode == 1) { // Search idle villager/soldier |
1443 | | var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); |
1444 | | if (cmpUnitAI && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned()) |
1445 | | return ent; |
1446 | | } |
| 1466 | if (ent > data.prevEntity) |
| 1467 | { |
| 1468 | var match = this.MatchEnt(ent, data); |
| 1469 | if (match) |
| 1470 | return match; |
1447 | 1471 | } |
1448 | 1472 | } |
1449 | 1473 | |
… |
… |
var exposedFunctions = {
|
1570 | 1594 | "SetWallPlacementPreview": 1, |
1571 | 1595 | "GetFoundationSnapData": 1, |
1572 | 1596 | "PlaySound": 1, |
| 1597 | "SubsetMatchedEnts": 1, |
1573 | 1598 | "FindEntity": 1, |
1574 | 1599 | "GetTradingDetails": 1, |
1575 | 1600 | "CanAttack": 1, |
-
commit 9a19e955fbf67dd61d2a9152ab23aec898d4d248
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Mon Jun 11 00:20:19 2012 +0200
Bugfix: during building placement we can now correctly select another
idle villager for the job.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index b724acd..24f32a5 100644
a
|
b
|
function updateBuildingPlacementPreview()
|
146 | 146 | return false; |
147 | 147 | } |
148 | 148 | |
149 | | function initBuildingPlacementView(ev) |
| 149 | function initBuildingPlacementView() |
150 | 150 | { |
151 | 151 | if (placementSupport.mode === "wall") |
152 | 152 | { |
… |
… |
function handleInputAfterGui(ev)
|
1054 | 1054 | var sptr = ev.hotkey.split("."); |
1055 | 1055 | var now = new Date(); |
1056 | 1056 | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey) && ev.hotkey.indexOf("selection.group.select.") == 0) { |
1057 | | performGroup("snap", sptr[3], ev); |
| 1057 | performGroup("snap", sptr[3]); |
1058 | 1058 | } |
1059 | 1059 | else |
1060 | 1060 | { |
1061 | | performGroup(sptr[2], sptr[3], ev); |
| 1061 | performGroup(sptr[2], sptr[3]); |
1062 | 1062 | |
1063 | 1063 | doublePressTimer = now.getTime(); |
1064 | 1064 | prevHotkey = ev.hotkey; |
… |
… |
function handleInputAfterGui(ev)
|
1214 | 1214 | { |
1215 | 1215 | case "mousemotion": |
1216 | 1216 | placementSupport.position = Engine.GetTerrainAtScreenPoint(ev.x, ev.y); |
1217 | | initBuildingPlacementView(ev); |
| 1217 | initBuildingPlacementView(); |
1218 | 1218 | return false; // continue processing mouse motion |
1219 | 1219 | |
1220 | 1220 | case "mousebuttondown": |
… |
… |
function handleInputAfterGui(ev)
|
1264 | 1264 | if (ev.hotkey.indexOf("selection.group.action.") == 0) |
1265 | 1265 | { // can switch buildings |
1266 | 1266 | var sptr = ev.hotkey.split("."); |
1267 | | performGroup(sptr[2], sptr[3], ev); |
| 1267 | performGroup(sptr[2], sptr[3]); |
1268 | 1268 | } |
1269 | 1269 | } |
1270 | 1270 | break; |
… |
… |
function getActionForSelection(player, selection)
|
1623 | 1623 | break; |
1624 | 1624 | case ACTION_BUILD: |
1625 | 1625 | if (state.buildEntities && state.buildEntities.length) { |
1626 | | inputState = INPUT_PRESELECTEDACTION; |
| 1626 | if (inputState != INPUT_BUILDING_PLACEMENT) |
| 1627 | inputState = INPUT_PRESELECTEDACTION; |
1627 | 1628 | return state.buildEntities; |
1628 | 1629 | } |
1629 | 1630 | break; |
… |
… |
function getActionForSelection(player, selection)
|
1662 | 1663 | } |
1663 | 1664 | |
1664 | 1665 | // Performs the specified group |
1665 | | function performGroup(action, nr, ev) |
| 1666 | function performGroup(action, nr) |
1666 | 1667 | { |
1667 | 1668 | if (nr == "reset") |
1668 | 1669 | { |
… |
… |
function performGroup(action, nr, ev)
|
1744 | 1745 | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
1745 | 1746 | startBuildingPlacement(lst); |
1746 | 1747 | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
1747 | | initBuildingPlacementView(ev); |
| 1748 | initBuildingPlacementView(); |
1748 | 1749 | } |
1749 | 1750 | break; |
1750 | 1751 | case ACTION_TRAIN: |
… |
… |
function findEntity(classes, mode)
|
1858 | 1859 | { |
1859 | 1860 | if (!getActionForSelection(player, [newEntity]).length) |
1860 | 1861 | resetPreselectedAction(); |
| 1862 | else if (preSelectedAction == ACTION_BUILD) |
| 1863 | updateBuildingPlacementPreview(); |
1861 | 1864 | |
1862 | 1865 | lastEntity = newEntity; |
1863 | 1866 | g_Selection.reset(); |
-
commit fc4d8b422f85397eda4b78de2cf849d146b33ab1
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 10 23:32:05 2012 +0200
Fixes reset hotkey
Fixes stance
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 1f7c35c..5201210 100644
a
|
b
|
hotkey.selection.group.action.9 = "Shift+K"
|
202 | 202 | hotkey.selection.group.action.10 = "Shift+L" |
203 | 203 | hotkey.selection.group.action.11 = Colon |
204 | 204 | hotkey.selection.group.action.12 = DoubleQuote |
205 | | hotkey.selection.group.reset.action = ForwardSlash |
| 205 | hotkey.selection.group.action.reset = ForwardSlash |
206 | 206 | |
207 | 207 | ; > SESSION CONTROLS |
208 | 208 | hotkey.session.kill = Delete ; Destroy selected units |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 8775bb3..b724acd 100644
a
|
b
|
function findGatherType(gatherer, supply)
|
185 | 185 | |
186 | 186 | function resetPreselectedAction() |
187 | 187 | { |
188 | | placementSupport.Reset(); |
| 188 | preSelectedAction = ACTION_NONE; |
189 | 189 | inputState = INPUT_NORMAL; |
190 | 190 | _optionsOfpreSelected = []; |
| 191 | placementSupport.Reset(); // or a hotkey may leave a building snapshot |
| 192 | updateCursorAndTooltip(); |
191 | 193 | |
192 | 194 | } |
193 | 195 | |
… |
… |
function handleInputAfterGui(ev)
|
1070 | 1072 | switch (ev.type) |
1071 | 1073 | { |
1072 | 1074 | case "mousebuttondown": |
1073 | | if (ev.button == SDL_BUTTON_LEFT && preSelectedAction != ACTION_NONE) |
| 1075 | if (ev.button == SDL_BUTTON_LEFT && preSelectedAction) |
1074 | 1076 | { |
1075 | 1077 | var action = determineAction(ev.x, ev.y); |
1076 | 1078 | resetPreselectedAction(); |
… |
… |
function handleInputAfterGui(ev)
|
1078 | 1080 | break; |
1079 | 1081 | return doAction(action, ev); |
1080 | 1082 | } |
1081 | | else if (ev.button == SDL_BUTTON_RIGHT && preSelectedAction != ACTION_NONE) |
| 1083 | else if (ev.button == SDL_BUTTON_RIGHT) |
1082 | 1084 | { |
1083 | 1085 | resetPreselectedAction(); |
1084 | 1086 | break; |
… |
… |
function getActionForSelection(player, selection)
|
1638 | 1640 | if (!hasClass(state, "Unit") || hasClass(state, "Animal") || state.garrisonHolder) |
1639 | 1641 | break; |
1640 | 1642 | |
1641 | | if (preSelectedAction == STANCE) |
| 1643 | if (preSelectedAction == ACTION_STANCE) |
1642 | 1644 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1643 | 1645 | if (ret.length) // minimimum is 2 units for formation to be enabled |
1644 | 1646 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
… |
… |
function getActionForSelection(player, selection)
|
1662 | 1664 | // Performs the specified group |
1663 | 1665 | function performGroup(action, nr, ev) |
1664 | 1666 | { |
| 1667 | if (nr == "reset") |
| 1668 | { |
| 1669 | resetPreselectedAction(); |
| 1670 | return; |
| 1671 | } |
1665 | 1672 | switch (action) |
1666 | 1673 | { |
1667 | 1674 | case "snap": |
… |
… |
function performGroup(action, nr, ev)
|
1795 | 1802 | } |
1796 | 1803 | } |
1797 | 1804 | break; |
1798 | | case "reset": |
1799 | | resetPreselectedAction(); |
1800 | | break; |
1801 | 1805 | } |
1802 | 1806 | } |
1803 | 1807 | |
-
commit ab24419fee2fd86ba4cfcec2d85f86c67a526e4a
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 10 21:37:36 2012 +0200
Separate function initBuildingPlacementView()
Building placement is now shown immediately, not after mouse movement.
User can use the same several hotkey more times, e.g. for training.
Or for iterate over the possible options using hotkeys, changing the
Formation or Stance of the selected units or choosing different buildings
during placement.
setting inputState = INPUT_PRESELECTEDACTION for build and garrison
alters mouse left/rightclick behavior.
Formation fix: don't allow hotkey if selection is only one unit
Add forwardslash as hotkey to reset action hotkey
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 0f1220e..1f7c35c 100644
a
|
b
|
hotkey.selection.group.action.9 = "Shift+K"
|
202 | 202 | hotkey.selection.group.action.10 = "Shift+L" |
203 | 203 | hotkey.selection.group.action.11 = Colon |
204 | 204 | hotkey.selection.group.action.12 = DoubleQuote |
| 205 | hotkey.selection.group.reset.action = ForwardSlash |
205 | 206 | |
206 | 207 | ; > SESSION CONTROLS |
207 | 208 | hotkey.session.kill = Delete ; Destroy selected units |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 1888087..8775bb3 100644
a
|
b
|
const ACTION_STANCE = 32;
|
22 | 22 | const ACTION_BARTER = 64; |
23 | 23 | const ACTION_TRADER =128; |
24 | 24 | var preSelectedAction = ACTION_NONE; |
| 25 | |
| 26 | // N.B. reset this after selecting different units or buildings |
25 | 27 | var _optionsOfpreSelected = []; |
26 | 28 | |
27 | 29 | const INPUT_NORMAL = 0; |
… |
… |
function updateBuildingPlacementPreview()
|
144 | 146 | return false; |
145 | 147 | } |
146 | 148 | |
| 149 | function initBuildingPlacementView(ev) |
| 150 | { |
| 151 | if (placementSupport.mode === "wall") |
| 152 | { |
| 153 | // Including only the on-screen towers in the next snap candidate list is sufficient here, since the user is |
| 154 | // still selecting a starting point (which must necessarily be on-screen). (The update of the snap entities |
| 155 | // itself happens in the call to updateBuildingPlacementPreview below). |
| 156 | placementSupport.wallSnapEntitiesIncludeOffscreen = false; |
| 157 | } |
| 158 | else |
| 159 | { |
| 160 | var snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", { |
| 161 | "template": placementSupport.template, |
| 162 | "x": placementSupport.position.x, |
| 163 | "z": placementSupport.position.z, |
| 164 | }); |
| 165 | if (snapData) |
| 166 | { |
| 167 | placementSupport.angle = snapData.angle; |
| 168 | placementSupport.position.x = snapData.x; |
| 169 | placementSupport.position.z = snapData.z; |
| 170 | } |
| 171 | } |
| 172 | updateBuildingPlacementPreview(); // includes an update of the snap entity candidates |
| 173 | } |
| 174 | |
147 | 175 | function findGatherType(gatherer, supply) |
148 | 176 | { |
149 | 177 | if (!gatherer || !supply) |
… |
… |
function findGatherType(gatherer, supply)
|
155 | 183 | return undefined; |
156 | 184 | } |
157 | 185 | |
| 186 | function resetPreselectedAction() |
| 187 | { |
| 188 | placementSupport.Reset(); |
| 189 | inputState = INPUT_NORMAL; |
| 190 | _optionsOfpreSelected = []; |
| 191 | |
| 192 | } |
| 193 | |
158 | 194 | function getActionInfo(action, target) |
159 | 195 | { |
160 | 196 | var selection = g_Selection.toList(); |
… |
… |
function determineAction(x, y, fromMinimap)
|
449 | 485 | break; |
450 | 486 | } |
451 | 487 | } |
452 | | else if (Engine.HotkeyIsPressed("session.garrison")) |
| 488 | else if (Engine.HotkeyIsPressed("session.garrison") || preSelectedAction == ACTION_GARRISON) |
453 | 489 | { |
454 | 490 | if (getActionInfo("garrison", target).possible) |
455 | 491 | return {"type": "garrison", "cursor": "action-garrison", "target": target}; |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
755 | 791 | var queued = Engine.HotkeyIsPressed("session.queue"); |
756 | 792 | if (tryPlaceBuilding(queued)) |
757 | 793 | { |
758 | | if (queued) { |
| 794 | if (queued) |
759 | 795 | inputState = INPUT_BUILDING_PLACEMENT; |
760 | | } else { |
761 | | inputState = INPUT_NORMAL; |
762 | | _optionsOfpreSelected = []; |
763 | | } |
| 796 | else |
| 797 | resetPreselectedAction(); |
764 | 798 | } |
765 | 799 | else |
766 | 800 | { |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
774 | 808 | if (ev.button == SDL_BUTTON_RIGHT) |
775 | 809 | { |
776 | 810 | // Cancel building |
777 | | placementSupport.Reset(); |
778 | | inputState = INPUT_NORMAL; |
779 | | _optionsOfpreSelected = []; |
| 811 | resetPreselectedAction(); |
780 | 812 | return true; |
781 | 813 | } |
782 | 814 | break; |
… |
… |
function handleInputAfterGui(ev)
|
998 | 1030 | return false; |
999 | 1031 | |
1000 | 1032 | case "mousebuttondown": |
| 1033 | _optionsOfpreSelected = []; |
1001 | 1034 | if (ev.button == SDL_BUTTON_LEFT) |
1002 | 1035 | { |
1003 | 1036 | dragStart = [ ev.x, ev.y ]; |
… |
… |
function handleInputAfterGui(ev)
|
1014 | 1047 | break; |
1015 | 1048 | |
1016 | 1049 | case "hotkeydown": |
1017 | | if (ev.hotkey.indexOf("selection.group.") == 0) |
| 1050 | if (ev.hotkey && ev.hotkey.indexOf("selection.group.") == 0) |
1018 | 1051 | { |
| 1052 | var sptr = ev.hotkey.split("."); |
1019 | 1053 | var now = new Date(); |
1020 | | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey)) |
1021 | | { |
1022 | | if (ev.hotkey.indexOf("selection.group.select.") == 0) |
1023 | | { |
1024 | | var sptr = ev.hotkey.split("."); |
1025 | | performGroup("snap", sptr[3]); |
1026 | | } |
| 1054 | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey) && ev.hotkey.indexOf("selection.group.select.") == 0) { |
| 1055 | performGroup("snap", sptr[3], ev); |
1027 | 1056 | } |
1028 | 1057 | else |
1029 | 1058 | { |
1030 | | var sptr = ev.hotkey.split("."); |
1031 | | performGroup(sptr[2], sptr[3]); |
| 1059 | performGroup(sptr[2], sptr[3], ev); |
1032 | 1060 | |
1033 | 1061 | doublePressTimer = now.getTime(); |
1034 | 1062 | prevHotkey = ev.hotkey; |
… |
… |
function handleInputAfterGui(ev)
|
1045 | 1073 | if (ev.button == SDL_BUTTON_LEFT && preSelectedAction != ACTION_NONE) |
1046 | 1074 | { |
1047 | 1075 | var action = determineAction(ev.x, ev.y); |
| 1076 | resetPreselectedAction(); |
1048 | 1077 | if (!action) |
1049 | 1078 | break; |
1050 | | preSelectedAction = ACTION_NONE; |
1051 | | inputState = INPUT_NORMAL; |
1052 | | _optionsOfpreSelected = []; |
1053 | 1079 | return doAction(action, ev); |
1054 | 1080 | } |
1055 | 1081 | else if (ev.button == SDL_BUTTON_RIGHT && preSelectedAction != ACTION_NONE) |
1056 | 1082 | { |
1057 | | preSelectedAction = ACTION_NONE; |
1058 | | inputState = INPUT_NORMAL; |
1059 | | _optionsOfpreSelected = []; |
| 1083 | resetPreselectedAction(); |
1060 | 1084 | break; |
1061 | 1085 | } |
1062 | | // else |
1063 | 1086 | case "hotkeydown": |
1064 | | if (!ev.hotkey) |
1065 | | break; |
1066 | | |
1067 | | if (ev.hotkey.indexOf("selection.group.action.") == 0) |
| 1087 | if (ev.hotkey && ev.hotkey.indexOf("selection.group.action.") == 0) |
1068 | 1088 | { |
1069 | 1089 | var sptr = ev.hotkey.split("."); |
1070 | 1090 | performGroup(sptr[2], sptr[3]); |
… |
… |
function handleInputAfterGui(ev)
|
1074 | 1094 | // Slight hack: If selection is empty, reset the input state |
1075 | 1095 | if (g_Selection.toList().length == 0) |
1076 | 1096 | { |
1077 | | preSelectedAction = ACTION_NONE; |
1078 | | inputState = INPUT_NORMAL; |
1079 | | _optionsOfpreSelected = []; |
| 1097 | resetPreselectedAction(); |
1080 | 1098 | break; |
1081 | 1099 | } |
1082 | 1100 | } |
… |
… |
function handleInputAfterGui(ev)
|
1108 | 1126 | { |
1109 | 1127 | g_Selection.reset(); |
1110 | 1128 | resetEntitySearch(); |
1111 | | inputState = INPUT_NORMAL; |
1112 | | _optionsOfpreSelected = []; |
| 1129 | resetPreselectedAction(); |
1113 | 1130 | return true; |
1114 | 1131 | } |
1115 | 1132 | |
… |
… |
function handleInputAfterGui(ev)
|
1183 | 1200 | g_Selection.reset(); |
1184 | 1201 | g_Selection.addList(ents); |
1185 | 1202 | } |
1186 | | |
1187 | | inputState = INPUT_NORMAL; |
1188 | | _optionsOfpreSelected = []; |
| 1203 | resetPreselectedAction(); |
1189 | 1204 | return true; |
1190 | 1205 | } |
1191 | 1206 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1196 | 1211 | switch (ev.type) |
1197 | 1212 | { |
1198 | 1213 | case "mousemotion": |
1199 | | |
1200 | 1214 | placementSupport.position = Engine.GetTerrainAtScreenPoint(ev.x, ev.y); |
1201 | | |
1202 | | if (placementSupport.mode === "wall") |
1203 | | { |
1204 | | // Including only the on-screen towers in the next snap candidate list is sufficient here, since the user is |
1205 | | // still selecting a starting point (which must necessarily be on-screen). (The update of the snap entities |
1206 | | // itself happens in the call to updateBuildingPlacementPreview below). |
1207 | | placementSupport.wallSnapEntitiesIncludeOffscreen = false; |
1208 | | } |
1209 | | else |
1210 | | { |
1211 | | var snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", { |
1212 | | "template": placementSupport.template, |
1213 | | "x": placementSupport.position.x, |
1214 | | "z": placementSupport.position.z, |
1215 | | }); |
1216 | | if (snapData) |
1217 | | { |
1218 | | placementSupport.angle = snapData.angle; |
1219 | | placementSupport.position.x = snapData.x; |
1220 | | placementSupport.position.z = snapData.z; |
1221 | | } |
1222 | | } |
1223 | | |
1224 | | updateBuildingPlacementPreview(); // includes an update of the snap entity candidates |
| 1215 | initBuildingPlacementView(ev); |
1225 | 1216 | return false; // continue processing mouse motion |
1226 | 1217 | |
1227 | 1218 | case "mousebuttondown": |
… |
… |
function handleInputAfterGui(ev)
|
1238 | 1229 | else |
1239 | 1230 | { |
1240 | 1231 | placementSupport.position = Engine.GetTerrainAtScreenPoint(ev.x, ev.y); |
1241 | | dragStart = [ ev.x, ev.y ]; |
1242 | | inputState = INPUT_BUILDING_CLICK; |
| 1232 | dragStart = [ ev.x, ev.y ]; |
| 1233 | inputState = INPUT_BUILDING_CLICK; |
| 1234 | _optionsOfpreSelected = []; |
1243 | 1235 | } |
1244 | 1236 | return true; |
1245 | 1237 | } |
… |
… |
function handleInputAfterGui(ev)
|
1247 | 1239 | { |
1248 | 1240 | // Cancel building |
1249 | 1241 | placementSupport.Reset(); |
1250 | | inputState = INPUT_NORMAL; |
1251 | | preSelectedAction = ACTION_NONE; |
1252 | | _optionsOfpreSelected = []; |
| 1242 | resetPreselectedAction(); |
1253 | 1243 | return true; |
1254 | 1244 | } |
1255 | 1245 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1268 | 1258 | placementSupport.angle -= rotation_step; |
1269 | 1259 | updateBuildingPlacementPreview(); |
1270 | 1260 | break; |
| 1261 | default: |
| 1262 | if (ev.hotkey.indexOf("selection.group.action.") == 0) |
| 1263 | { // can switch buildings |
| 1264 | var sptr = ev.hotkey.split("."); |
| 1265 | performGroup(sptr[2], sptr[3], ev); |
| 1266 | } |
1271 | 1267 | } |
1272 | 1268 | break; |
1273 | 1269 | |
… |
… |
function getActionForSelection(player, selection)
|
1618 | 1614 | switch (preSelectedAction) |
1619 | 1615 | { |
1620 | 1616 | case ACTION_GARRISON: |
1621 | | if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder)) |
| 1617 | if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder)) { |
| 1618 | inputState = INPUT_PRESELECTEDACTION; |
1622 | 1619 | ret.push(ent); |
| 1620 | } |
1623 | 1621 | break; |
1624 | 1622 | case ACTION_BUILD: |
1625 | | if (state.buildEntities && state.buildEntities.length) |
| 1623 | if (state.buildEntities && state.buildEntities.length) { |
| 1624 | inputState = INPUT_PRESELECTEDACTION; |
1626 | 1625 | return state.buildEntities; |
| 1626 | } |
1627 | 1627 | break; |
1628 | 1628 | case ACTION_TRAIN: |
1629 | 1629 | if (state.production && state.production.entities.length) |
… |
… |
function getActionForSelection(player, selection)
|
1638 | 1638 | if (!hasClass(state, "Unit") || hasClass(state, "Animal") || state.garrisonHolder) |
1639 | 1639 | break; |
1640 | 1640 | |
1641 | | if (preSelectedAction == ACTION_FORMATION) { |
1642 | | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
1643 | | } else { // FIXME: |
| 1641 | if (preSelectedAction == STANCE) |
1644 | 1642 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
1645 | | } |
| 1643 | if (ret.length) // minimimum is 2 units for formation to be enabled |
| 1644 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
| 1645 | ret.push(1); |
1646 | 1646 | break; |
1647 | 1647 | case ACTION_BARTER: |
1648 | 1648 | if (state.barterMarket) |
… |
… |
function getActionForSelection(player, selection)
|
1660 | 1660 | } |
1661 | 1661 | |
1662 | 1662 | // Performs the specified group |
1663 | | function performGroup(action, nr) |
| 1663 | function performGroup(action, nr, ev) |
1664 | 1664 | { |
1665 | 1665 | switch (action) |
1666 | 1666 | { |
… |
… |
function performGroup(action, nr)
|
1698 | 1698 | var actions = getActionForSelection(player, selection); |
1699 | 1699 | if (!actions || !actions.length) { |
1700 | 1700 | preSelectedAction = ACTION_NONE; |
1701 | | _optionsOfpreSelected = []; |
1702 | 1701 | break; |
1703 | 1702 | } |
1704 | 1703 | |
… |
… |
function performGroup(action, nr)
|
1707 | 1706 | else if (preSelectedAction == ACTION_TRADER) |
1708 | 1707 | setupUnitTradingPanel(state, selection); |
1709 | 1708 | |
1710 | | inputState = INPUT_PRESELECTEDACTION; |
1711 | 1709 | _optionsOfpreSelected = actions; |
1712 | 1710 | } |
1713 | 1711 | else |
… |
… |
function performGroup(action, nr)
|
1735 | 1733 | { |
1736 | 1734 | case ACTION_BUILD: |
1737 | 1735 | var tmpl = GetTemplateData(lst); |
1738 | | if (tmpl.requiredTechnology && !Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) |
1739 | | break; |
1740 | | |
1741 | | startBuildingPlacement(lst); |
1742 | | inputState = INPUT_BUILDING_PLACEMENT; |
1743 | | preSelectedAction = ACTION_NONE; |
1744 | | return; |
| 1736 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1737 | // N.B. sets inputState = INPUT_BUILDING_PLACEMENT: |
| 1738 | startBuildingPlacement(lst); |
| 1739 | placementSupport.position = Engine.GetTerrainAtScreenPoint(mouseX, mouseY); |
| 1740 | initBuildingPlacementView(ev); |
| 1741 | } |
| 1742 | break; |
1745 | 1743 | case ACTION_TRAIN: |
1746 | 1744 | var tmpl = GetTemplateData(lst); |
1747 | 1745 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
… |
… |
function performGroup(action, nr)
|
1753 | 1751 | g_Selection.reset(); |
1754 | 1752 | lst.splice(nr, lst.length - nr) |
1755 | 1753 | g_Selection.addList(lst); |
| 1754 | inputState = INPUT_PRESELECTEDACTION; |
1756 | 1755 | break; |
1757 | 1756 | case ACTION_UNGARRISON: |
1758 | | if (lst.length != 1 || nr == 0) { |
| 1757 | if (lst.length > 1 || nr == 0) { |
| 1758 | if (lst.length != 1) // TODO: uload all from all |
| 1759 | lst = lst[nr]; // selected buildings |
| 1760 | else |
| 1761 | lst = lst[0]; |
| 1762 | // FIXME: follow when ungarrisoning all |
1759 | 1763 | var state = GetEntityState(lst); |
1760 | | var gents = state.garrisonHolder.entities |
1761 | | unloadAll(lst[nr]); |
1762 | | // TODO: follow when ungarrisoning all |
1763 | | //var gents = g_Selection.toList(); |
1764 | | // Engine.CameraFollow(gents[0]); |
| 1764 | var gents = state.garrisonHolder.entities; |
| 1765 | unloadAll(lst); |
| 1766 | Engine.CameraFollow(0); |
| 1767 | g_Selection.reset(); |
| 1768 | g_Selection.addList(gents); |
| 1769 | Engine.CameraFollow(gents[0]); |
1765 | 1770 | } else { |
1766 | 1771 | lst = lst[0]; |
1767 | 1772 | var state = GetEntityState(lst); |
… |
… |
function performGroup(action, nr)
|
1788 | 1793 | case ACTION_TRADER: //TODO |
1789 | 1794 | break; |
1790 | 1795 | } |
1791 | | inputState = INPUT_NORMAL; |
1792 | | _optionsOfpreSelected = []; |
1793 | 1796 | } |
| 1797 | break; |
| 1798 | case "reset": |
| 1799 | resetPreselectedAction(); |
| 1800 | break; |
1794 | 1801 | } |
1795 | 1802 | } |
1796 | 1803 | |
… |
… |
function resetEntitySearch()
|
1837 | 1844 | |
1838 | 1845 | function findEntity(classes, mode) |
1839 | 1846 | { |
| 1847 | var player = Engine.GetPlayerID(); |
1840 | 1848 | // Cycle through idling classes before giving up |
1841 | 1849 | for (var i = 0; i <= classes.length; ++i) |
1842 | 1850 | { |
… |
… |
function findEntity(classes, mode)
|
1844 | 1852 | var newEntity = Engine.GuiInterfaceCall("FindEntity", data); |
1845 | 1853 | if (newEntity && newEntity != lastEntity) |
1846 | 1854 | { |
| 1855 | if (!getActionForSelection(player, [newEntity]).length) |
| 1856 | resetPreselectedAction(); |
| 1857 | |
1847 | 1858 | lastEntity = newEntity; |
1848 | 1859 | g_Selection.reset(); |
1849 | 1860 | g_Selection.addList([lastEntity]); |
-
commit 5656cbab54bcd160f89a6b6681f6329f8b4d15aa
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 10 12:24:03 2012 +0200
was too much indented (no semantic change)
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 7da7546..1888087 100644
a
|
b
|
function handleInputAfterGui(ev)
|
1014 | 1014 | break; |
1015 | 1015 | |
1016 | 1016 | case "hotkeydown": |
1017 | | if (ev.hotkey.indexOf("selection.group.") == 0) |
| 1017 | if (ev.hotkey.indexOf("selection.group.") == 0) |
| 1018 | { |
| 1019 | var now = new Date(); |
| 1020 | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey)) |
1018 | 1021 | { |
1019 | | var now = new Date(); |
1020 | | if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey)) |
1021 | | { |
1022 | | if (ev.hotkey.indexOf("selection.group.select.") == 0) |
1023 | | { |
1024 | | var sptr = ev.hotkey.split("."); |
1025 | | performGroup("snap", sptr[3]); |
1026 | | } |
1027 | | } |
1028 | | else |
| 1022 | if (ev.hotkey.indexOf("selection.group.select.") == 0) |
1029 | 1023 | { |
1030 | 1024 | var sptr = ev.hotkey.split("."); |
1031 | | performGroup(sptr[2], sptr[3]); |
1032 | | |
1033 | | doublePressTimer = now.getTime(); |
1034 | | prevHotkey = ev.hotkey; |
| 1025 | performGroup("snap", sptr[3]); |
1035 | 1026 | } |
1036 | 1027 | } |
1037 | | break; |
| 1028 | else |
| 1029 | { |
| 1030 | var sptr = ev.hotkey.split("."); |
| 1031 | performGroup(sptr[2], sptr[3]); |
| 1032 | |
| 1033 | doublePressTimer = now.getTime(); |
| 1034 | prevHotkey = ev.hotkey; |
| 1035 | } |
| 1036 | } |
| 1037 | break; |
1038 | 1038 | } |
1039 | 1039 | break; |
1040 | 1040 | |
-
commit 4fdb29daa1681969a6316a41e6f13daf5d513219
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sun Jun 10 05:55:54 2012 +0200
See default.cfg:
The keys H to backslash are implemented as numbers for hotkey actions. to
control the actions for currently selected buildings or workers/units.
Modified behaviour: watermark and camera reset hotkeys are altered.
For example to build a house:
select a villager (with mouse or with idle hot-key '.')
J, H and select the location to place the house.
H is garrison for all units. For a villager the option to build is J.
For buildings, K and L are train and ungarrison respectively. Military
units can use K, L for formation and stance. barter and trader options
aren't implemented yet.
The second press of the H to backslash button has a different meaning:
It indicates `how many' or `which', in the same order as the buttons in
the user interface. From H to backslash means 0 to 6, with shift,
capital H to doublequote means 7-12. Except when garrisoning, then
H to backslash means garrisoning 1 to 7 units.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 760ad38..0f1220e 100644
a
|
b
|
hotkey.pause = Pause ; Pause/unpause game
|
115 | 115 | hotkey.screenshot = F2 ; Take PNG screenshot |
116 | 116 | hotkey.bigscreenshot = "Shift+F2" ; Take large BMP screenshot |
117 | 117 | hotkey.togglefullscreen = "Alt+Return" ; Toggle fullscreen/windowed mode |
118 | | hotkey.screenshot.watermark = "K" ; Toggle product/company watermark for official screenshots |
| 118 | hotkey.screenshot.watermark = "R" ; Toggle product/company watermark for official screenshots |
119 | 119 | hotkey.wireframe = "Alt+W" ; Toggle wireframe mode |
120 | 120 | hotkey.silhouettes = "Alt+S" ; Toggle unit silhouettes |
121 | 121 | |
122 | 122 | ; > CAMERA SETTINGS |
123 | | hotkey.camera.reset = "H" ; Reset camera rotation to default. |
| 123 | hotkey.camera.reset = "X" ; Reset camera rotation to default. |
124 | 124 | hotkey.camera.follow = "F" ; Follow the first unit in the selection |
125 | 125 | hotkey.camera.zoom.in = Plus, Equals, NumPlus ; Zoom camera in (continuous control) |
126 | 126 | hotkey.camera.zoom.out = Minus, NumMinus ; Zoom camera out (continuous control) |
… |
… |
hotkey.selection.group.select.9 = 9
|
189 | 189 | hotkey.selection.group.save.9 = "Ctrl+9" |
190 | 190 | hotkey.selection.group.add.9 = "Shift+9" |
191 | 191 | |
| 192 | hotkey.selection.group.action.0 = H |
| 193 | hotkey.selection.group.action.1 = J |
| 194 | hotkey.selection.group.action.2 = K |
| 195 | hotkey.selection.group.action.3 = L |
| 196 | hotkey.selection.group.action.4 = Semicolon |
| 197 | hotkey.selection.group.action.5 = SingleQuote |
| 198 | hotkey.selection.group.action.6 = BackSlash |
| 199 | hotkey.selection.group.action.7 = "Shift+H" |
| 200 | hotkey.selection.group.action.8 = "Shift+J" |
| 201 | hotkey.selection.group.action.9 = "Shift+K" |
| 202 | hotkey.selection.group.action.10 = "Shift+L" |
| 203 | hotkey.selection.group.action.11 = Colon |
| 204 | hotkey.selection.group.action.12 = DoubleQuote |
| 205 | |
192 | 206 | ; > SESSION CONTROLS |
193 | 207 | hotkey.session.kill = Delete ; Destroy selected units |
194 | 208 | hotkey.session.garrison = Ctrl ; Modifier to garrison when clicking on building |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 165ac75..7da7546 100644
a
|
b
|
const SDLK_LALT = 308;
|
15 | 15 | const ACTION_NONE = 0; |
16 | 16 | const ACTION_GARRISON = 1; |
17 | 17 | const ACTION_BUILD = 2; |
| 18 | const ACTION_TRAIN = 4; |
| 19 | const ACTION_UNGARRISON = 8; |
| 20 | const ACTION_FORMATION = 16; |
| 21 | const ACTION_STANCE = 32; |
| 22 | const ACTION_BARTER = 64; |
| 23 | const ACTION_TRADER =128; |
18 | 24 | var preSelectedAction = ACTION_NONE; |
| 25 | var _optionsOfpreSelected = []; |
19 | 26 | |
20 | 27 | const INPUT_NORMAL = 0; |
21 | 28 | const INPUT_SELECTING = 1; |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
748 | 755 | var queued = Engine.HotkeyIsPressed("session.queue"); |
749 | 756 | if (tryPlaceBuilding(queued)) |
750 | 757 | { |
751 | | if (queued) |
| 758 | if (queued) { |
752 | 759 | inputState = INPUT_BUILDING_PLACEMENT; |
753 | | else |
| 760 | } else { |
754 | 761 | inputState = INPUT_NORMAL; |
| 762 | _optionsOfpreSelected = []; |
| 763 | } |
755 | 764 | } |
756 | 765 | else |
757 | 766 | { |
… |
… |
function handleInputBeforeGui(ev, hoveredObject)
|
767 | 776 | // Cancel building |
768 | 777 | placementSupport.Reset(); |
769 | 778 | inputState = INPUT_NORMAL; |
| 779 | _optionsOfpreSelected = []; |
770 | 780 | return true; |
771 | 781 | } |
772 | 782 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1039 | 1049 | break; |
1040 | 1050 | preSelectedAction = ACTION_NONE; |
1041 | 1051 | inputState = INPUT_NORMAL; |
| 1052 | _optionsOfpreSelected = []; |
1042 | 1053 | return doAction(action, ev); |
1043 | 1054 | } |
1044 | 1055 | else if (ev.button == SDL_BUTTON_RIGHT && preSelectedAction != ACTION_NONE) |
1045 | 1056 | { |
1046 | 1057 | preSelectedAction = ACTION_NONE; |
1047 | 1058 | inputState = INPUT_NORMAL; |
| 1059 | _optionsOfpreSelected = []; |
1048 | 1060 | break; |
1049 | 1061 | } |
1050 | 1062 | // else |
| 1063 | case "hotkeydown": |
| 1064 | if (!ev.hotkey) |
| 1065 | break; |
| 1066 | |
| 1067 | if (ev.hotkey.indexOf("selection.group.action.") == 0) |
| 1068 | { |
| 1069 | var sptr = ev.hotkey.split("."); |
| 1070 | performGroup(sptr[2], sptr[3]); |
| 1071 | } |
| 1072 | break; |
1051 | 1073 | default: |
1052 | 1074 | // Slight hack: If selection is empty, reset the input state |
1053 | 1075 | if (g_Selection.toList().length == 0) |
1054 | 1076 | { |
1055 | 1077 | preSelectedAction = ACTION_NONE; |
1056 | 1078 | inputState = INPUT_NORMAL; |
| 1079 | _optionsOfpreSelected = []; |
1057 | 1080 | break; |
1058 | 1081 | } |
1059 | 1082 | } |
… |
… |
function handleInputAfterGui(ev)
|
1086 | 1109 | g_Selection.reset(); |
1087 | 1110 | resetEntitySearch(); |
1088 | 1111 | inputState = INPUT_NORMAL; |
| 1112 | _optionsOfpreSelected = []; |
1089 | 1113 | return true; |
1090 | 1114 | } |
1091 | 1115 | |
… |
… |
function handleInputAfterGui(ev)
|
1161 | 1185 | } |
1162 | 1186 | |
1163 | 1187 | inputState = INPUT_NORMAL; |
| 1188 | _optionsOfpreSelected = []; |
1164 | 1189 | return true; |
1165 | 1190 | } |
1166 | 1191 | break; |
… |
… |
function handleInputAfterGui(ev)
|
1223 | 1248 | // Cancel building |
1224 | 1249 | placementSupport.Reset(); |
1225 | 1250 | inputState = INPUT_NORMAL; |
| 1251 | preSelectedAction = ACTION_NONE; |
| 1252 | _optionsOfpreSelected = []; |
1226 | 1253 | return true; |
1227 | 1254 | } |
1228 | 1255 | break; |
… |
… |
function performFormation(entity, formationName)
|
1577 | 1604 | } |
1578 | 1605 | } |
1579 | 1606 | |
| 1607 | // This returns a list of actions. Caller still has to check Technology availability |
| 1608 | function getActionForSelection(player, selection) |
| 1609 | { |
| 1610 | var ret = []; |
| 1611 | |
| 1612 | for each (var ent in selection) |
| 1613 | { |
| 1614 | var state = GetEntityState(ent); |
| 1615 | if (!state || (state.player != player && !g_DevSettings.controlAll)) |
| 1616 | continue; |
| 1617 | |
| 1618 | switch (preSelectedAction) |
| 1619 | { |
| 1620 | case ACTION_GARRISON: |
| 1621 | if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder)) |
| 1622 | ret.push(ent); |
| 1623 | break; |
| 1624 | case ACTION_BUILD: |
| 1625 | if (state.buildEntities && state.buildEntities.length) |
| 1626 | return state.buildEntities; |
| 1627 | break; |
| 1628 | case ACTION_TRAIN: |
| 1629 | if (state.production && state.production.entities.length) |
| 1630 | return state.production.entities; |
| 1631 | break; |
| 1632 | case ACTION_UNGARRISON: |
| 1633 | if (state.garrisonHolder && state.garrisonHolder.entities && state.garrisonHolder.entities.length) |
| 1634 | ret.push(ent); |
| 1635 | break; |
| 1636 | case ACTION_FORMATION: |
| 1637 | case ACTION_STANCE: |
| 1638 | if (!hasClass(state, "Unit") || hasClass(state, "Animal") || state.garrisonHolder) |
| 1639 | break; |
| 1640 | |
| 1641 | if (preSelectedAction == ACTION_FORMATION) { |
| 1642 | return Engine.GuiInterfaceCall("GetAvailableFormations"); |
| 1643 | } else { // FIXME: |
| 1644 | return ["violent", "aggressive", "passive", "defensive", "standground"]; |
| 1645 | } |
| 1646 | break; |
| 1647 | case ACTION_BARTER: |
| 1648 | if (state.barterMarket) |
| 1649 | ret.push(ent); |
| 1650 | break; |
| 1651 | case ACTION_TRADER: |
| 1652 | if (state.trader) |
| 1653 | ret.push([ent, state]); |
| 1654 | break; |
| 1655 | default: |
| 1656 | return ret; //shouldn't happen |
| 1657 | } |
| 1658 | } |
| 1659 | return ret; |
| 1660 | } |
| 1661 | |
1580 | 1662 | // Performs the specified group |
1581 | 1663 | function performGroup(action, nr) |
1582 | 1664 | { |
… |
… |
function performGroup(action, nr)
|
1604 | 1686 | g_Groups.addEntities(nr, selection); |
1605 | 1687 | updateGroups(); |
1606 | 1688 | break; |
| 1689 | case "action": |
| 1690 | if (!_optionsOfpreSelected.length) { |
| 1691 | // action hotkey (first pass): With current selection, check possible |
| 1692 | // ACTION_XXX's and set preSelectedAction when applicable |
| 1693 | preSelectedAction = (1 << nr); |
| 1694 | |
| 1695 | var selection = g_Selection.toList(); |
| 1696 | var player = Engine.GetPlayerID(); |
| 1697 | |
| 1698 | var actions = getActionForSelection(player, selection); |
| 1699 | if (!actions || !actions.length) { |
| 1700 | preSelectedAction = ACTION_NONE; |
| 1701 | _optionsOfpreSelected = []; |
| 1702 | break; |
| 1703 | } |
| 1704 | |
| 1705 | if (preSelectedAction == ACTION_BARTER) |
| 1706 | setupUnitBarterPanel(state); |
| 1707 | else if (preSelectedAction == ACTION_TRADER) |
| 1708 | setupUnitTradingPanel(state, selection); |
| 1709 | |
| 1710 | inputState = INPUT_PRESELECTEDACTION; |
| 1711 | _optionsOfpreSelected = actions; |
| 1712 | } |
| 1713 | else |
| 1714 | { |
| 1715 | // 2nd action hotkey. Do preselectedAction[nr] |
| 1716 | // The result depends on the action. |
| 1717 | |
| 1718 | var lst = _optionsOfpreSelected; |
| 1719 | if (!lst) // shouldn't happen |
| 1720 | break; |
| 1721 | |
| 1722 | if (preSelectedAction & (ACTION_UNGARRISON | ACTION_GARRISON)) |
| 1723 | { |
| 1724 | if (preSelectedAction & ACTION_GARRISON) |
| 1725 | ++nr; |
| 1726 | if (nr > lst.length) |
| 1727 | nr = lst.length; |
| 1728 | } else if (preSelectedAction != (ACTION_BUILD|ACTION_TRAIN)) { |
| 1729 | if (nr >= lst.length) |
| 1730 | break; |
| 1731 | lst = lst[nr]; |
| 1732 | } |
| 1733 | |
| 1734 | switch (preSelectedAction) |
| 1735 | { |
| 1736 | case ACTION_BUILD: |
| 1737 | var tmpl = GetTemplateData(lst); |
| 1738 | if (tmpl.requiredTechnology && !Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) |
| 1739 | break; |
| 1740 | |
| 1741 | startBuildingPlacement(lst); |
| 1742 | inputState = INPUT_BUILDING_PLACEMENT; |
| 1743 | preSelectedAction = ACTION_NONE; |
| 1744 | return; |
| 1745 | case ACTION_TRAIN: |
| 1746 | var tmpl = GetTemplateData(lst); |
| 1747 | if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) { |
| 1748 | var ents = g_Selection.toList(); |
| 1749 | addTrainingToQueue(ents, lst); |
| 1750 | } |
| 1751 | break; |
| 1752 | case ACTION_GARRISON: // we garison nr+1 count |
| 1753 | g_Selection.reset(); |
| 1754 | lst.splice(nr, lst.length - nr) |
| 1755 | g_Selection.addList(lst); |
| 1756 | break; |
| 1757 | case ACTION_UNGARRISON: |
| 1758 | if (lst.length != 1 || nr == 0) { |
| 1759 | var state = GetEntityState(lst); |
| 1760 | var gents = state.garrisonHolder.entities |
| 1761 | unloadAll(lst[nr]); |
| 1762 | // TODO: follow when ungarrisoning all |
| 1763 | //var gents = g_Selection.toList(); |
| 1764 | // Engine.CameraFollow(gents[0]); |
| 1765 | } else { |
| 1766 | lst = lst[0]; |
| 1767 | var state = GetEntityState(lst); |
| 1768 | var gents = state.garrisonHolder.entities; |
| 1769 | // FIXME unload nr times, requires some update. |
| 1770 | unload(lst, gents); |
| 1771 | } |
| 1772 | break; |
| 1773 | case ACTION_FORMATION: |
| 1774 | ents = g_Selection.toList(); |
| 1775 | var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", { |
| 1776 | "ents": g_Selection.toList(), |
| 1777 | "formationName": lst |
| 1778 | }); |
| 1779 | if (formationOk) |
| 1780 | performFormation(ents, lst); |
| 1781 | break |
| 1782 | case ACTION_STANCE: |
| 1783 | ents = g_Selection.toList(); |
| 1784 | performStance(ents, lst); |
| 1785 | break; |
| 1786 | case ACTION_BARTER: //TODO |
| 1787 | break; |
| 1788 | case ACTION_TRADER: //TODO |
| 1789 | break; |
| 1790 | } |
| 1791 | inputState = INPUT_NORMAL; |
| 1792 | _optionsOfpreSelected = []; |
| 1793 | } |
1607 | 1794 | } |
1608 | 1795 | } |
1609 | 1796 | |
-
commit 70644e097fb424a6690b717a71e8be553c5384c4
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 9 22:40:07 2012 +0200
Generalize findIdleUnit to findEntity and enable building hotkeys
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 1ae80ba..760ad38 100644
a
|
b
|
hotkey.selection.add = Shift ; Add units to selection
|
151 | 151 | hotkey.selection.milonly = Alt ; Add only military units to selection |
152 | 152 | hotkey.selection.remove = Ctrl ; Remove units from selection |
153 | 153 | hotkey.selection.idleworker = Period ; Select next idle worker |
| 154 | hotkey.selection.structure = Y ; Select structure |
| 155 | hotkey.selection.civilcenter = U ; Select towncenter |
| 156 | hotkey.selection.dropsiteres = I ; Select dropsite stone/wood/metal |
| 157 | hotkey.selection.dropsitefood = O ; Select dropsite food |
| 158 | hotkey.selection.market = P ; Select market |
154 | 159 | hotkey.selection.idlewarrior = Comma ; Select next idle warrior |
155 | 160 | hotkey.selection.offscreen = Alt ; Include offscreen units in selection |
156 | 161 | hotkey.selection.group.select.0 = 0 |
-
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 3dcecbb..165ac75 100644
a
|
b
|
function handleInputAfterGui(ev)
|
1084 | 1084 | if (!ents.length) |
1085 | 1085 | { |
1086 | 1086 | g_Selection.reset(); |
1087 | | resetIdleUnit(); |
| 1087 | resetEntitySearch(); |
1088 | 1088 | inputState = INPUT_NORMAL; |
1089 | 1089 | return true; |
1090 | 1090 | } |
… |
… |
function setCameraFollow(entity)
|
1642 | 1642 | var lastEntity = 0; |
1643 | 1643 | var currEntClass = 0; |
1644 | 1644 | |
1645 | | function resetIdleUnit() |
| 1645 | function resetEntitySearch() |
1646 | 1646 | { |
1647 | 1647 | lastEntity = 0; |
1648 | 1648 | currEntClass = 0; |
1649 | 1649 | } |
1650 | 1650 | |
1651 | | function findEntity(classes) |
| 1651 | function findEntity(classes, mode) |
1652 | 1652 | { |
1653 | 1653 | // Cycle through idling classes before giving up |
1654 | 1654 | for (var i = 0; i <= classes.length; ++i) |
1655 | 1655 | { |
1656 | | var data = { prevUnit: lastEntity, idleClass: classes[currEntClass] }; |
1657 | | var newIdleUnit = Engine.GuiInterfaceCall("FindIdleUnit", data); |
1658 | | |
1659 | | // Check if we have new valid entity |
1660 | | if (newIdleUnit && newIdleUnit != lastEntity) |
| 1656 | var data = { prevEntity: lastEntity, entClass: classes[currEntClass], searchMode: mode}; |
| 1657 | var newEntity = Engine.GuiInterfaceCall("FindEntity", data); |
| 1658 | if (newEntity && newEntity != lastEntity) |
1661 | 1659 | { |
1662 | | lastEntity = newIdleUnit; |
1663 | | g_Selection.reset() |
| 1660 | lastEntity = newEntity; |
| 1661 | g_Selection.reset(); |
1664 | 1662 | g_Selection.addList([lastEntity]); |
1665 | 1663 | Engine.CameraFollow(lastEntity); |
1666 | | |
1667 | 1664 | return; |
1668 | 1665 | } |
1669 | | |
1670 | 1666 | lastEntity = 0; |
1671 | 1667 | currEntClass = (currEntClass + 1) % classes.length; |
1672 | 1668 | } |
1673 | | |
1674 | 1669 | // TODO: display a message or play a sound to indicate no more idle units, or something |
1675 | 1670 | // Reset for next cycle |
1676 | | resetIdleUnit(); |
| 1671 | resetEntitySearch(); |
1677 | 1672 | } |
1678 | 1673 | |
1679 | 1674 | function unload(garrisonHolder, entities) |
-
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index d876959..1d34482 100644
a
|
b
|
|
86 | 86 | |
87 | 87 | <!-- Find idle warrior - TODO: Potentially move this to own UI button? --> |
88 | 88 | <object hotkey="selection.idlewarrior"> |
89 | | <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action> |
| 89 | <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"], 1);</action> |
| 90 | </object> |
| 91 | |
| 92 | <!-- Select civilcenter --> |
| 93 | <object hotkey="selection.civilcenter"> |
| 94 | <action on="Press">findEntity(["CivCentre"], 0);</action> |
| 95 | </object> |
| 96 | <!-- Select market --> |
| 97 | <object hotkey="selection.market"> |
| 98 | <action on="Press">findEntity(["BarterMarket", "Market", "NavalMarket"], 0);</action> |
| 99 | </object> |
| 100 | <!-- Select dropsitefood --> |
| 101 | <object hotkey="selection.dropsitefood"> |
| 102 | <action on="Press">findEntity(["CivCentre", "DropsiteFood"], 0);</action> |
| 103 | </object> |
| 104 | <!-- Select dropsitewood --> |
| 105 | <object hotkey="selection.dropsiteres"> |
| 106 | <action on="Press">findEntity(["CivCentre", "DropsiteWood", "DropsiteStone", "DropsiteMetal"], 0);</action> |
| 107 | </object> |
| 108 | <!-- Select structure --> |
| 109 | <object hotkey="selection.structure"> |
| 110 | <action on="Press">findEntity(["Structure"], 0);</action> |
90 | 111 | </object> |
91 | 112 | |
92 | 113 | <!-- ================================ ================================ --> |
… |
… |
|
525 | 546 | > |
526 | 547 | <!-- TODO: should highlight the button if there's non-zero idle workers --> |
527 | 548 | <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" /> |
528 | | <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> |
| 549 | <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"], 1);</action> |
529 | 550 | </object> |
530 | 551 | </object> |
531 | 552 | </object> |
-
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
index 4ce8c71..a2c29ba 100644
a
|
b
|
GuiInterface.prototype.PlaySound = function(player, data)
|
1426 | 1426 | PlaySound(data.name, data.entity); |
1427 | 1427 | }; |
1428 | 1428 | |
1429 | | function isIdleUnit(ent, idleClass) |
1430 | | { |
1431 | | var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); |
1432 | | var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); |
1433 | | |
1434 | | // TODO: Do something with garrisoned idle units |
1435 | | return (cmpUnitAI && cmpIdentity && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned() && idleClass && cmpIdentity.HasClass(idleClass)); |
1436 | | } |
1437 | | |
1438 | | GuiInterface.prototype.FindIdleUnit = function(player, data) |
| 1429 | GuiInterface.prototype.FindEntity = function(player, data) |
1439 | 1430 | { |
1440 | 1431 | var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); |
1441 | 1432 | var playerEntities = rangeMan.GetEntitiesByPlayer(player); |
… |
… |
GuiInterface.prototype.FindIdleUnit = function(player, data)
|
1444 | 1435 | // so that we cycle around in a predictable order |
1445 | 1436 | for each (var ent in playerEntities) |
1446 | 1437 | { |
1447 | | if (ent > data.prevUnit && isIdleUnit(ent, data.idleClass)) |
1448 | | return ent; |
| 1438 | var cmpId = Engine.QueryInterface(ent, IID_Identity); |
| 1439 | if (ent > data.prevEntity && cmpId && cmpId.HasClass(data.entClass)) { |
| 1440 | if (data.searchMode == 0) { |
| 1441 | return ent; |
| 1442 | } else if (data.searchMode == 1) { // Search idle villager/soldier |
| 1443 | var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); |
| 1444 | if (cmpUnitAI && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned()) |
| 1445 | return ent; |
| 1446 | } |
| 1447 | } |
1449 | 1448 | } |
1450 | 1449 | |
1451 | | // No idle entities left in the class |
| 1450 | // No entities left in the class |
1452 | 1451 | return 0; |
1453 | 1452 | }; |
1454 | 1453 | |
… |
… |
var exposedFunctions = {
|
1571 | 1570 | "SetWallPlacementPreview": 1, |
1572 | 1571 | "GetFoundationSnapData": 1, |
1573 | 1572 | "PlaySound": 1, |
1574 | | "FindIdleUnit": 1, |
| 1573 | "FindEntity": 1, |
1575 | 1574 | "GetTradingDetails": 1, |
1576 | 1575 | "CanAttack": 1, |
1577 | 1576 | |
-
commit c68f943a39043debfcbcad02408d7362c088396e
Author: Roel Kluin <roel.kluin@gmail.com>
Date: Sat Jun 9 18:25:59 2012 +0200
rename:
ACTION_REPAIR => ACTION_REPAIR
performGroup:groupId => nr
lastIdleUnit => lastEntity
currIdleClass => currEntClass
findIdleUnit() => findEntity()
These names will make more sense after next patches
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index ff39b74..3dcecbb 100644
a
|
b
|
const SDLK_LALT = 308;
|
14 | 14 | |
15 | 15 | const ACTION_NONE = 0; |
16 | 16 | const ACTION_GARRISON = 1; |
17 | | const ACTION_REPAIR = 2; |
| 17 | const ACTION_BUILD = 2; |
18 | 18 | var preSelectedAction = ACTION_NONE; |
19 | 19 | |
20 | 20 | const INPUT_NORMAL = 0; |
… |
… |
function determineAction(x, y, fromMinimap)
|
434 | 434 | else |
435 | 435 | return {"type": "none", "cursor": "action-garrison-disabled", "target": undefined}; |
436 | 436 | break; |
437 | | case ACTION_REPAIR: |
| 437 | case ACTION_BUILD: |
438 | 438 | if (getActionInfo("repair", target).possible) |
439 | 439 | return {"type": "repair", "cursor": "action-repair", "target": target}; |
440 | 440 | else |
… |
… |
function performCommand(entity, commandName)
|
1533 | 1533 | break; |
1534 | 1534 | case "repair": |
1535 | 1535 | inputState = INPUT_PRESELECTEDACTION; |
1536 | | preSelectedAction = ACTION_REPAIR; |
| 1536 | preSelectedAction = ACTION_BUILD; |
1537 | 1537 | break; |
1538 | 1538 | case "unload-all": |
1539 | 1539 | unloadAll(entity); |
… |
… |
function performFormation(entity, formationName)
|
1578 | 1578 | } |
1579 | 1579 | |
1580 | 1580 | // Performs the specified group |
1581 | | function performGroup(action, groupId) |
| 1581 | function performGroup(action, nr) |
1582 | 1582 | { |
1583 | 1583 | switch (action) |
1584 | 1584 | { |
… |
… |
function performGroup(action, groupId)
|
1587 | 1587 | case "add": |
1588 | 1588 | var toSelect = []; |
1589 | 1589 | g_Groups.update(); |
1590 | | for (var ent in g_Groups.groups[groupId].ents) |
| 1590 | for (var ent in g_Groups.groups[nr].ents) |
1591 | 1591 | toSelect.push(+ent); |
1592 | 1592 | |
1593 | 1593 | if (action != "add") |
… |
… |
function performGroup(action, groupId)
|
1600 | 1600 | break; |
1601 | 1601 | case "save": |
1602 | 1602 | var selection = g_Selection.toList(); |
1603 | | g_Groups.groups[groupId].reset(); |
1604 | | g_Groups.addEntities(groupId, selection); |
| 1603 | g_Groups.groups[nr].reset(); |
| 1604 | g_Groups.addEntities(nr, selection); |
1605 | 1605 | updateGroups(); |
1606 | 1606 | break; |
1607 | 1607 | } |
… |
… |
function setCameraFollow(entity)
|
1639 | 1639 | Engine.CameraFollow(0); |
1640 | 1640 | } |
1641 | 1641 | |
1642 | | var lastIdleUnit = 0; |
1643 | | var currIdleClass = 0; |
| 1642 | var lastEntity = 0; |
| 1643 | var currEntClass = 0; |
1644 | 1644 | |
1645 | 1645 | function resetIdleUnit() |
1646 | 1646 | { |
1647 | | lastIdleUnit = 0; |
1648 | | currIdleClass = 0; |
| 1647 | lastEntity = 0; |
| 1648 | currEntClass = 0; |
1649 | 1649 | } |
1650 | 1650 | |
1651 | | function findIdleUnit(classes) |
| 1651 | function findEntity(classes) |
1652 | 1652 | { |
1653 | 1653 | // Cycle through idling classes before giving up |
1654 | 1654 | for (var i = 0; i <= classes.length; ++i) |
1655 | 1655 | { |
1656 | | var data = { prevUnit: lastIdleUnit, idleClass: classes[currIdleClass] }; |
| 1656 | var data = { prevUnit: lastEntity, idleClass: classes[currEntClass] }; |
1657 | 1657 | var newIdleUnit = Engine.GuiInterfaceCall("FindIdleUnit", data); |
1658 | 1658 | |
1659 | 1659 | // Check if we have new valid entity |
1660 | | if (newIdleUnit && newIdleUnit != lastIdleUnit) |
| 1660 | if (newIdleUnit && newIdleUnit != lastEntity) |
1661 | 1661 | { |
1662 | | lastIdleUnit = newIdleUnit; |
| 1662 | lastEntity = newIdleUnit; |
1663 | 1663 | g_Selection.reset() |
1664 | | g_Selection.addList([lastIdleUnit]); |
1665 | | Engine.CameraFollow(lastIdleUnit); |
| 1664 | g_Selection.addList([lastEntity]); |
| 1665 | Engine.CameraFollow(lastEntity); |
1666 | 1666 | |
1667 | 1667 | return; |
1668 | 1668 | } |
1669 | 1669 | |
1670 | | lastIdleUnit = 0; |
1671 | | currIdleClass = (currIdleClass + 1) % classes.length; |
| 1670 | lastEntity = 0; |
| 1671 | currEntClass = (currEntClass + 1) % classes.length; |
1672 | 1672 | } |
1673 | 1673 | |
1674 | 1674 | // TODO: display a message or play a sound to indicate no more idle units, or something |
-
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 08f5d06..d876959 100644
a
|
b
|
|
86 | 86 | |
87 | 87 | <!-- Find idle warrior - TODO: Potentially move this to own UI button? --> |
88 | 88 | <object hotkey="selection.idlewarrior"> |
89 | | <action on="Press">findIdleUnit(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action> |
| 89 | <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action> |
90 | 90 | </object> |
91 | 91 | |
92 | 92 | <!-- ================================ ================================ --> |
… |
… |
|
525 | 525 | > |
526 | 526 | <!-- TODO: should highlight the button if there's non-zero idle workers --> |
527 | 527 | <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" /> |
528 | | <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> |
| 528 | <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action> |
529 | 529 | </object> |
530 | 530 | </object> |
531 | 531 | </object> |