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"
10 
12 {
13  QGridLayout* layout = new QGridLayout(this);
14  int line = 0;
15 
16  layout->addWidget(new QLabel(tr("First fighter:"), this), line, 0);
17  myFirst = new QComboBox(this);
18  layout->addWidget(myFirst, line++, 1);
19 
20  layout->addWidget(new QLabel(tr("Second fighter:"), this), line, 0);
21  mySecond = new QComboBox(this);
22  layout->addWidget(mySecond, line++, 1);
23 
24  getManager()->archetypes()->each([this] (archetype *arch)
25  {
26  if (arch->head == NULL && QUERY_FLAG(&arch->clone, FLAG_MONSTER))
27  {
28  myFirst->addItem(CREPixmap::getIcon(arch->clone.face->number), arch->name, QVariant::fromValue((void*)arch));
29  mySecond->addItem(CREPixmap::getIcon(arch->clone.face->number), arch->name, QVariant::fromValue((void*)arch));
30  }
31  });
32 
33  layout->addWidget(new QLabel(tr("Number of fights:"), this), line, 0);
34  myCombats = new QSpinBox(this);
35  myCombats->setMinimum(1);
36  myCombats->setMaximum(10000);
37  layout->addWidget(myCombats, line++, 1);
38 
39  layout->addWidget(new QLabel(tr("Maximum number of rounds:"), this), line, 0);
40  myMaxRounds = new QSpinBox(this);
41  myMaxRounds->setMinimum(1);
42  myMaxRounds->setMaximum(10000);
43  myMaxRounds->setValue(500);
44  layout->addWidget(myMaxRounds, line++, 1);
45 
46  myResultLabel = new QLabel(tr("Combat result:"), this);
47  myResultLabel->setVisible(false);
48  layout->addWidget(myResultLabel, line++, 0, 1, 2);
49  myResult = new QLabel(this);
50  myResult->setVisible(false);
51  layout->addWidget(myResult, line++, 0, 1, 2);
52 
53  QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close, Qt::Horizontal, this);
54  layout->addWidget(box, line++, 0, 1, 2);
55  connect(box, SIGNAL(rejected()), this, SLOT(reject()));
56  connect(box, SIGNAL(accepted()), this, SLOT(fight()));
57 
58  setWindowTitle(tr("Combat simulator"));
59 }
60 
62 {
63 }
64 
65 void CRECombatSimulator::fight(const archetype* first, const archetype* second)
66 {
67  int limit = myMaxRounds->value();
68  object* obfirst = object_create_arch((archetype*)first);
69  object* obsecond = object_create_arch((archetype*)second);
70  tag_t tagfirst = obfirst->count;
71  tag_t tagsecond = obsecond->count;
72 
73  // make a big map so large monsters are ok in map
74  mapstruct* test_map = get_empty_map(50, 50);
75 
76  // insert shifted for monsters like titans who have parts with negative values
77  obfirst = object_insert_in_map_at(obfirst, test_map, NULL, 0, 12, 12);
78  obsecond = object_insert_in_map_at(obsecond, test_map, NULL, 0, 37, 37);
79 
80  while (limit-- > 0 && obfirst->stats.hp >= 0 && obsecond->stats.hp >= 0)
81  {
82  if (obfirst->speed_left > 0) {
83  --obfirst->speed_left;
84  monster_do_living(obfirst);
85  if (obfirst->stats.hp > myFirstMaxHp)
86  myFirstMaxHp = obfirst->stats.hp;
87 
88  attack_ob(obsecond, obfirst);
89  if (object_was_destroyed(obsecond, tagsecond))
90  break;
91  if (obsecond->stats.hp < mySecondMinHp && obsecond->stats.hp > 0)
92  mySecondMinHp = obsecond->stats.hp;
93  }
94 
95  if (obsecond->speed_left > 0) {
96  --obsecond->speed_left;
97  monster_do_living(obsecond);
98  if (obsecond->stats.hp > mySecondMaxHp)
99  mySecondMaxHp = obsecond->stats.hp;
100 
101  attack_ob(obfirst, obsecond);
102  if (object_was_destroyed(obfirst, tagfirst))
103  break;
104  if (obfirst->stats.hp < myFirstMinHp && obfirst->stats.hp > 0)
105  myFirstMinHp = obfirst->stats.hp;
106  }
107 
108  if (obfirst->speed_left <= 0)
109  obfirst->speed_left += FABS(obfirst->speed);
110  if (obsecond->speed_left <= 0)
111  obsecond->speed_left += FABS(obsecond->speed);
112  }
113 
114  if (limit > 0)
115  {
116  if (obfirst->stats.hp < 0)
118  else
120  }
121 
122  if (!object_was_destroyed(obfirst, tagfirst))
123  {
124  object_remove(obfirst);
125  object_free(obfirst, 0);
126  }
127  if (!object_was_destroyed(obsecond, tagsecond))
128  {
129  object_remove(obsecond);
130  object_free(obsecond, 0);
131  }
133 }
134 
136 {
137  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
138 
139  myFirstVictories = 0;
140  mySecondVictories = 0;
141 
142  const archetype* first = (const archetype*)myFirst->itemData(myFirst->currentIndex()).value<void*>();
143  const archetype* second = (const archetype*)mySecond->itemData(mySecond->currentIndex()).value<void*>();
144 
145  /*
146  * Set min and max hp here, in case a monster doesn't ever get attacked
147  * Example as of the time of writing is cherub vs. cherub
148  * without this fix, the first cherub had maxhp of 10000 and minhp of -1
149  *
150  * So, temporaily create the objects to then determine what the maxhp is for
151  * each object from the archetypes.
152  */
153  object* obfirst = object_create_arch((archetype*)first);
154  object* obsecond = object_create_arch((archetype*)second);
155 
156  myFirstMinHp = obfirst->stats.maxhp;
157  myFirstMaxHp = obfirst->stats.maxhp;
158  mySecondMinHp = obsecond->stats.maxhp;
159  mySecondMaxHp = obsecond->stats.maxhp;
160 
161  /*
162  * Then, free the objects since this is done.
163  */
164  object_free(obfirst, 0);
165  object_free(obsecond, 0);
166 
167  int count = myCombats->value();
168  while (count-- > 0)
169  {
170  fight(first, second);
171  }
172 
173  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)")
174  .arg(myCombats->value() - myFirstVictories - mySecondVictories)
175  .arg(first->name).arg(myFirstVictories).arg(myFirstMaxHp).arg(myFirstMinHp)
176  .arg(second->name).arg(mySecondVictories).arg(mySecondMaxHp).arg(mySecondMinHp));
177 
178  myResultLabel->setVisible(true);
179  myResult->setVisible(true);
180 
181  QApplication::restoreOverrideCursor();
182 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
global.h
CRECombatSimulator::fight
void fight()
Definition: CRECombatSimulator.cpp:135
object_free
void object_free(object *ob, int flags)
Definition: object.c:1565
object_remove
void object_remove(object *op)
Definition: object.c:1806
layout
Definition: main.c:85
FABS
#define FABS(x)
Definition: define.h:22
obj::count
tag_t count
Definition: object.h:300
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
AssetsManager.h
liv::maxhp
int16_t maxhp
Definition: living.h:41
CRECombatSimulator::mySecondMaxHp
int mySecondMaxHp
Definition: CRECombatSimulator.h:42
CRECombatSimulator::myCombats
QSpinBox * myCombats
Definition: CRECombatSimulator.h:32
liv::hp
int16_t hp
Definition: living.h:40
monster_do_living
void monster_do_living(object *op)
Definition: monster.c:688
getManager
AssetsManager * getManager()
Definition: assets.cpp:329
CRECombatSimulator::myFirstVictories
int myFirstVictories
Definition: CRECombatSimulator.h:37
archt
Definition: object.h:468
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
CRECombatSimulator::CRECombatSimulator
CRECombatSimulator()
Definition: CRECombatSimulator.cpp:11
CRECombatSimulator::myResultLabel
QLabel * myResultLabel
Definition: CRECombatSimulator.h:34
CRECombatSimulator.h
obj::speed_left
float speed_left
Definition: object.h:331
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:301
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:1670
obj::speed
float speed
Definition: object.h:330
tag_t
uint32_t tag_t
Definition: object.h:12
sproto.h
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:135
mapdef
Definition: map.h:324
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
CRECombatSimulator::mySecond
QComboBox * mySecond
Definition: CRECombatSimulator.h:31
CRECombatSimulator::~CRECombatSimulator
virtual ~CRECombatSimulator()
Definition: CRECombatSimulator.cpp:61
test_map
mapstruct * test_map
Definition: comet_perf.c:74
obj::stats
living stats
Definition: object.h:371
CRECombatSimulator::myFirst
QComboBox * myFirst
Definition: CRECombatSimulator.h:30
assets.h
CRECombatSimulator::myFirstMaxHp
int myFirstMaxHp
Definition: CRECombatSimulator.h:39
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:2067
CRECombatSimulator::myMaxRounds
QSpinBox * myMaxRounds
Definition: CRECombatSimulator.h:33
CRECombatSimulator::myFirstMinHp
int myFirstMinHp
Definition: CRECombatSimulator.h:38
CRECombatSimulator::mySecondVictories
int mySecondVictories
Definition: CRECombatSimulator.h:40
archt::name
sstring name
Definition: object.h:469
CRECombatSimulator::myResult
QLabel * myResult
Definition: CRECombatSimulator.h:35
CRECombatSimulator::mySecondMinHp
int mySecondMinHp
Definition: CRECombatSimulator.h:41
attack_ob
int attack_ob(object *op, object *hitter)
Definition: attack.c:912
connect
Definition: connect.py:1
CREPixmap.h
get_empty_map
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.c:867