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