1 /************************************************************************
2 * *
3 * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
4 * *
5 * Copyright (C) 2005 Stuart Binge <skbinge@gmail.com> *
6 * Copyright (C) 2005 Joost Peters <joostp@users.sourceforge.net> *
7 * Copyright (C) 2006 Trent Waddington <qg@biodome.org> *
8 * Copyright (C) 2006 Tarjei Knapstad <tarjei.knapstad@gmail.com> *
9 * Copyright (C) 2010 Bohdan Stelmakh <chamel@users.sourceforge.net> *
10 * Copyright (C) 2011 Benoit Blancard <benblan@users.sourceforge.net>*
11 * Copyright (C) 2011 Joey Parrish <joey.parrish@gmail.com> *
12 * *
13 * This program is free software; you can redistribute it and / or *
14 * modify it under the terms of the GNU General Public License as *
15 * published by the Free Software Foundation; either version 2 of the *
16 * License, or (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
21 * General Public License for more details. *
22 * *
23 * You can view the GNU General Public License, online, at the GNU *
24 * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
25 * The full text of the license is also included in the file COPYING. *
26 * *
27 ************************************************************************/
28
29 #include <stdio.h>
30 #include <assert.h>
31
32 #include "app.h"
33 #include "utils/log.h"
34 #include "utils/file.h"
35 #include "utils/configfile.h"
36
WeaponManager()37 WeaponManager::WeaponManager() {
38 all_game_weapons_.reserve(18);
39 }
40
destroy()41 void WeaponManager::destroy() {
42 preFetch_.clear();
43 availableWeapons_.clear();
44 }
45
~WeaponManager()46 WeaponManager::~WeaponManager() {
47 destroy();
48 for (std::vector<Weapon *>::iterator it = all_game_weapons_.begin();
49 it != all_game_weapons_.end();it++)
50 {
51 delete (*it);
52 }
53 all_game_weapons_.clear();
54
55 }
56
reset()57 void WeaponManager::reset() {
58 destroy();
59
60 all_game_weapons_.clear();
61 all_game_weapons_.push_back(loadWeapon(Weapon::Persuadatron));
62 all_game_weapons_.push_back(loadWeapon(Weapon::Pistol));
63 all_game_weapons_.push_back(loadWeapon(Weapon::Shotgun));
64 all_game_weapons_.push_back(loadWeapon(Weapon::Uzi));
65 all_game_weapons_.push_back(loadWeapon(Weapon::Scanner));
66 all_game_weapons_.push_back(loadWeapon(Weapon::MediKit));
67 all_game_weapons_.push_back(loadWeapon(Weapon::Minigun));
68 all_game_weapons_.push_back(loadWeapon(Weapon::Flamer));
69 all_game_weapons_.push_back(loadWeapon(Weapon::LongRange));
70 all_game_weapons_.push_back(loadWeapon(Weapon::EnergyShield));
71 all_game_weapons_.push_back(loadWeapon(Weapon::Laser));
72 all_game_weapons_.push_back(loadWeapon(Weapon::GaussGun));
73 all_game_weapons_.push_back(loadWeapon(Weapon::AccessCard));
74 all_game_weapons_.push_back(loadWeapon(Weapon::TimeBomb));
75
76 // Enables default weapons
77 enableWeapon(Weapon::Persuadatron);
78 enableWeapon(Weapon::Pistol);
79 enableWeapon(Weapon::Shotgun);
80 enableWeapon(Weapon::Scanner);
81 enableWeapon(Weapon::MediKit);
82 }
83
cheatEnableAllWeapons()84 void WeaponManager::cheatEnableAllWeapons() {
85 enableWeapon(Weapon::Persuadatron);
86 enableWeapon(Weapon::Pistol);
87 enableWeapon(Weapon::Shotgun);
88 enableWeapon(Weapon::Uzi);
89 enableWeapon(Weapon::Scanner);
90 enableWeapon(Weapon::MediKit);
91 enableWeapon(Weapon::Minigun);
92 enableWeapon(Weapon::Flamer);
93 enableWeapon(Weapon::LongRange);
94 enableWeapon(Weapon::EnergyShield);
95 enableWeapon(Weapon::Laser);
96 enableWeapon(Weapon::GaussGun);
97 enableWeapon(Weapon::AccessCard);
98 enableWeapon(Weapon::TimeBomb);
99 }
100
enableWeapon(Weapon::WeaponType wt)101 void WeaponManager::enableWeapon(Weapon::WeaponType wt) {
102 // First check if weapon is not already available
103 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
104 if (wt == availableWeapons_.get(i)->getWeaponType())
105 return;
106 }
107
108 // Then get weapon
109 Weapon *pWeapon = getWeapon(wt);
110
111 // removes it from cache
112 for (std::vector < Weapon * >::iterator it = preFetch_.begin();
113 it != preFetch_.end(); it++) {
114 if (pWeapon == *it) {
115 preFetch_.erase(it);
116 break;
117 }
118 }
119
120 // make it available
121 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
122 if (pWeapon->getWeaponType() < availableWeapons_.get(i)->getWeaponType()) {
123 // The new weapon is inserted in the order of the WeaponType constants
124 availableWeapons_.insertAt(i, pWeapon);
125 return;
126 }
127 }
128 // If we're here, it's because the new weapon comes at the end of the list
129 availableWeapons_.add(pWeapon);
130 }
131
getWeapon(Weapon::WeaponType wt)132 Weapon * WeaponManager::getWeapon(Weapon::WeaponType wt) {
133 // Search in prefetched weapons first
134 for (unsigned int i = 0; i < preFetch_.size(); i++) {
135 if (wt == preFetch_[i]->getWeaponType())
136 return preFetch_[i];
137 }
138
139 // Then search in available weapons
140 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
141 if (wt == availableWeapons_.get(i)->getWeaponType())
142 return availableWeapons_.get(i);
143 }
144
145 // Weapon was not found so loads it
146 Weapon *pWeapon = NULL;
147
148 for (std::vector<Weapon *>::iterator it = all_game_weapons_.begin();
149 it != all_game_weapons_.end();it++)
150 {
151 if ((*it)->getWeaponType() == wt) {
152 pWeapon = *it;
153 break;
154 }
155 }
156 assert(pWeapon);
157 // Stores it in cache
158 preFetch_.push_back(pWeapon);
159
160 return pWeapon;
161 }
162
isAvailable(Weapon * pWeapon)163 bool WeaponManager::isAvailable(Weapon *pWeapon) {
164 // search in available weapons
165 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
166 if (pWeapon->getWeaponType() == availableWeapons_.get(i)->getWeaponType())
167 return true;
168 }
169
170 // No weapon of that type has been found
171 return false;
172 }
173
getAvailable(Weapon::WeaponType wpn)174 Weapon * WeaponManager::getAvailable(Weapon::WeaponType wpn) {
175 // search in available weapons
176 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
177 if (wpn == availableWeapons_.get(i)->getWeaponType())
178 return availableWeapons_.get(i);
179 }
180
181 // No weapon of that type has been found
182 return NULL;
183 }
184
getAvailable(uint32 dmg_type,std::vector<Weapon * > & wpns)185 void WeaponManager::getAvailable(uint32 dmg_type, std::vector <Weapon *> &wpns)
186 {
187 // search in available weapons
188 for (unsigned i = 0; i != availableWeapons_.size(); ++i) {
189 if ((availableWeapons_.get(i)->dmgType() & dmg_type) != 0)
190 wpns.push_back(availableWeapons_.get(i));
191 }
192 }
193
loadWeapon(Weapon::WeaponType wt)194 Weapon * WeaponManager::loadWeapon(Weapon::WeaponType wt) {
195 /* NOTE: small icon 27 exists and looks like an N with an arrow above it.
196 the corresponding large icon is actually the "all" button on the
197 select menu. It would appear Bullfrog was going to have another
198 weapon here but it got scrapped early on and they used the large
199 icon space to implement the all button.
200 */
201 std::string filename(File::dataFullPath("ref/weapons.dat"));
202 try {
203 // Loads configuration file
204 ConfigFile conf(filename);
205 // TODO:calibrate weapon time for shot and reload, angle, accuracy
206 return new Weapon(wt, conf);
207 } catch (...) {
208 FSERR(Log::k_FLG_IO, "WeaponManager", "loadWeapon", ("File %s cannot be read", filename.c_str()))
209 return NULL;
210 }
211 }
212
saveToFile(PortableFile & file)213 bool WeaponManager::saveToFile(PortableFile &file) {
214 file.write32(availableWeapons_.size());
215
216 for(unsigned int i=0; i<availableWeapons_.size(); i++) {
217 Weapon *pWeapon = availableWeapons_.get(i);
218 file.write32(pWeapon->getWeaponType());
219 }
220
221 return true;
222 }
223
loadFromFile(PortableFile & infile,const FormatVersion & v)224 bool WeaponManager::loadFromFile(PortableFile &infile, const FormatVersion& v) {
225 int nbWeap = infile.read32();
226
227 for (int i = 0; i < nbWeap; i++) {
228 int type = infile.read32();
229 Weapon::WeaponType wt = Weapon::Unknown;
230 switch (type) {
231 case Weapon::Persuadatron:
232 wt = Weapon::Persuadatron;
233 break;
234 case Weapon::Pistol:
235 wt = Weapon::Pistol;
236 break;
237 case Weapon::GaussGun:
238 wt = Weapon::GaussGun;
239 break;
240 case Weapon::Shotgun:
241 wt = Weapon::Shotgun;
242 break;
243 case Weapon::Uzi:
244 wt = Weapon::Uzi;
245 break;
246 case Weapon::Minigun:
247 wt = Weapon::Minigun;
248 break;
249 case Weapon::Laser:
250 wt = Weapon::Laser;
251 break;
252 case Weapon::Flamer:
253 wt = Weapon::Flamer;
254 break;
255 case Weapon::LongRange:
256 wt = Weapon::LongRange;
257 break;
258 case Weapon::Scanner:
259 wt = Weapon::Scanner;
260 break;
261 case Weapon::MediKit:
262 wt = Weapon::MediKit;
263 break;
264 case Weapon::TimeBomb:
265 wt = Weapon::TimeBomb;
266 break;
267 case Weapon::AccessCard:
268 wt = Weapon::AccessCard;
269 break;
270 case Weapon::EnergyShield:
271 wt = Weapon::EnergyShield;
272 break;
273 default:
274 wt = Weapon::Unknown;
275 }
276 // enable weapon
277 enableWeapon(wt);
278 }
279
280 return true;
281 }
282
checkDmgTypeCanShootStrict(uint32 dmg,bool & can_shoot)283 bool WeaponManager::checkDmgTypeCanShootStrict(uint32 dmg, bool &can_shoot)
284 {
285 bool found = false;
286 can_shoot = false;
287
288 for (std::vector<Weapon *>::iterator it = all_game_weapons_.begin();
289 it != all_game_weapons_.end();it++)
290 {
291 if ((*it)->dmgType() == dmg) {
292 found = true;
293 if (((*it)->shotProperty() & Weapon::spe_CanShoot) != 0)
294 can_shoot = true;
295 }
296 }
297
298 return found;
299 }
300
checkDmgTypeCanShootNonStrict(uint32 dmg,bool & can_shoot)301 bool WeaponManager::checkDmgTypeCanShootNonStrict(uint32 dmg, bool &can_shoot)
302 {
303 bool found = false;
304 can_shoot = false;
305
306 for (std::vector<Weapon *>::iterator it = all_game_weapons_.begin();
307 it != all_game_weapons_.end();it++)
308 {
309 if (((*it)->dmgType() & dmg) != 0) {
310 found = true;
311 if ((*it)->canShoot())
312 can_shoot = true;
313 }
314 }
315
316 return found;
317
318 }
319
320