1 /* $Id: ComTrainingPenDrive.cpp,v 1.11 2002/11/04 14:03:47 nan Exp $ */
2 
3 // Copyright (C) 2000  $B?@Fn(B $B5H9((B(Kanna Yoshihiro)
4 //
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 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19 #include "ttinc.h"
20 #include "ComTrainingPenDrive.h"
21 #include "Ball.h"
22 #include "Player.h"
23 #include "Control.h"
24 #include "PlayGame.h"
25 #include "Training.h"
26 
27 extern Ball   theBall;
28 
ComTrainingPenDrive()29 ComTrainingPenDrive::ComTrainingPenDrive() : ComPenDrive() {
30 }
31 
ComTrainingPenDrive(long side)32 ComTrainingPenDrive::ComTrainingPenDrive(long side) :
33   ComPenDrive(side) {
34 }
35 
ComTrainingPenDrive(long playerType,long side,double x,double y,double z,double vx,double vy,double vz,long status,long swing,long swingType,bool swingSide,long afterSwing,long swingError,double targetX,double targetY,double eyeX,double eyeY,double eyeZ,long pow,double spin,double stamina,long statusMax)36 ComTrainingPenDrive::ComTrainingPenDrive( long playerType, long side,
37 					  double x, double y, double z,
38 					  double vx, double vy, double vz,
39 					  long status, long swing,
40 					  long swingType, bool swingSide,
41 					  long afterSwing, long swingError,
42 					  double targetX, double targetY,
43 					  double eyeX, double eyeY,
44 					  double eyeZ,
45 					  long pow, double spin,
46 					  double stamina, long statusMax ) :
47   ComPenDrive( playerType, side, x, y, z, vx, vy, vz, status, swing, swingType,
48 	       swingSide, afterSwing, swingError, targetX, targetY,
49 	       eyeX, eyeY, eyeZ, pow, spin, stamina, statusMax ) {
50 }
51 
~ComTrainingPenDrive()52 ComTrainingPenDrive::~ComTrainingPenDrive() {
53 }
54 
55 bool
Think()56 ComTrainingPenDrive::Think() {
57   double hitTX, hitTY;	// estimation time until ball reaches _hitX, _hitY
58   double mx;
59 
60   // If the ball status changes, change _hitX, _hitY
61   if ( _prevBallstatus != theBall.GetStatus() && m_swing == 0 ){
62     Hitarea( _hitX, _hitY );
63 
64     _prevBallstatus = theBall.GetStatus();
65   }
66 
67   if ( theBall.GetVX() != 0.0 )
68     hitTX = (_hitX - theBall.GetX())/theBall.GetVX();
69   else
70     hitTX = -1.0;
71 
72   if ( theBall.GetVY() != 0.0 )
73     hitTY = (_hitY - theBall.GetY())/theBall.GetVY();
74   else
75     hitTY = -1.0;
76 
77   if ( fabs( _hitX-(m_x+m_side*0.3) ) < fabs( _hitX-(m_x-m_side*0.3) ) ||
78        theBall.GetStatus() == 8 || _hitX*m_side > 0 )
79     mx = m_x+m_side*0.3;
80   else
81     mx = m_x-m_side*0.3;
82 
83   if ( hitTX > 0.0 ) {
84     if ( m_vx > 0 && mx + m_vx*hitTX < _hitX )
85       m_vx += 0.1;
86     else if ( m_vx < 0 && mx + m_vx*hitTX > _hitX )
87       m_vx -= 0.1;
88     else if ( m_vx*fabs(m_vx*0.1)/2 < _hitX - mx )
89       m_vx += 0.1;
90     else
91       m_vx -= 0.1;
92   } else {
93     if ( m_vx*fabs(m_vx*0.1)/2 < _hitX - mx )
94       m_vx += 0.1;
95     else
96       m_vx -= 0.1;
97   }
98 
99   if ( hitTY > 0.0 ) {
100     if ( m_vy > 0 && m_y + m_vy*hitTY < _hitY )
101       m_vy += 0.1;
102     else if ( m_vy < 0 && m_y + m_vy*hitTY > _hitY )
103       m_vy -= 0.1;
104     else if ( m_vy*fabs(m_vy*0.1)/2 < _hitY - m_y )
105       m_vy += 0.1;
106     else
107       m_vy -= 0.1;
108   } else {
109     if ( m_vy*fabs(m_vy*0.1)/2 < _hitY - m_y )
110       m_vy += 0.1;
111     else
112       m_vy -= 0.1;
113   }
114 
115   if ( m_vx > 5.0 )
116     m_vx = 5.0;
117   else if ( m_vx < -5.0 )
118     m_vx = -5.0;
119   if ( m_vy > 5.0 )
120     m_vy = 5.0;
121   else if ( m_vy < -5.0 )
122     m_vy = -5.0;
123 
124   // Toss
125   if ( theBall.GetStatus() == 8 &&
126        ((PlayGame *)Control::TheControl())->GetService() == GetSide() &&
127        fabs(m_vx) < 0.1 && fabs(m_vy) < 0.1 &&
128        fabs(m_x+m_side*0.3-_hitX) < 0.1 && fabs(m_y-_hitY) < 0.1 &&
129        m_swing == 0 ){
130     theBall.Toss( this, 2 );
131     StartSwing( 3 );
132     m_targetY = TABLELENGTH/8*m_side;
133 
134     return true;
135   }
136 
137   // Calc the ball location of 0.1 second later.
138   // This part seems to be the same as Swing(). Consider again.
139   Ball *tmpBall;
140 
141   tmpBall = new Ball( theBall.GetX(), theBall.GetY(), theBall.GetZ(),
142 		      theBall.GetVX(), theBall.GetVY(), theBall.GetVZ(),
143 		      theBall.GetSpin(), theBall.GetStatus() );
144 
145   for ( int i = 0 ; i < 10 ; i++ )
146     tmpBall->Move();
147 
148   if ( ((tmpBall->GetStatus() == 3 && m_side == 1) ||
149 	(tmpBall->GetStatus() == 1 && m_side == -1)) &&
150        (m_y-tmpBall->GetY())*m_side < 0.3 &&
151        (m_y-tmpBall->GetY())*m_side > 0.0 ){
152     _hitX = tmpBall->GetX();
153     _hitY = tmpBall->GetY();
154 
155     Player *opponent;
156     if ( m_side == -1 )
157       opponent = Control::TheControl()->GetThePlayer();
158     else
159       opponent = Control::TheControl()->GetComPlayer();
160 
161     SetTargetX( opponent );
162 
163     Swing( 3 );
164   }
165   delete tmpBall;
166 
167   return true;
168 }
169 
170 bool
HitBall()171 ComTrainingPenDrive::HitBall() {
172   double vx, vy, vz;
173   double level;
174 
175   // Serve
176   if ( ( (m_side == 1 && theBall.GetStatus() == 6) ||
177          (m_side ==-1 && theBall.GetStatus() == 7) ) &&
178        fabs( m_x-theBall.GetX() ) < 0.6 && fabs( m_y-theBall.GetY() ) < 0.3 ){
179     PenDrive::HitBall();
180   } else {
181     if ( ((m_side == 1 && theBall.GetStatus() == 3) ||
182 	  (m_side ==-1 && theBall.GetStatus() == 1)) ) {
183       ((Training *)Control::TheControl())->AddTrainingCount();
184 
185       level = 1.0 - 1.0/((double)((Training *)Control::TheControl())->GetTrainingCount()/20.0+1.5);
186       theBall.TargetToV( -TABLEWIDTH/5*2+TABLEWIDTH/5*4*(((Training *)Control::TheControl())->GetTrainingCount()%2),
187 			 TABLELENGTH/5*2*m_side, level, m_spin,
188 			 vx, vy, vz, 0.1, 20.0 );
189 
190       theBall.Hit( vx, vy, vz, m_spin, this );
191     } else
192       m_swingError = SWING_MISS;
193   }
194 
195   return true;
196 }
197