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, "nrof_rolls %d", &value))
88  t->nrof_rolls = (uint16_t)value;
89  else if (sscanf(cp, "magic %d", &value))
90  t->magic = (uint8_t)value;
91  else if (!strcmp(cp, "yes"))
92  t->next_yes = loadTreasure(reader, filename);
93  else if (!strcmp(cp, "no"))
94  t->next_no = loadTreasure(reader, filename);
95  else if (!strcmp(cp, "end"))
96  return t;
97  else if (!strcmp(cp, "more")) {
98  t->next = loadTreasure(reader, filename);
99  return t;
100  } else
101  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));
102  }
103  LOG(llevError, "treasure lacks 'end' in %s at line %zu.\n", filename.c_str(), bufferreader_current_line(reader));
105  return t;
106 }
107 
113 void TreasureLoader::load(BufferReader *reader, const std::string& filename) {
114  char *buf, name[MAX_BUF];
115  treasure *t;
116 
117  while ((buf = bufferreader_next_line(reader)) != NULL) {
118  if (*buf == '#' || *buf == '\0')
119  continue;
120 
121  if (sscanf(buf, "treasureone %s", name) || sscanf(buf, "treasure %s", name)) {
122  treasurelist *tl = (treasurelist *)calloc(1, sizeof(treasurelist));
123  tl->name = add_string(name);
124  tl->items = loadTreasure(reader, filename);
125 
126  /* This is a one of the many items on the list should be generated.
127  * Add up the chance total, and check to make sure the yes & no
128  * fields of the treasures are not being used.
129  */
130  if (!strncmp(buf, "treasureone", 11)) {
131  for (t = tl->items; t != NULL; t = t->next) {
132  if (t->next_yes || t->next_no) {
133  LOG(llevError, "Treasure %s is one item, but on treasure %s\n", tl->name, t->item ? t->item->name : t->name);
134  LOG(llevError, " the next_yes or next_no field is set\n");
135  }
136  tl->total_chance += t->chance;
137  }
138  }
139 
140  tl = m_treasures->define(tl->name, tl);
141  if (m_tracker) {
142  m_tracker->assetDefined(tl, filename);
143  }
144  } else
145  LOG(llevError, "Treasure-list didn't understand: %s in %s:%zu\n", buf, filename.c_str(), bufferreader_current_line(reader));
146  }
147 }
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:148
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:93
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:88
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:1434
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:86
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:87
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:113
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:110