Crossfire Server  1.75.0
TreasureLoader.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 "TreasureLoader.h"
14 #include "Archetypes.h"
15 #include "Treasures.h"
16 #include "Utils.h"
17 #include "AssetsTracker.h"
18 
19 #include "string.h"
20 #include "global.h"
21 #include "compat.h"
22 
24  : m_treasures(treasures), m_archetypes(archetypes), m_tracker(tracker) {
25 }
26 
27 extern size_t nroftreasures;
28 
40 treasure *TreasureLoader::loadTreasure(BufferReader *reader, const std::string &filename) {
41  char *buf, *cp, variable[MAX_BUF];
43  int value;
44 
45  nroftreasures++;
46  while ((buf = bufferreader_next_line(reader)) != NULL) {
47 
48  if (*buf == '#')
49  continue;
50  cp = buf;
51  while (isspace(*cp)) /* Skip blanks */
52  cp++;
53 
54  if (sscanf(cp, "arch %s", variable)) {
55  if (t->item) {
56  LOG(llevError, "treasure: duplicate 'arch' in %s:%zu\n", filename.c_str(), bufferreader_current_line(reader));
57  }
58  t->item = m_archetypes->get(variable);
59  // artifact fields can have one or more words in them, so sscanf does not work.
60  } else if (strncmp(cp, "artifact ", 9) == 0) {
61  if (t->artifact) {
62  LOG(llevError, "treasure: duplicate 'artifact' in %s:%zu\n", filename.c_str(), bufferreader_current_line(reader));
64  }
65  // Take all the way to the newline
66  t->artifact = add_string(cp+9);
67  } else if (sscanf(cp, "list_magic_value %d", &value)) {
68  t->list_magic_value = (uint8_t)value;
69  } else if (sscanf(cp, "list_magic_adjustment %d", &value)) {
70  t->list_magic_adjustment = (int8_t)value;
71  } else if (sscanf(cp, "list %s", variable)) {
72  if (t->name) {
73  LOG(llevError, "treasure: duplicate 'name' in %s:%zu\n", filename.c_str(), bufferreader_current_line(reader));
74  free_string(t->name);
75  }
76  t->name = add_string(variable);
77  } else if (sscanf(cp, "change_name %s", variable))
78  t->change_arch.name = add_string(variable);
79  else if (sscanf(cp, "change_title %s", variable))
80  t->change_arch.title = add_string(variable);
81  else if (sscanf(cp, "change_slaying %s", variable))
82  t->change_arch.slaying = add_string(variable);
83  else if (sscanf(cp, "chance %d", &value))
84  t->chance = (uint8_t)value;
85  else if (sscanf(cp, "nrof %d", &value))
86  t->nrof = (uint16_t)value;
87  else if (sscanf(cp, "magic %d", &value))
88  t->magic = (uint8_t)value;
89  else if (!strcmp(cp, "yes"))
90  t->next_yes = loadTreasure(reader, filename);
91  else if (!strcmp(cp, "no"))
92  t->next_no = loadTreasure(reader, filename);
93  else if (!strcmp(cp, "end"))
94  return t;
95  else if (!strcmp(cp, "more")) {
96  t->next = loadTreasure(reader, filename);
97  return t;
98  } else
99  LOG(llevError, "Unknown treasure-command: '%s', last entry %s in %s:%zu\n", cp, t->name ? t->name : "null", filename.c_str(), bufferreader_current_line(reader));
100  }
101  LOG(llevError, "treasure lacks 'end' in %s at line %zu.\n", filename.c_str(), bufferreader_current_line(reader));
103  return t;
104 }
105 
111 void TreasureLoader::load(BufferReader *reader, const std::string& filename) {
112  char *buf, name[MAX_BUF];
113  treasure *t;
114 
115  while ((buf = bufferreader_next_line(reader)) != NULL) {
116  if (*buf == '#' || *buf == '\0')
117  continue;
118 
119  if (sscanf(buf, "treasureone %s", name) || sscanf(buf, "treasure %s", name)) {
120  treasurelist *tl = (treasurelist *)calloc(1, sizeof(treasurelist));
121  tl->name = add_string(name);
122  tl->items = loadTreasure(reader, filename);
123 
124  /* This is a one of the many items on the list should be generated.
125  * Add up the chance total, and check to make sure the yes & no
126  * fields of the treasures are not being used.
127  */
128  if (!strncmp(buf, "treasureone", 11)) {
129  for (t = tl->items; t != NULL; t = t->next) {
130  if (t->next_yes || t->next_no) {
131  LOG(llevError, "Treasure %s is one item, but on treasure %s\n", tl->name, t->item ? t->item->name : t->name);
132  LOG(llevError, " the next_yes or next_no field is set\n");
133  }
134  tl->total_chance += t->chance;
135  }
136  }
137 
138  tl = m_treasures->define(tl->name, tl);
139  if (m_tracker) {
140  m_tracker->assetDefined(tl, filename);
141  }
142  } else
143  LOG(llevError, "Treasure-list didn't understand: %s in %s:%zu\n", buf, filename.c_str(), bufferreader_current_line(reader));
144  }
145 }
Error, serious thing.
Definition: logger.h:11
T * get(const Key &name)
Get a named asset.
const char * name
If != NULL, copy this over the original arch name.
Definition: treasure.h:52
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
sstring name
If non null, name of list to use instead.
Definition: treasure.h:66
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
int8_t list_magic_adjustment
Adjust difficulty when generating the list pointed by name, ignored if list_magic_value is non zero...
Definition: treasure.h:67
All archetypes in the game.
Definition: Archetypes.h:23
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
treasure * loadTreasure(BufferReader *reader, const std::string &filename)
Reads one treasure, including the &#39;yes&#39;, &#39;no&#39; and &#39;more&#39; options.
Global type definitions and header inclusions.
TreasureLoader(Treasures *treasures, Archetypes *archetypes, AssetsTracker *tracker)
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
AssetsTracker * m_tracker
sstring name
More definite name, like "generate_kobold".
Definition: object.h:484
size_t nroftreasures
Number of treasure items, for malloc info.
Definition: assets.cpp:80
uint8_t chance
Percent chance for this item.
Definition: treasure.h:73
Base class to be informed of where an asset is defined.
Definition: AssetsTracker.h:24
const char * title
If != NULL, copy this over the original arch title.
Definition: treasure.h:53
Treasures * m_treasures
int16_t total_chance
If non-zero, only 1 item on this list should be generated.
Definition: treasure.h:87
Archetypes * m_archetypes
treasure * next_no
If this item was not generated, then continue here.
Definition: treasure.h:71
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
Compatibility implementations of useful nonstandard types and functions.
treasurelist represents one logical group of items to be generated together.
Definition: treasure.h:85
treasure * next_yes
If this item was generated, use this link instead of ->next.
Definition: treasure.h:70
virtual void assetDefined(const archetype *asset, const std::string &filename)
Function called when an asset is defined in a file.
Definition: AssetsTracker.h:32
sstring artifact
If not null, the name of the artifact to apply to item.
Definition: treasure.h:65
virtual void load(BufferReader *reader, const std::string &filename) override
Load all treasures from a buffer.
treasure * next
Next treasure-item in a linked list.
Definition: treasure.h:69
struct _change_arch change_arch
Override default arch values if set in treasure list.
Definition: treasure.h:72
sstring name
Usually monster-name/combination.
Definition: treasure.h:86
treasure * items
Items in this list, linked.
Definition: treasure.h:92
uint8_t list_magic_value
Set difficulty when generating the list pointed by name.
Definition: treasure.h:68
uint16_t nrof
Random 1 to nrof items are generated.
Definition: treasure.h:79
treasure * get_empty_treasure(void)
Allocate and return the pointer to an empty treasure structure.
Definition: treasure.cpp:1420
treasure is one element in a linked list, which together consist of a complete treasure-list.
Definition: treasure.h:63
const char * slaying
If != NULL, copy this over the original arch slaying.
Definition: treasure.h:54
uint8_t magic
Max magic bonus to item If the entry is a list transition, &#39;magic&#39; contains the difficulty required t...
Definition: treasure.h:74
StringBuffer * buf
Definition: readable.cpp:1563
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
struct archetype * item
Which item this link can be.
Definition: treasure.h:64
T * define(const Key &name, T *asset)
Define an asset, erasing an existing one.