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 "animationfactory.h"
16 #include "namedsprite.h"
21 template <typename Base
>
22 class DropAnimatorMixin
: public Base
{
23 typedef typename
Base::Variant Variant
;
24 using Base::m_cinterface
;
26 typedef typename
Base::API API
;
27 typedef typename
Base::GameState GameState
;
28 typedef typename
Base::Piece Piece
;
29 typedef typename
Base::Move Move
;
31 virtual void updatePool(const GameState
& final
);
33 DropAnimatorMixin(API cinterface
);
35 virtual AnimationGroupPtr
warp(const GameState
& final
);
36 virtual AnimationGroupPtr
forward(const GameState
& final
, const Move
& move
);
37 virtual AnimationGroupPtr
back(const GameState
& final
, const Move
& move
);
42 template <typename Base
>
43 DropAnimatorMixin
<Base
>::DropAnimatorMixin(API cinterface
)
44 : Base(cinterface
) { }
47 template <typename Base
>
48 void DropAnimatorMixin
<Base
>::updatePool(const GameState
& final
) {
49 for(int color
= 0; color
< 2; color
++) {
50 typename
Piece::Color c
= static_cast<typename
Piece::Color
>(color
);
51 const typename
GameState::Pool pool
= final
.pools().pool(c
);
52 const int n
= pool
.size();
54 for (int index
= 0; index
< n
; ) {
55 // precondition: pool and graphical pool match up to index
57 // no more sprites on the graphical pool
58 if (index
>= m_cinterface
->poolSize(color
)) {
60 for (int i
= index
; i
< n
; i
++)
61 m_cinterface
->insertPoolPiece(color
, i
, pool
.get(i
));
67 NamedSprite sprite
= m_cinterface
->getPoolSprite(color
, index
);
70 // find a matching piece on the pool
71 for (i
= index
; i
< n
; i
++) {
72 if (pool
.get(i
).name() == sprite
.name())
77 // matching piece found on the pool
78 // insert all pieces before this one on the graphical pool
79 for (int j
= index
; j
< i
; j
++)
80 m_cinterface
->insertPoolPiece(color
, j
, pool
.get(j
));
84 // no such piece found: remove it from the graphical pool
85 m_cinterface
->removePoolSprite(color
, index
);
89 // remove extra pieces from the graphical pool
90 while (m_cinterface
->poolSize(color
) > n
)
91 m_cinterface
->removePoolSprite(color
, n
);
95 template <typename Base
>
96 AnimationGroupPtr DropAnimatorMixin
<Base
>::warp(const GameState
& final
) {
98 return Base::warp(final
);
101 template <typename Base
>
102 AnimationGroupPtr DropAnimatorMixin
<Base
>::forward(const GameState
& final
, const Move
& move
) {
103 AnimationFactory
res(m_cinterface
->inner());
105 if (move
.drop() != Piece()) {
106 NamedSprite captured
= m_cinterface
->takeSprite(move
.to());
108 std::pair
<int, int> dropped
= m_cinterface
->droppedPoolPiece();
109 if (dropped
.first
!= -1 && dropped
.second
!= -1
110 && m_cinterface
->position()->pools().pool(
111 static_cast<typename
Piece::Color
>(dropped
.first
)
113 static_cast<typename
Piece::Type
>(dropped
.second
)
115 NamedSprite drop
= m_cinterface
->takePoolSprite(dropped
.first
, dropped
.second
);
116 m_cinterface
->setSprite(move
.to(), drop
);
117 res
.addPreAnimation(Animate::move(drop
, move
.to()));
120 NamedSprite drop
= m_cinterface
->setPiece(move
.to(), move
.drop(), false);
121 drop
.sprite()->raise();
122 res
.addPreAnimation(Animate::appear(drop
));
127 res
.addPostAnimation(Animate::destroy(captured
));
128 res
.group()->addPostAnimation(warp(final
));
131 res
.setGroup(Base::forward(final
, move
));
137 template <typename Base
>
138 AnimationGroupPtr DropAnimatorMixin
<Base
>::back(const GameState
& final
, const Move
& move
) {
139 AnimationFactory
res(m_cinterface
->inner());
141 if(move
.drop() != Piece()) {
142 NamedSprite drop
= m_cinterface
->takeSprite(move
.to());
143 res
.addPostAnimation(Animate::disappear(drop
));
145 res
.group()->addPostAnimation(warp(final
));
148 res
.setGroup(Base::back(final
, move
));
156 #endif // HLVARIANT__DROPANIMATOR_H