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 #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];
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  loadAnimationBlock(buffer, filename, buf + 10);
132  continue;
133  }
134 
135  if (on_face == NULL) {
136  LOG(llevError, "faces: got line with no face set in %s: %s\n", filename.c_str(), buf);
137  } else if (!strncmp(buf, "visibility", 10)) {
138  on_face->visibility = atoi(buf+11);
139  } else if (!strncmp(buf, "magicmap", 8)) {
140  cp = buf+9;
141  on_face->magicmap = find_color(cp) | (on_face->magicmap & FACE_FLOOR);
142  } else if (!strncmp(buf, "is_floor", 8)) {
143  int value = atoi(buf+9);
144  if (value)
145  on_face->magicmap |= FACE_FLOOR;
146  } else
147  LOG(llevError, "faces: unknown line in file %s: %s\n", filename.c_str(), buf);
148  }
149 
150  if (on_face) {
151  LOG(llevError, "unfinished face in %s\n", filename.c_str());
152  if (on_face->name) {
153  free_string(on_face->name);
154  }
155  free(on_face);
156  }
157 }
Face::name
sstring name
Definition: face.h:19
Face
Definition: face.h:14
Face::smoothface
Face * smoothface
Definition: face.h:18
FaceLoader::FaceLoader
FaceLoader(Faces *faces, AllAnimations *animations, AssetsTracker *tracker)
Definition: FaceLoader.cpp:22
global.h
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
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
Definition: FaceLoader.cpp:77
npc_dialog.filename
filename
Definition: npc_dialog.py:99
find_face
const Face * find_face(const char *name)
Definition: assets.cpp:282
buf
StringBuffer * buf
Definition: readable.cpp:1565
AssetsTracker
Definition: AssetsTracker.h:26
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:120
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
dragon_attune.animations
dictionary animations
Definition: dragon_attune.py:25
compat.h
AssetsTracker::assetDefined
virtual void assetDefined(const archetype *asset, const std::string &filename)
Definition: AssetsTracker.h:34
FACE_FLOOR
#define FACE_FLOOR
Definition: newclient.h:292
AssetsTracker.h
AssetsCollection::get
T * get(const Key &name)
Definition: AssetsCollection.h:89
animate.anim
string anim
Definition: animate.py:20
Faces
Definition: Faces.h:19
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
FaceLoader::m_tracker
AssetsTracker * m_tracker
Definition: FaceLoader.h:36
AllAnimations
Definition: Animations.h:19
Face::visibility
uint8_t visibility
Definition: face.h:16
Faces.h
Animations
Definition: face.h:25
autojail.value
value
Definition: autojail.py:6
find_color
uint8_t find_color(const char *name)
Definition: image.cpp:75
Animations.h
Face::magicmap
uint8_t magicmap
Definition: face.h:17
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:35
FaceLoader::m_faces
Faces * m_faces
Definition: FaceLoader.h:34
BufferReader
Definition: bufferreader.cpp:21
llevDebug
@ llevDebug
Definition: logger.h:13
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102