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 * AirHammer - Use it to dig
20 *****************************************************************************/
21
22 #include "weapon/airhammer.h"
23 #include "weapon/explosion.h"
24 #include "weapon/weapon_cfg.h"
25
26 //-----------------------------------------------------------------------------
27 #include <sstream>
28 #include "character/character.h"
29 #include "game/game.h"
30 #include "game/game_time.h"
31 #include "include/action_handler.h"
32 #include "interface/game_msg.h"
33 #include "map/map.h"
34 #include "object/objects_list.h"
35 #include "sound/jukebox.h"
36 #include "team/teams_list.h"
37 #include "team/macro.h"
38 #include "team/team.h"
39 #include "tool/resource_manager.h"
40 #include "tool/xml_document.h"
41
42 //-----------------------------------------------------------------------------
43
44 const uint MIN_TIME_BETWEEN_JOLT = 100; // in milliseconds
45
46 //-----------------------------------------------------------------------------
47
48 class AirhammerConfig : public WeaponConfig
49 {
50 public:
51 uint range;
52 AirhammerConfig();
53 void LoadXml(const xmlNode* elem);
54 };
55
56 //-----------------------------------------------------------------------------
57
Airhammer()58 Airhammer::Airhammer():
59 Weapon(WEAPON_AIR_HAMMER, "airhammer", new AirhammerConfig()),
60 active(false),
61 deactivation_requested(false)
62 {
63 UpdateTranslationStrings();
64
65 m_category = TOOL;
66
67 impact = GetResourceManager().LoadImage( weapons_res_profile, "airhammer_impact");
68 m_time_between_each_shot = MIN_TIME_BETWEEN_JOLT;
69 m_can_change_weapon = true;
70 }
71
72 //-----------------------------------------------------------------------------
73
UpdateTranslationStrings()74 void Airhammer::UpdateTranslationStrings()
75 {
76 m_name = _("Airhammer");
77 m_help = _("Press space to dig\nAmmo is used when counter reaches zero\nOne ammo per turn");
78 }
79
80 //-----------------------------------------------------------------------------
81
p_Shoot()82 bool Airhammer::p_Shoot()
83 {
84 // initiate movement ;-)
85 ActiveCharacter().SetRebounding(false);
86
87 Point2i pos = Point2i(ActiveCharacter().GetX() + ActiveCharacter().GetWidth()/2 - impact.GetWidth()/2,
88 ActiveCharacter().GetTestRect().GetPositionY() +
89 ActiveCharacter().GetHeight() -16);
90
91 ParticleEngine::AddNow(pos + Point2i(impact.GetWidth()/4,9), 1, particle_AIR_HAMMER,
92 true, -THREE * QUARTER_PI, 5.0 + GameTime::GetInstance()->Read() % 5);
93 ParticleEngine::AddNow(pos + Point2i(3*impact.GetWidth()/4,9), 1, particle_AIR_HAMMER,
94 true, -QUARTER_PI, 5.0 + GameTime::GetInstance()->Read() % 5);
95 GetWorld().Dig(pos, impact);
96
97 return true;
98 }
99
100 //-----------------------------------------------------------------------------
p_Deselect()101 void Airhammer::p_Deselect()
102 {
103 drill_sound.Stop();
104 select_sound.Stop();
105 ActiveCharacter().SetMovement("breathe");
106 active = false;
107 }
108
StartShooting()109 void Airhammer::StartShooting()
110 {
111 if (!EnoughAmmo())
112 return;
113 //if the sound isn't already playing, play it again.
114 select_sound.Stop();
115 if (!drill_sound.IsPlaying()) {
116 drill_sound.Play("default","weapon/airhammer", -1);
117 }
118
119 active = true;
120 deactivation_requested = false;
121 }
122
StopShooting()123 void Airhammer::StopShooting()
124 {
125 // The airhammer does not get deactivated in this method,
126 // because there could be a shot in progress.
127 // Explantion:
128 // The weapon calls PrepareShot of the active character
129 // which will then call p_Shot when it's ready
130 deactivation_requested = true;
131 }
132
ShouldAmmoUnitsBeDrawn() const133 bool Airhammer::ShouldAmmoUnitsBeDrawn() const
134 {
135 // Hide that the units are actually at maximum and not at 0
136 // when the ammo counter is at 0.
137 return active || EnoughAmmo();
138 }
139 //-----------------------------------------------------------------------------
140
Refresh()141 void Airhammer::Refresh()
142 {
143 if (active && deactivation_requested && !ActiveCharacter().IsPreparingShoot()) {
144 active = false;
145 drill_sound.Stop();
146 PlaySoundSelect();
147 ActiveTeam().AccessNbUnits() = 0;
148 }
149 if (EnoughAmmoUnit() && active) {
150 Weapon::RepeatShoot();
151 }
152 }
153
PlaySoundSelect()154 void Airhammer::PlaySoundSelect()
155 {
156 select_sound.Play("default","weapon/airhammer_select",-1);
157 }
158
p_Select()159 void Airhammer::p_Select()
160 {
161 PlaySoundSelect();
162 }
163
GetWeaponWinString(const char * TeamName,uint items_count) const164 std::string Airhammer::GetWeaponWinString(const char *TeamName, uint items_count ) const
165 {
166 return Format(ngettext(
167 "%s team has won %u airhammer! Don't make too much noise with it! Thanks, your neighbours.",
168 "%s team has won %u airhammers! Don't make too much noise with them! Thanks, your neighbours.",
169 items_count), TeamName, items_count);
170 }
171
172
173 //-----------------------------------------------------------------------------
174
cfg()175 AirhammerConfig& Airhammer::cfg()
176 {
177 return static_cast<AirhammerConfig&>(*extra_params);
178 }
179
180 //-----------------------------------------------------------------------------
181
AirhammerConfig()182 AirhammerConfig::AirhammerConfig()
183 {
184 range = 30;
185 }
186
187 //-----------------------------------------------------------------------------
188
LoadXml(const xmlNode * elem)189 void AirhammerConfig::LoadXml(const xmlNode* elem){
190 WeaponConfig::LoadXml(elem);
191 XmlReader::ReadUint(elem, "range", range);
192 }
193