Crossfire Server, Trunk
CRECombatSimulator.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2022 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include "CRECombatSimulator.h"
14 #include "CREPixmap.h"
15 
16 #include <global.h>
17 #include <sproto.h>
18 #include "assets.h"
19 #include "AssetsManager.h"
21 
23 {
24  QGridLayout* layout = new QGridLayout(this);
25  int line = 0;
26 
27  layout->addWidget(new QLabel(tr("First fighter:"), this), line, 0);
28  myFirst = new ArchetypeComboBox(this, false);
29  layout->addWidget(myFirst, line++, 1);
30 
31  layout->addWidget(new QLabel(tr("Second fighter:"), this), line, 0);
32  mySecond = new ArchetypeComboBox(this, false);
33  layout->addWidget(mySecond, line++, 1);
34 
35  layout->addWidget(new QLabel(tr("Number of fights:"), this), line, 0);
36  myCombats = new QSpinBox(this);
37  myCombats->setMinimum(1);
38  myCombats->setMaximum(10000);
39  layout->addWidget(myCombats, line++, 1);
40 
41  layout->addWidget(new QLabel(tr("Maximum number of rounds:"), this), line, 0);
42  myMaxRounds = new QSpinBox(this);
43  myMaxRounds->setMinimum(1);
44  myMaxRounds->setMaximum(10000);
45  myMaxRounds->setValue(500);
46  layout->addWidget(myMaxRounds, line++, 1);
47 
48  myResultLabel = new QLabel(tr("Combat result:"), this);
49  myResultLabel->setVisible(false);
50  layout->addWidget(myResultLabel, line++, 0, 1, 2);
51  myResult = new QLabel(this);
52  myResult->setVisible(false);
53  layout->addWidget(myResult, line++, 0, 1, 2);
54 
55  QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close, Qt::Horizontal, this);
56  layout->addWidget(box, line++, 0, 1, 2);
57  connect(box, SIGNAL(rejected()), this, SLOT(reject()));
58  connect(box, SIGNAL(accepted()), this, SLOT(fight()));
59 
60  setWindowTitle(tr("Combat simulator"));
61 }
62 
64 {
65 }
66 
68 {
69  int limit = myMaxRounds->value();
70  object* obfirst = object_create_arch(const_cast<archetype *>(first));
71  object* obsecond = object_create_arch(const_cast<archetype *>(second));
72  tag_t tagfirst = obfirst->count;
73  tag_t tagsecond = obsecond->count;
74 
75  // make a big map so large monsters are ok in map
76  mapstruct* test_map = get_empty_map(50, 50);
77 
78  // insert shifted for monsters like titans who have parts with negative values
79  obfirst = object_insert_in_map_at(obfirst, test_map, NULL, 0, 12, 12);
80  obsecond = object_insert_in_map_at(obsecond, test_map, NULL, 0, 37, 37);
81 
82  while (limit-- > 0 && obfirst->stats.hp >= 0 && obsecond->stats.hp >= 0)
83  {
84  if (obfirst->speed_left > 0) {
85  --obfirst->speed_left;
86  monster_do_living(obfirst);
87  if (obfirst->stats.hp > myFirstMaxHp)
88  myFirstMaxHp = obfirst->stats.hp;
89 
90  attack_ob(obsecond, obfirst);
91  if (object_was_destroyed(obsecond, tagsecond))
92  break;
93  if (obsecond->stats.hp < mySecondMinHp && obsecond->stats.hp > 0)
94  mySecondMinHp = obsecond->stats.hp;
95  }
96 
97  if (obsecond->speed_left > 0) {
98  --obsecond->speed_left;
99  monster_do_living(obsecond);
100  if (obsecond->stats.hp > mySecondMaxHp)
101  mySecondMaxHp = obsecond->stats.hp;
102 
103  attack_ob(obfirst, obsecond);
104  if (object_was_destroyed(obfirst, tagfirst))
105  break;
106  if (obfirst->stats.hp < myFirstMinHp && obfirst->stats.hp > 0)
107  myFirstMinHp = obfirst->stats.hp;
108  }
109 
110  if (obfirst->speed_left <= 0)
111  obfirst->speed_left += FABS(obfirst->speed);
112  if (obsecond->speed_left <= 0)
113  obsecond->speed_left += FABS(obsecond->speed);
114  }
115 
116  if (limit > 0)
117  {
118  if (obfirst->stats.hp < 0)
120  else
122  }
123 
124  if (!object_was_destroyed(obfirst, tagfirst))
125  {
126  object_remove(obfirst);
127  object_free(obfirst, 0);
128  }
129  if (!object_was_destroyed(obsecond, tagsecond))
130  {
131  object_remove(obsecond);
132  object_free(obsecond, 0);
133  }
135 }
136 
138 {
139  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
140 
141  myFirstVictories = 0;
142  mySecondVictories = 0;
143 
144  const archetype* first = myFirst->arch();
145  const archetype* second = mySecond->arch();
146 
147  /*
148  * Set min and max hp here, in case a monster doesn't ever get attacked
149  * Example as of the time of writing is cherub vs. cherub
150  * without this fix, the first cherub had maxhp of 10000 and minhp of -1
151  *
152  * So, temporaily create the objects to then determine what the maxhp is for
153  * each object from the archetypes.
154  */
155  object* obfirst = object_create_arch(const_cast<archetype *>(first));
156  object* obsecond = object_create_arch(const_cast<archetype *>(second));
157 
158  myFirstMinHp = obfirst->stats.maxhp;
159  myFirstMaxHp = obfirst->stats.maxhp;
160  mySecondMinHp = obsecond->stats.maxhp;
161  mySecondMaxHp = obsecond->stats.maxhp;
162 
163  /*
164  * Then, free the objects since this is done.
165  */
166  object_free(obfirst, 0);
167  object_free(obsecond, 0);
168 
169  int count = myCombats->value();
170  while (count-- > 0)
171  {
172  fight(first, second);
173  }
174 
175  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)")
176  .arg(myCombats->value() - myFirstVictories - mySecondVictories)
177  .arg(first->name).arg(myFirstVictories).arg(myFirstMaxHp).arg(myFirstMinHp)
178  .arg(second->name).arg(mySecondVictories).arg(mySecondMaxHp).arg(mySecondMinHp));
179 
180  myResultLabel->setVisible(true);
181  myResult->setVisible(true);
182 
183  QApplication::restoreOverrideCursor();
184 }
CRECombatSimulator::fight
void fight()
Definition: CRECombatSimulator.cpp:137
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:70
global.h
line
Install Bug reporting Credits so make sure you have version or later There are files involved in the automatic convert convertall and filelist py GuildList has the list of guilds for the server GuildLocations is what is used by the install script for setting up the maps It has columns in the first is the name of the no spaces The second is the region of the the third is the destination folder for the the fourth is the exit the fifth and sixth are the x and y coords within the exit the seventh eighth and ninth are the exit location for the storage hall If field seven is then it uses the same exit map as for the guild hall itself filelist py has a list of which files to process for each guild hall convert py takes all the files in filelist py and customises them to the specific guild then outputs them into a in the same order that they are listed in GuildLocations convertall py reads the lines from GuildLocations and runs line by line
Definition: README.txt:12
living::maxhp
int16_t maxhp
Definition: living.h:41
ArchetypeComboBox.h
layout
Definition: main.cpp:84
FABS
#define FABS(x)
Definition: define.h:22
get_empty_map
mapstruct * get_empty_map(int sizex, int sizey)
Definition: map.cpp:842
test_map
mapstruct * test_map
Definition: comet_perf.cpp:74
CRECombatSimulator::myResultLabel
QLabel * myResultLabel
Definition: CRECombatSimulator.h:45
object::speed
float speed
Definition: object.h:337
object::speed_left
float speed_left
Definition: object.h:338
CRECombatSimulator::myFirstVictories
int myFirstVictories
Definition: CRECombatSimulator.h:48
object::count
tag_t count
Definition: object.h:307
monster_do_living
void monster_do_living(object *op)
Definition: monster.cpp:721
CRECombatSimulator::mySecondVictories
int mySecondVictories
Definition: CRECombatSimulator.h:51
AssetsManager.h
CRECombatSimulator::mySecond
ArchetypeComboBox * mySecond
Definition: CRECombatSimulator.h:42
CRECombatSimulator::CRECombatSimulator
CRECombatSimulator()
Definition: CRECombatSimulator.cpp:22
ArchetypeComboBox
Definition: ArchetypeComboBox.h:23
CRECombatSimulator::myFirst
ArchetypeComboBox * myFirst
Definition: CRECombatSimulator.h:41
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:298
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1587
say.box
box
Definition: say.py:152
free_map
void free_map(mapstruct *m)
Definition: map.cpp:1650
disinfect.count
int count
Definition: disinfect.py:7
tag_t
uint32_t tag_t
Definition: object.h:14
archetype
Definition: object.h:474
sproto.h
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.cpp:2095
CRECombatSimulator::mySecondMinHp
int mySecondMinHp
Definition: CRECombatSimulator.h:52
CRECombatSimulator::myFirstMaxHp
int myFirstMaxHp
Definition: CRECombatSimulator.h:50
CRECombatSimulator::myMaxRounds
QSpinBox * myMaxRounds
Definition: CRECombatSimulator.h:44
CREPixmap.h
CRECombatSimulator::~CRECombatSimulator
virtual ~CRECombatSimulator()
Definition: CRECombatSimulator.cpp:63
CRECombatSimulator::myCombats
QSpinBox * myCombats
Definition: CRECombatSimulator.h:43
mapstruct
Definition: map.h:314
assets.h
CRECombatSimulator.h
first
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at first
Definition: protocol.txt:20
object_remove
void object_remove(object *op)
Definition: object.cpp:1828
CRECombatSimulator::myFirstMinHp
int myFirstMinHp
Definition: CRECombatSimulator.h:49
CRECombatSimulator::mySecondMaxHp
int mySecondMaxHp
Definition: CRECombatSimulator.h:53
archetype::name
sstring name
Definition: object.h:475
object::stats
living stats
Definition: object.h:378
attack_ob
int attack_ob(object *op, object *hitter)
Definition: attack.cpp:937
connect
Definition: connect.py:1
ArchetypeComboBox::arch
const archetype arch
Definition: ArchetypeComboBox.h:26
living::hp
int16_t hp
Definition: living.h:40
CRECombatSimulator::myResult
QLabel * myResult
Definition: CRECombatSimulator.h:46