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 * Refresh des armes.
20 *****************************************************************************/
21
22 #include "weapon/weapons_list.h"
23 //-----------------------------------------------------------------------------
24 #include <algorithm>
25 #include "weapon/all.h"
26 #include "weapon/explosion.h"
27 #include "interface/interface.h"
28 #include "map/camera.h"
29 #include "map/maps_list.h"
30 #include "object/objects_list.h"
31 #include "team/macro.h"
32 #include "team/team.h"
33 #include "tool/resource_manager.h"
34 #include "network/randomsync.h"
35 //-----------------------------------------------------------------------------
36
37 //-----------------------------------------------------------------------------
38
~WeaponsList()39 WeaponsList::~WeaponsList()
40 {
41 weapons_list_it it=m_weapons_list.begin(), end=m_weapons_list.end();
42 for (; it != end; ++it)
43 delete *it;
44
45 // no need to delete objects in m_weapons_launcher_list nor clear the 2 lists !
46 // no need either to release profile, ResourceManager will do it on exit
47 weapons_res_profile = NULL;
48 }
49
50 //-----------------------------------------------------------------------------
51
WeaponsList(const xmlNode * weapons_xml)52 WeaponsList::WeaponsList(const xmlNode* weapons_xml)
53 {
54 weapons_res_profile = GetResourceManager().LoadXMLProfile("weapons.xml", false);
55
56 // First launcher weapons
57 m_launcher_weapons_list.push_back(new AnvilLauncher);
58 m_launcher_weapons_list.push_back(new TuxLauncher);
59 m_launcher_weapons_list.push_back(new GnuLauncher);
60 m_launcher_weapons_list.push_back(new PolecatLauncher);
61 m_launcher_weapons_list.push_back(new BounceBallLauncher);
62 m_launcher_weapons_list.push_back(new AutomaticBazooka);
63 m_launcher_weapons_list.push_back(new GrenadeLauncher);
64 m_launcher_weapons_list.push_back(new DiscoGrenadeLauncher);
65 m_launcher_weapons_list.push_back(new ClusterLauncher);
66 m_launcher_weapons_list.push_back(new FootBombLauncher);
67 m_launcher_weapons_list.push_back(new Bazooka);
68 m_launcher_weapons_list.push_back(new RiotBomb);
69 m_launcher_weapons_list.push_back(new Cluzooka);
70 m_launcher_weapons_list.push_back(new SubMachineGun);
71 m_launcher_weapons_list.push_back(new Gun);
72 m_launcher_weapons_list.push_back(new Shotgun);
73 m_launcher_weapons_list.push_back(new SnipeRifle);
74 m_launcher_weapons_list.push_back(new RailGun);
75 m_launcher_weapons_list.push_back(new Dynamite);
76 m_launcher_weapons_list.push_back(new FlameThrower);
77 m_launcher_weapons_list.push_back(new Mine);
78
79 // Copy launcher weapons to normal list
80 //m_weapons_list = m_launcher_weapons_list;
81 m_weapons_list.insert(m_weapons_list.end(),
82 m_launcher_weapons_list.begin(),
83 m_launcher_weapons_list.end());
84
85
86 // Add other weapons
87 m_weapons_list.push_back(new Baseball);
88 m_weapons_list.push_back(new AirAttack);
89 m_weapons_list.push_back(new Slap);
90 m_weapons_list.push_back(new Teleportation);
91 m_weapons_list.push_back(new Parachute);
92 m_weapons_list.push_back(new Suicide);
93 m_weapons_list.push_back(new SkipTurn);
94 m_weapons_list.push_back(new JetPack);
95 m_weapons_list.push_back(new Airhammer);
96 m_weapons_list.push_back(new Construct);
97 m_weapons_list.push_back(new LowGrav);
98 m_weapons_list.push_back(new Grapple);
99 m_weapons_list.push_back(new Blowtorch);
100 m_weapons_list.push_back(new Syringe);
101
102 std::list<Weapon*>::iterator
103 itw = m_weapons_list.begin(),
104 end = m_weapons_list.end();
105
106 for (; itw != end ; ++itw) {
107 (*itw)->LoadXml(weapons_xml);
108 }
109 }
110
111
112 //-----------------------------------------------------------------------------
113
UpdateTranslation()114 void WeaponsList::UpdateTranslation()
115 {
116 weapons_list_it it;
117 for (it = m_weapons_list.begin(); it != m_weapons_list.end(); it++) {
118 (*it)->UpdateTranslationStrings();
119 }
120 }
121
122 //-----------------------------------------------------------------------------
123
GetWeaponBySort(Weapon::category_t sort,Weapon::Weapon_type & type)124 bool WeaponsList::GetWeaponBySort(Weapon::category_t sort, Weapon::Weapon_type &type)
125 {
126 weapons_list_it it, end=m_weapons_list.end();
127 bool open = ActiveMap()->LoadedData()->IsOpened();
128
129 /* find the current position */
130 it = std::find(m_weapons_list.begin(),
131 m_weapons_list.end(),
132 &ActiveTeam().GetWeapon());
133
134 /* if the current weapon match the criteria */
135 if (it != end && ActiveTeam().GetWeapon().Category() == sort)
136 {
137 /* try to find the next weapon matching our criteria */
138 do {
139 ++it;
140 } while(it != end
141 && ((*it)->Category() != sort
142 || ActiveTeam().ReadNbAmmos((*it)->GetType()) == 0
143 || (!((*it)->CanBeUsedOnClosedMap()) && !open))
144 );
145
146 /* Ok, a weapon was found let's return it */
147 if (it != end && (*it)->Category() == sort)
148 {
149 type = (*it)->GetType();
150 return true;
151 }
152 }
153 /* we didn't find a valid weapon after the current one ; lets wrap:
154 * restart from the begining and try to find the first one matching
155 * our criteria */
156 it = m_weapons_list.begin();
157 while(it != end && (*it)->Category() != sort)
158 ++it;
159
160 /* no weapon of this sort was found -> give up... */
161 if (it == end)
162 return false;
163
164 /* try to find the next weapon matching our criteria */
165 while(it != end
166 && ((*it)->Category() != sort
167 || ActiveTeam().ReadNbAmmos((*it)->GetType()) == 0
168 || (!(*it)->CanBeUsedOnClosedMap() && open)))
169 ++it;
170
171 /* Ok, a weapon was found let's return it if it is not the one active */
172 if (it != end && (*it)->Category() == sort && (*it) != &ActiveTeam().GetWeapon())
173 {
174 type = (*it)->GetType();
175 return true;
176 }
177
178 /* we definitly found nothing... */
179 return false;
180 }
181
GetRandomWeaponToDrop()182 Weapon * WeaponsList::GetRandomWeaponToDrop()
183 {
184 std::list<Weapon*>::iterator it;
185 Double probability_sum = 0;
186 for (it = m_weapons_list.begin(); it != m_weapons_list.end(); ++it) {
187 probability_sum += (*it)->GetDropProbability();
188 }
189 ASSERT(probability_sum > 0);
190
191 MSG_DEBUG("random.get", "WeaponList::GetRandomWeaponToDrop()");
192 Double num = RandomSync().GetDouble(0, probability_sum);
193 Double total_bf_weapon = 0;
194 Double total_after_weapon = 0;
195
196 for (it = m_weapons_list.begin(); it != m_weapons_list.end(); it++) {
197 Weapon * weapon = *it;
198 total_after_weapon = total_bf_weapon + weapon->GetDropProbability();
199 if (total_bf_weapon < num && num <= total_after_weapon) {
200 MSG_DEBUG("bonus","Weapon choosed: %s", weapon->GetName().c_str());
201 return weapon;
202 }
203 total_bf_weapon = total_after_weapon;
204 }
205 ASSERT(false);
206 return NULL;
207 }
208
209 //-----------------------------------------------------------------------------
210
211 class test_weapon_type {
212 private:
213 Weapon::Weapon_type m_type;
214 public:
test_weapon_type(const Weapon::Weapon_type & type)215 test_weapon_type(const Weapon::Weapon_type &type) : m_type(type){ }
operator ()(const Weapon * w) const216 bool operator() (const Weapon* w) const { return w->GetType()==m_type; }
217 };
218
GetWeapon(Weapon::Weapon_type type) const219 Weapon* WeaponsList::GetWeapon (Weapon::Weapon_type type) const
220 {
221 weapons_list_it it;
222 it = std::find_if(m_weapons_list.begin(), m_weapons_list.end(), test_weapon_type(type));
223 ASSERT (it != m_weapons_list.end());
224 return *it;
225 }
226
GetWeaponLauncher(Weapon::Weapon_type type) const227 WeaponLauncher* WeaponsList::GetWeaponLauncher(Weapon::Weapon_type type) const
228 {
229 launcher_weapons_list_it it;
230 it = std::find_if(m_launcher_weapons_list.begin(), m_launcher_weapons_list.end(), test_weapon_type(type));
231 ASSERT (it != m_launcher_weapons_list.end());
232 return *it;
233 }
234
235 //-----------------------------------------------------------------------------
236