Crossfire Server, Trunk
CRECombatSimulator.cpp
Go to the documentation of this file.
1 #include "CRECombatSimulator.h"
2 #include "CREPixmap.h"
3 
4 extern "C" {
5 #include <global.h>
6 #include <sproto.h>
7 }
8 #include "assets.h"
9 #include "AssetsManager.h"
11 
13 {
14  QGridLayout* layout = new QGridLayout(this);
15  int line = 0;
16 
17  layout->addWidget(new QLabel(tr("First fighter:"), this), line, 0);
18  myFirst = new ArchetypeComboBox(this, false);
19  layout->addWidget(myFirst, line++, 1);
20 
21  layout->addWidget(new QLabel(tr("Second fighter:"), this), line, 0);
22  mySecond = new ArchetypeComboBox(this, false);
23  layout->addWidget(mySecond, line++, 1);
24 
25  layout->addWidget(new QLabel(tr("Number of fights:"), this), line, 0);
26  myCombats = new QSpinBox(this);
27  myCombats->setMinimum(1);
28  myCombats->setMaximum(10000);
29  layout->addWidget(myCombats, line++, 1);
30 
31  layout->addWidget(new QLabel(tr("Maximum number of rounds:"), this), line, 0);
32  myMaxRounds = new QSpinBox(this);
33  myMaxRounds->setMinimum(1);
34  myMaxRounds->setMaximum(10000);
35  myMaxRounds->setValue(500);
36  layout->addWidget(myMaxRounds, line++, 1);
37 
38  myResultLabel = new QLabel(tr("Combat result:"), this);
39  myResultLabel->setVisible(false);
40  layout->addWidget(myResultLabel, line++, 0, 1, 2);
41  myResult = new QLabel(this);
42  myResult->setVisible(false);
43  layout->addWidget(myResult, line++, 0, 1, 2);
44 
45  QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close, Qt::Horizontal, this);
46  layout->addWidget(box, line++, 0, 1, 2);
47  connect(box, SIGNAL(rejected()), this, SLOT(reject()));
48  connect(box, SIGNAL(accepted()), this, SLOT(fight()));
49 
50  setWindowTitle(tr("Combat simulator"));
51 }
52 
54 {
55 }
56 
57 void CRECombatSimulator::fight(const archetype* first, const archetype* second)
58 {
59  int limit = myMaxRounds->value();
60  object* obfirst = object_create_arch(const_cast<archetype *>(first));
61  object* obsecond = object_create_arch(const_cast<archetype *>(second));
62  tag_t tagfirst = obfirst->count;
63  tag_t tagsecond = obsecond->count;
64 
65  // make a big map so large monsters are ok in map
66  mapstruct* test_map = get_empty_map(50, 50);
67 
68  // insert shifted for monsters like titans who have parts with negative values
69  obfirst = object_insert_in_map_at(obfirst, test_map, NULL, 0, 12, 12);
70  obsecond = object_insert_in_map_at(obsecond, test_map, NULL, 0, 37, 37);
71 
72  while (limit-- > 0 && obfirst->stats.hp >= 0 && obsecond->stats.hp >= 0)
73  {
74  if (obfirst->speed_left > 0) {
75  --obfirst->speed_left;
76  monster_do_living(obfirst);
77  if (obfirst->stats.hp > myFirstMaxHp)
78  myFirstMaxHp = obfirst->stats.hp;
79 
80  attack_ob(obsecond, obfirst);
81  if (object_was_destroyed(obsecond, tagsecond))
82  break;
83  if (obsecond->stats.hp < mySecondMinHp && obsecond->stats.hp > 0)
84  mySecondMinHp = obsecond->stats.hp;
85  }
86 
87  if (obsecond->speed_left > 0) {
88  --obsecond->speed_left;
89  monster_do_living(obsecond);
90  if (obsecond->stats.hp > mySecondMaxHp)
91  mySecondMaxHp = obsecond->stats.hp;
92 
93  attack_ob(obfirst, obsecond);
94  if (object_was_destroyed(obfirst, tagfirst))
95  break;
96  if (obfirst->stats.hp < myFirstMinHp && obfirst->stats.hp > 0)
97  myFirstMinHp = obfirst->stats.hp;
98  }
99 
100  if (obfirst->speed_left <= 0)
101  obfirst->speed_left += FABS(obfirst->speed);
102  if (obsecond->speed_left <= 0)
103  obsecond->speed_left += FABS(obsecond->speed);
104  }
105 
106  if (limit > 0)
107  {
108  if (obfirst->stats.hp < 0)
110  else
112  }
113 
114  if (!object_was_destroyed(obfirst, tagfirst))
115  {
116  object_remove(obfirst);
117  object_free(obfirst, 0);
118  }
119  if (!object_was_destroyed(obsecond, tagsecond))
120  {
121  object_remove(obsecond);
122  object_free(obsecond, 0);
123  }
125 }
126 
128 {
129  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
130 
131  myFirstVictories = 0;
132  mySecondVictories = 0;
133 
134  const archetype* first = myFirst->arch();
135  const archetype* second = mySecond->arch();
136 
137  /*
138  * Set min and max hp here, in case a monster doesn't ever get attacked
139  * Example as of the time of writing is cherub vs. cherub
140  * without this fix, the first cherub had maxhp of 10000 and minhp of -1
141  *
142  * So, temporaily create the objects to then determine what the maxhp is for
143  * each object from the archetypes.
144  */
145  object* obfirst = object_create_arch(const_cast<archetype *>(first));
146  object* obsecond = object_create_arch(const_cast<archetype *>(second));
147 
148  myFirstMinHp = obfirst->stats.maxhp;
149  myFirstMaxHp = obfirst->stats.maxhp;
150  mySecondMinHp = obsecond->stats.maxhp;
151  mySecondMaxHp = obsecond->stats.maxhp;
152 
153  /*
154  * Then, free the objects since this is done.
155  */
156  object_free(obfirst, 0);
157  object_free(obsecond, 0);
158 
159  int count = myCombats->value();
160  while (count-- > 0)
161  {
162  fight(first, second);
163  }
164 
165  myResult->setText(tr("Draw: %1 fights\n%2 victories: %3 (max hp: %4, min hp: %5)\n%6 victories: %7 (max hp: %8, min hp: %9)")
166  .arg(myCombats->value() - myFirstVictories - mySecondVictories)
167  .arg(first->name).arg(myFirstVictories).arg(myFirstMaxHp).arg(myFirstMinHp)
168  .arg(second->name).arg(mySecondVictories).arg(mySecondMaxHp).arg(mySecondMinHp));
169 
170  myResultLabel->setVisible(true);
171  myResult->setVisible(true);
172 
173  QApplication::restoreOverrideCursor();
174 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
global.h
CRECombatSimulator::fight
void fight()
Definition: CRECombatSimulator.cpp:127
object_free
void object_free(object *ob, int flags)
Definition: object.c:1578
object_remove
void object_remove(object *op)
Definition: object.c:1819
layout
Definition: main.c:85
FABS
#define FABS(x)
Definition: define.h:22
obj::count
tag_t count
Definition: object.h:302
AssetsManager.h
liv::maxhp
int16_t maxhp
Definition: living.h:41
CRECombatSimulator::mySecondMaxHp
int mySecondMaxHp
Definition: CRECombatSimulator.h:43
CRECombatSimulator::myCombats
QSpinBox * myCombats
Definition: CRECombatSimulator.h:33
liv::hp
int16_t hp
Definition: living.h:40
monster_do_living
void monster_do_living(object *op)
Definition: monster.c:715
ArchetypeComboBox::arch
const archetype arch
Definition: ArchetypeComboBox.h:16
CRECombatSimulator::myFirstVictories
int myFirstVictories
Definition: CRECombatSimulator.h:38
archt
Definition: object.h:470
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
CRECombatSimulator::CRECombatSimulator
CRECombatSimulator()
Definition: CRECombatSimulator.cpp:12
CRECombatSimulator::myResultLabel
QLabel * myResultLabel
Definition: CRECombatSimulator.h:35
CRECombatSimulator.h
obj::speed_left
float speed_left
Definition: object.h:333
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:301
ArchetypeComboBox
Definition: ArchetypeComboBox.h:13
say.box
box
Definition: say.py:152
disinfect.count
int count
Definition: disinfect.py:7
free_map
void free_map(mapstruct *m)
Definition: map.c:1676
obj::speed
float speed
Definition: object.h:332
tag_t
uint32_t tag_t
Definition: object.h:12
sproto.h
mapdef
Definition: map.h:324
CRECombatSimulator::~CRECombatSimulator
virtual ~CRECombatSimulator()
Definition: CRECombatSimulator.cpp:53
test_map
mapstruct * test_map
Definition: comet_perf.c:74
obj::stats
living stats
Definition: object.h:373
ArchetypeComboBox.h
assets.h
CRECombatSimulator::myFirstMaxHp
int myFirstMaxHp
Definition: CRECombatSimulator.h:40
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:2080
CRECombatSimulator::mySecond
ArchetypeComboBox * mySecond
Definition: CRECombatSimulator.h:32
CRECombatSimulator::myMaxRounds
QSpinBox * myMaxRounds
Definition: CRECombatSimulator.h:34
CRECombatSimulator::myFirstMinHp
int myFirstMinHp
Definition: CRECombatSimulator.h:39
CRECombatSimulator::myFirst
ArchetypeComboBox * myFirst
Definition: CRECombatSimulator.h:31
CRECombatSimulator::mySecondVictories
int mySecondVictories
Definition: CRECombatSimulator.h:41
archt::name
sstring name
Definition: object.h:471
CRECombatSimulator::myResult
QLabel * myResult
Definition: CRECombatSimulator.h:36
CRECombatSimulator::mySecondMinHp
int mySecondMinHp
Definition: CRECombatSimulator.h:42
attack_ob
int attack_ob(object *op, object *hitter)
Definition: attack.c:919
connect
Definition: connect.py:1
CREPixmap.h
get_empty_map
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.c:869