1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 #ifndef __LOCALPLAYER_H__
14 #define __LOCALPLAYER_H__
15 
16 /* interface header */
17 #include "BaseLocalPlayer.h"
18 
19 /* system interface headers */
20 #include <string>
21 #include <vector>
22 
23 /* common interface headers */
24 #include "Obstacle.h"
25 #include "TimeKeeper.h"
26 
27 /* local interface headers */
28 #include "Player.h"
29 #include "ServerLink.h"
30 
31 class FlagSceneNode;
32 
33 class LocalPlayer : public BaseLocalPlayer
34 {
35 public:
36     enum FiringStatus
37     {
38         Deceased,       // can't shoot cos I'm dead
39         Ready,      // ready to shoot
40         Loading,        // reloading
41         Sealed,     // I'm inside a building
42         Zoned       // I'm zoned
43     };
44     enum Location
45     {
46         Dead,       // dead, explosion over
47         Exploding,      // dead and exploding
48         OnGround,       // playing on ground
49         InBuilding,     // playing in building
50         OnBuilding,     // playing on building
51         InAir       // playing in air
52     };
53     enum InputMethod      // what device am I using to move around
54     {
55         Keyboard = 0,
56         Mouse,
57         Joystick
58     };
59 
60     LocalPlayer(const PlayerId&,
61                 const char* name, const char* motto);
62     ~LocalPlayer();
63 
64     Location  getLocation() const;
65     FiringStatus  getFiringStatus() const;
66     float     getFlagShakingTime() const;
67     int       getFlagShakingWins() const;
68     const float*  getAntidoteLocation() const;
69     ShotPath* getShot(int index) const;
70     const Player* getTarget() const;
71     int       getDeathPhysicsDriver() const;
72     const std::vector<const Obstacle*>& getInsideBuildings() const;
73 
74     void      setTeam(TeamColor);
75     void      setDesiredSpeed(float fracOfMaxSpeed);
76     void      setDesiredAngVel(float fracOfMaxAngVel);
77     void      setPause(bool = true);
78     void      activateAutoPilot(bool = true);
79     bool      fireShot();
80     void      explodeTank();
81     void      doJump();
82     void      setJump();
83     void      setJumpPressed(bool value);
84     void      setTarget(const Player*);
85 
86     float     getReloadTime() const;
87 
88 
89     void      setNemesis(const Player*);
90     const Player* getNemesis() const;
91 
92     void      setRecipient(const Player*);
93     const Player* getRecipient() const;
94 
95     void      restart(const float* pos, float azimuth);
96     bool      checkHit(const Player* source, const ShotPath*& hit,
97                        float& minTime) const;
98     void      setFlag(FlagType*);
99     void      changeScore(short deltaWins, short deltaLosses, short deltaTeamKills);
100 
101     void      addAntidote(SceneDatabase*);
102 
103     InputMethod   getInputMethod() const;
104     void      setInputMethod(InputMethod newInput);
105     void      setInputMethod(std::string newInput);
106     static std::string    getInputMethodName(InputMethod whatInput);
107     bool      queryInputChange();
108     void      setKey(int button, bool pressed);
109     int       getRotation();
110     int       getSpeed();
111     bool      isSpawning();
112     void      setSpawning( bool spawn );
113 
114 
115     static LocalPlayer*   getMyTank();
116     static void       setMyTank(LocalPlayer*);
117 
118     const Obstacle*   getHitBuilding(const float* pos, float angle,
119                                      bool phased, bool& expel) const;
120     const Obstacle*   getHitBuilding(const float* oldPos, float oldAngle,
121                                      const float* pos, float angle,
122                                      bool phased, bool& expel);
123     bool      getHitNormal(const Obstacle* o,
124                            const float* pos1, float azimuth1,
125                            const float* pos2, float azimuth2,
126                            float* normal) const;
127 
128 protected:
129     bool      doEndShot(int index, bool isHit, float* pos);
130     void      doUpdate(float dt);
131     void      doUpdateMotion(float dt);
132     void      doMomentum(float dt, float& speed, float& angVel);
133     void      doFriction(float dt, const float *oldVelocity, float *newVelocity);
134     void      doForces(float dt, float* velocity, float& angVel);
135     LocalShotPath**   shots;
136     bool    gettingSound;
137     ServerLink*   server;
138 
139 private:
140     void      doSlideMotion(float dt, float slideTime,
141                             float newAngVel, float* newVelocity);
142     float     getNewAngVel(float old, float desired);
143     void      collectInsideBuildings();
144 
145 private:
146     Location  location;
147     FiringStatus  firingStatus;
148     TimeKeeper    bounceTime;
149     TimeKeeper    agilityTime;
150     float     flagShakingTime;
151     int       flagShakingWins;
152     float     flagAntidotePos[3];
153     FlagSceneNode*    antidoteFlag;
154     float     desiredSpeed;
155     float     desiredAngVel;
156     float     lastSpeed;
157     float     crossingPlane[4];
158     bool      anyShotActive;
159     const Player* target;
160     const Player* nemesis;
161     const Player* recipient;
162     static LocalPlayer*   mainPlayer;
163     InputMethod   inputMethod;
164     bool      inputChanged;
165     int       stuckFrameCount;
166     bool      spawning;
167     int       wingsFlapCount;
168     bool      left;
169     bool      right;
170     bool      up;
171     bool      down;
172     bool      entryDrop; // first drop since entering
173     bool      wantJump;
174     bool      jumpPressed;
175     int       deathPhyDrv;    // physics driver that caused death
176     std::vector<const Obstacle*> insideBuildings;
177 };
178 
179 
getLocation()180 inline LocalPlayer::Location LocalPlayer::getLocation() const
181 {
182     return location;
183 }
184 
getFiringStatus()185 inline LocalPlayer::FiringStatus LocalPlayer::getFiringStatus() const
186 {
187     return firingStatus;
188 }
189 
getTarget()190 inline const Player* LocalPlayer::getTarget() const
191 {
192     return target;
193 }
194 
getNemesis()195 inline const Player* LocalPlayer::getNemesis() const
196 {
197     return nemesis;
198 }
199 
getRecipient()200 inline const Player* LocalPlayer::getRecipient() const
201 {
202     return recipient;
203 }
204 
getDeathPhysicsDriver()205 inline int      LocalPlayer::getDeathPhysicsDriver() const
206 {
207     return deathPhyDrv;
208 }
209 
getInsideBuildings()210 inline const std::vector<const Obstacle*>& LocalPlayer::getInsideBuildings() const
211 {
212     return insideBuildings;
213 }
214 
getInputMethod()215 inline LocalPlayer::InputMethod LocalPlayer::getInputMethod() const
216 {
217     return inputMethod;
218 }
219 
setInputMethod(InputMethod newInput)220 inline void LocalPlayer::setInputMethod(InputMethod newInput)
221 {
222     inputMethod = newInput;
223     inputChanged = true;
224 }
225 
setInputMethod(std::string newInput)226 inline void LocalPlayer::setInputMethod(std::string newInput)
227 {
228     // FIXME - using hardcoded upper bound is ugly
229     for (int i = 0; i < 3; i++)
230     {
231         if (newInput == getInputMethodName((InputMethod)i))
232             setInputMethod((InputMethod)i);
233     }
234 }
235 
queryInputChange()236 inline bool LocalPlayer::queryInputChange()
237 {
238     const bool returnVal = inputChanged;
239     inputChanged = false;
240     return returnVal;
241 }
242 
isSpawning()243 inline bool LocalPlayer::isSpawning()
244 {
245     return spawning;
246 }
247 
setSpawning(bool spawn)248 inline void LocalPlayer::setSpawning( bool spawn )
249 {
250     spawning = spawn;
251 }
252 
getRotation()253 inline int LocalPlayer::getRotation()
254 {
255     if (left && !right)
256         return 1;
257     else if (right && !left)
258         return -1;
259     else
260         return 0;
261 }
262 
getSpeed()263 inline int LocalPlayer::getSpeed()
264 {
265     if (up && !down)
266         return 1;
267     else if (down && !up)
268         return -1;
269     else
270         return 0;
271 }
272 
getMyTank()273 inline LocalPlayer* LocalPlayer::getMyTank()
274 {
275     return mainPlayer;
276 }
277 
278 #endif /* __LOCALPLAYER_H__ */
279 
280 // Local Variables: ***
281 // mode: C++ ***
282 // tab-width: 4 ***
283 // c-basic-offset: 4 ***
284 // indent-tabs-mode: nil ***
285 // End: ***
286 // ex: shiftwidth=4 tabstop=4
287