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.
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>
24 Animator::Animator(TaguaAPI
* api
, const INamer
* namer
)
25 : BaseAnimator(api
, namer
)
28 void Animator::setWarper(IWarper
* 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
);
43 res
->addPreAnimation(movement(piece
, move
));
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
));
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());
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"));
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
);
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
));
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
);