Crossfire Server  1.75.0
Archetypes.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2020 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 "Archetypes.h"
14 
15 #include <string.h>
16 
17 template<>
18 archetype *asset_create(const std::string& name) {
19  auto arch = get_archetype_struct();
20  CLEAR_FLAG(&arch->clone, FLAG_REMOVED);
21  arch->name = add_string(name.c_str());
22  return arch;
23 }
24 
25 template<>
26 void asset_destroy(archetype *item) {
28  free_arch(item);
29 }
30 
31 void Archetypes::recursive_update(object *item, archetype *updated) {
32  if (!item)
33  return;
34  if (item->arch->name == updated->name) {
36  auto diff = stringbuffer_new();
37  get_ob_diff(diff, item, &item->arch->clone);
38  auto arch = item->arch;
39  object_copy_with_inv(&updated->clone, item, false);
40  item->arch = arch;
41  auto finished = stringbuffer_finish(diff);
42  set_variable(item, finished);
43  free(finished);
44  }
45  recursive_update(item->below, updated);
46  recursive_update(item->inv, updated);
47 }
48 
53 static void mark_inv_not_removed(object *item) {
54  auto inv = item->inv;
55  while (inv) {
58  inv = inv->below;
59  }
60 }
61 
62 void Archetypes::replace(archetype *existing, archetype *update) {
63  for (auto &arch : m_assets) {
64  recursive_update(arch.second->clone.inv, update);
65  }
66  if (m_updateListener) {
67  m_updateListener(existing, update);
68  }
69 
70  // We need to mark items as not removed before calling object_free_inventory().
71  // The flag is set at object initialisation but never cleared since an
72  // archetype's object is never inserted anywhere.
73  mark_inv_not_removed(&existing->clone);
74  object_free_inventory(&existing->clone);
75  object_copy_with_inv(&update->clone, &existing->clone, false);
76  existing->clone.arch = existing;
77  mark_inv_not_removed(&update->clone);
78  object_free_inventory(&update->clone);
79  free_arch(update);
80 }
81 
83  if (name == NULL)
84  return (archetype *)NULL;
85  auto tmp = find_string(name);
86  if (!tmp)
87  return NULL;
88 
89  for (auto arch : m_assets) {
90  if (arch.second->clone.name == tmp) {
91  return arch.second;
92  }
93  }
94  return NULL;
95 }
96 
97 archetype *Archetypes::findByObjectTypeName(int type, const char *name) {
98  if (name == NULL)
99  return NULL;
100 
101  for (auto arch : m_assets) {
102  if (arch.second->clone.type == type && strcmp(arch.second->clone.name, name) == 0)
103  return arch.second;
104  }
105 
106  return NULL;
107 }
108 
109 archetype *Archetypes::findBySkillNameAndType(const char *skill, int type) {
110  if (skill == NULL)
111  return NULL;
112 
113  for (auto arch : m_assets) {
114  if (((type == -1) || (type == arch.second->clone.type))
115  && (arch.second->clone.skill) && (!strcmp(arch.second->clone.skill, skill)))
116  return arch.second;
117  }
118  return NULL;
119 }
120 
121 archetype *Archetypes::findByTypeSubtype(int type, int subtype) {
122  for (auto arch : m_assets) {
123  if (((type == -1) || (type == arch.second->clone.type))
124  && (subtype == -1 || subtype == arch.second->clone.subtype))
125  return arch.second;
126  }
127  return NULL;
128 }
static void recursive_update(object *item, archetype *updated)
Update if needed item based on the updated archetype, then recurse on item->below and item->inv...
Definition: Archetypes.cpp:31
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
archetype * findBySkillNameAndType(const char *skill, int type)
Retrieve an archetype by skill name and type.
Definition: Archetypes.cpp:109
void asset_destroy(archetype *item)
Definition: Archetypes.cpp:26
object * below
Pointer to the object stacked below this one.
Definition: object.h:295
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
archetype * findByObjectName(const char *name)
Retrieve an archetype given the name that appears during the game (for example, "writing pen" instead...
Definition: Archetypes.cpp:82
sstring find_string(const char *str)
Searches a string in the shared strings.
Definition: shstr.cpp:250
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
std::unordered_map< std::string, archetype *> m_assets
Known assets.
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:219
virtual void replace(archetype *existing, archetype *update) override
Replace an asset by an updated version.
Definition: Archetypes.cpp:62
int set_variable(object *op, const char *buf)
updateListener m_updateListener
Definition: Archetypes.h:116
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:483
archetype * findByObjectTypeName(int type, const char *name)
Retrieve an archetype by type and name that appears during the game.
Definition: Archetypes.cpp:97
sstring name
More definite name, like "generate_kobold".
Definition: object.h:484
void object_free_inventory(object *ob)
Frees the inventory of an object, without any callback.
Definition: object.cpp:1553
static void mark_inv_not_removed(object *item)
Recursively mark all items in inventory as not removed.
Definition: Archetypes.cpp:53
archetype * asset_create(const std::string &name)
Definition: Archetypes.cpp:18
void object_copy_with_inv(const object *src_ob, object *dest_ob, bool update_speed)
Copy an object with an inventory, duplicate the inv too.
Definition: object.cpp:1193
archetype * get_archetype_struct(void)
Allocates, initialises and returns the pointer to an archetype structure.
Definition: arch.cpp:193
#define CLEAR_FLAG(xyz, p)
Definition: define.h:385
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Returns a pointer to a static string which contains all variables which are different in the two give...
Definition: object.cpp:4971
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
void free_arch(archetype *at)
Frees archetype.
Definition: arch.cpp:167
archetype * findByTypeSubtype(int type, int subtype)
Retrieve an archetype by type and subtype.
Definition: Archetypes.cpp:121
object clone
An object from which to do object_copy()
Definition: object.h:487