Pawn now changes into a queen when its promoted.
[NALCG.git] / src / view / bufferedinputhandler.cpp
blob0abe0cc56a9a739a3c60f124dafcb5a96f1bb0c5
1 #include "bufferedinputhandler.h"
3 #include "animationmanager.h"
4 #include "animationfactory.h"
5 #include "movementanimation.h"
6 #include "promotionanimation.h"
7 #include "../middleman.h"
8 #include "view.h"
9 #include "viewconstants.h"
10 #include "../logic/chessboard.h"
12 bool BufferedInputHandler::keyPressed(const OIS::KeyEvent& arg)
14 CEGUI::System* sys = CEGUI::System::getSingletonPtr();
15 sys->injectKeyDown(arg.key);
16 sys->injectChar(arg.text);
18 switch (arg.key)
20 case OIS::KC_1:
21 mCamera->setPosition(ViewConstants::WHITE_CAMERA_POSITION);
22 mCamera->lookAt(Vector3::ZERO);
23 break;
24 case OIS::KC_2:
25 mCamera->setPosition(ViewConstants::BLACK_CAMERA_POSITION);
26 mCamera->lookAt(Vector3::ZERO);
27 break;
28 case OIS::KC_UP:
29 case OIS::KC_W:
30 mDirection.z -= CAMERA_MOVEMENT_SPEED;
31 break;
33 case OIS::KC_DOWN:
34 case OIS::KC_S:
35 mDirection.z += CAMERA_MOVEMENT_SPEED;
36 break;
38 case OIS::KC_LEFT:
39 case OIS::KC_A:
40 mDirection.x -= CAMERA_MOVEMENT_SPEED;
41 break;
43 case OIS::KC_RIGHT:
44 case OIS::KC_D:
45 mDirection.x += CAMERA_MOVEMENT_SPEED;
46 break;
48 case OIS::KC_PGDOWN:
49 case OIS::KC_F:
50 mDirection.y -= CAMERA_MOVEMENT_SPEED;
51 break;
53 case OIS::KC_PGUP:
54 case OIS::KC_R:
55 mDirection.y += CAMERA_MOVEMENT_SPEED;
56 break;
57 default:
58 ; // No handling
60 return true;
63 bool BufferedInputHandler::keyReleased(const OIS::KeyEvent& arg)
65 CEGUI::System::getSingleton().injectKeyUp(arg.key);
67 switch (arg.key)
69 case OIS::KC_UP:
70 case OIS::KC_W:
71 mDirection.z += CAMERA_MOVEMENT_SPEED;
72 break;
74 case OIS::KC_DOWN:
75 case OIS::KC_S:
76 mDirection.z -= CAMERA_MOVEMENT_SPEED;
77 break;
79 case OIS::KC_LEFT:
80 case OIS::KC_A:
81 mDirection.x += CAMERA_MOVEMENT_SPEED;
82 break;
84 case OIS::KC_RIGHT:
85 case OIS::KC_D:
86 mDirection.x -= CAMERA_MOVEMENT_SPEED;
87 break;
89 case OIS::KC_PGDOWN:
90 case OIS::KC_F:
91 mDirection.y += CAMERA_MOVEMENT_SPEED;
92 break;
94 case OIS::KC_PGUP:
95 case OIS::KC_R:
96 mDirection.y -= CAMERA_MOVEMENT_SPEED;
97 break;
98 default:
99 ; // No handling
101 return true;
104 // MouseListener
106 CEGUI::MouseButton BufferedInputHandler::convertButton(OIS::MouseButtonID buttonID) const
108 switch (buttonID)
110 case OIS::MB_Left:
111 return CEGUI::LeftButton;
113 case OIS::MB_Right:
114 return CEGUI::RightButton;
116 case OIS::MB_Middle:
117 return CEGUI::MiddleButton;
119 default:
120 return CEGUI::LeftButton;
123 bool BufferedInputHandler::mouseMoved(const OIS::MouseEvent& arg)
125 if (!mRMouseDown) {
126 CEGUI::System::getSingleton().injectMousePosition(arg.state.X.abs, arg.state.Y.abs);
127 //CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);
130 // If we are dragging the left mouse button.
131 if (mLMouseDown)
136 // If we are dragging the right mouse button.
137 else if (mRMouseDown)
139 const double rotationSpeed = 0.2;
140 mCamera->yaw(Degree(-arg.state.X.rel) * rotationSpeed);
141 mCamera->pitch(Degree(-arg.state.Y.rel) * rotationSpeed);
144 return true;
146 bool BufferedInputHandler::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
148 CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));
150 // Left mouse button down
151 if (id == OIS::MB_Left)
153 onLeftPressed(arg);
154 mLMouseDown = true;
157 // Right mouse button down
158 else if (id == OIS::MB_Right)
160 onRightPressed(arg);
161 mRMouseDown = true;
163 return true;
165 bool BufferedInputHandler::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
167 CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));
169 // Left mouse button up
170 if (id == OIS::MB_Left)
172 onLeftReleased(arg);
173 mLMouseDown = false;
176 // Right mouse button up
177 else if (id == OIS::MB_Right)
179 onRightReleased(arg);
180 mRMouseDown = false;
182 return true;
185 void BufferedInputHandler::moveCamera(const Real& timeSinceLastFrame)
187 mCamera->setPosition(mCamera->getPosition() +
188 mCamera->getOrientation() * mDirection * timeSinceLastFrame);
190 if (mCamera->getPosition().y < 10)
192 Vector3 newPosition = mCamera->getPosition();
193 newPosition.y = 10;
194 mCamera->setPosition(newPosition);
198 void BufferedInputHandler::onLeftPressed(const OIS::MouseEvent& arg)
200 CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
202 Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/arg.state.width, mousePos.d_y/arg.state.height);
204 mRaySceneQuery->setRay(mouseRay);
205 mRaySceneQuery->setSortByDistance(true);
206 mRaySceneQuery->setQueryMask(1 << 0);
208 RaySceneQueryResult& result = mRaySceneQuery->execute();
209 RaySceneQueryResult::iterator itr;
211 for (itr = result.begin(); itr != result.end(); itr++)
213 if (itr->movable)
215 if (mSafeMode)
217 mAnimationManager->finishAnimations();
220 if (mSelectedObject)
222 toggleMovementPossibilities();
223 SceneNode* targetNode = itr->movable->getParentSceneNode();
224 SceneNode* pieceNode = findPieceAbove(mSelectedObject);
225 if (mSelectedObject != targetNode)
227 std::stringstream name;
228 name << mSelectedObject->getName() << " " << targetNode->getName();
229 std::size_t fromX, fromY, toX, toY;
230 name >> fromX;
231 name >> fromY;
232 name >> toX;
233 name >> toY;
235 Middleman* middleman = mView->getMiddleman();
236 if (middleman)
238 unsigned int returnValue = mView->getMiddleman()->move(
239 fromX, fromY, toX, toY);
241 if (!(returnValue & Board::MOVE_OK))
243 if (returnValue & Board::INVALID_MOVE)
245 // TODO: handle
247 if (returnValue & Board::INVALID_TURN)
249 // TODO: handle
251 if (returnValue & Board::PROMOTION_REQUEST)
253 mView->getMiddleman()->move(fromX, fromY,
254 toX, toY, ChessBoard::PROMOTE_TO_QUEEN);
258 else
260 move(fromX, fromY, toX, toY);
263 mSelectedObject->showBoundingBox(false);
264 pieceNode->showBoundingBox(false);
265 Entity* ent = mSceneMgr->getEntity(mSelectedObject->getName() + " s");
266 ent->setMaterialName("board/square/move");
267 ent->setVisible(false);
268 mSelectedObject = 0;
270 else
272 SceneNode* squareNode = itr->movable->getParentSceneNode();
273 SceneNode* pieceNode = findPieceAbove(squareNode);
274 if (pieceNode)
276 mSelectedObject = squareNode;
277 mSelectedObject->showBoundingBox(true);
278 Entity* ent = mSceneMgr->getEntity(mSelectedObject->getName() + " s");
279 ent->setVisible(true);
280 ent->setMaterialName("board/square/selected");
281 pieceNode->showBoundingBox(true);
282 toggleMovementPossibilities();
285 break;
290 void BufferedInputHandler::move(int fromX, int fromY, int toX, int toY,
291 bool continuous, unsigned int promoteTo)
293 if (mQueueAnimations && mAnimationManager->animationsRunning())
295 std::vector<int> moveOrder;
296 moveOrder.push_back(fromX);
297 moveOrder.push_back(fromY);
298 moveOrder.push_back(toX);
299 moveOrder.push_back(toY);
300 moveOrder.push_back(continuous);
301 moveOrder.push_back(promoteTo);
303 mAnimationQueue.push_back(moveOrder);
305 else
307 std::ostringstream sourceName;
308 sourceName << fromX << " " << fromY;
309 SceneNode* pieceNode = findPieceAbove(mSceneMgr->getSceneNode(sourceName.str()));
311 std::ostringstream targetName;
312 targetName << toX << " " << toY;
313 SceneNode* targetNode = mSceneMgr->getSceneNode(targetName.str());
315 SceneNode* targetPiece = findPieceAbove(targetNode);
317 GenericAnimation* animation;
318 if (promoteTo)
320 animation = AnimationFactory::createPromotionAnimation(
321 promoteTo, pieceNode, mSceneMgr, mView);
323 else
325 animation = AnimationFactory::createMovementAnimation(
326 *pieceNode->getName().begin(), targetNode->getPosition(),
327 pieceNode, targetPiece, mSceneMgr, mAnimationManager);
330 mAnimationManager->addAnimation(animation);
332 if (continuous)
334 animation->enableCallback(this);
335 mQueueAnimations = true;
337 else
339 mQueueAnimations = false;
344 void BufferedInputHandler::animationFinished()
346 std::vector<int> moveOrder = mAnimationQueue.back();
347 mAnimationQueue.pop_back();
349 // fromX, fromY, toX, toY, continuous, promote
350 // TODO: a struct or class for this so it won't seem so magical
351 move(moveOrder.at(0), moveOrder.at(1),
352 moveOrder.at(2), moveOrder.at(3),
353 moveOrder.at(4) != 0, moveOrder.at(5));
356 bool BufferedInputHandler::toggleMovementPossibilities()
358 Middleman* middleman = mView->getMiddleman();
359 if (!middleman)
361 return false;
364 int x = -1;
365 int y = -1;
366 mView->convertPosition(mSelectedObject->getPosition(), &x, &y);
368 std::vector<std::size_t> validMoves = middleman->getValidMovesAt(x, y);
369 for (std::size_t i = 0; i < validMoves.size(); i++)
371 std::size_t column = 0;
372 std::size_t row = 0;
373 Board::getCoordinates(validMoves.at(i), column, row,
374 mView->getBoardWidth(), mView->getBoardHeight());
376 std::ostringstream name;
377 name << column << " " << row << " s";
378 Entity* ent = mSceneMgr->getEntity(name.str());
379 ent->setVisible(!ent->isVisible());
380 if (ent->isVisible() && ent->getParentNode())
382 if (findPieceAbove(ent->getParentNode()->getParent()))
384 ent->setMaterialName("board/square/attack");
389 return true;
393 SceneNode* BufferedInputHandler::findPieceAbove(Node* squareNode) const
395 // TODO: When everything is done, we should do a null check here
396 // for the squareNode in case query mask for some env is not correctly set
398 const Vector3& squarePosition = squareNode->getPosition();
399 Node::ChildNodeIterator it = mSceneMgr->getRootSceneNode()->getChildIterator();
400 while (it.hasMoreElements())
402 Node* next = it.getNext();
403 if (squareNode != next && next->getPosition() == squarePosition)
405 return dynamic_cast<SceneNode*>(next);
408 return 0;
411 void BufferedInputHandler::onLeftReleased(const OIS::MouseEvent& arg)
415 void BufferedInputHandler::onRightPressed(const OIS::MouseEvent& arg)
419 void BufferedInputHandler::onRightReleased(const OIS::MouseEvent& arg)