push d05c3c071486b33b66ab6e343e6cce821d847653
[tagua/yd.git] / src / variants / chess / animator.cpp
blob7a61d5912ff7e3df9445453538f90be5ac1a0c67
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 */
10 #include "animator.h"
11 #include <core/animation.h>
12 #include <core/behaviour.h>
13 #include <core/board.h>
14 #include <core/state.h>
15 #include <core/move.h>
16 #include <core/namedsprite.h>
17 #include <core/piece.h>
18 #include <core/taguaapi.h>
19 #include <core/taguacast.h>
20 #include "knight.h"
22 namespace Chess {
24 Animator::Animator(TaguaAPI* api, const INamer* namer)
25 : BaseAnimator(api, namer)
26 , m_warper(this) { }
28 void Animator::setWarper(IWarper* warper) {
29 m_warper = warper;
32 AnimationPtr Animator::forward(const Move& move, const IState* state) {
33 AnimationPtr res = m_api->group("default");
35 NamedSprite piece = m_api->takeSprite(move.src());
36 Point captureSquare = move.dst();
37 if (const IBehaviour* behaviour = state->behaviour())
38 captureSquare = behaviour->captureSquare(state, move);
39 NamedSprite captured = m_api->takeSprite(captureSquare);
40 m_api->setSprite(move.dst(), piece);
42 if (piece)
43 res->addPreAnimation(movement(piece, move));
45 if (captured)
46 res->addPostAnimation(m_api->disappear(captured, "destroy"));
48 if (move.promotion() && move.type() == "promotion") {
49 Piece promoted = state->board()->get(move.dst());
51 if (promoted != Piece()) {
52 NamedSprite old_sprite = m_api->getSprite(move.dst());
53 NamedSprite new_sprite = m_api->setPiece(move.dst(), promoted, false);
55 res->addPostAnimation(m_api->morph(old_sprite, new_sprite, "default"));
58 else if (move.type() == "king_castling") {
59 Point rookSquare = move.dst() + Point(1,0);
60 Point rookDestination = move.src() + Point(1,0);
62 NamedSprite rook = m_api->takeSprite(rookSquare);
63 m_api->setSprite(rookDestination, rook);
64 res->addPreAnimation(m_api->move(rook, rookDestination, "default"));
66 else if (move.type() == "queen_castling") {
67 Point rookSquare = move.dst() + Point(-2,0);
68 Point rookDestination = move.src() + Point(-1,0);
70 NamedSprite rook = m_api->takeSprite(rookSquare);
71 m_api->setSprite(rookDestination, rook);
72 res->addPreAnimation(m_api->move(rook, rookDestination, "default"));
75 res->addPostAnimation(m_warper->warp(state));
76 return res;
79 AnimationPtr Animator::back(const Move& move, const IState* state) {
80 AnimationPtr res = m_api->group("default");
82 NamedSprite piece = m_api->takeSprite(move.dst());
83 NamedSprite captured;
84 Point captureSquare = move.dst();
85 if (const IBehaviour* behaviour = state->behaviour())
86 captureSquare = behaviour->captureSquare(state, move);
87 Piece captured_piece = state->board()->get(captureSquare);
88 if (captured_piece != Piece()) {
89 captured = m_api->setPiece(captureSquare, captured_piece, false);
90 res->addPreAnimation(m_api->appear(captured, "default"));
93 if (!piece) {
94 piece = m_api->createPiece(move.dst(), state->board()->get(move.src()), false);
95 res->addPreAnimation(m_api->appear(piece, "default"));
98 m_api->setSprite(move.src(), piece);
100 if (move.promotion() && move.type() == "promotion") {
101 Piece pawn_piece = state->board()->get(move.src());
102 if (pawn_piece != Piece()) {
103 NamedSprite pawn = m_api->createPiece(move.dst(), pawn_piece, false);
104 res->addPreAnimation(m_api->morph(piece, pawn, "default"));
106 // replace piece with pawn
107 m_api->setSprite(move.src(), pawn);
108 piece = pawn;
111 else if (move.type() == "king_castling") {
112 Point rookSquare = move.dst() + Point(1,0);
113 Point rookDestination = move.src() + Point(1,0);
115 NamedSprite rook = m_api->takeSprite(rookDestination);
116 m_api->setSprite(rookSquare, rook);
118 res->addPreAnimation(m_api->move(rook, rookSquare, "default"));
120 else if (move.type() == "queen_castling") {
121 Point rookSquare = move.dst() + Point(-2,0);
122 Point rookDestination = move.src() + Point(-1,0);
124 NamedSprite rook = m_api->takeSprite(rookDestination);
125 m_api->setSprite(rookSquare, rook);
127 res->addPreAnimation(m_api->move(rook, rookSquare, "default"));
131 res->addPreAnimation(movement(piece, Move(move.dst(), move.src())));
132 res->addPostAnimation(m_warper->warp(state));
134 return res;
137 AnimationPtr Animator::movement(const NamedSprite& sprite, const Move& move) const {
138 bool knight = m_api->state()->board()->get(move.src()).type() == Knight::self();
139 QString flags = knight ? "lshaped rotating" : "straight";
140 return m_api->move(sprite, move.dst(), flags);
143 IAnimator* AnimatorFactory::create(TaguaAPI* api, const INamer* namer) const {
144 return new Animator(api, namer);
147 } // namespace Chess