Move all() up to IVariantLoader.
[tagua/yd.git] / src / core / dropanimator.cpp
blobb1b329620c56bf6afa2a8770731ce744a6ee7d40
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 */
10 #include "animation.h"
12 #include "dropanimator.h"
13 #include "move.h"
14 #include "namer.h"
15 #include "piece.h"
16 #include "pool.h"
17 #include "poolcollection.h"
18 #include "state.h"
19 #include "taguaapi.h"
21 DropAnimator::~DropAnimator() { delete m_base; }
23 DropAnimator::DropAnimator(IAnimator* base,
24 TaguaAPI* api,
25 const INamer* namer,
26 const IColor** players)
27 : BaseAnimator(api, namer)
28 , m_base(base)
29 , m_players(players) {
30 m_warper = this;
33 AnimationPtr DropAnimator::warp(const IState* state) {
34 updatePool(state);
35 return BaseAnimator::warp(state);
38 AnimationPtr DropAnimator::forward(const Move& move, const IState* state) {
39 if (move.drop() != Piece()) {
40 AnimationPtr res = m_api->group("default");
42 NamedSprite captured = m_api->takeSprite(move.dst());
44 std::pair<const IColor*, int> dropped = m_api->droppedPoolPiece();
45 if (dropped.first && dropped.second != -1 &&
46 m_api->state()->pools()->
47 pool(dropped.first)->get(dropped.second) == move.drop()) {
48 NamedSprite drop = m_api->takePoolSprite(dropped.first, dropped.second);
49 m_api->setSprite(move.dst(), drop);
50 res->addPreAnimation(m_api->move(drop, move.dst(), "default"));
52 else {
53 NamedSprite drop = m_api->setPiece(move.dst(), move.drop(), false);
54 res->addPreAnimation(m_api->appear(drop, "default"));
57 if (captured)
58 res->addPostAnimation(m_api->disappear(captured, "destroy"));
59 res->addPostAnimation(m_warper->warp(state));
61 return res;
63 else {
64 return m_base->forward(move, state);
68 AnimationPtr DropAnimator::back(const Move& move, const IState* state) {
69 if (move.drop() != Piece()) {
70 AnimationPtr res = m_api->group("default");
71 NamedSprite drop = m_api->takeSprite(move.dst());
72 res->addPostAnimation(m_api->disappear(drop, "default"));
74 res->addPostAnimation(m_warper->warp(state));
75 return res;
78 return m_base->back(move, state);
81 void DropAnimator::updatePool(const IState* final) {
82 for (int color = 0; color < 2; color++) {
83 const IColor* c = m_players[color];
84 const IPool* pool = final->pools()->pool(c);
85 const int n = pool->size();
87 for (int index = 0; index < n; ) {
88 // precondition: pool and graphical pool match up to index
90 // no more sprites on the graphical pool
91 if (index >= m_api->poolSize(color)) {
92 // add extra sprites
93 for (int i = index; i < n; i++)
94 m_api->insertPoolPiece(c, i, pool->get(i));
96 // done
97 break;
100 NamedSprite sprite = m_api->getPoolSprite(c, index);
101 int i;
103 // find a matching piece on the pool
104 for (i = index; i < n; i++) {
105 if (m_namer->name(pool->get(i)) == sprite.name())
106 break;
109 if (i < n) {
110 // matching piece found on the pool
111 // insert all pieces before this one on the graphical pool
112 for (int j = index; j < i; j++)
113 m_api->insertPoolPiece(c, j, pool->get(j));
114 index = i + 1;
116 else {
117 // no such piece found: remove it from the graphical pool
118 m_api->removePoolSprite(c, index);
122 // remove extra pieces from the graphical pool
123 while (m_api->poolSize(color) > n)
124 m_api->removePoolSprite(c, n);
128 void DropAnimator::setWarper(IWarper* warper) { m_warper = warper; }