Crossfire Server, Trunk
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 
17 extern "C" {
18 #include "global.h"
19 #include "compat.h"
20 #include "string.h"
21 }
22 
24  : m_faces(faces), m_animations(animations)
25 {
26 }
27 
28 void FaceLoader::loadAnimationBlock(BufferReader *reader, const std::string &full_path, const char *animation_name) {
29  char *buf;
30  int num_frames = 0, i;
31  const Face *faces[MAX_ANIMATIONS];
33 
34  anim = static_cast<Animations *>(calloc(1, sizeof(Animations)));
35  anim->name = add_string(animation_name);
36  anim->faces = NULL;
37  anim->facings = 1;
38  anim->num_animations = 0;
39 
40  while ((buf = bufferreader_next_line(reader)) != NULL) {
41  if (*buf == '#')
42  continue;
43  if (strlen(buf) == 0)
44  continue;
45 
46  if (!strncmp(buf, "mina", 4)) {
47  anim->faces = static_cast<const Face **>(malloc(sizeof(Face*)*num_frames));
48  for (i = 0; i < num_frames; i++)
49  anim->faces[i] = faces[i];
50  anim->num_animations = num_frames;
51  if (num_frames <= 1) {
52  LOG(llevDebug, "anim: %s has less then two faces in %s\n",
53  anim->name, full_path.c_str());
54  }
55  if (num_frames % anim->facings) {
56  LOG(llevDebug, "anim: %s has %d frames: not a multiple of facings (%d) in %s\n",
57  anim->name, num_frames,
58  anim->facings, full_path.c_str());
59  }
60  m_animations->define(anim->name, anim);
61  return;
62  } else if (!strncmp(buf, "facings", 7)) {
63  if (!(anim->facings = atoi(buf+7))) {
64  LOG(llevDebug, "anim: %s has 0 facings in %s (line %s)\n",
65  anim->name, full_path.c_str(), buf);
66  anim->facings = 1;
67  }
68  } else {
69  const Face *face = find_face(buf);
70  faces[num_frames++] = face;
71  }
72  }
73 }
74 
75 void FaceLoader::load(BufferReader *buffer, const std::string& filename) {
76  char *buf, *cp;
77  Face *on_face = NULL;
78 
79  while ((buf = bufferreader_next_line(buffer)) != NULL) {
80  if (*buf == '#' || *buf == '\0')
81  continue;
82  if (!strncmp(buf, "end", 3)) {
83  if (on_face) {
84  m_faces->define(on_face->name, on_face);
85  on_face = NULL;
86  }
87  continue;
88  }
89 
90  if (!strncmp(buf, "smoothface ", 11)) {
91  if (on_face) {
92  on_face->smoothface = m_faces->get(buf + 11);
93  } else {
94  char *space = strchr(buf + 11, ' ');
95  if (!space) {
96  LOG(llevError, "Invalid 'smoothface' %s in %s\n", buf, filename.c_str());
97  } else {
98  (*space) = '\0';
99  space++;
100  auto original = m_faces->get(buf + 11);
101  auto smoothed = m_faces->get(space);
102  original->smoothface = smoothed;
103  }
104  }
105  continue;
106  }
107 
108  if (!strncmp(buf, "face ", 5)) {
109  cp = buf+5;
110 
111  if (on_face) {
112  LOG(llevError, "'face' within a 'face' in %s\n", filename.c_str());
113  if (on_face->name) {
114  free_string(on_face->name);
115  }
116  free(on_face);
117  }
118  on_face = static_cast<Face *>(calloc(1, sizeof(Face)));
119  on_face->name = add_string(cp);
120  on_face->visibility = 0;
121  on_face->magicmap = 0;
122  continue;
123  }
124 
125  if (!strncmp(buf, "animation ", 10)) {
126  loadAnimationBlock(buffer, filename, buf + 10);
127  continue;
128  }
129 
130  if (on_face == NULL) {
131  LOG(llevError, "faces: got line with no face set in %s: %s\n", filename.c_str(), buf);
132  } else if (!strncmp(buf, "visibility", 10)) {
133  on_face->visibility = atoi(buf+11);
134  } else if (!strncmp(buf, "magicmap", 8)) {
135  cp = buf+9;
136  on_face->magicmap = find_color(cp) | (on_face->magicmap & FACE_FLOOR);
137  } else if (!strncmp(buf, "is_floor", 8)) {
138  int value = atoi(buf+9);
139  if (value)
140  on_face->magicmap |= FACE_FLOOR;
141  } else
142  LOG(llevDebug, "faces: unknown line in file %s: %s\n", filename.c_str(), buf);
143  }
144 
145  if (on_face) {
146  LOG(llevError, "unfinished face in %s\n", filename.c_str());
147  if (on_face->name) {
148  free_string(on_face->name);
149  }
150  free(on_face);
151  }
152 }
FaceLoader::FaceLoader
FaceLoader(Faces *faces, AllAnimations *animations)
Definition: FaceLoader.cpp:23
Face::name
sstring name
Definition: face.h:19
Face
Definition: face.h:14
global.h
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
llevError
@ llevError
Definition: logger.h:11
FaceLoader::loadAnimationBlock
void loadAnimationBlock(BufferReader *reader, const std::string &full_path, const char *animation_name)
Definition: FaceLoader.cpp:28
FaceLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Definition: FaceLoader.cpp:75
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.c:102
npc_dialog.filename
filename
Definition: npc_dialog.py:99
find_face
const Face * find_face(const char *name)
Definition: assets.cpp:302
free_string
void free_string(sstring str)
Definition: shstr.c:280
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:97
dragon_attune.animations
dictionary animations
Definition: dragon_attune.py:25
compat.h
FACE_FLOOR
#define FACE_FLOOR
Definition: newclient.h:303
Face::smoothface
struct Face * smoothface
Definition: face.h:18
AssetsCollection::get
T * get(const Key &name)
Definition: AssetsCollection.h:66
animate.anim
string anim
Definition: animate.py:20
Faces
Definition: Faces.h:21
animations_struct
Definition: face.h:25
AllAnimations
Definition: Animations.h:22
find_color
uint8_t find_color(const char *name)
Definition: image.c:74
Face::visibility
uint8_t visibility
Definition: face.h:16
Faces.h
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
autojail.value
value
Definition: autojail.py:6
Animations.h
Face::magicmap
uint8_t magicmap
Definition: face.h:17
buf
StringBuffer * buf
Definition: readable.c:1606
dragon_attune.faces
dictionary faces
Definition: dragon_attune.py:31
FaceLoader.h
MAX_ANIMATIONS
#define MAX_ANIMATIONS
Definition: define.h:39
FaceLoader::m_animations
AllAnimations * m_animations
Definition: FaceLoader.h:34
FaceLoader::m_faces
Faces * m_faces
Definition: FaceLoader.h:33
BufferReader
Definition: bufferreader.c:21
if
if(!(yy_init))
Definition: loader.c:2589
llevDebug
@ llevDebug
Definition: logger.h:13