2 * Copyright 2008 Jacek Caban
3 * Copyright 2008 Piotr Caban
4 * Copyright 2008 Jaroslaw Sobiecki
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * Constructor of PoolGame class. It defines starting game state.
27 PoolGame::PoolGame(Real sizeX
, Real sizeY
) : sizeX(sizeX
), sizeY(sizeY
) {
32 * Destructor of PoolGame class.
34 PoolGame::~PoolGame() {
39 * This method initializes the pool game. It is used by constructor and restart method.
41 void PoolGame::init(void) {
42 game
= new Table(sizeX
, sizeY
);
45 game
->balls
.push_back(new Ball(0, Vector3(16.0f
, 0.0f
, 0.6f
), Vector3(0.0f
, 0.0f
, 0.0f
), Vector3(0.0f
, 0.0f
, 0.0f
), 1.0f
));
48 game
->balls
.push_back(new Ball(1, Vector3(-16.0f
-2*1.7320f
, 2.0f
, 0.6f
)));
49 game
->balls
.push_back(new Ball(2, Vector3(-16.0f
-4*1.7320f
, -2.0f
, 0.6f
)));
50 game
->balls
.push_back(new Ball(3, Vector3(-16.0f
-3*1.7320f
, 1.0f
, 0.6f
)));
51 game
->balls
.push_back(new Ball(4, Vector3(-16.0f
-4*1.7320f
, 2.0f
, 0.6f
)));
52 game
->balls
.push_back(new Ball(5, Vector3(-16.0f
-4*1.7320f
, 4.0f
, 0.6f
)));
53 game
->balls
.push_back(new Ball(6, Vector3(-16.0f
-3*1.7320f
, -3.0f
, 0.6f
)));
54 game
->balls
.push_back(new Ball(7, Vector3(-16.0f
-1.7320f
, -1.0f
, 0.6f
)));
55 game
->balls
.push_back(new Ball(8, Vector3(-16.0f
-2*1.7320f
, 0.0f
, 0.6f
)));
56 game
->balls
.push_back(new Ball(9, Vector3(-16.0f
, 0.0f
, 0.6f
)));
57 game
->balls
.push_back(new Ball(10, Vector3(-16.0f
-3*1.7320f
, -1.0f
, 0.6f
)));
58 game
->balls
.push_back(new Ball(11, Vector3(-16.0f
-4*1.7320f
, -4.0f
, 0.6f
)));
59 game
->balls
.push_back(new Ball(12, Vector3(-16.0f
-1.7320f
, 1.0f
, 0.6f
)));
60 game
->balls
.push_back(new Ball(13, Vector3(-16.0f
-4*1.7320f
, 0.0f
, 0.6f
)));
61 game
->balls
.push_back(new Ball(14, Vector3(-16.0f
-3*1.7320f
, 3.0f
, 0.6f
)));
62 game
->balls
.push_back(new Ball(15, Vector3(-16.0f
-2*1.7320f
, -2.0f
, 0.6f
)));
68 memset(pocketedBalls
, 0, sizeof(pocketedBalls
));
72 * This method destroys game object. It frees the memory.
74 void PoolGame::destroy(void) {
75 std::vector
<Ball
*>::iterator iter
;
76 for(iter
=game
->balls
.begin(); iter
!=game
->balls
.end(); iter
++) delete *iter
;
83 void PoolGame::restart(void) {
89 * This function checks if it's time to make a shot. Returns true if so.
91 bool PoolGame::isWaitingForShot(Ogre::Real time
) {
92 if(gameEnded()!=-1) return false;
94 if(!game
->update(time
)) {
95 bool forceChangingPlayer
= false;
96 bool keepPlayer
= false;
98 for(int i
=1; i
<16; i
++) {
99 if(pocketedBalls
[i
]) continue;
100 if(!game
->balls
[i
]->isOnTable()) {
101 pocketedBalls
[i
] = true;
102 if((color
==0 && i
<8) || (color
==1 && i
>8) || color
==2) keepPlayer
= true;
103 if((color
==1 && i
<8) || (color
==0 && i
>8)) forceChangingPlayer
= true;
107 if(isWhiteBallMovable() || !keepPlayer
|| forceChangingPlayer
) {
109 if(color
!=2) color
= !color
;
118 * This method checks if there was a faul. If so the white ball will be movable in the game.
120 bool PoolGame::isWhiteBallMovable(void) {
121 if(!stopped
) return false;
122 if(faul
!=2) return faul
;
124 int firstHit
= game
->balls
[0]->getFirstHit();
127 if(!game
->balls
[0]->isOnTable());
129 else if(color
== 2) {
131 for(i
=1; i
<8; i
++) if(!game
->balls
[i
]->isOnTable()) break;
132 for(j
=9; j
<16; j
++) if(!game
->balls
[j
]->isOnTable()) break;
133 if(i
<8 && j
<16) return false;
139 else if((firstHit
<8 && color
==0) || (firstHit
>8 && color
==1)) {
143 else if(firstHit
== 8) {
144 bool canHitBlackBall
= true;
145 for(int i
=1; i
<16; i
++) {
146 if(color
==0 && i
>8) continue;
147 if(color
==1 && i
<8) continue;
148 if(game
->balls
[i
]->isOnTable()) canHitBlackBall
= false;
150 if(canHitBlackBall
) {
157 game
->balls
[0]->getPosition() = Vector3(16.0f
, 0.0f
, 0.6f
);
158 game
->balls
[0]->isOnTable() = true;
163 * This function is used to set white ball position after a faul.
165 void PoolGame::setWhitePosition(Vector3
&pos
) {
166 Ball
*ball
= game
->balls
[0];
167 Real r
= ball
->getR();
169 if(pos
[0] > sizeX
/2.0 - r
)
170 pos
[0] = sizeX
/2.0 - r
;
171 else if(pos
[0] < -sizeX
/2.0 + r
)
172 pos
[0] = -sizeX
/2.0 + r
;
173 else if(pos
[1] > sizeY
/2.0 - r
)
174 pos
[1] = sizeY
/2.0 - r
;
175 else if(pos
[1] < -sizeY
/2.0 + r
)
176 pos
[1] = -sizeY
/2.0 + r
;
178 ball
->getPosition() = pos
;
182 * This method returns the number of player who is currently playing.
184 int PoolGame::currentPlayer(void) {
189 * This method returns what color should be hit be current player. It return 0 and 1 for colors and 2 if it is not yet defined.
191 int PoolGame::currentColor(void) {
196 * This method checks if the game has ended. It returns -1 if the game is still lasts or the winner number otherwise.
198 int PoolGame::gameEnded(void) {
199 if(!stopped
) return -1;
200 if(game
->balls
[8]->isOnTable()) return -1;
201 if(isWhiteBallMovable()) return !player
;
203 bool canHitBlackBall
= true;
204 for(int i
=1; i
<16; i
++) {
205 if(color
==0 && i
>8) continue;
206 if(color
==1 && i
<8) continue;
207 if(game
->balls
[i
]->isOnTable()) canHitBlackBall
= false;
210 if(canHitBlackBall
) return player
;
215 * This function returns the position vector of selected ball.
217 Vector3
PoolGame::getBallPosition(int ball
) {
218 return game
->balls
[ball
]->getPosition();
222 * This functions returns quaternion that describes current ball orientation.
224 Quaternion
PoolGame::getBallOrientation(int ball
) {
225 return game
->balls
[ball
]->getOrientation();
229 * This functions checks if a ball is in socket. Returns true if ball is on table.
231 bool PoolGame::isBallOnTable(int ball
) {
232 return game
->balls
[ball
]->isOnTable();
236 * This function is used to make a shot. It takes the rotations status, ball rotations and force as arguments.
238 void PoolGame::shot(Real horDirection
, Real vertDirection
, Real horPoint
, Real vertPoint
, Real force
) {
239 if(isWhiteBallMovable()) {
240 Table::BallVector::iterator iter
;
241 Ball
*white
= game
->balls
[0], *ball
;
243 for(iter
= game
->balls
.begin(); iter
!= game
->balls
.end(); iter
++) {
246 if(ball
->getID() == 0)
249 if((ball
->getPosition() - white
->getPosition()).length() < ball
->getR() + white
->getR())
256 game
->balls
[0]->getFirstHit() = 0;
257 game
->balls
[0]->shot(horDirection
, force
, Vector3(horPoint
, vertPoint
, vertDirection
));