]> ruin.nu Git - hbs.git/blob - bs/fleet.cpp
started to work on the battle report.. almost there =)
[hbs.git] / bs / fleet.cpp
1 /***************************************************************************
2   fleet.cpp  -  description
3   -------------------
4 begin                : Tue Jan 22 2002
5 copyright            : (C) 2002 by Michael Andreen
6 email                : whale@linux.nu
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include "fleet.h"
19
20 #include <iostream>
21 #include <cstdlib>
22 using namespace std;
23
24 //Static variables
25 map<string, vector<int> > Fleet::s_Races;
26 UnitList Fleet::s_Units;
27
28 Fleet::Fleet()
29 {
30         m_iETA = 0;
31         m_iStays = 3;
32         m_sRace = "Cathaar";
33 }
34
35 Fleet::~Fleet(){
36 }
37
38 //////////////////////////////////////////////////////////////////////////
39 //
40 void Fleet::setName(string sName)
41 {
42         m_sName = sName;
43 }
44
45 //////////////////////////////////////////////////////////////////////////
46 //
47 string Fleet::name() const
48 {
49         return m_sName;
50 }
51
52 //////////////////////////////////////////////////////////////////////////
53 //
54 /** This function first sets the race, then it iterates through the the 
55  * s_Races and checks if it finds the race it returns true, if it reaches
56  * the end without finding it it returns false.
57  */
58 bool Fleet::setRace(string sRace)
59 {
60         m_sRace = sRace;
61         for (map<string, vector<int> >::iterator i = s_Races.begin(); i != s_Races.end(); i++)
62         {
63                 if (m_sRace == (*i).first)
64                         return true;
65         }
66         return false;
67 }
68
69 //////////////////////////////////////////////////////////////////////////
70 //
71 string Fleet::race() const
72 {
73         return m_sRace;
74 }
75
76 //////////////////////////////////////////////////////////////////////////
77 //
78 /** This function iterates through m_Fleet and adds all numbers together to
79  * produce a total.
80  */
81 int Fleet::numberOfShips() const
82 {
83         int total = 0;
84
85         for (map<string, vector<int> >::const_iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
86         {
87                 if (i->second.size() != 0)
88                         total += i->second[0];
89         }
90
91         return total;
92 }
93
94 //////////////////////////////////////////////////////////////////////////
95 //
96 void Fleet::setETA(int eta)
97 {
98         m_iETA = eta;
99 }
100
101 //////////////////////////////////////////////////////////////////////////
102 //
103 int  Fleet::ETA() const
104 {
105         return m_iETA;
106 }
107
108 //////////////////////////////////////////////////////////////////////////
109 //
110 void Fleet::setRaces(map<string, vector<int> >& races)
111 {
112         s_Races = races;
113 }
114
115 //////////////////////////////////////////////////////////////////////////
116 //
117 void Fleet::setUnits(UnitList& units)
118 {
119         s_Units = units;
120
121
122         
123            for (UnitList::iterator i = s_Units.begin(); i != s_Units.end(); i++)
124            {
125                    cerr << s_Units[(*i).first].Name() << "\t\t"
126 /*                 << s_Units[(*i).first].race() <<"\t"
127                    << s_Units[(*i).first].unitClass() << "\t"
128                    << s_Units[(*i).first].target(0) << "\t"
129                    << s_Units[(*i).first].target(1) << "\t"
130                    << s_Units[(*i).first].target(2) << "\t"
131                    << s_Units[(*i).first].initiative() << "\t"
132                    << s_Units[(*i).first].agility() << "\t"
133                    << s_Units[(*i).first].weaponSpeed() << "\t"
134                    << s_Units[(*i).first].guns() << "\t"
135                    << s_Units[(*i).first].power() << "\t"
136                    << s_Units[(*i).first].armor() << "\t"
137                    << s_Units[(*i).first].EMP() << "\t"
138                    << s_Units[(*i).first].totRes() << "\t"
139                    << s_Units[(*i).first].fuel() << "\t"
140                    << s_Units[(*i).first].ETA() << "\t"*/
141                    << s_Units[(*i).first].type() << endl;
142            }
143 }
144
145 //////////////////////////////////////////////////////////////////////////
146 //
147 const map<string, vector<int> >& Fleet::Races()
148 {
149         return s_Races;
150 }
151
152 //////////////////////////////////////////////////////////////////////////
153 //
154 const UnitList& Fleet::Units()
155 {
156         return s_Units;
157 }
158
159 //////////////////////////////////////////////////////////////////////////
160 //
161 vector<int> Fleet::RacesAllowed() const
162 {
163         return s_Races[m_sRace];
164 }
165
166 //////////////////////////////////////////////////////////////////////////
167 //
168 unsigned Fleet::score(int tick) const
169 {
170         unsigned tot_score = 0;
171
172         for (FleetList::const_iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
173         {
174                 int ticks =     i->second.size();
175                 if (ticks == 0)
176                         continue;
177                 --ticks;
178                 if ( ticks < tick)
179                         tot_score += i->second[ticks] * s_Units[i->first].totRes() / 10;
180                 else
181                         tot_score += i->second[tick] * s_Units[i->first].totRes() / 10;
182         }
183
184         return tot_score;
185 }
186
187 //////////////////////////////////////////////////////////////////////////
188 //
189 void Fleet::setFleet(string unittype, int number, int tick)
190 {
191         int earlier = 0;
192         int ticks = m_Fleet[unittype].size();
193
194         if (ticks != 0)
195                 earlier = m_Fleet[unittype][ticks - 1];
196
197         for (int i = ticks; i <= tick; ++i)
198         {
199                 m_Fleet[unittype].push_back(earlier);
200         }
201         m_Fleet[unittype][tick] = number;
202 }
203
204 //////////////////////////////////////////////////////////////////////////
205 //
206 void Fleet::addFleet(std::string unittype, int number, int tick)
207 {
208         int earlier = 0;
209         int ticks = m_Fleet[unittype].size();
210
211         if (ticks != 0)
212                 earlier = m_Fleet[unittype][ticks - 1];
213
214         for (int i = ticks; i <= tick; ++i)
215         {
216                 m_Fleet[unittype].push_back(earlier);
217         }
218         m_Fleet[unittype][tick] += number;
219 }
220
221 //////////////////////////////////////////////////////////////////////////
222 //
223 int      Fleet::fleet(string unittype, int tick)
224 {
225
226         int ticks = m_Fleet[unittype].size();
227         if (ticks == 0)
228                 return 0;
229
230         if (tick < 0)
231                 return m_Fleet[unittype][0];
232
233         --ticks;
234
235         if (ticks < tick)
236                 return m_Fleet[unittype][ticks];
237
238         return m_Fleet[unittype][tick];
239 }
240
241 //////////////////////////////////////////////////////////////////////////
242 //
243 int Fleet::blockedFleet(std::string unittype, int tick)
244 {
245         int ticks = m_BlockedFleet[unittype].size();
246         if (ticks == 0)
247                 return 0;
248
249         --ticks;
250
251         if (ticks < tick)
252                 return 0;
253
254         return m_BlockedFleet[unittype][tick];
255 }
256
257 //////////////////////////////////////////////////////////////////////////
258 //
259 void Fleet::setBlockedFleet(std::string unittype, int number, int tick)
260 {
261         int ticks = m_BlockedFleet[unittype].size();
262
263         for (int i = ticks; i <= tick; ++i)
264         {
265                 m_BlockedFleet[unittype].push_back(0);
266         }
267         m_BlockedFleet[unittype][tick] = number;
268
269         cerr << "This fleet got " << m_BlockedFleet[unittype][tick] << " blocked units tick: " << tick << endl;
270
271 }
272
273 //////////////////////////////////////////////////////////////////////////
274 //
275 void Fleet::addToThis(std::vector<Fleet*> fleets, int tick)
276 {
277         for (UnitList::iterator i = s_Units.begin();  i != s_Units.end(); ++i)
278         {
279                 if (m_Fleet[i->first].size() == 0)
280                         m_Fleet[i->first].push_back(0);
281
282                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
283                 {
284                         int num = (*j)->fleet(i->first, tick);
285                         m_Fleet[i->first][0] += num;
286                         if (num > 0)
287                                 cerr << (*j)->name() <<  " adding " << num << " units of type " << i->first << endl;
288                 }
289         }
290 }
291
292 //////////////////////////////////////////////////////////////////////////
293 //
294 void Fleet::distributeLossesGains(std::vector<Fleet*> fleets, int tick)
295 {
296         for (UnitList::iterator i = s_Units.begin(); i != s_Units.end(); ++i)
297         {
298                 string unittype = i->first;
299
300
301                 if (m_Fleet[unittype].size() < 1)
302                         continue;
303                 if (m_Fleet[unittype][0] == 0)
304                         continue;
305
306
307                 int totallost = fleet(unittype,1) - fleet(unittype, 0);
308
309
310                 cerr << "Distributing type: " << unittype << " with a total loss of " << totallost << " units" << endl;
311
312                 cerr << "Total number of units before: " << fleet(unittype, 0)  << " and after : " << fleet(unittype, 1) << endl;
313
314                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
315                 {
316                         int fl1 = (*j)->fleet(unittype, tick - 1);
317                         float part = float(fl1) / fleet(unittype, 0) ;
318                         int lost =  totallost * part;
319                         (*j)->setFleet(unittype, (*j)->fleet(unittype, tick - 1) + lost, tick);
320
321                         cerr << (*j)->name() << " gaining " << lost << " " << unittype  << " since it's " << part * 100 << "% of the whole fleet, and it had : " << fl1 << " units last tick.." <<  endl;
322
323                         lost = part * blockedFleet(unittype, 0);
324
325                         cerr << (*j)->name() << " got " << lost << " blocked " << unittype  << ", the total number of blocked ships was: " << blockedFleet(unittype, 0) << endl; 
326
327                         (*j)->setBlockedFleet(unittype, lost, tick);
328                 }
329         }
330 }
331
332 //////////////////////////////////////////////////////////////////////////
333 //
334 std::vector<Fleet*> Fleet::calculateSide(std::vector<Fleet*> fleets, int stays, int tick)
335 {
336         vector<Fleet*> fl;
337         for (vector<Fleet*>::iterator i = fleets.begin(); i != fleets.end(); ++i)
338         {
339                 if ((*i)->stays() == 0)
340                         continue;
341                 else if (( tick - (*i)->ETA()) >= 0 && (tick - (*i)->ETA()) < (*i)->stays())
342                 {
343                         fl.push_back((*i));
344                         cerr << "Using fleet " << (*i)->name() << " for tick " << tick << endl;
345                 }
346                 else if ((*i)->stays() < 0)
347                         fl.push_back((*i));
348         }
349         return fl;
350 }
351
352 //////////////////////////////////////////////////////////////////////////
353 //
354 int Fleet::freeFleet(std:: string unittype, int tick)
355 {
356         int bticks = m_BlockedFleet[unittype].size();
357
358         --bticks;
359
360         if (bticks < tick)
361                 return fleet(unittype, tick);
362
363
364         int free = fleet(unittype,tick) - m_BlockedFleet[unittype][tick];
365         if (free < 0)
366                 return 0;
367         return free;
368 }
369
370
371 //////////////////////////////////////////////////////////////////////////
372 //
373 void Fleet::takeShoot(std::string unittype, int number, std::map<std::string, int>& hitunits)
374 {
375
376         float guns = s_Units[unittype].guns() * number;
377
378
379         if (guns == 0)
380                 return;
381
382         cerr << number << " " << unittype << ": with " << guns << " guns\n";
383
384         float gunsleft = guns;
385         for (int count = 0; count < 3; ++count)//vector<string>::iterator i = s_Units[unittype].target().begin(); i != s_Units[unittype].target().end(); ++i)
386         {
387                 string ta = s_Units[unittype].target(count);
388                 cerr << "Shooting at target class: " << ta << endl;
389                 while (gunsleft > 0)
390                 {
391
392                         map<string, int*> targets;
393
394                         for (UnitList::iterator j = s_Units.begin(); j != s_Units.end(); ++j)
395                         {
396                                 if (m_Fleet[j->first].size() == 0)
397                                         continue;
398
399
400                                 if (m_Fleet[j->first].size() == 1 )
401                                         m_Fleet[j->first].push_back(m_Fleet[j->first][0]);
402
403                                 //cerr << "Target is class: " << j->second.type() << endl;
404
405                                 if (m_Fleet[j->first][1] > 0  && ( ta == j->second.unitClass() || ta == "All"))
406                                 {
407
408                                         //      cerr << "Looking at target: " << j->first << endl;
409                                         targets[j->first] = &m_Fleet[j->first][1];
410                                 }
411                         }
412
413                         if (targets.size() == 0)
414                                 break;
415
416                         int total = 0;
417                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
418                                 total += (*j->second);
419
420                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
421                         {
422                                 float maxguns = float((*j->second))/total * guns;
423                                 //cerr << "Now shooting at target: " << j->first << endl;
424
425                                 if (m_Armor[j->first] <= 0 || m_Armor[j->first] > s_Units[j->first].armor())
426                                         m_Armor[j->first] = s_Units[j->first].armor();
427                                 double k = maxguns;
428
429                                 //cerr << "Targets agility: " << s_Units[j->first].agility() << endl;
430                                 //cerr << "Weaponspeed: " << s_Units[unittype].weaponSpeed() << endl;
431                                 while (k > 0)   
432                                 {
433
434                                         if (*(j->second) <= 0)
435                                                 break;
436
437                                         int wpsp = s_Units[unittype].weaponSpeed();
438                                         int agil = s_Units[j->first].agility();
439
440                                         k -= float(100)/(25 + wpsp - agil);
441                                         //cout << "Used " << blaha << " guns to hit with one shot.\n";
442                                         //cout << "WPSP: " << wpsp << "\nAgil: " << agil << endl;
443
444                                         m_Armor[j->first] -= s_Units[unittype].power();
445                                         if (m_Armor[j->first] <= 0)
446                                         {
447                                                 m_Armor[j->first] = s_Units[j->first].armor();
448                                                 (*j->second)--;
449                                                 hitunits[j->first]++;
450
451                                                 //There is a chance that we're hitting a blocked ship.
452                                                 /*Not anymore..
453                                                 if (m_BlockedFleet[j->first].size() >= 1)
454                                                 {
455                                                         int test = rand() % m_BlockedFleet[j->first][0];
456                                                         if (test == 1
457                                                                         && m_BlockedFleet[j->first][0] > 0)
458                                                         {
459                                                                 if (m_BlockedFleet[j->first].size() == 1)
460                                                                         m_BlockedFleet[j->first].push_back(m_BlockedFleet[j->first][0] - 1);
461                                                                 else if (m_BlockedFleet[j->first][1] > 0)
462                                                                         m_BlockedFleet[j->first][1]--;
463                                                         }
464                                                 }
465                                                 */
466                                         }
467
468                                 }
469
470                                 cerr << hitunits[j->first] << " units of type: " << j->first << "killed\n";
471                                 if (k <= 0)
472                                         gunsleft -= maxguns;
473                                 else
474                                         gunsleft -= maxguns - k;
475                         }
476                 }
477         }
478 }
479
480 //////////////////////////////////////////////////////////////////////////
481 //
482 void Fleet::takeEMP(std::string unittype, int number, std::map<std::string, int>& hitunits)
483 {
484         int guns = s_Units[unittype].guns() * number;
485         if (guns == 0)
486                 return;
487
488         cerr << unittype << ": with " << guns << " guns\n";
489
490         float gunsleft = guns;
491         for (int count = 0; count < 3; ++count)//vector<string>::iterator i = s_Units[unittype].target().begin(); i != s_Units[unittype].target().end(); ++i)
492         {
493                 string ta = s_Units[unittype].target(count);
494                 cerr << "Shooting at target class: " << ta << endl;
495                 while (gunsleft > 0)
496                 {
497
498                         map<string, int*> targets;
499
500                         for (UnitList::iterator j = s_Units.begin(); j != s_Units.end(); ++j)
501                         {
502                                 if (j->second.type() == "PDS")
503                                         continue;
504
505                                 if (freeFleet(j->first, 1) <= 0)
506                                         continue;
507
508                                 if (m_Fleet[j->first].size() == 0)
509                                         continue;
510
511                                 if (m_Fleet[j->first].size() == 1)
512                                         m_Fleet[j->first].push_back(m_Fleet[j->first][0]);
513
514                                 //cerr << "Target is class: " << j->second.type() << endl;
515
516                                 if (m_Fleet[j->first][1] > 0  && ( ta == j->second.unitClass() || ta == "All"))
517                                 {
518
519                                         //      cerr << "Looking at target: " << j->first << endl;
520                                         targets[j->first] = &m_Fleet[j->first][1];
521                                 }
522
523                         }
524
525                         if (targets.size() == 0)
526                                 break;
527
528                         int total = 0;
529                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
530                                 total += (*j->second);
531
532                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
533                         {
534                                 float maxguns = float((*j->second))/total * guns;
535                                 cerr << "Now shooting at target: " << j->first << endl;
536
537                                 double k = maxguns;
538
539                                 int hits = 0;
540
541                                 while (k > 0)   
542                                 {
543
544                                         if (*(j->second) <= blockedFleet(j->first, 1))
545                                                 break;
546
547                                         int eres = s_Units[j->first].EMP();
548
549                                         k -= float(100)/(100-eres);
550                                         hits++;
551                                         blockFleet(j->first, 1);
552                                 }
553
554                                 cerr << hits << " units of type: " << j->first << " blocked\n";
555                                 if (k <= 0)
556                                         gunsleft -= maxguns;
557                                 else
558                                         gunsleft -= maxguns - k;
559                         }
560                 }
561         }
562 }
563
564 //////////////////////////////////////////////////////////////////////////
565 //
566 void Fleet::killFleet(std::string unittype, int number, int tick)
567 {
568         int earlier = 0;
569         int ticks = m_Fleet[unittype].size();
570
571         if (ticks != 0)
572                 earlier = m_Fleet[unittype][ticks - 1];
573
574         for (int i = ticks; i <= tick; ++i)
575         {
576                 m_Fleet[unittype].push_back(earlier);
577         }
578         m_Fleet[unittype][tick] -= number;
579 }
580
581 //////////////////////////////////////////////////////////////////////////
582 //
583 void Fleet::setResource(std::string type, int number, int tick)
584 {
585
586         int ticks = m_Resources[type].size();
587         for (int i = ticks; i <= tick; ++i)
588                 m_Resources[type].push_back(number);
589         m_Resources[type][tick] = number;
590 }
591
592 //////////////////////////////////////////////////////////////////////////
593 //
594 void Fleet::addResource(std::string type, int number, int tick)
595 {
596
597         int ticks = m_Resources[type].size();
598         int latest = resource(type, tick - 1);
599
600         for (int i = ticks; i <= tick; ++i)
601                 m_Resources[type].push_back(latest);
602         m_Resources[type][tick] += number;
603 }
604
605 //////////////////////////////////////////////////////////////////////////
606 //
607 int Fleet::resource(std::string type, int tick) const
608 {
609         if (tick < 0)
610                 return 0;
611
612         vector<int>const* resource = 0;
613         for (ResourceList::const_iterator i = m_Resources.begin(); i != m_Resources.end(); ++i)
614         {
615                 if (i->first == type)
616                 {
617                         resource = &i->second;
618                         break;
619                 }
620         }
621         if (resource == 0)
622                 return 0;
623
624         int ticks = resource->size();
625
626         if( ticks == 0)
627                 return 0;
628
629         --ticks;
630
631         if (ticks < tick)
632                 return resource->at(ticks);
633         return resource->at(tick);
634 }
635
636 //////////////////////////////////////////////////////////////////////////
637 //
638 void Fleet::resetResources()
639 {
640         m_Resources.clear() ;   
641 }
642
643 //////////////////////////////////////////////////////////////////////////
644 //
645 void Fleet::printFleet()
646 {
647         for (UnitList::iterator i = s_Units.begin(); i != s_Units.end(); ++i)
648         {
649                 for (int tick = 0; tick < 5 ;++tick)
650                 {
651                         int num = fleet(i->first, tick);
652
653                         if (num <= 0)
654                                 break;
655                         cerr << num << " " << i->first << " during tick: " << tick << endl;
656                 }
657         }
658 }
659
660 //////////////////////////////////////////////////////////////////////////
661 //
662 void Fleet::blockFleet(std::string unittype, int number, int tick)
663 {
664         if (m_BlockedFleet[unittype].size() >= 1)
665         {
666                 m_BlockedFleet[unittype][0] += number;
667                 if (m_BlockedFleet[unittype].size() > 1)
668                         m_BlockedFleet[unittype][1] += number;
669                 else
670                         m_BlockedFleet[unittype].push_back(m_BlockedFleet[unittype][0]);
671         }
672         else
673         {
674                 m_BlockedFleet[unittype].push_back(number);
675                 m_BlockedFleet[unittype].push_back(number);
676         }
677 }
678
679 //////////////////////////////////////////////////////////////////////////
680 //
681 void Fleet::distributeCappedRoids(std::vector<Fleet*> fleets, int tick)
682 {
683         for (ResourceList::iterator i = m_Resources.begin(); i != m_Resources.end(); ++i)
684         {
685                 string res = i->first;
686
687
688                 cerr << "Distributing type: " << res << endl;
689                 for (vector<int>::iterator j = i->second.begin(); j != i->second.end(); ++j)
690                         cout << (*j) << endl;
691
692                 if (m_Resources[res].size() < 2)
693                         continue;
694                 if (m_Resources[res][1] == 0)
695                         continue;
696
697
698                 int totcapped = resource(res,1) - resource(res, 0);
699
700
701                 cerr << "Distributing type: " << res << " with a total gain of " << totcapped << " roids" << endl;
702
703                 cerr << "Total number of roids before: " << resource(res, 0)  << " and after : " << resource(res, 1) << endl;
704
705                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
706                 {
707                         unsigned fl1 = (*j)->score(tick - 1);
708                         float part = float(fl1) / score(0) ;
709                         int lost =  totcapped * part;
710
711                         cerr << (*j)->name() << " gaining " << lost << " " << res  << " since it's " << part * 100 << "% of the whole score, and it had : " << fl1 << " score last tick.. compared to fleet total of: " << score(0) <<  endl;
712
713                         //(*j)->setResource(res, (*j)->resource(res,tick-1) + lost, tick);
714                         (*j)->addResource(res,lost, tick);
715                 }
716         }
717 }
718
719 //////////////////////////////////////////////////////////////////////////
720 //
721 void Fleet::addFleet(std::map<string, int> units, int tick)
722 {
723         for (map<string, int>::iterator i = units.begin(); i != units.end(); ++i)
724                 addFleet(i->first, i->second, tick);
725 }
726
727 //////////////////////////////////////////////////////////////////////////
728 //
729 int Fleet::stays() const
730 {
731         return m_iStays;
732 }
733
734 //////////////////////////////////////////////////////////////////////////
735 //
736 void Fleet::setStays(int ticks)
737 {
738         m_iStays = ticks;
739 }
740
741 //////////////////////////////////////////////////////////////////////////
742 //
743 void Fleet::calculateLostStealships(string unittype, std::map<std::string, int> stolen, int tick)
744 {
745         int stealscore = 0;
746         for (map<string, int>::iterator i = stolen.begin(); i != stolen.end(); ++i)
747         {
748                 stealscore += stolen[i->first] * (s_Units[i->first].totRes() / 10.0);   
749         }
750
751         int lost = stealscore / (s_Units[unittype].totRes() / 10.0);
752
753         cerr << "Lost " << lost << " " << unittype << " due to stealing ships worth: " << stealscore << endl; 
754         killFleet(unittype, lost, tick);
755 }
756
757 //////////////////////////////////////////////////////////////////////////
758 //
759 void Fleet::distributeStolenShips(std::map<std::string, std::map<std::string, int> > stolen, std::vector<Fleet*> fleets, int tick)
760 {
761         for(map<string, map<string, int> >::iterator i = stolen.begin(); i != stolen.end(); ++i)
762         {
763                 int totalstealers = 0;
764                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
765                         totalstealers += (*j)->fleet(i->first, tick - 1);
766
767                 for (map<string, int>::iterator j = i->second.begin(); j != i->second.end(); ++j)
768                 {
769                         for (vector<Fleet*>::iterator k = fleets.begin(); k != fleets.end(); ++k)
770                         {
771                                 int stolen = float ((*k)->fleet(i->first, tick - 1)) / totalstealers * j->second;
772                                 (*k)->addFleet(j->first, stolen, tick);
773                         }
774                 }
775         }
776 }
777
778 //////////////////////////////////////////////////////////////////////////
779 //
780 void Fleet::calculateSalvage()
781 {
782         for (FleetList::iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
783         {
784
785                 map<string, int> res = s_Units[i->first].resources();
786
787                 if (i->second.size() > 0)
788                         cerr << endl << i->first << ": ";
789
790                 int tick = 0;
791                 for (vector<int>::iterator j = i->second.begin(); j != i->second.end(); ++j, ++tick)
792                 {
793                         int lostunits = fleet(i->first, tick - 1) - fleet(i->first, tick);
794
795                         if (lostunits <= 0)
796                                 continue;
797                         cerr << "(" << tick << ":" << fleet(i->first, tick) << ") ";
798                         for (map<string, int>::iterator k = res.begin(); k != res.end(); ++k)
799                                 addResource(k->first, lostunits * k->second * 0.25, tick);
800                 }
801         }
802 }
803
804 //////////////////////////////////////////////////////////////////////////
805 //
806 void Fleet::resetTicks()
807 {
808         for (FleetList::iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
809         {
810                 if ( i->second.size() < 2)
811                         continue;
812
813                 int temp = i->second[0];
814                 i->second.clear();
815
816                 if (temp > 0)
817                         i->second.push_back(temp);
818         }
819         resetResources();
820 }
821
822 //////////////////////////////////////////////////////////////////////////
823 //
824 int Fleet::freePodGuns(int tick) 
825 {
826         int guns = 0;
827         for (FleetList::const_iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
828         {
829                 if (s_Units[i->first].type() == "Pod")
830                 {
831                         guns += freeFleet(i->first, tick) * s_Units[i->first].guns();
832                 }
833         }
834         guns -= usedPodGuns(tick);
835         return guns;
836 }
837
838 //////////////////////////////////////////////////////////////////////////
839 //
840 int Fleet::usedPodGuns(int tick) const
841 {
842         int ticks = m_UsedPodGuns.size();
843
844         if (ticks == 0)
845                 return 0;
846
847         if (tick < 0)
848                 return m_UsedPodGuns[0];
849
850         --ticks;
851
852         if (ticks < tick)
853                 return m_UsedPodGuns[ticks];
854
855         return m_UsedPodGuns[tick];
856
857 }
858
859 //////////////////////////////////////////////////////////////////////////
860 //
861 void Fleet::usePodGuns(int tick, int guns)
862 {
863         int ticks = m_UsedPodGuns.size();
864
865         for (int i = ticks; i <= tick; ++i)
866         {
867                 m_UsedPodGuns.push_back(0);
868         }
869         m_UsedPodGuns[tick] += guns;
870 }