2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2007 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.
12 #ifndef HLVARIANT__DROPANIMATOR_H
13 #define HLVARIANT__DROPANIMATOR_H
15 #include <core/namedsprite.h>
20 template <typename Base
>
21 class DropAnimatorMixin
: public Base
{
22 typedef typename
Base::Variant Variant
;
23 using Base::m_cinterface
;
25 typedef typename
Base::API API
;
26 typedef typename
Base::GameState GameState
;
27 typedef typename
Base::Piece Piece
;
28 typedef typename
Base::Move Move
;
30 virtual void updatePool(const GameState
& final
);
32 DropAnimatorMixin(API cinterface
);
34 virtual AnimationGroupPtr
warp(const GameState
& final
);
35 virtual AnimationGroupPtr
forward(const GameState
& final
, const Move
& move
);
36 virtual AnimationGroupPtr
back(const GameState
& final
, const Move
& move
);
41 template <typename Base
>
42 DropAnimatorMixin
<Base
>::DropAnimatorMixin(API cinterface
)
43 : Base(cinterface
) { }
46 template <typename Base
>
47 void DropAnimatorMixin
<Base
>::updatePool(const GameState
& final
) {
48 for(int color
= 0; color
< 2; color
++) {
49 typename
Piece::Color c
= static_cast<typename
Piece::Color
>(color
);
50 const typename
GameState::Pool pool
= final
.pools().pool(c
);
51 const int n
= pool
.size();
53 for (int index
= 0; index
< n
; ) {
54 // precondition: pool and graphical pool match up to index
56 // no more sprites on the graphical pool
57 if (index
>= m_cinterface
->poolSize(color
)) {
59 for (int i
= index
; i
< n
; i
++)
60 m_cinterface
->insertPoolPiece(color
, i
, pool
.get(i
));
66 NamedSprite sprite
= m_cinterface
->getPoolSprite(color
, index
);
69 // find a matching piece on the pool
70 for (i
= index
; i
< n
; i
++) {
71 if (pool
.get(i
).name() == sprite
.name())
76 // matching piece found on the pool
77 // insert all pieces before this one on the graphical pool
78 for (int j
= index
; j
< i
; j
++)
79 m_cinterface
->insertPoolPiece(color
, j
, pool
.get(j
));
83 // no such piece found: remove it from the graphical pool
84 m_cinterface
->removePoolSprite(color
, index
);
88 // remove extra pieces from the graphical pool
89 while (m_cinterface
->poolSize(color
) > n
)
90 m_cinterface
->removePoolSprite(color
, n
);
94 template <typename Base
>
95 AnimationGroupPtr DropAnimatorMixin
<Base
>::warp(const GameState
& final
) {
97 return Base::warp(final
);
100 template <typename Base
>
101 AnimationGroupPtr DropAnimatorMixin
<Base
>::forward(const GameState
& final
, const Move
& move
) {
102 AnimationFactory
res(m_cinterface
->inner());
104 if (move
.drop() != Piece()) {
105 NamedSprite captured
= m_cinterface
->takeSprite(move
.to());
107 std::pair
<int, int> dropped
= m_cinterface
->droppedPoolPiece();
108 if (dropped
.first
!= -1 && dropped
.second
!= -1
109 && m_cinterface
->position()->pools().pool(
110 static_cast<typename
Piece::Color
>(dropped
.first
)
112 static_cast<typename
Piece::Type
>(dropped
.second
)
114 NamedSprite drop
= m_cinterface
->takePoolSprite(dropped
.first
, dropped
.second
);
115 m_cinterface
->setSprite(move
.to(), drop
);
116 res
.addPreAnimation(Animate::move(drop
, move
.to()));
119 NamedSprite drop
= m_cinterface
->setPiece(move
.to(), move
.drop(), false);
120 drop
.sprite()->raise();
121 res
.addPreAnimation(Animate::appear(drop
));
126 res
.addPostAnimation(Animate::destroy(captured
));
127 res
.group()->addPostAnimation(warp(final
));
130 res
.setGroup(Base::forward(final
, move
));
136 template <typename Base
>
137 AnimationGroupPtr DropAnimatorMixin
<Base
>::back(const GameState
& final
, const Move
& move
) {
138 AnimationFactory
res(m_cinterface
->inner());
140 if(move
.drop() != Piece()) {
141 NamedSprite drop
= m_cinterface
->takeSprite(move
.to());
142 res
.addPostAnimation(Animate::disappear(drop
));
144 res
.group()->addPostAnimation(warp(final
));
147 res
.setGroup(Base::back(final
, move
));
155 #endif // HLVARIANT__DROPANIMATOR_H