Fixed off by 1 bug in the Pool.
[tagua/yd.git] / src / piecepool.cpp
blob6b8f2ec7ecfe8d6397a3a783bd3b42364277e019
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 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 #include "board.h"
13 #include "animation.h"
14 #include "piecepool.h"
16 /*****************************************************************************************/
17 PiecePool::PiecePool(Board* b, KGameCanvasAbstract* parent)
18 : ClickableCanvas(parent)
19 , m_board(b)
20 , m_flipped(false)
21 , m_square_size(0)
22 , m_width(1)
23 , m_dragged_index(-1) {
24 m_main_animation = new MainAnimation( 1.0 );
25 setGridWidth(1);
28 /*****************************************************************************************/
29 PiecePool::~PiecePool() {
30 delete m_main_animation;
33 /*****************************************************************************************/
34 QPoint PiecePool::toReal(int i) {
35 int x = i%m_width;
36 int y = i/m_width;
37 if(y&1)
38 x = m_width-1-x;
39 if(m_flipped)
40 y = -1-y;
42 return QPoint(m_square_size*x, m_square_size*y);
45 /*****************************************************************************************/
46 int PiecePool::toLogical(const QPoint& p) {
47 int x = p.x()/m_square_size;
48 int y = p.y()/m_square_size;
50 if(x<0 || x>= m_width)
51 return -1;
52 if(m_flipped)
53 y = -1-y;
54 if(y&1)
55 x = m_width-1-x;
57 int retv = y*m_width + x;
58 if(retv < 0 || retv >= (int)m_sprites.size())
59 return -1;
60 return retv;
63 /*****************************************************************************************/
64 void PiecePool::settingsChanged() {
65 //PieceGroup::settingsChanged();
68 /*****************************************************************************************/
69 void PiecePool::setGridWidth(int w) {
70 m_width = w;
73 /*****************************************************************************************/
74 int PiecePool::fill() {
75 return m_sprites.size();
78 /*****************************************************************************************/
79 void PiecePool::clear() {
80 m_sprites.clear();
83 /*****************************************************************************************/
84 void PiecePool::insertSprite(int index, const NamedSprite& nsprite) {
85 if(m_dragged && index > m_dragged_index)
86 index--;
88 if(index < 0 || index > fill() ) {
89 ERROR("invalid index " << index);
90 return;
93 m_sprites.resize(m_sprites.size()+1);
95 for(int i = m_sprites.size()-1; i > index; i--) {
96 double speed = (1.0+1.0/(i - index + 1))*0.4;
97 m_sprites[i] = m_sprites[i-1];
98 m_sprites[i].sprite()->moveTo(toReal(i)); //BROKEN animate to that point?
101 m_sprites[index] = nsprite;
102 m_sprites[index].sprite()->show();
103 m_sprites[index].sprite()->moveTo(toReal(index));
104 //BROKEN fadeIn(index);
107 /*****************************************************************************************/
108 NamedSprite PiecePool::getSprite(int index) {
109 if(m_dragged && index == m_dragged_index)
110 return m_dragged;
112 if(m_dragged && index > m_dragged_index)
113 index--;
115 if(index < 0 || index >= (int)m_sprites.size() ) {
116 ERROR("invalid index " << index);
117 return NamedSprite();
120 return m_sprites[index];
123 /*****************************************************************************************/
124 NamedSprite PiecePool::takeSprite(int index) {
125 if(m_dragged && index == m_dragged_index) {
126 NamedSprite retv = m_dragged;
127 m_dragged = NamedSprite();
128 m_dragged_index = -1;
130 return retv;
133 if(m_dragged && index > m_dragged_index)
134 index--;
136 if(index < 0 || index >= (int)m_sprites.size() ) {
137 ERROR("invalid index " << index);
138 return NamedSprite();
141 return takeSpriteAt(index);
144 /*****************************************************************************************/
145 NamedSprite PiecePool::takeSpriteAt(int index) {
146 if(index < 0 || index >= (int)m_sprites.size() ) {
147 ERROR("invalid index " << index);
148 return NamedSprite();
151 NamedSprite retv = m_sprites[index];
152 if(!retv)
153 return NamedSprite();
155 for(int i = index; i < (int)m_sprites.size()-1; i++) {
156 double speed = (1.0+1.0/(i - index + 1))*0.4;
157 m_sprites[i] = m_sprites[i+1];
158 m_sprites[i].sprite()->moveTo(toReal(i)); //BROKEN animate to that point?
160 m_sprites.resize(m_sprites.size()-1);
162 return retv;
165 /*****************************************************************************************/
166 KGameCanvasAbstract* PiecePool::piecesGroup() {
167 return this;
170 /*****************************************************************************************/
171 void PiecePool::cancelDragging(bool fadeOff) {
172 if(!m_dragged)
173 return;
175 m_dragged.sprite()->setPixmap( m_loader( m_dragged.name() ) );
176 m_dragged.sprite()->putInCanvas(piecesGroup());
178 if (fadeOff) {
179 SpritePtr phantom = SpritePtr(m_dragged.sprite()->duplicate());
180 if(1/*BROKEN m_anim_fade*/)
181 m_main_animation->addAnimation( AnimationPtr(new FadeAnimation(phantom, phantom->pos(), 255, 0)) );
182 else
183 m_main_animation->addAnimation( AnimationPtr(new CaptureAnimation(phantom)) );
186 insertSprite(m_dragged_index, m_dragged);
188 m_dragged = NamedSprite();
189 m_dragged_index = -1;
192 /*****************************************************************************************/
193 void PiecePool::flipAndMoveBy(QPoint p) {
194 QPoint deltapos = m_flipped ? -p : p;
195 moveTo(pos() + deltapos);
196 m_flipped = !m_flipped;
198 for(int i=0;i<(int)m_sprites.size(); i++)
199 if(1/*BROKEN m_anim_movement*/) {
200 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(),
201 m_sprites[i].sprite()->pos() - deltapos)));
202 m_main_animation->addAnimation(AnimationPtr(new MovementAnimation(m_sprites[i].sprite(),
203 toReal(i), 1.0)));
205 else
206 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(),
207 toReal(i))));
210 /*****************************************************************************************/
211 void PiecePool::onResize(int new_size, bool force_reload) {
212 if(m_square_size == new_size && !force_reload)
213 return;
215 m_square_size = new_size;
216 m_loader.setSize(m_square_size);
218 // update the sprites
219 for (int i=0;i<(int)m_sprites.size(); i++) {
220 m_sprites[i].sprite()->setPixmap( m_loader( m_sprites[i].name() ) );
221 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(), toReal(i))));
225 /*****************************************************************************************/
226 void PiecePool::onMouseRelease(const QPoint& pos, int button) {
227 if (button != Qt::LeftButton || !m_dragged)
228 return;
230 /* did the board take this sprite? */
231 m_board->dropOn( 0/*BROKEN*/, m_dragged_index, pos + this->pos() - m_board->pos() );
233 #if 0
234 bool fadeOff = true;
235 if(!m_board->m_drop_sprite && m_dragged) {
237 //this happens if the animator used the piece being dropped but removed another piece from the pool
238 //for instance it remove another piece of the same type.
239 m_dragged = NamedSprite( m_dragged.name(), SpritePtr(m_dragged.sprite()->duplicate()) );
240 fadeOff = false;
242 m_board->m_drop_sprite = NamedSprite();
243 cancelDragging(fadeOff);
244 #endif
246 cancelDragging(true);
249 /*****************************************************************************************/
250 void PiecePool::onMousePress(const QPoint& pos, int button) {
251 if (button != Qt::LeftButton)
252 return;
254 if(m_dragged) {
255 std::cout << "Eh? We are already dragging?" << std::endl;
256 #if 0
257 m_board->m_drop_sprite = NamedSprite();
258 #endif
259 cancelDragging(); //never remove implicitly a piece from the pool
262 int index = toLogical(pos);
263 NamedSprite got = takeSpriteAt(index);
264 if(!got)
265 return;
267 got.sprite()->hide();
269 /* recreate the sprite, as "got" may be being animated */
270 QPixmap px = m_board->m_loader( got.name() );
271 QPoint at = pos + this->pos() - m_board->pos() - QPoint(px.width(), px.height())/2;
272 m_dragged = NamedSprite( got.name(), SpritePtr(new Sprite(px, m_board->piecesGroup(), at) ) );
273 m_dragged.sprite()->raise();
274 m_dragged.sprite()->show();
275 #if 0
276 m_board->m_drop_sprite = m_dragged;
277 #endif
280 /*****************************************************************************************/
281 void PiecePool::onMouseMove(const QPoint& pos, int /*button*/) {
282 if(m_dragged) {
283 m_dragged.sprite()->moveTo(pos + this->pos() - m_board->pos()
284 - QPoint(m_dragged.sprite()->pixmap().width(),
285 m_dragged.sprite()->pixmap().height() ) / 2 );
286 m_board->draggingOn( 0/*BROKEN*/, m_dragged_index, pos + this->pos() - m_board->pos() );