Ported Animator, UnwrappedGraphicalApi and MoveFactory.
[tagua/yd.git] / src / variants / xchess / animator.impl.h
blobc7d962fd47313afbc854eafa6a5de7198ee7a406
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #ifndef XCHESS__ANIMATOR_IMPL_H
12 #define XCHESS__ANIMATOR_IMPL_H
14 #include "animator.h"
15 #include "animationfactory.h"
16 #include "common.h"
17 #include "namedsprite.h"
18 #include "variants/xchess/piecetype.h"
20 template <typename Variant>
21 AnimationGroupPtr BaseAnimator<Variant>::warp(const Position& final) {
22 const Position* current = m_cinterface->position();
23 AnimationFactory res(m_cinterface->inner());
25 for (Point i = current->first(); i <= current->last(); i = current->next(i)) {
26 Piece c = current->get(i);
27 Piece f = final.get(i);
29 if( !c && f ) {
30 //current->set(i, f);
31 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
32 res.addPreAnimation(Animate::appear(sprite), Animate::Instant);
34 else if (c && !f) {
35 NamedSprite old_sprite = m_cinterface->takeSprite(i);
36 res.addPreAnimation(Animate::disappear(old_sprite), Animate::Instant);
38 else if(c && f && !(c == f) ) {
39 NamedSprite old_sprite = m_cinterface->takeSprite(i);
40 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
41 res.addPreAnimation(Animate::morph(old_sprite, sprite), Animate::Instant);
45 return res;
48 template <typename Variant>
49 AnimationGroupPtr BaseAnimator<Variant>::forward(const Position& final, const Move&) {
50 return warp(final);
54 template <typename Variant>
55 AnimationGroupPtr BaseAnimator<Variant>::back(const Position& final, const Move&) {
56 return warp(final);
59 template <typename Variant>
60 AnimationGroupPtr SimpleAnimator<Variant>::warp(const Position& final) {
61 AnimationFactory res(m_cinterface->inner());
63 res.setGroup(Base::warp(final));
65 return res;
68 template <typename Variant>
69 SchemePtr SimpleAnimator<Variant>::movement(const NamedSprite& sprite, const Point& from, const Point& to) {
70 bool knight = m_cinterface->position()->get(from).type() == KNIGHT;
71 int mtype = knight
72 ? Animate::move::LShaped | Animate::move::Rotating
73 : Animate::move::Straight;
74 return SchemePtr(new Animate::move(sprite, to, mtype));
77 template <typename Variant>
78 AnimationGroupPtr SimpleAnimator<Variant>::forward(const Position& final, const Move& move) {
79 AnimationFactory res(m_cinterface->inner());
81 NamedSprite piece = m_cinterface->takeSprite(move.from);
82 NamedSprite captured = m_cinterface->takeSprite(move.to);
83 m_cinterface->setSprite(move.to, piece);
85 if (piece)
86 res.addPreAnimation(*movement(piece, move.from, move.to));
87 else
88 ERROR("Bug!!!");
90 if (captured)
91 res.addPostAnimation(Animate::destroy(captured));
93 if (move.type() == Move::EnPassantCapture) {
94 Point phantom(move.to.x, move.from.y);
95 NamedSprite capturedPawn = m_cinterface->takeSprite(phantom);
97 if (capturedPawn) {
98 QPoint real = m_cinterface->converter()->toReal(phantom);
99 res.addPostAnimation(Animate::disappear(capturedPawn));
101 else
102 ERROR("Bug!!!");
104 else if (move.type() == Move::Promotion) {
105 Piece promoted = final.get(move.to);
107 if (promoted) {
108 QPoint real = m_cinterface->converter()->toReal(move.to);
109 NamedSprite old_sprite = m_cinterface->getSprite(move.to);
110 NamedSprite new_sprite = m_cinterface->setPiece(move.to, promoted, /*false,*/ false);
112 res.addPostAnimation(Animate::morph(old_sprite, new_sprite));
114 else
115 ERROR("Bug!!!");
117 else if (move.type() == Move::KingSideCastling) {
118 Point rookSquare = move.to + Point(1,0);
119 Point rookDestination = move.from + Point(1,0);
121 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
122 m_cinterface->setSprite(rookDestination, rook);
123 res.addPreAnimation(Animate::move(rook, rookDestination));
125 else if (move.type() == Move::QueenSideCastling) {
126 Point rookSquare = move.to + Point(-2,0);
127 Point rookDestination = move.from + Point(-1,0);
129 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
130 m_cinterface->setSprite(rookDestination, rook);
131 res.addPreAnimation(Animate::move(rook, rookDestination));
134 return res;
137 template <typename Variant>
138 AnimationGroupPtr SimpleAnimator<Variant>::back(const Position& final, const Move& move) {
139 AnimationFactory res(m_cinterface->inner());
141 NamedSprite piece = m_cinterface->takeSprite(move.to);
142 NamedSprite captured;
143 if (Piece captured_piece = final.get(move.to)) {
144 captured = m_cinterface->setPiece(move.to, captured_piece, false);
145 res.addPreAnimation(Animate::appear(captured));
148 if (!piece) {
149 piece = m_cinterface->createPiece(move.to, final.get(move.from), false);
150 res.addPreAnimation(Animate::appear(piece));
153 m_cinterface->setSprite(move.from, piece);
156 if (move.type() == Move::EnPassantCapture) {
157 Point phantom(move.to.x, move.from.y);
159 if (Piece pawn_piece = final.get(phantom)) {
160 NamedSprite captured_pawn = m_cinterface->setPiece(phantom, pawn_piece, false);
161 res.addPreAnimation(Animate::appear(captured_pawn));
164 else if (move.type() == Move::Promotion) {
165 Piece pawn_piece = final.get(move.from);
166 if (pawn_piece) {
167 NamedSprite pawn = m_cinterface->createPiece(move.to, pawn_piece, false);
168 res.addPreAnimation(Animate::morph(piece, pawn));
170 // replace piece with pawn
171 m_cinterface->setSprite(move.from, pawn);
172 piece = pawn;
175 else if (move.type() == Move::KingSideCastling) {
176 Point rookSquare = move.to + Point(1,0);
177 Point rookDestination = move.from + Point(1,0);
179 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
180 m_cinterface->setSprite(rookSquare, rook);
182 res.addPreAnimation(Animate::move(rook, rookSquare));
184 else if (move.type() == Move::QueenSideCastling) {
185 Point rookSquare = move.to + Point(-2,0);
186 Point rookDestination = move.from + Point(-1,0);
188 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
189 m_cinterface->setSprite(rookSquare, rook);
191 res.addPreAnimation(Animate::move(rook, rookSquare));
194 res.addPreAnimation(*movement(piece, move.to, move.from));
196 return res;
200 #endif // XCHESS__ANIMATOR_IMPL_H