Crossfire Server, Trunk  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));
63  free_string(t->artifact);
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 }
global.h
Archetypes
All archetypes in the game.
Definition: Archetypes.h:23
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
Definition: bufferreader.cpp:142
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:82
treasurelist::items
treasure * items
Items in this list, linked.
Definition: treasure.h:92
archetypes
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific and settings file datadir Usually usr share crossfire Contains data that the server does not need to modify while such as the archetypes
Definition: server-directories.txt:45
treasurelist::total_chance
int16_t total_chance
If non-zero, only 1 item on this list should be generated.
Definition: treasure.h:87
TreasureLoader::TreasureLoader
TreasureLoader(Treasures *treasures, Archetypes *archetypes, AssetsTracker *tracker)
Definition: TreasureLoader.cpp:23
TreasureLoader.h
get_empty_treasure
treasure * get_empty_treasure(void)
Allocate and return the pointer to an empty treasure structure.
Definition: treasure.cpp:1423
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
buf
StringBuffer * buf
Definition: readable.cpp:1564
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
Treasures
Definition: Treasures.h:21
AssetsTracker
Base class to be informed of where an asset is defined.
Definition: AssetsTracker.h:24
TreasureLoader::loadTreasure
treasure * loadTreasure(BufferReader *reader, const std::string &filename)
Reads one treasure, including the 'yes', 'no' and 'more' options.
Definition: TreasureLoader.cpp:40
TreasureLoader::m_tracker
AssetsTracker * m_tracker
Definition: TreasureLoader.h:38
TreasureLoader::m_treasures
Treasures * m_treasures
Definition: TreasureLoader.h:36
Utils.h
AssetsCollection::define
T * define(const Key &name, T *asset)
Define an asset, erasing an existing one.
Definition: AssetsCollection.h:120
nroftreasures
size_t nroftreasures
Number of treasure items, for malloc info.
Definition: assets.cpp:80
treasurelist
treasurelist represents one logical group of items to be generated together.
Definition: treasure.h:85
add_string
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
treasurelist::name
sstring name
Usually monster-name/combination.
Definition: treasure.h:86
compat.h
TreasureLoader::m_archetypes
Archetypes * m_archetypes
Definition: TreasureLoader.h:37
AssetsTracker::assetDefined
virtual void assetDefined(const archetype *asset, const std::string &filename)
Function called when an asset is defined in a file.
Definition: AssetsTracker.h:32
t
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn t
Definition: server-directories.txt:27
AssetsTracker.h
AssetsCollection::get
T * get(const Key &name)
Get a named asset.
Definition: AssetsCollection.h:89
Treasures.h
fatal
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:595
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
free_string
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
Archetypes.h
treasure
treasure is one element in a linked list, which together consist of a complete treasure-list.
Definition: treasure.h:63
BufferReader
Definition: bufferreader.cpp:22
TreasureLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Load all treasures from a buffer.
Definition: TreasureLoader.cpp:111
variable
*envar *is the environment variable
Definition: server-directories.txt:9
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:104