Initial porting to the new component API.
[tagua/yd.git] / src / hlvariant / dropanimator.h
blob0533587da918675949337917719e92781b466cc6
1 w/*
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.
9 */
12 #ifndef HLVARIANT__DROPANIMATOR_H
13 #define HLVARIANT__DROPANIMATOR_H
15 #include <core/namedsprite.h>
16 #include "common.h"
18 namespace HLVariant {
20 template <typename Base>
21 class DropAnimatorMixin : public Base {
22 typedef typename Base::Variant Variant;
23 using Base::m_cinterface;
24 protected:
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);
31 public:
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);
39 // IMPLEMENTATION
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)) {
58 // add extra sprites
59 for (int i = index; i < n; i++)
60 m_cinterface->insertPoolPiece(color, i, pool.get(i));
62 // done
63 break;
66 NamedSprite sprite = m_cinterface->getPoolSprite(color, index);
67 int i;
69 // find a matching piece on the pool
70 for (i = index; i < n; i++) {
71 if (pool.get(i).name() == sprite.name())
72 break;
75 if (i < n) {
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));
80 index = i + 1;
82 else {
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) {
96 updatePool(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)
111 ).get(
112 static_cast<typename Piece::Type>(dropped.second)
113 ) == move.drop()) {
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()));
118 else {
119 NamedSprite drop = m_cinterface->setPiece(move.to(), move.drop(), false);
120 drop.sprite()->raise();
121 res.addPreAnimation(Animate::appear(drop));
125 if (captured)
126 res.addPostAnimation(Animate::destroy(captured));
127 res.group()->addPostAnimation(warp(final));
129 else {
130 res.setGroup(Base::forward(final, move));
133 return res;
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));
146 else {
147 res.setGroup(Base::back(final, move));
150 return res;
155 #endif // HLVARIANT__DROPANIMATOR_H