]> ruin.nu Git - hbs.git/blob - bs/fleet.cpp
4fc5be57a4fe8376e0552550832f856274fb3905
[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 //
148 const map<string, vector<int> >& Fleet::Races()
149 {
150         return s_Races;
151 }
152
153 //////////////////////////////////////////////////////////////////////////
154 //
155 const UnitList& Fleet::Units()
156 {
157         return s_Units;
158 }
159
160 //////////////////////////////////////////////////////////////////////////
161 //
162 vector<int> Fleet::RacesAllowed() const
163 {
164         return s_Races[m_sRace];
165 }
166
167 //////////////////////////////////////////////////////////////////////////
168 //
169 unsigned Fleet::score(int tick = 0) const
170 {
171         unsigned tot_score = 0;
172
173         for (FleetList::const_iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
174         {
175                 int ticks =     i->second.size();
176                 if (ticks == 0)
177                         continue;
178                 --ticks;
179                 if ( ticks < tick)
180                         tot_score += i->second[ticks] * s_Units[i->first].totRes() / 10;
181                 else
182                         tot_score += i->second[tick] * s_Units[i->first].totRes() / 10;
183         }
184
185         return tot_score;
186 }
187
188 //////////////////////////////////////////////////////////////////////////
189 //
190 void Fleet::setFleet(string unittype, int number, int tick = 0)
191 {
192         int earlier = 0;
193         int ticks = m_Fleet[unittype].size();
194
195         if (ticks != 0)
196                 earlier = m_Fleet[unittype][ticks - 1];
197
198         for (int i = ticks; i <= tick; ++i)
199         {
200                 m_Fleet[unittype].push_back(earlier);
201         }
202         m_Fleet[unittype][tick] = number;
203 }
204
205 //////////////////////////////////////////////////////////////////////////
206 //
207 void Fleet::addFleet(std::string unittype, int number, int tick = 0)
208 {
209         int earlier = 0;
210         int ticks = m_Fleet[unittype].size();
211
212         if (ticks != 0)
213                 earlier = m_Fleet[unittype][ticks - 1];
214
215         for (int i = ticks; i <= tick; ++i)
216         {
217                 m_Fleet[unittype].push_back(earlier);
218         }
219         m_Fleet[unittype][tick] += number;
220 }
221
222 //////////////////////////////////////////////////////////////////////////
223 //
224 int      Fleet::fleet(string unittype, int tick = 0)
225 {
226
227         int ticks = m_Fleet[unittype].size();
228         if (ticks == 0)
229                 return 0;
230
231         if (tick < 0)
232                 return m_Fleet[unittype][0];
233
234         --ticks;
235
236         if (ticks < tick)
237                 return m_Fleet[unittype][ticks];
238
239         return m_Fleet[unittype][tick];
240 }
241
242 //////////////////////////////////////////////////////////////////////////
243 //
244 int Fleet::blockedFleet(std::string unittype, int tick = 0)
245 {
246         int ticks = m_BlockedFleet[unittype].size();
247         if (ticks == 0)
248                 return 0;
249
250         --ticks;
251
252         if (ticks < tick)
253                 return 0;
254
255         return m_BlockedFleet[unittype][tick];
256 }
257
258 //////////////////////////////////////////////////////////////////////////
259 //
260 void Fleet::setBlockedFleet(std::string unittype, int number, int tick = 0)
261 {
262         int ticks = m_BlockedFleet[unittype].size();
263
264         for (int i = ticks; i <= tick; ++i)
265         {
266                 m_BlockedFleet[unittype].push_back(0);
267         }
268         m_BlockedFleet[unittype][tick] = number;
269
270         cerr << "This fleet got " << m_BlockedFleet[unittype][tick] << " blocked units tick: " << tick << endl;
271
272 }
273
274 //////////////////////////////////////////////////////////////////////////
275 //
276 void Fleet::addToThis(std::vector<Fleet*> fleets, int tick = 0)
277 {
278         for (UnitList::iterator i = s_Units.begin();  i != s_Units.end(); ++i)
279         {
280                 if (m_Fleet[i->first].size() == 0)
281                         m_Fleet[i->first].push_back(0);
282
283                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
284                 {
285                         int num = (*j)->fleet(i->first, tick);
286                         m_Fleet[i->first][0] += num;
287                         if (num > 0)
288                                 cerr << (*j)->name() <<  " adding " << num << " units of type " << i->first << endl;
289                 }
290         }
291 }
292
293 //////////////////////////////////////////////////////////////////////////
294 //
295 void Fleet::distributeLossesGains(std::vector<Fleet*> fleets, int tick = 0)
296 {
297         for (UnitList::iterator i = s_Units.begin(); i != s_Units.end(); ++i)
298         {
299                 string unittype = i->first;
300
301
302                 if (m_Fleet[unittype].size() < 1)
303                         continue;
304                 if (m_Fleet[unittype][0] == 0)
305                         continue;
306
307
308                 int totallost = fleet(unittype,1) - fleet(unittype, 0);
309
310
311                 cerr << "Distributing type: " << unittype << " with a total loss of " << totallost << " units" << endl;
312
313                 cerr << "Total number of units before: " << fleet(unittype, 0)  << " and after : " << fleet(unittype, 1) << endl;
314
315                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
316                 {
317                         int fl1 = (*j)->fleet(unittype, tick - 1);
318                         float part = float(fl1) / fleet(unittype, 0) ;
319                         int lost =  totallost * part;
320                         (*j)->setFleet(unittype, (*j)->fleet(unittype, tick - 1) + lost, tick);
321
322                         cerr << (*j)->name() << " gaining " << lost << " " << unittype  << " since it's " << part * 100 << "% of the whole fleet, and it had : " << fl1 << " units last tick.." <<  endl;
323
324                         lost = part * blockedFleet(unittype, 0);
325
326                         cerr << (*j)->name() << " got " << lost << " blocked " << unittype  << ", the total number of blocked ships was: " << blockedFleet(unittype, 0) << endl; 
327
328                         (*j)->setBlockedFleet(unittype, lost, tick);
329                 }
330         }
331 }
332
333 //////////////////////////////////////////////////////////////////////////
334 //
335 std::vector<Fleet*> Fleet::calculateSide(std::vector<Fleet*> fleets, int stays = 0, int tick = 0)
336 {
337         vector<Fleet*> fl;
338         for (vector<Fleet*>::iterator i = fleets.begin(); i != fleets.end(); ++i)
339         {
340                 if ((*i)->stays() == 0)
341                         continue;
342                 else if (( tick - (*i)->ETA()) >= 0 && (tick - (*i)->ETA()) < (*i)->stays())
343                 {
344                         fl.push_back((*i));
345                         cerr << "Using fleet " << (*i)->name() << " for tick " << tick << endl;
346                 }
347                 else if ((*i)->stays() < 0)
348                         fl.push_back((*i));
349         }
350         return fl;
351 }
352
353 //////////////////////////////////////////////////////////////////////////
354 //
355 int Fleet::freeFleet(std:: string unittype, int tick = 0)
356 {
357         int bticks = m_BlockedFleet[unittype].size();
358
359         --bticks;
360
361         if (bticks < tick)
362                 return fleet(unittype, tick);
363
364
365         int free = fleet(unittype,tick) - m_BlockedFleet[unittype][tick];
366         if (free < 0)
367                 return 0;
368         return free;
369 }
370
371
372 //////////////////////////////////////////////////////////////////////////
373 //
374 void Fleet::takeShoot(std::string unittype, int number, std::map<std::string, int>& hitunits)
375 {
376
377         float guns = s_Units[unittype].guns() * number;
378
379
380         if (guns == 0)
381                 return;
382
383         cerr << number << " " << unittype << ": with " << guns << " guns\n";
384
385         float gunsleft = guns;
386         for (int count = 0; count < 3; ++count)//vector<string>::iterator i = s_Units[unittype].target().begin(); i != s_Units[unittype].target().end(); ++i)
387         {
388                 string ta = s_Units[unittype].target(count);
389                 cerr << "Shooting at target class: " << ta << endl;
390                 while (gunsleft > 0)
391                 {
392
393                         map<string, int*> targets;
394
395                         for (UnitList::iterator j = s_Units.begin(); j != s_Units.end(); ++j)
396                         {
397                                 if (m_Fleet[j->first].size() == 0)
398                                         continue;
399
400
401                                 if (m_Fleet[j->first].size() == 1 )
402                                         m_Fleet[j->first].push_back(m_Fleet[j->first][0]);
403
404                                 //cerr << "Target is class: " << j->second.type() << endl;
405
406                                 if (m_Fleet[j->first][1] > 0  && ( ta == j->second.unitClass() || ta == "All"))
407                                 {
408
409                                         //      cerr << "Looking at target: " << j->first << endl;
410                                         targets[j->first] = &m_Fleet[j->first][1];
411                                 }
412                         }
413
414                         if (targets.size() == 0)
415                                 break;
416
417                         int total = 0;
418                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
419                                 total += (*j->second);
420
421                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
422                         {
423                                 float maxguns = float((*j->second))/total * guns;
424                                 //cerr << "Now shooting at target: " << j->first << endl;
425
426                                 if (m_Armor[j->first] <= 0 || m_Armor[j->first] > s_Units[j->first].armor())
427                                         m_Armor[j->first] = s_Units[j->first].armor();
428                                 double k = maxguns;
429
430                                 //cerr << "Targets agility: " << s_Units[j->first].agility() << endl;
431                                 //cerr << "Weaponspeed: " << s_Units[unittype].weaponSpeed() << endl;
432                                 while (k > 0)   
433                                 {
434
435                                         if (*(j->second) <= 0)
436                                                 break;
437
438                                         int wpsp = s_Units[unittype].weaponSpeed();
439                                         int agil = s_Units[j->first].agility();
440
441                                         k -= float(100)/(25 + wpsp - agil);
442                                         //cout << "Used " << blaha << " guns to hit with one shot.\n";
443                                         //cout << "WPSP: " << wpsp << "\nAgil: " << agil << endl;
444
445                                         m_Armor[j->first] -= s_Units[unittype].power();
446                                         if (m_Armor[j->first] <= 0)
447                                         {
448                                                 m_Armor[j->first] = s_Units[j->first].armor();
449                                                 (*j->second)--;
450                                                 hitunits[j->first]++;
451
452                                                 //There is a chance that we're hitting a blocked ship.
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                                 cerr << hitunits[j->first] << " units of type: " << j->first << "killed\n";
470                                 if (k <= 0)
471                                         gunsleft -= maxguns;
472                                 else
473                                         gunsleft -= maxguns - k;
474                         }
475                 }
476         }
477 }
478
479 //////////////////////////////////////////////////////////////////////////
480 //
481 void Fleet::takeEMP(std::string unittype, int number)
482 {
483         int guns = s_Units[unittype].guns() * number;
484         if (guns == 0)
485                 return;
486
487         cerr << unittype << ": with " << guns << " guns\n";
488
489         float gunsleft = guns;
490         for (int count = 0; count < 3; ++count)//vector<string>::iterator i = s_Units[unittype].target().begin(); i != s_Units[unittype].target().end(); ++i)
491         {
492                 string ta = s_Units[unittype].target(count);
493                 cerr << "Shooting at target class: " << ta << endl;
494                 while (gunsleft > 0)
495                 {
496
497                         map<string, int*> targets;
498
499                         for (UnitList::iterator j = s_Units.begin(); j != s_Units.end(); ++j)
500                         {
501                                 if (j->second.type() == "PDS")
502                                         continue;
503
504                                 if (freeFleet(j->first, 1) <= 0)
505                                         continue;
506
507                                 if (m_Fleet[j->first].size() == 0)
508                                         continue;
509
510                                 if (m_Fleet[j->first].size() == 1)
511                                         m_Fleet[j->first].push_back(m_Fleet[j->first][0]);
512
513                                 //cerr << "Target is class: " << j->second.type() << endl;
514
515                                 if (m_Fleet[j->first][1] > 0  && ( ta == j->second.unitClass() || ta == "All"))
516                                 {
517
518                                         //      cerr << "Looking at target: " << j->first << endl;
519                                         targets[j->first] = &m_Fleet[j->first][1];
520                                 }
521
522                         }
523
524                         if (targets.size() == 0)
525                                 break;
526
527                         int total = 0;
528                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
529                                 total += (*j->second);
530
531                         for (map<string, int*>::iterator j = targets.begin(); j != targets.end(); ++j)
532                         {
533                                 float maxguns = float((*j->second))/total * guns;
534                                 cerr << "Now shooting at target: " << j->first << endl;
535
536                                 double k = maxguns;
537
538                                 int hits = 0;
539
540                                 while (k > 0)   
541                                 {
542
543                                         if (*(j->second) <= blockedFleet(j->first, 1))
544                                                 break;
545
546                                         int eres = s_Units[j->first].EMP();
547
548                                         k -= float(100)/(100-eres);
549                                         hits++;
550                                         blockFleet(j->first, 1);
551                                 }
552
553                                 cerr << hits << " units of type: " << j->first << " blocked\n";
554                                 if (k <= 0)
555                                         gunsleft -= maxguns;
556                                 else
557                                         gunsleft -= maxguns - k;
558                         }
559                 }
560         }
561 }
562
563 //////////////////////////////////////////////////////////////////////////
564 //
565 void Fleet::killFleet(std::string unittype, int number, int tick = 0)
566 {
567         int earlier = 0;
568         int ticks = m_Fleet[unittype].size();
569
570         if (ticks != 0)
571                 earlier = m_Fleet[unittype][ticks - 1];
572
573         for (int i = ticks; i <= tick; ++i)
574         {
575                 m_Fleet[unittype].push_back(earlier);
576         }
577         m_Fleet[unittype][tick] -= number;
578 }
579
580 //////////////////////////////////////////////////////////////////////////
581 //
582 void Fleet::setResource(std::string type, int number, int tick = 0)
583 {
584
585         int ticks = m_Resources[type].size();
586         for (int i = ticks; i <= tick; ++i)
587                 m_Resources[type].push_back(number);
588         m_Resources[type][tick] = number;
589 }
590
591 //////////////////////////////////////////////////////////////////////////
592 //
593 void Fleet::addResource(std::string type, int number, int tick = 0)
594 {
595
596         int ticks = m_Resources[type].size();
597         int latest = resource(type, tick - 1);
598
599         for (int i = ticks; i <= tick; ++i)
600                 m_Resources[type].push_back(latest);
601         m_Resources[type][tick] += number;
602 }
603
604 //////////////////////////////////////////////////////////////////////////
605 //
606 int Fleet::resource(std::string type, int tick = 0) const
607 {
608         if (tick < 0)
609                 return 0;
610
611         vector<int>const* resource = 0;
612         for (ResourceList::const_iterator i = m_Resources.begin(); i != m_Resources.end(); ++i)
613         {
614                 if (i->first == type)
615                 {
616                         resource = &i->second;
617                         break;
618                 }
619         }
620         if (resource == 0)
621                 return 0;
622
623         int ticks = resource->size();
624
625         if( ticks == 0)
626                 return 0;
627
628         --ticks;
629
630         if (ticks < tick)
631                 return resource->at(ticks);
632         return resource->at(tick);
633 }
634
635 //////////////////////////////////////////////////////////////////////////
636 //
637 void Fleet::resetResources()
638 {
639         m_Resources.clear() ;   
640 }
641
642 //////////////////////////////////////////////////////////////////////////
643 //
644 void Fleet::printFleet()
645 {
646         for (UnitList::iterator i = s_Units.begin(); i != s_Units.end(); ++i)
647         {
648                 for (int tick = 0; tick < 5 ;++tick)
649                 {
650                         int num = fleet(i->first, tick);
651
652                         if (num <= 0)
653                                 break;
654                         cerr << num << " " << i->first << " during tick: " << tick << endl;
655                 }
656         }
657 }
658
659 //////////////////////////////////////////////////////////////////////////
660 //
661 void Fleet::blockFleet(std::string unittype, int number, int tick = 0)
662 {
663         if (m_BlockedFleet[unittype].size() >= 1)
664         {
665                 m_BlockedFleet[unittype][0] += number;
666                 if (m_BlockedFleet[unittype].size() > 1)
667                         m_BlockedFleet[unittype][1] += number;
668                 else
669                         m_BlockedFleet[unittype].push_back(m_BlockedFleet[unittype][0]);
670         }
671         else
672         {
673                 m_BlockedFleet[unittype].push_back(number);
674                 m_BlockedFleet[unittype].push_back(number);
675         }
676 }
677
678 //////////////////////////////////////////////////////////////////////////
679 //
680 void Fleet::distributeCappedRoids(std::vector<Fleet*> fleets, int tick = 0)
681 {
682         for (ResourceList::iterator i = m_Resources.begin(); i != m_Resources.end(); ++i)
683         {
684                 string res = i->first;
685
686
687                 cerr << "Distributing type: " << res << endl;
688                 for (vector<int>::iterator j = i->second.begin(); j != i->second.end(); ++j)
689                         cout << (*j) << endl;
690
691                 if (m_Resources[res].size() < 2)
692                         continue;
693                 if (m_Resources[res][1] == 0)
694                         continue;
695
696
697                 int totcapped = resource(res,1) - resource(res, 0);
698
699
700                 cerr << "Distributing type: " << res << " with a total gain of " << totcapped << " roids" << endl;
701
702                 cerr << "Total number of roids before: " << resource(res, 0)  << " and after : " << resource(res, 1) << endl;
703
704                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
705                 {
706                         unsigned fl1 = (*j)->score(tick - 1);
707                         float part = float(fl1) / score(0) ;
708                         int lost =  totcapped * part;
709
710                         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;
711
712                         //(*j)->setResource(res, (*j)->resource(res,tick-1) + lost, tick);
713                         (*j)->addResource(res,lost, tick);
714                 }
715         }
716 }
717
718 //////////////////////////////////////////////////////////////////////////
719 //
720 void Fleet::addFleet(std::map<string, int> units, int tick = 0)
721 {
722         for (map<string, int>::iterator i = units.begin(); i != units.end(); ++i)
723                 addFleet(i->first, i->second, tick);
724 }
725
726 //////////////////////////////////////////////////////////////////////////
727 //
728 int Fleet::stays() const
729 {
730         return m_iStays;
731 }
732
733 //////////////////////////////////////////////////////////////////////////
734 //
735 void Fleet::setStays(int ticks)
736 {
737         m_iStays = ticks;
738 }
739
740 //////////////////////////////////////////////////////////////////////////
741 //
742 void Fleet::calculateLostStealships(string unittype, std::map<std::string, int> stolen, int tick = 1)
743 {
744         int stealscore = 0;
745         for (map<string, int>::iterator i = stolen.begin(); i != stolen.end(); ++i)
746         {
747                 stealscore += stolen[i->first] * (s_Units[i->first].totRes() / 10.0);   
748         }
749
750         int lost = stealscore / (s_Units[unittype].totRes() / 10.0);
751
752         cerr << "Lost " << lost << " " << unittype << " due to stealing ships worth: " << stealscore << endl; 
753         killFleet(unittype, lost, tick);
754 }
755
756 //////////////////////////////////////////////////////////////////////////
757 //
758 void Fleet::distributeStolenShips(std::map<std::string, std::map<std::string, int> > stolen, std::vector<Fleet*> fleets, int tick = 0)
759 {
760         for(map<string, map<string, int> >::iterator i = stolen.begin(); i != stolen.end(); ++i)
761         {
762                 int totalstealers = 0;
763                 for (vector<Fleet*>::iterator j = fleets.begin(); j != fleets.end(); ++j)
764                         totalstealers += (*j)->fleet(i->first, tick - 1);
765
766                 for (map<string, int>::iterator j = i->second.begin(); j != i->second.end(); ++j)
767                 {
768                         for (vector<Fleet*>::iterator k = fleets.begin(); k != fleets.end(); ++k)
769                         {
770                                 int stolen = float ((*k)->fleet(i->first, tick - 1)) / totalstealers * j->second;
771                                 (*k)->addFleet(j->first, stolen, tick);
772                         }
773                 }
774         }
775 }
776
777 //////////////////////////////////////////////////////////////////////////
778 //
779 void Fleet::calculateSalvage()
780 {
781         for (FleetList::iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
782         {
783
784                 map<string, int> res = s_Units[i->first].resources();
785
786                 if (i->second.size() > 0)
787                         cerr << endl << i->first << ": ";
788
789                 int tick = 0;
790                 for (vector<int>::iterator j = i->second.begin(); j != i->second.end(); ++j, ++tick)
791                 {
792                         int lostunits = fleet(i->first, tick - 1) - fleet(i->first, tick);
793
794                         if (lostunits <= 0)
795                                 continue;
796                         cerr << "(" << tick << ":" << fleet(i->first, tick) << ") ";
797                         for (map<string, int>::iterator k = res.begin(); k != res.end(); ++k)
798                                 addResource(k->first, lostunits * k->second * 0.25, tick);
799                 }
800         }
801 }
802
803 //////////////////////////////////////////////////////////////////////////
804 //
805 void Fleet::resetTicks()
806 {
807         for (FleetList::iterator i = m_Fleet.begin(); i != m_Fleet.end(); ++i)
808         {
809                 if ( i->second.size() < 2)
810                         continue;
811
812                 int temp = i->second[0];
813                 i->second.clear();
814
815                 if (temp > 0)
816                         i->second.push_back(temp);
817         }
818         resetResources();
819 }