1 /******************************************************************************
2  *  Warmux is a convivial mass murder game.
3  *  Copyright (C) 2001-2011 Warmux Team.
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  * Virtual class to handle weapon in warmux.
20  * Weapon projectile are handled in WeaponLauncher (see launcher.cpp and launcher.h).
21  *****************************************************************************/
22 
23 #ifndef WEAPON_H
24 #define WEAPON_H
25 #include <string>
26 #include <WARMUX_base.h>
27 #include "sound/sound_sample.h"
28 #include <WARMUX_debug.h>
29 #include <WARMUX_point.h>
30 
31 class Character;
32 class Sprite;
33 class EmptyWeaponConfig;
34 typedef struct _xmlNode xmlNode;
35 
36 // Infinite ammos constant
37 extern const int INFINITE_AMMO;
38 
39 extern const uint BUTTON_ICO_WIDTH;
40 extern const uint BUTTON_ICO_HEIGHT;
41 
42 extern const uint WEAPON_ICO_WIDTH;
43 extern const uint WEAPON_ICO_HEIGHT;
44 
45 //-----------------------------------------------------------------------------
46 
47 class Weapon
48 {
49 public:
50   typedef enum
51   {
52     FIRST,
53     WEAPON_BAZOOKA=FIRST, WEAPON_AUTOMATIC_BAZOOKA, WEAPON_CLUZOOKA, WEAPON_RIOT_BOMB,
54     WEAPON_GRENADE,       WEAPON_DISCO_GRENADE,     WEAPON_CLUSTER_BOMB, WEAPON_FOOTBOMB,
55     WEAPON_GUN,           WEAPON_SHOTGUN,           WEAPON_SUBMACHINE_GUN,
56     WEAPON_BASEBALL,      WEAPON_FLAMETHROWER,      WEAPON_SLAP,
57 
58     WEAPON_DYNAMITE,      WEAPON_MINE,
59 
60     WEAPON_SUPERTUX,      WEAPON_AIR_ATTACK,  WEAPON_ANVIL, WEAPON_GNU,
61     WEAPON_POLECAT,       WEAPON_BOUNCE_BALL,
62 
63     WEAPON_TELEPORTATION, WEAPON_GRAPPLE,  WEAPON_LOWGRAV,   WEAPON_SUICIDE,
64     WEAPON_SKIP_TURN,     WEAPON_JETPACK,     WEAPON_PARACHUTE, WEAPON_AIR_HAMMER,
65     WEAPON_CONSTRUCT,     WEAPON_SNIPE_RIFLE, WEAPON_RAIL_GUN, WEAPON_BLOWTORCH, WEAPON_SYRINGE,
66     LAST = WEAPON_SYRINGE
67   } Weapon_type;
68   typedef enum {
69     INVALID = 0,
70     HEAVY,
71     RIFLE,
72     THROW,
73     SPECIAL,
74     DUEL,
75     MOVE,
76     TOOL
77   } category_t;
78 
79 private:
80   // Angle in radian between -PI to PI
81   Double min_angle, max_angle;
82   // display crosshair ?
83   bool m_display_crosshair;
84 
85 protected:
86   Weapon::Weapon_type m_type;
87   Weapon::category_t  m_category;
88 
89   std::string m_id;
90   std::string m_name;
91   std::string m_help;
92   Sprite *m_image;
93   Sprite *m_weapon_fire;
94   uint m_fire_remanence_time;
95 
96   typedef enum {
97     weapon_origin_HAND,
98     weapon_origin_OVER
99   } weapon_origin_t;
100   weapon_origin_t origin;
101 
102   Point2i hole_delta; // relative position of the hole of the weapon
103   Point2i position;   // Position of the weapon
104 
105   // GameTime when the weapon is selected for the animation
106   uint m_time_anim_begin;
107 
108   // Actual strength of the weapon
109   Double m_strength;
110 
111   // time of beginning to load (for choosing the strength)
112   uint m_first_time_loading;
113 
114   // time of the last fire
115   uint m_last_fire_time;
116 
117   // time between 2 shot
118   uint m_time_between_each_shot;
119 
120   // change weapon after ? (for the grapple = true)
121   bool m_can_change_weapon;
122 
123   // Extra parameters
124   EmptyWeaponConfig *extra_params;
125 
126   // Visibility
127   const bool drawable;
128 
129   // how many times can we use this weapon (since the beginning of the game) ?
130   int m_available_after_turn; // -1 means NEVER
131   int m_initial_nb_ammo;
132   int m_initial_nb_unit_per_ammo;
133   int ammo_per_drop;
134   Double drop_probability;
135   bool use_unit_on_first_shoot;
136   bool can_be_used_on_closed_map;
137   SoundSample loading_sound;
138 
139 public:
140   // weapon's icon
141   Sprite * icon;
142 
143   // if max_strength != 0, display the strength bar
144   Double max_strength;
145 
146   bool use_flipping;
Category()147   const category_t& Category() const { return m_category; };
148 
149 protected:
p_Select()150   virtual void p_Select() { m_last_fire_time = 0; };
151   virtual void p_Deselect();
152   virtual void Refresh();
153   virtual bool p_Shoot() = 0;
154 
155   /* This method offer sub classes a way to hide the weapon. */
ShouldBeDrawn()156   virtual bool ShouldBeDrawn() { return true; };
157   /* This method offer sub classes a way to hide the ammo units. */
ShouldAmmoUnitsBeDrawn()158   virtual bool ShouldAmmoUnitsBeDrawn() const { return true; };
159   virtual void DrawWeaponFire();
160   void DrawAmmoUnits() const;
161 
162   // Begin the shooting animation of the character
163   void PrepareShoot();
164 
165   void RepeatShoot();
166 
167   void StartMovingLeftForAllPlayers();
168   void StopMovingLeftForAllPlayers();
169 
170   void StartMovingRightForAllPlayers();
171   void StopMovingRightForAllPlayers();
172 
173   void StartMovingUpForAllPlayers();
174   void StopMovingUpForAllPlayers();
175 
176   void StartMovingDownForAllPlayers();
177   void StopMovingDownForAllPlayers();
178 
179 public:
180   Weapon(Weapon_type type,
181          const std::string &id,
182          EmptyWeaponConfig * params,
183          bool drawable = true);
184   virtual ~Weapon();
185 
186   // Select or deselect the weapon
187   void Select();
188   void Deselect();
189 
190   // Gestion de l'arme
191   void Manage();
192   bool CanChangeWeapon() const ;
193 
194   // Draw the weapon
195   virtual void Draw();
196 
GetIcon()197   Sprite & GetIcon() const { return *icon; };
198   // Manage the numbers of ammunitions
199   bool EnoughAmmo() const;
200   void UseAmmo() const;
201   bool EnoughAmmoUnit() const;
202   void UseAmmoUnit() const;
203 
AvailableAfterTurn()204   int AvailableAfterTurn() const { return m_available_after_turn; };
ReadInitialNbAmmo()205   int ReadInitialNbAmmo() const { return m_initial_nb_ammo; };
WriteInitialNbAmmo(int nb)206   void WriteInitialNbAmmo(int nb) { m_initial_nb_ammo = nb; };
ReadInitialNbUnit()207   int ReadInitialNbUnit() const { return m_initial_nb_unit_per_ammo; };
GetAmmoPerDrop()208   int GetAmmoPerDrop() const { return ammo_per_drop; }
GetDropProbability()209   Double GetDropProbability() const { return drop_probability; }
210 
CanBeUsedOnClosedMap()211   bool CanBeUsedOnClosedMap() const { return can_be_used_on_closed_map; };
UseCrossHair()212   bool UseCrossHair() const { return min_angle != max_angle; };
213 
214   // Calculate weapon position
215   virtual void PosXY (int &x, int &y) const;
216 
217   // Shot with the weapon
218   // Return true if we have been able to trigger the weapon
219   bool Shoot();
220 
221   // the weapon is ready to use ? (is there bullets left ?)
222   virtual bool IsReady() const;
223 
224   virtual bool IsOnCooldownFromShot() const;
225 
226   // Begin to load, to choose the strength
227   virtual void InitLoading() ;
228 
229   // Are we loading to choose the strength
IsLoading()230   virtual bool IsLoading() const { return m_first_time_loading ? true : false; };
231 
232   // Stop loading
233   virtual void StopLoading() ;
234 
235   // update strength (so the strength bar can be updated)
236   virtual void UpdateStrength();
237 
GetStrength()238   Double GetStrength() const { return m_strength; };
239 
GetMaxStrength()240   Double GetMaxStrength() const { return max_strength; };
241 
242   const Point2i GetGunHolePosition() const;
243 
244   // Choose a target.
ChooseTarget(Point2i)245   virtual void ChooseTarget (Point2i /*mouse_pos*/) { };
246 
247   // Notify a move. It is usefull only for weapon which have strong
248   // interactions with the physical engine such as grapple
NotifyMove(bool)249   virtual void NotifyMove(bool /*collision*/){};
250 
251 
252   // While the method returns true the character can not start moving left nor right.
IsPreventingLRMovement()253   virtual bool IsPreventingLRMovement() { return false; };
254   // While the method returns true the character will not jump when the user press the jump key.
IsPreventingJumps()255   virtual bool IsPreventingJumps() { return false; };
256   // While the method returns true the character will not change the weapon angle when the user tries to do so.
IsPreventingWeaponAngleChanges()257   virtual bool IsPreventingWeaponAngleChanges() { return false; };
258 
259   // Handle a keyboard event.
260 
261   // Key Shoot management
262   void HandleKeyPressed_Shoot();
263   void HandleKeyReleased_Shoot();
264 
265   // To override standard moves of character
HandleKeyPressed_MoveRight(bool)266   virtual void HandleKeyPressed_MoveRight(bool /*slowly*/) {};
HandleKeyReleased_MoveRight(bool)267   virtual void HandleKeyReleased_MoveRight(bool /*slowly*/) {};
268 
HandleKeyPressed_MoveLeft(bool)269   virtual void HandleKeyPressed_MoveLeft(bool /*slowly*/) {};
HandleKeyReleased_MoveLeft(bool)270   virtual void HandleKeyReleased_MoveLeft(bool /*slowly*/) {};
271 
HandleKeyPressed_Up(bool)272   virtual void HandleKeyPressed_Up(bool /*slowly*/) {};
HandleKeyReleased_Up(bool)273   virtual void HandleKeyReleased_Up(bool /*slowly*/) {};
274 
HandleKeyPressed_Down(bool)275   virtual void HandleKeyPressed_Down(bool /*slowly*/) {};
HandleKeyReleased_Down(bool)276   virtual void HandleKeyReleased_Down(bool /*slowly*/) {};
277 
HandleKeyPressed_Jump()278   virtual void HandleKeyPressed_Jump() {};
HandleKeyReleased_Jump()279   virtual void HandleKeyReleased_Jump() {};
280 
HandleKeyPressed_HighJump()281   virtual void HandleKeyPressed_HighJump() {};
HandleKeyReleased_HighJump()282   virtual void HandleKeyReleased_HighJump() {};
283 
HandleKeyPressed_BackJump()284   virtual void HandleKeyPressed_BackJump() {};
HandleKeyReleased_BackJump()285   virtual void HandleKeyReleased_BackJump() {};
286 
287   // Other keys
HandleKeyReleased_Num1()288   virtual void HandleKeyReleased_Num1(){};
HandleKeyReleased_Num2()289   virtual void HandleKeyReleased_Num2(){};
HandleKeyReleased_Num3()290   virtual void HandleKeyReleased_Num3(){};
HandleKeyReleased_Num4()291   virtual void HandleKeyReleased_Num4(){};
HandleKeyReleased_Num5()292   virtual void HandleKeyReleased_Num5(){};
HandleKeyReleased_Num6()293   virtual void HandleKeyReleased_Num6(){};
HandleKeyReleased_Num7()294   virtual void HandleKeyReleased_Num7(){};
HandleKeyReleased_Num8()295   virtual void HandleKeyReleased_Num8(){};
HandleKeyReleased_Num9()296   virtual void HandleKeyReleased_Num9(){};
HandleKeyReleased_Less()297   virtual void HandleKeyReleased_Less(){};
HandleKeyReleased_More()298   virtual void HandleKeyReleased_More(){};
299 
300   // Handle a mouse event
HandleMouseLeftClicReleased(bool)301   virtual void HandleMouseLeftClicReleased(bool){};
HandleMouseWheelUp(bool)302   virtual void HandleMouseWheelUp(bool /*shift*/){};
HandleMouseWheelDown(bool)303   virtual void HandleMouseWheelDown(bool /*shift*/){};
304 
305   // Get informed that the turn is over.
SignalTurnEnd()306   virtual void SignalTurnEnd() { StopLoading(); };
307 
308   // Load parameters from the xml config file
309   // Return true if xml has been succesfully load
310   bool LoadXml(const xmlNode*  weapon);
311 
312   // return the strength of the weapon
ReadStrength()313   Double ReadStrength() const { return m_strength; };
314 
315   // Data access
GetName()316   const std::string& GetName() const { return m_name; }
GetID()317   const std::string& GetID() const { return m_id; }
GetHelp()318   const std::string& GetHelp() const { return m_help; }
GetType()319   Weapon_type GetType() const { return m_type; };
320 
321   // For localization purposes, called when changing language
322   virtual void UpdateTranslationStrings() = 0;
323 
324   // For localization purposes, each weapon needs to have its own
325   // "%s team has won %d <weapon>" function
326   virtual std::string GetWeaponWinString(const char *TeamName, uint items_count) const = 0;
327 
328   // Allows or not the character selection with mouse click (tab is allowed)
329   // This is used in weapons like the automated bazooka, where it's required
330   // a target. Default is true.
331   bool mouse_character_selection;
332 
SetMinAngle(Double min)333   inline void SetMinAngle(Double min) {min_angle = min;}
GetMinAngle()334   inline const Double &GetMinAngle() const {return min_angle;}
SetMaxAngle(Double max)335   inline void SetMaxAngle(Double max) {max_angle = max;}
GetMaxAngle()336   inline const Double &GetMaxAngle() const {return max_angle;}
337   bool IsAngleValid(Double angle) const;
338 
StartMovingLeft()339   virtual void StartMovingLeft() {};
StopMovingLeft()340   virtual void StopMovingLeft() {};
341 
StartMovingRight()342   virtual void StartMovingRight() {};
StopMovingRight()343   virtual void StopMovingRight() {};
344 
StartMovingUp()345   virtual void StartMovingUp() {};
StopMovingUp()346   virtual void StopMovingUp() {};
347 
StartMovingDown()348   virtual void StartMovingDown() {};
StopMovingDown()349   virtual void StopMovingDown() {};
350 
351   virtual void StartShooting();
352   virtual void StopShooting();
353 
354   // Functions to avoid dynamic_cast
SetProjectileTimeOut(int)355   virtual void SetProjectileTimeOut(int) { };
SetAngle(Double)356   virtual void SetAngle(Double) { }
357 
358   static void Message(const std::string& msg);
359 };
360 
361 //-----------------------------------------------------------------------------
362 #endif
363