1 #ifndef _global_h
2 #	include "global.h"
3 #endif
4 
5 #ifndef _pool8_h
6 #	include "pool8.h"
7 #endif
8 #ifndef _graph_h
9 #	include "graph.h"
10 #endif
11 #ifndef _mover_h
12 #	include "mover.h"
13 #endif
14 #ifndef _ball_h
15 #	include "ball.h"
16 #endif
17 
Pool8(double ft)18 Pool8::Pool8(double ft) :
19 	Pool( ft*2.54*12, ft*2.54*6 )
20 {
21 	SelectTable(-1);
22 
23 	black_col	= AddBallColor( "black" );
24 	cueball=0;
25 
26 	if (!deluxe) {
27 // Pool-Kugeln: "Television"
28 		full_col		= AddBallColor( "yellow" );
29 		half_col		= AddBallColor( "red" );
30 	}
31 	else {
32 // normale Pool-Kugeln
33 		ball_col[0] = AddBallColor( "gold1" );			// yellow
34 		ball_col[1] = AddBallColor( "blue" );			// blue
35 		ball_col[2] = AddBallColor( "red" );			// red
36 		ball_col[3] = AddBallColor( "DarkViolet" );	// dark violett
37 		ball_col[4] = AddBallColor( "orange" );		// orange
38 		ball_col[5] = AddBallColor( "MediumForestGreen" );	// dark green
39 		ball_col[6] = AddBallColor( "brown" );			// brown
40 	}
41 
42 	mh = 0;
43 	balls_in_pocket = 0;
44 	for (int i=0;i<15;i++)	ball[i]=NULL;
45 }
46 
~Pool8()47 Pool8::~Pool8() {
48 	if (cueball) {
49 		delete cueball;
50 		for (int i=0;i<15;i++)	if (ball[i])	delete ball[i];
51 		cueball=0;
52 	}
53 	if (mh)		delete mh;
54 }
55 
56 
Triangle(const Vec2 & vec)57 void Pool8::Triangle( const Vec2 &vec )
58 {
59 static int t[15] = {		1,
60 						-1, -2,
61 					  2,  0,  3,
62 				  -3,  4, -4, -5,
63 				 5, -6,  6,  7, -7 };
64 
65 Real	x = vec.X();
66 Real	y = vec.Y();
67 const int count = 5;
68 int		c=0;
69 double	cdist = sqrt( 3.*(GetNormalBallSize()+Offset)*(GetNormalBallSize()+Offset) );
70 Ball	*r;
71 
72 //	x-=(cdist*(count-1)/2);
73 	for( int col=0; col<count; col++ ) {
74 		for( int row=0; row<=col; row++ ) {
75 			Vec2	pos(x+col*cdist,y+(row-col/2.0)*2*(GetNormalBallSize()+Offset));
76 			r=new Ball( pos, GetNormalBallSize() );
77 			if (t[c]>0) {
78 				if (!deluxe)
79 						r->state = new BallState( m, full_col, r->P() );
80 				else	r->state = new HalfBallState( m, ball_col[t[c]-1], r->P() );
81 				ball[t[c]-1]   = r;
82 				ball_p[t[c]-1] = pos;
83 			}
84 			else if (t[c]<0) {
85 				if (!deluxe)
86 						r->state = new BallState( m, half_col, r->P() );
87 				else	r->state = new HalfBallState( mh, ball_col[-t[c]-1], r->P() );
88 				ball[8-t[c]-1]   = r;
89 				ball_p[8-t[c]-1] = pos;
90 			}
91 			else {
92 				if (!deluxe)
93 						r->state = new BallState( m, black_col, r->P() );
94 				else	r->state = new HalfBallState( m, black_col, r->P() );
95 				ball[7]   = r;
96 				ball_p[7] = pos;
97 			}
98 			c++;
99 		}
100 	}
101 }
102 
103 
InitPlayground()104 void Pool8::InitPlayground() {
105 
106 	if (deluxe) {
107 		mh = HalfBallMover::Create( GetNormalBallSize(), (deluxe==3)?2:4 );
108 		mh->Init();
109 		m  = HalfBallMover::Create( GetNormalBallSize(), (deluxe==2)?3:((deluxe==3)?1:0) );
110 		m->Init();
111 		BallRadius = m->GetActRadius()-Offset;
112 	}
113 	Pool::InitPlayground();
114 
115 	tridef  = Vec2(AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()/2.);
116 	Triangle(tridef);
117 	cuedef  = Vec2(AreaOffX()+AreaWidth()*0.125,AreaOffY()+AreaHeight()*0.375);
118 	cueball = new Ball( cuedef.X(), cuedef.Y(), RealZero, RealZero, BallRadius );
119 	if (!deluxe)
120 			cueball->state = new BallState( m, cue_col, cueball->P() );
121 	else	cueball->state = new HalfBallState( m, cue_col, cueball->P() );
122 
123 #ifdef DEBUG
124 	if (deluxe) {
125 		if (debug&ShowTurns)		mh->CreateTurnWindow();
126 		if (debug&ShowRings)		mh->CreateRingWindow();
127 	}
128 #endif
129 }
130 
131 
DrawBackground()132 void Pool8::DrawBackground() const {
133 	Pool::DrawBackground();
134 	SetBgColor(table_line_col);
135 	DrawLine( AreaOffX()+AreaWidth()*0.25, AreaOffY(),
136 							AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight() );
137 	FillCircle( AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight()*0.50, 1.0 );
138 	FillCircle( AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()*0.50, 1.0 );
139 }
140 
ResetGame()141 void Pool8::ResetGame() {
142 	for (int i=0;i<15;i++)
143 		if (ball[i])				ball[i]->SetPV( ball_p[i] );
144 	balls_in_pocket = 0;
145 	Pool::ResetGame();
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////
149 
InPocket(Ball * b)150 void Pool8::InPocket( Ball *b ) {
151 	for (int i=0;i<15;i++) {
152 		if (b==ball[i]) {
153 			balls_in_pocket  |= (1<<i);
154 			return;
155 		}
156 	}
157 	Pool::InPocket(b);
158 }
159 
IsSelectable(Ball * b)160 int Pool8::IsSelectable(Ball *b) {
161 	for (int i=0;i<15;i++) {
162 		if (b==ball[i]) {
163 			if (balls_in_pocket & (1<<i)) {
164 				Vec2	newpos;
165 				b->FitsNextTo(tridef,Vec2(1.0,RealZero),&newpos);
166 				b->SetP(newpos);					// closer to right wall
167 
168 				b->ChgV(Vec2Zero);
169 				balls_in_pocket &= ~(1<<i);	// it's back in the game
170 
171 				return 0;
172 			}
173 			else {
174 				return 1;
175 			}
176 		}
177 	}
178 
179 	return Pool::IsSelectable(b);
180 }
181 
182 // -------------------------------------------------------------------------
183 
~Pool9()184 Pool9::~Pool9() {
185 }
186 
Triangle(const Vec2 & vec)187 void Pool9::Triangle( const Vec2 &vec )
188 {
189 static int t[9] = {		1,
190 						 2,  3,
191 					  4, -1,  5,
192 				       6,  7,
193 				         0 };
194 
195 Real	x = vec.X();
196 Real	y = vec.Y();
197 const int count = 5;
198 int		c=0;
199 double	cdist = sqrt( 3.*(GetNormalBallSize()+Offset)*(GetNormalBallSize()+Offset) );
200 Ball	*r;
201 
202 //	x-=(cdist*(count-1)/2);
203 	for( int col=0; col<count; col++ ) {
204 		int per_col = 2-abs(2-col);
205 		for( int row=0; row<=per_col; row++ ) {
206 			Vec2 pos( x+col*cdist, y+(row-per_col/2.0)*2*(GetNormalBallSize()+Offset) );
207 			r=new Ball( pos, GetNormalBallSize() );
208 			if (t[c]>0) {
209 				if (!deluxe)
210 						r->state = new BallState( m, full_col, r->P() );
211 				else	r->state = new HalfBallState( m, ball_col[t[c]-1], r->P() );
212 				ball[t[c]-1]   = r;
213 				ball_p[t[c]-1] = pos;
214 			}
215 			else if (t[c]<0) {
216 				if (!deluxe)
217 						r->state = new BallState( m, half_col, r->P() );
218 				else	r->state = new HalfBallState( mh, ball_col[-t[c]-1], r->P() );
219 				ball[8-t[c]-1]   = r;
220 				ball_p[8-t[c]-1] = pos;
221 			}
222 			else {
223 				if (!deluxe)
224 						r->state = new BallState( m, black_col, r->P() );
225 				else	r->state = new HalfBallState( m, black_col, r->P() );
226 				ball[7]   = r;
227 				ball_p[7] = pos;
228 			}
229 			c++;
230 		}
231 	}
232 }
233 
234 // -------------------------------------------------------------------------
235 
~Pool8Demo()236 Pool8Demo::~Pool8Demo() {}
237 
GetPresetA()238 const Real &Pool8Demo::GetPresetA() const			{ return PresetA; }
GetSlowGranularity()239 const Real &Pool8Demo::GetSlowGranularity() const	{ return SlowGranularity; }
240 
InitPlayground()241 void Pool8Demo::InitPlayground() {
242 
243 	if (deluxe) {
244 		mh = HalfBallMover::Create( GetNormalBallSize(), (deluxe==3)?2:4 );
245 		mh->Init();
246 		m  = HalfBallMover::Create( GetNormalBallSize(), (deluxe==2)?3:((deluxe==3)?1:0) );
247 		m->Init();
248 		BallRadius = m->GetActRadius()-Offset;
249 	}
250 	Billard::InitPlayground();
251 	BallRadius = m->GetActRadius();
252 	Billard::InitTable();
253 
254 	Triangle(   Vec2(AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()/2.) );
255 	cueball = new Ball( AreaOffX()+AreaWidth()*0.125, AreaOffY()+AreaHeight()*0.375,
256 					shot_speed, shot_speed, BallRadius );
257 	if (!deluxe)
258 			cueball->state = new BallState( m, cue_col, cueball->P() );
259 	else	cueball->state = new HalfBallState( m, cue_col, cueball->P() );
260 }
261 
DrawBackground()262 void Pool8Demo::DrawBackground() const {
263 	Billard::DrawBackground();
264 	SetBgColor(table_line_col);
265 	DrawLine( AreaOffX()+AreaWidth()*0.25, AreaOffY(),
266 							AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight() );
267 	FillCircle( AreaOffX()+AreaWidth()*0.25, AreaOffY()+AreaHeight()*0.50, 1.0 );
268 	FillCircle( AreaOffX()+AreaWidth()*0.75, AreaOffY()+AreaHeight()*0.50, 1.0 );
269 }
270 
271 // -------------------------------------------------------------------------
272 
273 #ifdef DEBUG
274 
275 #ifndef _wall_h
276 #	include "wall.h"
277 #endif
278 
279 
280 class TestField {
281 	public:
282 		TestField( const Vec2 &p1, const Vec2 &p2, const Real &len,
283 							Pool8Test *d );
284 		~TestField();
285 
286 		void Draw() const;
Insert(TestField * n)287 		void Insert( TestField *n )	{ n->next = next; next = n; }
288 
289 	private:
290 		Vec2		e[4];
291 		Wall			*w[4];
292 		int			nballs;
293 		Ball			**b;
294 		TestField	*next;
295 };
296 
TestField(const Vec2 & p1,const Vec2 & p2,const Real & len,Pool8Test * d)297 TestField::TestField( const Vec2 &p1, const Vec2 &p2, const Real &len,
298 		Pool8Test *d ) {
299 Vec2	dist = (p2-p1);
300 Vec2	dir_x = dist.TurnRight().Norm1();
301 Vec2	dir_y = dist.Norm1();
302 
303 const double SPEED = 20.0;
304 
305 	next = 0l;
306 	e[0] = p1;
307 	e[1] = p1+dir_x*len;
308 	e[2] = p2+dir_x*len;
309 	e[3] = p2;
310 	for (int i=0;i<4;i++)	w[i] = new Wall( e[i], e[(i+1)%4] );
311 
312 	nballs = (int)(dist.Norm()/Pool8Test::BallRadius/3.);
313 	b = new Ball*[nballs];
314 	for (i=0;i<nballs;i++) {
315 		Vec2 pos	= e[0]
316 						+ 3.*Pool8Test::BallRadius*dir_x
317 						+ Real((i+1)*3)*Pool8Test::BallRadius * dir_y;
318 		b[i] = new Ball( pos.X()+((rand()%150)/100.0), pos.Y(),
319 						dir_x.X()*SPEED, dir_x.Y()*SPEED,
320 						Pool8Test::BallRadius );
321 		b[i]->state = new HalfBallState( d->mh, d->ball_col[i%7], b[i]->P() );
322 		((HalfBallState*)b[i]->state)->st = d->mh->AngVec2St(0,i*d->mh->vecs_b/nballs);
323 
324 	}
325 }
326 
~TestField()327 TestField::~TestField() {
328 	for (int i=0;i<nballs;i++)		delete b[i];
329 	delete b;
330 	for (i=0;i<4;i++)	delete w[i];
331 	if (next)		delete next;
332 }
333 
Draw()334 void TestField::Draw() const {
335 	for (int i=0;i<4;i++)	DrawLine( e[i], e[(i+1)%4] );
336 	if (next)		next->Draw();
337 }
338 
339 
~Pool8Test()340 Pool8Test::~Pool8Test()
341 {
342 	delete field_queue;
343 }
344 
InitPlayground()345 void Pool8Test::InitPlayground() {
346 
347 	if (deluxe) {
348 		mh = HalfBallMover::Create( GetNormalBallSize(), 2 );
349 		mh->Init();
350 		BallRadius = mh->GetActRadius()-Offset;
351 	}
352 	Billard::InitPlayground();
353 	BallRadius = m->GetActRadius();
354 	Billard::InitTable();
355 
356 	Vec2	dir = (Mid(2)-Mid(0))*3.0/4.0;
357 	if (shot_speed>=RealZero&&shot_speed<=90.)
358 			dir=dir.TurnAngleDeg(-shot_speed);
359 
360 #if (1)
361 	field_queue = new TestField( Mid(0), Mid(0)+dir, AreaWidth()/4., this );
362 #else
363 	field_queue = new TestField( Edge(0), Edge(3), AreaWidth(), this );
364 	field_queue->Insert( new TestField( Mid(2), Mid(1), AreaWidth()/5, this ) );
365 #endif
366 }
367 
DrawBackground()368 void Pool8Test::DrawBackground() const {
369 	Pool8Demo::DrawBackground();
370 	SetBgColor(marker_col);
371 	field_queue->Draw();
372 }
373 #endif
374