Ported DropAnimatorMixin.
[tagua/yd.git] / src / hlvariant / dropanimator.h
blobd53fcfac5e8727160452e88ccafe603f881681ff
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@sns.it>
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 namespace HLVariant {
17 template <typename Base>
18 class DropAnimatorMixin : public Base {
19 typedef typename Base::Variant Variant;
20 using Base::m_cinterface;
21 protected:
22 typedef typename Base::API API;
23 typedef typename Base::GameState GameState;
24 typedef typename Base::Piece Piece;
25 typedef typename Base::Move Move;
27 virtual void updatePool(const GameState& final);
28 public:
29 DropAnimatorMixin(API cinterface);
31 virtual AnimationGroupPtr warp(const GameState& final);
32 virtual AnimationGroupPtr forward(const GameState& final, const Move& move);
33 virtual AnimationGroupPtr back(const GameState& final, const Move& move);
36 // IMPLEMENTATION
38 template <typename Base>
39 DropAnimatorMixin<Base>::DropAnimatorMixin(API cinterface)
40 : Base(cinterface) { }
43 template <typename Base>
44 void DropAnimatorMixin<Base>::updatePool(const GameState& final) {
45 for(int color = 0; color < 2; color++) {
46 typename Piece::Color c = static_cast<typename Piece::Color>(color);
47 const typename GameState::PlayerPool& before = m_cinterface->position()->rawPool(c);
48 const typename GameState::PlayerPool& after = final.rawPool(c);
49 typename GameState::PlayerPool::const_iterator before_it = before.begin();
50 typename GameState::PlayerPool::const_iterator after_it = after.begin();
52 int pos = 0;
54 // oh, a nice bunch of write-only magic shit
55 while (before_it != before.end() || after_it != after.end()) {
56 bool skip_after = (after_it == after.end() || (before_it != before.end()
57 && before_it->first < after_it->first ));
58 bool skip_before = (before_it == before.end() || (after_it != after.end()
59 && after_it->first < before_it->first ));
60 int na = skip_after ? 0 : after_it->second;
61 int nb = skip_before ? 0 : before_it->second;
63 if (nb < na) {
64 for(int i = nb; i < na; i++)
65 m_cinterface->insertPoolPiece(color, pos + (i - nb), Piece(c, after_it->first) );
67 else if (na < nb) {
68 for (int i = na; i < nb; i++)
69 m_cinterface->removePoolSprite(color, pos);
72 if (!skip_before)
73 ++before_it;
74 if (!skip_after) {
75 pos += after_it->second;
76 ++after_it;
82 template <typename Base>
83 AnimationGroupPtr DropAnimatorMixin<Base>::warp(const GameState& final) {
84 updatePool(final);
85 return Base::warp(final);
88 template <typename Base>
89 AnimationGroupPtr DropAnimatorMixin<Base>::forward(const GameState& final, const Move& move) {
90 AnimationFactory res(m_cinterface->inner());
92 if (move.drop() != Piece()) {
93 std::pair<int, int> dropped = m_cinterface->droppedPoolPiece();
94 if (dropped.first != -1 && dropped.second != -1
95 && m_cinterface->position()->pool(dropped.first).get(dropped.second) == move.drop()) {
96 NamedSprite drop = m_cinterface->takePoolSprite(dropped.first, dropped.second);
97 m_cinterface->setSprite(move.to(), drop);
98 res.addPreAnimation(Animate::move(drop, move.to()));
99 return res;
101 else {
102 NamedSprite drop = m_cinterface->setPiece(move.to(), move.drop(), false);
103 res.addPreAnimation(Animate::appear(drop));
106 else {
107 res.setGroup(Base::forward(final, move));
110 updatePool(final);
111 return res;
114 template <typename Base>
115 AnimationGroupPtr DropAnimatorMixin<Base>::back(const GameState& final, const Move& move) {
116 AnimationFactory res(m_cinterface->inner());
118 if(move.drop() != Piece()) {
119 NamedSprite drop = m_cinterface->takeSprite(move.to());
120 res.addPostAnimation(Animate::disappear(drop));
122 else {
123 res.setGroup(Base::back(final, move));
126 updatePool(final);
127 return res;
132 #endif // HLVARIANT__DROPANIMATOR_H