Crossfire Server, Trunk  1.75.0
FaceLoader.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 "FaceLoader.h"
14 #include "Faces.h"
15 #include "Animations.h"
16 #include "AssetsTracker.h"
17 
18 #include "global.h"
19 #include "compat.h"
20 #include "string.h"
21 
23  : m_faces(faces), m_animations(animations), m_tracker(tracker)
24 {
25 }
26 
27 void FaceLoader::loadAnimationBlock(BufferReader *reader, const std::string &full_path, const char *animation_name) {
28  char *buf;
29  int num_frames = 0, i;
30  const Face *faces[MAX_ANIMATIONS];
31  Animations *anim;
32 
33  anim = static_cast<Animations *>(calloc(1, sizeof(Animations)));
34  anim->name = add_string(animation_name);
35  anim->faces = NULL;
36  anim->facings = 1;
37  anim->num_animations = 0;
38 
39  while ((buf = bufferreader_next_line(reader)) != NULL) {
40  if (*buf == '#')
41  continue;
42  if (strlen(buf) == 0)
43  continue;
44 
45  if (!strncmp(buf, "mina", 4)) {
46  anim->faces = static_cast<const Face **>(malloc(sizeof(Face*)*num_frames));
47  for (i = 0; i < num_frames; i++)
48  anim->faces[i] = faces[i];
49  anim->num_animations = num_frames;
50  if (num_frames <= 1) {
51  LOG(llevDebug, "anim: %s has less then two faces in %s\n",
52  anim->name, full_path.c_str());
53  }
54  if (num_frames % anim->facings) {
55  LOG(llevDebug, "anim: %s has %d frames: not a multiple of facings (%d) in %s\n",
56  anim->name, num_frames,
57  anim->facings, full_path.c_str());
58  }
59  m_animations->define(anim->name, anim);
60  if (m_tracker) {
61  m_tracker->assetDefined(anim, full_path);
62  }
63  return;
64  } else if (!strncmp(buf, "facings", 7)) {
65  if (!(anim->facings = atoi(buf+7))) {
66  LOG(llevDebug, "anim: %s has 0 facings in %s (line %s)\n",
67  anim->name, full_path.c_str(), buf);
68  anim->facings = 1;
69  }
70  } else {
71  const Face *face = find_face(buf);
72  faces[num_frames++] = face;
73  }
74  }
75 }
76 
77 void FaceLoader::load(BufferReader *buffer, const std::string& filename) {
78  char *buf, *cp;
79  Face *on_face = NULL;
80 
81  while ((buf = bufferreader_next_line(buffer)) != NULL) {
82  if (*buf == '#' || *buf == '\0')
83  continue;
84  if (!strncmp(buf, "end", 3)) {
85  if (on_face) {
86  on_face = m_faces->define(on_face->name, on_face);
87  if (m_tracker) {
88  m_tracker->assetDefined(on_face, filename);
89  }
90  on_face = NULL;
91  }
92  continue;
93  }
94 
95  if (!strncmp(buf, "smoothface ", 11)) {
96  if (on_face) {
97  on_face->smoothface = m_faces->get(buf + 11);
98  } else {
99  char *space = strchr(buf + 11, ' ');
100  if (!space) {
101  LOG(llevError, "Invalid 'smoothface' %s in %s\n", buf, filename.c_str());
102  } else {
103  (*space) = '\0';
104  space++;
105  auto original = m_faces->get(buf + 11);
106  auto smoothed = m_faces->get(space);
107  original->smoothface = smoothed;
108  }
109  }
110  continue;
111  }
112 
113  if (!strncmp(buf, "face ", 5)) {
114  cp = buf+5;
115 
116  if (on_face) {
117  LOG(llevError, "'face' within a 'face' in %s\n", filename.c_str());
118  if (on_face->name) {
119  free_string(on_face->name);
120  }
121  free(on_face);
122  }
123  on_face = static_cast<Face *>(calloc(1, sizeof(Face)));
124  on_face->name = add_string(cp);
125  on_face->visibility = 0;
126  on_face->magicmap = 0;
127  continue;
128  }
129 
130  if (!strncmp(buf, "animation ", 10)) {
131  if (on_face)
132  LOG(llevError, "faces: 'animation' in 'face' block is deprecated in %s\n", filename.c_str());
133  loadAnimationBlock(buffer, filename, buf + 10);
134  continue;
135  }
136 
137  if (on_face == NULL) {
138  LOG(llevError, "faces: got line with no face set in %s: %s\n", filename.c_str(), buf);
139  } else if (!strncmp(buf, "visibility", 10)) {
140  on_face->visibility = atoi(buf+11);
141  } else if (!strncmp(buf, "magicmap", 8)) {
142  cp = buf+9;
143  on_face->magicmap = find_color(cp) | (on_face->magicmap & FACE_FLOOR);
144  } else if (!strncmp(buf, "is_floor", 8)) {
145  int value = atoi(buf+9);
146  if (value)
147  on_face->magicmap |= FACE_FLOOR;
148  } else
149  LOG(llevError, "faces: unknown line in file %s: %s\n", filename.c_str(), buf);
150  }
151 
152  if (on_face) {
153  LOG(llevError, "unfinished face in %s\n", filename.c_str());
154  if (on_face->name) {
155  free_string(on_face->name);
156  }
157  free(on_face);
158  }
159 }
Face::name
sstring name
Face name, as used by archetypes and such.
Definition: face.h:19
Face
New face structure - this enforces the notion that data is face by face only - you can not change the...
Definition: face.h:14
Face::smoothface
Face * smoothface
Smoothed face for this, NULL for none.
Definition: face.h:18
FaceLoader::FaceLoader
FaceLoader(Faces *faces, AllAnimations *animations, AssetsTracker *tracker)
Definition: FaceLoader.cpp:22
global.h
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
if
if(!(yy_init))
Definition: loader.cpp:36428
FaceLoader::loadAnimationBlock
void loadAnimationBlock(BufferReader *reader, const std::string &full_path, const char *animation_name)
Definition: FaceLoader.cpp:27
FaceLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Load assets from the specified reader.
Definition: FaceLoader.cpp:77
find_face
const Face * find_face(const char *name)
Definition: assets.cpp:281
buf
StringBuffer * buf
Definition: readable.cpp:1565
AssetsTracker
Base class to be informed of where an asset is defined.
Definition: AssetsTracker.h:24
AssetsCollection::define
T * define(const Key &name, T *asset)
Define an asset, erasing an existing one.
Definition: AssetsCollection.h:120
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
compat.h
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
Animations::facings
uint8_t facings
How many facings (1,2,4,8).
Definition: face.h:28
FACE_FLOOR
#define FACE_FLOOR
Definition: newclient.h:306
AssetsTracker.h
AssetsCollection::get
T * get(const Key &name)
Get a named asset.
Definition: AssetsCollection.h:89
Animations::num_animations
uint8_t num_animations
How many different faces to animate, size of the faces array.
Definition: face.h:27
Faces
Definition: Faces.h:19
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:280
FaceLoader::m_tracker
AssetsTracker * m_tracker
Definition: FaceLoader.h:36
AllAnimations
Definition: Animations.h:19
Animations::faces
const Face ** faces
The actual faces for the animation.
Definition: face.h:30
Face::visibility
uint8_t visibility
How visible is the face compared to other faces, highest wins.
Definition: face.h:16
Faces.h
Animations
This represents one animation.
Definition: face.h:25
find_color
uint8_t find_color(const char *name)
Finds a color by name.
Definition: image.cpp:75
Animations.h
buffer
if you malloc the data for the buffer
Definition: protocol.txt:2100
Face::magicmap
uint8_t magicmap
Color to show this in magic map.
Definition: face.h:17
FaceLoader.h
MAX_ANIMATIONS
#define MAX_ANIMATIONS
Definition: define.h:39
FaceLoader::m_animations
AllAnimations * m_animations
Definition: FaceLoader.h:35
FaceLoader::m_faces
Faces * m_faces
Definition: FaceLoader.h:34
BufferReader
Definition: bufferreader.cpp:21
Animations::name
sstring name
Name of the animation sequence.
Definition: face.h:26
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
face
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 etc A default install will pack the and treasurelist definitions into a single or trs file and the graphics into a face(metadata) and .tar(bitmaps) file
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:102