Crossfire Server, Trunk
ArchetypeWrapper.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 "ArchetypeWrapper.h"
14 #include <QMimeData>
15 #include "../ResourcesManager.h"
16 #include "../CREPixmap.h"
17 #include "faces/FaceWrapper.h"
18 #include "assets.h"
19 #include "ArchetypeLoader.h"
20 #include "AssetsManager.h"
23 #include "MimeUtils.h"
25 #include "sounds/SoundFile.h"
26 
28  : AssetWithArtifacts<archetype>(parent, "Archetype", arch, resourcesManager) {
29  if (appearsOnTreasureList()) {
30  setSpecificItem(&arch->clone, false);
31  }
32 
35  char* final = stringbuffer_finish(dump);
36  myRaw = final;
37  free(final);
38 
39  // Hacks: replace initial "arch" by "Object", and remove the "more 0" line which messes things
40  myRaw.replace(0, 4, "Object");
41  auto more = myRaw.find("more 0\n");
42  if (more != std::string::npos) {
43  myRaw.erase(more, 7);
44  }
45 }
46 
49  AssetTWrapper::wasModified(asset, type, extra);
50 }
51 
52 QString ArchetypeWrapper::name() const {
53  return myWrappedItem->name;
54 }
55 
56 QObject* ArchetypeWrapper::clone() {
57  return myResources->wrap(&myWrappedItem->clone, this);
58 }
59 
60 QObject *ArchetypeWrapper::head() const {
61  return myWrappedItem->head ? myResources->wrap(myWrappedItem->head, nullptr) : nullptr;
62 }
63 
64 QObject *ArchetypeWrapper::more() const {
65  return myWrappedItem->more ? myResources->wrap(myWrappedItem->more, nullptr) : nullptr;
66 }
67 
69  if (myWrappedItem->head) {
70  return 0;
71  }
72  int count = 0;
73  auto part = myWrappedItem;
74  while (part->more) {
75  count++;
76  part = part->more;
77  }
78  return count + myArtifacts.size();
79 }
80 
82  auto part = myWrappedItem->more;
83  while (index > 0 && part) {
84  part = part->more;
85  index--;
86  }
87  if (part) {
88  return myResources->wrap(part, this);
89  }
91 }
92 
94  if (myWrappedItem->head) {
95  return -1;
96  }
97  int index = 0;
98  if (myWrappedItem->more) {
99  auto part = myResources->wrap(myWrappedItem->more, this);
100  while (part != child && part) {
101  part = myResources->wrap(part->wrappedItem()->more, this);
102  index++;
103  }
104  if (part) {
105  return index;
106  }
107  }
109 }
110 
111 static bool treasureContains(const treasure *t, const archetype *arch) {
112  while (t) {
113  if (t->item == arch)
114  return true;
115  if (t->name) {
116  auto other = getManager()->treasures()->find(t->name);
117  if (other && treasureContains(other->items, arch))
118  return true;
119  }
120  if (t->next_yes && treasureContains(t->next_yes, arch))
121  return true;
122  if (t->next_no && treasureContains(t->next_no, arch))
123  return true;
124  t = t->next;
125  }
126  return false;
127 }
128 
129 static bool isValidArchFlesh(const archetype *arch, const Face *fleshFace) {
130  if (!arch->clone.randomitems || !fleshFace)
131  return false;
132 
133  std::vector<const archetype *> sources;
134  getManager()->archetypes()->each([&sources, &fleshFace] (const archetype * candidate) {
135  if (candidate->clone.face == fleshFace)
136  sources.push_back(candidate);
137  });
138 
139  for (auto source : sources) {
140  if (treasureContains(arch->clone.randomitems->items, source))
141  return true;
142  }
143 
144  return false;
145 }
146 
147 AssetWrapper::PossibleUse ArchetypeWrapper::uses(const AssetWrapper *asset, std::string &hint) const {
148  auto face = dynamic_cast<const FaceWrapper *>(asset);
149  if (face != nullptr) {
150  auto key = object_get_value(&myWrappedItem->clone, "identified_face");
151  if (face->wrappedItem() == myWrappedItem->clone.face || (key && strcmp(face->wrappedItem()->name, key) == 0)) {
152  return Uses;
153  }
154 
155  auto len = strlen(myWrappedItem->name);
156  if (strncmp(myWrappedItem->name, face->wrappedItem()->name, len) == 0 && face->wrappedItem()->name[len] == '_') {
157  auto flesh = getManager()->faces()->find(face->wrappedItem()->name + len + 1);
158  if (isValidArchFlesh(myWrappedItem, flesh)) {
159  hint = "flesh face";
160  return Uses;
161  }
162  }
163 
164  return ChildrenMayUse;
165  }
166  auto anim = dynamic_cast<const AnimationWrapper *>(asset);
167  if (anim) {
168  auto key = object_get_value(&myWrappedItem->clone, "identified_animation");
169  if (anim->wrappedItem() == myWrappedItem->clone.animation || (key && strcmp(anim->wrappedItem()->name, key) == 0)) {
170  return Uses;
171  }
172  return DoesntUse;
173  }
174  auto tl = dynamic_cast<const TreasureListWrapper *>(asset);
175  if (tl) {
176  return myWrappedItem->clone.randomitems == tl->wrappedItem() ? Uses : DoesntUse;
177  }
178  auto arch = dynamic_cast<const ArchetypeWrapper *>(asset);
179  if (arch) {
180  if (wrappedItem()->clone.other_arch == arch->wrappedItem()) {
181  hint = "other arch";
182  return Uses;
183  }
184  sstring death_anim = NULL;
185  if ((death_anim = object_get_value(&myWrappedItem->clone, "death_animation")) && strcmp(death_anim, arch->wrappedItem()->name) == 0) {
186  hint = "death animation";
187  return Uses;
188  }
189  }
190  auto sound = dynamic_cast<const SoundFile *>(asset);
191  if (sound) {
193  return DoesntUse;
194  }
195  bool uses = std::any_of(sound->events().cbegin(), sound->events().cend(), [this] (const std::string &event) {
196  return event == myWrappedItem->name || event == myWrappedItem->clone.name;
197  });
198  return uses ? Uses : DoesntUse;
199  }
200  return DoesntUse;
201 }
202 
203 void ArchetypeWrapper::drag(QMimeData *data) const {
205 }
206 
208  std::function<bool(const treasure *item)> ci = [&] (const treasure *item) {
209  if (item->item == myWrappedItem) {
210  return true;
211  }
212  if (item->next_yes && ci(item->next_yes)) {
213  return true;
214  }
215  if (item->next_no && ci(item->next_no)) {
216  return true;
217  }
218  if (item->next && ci(item->next)) {
219  return true;
220  }
221  return false;
222  };
223  auto cl = [&] (const treasurelist *item) { return item->items && ci(item->items); };
224  return getManager()->treasures()->first(cl) != nullptr;
225 }
226 
227 QString ArchetypeWrapper::raw() const {
228  return QString::fromStdString(myRaw);
229 }
230 
231 void ArchetypeWrapper::setRaw(const QString &raw) {
232  if (raw.toStdString() != myRaw) {
233  myRaw = raw.toStdString();
234  BufferReader *br = bufferreader_init_from_memory(nullptr, myRaw.data(), myRaw.length());
235 
236  auto origin = myResources->originOf(myWrappedItem);
237  ArchetypeLoader loader(getManager()->archetypes(), nullptr);
238  loader.load(br, origin);
240 
242  }
243 }
MimeUtils::Archetype
static const char * Archetype
Definition: MimeUtils.h:24
AssetTWrapper< archetype >::myWrappedItem
archetype * myWrappedItem
Definition: AssetWrapper.h:104
Face
Definition: face.h:14
MimeUtils::addMime
void addMime(QMimeData *data, const QString &mime, const QString &name)
Definition: MimeUtils.cpp:17
AssetsCollection::first
T * first(std::function< bool(const T *)> op)
Definition: AssetsCollection.h:167
AssetWrapper::AssetUpdated
@ AssetUpdated
Definition: AssetWrapper.h:33
archetype::more
archetype * more
Definition: object.h:484
ArchetypeWrapper::more
QObject more
Definition: ArchetypeWrapper.h:31
ResourcesManager
Definition: ResourcesManager.h:80
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
ArchetypeWrapper::setRaw
void setRaw(const QString &raw)
Definition: ArchetypeWrapper.cpp:231
AssetsManager.h
AnimationWrapper
Definition: AnimationWrapper.h:24
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
ResourcesManager::wrap
ArchetypeWrapper * wrap(archetype *arch, AssetWrapper *parent)
Definition: ResourcesManager.h:131
AssetWithArtifacts< archetype >::setSpecificItem
void setSpecificItem(const object *item, bool notify)
Definition: AssetWithArtifacts.h:61
AssetWrapper::PossibleUse
PossibleUse
Definition: AssetWrapper.h:32
ArchetypeWrapper::myRaw
std::string myRaw
Definition: ArchetypeWrapper.h:59
treasureContains
static bool treasureContains(const treasure *t, const archetype *arch)
Definition: ArchetypeWrapper.cpp:111
ArchetypeWrapper::uses
virtual PossibleUse uses(const AssetWrapper *asset, std::string &) const override
Definition: ArchetypeWrapper.cpp:147
archetype::head
archetype * head
Definition: object.h:483
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
AssetWithArtifacts::child
virtual AssetWrapper * child(int child) override
Definition: AssetWithArtifacts.h:42
SKILL
@ SKILL
Definition: object.h:148
TreasureListWrapper
Definition: TreasureListWrapper.h:27
ArchetypeWrapper::appearsOnTreasureList
bool appearsOnTreasureList() const
Definition: ArchetypeWrapper.cpp:207
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.cpp:4342
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
AssetWrapper::ChildrenMayUse
@ ChildrenMayUse
Definition: AssetWrapper.h:32
AssetsCollection::find
T * find(const Key &name)
Definition: AssetsCollection.h:108
ResourcesManager::originOf
std::string originOf(const archetype *arch) const
Definition: ResourcesManager.h:110
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
ArchetypeWrapper::ArchetypeWrapper
ArchetypeWrapper(AssetWrapper *parent, archetype *arch, ResourcesManager *resourcesManager)
Definition: ArchetypeWrapper.cpp:27
FaceWrapper
Definition: FaceWrapper.h:24
AssetsManager::treasures
Treasures * treasures()
Definition: AssetsManager.h:54
ArchetypeWrapper::wasModified
virtual void wasModified(AssetWrapper *asset, ChangeType type, int extra) override
Definition: ArchetypeWrapper.cpp:47
ArchetypeLoader
Definition: ArchetypeLoader.h:22
ArchetypeWrapper::raw
QString raw
Definition: ArchetypeWrapper.h:32
treasurelist
Definition: treasure.h:85
ArchetypeWrapper::head
QObject head
Definition: ArchetypeWrapper.h:30
archetype::clone
object clone
Definition: object.h:485
AssetWrapper
Definition: AssetWrapper.h:25
object_dump
void object_dump(const object *op, StringBuffer *sb)
Definition: object.cpp:645
ArchetypeLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Definition: ArchetypeLoader.cpp:23
AnimationWrapper.h
object::face
const Face * face
Definition: object.h:341
dump
Definition: quest.cpp:847
AssetWithArtifacts< archetype >::myArtifacts
std::vector< ArtifactWrapper * > myArtifacts
Definition: AssetWithArtifacts.h:59
AssetsManager::faces
Faces * faces()
Definition: AssetsManager.h:39
object::type
uint8_t type
Definition: object.h:348
AssetWrapper::ChangeType
ChangeType
Definition: AssetWrapper.h:33
AssetWithArtifacts< archetype >::myResources
ResourcesManager * myResources
Definition: AssetWithArtifacts.h:58
navar-midane_time.data
data
Definition: navar-midane_time.py:11
ArchetypeWrapper.h
ArchetypeWrapper::clone
QObject clone
Definition: ArchetypeWrapper.h:29
disinfect.count
int count
Definition: disinfect.py:7
FaceWrapper.h
archetype
Definition: object.h:481
AssetWrapper::Uses
@ Uses
Definition: AssetWrapper.h:32
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
ArchetypeWrapper::childrenCount
virtual int childrenCount() const override
Definition: ArchetypeWrapper.cpp:68
animate.anim
string anim
Definition: animate.py:20
AssetTWrapper< archetype >::wrappedItem
archetype * wrappedItem() const
Definition: AssetWrapper.h:101
object::animation
const Animations * animation
Definition: object.h:426
object::other_arch
struct archetype * other_arch
Definition: object.h:423
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
isValidArchFlesh
static bool isValidArchFlesh(const archetype *arch, const Face *fleshFace)
Definition: ArchetypeWrapper.cpp:129
StringBuffer
Definition: stringbuffer.cpp:25
AssetWrapperPanel.h
ResourcesManager::archetypeModified
void archetypeModified(archetype *arch)
Definition: ResourcesManager.cpp:214
AssetWithArtifacts::childIndex
virtual int childIndex(AssetWrapper *child) override
Definition: AssetWithArtifacts.h:48
Floor.t
t
Definition: Floor.py:62
bufferreader_init_from_memory
BufferReader * bufferreader_init_from_memory(BufferReader *br, const char *data, size_t length)
Definition: bufferreader.cpp:93
item
Definition: item.py:1
ArchetypeWrapper
Definition: ArchetypeWrapper.h:25
ArchetypeWrapper::name
QString name
Definition: ArchetypeWrapper.h:28
sstring
const typedef char * sstring
Definition: sstring.h:2
ArchetypeWrapper::childIndex
virtual int childIndex(AssetWrapper *child) override
Definition: ArchetypeWrapper.cpp:93
AssetWrapper::wasModified
virtual void wasModified(AssetWrapper *asset, ChangeType type, int extra)
Definition: AssetWrapper.h:78
TreasureListWrapper.h
SPELL_EFFECT
@ SPELL_EFFECT
Definition: object.h:220
assets.h
npc_dialog.index
int index
Definition: npc_dialog.py:102
SoundFile.h
ArchetypeLoader.h
castle_read.key
key
Definition: castle_read.py:64
MimeUtils.h
object::randomitems
struct treasurelist * randomitems
Definition: object.h:395
AssetWrapper::markModified
void markModified(ChangeType change, int extra=0)
Definition: AssetWrapper.h:55
AssetWithArtifacts
Definition: AssetWithArtifacts.h:26
animate.event
event
DIALOGCHECK MINARGS 1 MAXARGS 2
Definition: animate.py:17
AssetWrapper::DoesntUse
@ DoesntUse
Definition: AssetWrapper.h:32
archetype::name
sstring name
Definition: object.h:482
say.item
dictionary item
Definition: say.py:149
treasure
Definition: treasure.h:63
ArchetypeWrapper::child
virtual AssetWrapper * child(int index) override
Definition: ArchetypeWrapper.cpp:81
SPELL
@ SPELL
Definition: object.h:219
ArchetypeWrapper::drag
virtual void drag(QMimeData *) const override
Definition: ArchetypeWrapper.cpp:203
BufferReader
Definition: bufferreader.cpp:21
SoundFile
Definition: SoundFile.h:19
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25