Crossfire Server, Trunk
CRESmoothFaceMaker.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 "CRESmoothFaceMaker.h"
14 #include "CREPixmap.h"
15 #include <QtWidgets>
16 #include "FaceComboBox.h"
17 
18 #include "global.h"
19 #include "image.h"
20 
21 #include "assets.h"
22 #include "AssetsManager.h"
23 
25 {
26  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
27 
28  myAutoClose = false;
29  myOverwrite = false;
30 
31  QGridLayout* layout = new QGridLayout(this);
32  int line = 0;
33 
34  layout->addWidget(new QLabel(tr("Face to use:"), this), line, 0);
35  myFace = new FaceComboBox(this, false);
36  layout->addWidget(myFace, line++, 1, 1, 2);
37 
38  layout->addWidget(new QLabel(tr("Path of the picture to create:"), this), line, 0);
39  myDestination = new QLineEdit();
40  layout->addWidget(myDestination, line, 1);
41  connect(myDestination, SIGNAL(textEdited(const QString &)), this, SLOT(destinationEdited(const QString&)));
42 
43  QPushButton* browse = new QPushButton(tr("Browse"), this);
44  layout->addWidget(browse, line++, 2);
45  connect(browse, SIGNAL(clicked(bool)), this, SLOT(browse(bool)));
46 
47  QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close, Qt::Horizontal, this);
48  layout->addWidget(box, line++, 1, 1, 3);
49  connect(box, SIGNAL(rejected()), this, SLOT(reject()));
50  connect(box, SIGNAL(accepted()), this, SLOT(makeSmooth()));
51 
52  setWindowTitle(tr("Smooth face base generator"));
53 
54  QApplication::restoreOverrideCursor();
55 }
56 
58 {
59 }
60 
62 {
63  myFace->setFace(face);
64 }
65 
67 {
68  return myDestination->text();
69 }
70 
72 {
73  myAutoClose = autoClose;
74 }
75 
77 {
78  if (destination().isEmpty())
79  {
80  QMessageBox::warning(this, tr("Oops"), tr("You must select a destination!"));
81  return;
82  }
83 
84  if (!myOverwrite && QFile::exists(destination()))
85  {
86  if (QMessageBox::question(this, tr("Confirm file overwrite"), tr("File %1 already exists. Overwrite it?").arg(destination()), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
87  return;
88  }
89 
90  QPixmap pic(32 * 16, 32 * 2);
91  pic.fill(QColor(0, 0, 0, 0));
92  QImage icon = CREPixmap::getIcon(myFace->face()->number).pixmap(32, 32).toImage();
93  QPainter device(&pic);
94  device.setBackground(QColor(0, 0, 0, 0));
95 
96  long spots[] = {
97  0x0, /* 0b000000000 */
98  0x49, /* 0b001001001 */
99  0x7, /* 0b000000111 */
100  0x4f, /* 0b001001111 */
101  0x124, /* 0b100100100 */
102  0x16d, /* 0b101101101 */
103  0x127, /* 0b100100111 */
104  0x16f, /* 0b101101111 */
105  0x1c0, /* 0b111000000 */
106  0x1c9, /* 0b111001001 */
107  0x1c7, /* 0b111000111 */
108  0x1cf, /* 0b111001111 */
109  0x1e4, /* 0b111100100 */
110  0x1ed, /* 0b111101101 */
111  0x1e7, /* 0b111100111 */
112  0x1ef, /* 0b111101111 */
113  0x0, /* 0b000000000 */
114  0x1, /* 0b000000001 */
115  0x4, /* 0b000000100 */
116  0x5, /* 0b000000101 */
117  0x100, /* 0b100000000 */
118  0x101, /* 0b100000001 */
119  0x104, /* 0b100000100 */
120  0x105, /* 0b100000101 */
121  0x40, /* 0b001000000 */
122  0x41, /* 0b001000001 */
123  0x44, /* 0b001000100 */
124  0x45, /* 0b001000101 */
125  0x140, /* 0b101000000 */
126  0x141, /* 0b101000001 */
127  0x144, /* 0b101000100 */
128  0x145, /* 0b101000101 */
129  };
130 
131 
132  int sx, sy, sw, sh, dx, dy, spot;
133  for (int x = 0; x < 16; x++) {
134  for (int y = 0; y < 2; y++) {
135  spot = y * 16 + x;
136 
137  for (int bit = 0; bit < 9; bit++) {
138  if ((spots[spot] & (1 << bit)) == 0)
139  continue;
140 
141  dx = x * 32;
142  dy = y * 32;
143  sw = 8;
144  sh = 8;
145 
146  switch (bit / 3)
147  {
148  case 0:
149  sy = 0;
150  break;
151  case 1:
152  sy = 8;
153  dy += 8;
154  sh = 16;
155  break;
156  case 2:
157  sy = 24;
158  dy += 24;
159  break;
160  default:
161  Q_ASSERT(false);
162  }
163 
164  switch (bit % 3)
165  {
166  case 0:
167  sx = 0;
168  break;
169  case 1:
170  sx = 8;
171  dx += 8;
172  sw = 16;
173  break;
174  case 2:
175  sx = 24;
176  dx += 24;
177  break;
178  default:
179  Q_ASSERT(false);
180  }
181 
182  device.drawImage(dx, dy, icon, sx, sy, sw, sh);
183  }
184 
185  }
186  }
187 
188  if (!pic.save(destination(), "PNG"))
189  {
190  QMessageBox::critical(this, tr("Error"), tr("Error while saving the picture as %1!").arg(destination()));
191  return;
192  }
193 
194  QMessageBox::information(this, tr("Smooth base saved"), tr("The smooth base was correctly saved as %1").arg(destination()));
195 
196  if (myAutoClose)
197  accept();
198 
199  myOverwrite = false;
200 }
201 
203 {
204  QString dest = QFileDialog::getSaveFileName(this, tr("Select destination file"), "", tr("PNG file (*.png);;All files (*.*)"));
205  if (dest.isEmpty())
206  return;
207 
208  myDestination->setText(dest);
209  myOverwrite = true;
210 }
211 
213 {
214  myOverwrite = false;
215 }
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
layout
Definition: main.cpp:84
CRESmoothFaceMaker::browse
void browse(bool)
Definition: CRESmoothFaceMaker.cpp:202
diamondslots.x
x
Definition: diamondslots.py:15
CRESmoothFaceMaker::myAutoClose
bool myAutoClose
Definition: CRESmoothFaceMaker.h:42
CRESmoothFaceMaker::setSelectedFace
void setSelectedFace(const Face *face)
Definition: CRESmoothFaceMaker.cpp:61
AssetsManager.h
CRESmoothFaceMaker::myFace
FaceComboBox * myFace
Definition: CRESmoothFaceMaker.h:45
CRESmoothFaceMaker::~CRESmoothFaceMaker
virtual ~CRESmoothFaceMaker()
Definition: CRESmoothFaceMaker.cpp:57
CRESmoothFaceMaker::destinationEdited
void destinationEdited(const QString &)
Definition: CRESmoothFaceMaker.cpp:212
CRESmoothFaceMaker.h
FaceComboBox::face
const Face face
Definition: FaceComboBox.h:27
say.box
box
Definition: say.py:152
FaceComboBox::setFace
void setFace(const Face *face)
Definition: FaceComboBox.cpp:45
CRESmoothFaceMaker::CRESmoothFaceMaker
CRESmoothFaceMaker()
Definition: CRESmoothFaceMaker.cpp:24
CRESmoothFaceMaker::myDestination
QLineEdit * myDestination
Definition: CRESmoothFaceMaker.h:44
image.h
FaceComboBox
Definition: FaceComboBox.h:23
CRESmoothFaceMaker::myOverwrite
bool myOverwrite
Definition: CRESmoothFaceMaker.h:43
CREPixmap.h
CRESmoothFaceMaker::setAutoClose
void setAutoClose(bool autoClose=true)
Definition: CRESmoothFaceMaker.cpp:71
FaceComboBox.h
convert.dest
dest
Definition: convert.py:25
diamondslots.y
y
Definition: diamondslots.py:16
assets.h
Face
Definition: face.h:14
CRESmoothFaceMaker::makeSmooth
void makeSmooth()
Definition: CRESmoothFaceMaker.cpp:76
Face::number
uint16_t number
Definition: face.h:15
CREPixmap::getIcon
static QIcon getIcon(uint16_t faceNumber)
Definition: CREPixmap.cpp:65
connect
Definition: connect.py:1
altar_valkyrie.accept
def accept(description)
Definition: altar_valkyrie.py:22
CRESmoothFaceMaker::destination
QString destination() const
Definition: CRESmoothFaceMaker.cpp:66