~ubuntu-branches/ubuntu/maverick/lordsawar/maverick

« back to all changes in this revision

Viewing changes to src/armyset.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2010-04-10 09:29:33 UTC
  • mfrom: (1.1.9 upstream) (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100410092933-23uq4dxig30kmtcw
Tags: 0.1.8-1
* New upstream release.
* Add misc:Depends for -data package.
* Bump Standards Version to 3.8.4. (No changes needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "File.h"
27
27
#include "GraphicsCache.h"
28
28
#include "shield.h"
 
29
#include "gui/image-helpers.h"
 
30
#include "armysetlist.h"
 
31
#include "armyprodbase.h"
29
32
 
30
33
std::string Armyset::d_tag = "armyset";
 
34
std::string Armyset::file_extension = ARMYSET_EXT;
31
35
using namespace std;
32
36
 
33
37
#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
35
39
 
36
40
#define DEFAULT_ARMY_TILE_SIZE 40
37
41
Armyset::Armyset(guint32 id, std::string name)
38
 
        : d_id(id), d_name(name), d_dir(""), d_tilesize(DEFAULT_ARMY_TILE_SIZE),
39
 
        d_ship(0), d_shipmask(0), d_standard(0), d_standard_mask(0),
40
 
        private_collection(true)
 
42
        : d_id(id), d_name(name), d_copyright(""), d_license(""), d_subdir(""), 
 
43
        d_tilesize(DEFAULT_ARMY_TILE_SIZE), d_ship(0), d_shipmask(0), 
 
44
        d_standard(0), d_standard_mask(0), d_bag(0)
41
45
{
 
46
  d_bag_name = "";
 
47
  d_stackship_name = "";
 
48
  d_standard_name = "";
42
49
}
43
50
 
44
 
Armyset::Armyset(XML_Helper *helper, bool from_private_collection)
45
 
    : d_id(0), d_name(""), d_dir(""), d_tilesize(DEFAULT_ARMY_TILE_SIZE),
46
 
        d_ship(0), d_shipmask(0), d_standard(0), d_standard_mask(0)
 
51
Armyset::Armyset(XML_Helper *helper, std::string directory)
 
52
    : d_id(0), d_name(""), d_copyright(""), d_license(""), d_subdir(""), 
 
53
    d_tilesize(DEFAULT_ARMY_TILE_SIZE), d_ship(0), d_shipmask(0), 
 
54
    d_standard(0), d_standard_mask(0), d_bag(0)
47
55
{
48
 
  private_collection = from_private_collection;
 
56
  d_bag_name = "";
 
57
  d_stackship_name = "";
 
58
  d_standard_name = "";
 
59
  setDirectory(directory);
49
60
  helper->getData(d_id, "id");
50
61
  helper->getData(d_name, "name");
 
62
  helper->getData(d_copyright, "copyright");
 
63
  helper->getData(d_license, "license");
51
64
  helper->getData(d_tilesize, "tilesize");
52
65
  helper->getData(d_stackship_name, "stackship");
53
66
  helper->getData(d_standard_name, "plantedstandard");
 
67
  helper->getData(d_bag_name, "bag");
54
68
  helper->registerTag(ArmyProto::d_tag, 
55
69
                      sigc::mem_fun((*this), &Armyset::loadArmyProto));
56
70
}
57
71
 
58
72
Armyset::~Armyset()
59
73
{
 
74
  uninstantiateImages();
60
75
  for (iterator it = begin(); it != end(); it++)
61
 
      delete *it;
 
76
    delete *it;
62
77
}
63
78
 
64
79
bool Armyset::loadArmyProto(string tag, XML_Helper* helper)
82
97
 
83
98
    retval &= helper->saveData("id", d_id);
84
99
    retval &= helper->saveData("name", d_name);
 
100
    retval &= helper->saveData("copyright", d_copyright);
 
101
    retval &= helper->saveData("license", d_license);
85
102
    retval &= helper->saveData("tilesize", d_tilesize);
86
103
    retval &= helper->saveData("stackship", d_stackship_name);
87
104
    retval &= helper->saveData("plantedstandard", d_standard_name);
 
105
    retval &= helper->saveData("bag", d_bag_name);
88
106
 
89
107
    for (const_iterator it = begin(); it != end(); it++)
90
108
      (*it)->save(helper);
94
112
    return retval;
95
113
}
96
114
 
97
 
ArmyProto * Armyset::lookupArmyByType(guint32 army_type_id)
98
 
{
99
 
  for (iterator it = begin(); it != end(); it++)
 
115
ArmyProto * Armyset::lookupSimilarArmy(ArmyProto *army) const
 
116
{
 
117
  for (const_iterator it = begin(); it != end(); it++)
 
118
    {
 
119
      if ((*it)->getGender() == army->getGender() &&
 
120
          (*it)->getStrength() == army->getStrength() &&
 
121
          (*it)->getProduction() == army->getProduction() &&
 
122
          (*it)->getArmyBonus() == army->getArmyBonus() &&
 
123
          (*it)->getMoveBonus() == army->getMoveBonus() &&
 
124
          (*it)->getMaxMoves() == army->getMaxMoves() &&
 
125
          (*it)->getAwardable() == army->getAwardable() &&
 
126
          (*it)->getDefendsRuins() == army->getDefendsRuins())
 
127
        return *it;
 
128
    }
 
129
  for (const_iterator it = begin(); it != end(); it++)
 
130
    {
 
131
      if ((*it)->getGender() == army->getGender() &&
 
132
          (*it)->getStrength() == army->getStrength() &&
 
133
          (*it)->getProduction() == army->getProduction() &&
 
134
          (*it)->getArmyBonus() == army->getArmyBonus() &&
 
135
          (*it)->getMoveBonus() == army->getMoveBonus() &&
 
136
          (*it)->getMaxMoves() == army->getMaxMoves())
 
137
        return *it;
 
138
    }
 
139
  for (const_iterator it = begin(); it != end(); it++)
 
140
    {
 
141
      if ((*it)->getGender() == army->getGender() &&
 
142
          (*it)->getStrength() == army->getStrength() &&
 
143
          (*it)->getProduction() == army->getProduction() &&
 
144
          (*it)->getMaxMoves() == army->getMaxMoves())
 
145
        return *it;
 
146
    }
 
147
  return NULL;
 
148
}
 
149
 
 
150
ArmyProto * Armyset::lookupArmyByGender(Hero::Gender gender) const
 
151
{
 
152
  for (const_iterator it = begin(); it != end(); it++)
 
153
    {
 
154
      if ((*it)->getGender() == gender)
 
155
        return *it;
 
156
    }
 
157
  return  NULL;
 
158
}
 
159
ArmyProto * Armyset::lookupArmyByStrengthAndTurns(guint32 str, guint32 turns) const
 
160
{
 
161
  for (const_iterator it = begin(); it != end(); it++)
 
162
    {
 
163
      if (str && turns)
 
164
        {
 
165
          if ((*it)->getStrength() == str && (*it)->getProduction() == turns)
 
166
            return *it;
 
167
        }
 
168
      else if (str)
 
169
        {
 
170
          if ((*it)->getStrength() == str)
 
171
            return *it;
 
172
        }
 
173
      else if (turns)
 
174
        {
 
175
          if ((*it)->getProduction() == turns)
 
176
            return *it;
 
177
        }
 
178
    }
 
179
  return NULL;
 
180
}
 
181
 
 
182
ArmyProto * Armyset::lookupArmyByName(std::string name) const
 
183
{
 
184
  for (const_iterator it = begin(); it != end(); it++)
 
185
    {
 
186
      if ((*it)->getName() == name)
 
187
        return *it;
 
188
    }
 
189
  return NULL;
 
190
}
 
191
        
 
192
ArmyProto * Armyset::lookupArmyByType(guint32 army_type_id) const
 
193
{
 
194
  for (const_iterator it = begin(); it != end(); it++)
100
195
    {
101
196
      if ((*it)->getTypeId() == army_type_id)
102
197
        return *it;
132
227
  bool found = false;
133
228
  for (iterator it = begin(); it != end(); it++)
134
229
    {
135
 
      if ((*it)->getProductionCost() > 0 )
 
230
      if ((*it)->getNewProductionCost() > 0 )
136
231
        {
137
232
          found = true;
138
233
          break;
181
276
  return true;
182
277
}
183
278
 
 
279
bool Armyset::validateBag()
 
280
{
 
281
  if (getBagImageName() == "")
 
282
    return false;
 
283
  return true;
 
284
}
 
285
 
184
286
bool Armyset::validateStandard()
185
287
{
186
288
  if (getStandardImageName() == "")
252
354
  valid = validateStandard();
253
355
  if (!valid)
254
356
    return false;
 
357
  //is the bag set?
 
358
  valid = validateBag();
 
359
  if (!valid)
 
360
    return false;
255
361
  //is there an image set for each army unit?
256
362
  valid = validateArmyUnitImages();
257
363
  if (!valid)
266
372
class ArmysetLoader
267
373
{
268
374
public:
269
 
    ArmysetLoader(std::string name, bool p) 
 
375
    ArmysetLoader(std::string filename)
270
376
      {
271
377
        armyset = NULL;
272
 
        private_collection = p;
273
 
        std::string filename = "";
274
 
        if (private_collection == false)
275
 
          filename = File::getArmyset(name);
276
 
        else
277
 
          filename = File::getUserArmyset(name);
 
378
        dir = File::get_dirname(filename);
 
379
        if (File::nameEndsWith(filename, Armyset::file_extension) == false)
 
380
          filename += Armyset::file_extension;
278
381
        XML_Helper helper(filename, ios::in, false);
279
382
        helper.registerTag(Armyset::d_tag, sigc::mem_fun((*this), &ArmysetLoader::load));
280
383
        if (!helper.parse())
281
384
          {
282
385
            std::cerr << "Error, while loading an armyset. Armyset Name: ";
283
 
            std::cerr <<name <<std::endl <<std::flush;
 
386
            std::cerr <<File::get_basename(File::get_dirname(filename)) <<std::endl <<std::flush;
 
387
            if (armyset != NULL)
 
388
              delete armyset;
 
389
            armyset = NULL;
284
390
          }
285
391
      };
286
392
    bool load(std::string tag, XML_Helper* helper)
287
393
      {
288
394
        if (tag == Armyset::d_tag)
289
395
          {
290
 
            armyset = new Armyset(helper, private_collection);
 
396
            armyset = new Armyset(helper, dir);
291
397
            return true;
292
398
          }
293
399
        return false;
294
400
      };
295
 
    bool private_collection;
 
401
    std::string dir;
296
402
    Armyset *armyset;
297
403
};
298
 
Armyset *Armyset::create(std::string filename, bool private_collection)
 
404
Armyset *Armyset::create(std::string filename)
299
405
{
300
 
  ArmysetLoader d(filename, private_collection);
 
406
  ArmysetLoader d(filename);
301
407
  return d.armyset;
302
408
}
303
409
void Armyset::getFilenames(std::list<std::string> &files)
312
418
        }
313
419
    }
314
420
}
 
421
        
 
422
void Armyset::instantiateImages()
 
423
{
 
424
  for (iterator it = begin(); it != end(); it++)
 
425
    (*it)->instantiateImages(this);
 
426
  if (getShipImageName().empty() == false)
 
427
    loadShipPic(getFile(getShipImageName()));
 
428
  if (getStandardImageName().empty() == false)
 
429
    loadStandardPic(getFile(getStandardImageName()));
 
430
  if (getBagImageName().empty() == false)
 
431
    loadBagPic(getFile(getBagImageName()));
 
432
}
 
433
 
 
434
void Armyset::uninstantiateImages()
 
435
{
 
436
  for (iterator it = begin(); it != end(); it++)
 
437
    (*it)->uninstantiateImages();
 
438
}
 
439
 
 
440
void Armyset::loadShipPic(std::string image_filename)
 
441
{
 
442
  if (image_filename.empty() == true)
 
443
    return;
 
444
  std::vector<PixMask*> half;
 
445
  half = disassemble_row(image_filename, 2);
 
446
  int size = getTileSize();
 
447
  PixMask::scale(half[0], size, size);
 
448
  PixMask::scale(half[1], size, size);
 
449
  setShipImage(half[0]);
 
450
  setShipMask(half[1]);
 
451
}
 
452
 
 
453
void Armyset::loadBagPic(std::string image_filename)
 
454
{
 
455
  if (image_filename.empty() == true)
 
456
    return;
 
457
  setBagPic(PixMask::create(image_filename));
 
458
}
 
459
void Armyset::loadStandardPic(std::string image_filename)
 
460
{
 
461
  if (image_filename.empty() == true)
 
462
    return;
 
463
  std::vector<PixMask*> half = disassemble_row(image_filename, 2);
 
464
  int size = getTileSize();
 
465
  PixMask::scale(half[0], size, size);
 
466
  PixMask::scale(half[1], size, size);
 
467
  setStandardPic(half[0]);
 
468
  setStandardMask(half[1]);
 
469
}
 
470
 
 
471
std::string Armyset::getConfigurationFile()
 
472
{
 
473
  return getDirectory() + d_subdir + file_extension;
 
474
}
 
475
 
 
476
std::list<std::string> Armyset::scanUserCollection()
 
477
{
 
478
  return File::scanFiles(File::getUserArmysetDir(), file_extension);
 
479
}
 
480
 
 
481
std::list<std::string> Armyset::scanSystemCollection()
 
482
{
 
483
  std::list<std::string> retlist = File::scanFiles(File::getArmysetDir(), 
 
484
                                                   file_extension);
 
485
  if (retlist.empty())
 
486
    {
 
487
      std::cerr << "Couldn't find any armysets (*" << file_extension << 
 
488
        ") in directories below: " << File::getArmysetDir() << std::endl;
 
489
      std::cerr << "Please check the path settings in /etc/lordsawarrc or ~/.lordsawarrc" << std::endl;
 
490
      std::cerr << "Exiting!" << std::endl;
 
491
      exit(-1);
 
492
    }
 
493
 
 
494
  return retlist;
 
495
}
 
496
 
 
497
void Armyset::switchArmysetForRuinKeeper(Army *army, const Armyset *armyset)
 
498
{
 
499
  //do our best to change the armyset for the given ruin keeper.
 
500
 
 
501
  //go find an equivalent type in the new armyset.
 
502
  Armyset *old_armyset
 
503
    = Armysetlist::getInstance()->getArmyset(army->getOwner()->getArmyset());
 
504
  ArmyProto *old_armyproto = old_armyset->lookupArmyByType(army->getTypeId());
 
505
  const ArmyProto *new_armyproto = armyset->lookupArmyByType(army->getTypeId());
 
506
 
 
507
  //try looking at the same id first
 
508
  if (new_armyproto != NULL && 
 
509
      old_armyproto->getName() == new_armyproto->getName() &&
 
510
      old_armyproto->getDefendsRuins() == new_armyproto->getDefendsRuins())
 
511
    {
 
512
      army->morph(new_armyproto);
 
513
      return;
 
514
    }
 
515
 
 
516
  //try finding an army by the same name
 
517
  new_armyproto = armyset->lookupArmyByName(old_armyproto->getName());
 
518
  if (new_armyproto != NULL &&
 
519
      old_armyproto->getDefendsRuins() == new_armyproto->getDefendsRuins())
 
520
    {
 
521
      army->morph(new_armyproto);
 
522
      return;
 
523
    }
 
524
 
 
525
  //failing that, any ruin keeper will do.
 
526
  new_armyproto = armyset->getRandomRuinKeeper();
 
527
  if (new_armyproto != NULL)
 
528
    {
 
529
      army->morph(new_armyproto);
 
530
      return;
 
531
    }
 
532
 
 
533
}
 
534
 
 
535
void Armyset::switchArmyset(ArmyProdBase *army, const Armyset *armyset)
 
536
{
 
537
  //do our best to change the armyset for the given armyprodbase.
 
538
 
 
539
  //go find an equivalent type in the new armyset.
 
540
  Armyset *old_armyset
 
541
    = Armysetlist::getInstance()->getArmyset(army->getArmyset());
 
542
  ArmyProto *old_armyproto = old_armyset->lookupArmyByType(army->getTypeId());
 
543
  ArmyProto *new_armyproto = armyset->lookupArmyByType(army->getTypeId());
 
544
 
 
545
  //try looking at the same id first
 
546
  if (new_armyproto != NULL && 
 
547
      old_armyproto->getName() == new_armyproto->getName())
 
548
    {
 
549
      army->morph(new_armyproto);
 
550
      return;
 
551
    }
 
552
 
 
553
  //try finding an army by the same name
 
554
  new_armyproto = armyset->lookupArmyByName(old_armyproto->getName());
 
555
  if (new_armyproto != NULL)
 
556
    {
 
557
      army->morph(new_armyproto);
 
558
      return;
 
559
    }
 
560
 
 
561
  //failing that, any army with similar characteristics will do.
 
562
  new_armyproto = armyset->lookupSimilarArmy(old_armyproto);
 
563
  if (new_armyproto != NULL)
 
564
    {
 
565
      army->morph(new_armyproto);
 
566
      return;
 
567
    }
 
568
 
 
569
  //failing that, any army with the same strength and turns will do.
 
570
  new_armyproto = 
 
571
    armyset->lookupArmyByStrengthAndTurns(old_armyproto->getStrength(),
 
572
                                          old_armyproto->getProduction());
 
573
  if (new_armyproto != NULL)
 
574
    {
 
575
      army->morph(new_armyproto);
 
576
      return;
 
577
    }
 
578
 
 
579
  //failing that, any army with the same strength will do.
 
580
  new_armyproto = 
 
581
    armyset->lookupArmyByStrengthAndTurns(old_armyproto->getStrength(), 0);
 
582
  if (new_armyproto != NULL)
 
583
    {
 
584
      army->morph(new_armyproto);
 
585
      return;
 
586
    }
 
587
 
 
588
  //failing that, any army with the same turns will do.
 
589
  new_armyproto = 
 
590
    armyset->lookupArmyByStrengthAndTurns(0, old_armyproto->getProduction());
 
591
  if (new_armyproto != NULL)
 
592
    {
 
593
      army->morph(new_armyproto);
 
594
      return;
 
595
    }
 
596
 
 
597
  //failing that, any army will do.
 
598
  new_armyproto = armyset->lookupArmyByGender(old_armyproto->getGender());
 
599
  if (new_armyproto != NULL)
 
600
    {
 
601
      army->morph(new_armyproto);
 
602
      return;
 
603
    }
 
604
 
 
605
}
 
606
 
 
607
void Armyset::switchArmyset(Army *army, const Armyset *armyset)
 
608
{
 
609
  //do our best to change the armyset for the given army.
 
610
 
 
611
  //go find an equivalent type in the new armyset.
 
612
  Armyset *old_armyset
 
613
    = Armysetlist::getInstance()->getArmyset(army->getOwner()->getArmyset());
 
614
  ArmyProto *old_armyproto = old_armyset->lookupArmyByType(army->getTypeId());
 
615
  ArmyProto *new_armyproto = armyset->lookupArmyByType(army->getTypeId());
 
616
 
 
617
  //try looking at the same id first
 
618
  if (new_armyproto != NULL && 
 
619
      old_armyproto->getName() == new_armyproto->getName())
 
620
    {
 
621
      army->morph(new_armyproto);
 
622
      return;
 
623
    }
 
624
 
 
625
  //try finding an army by the same name
 
626
  new_armyproto = armyset->lookupArmyByName(old_armyproto->getName());
 
627
  if (new_armyproto != NULL)
 
628
    {
 
629
      army->morph(new_armyproto);
 
630
      return;
 
631
    }
 
632
 
 
633
  //failing that, an army with the same gender (heroes).
 
634
  if (army->isHero() == true)
 
635
    {
 
636
      new_armyproto = armyset->lookupArmyByGender(old_armyproto->getGender());
 
637
      if (new_armyproto != NULL)
 
638
        {
 
639
          army->morph(new_armyproto);
 
640
          return;
 
641
        }
 
642
    }
 
643
 
 
644
  //failing that, any army with similar characteristics will do.
 
645
  new_armyproto = armyset->lookupSimilarArmy(old_armyproto);
 
646
  if (new_armyproto != NULL)
 
647
    {
 
648
      army->morph(new_armyproto);
 
649
      return;
 
650
    }
 
651
 
 
652
  //failing that, any army with the same strength and turns will do.
 
653
  new_armyproto = 
 
654
    armyset->lookupArmyByStrengthAndTurns(old_armyproto->getStrength(),
 
655
                                          old_armyproto->getProduction());
 
656
  if (new_armyproto != NULL)
 
657
    {
 
658
      army->morph(new_armyproto);
 
659
      return;
 
660
    }
 
661
 
 
662
  //failing that, any army with the same strength will do.
 
663
  new_armyproto = 
 
664
    armyset->lookupArmyByStrengthAndTurns(old_armyproto->getStrength(), 0);
 
665
  if (new_armyproto != NULL)
 
666
    {
 
667
      army->morph(new_armyproto);
 
668
      return;
 
669
    }
 
670
 
 
671
  //failing that, any army with the same turns will do.
 
672
  new_armyproto = 
 
673
    armyset->lookupArmyByStrengthAndTurns(0, old_armyproto->getProduction());
 
674
  if (new_armyproto != NULL)
 
675
    {
 
676
      army->morph(new_armyproto);
 
677
      return;
 
678
    }
 
679
 
 
680
  //failing that, any army will do.
 
681
  new_armyproto = armyset->lookupArmyByGender(old_armyproto->getGender());
 
682
  if (new_armyproto != NULL)
 
683
    {
 
684
      army->morph(new_armyproto);
 
685
      return;
 
686
    }
 
687
 
 
688
}
 
689
 
 
690
const ArmyProto * Armyset::getRandomRuinKeeper() const
 
691
{
 
692
  // list all the army types that can be a sentinel.
 
693
  std::vector<const ArmyProto*> occupants;
 
694
  for (const_iterator i = begin(); i != end(); i++)
 
695
    {
 
696
      const ArmyProto *a = *i;
 
697
      if (a->getDefendsRuins())
 
698
        occupants.push_back(a);
 
699
    }
 
700
            
 
701
  if (!occupants.empty())
 
702
    return occupants[rand() % occupants.size()];
 
703
 
 
704
  return NULL;
 
705
}
 
706
 
 
707
const ArmyProto *Armyset::getRandomAwardableAlly() const
 
708
{
 
709
  // list all the army types that can be given out as a reward.
 
710
  std::vector<const ArmyProto*> allies;
 
711
  for (const_iterator i = begin(); i != end(); i++)
 
712
    {
 
713
      const ArmyProto *a = *i;
 
714
      if (a->getAwardable() == true)
 
715
        allies.push_back(a);
 
716
    }
 
717
            
 
718
  if (!allies.empty())
 
719
    return allies[rand() % allies.size()];
 
720
 
 
721
  return NULL;
 
722
}