1 /** 2 * Copyright © Novelate 2020 3 * License: MIT (https://github.com/Novelate/NovelateEngine/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 * Website: https://novelate.com/ 6 * ------ 7 * Novelate is a free and open-source visual novel engine and framework written in the D programming language. 8 * It can be used freely for both personal and commercial projects. 9 * ------ 10 * Module Description: 11 * This module handles everything that has to do with the core of characters within a novel. 12 */ 13 module novelate.character; 14 15 import std.array : split; 16 import std.path : baseName; 17 import std.conv : to; 18 19 /// A character. 20 final class NovelateCharacter 21 { 22 private: 23 /// The name. 24 string _name; 25 /// The alias name. Used internally if ex. display name has special characters, making it easier to retrieve/update etc. from code. 26 string _aliasName; 27 /// The name color. 28 string _nameColor; 29 /// The about information. 30 string _about; 31 /// The about image. 32 string _aboutImage; 33 /// The image collection of the character. 34 NovelateCharacterImageCollection[string] _graphics; 35 36 public: 37 final: 38 /** 39 * Creates a new character. 40 * Params: 41 * name = The name of the character. 42 */ 43 this(string name) 44 { 45 _name = name; 46 _aliasName = _name; 47 } 48 49 @property 50 { 51 /// Gets the name of the character. 52 string name() { return _name; } 53 54 /// Gets the alias name of the character. Used internally if ex. display name has special characters, making it easier to retrieve/update etc. from code. 55 string aliasName() { return _aliasName; } 56 57 /// Gets the name color of the character. 58 string nameColor() { return _nameColor; } 59 60 /// Gets the about information of the character. 61 string about() { return _about; } 62 63 /// Gets the about image of the character. 64 string aboutImage() { return _aboutImage; } 65 } 66 67 /** 68 * Gets an image from the character's internal image collection. 69 * Params: 70 * entry = The entry of the image ex. "Casual.Smiling" 71 * width = The relative width to retrieve from. This can be 800, 1024 or 1280. 72 * Returns: 73 * The path of the image retrieved. 74 */ 75 string getImage(string entry, size_t width) 76 { 77 if (!_graphics) 78 { 79 return null; 80 } 81 82 auto data = entry.split("."); 83 84 if (data.length != 2) 85 { 86 return null; 87 } 88 89 auto collection = _graphics.get(data[0], null); 90 91 if (!collection) 92 { 93 return null; 94 } 95 96 return collection.get(data[1] ~ "_" ~ to!string(width)); 97 } 98 } 99 100 /// A collection of character images. 101 final class NovelateCharacterImageCollection 102 { 103 private: 104 /// The images of the character. 105 string[string] _images; 106 107 public: 108 final: 109 /** 110 * Creates a new collection of character images. 111 * Params: 112 * path = The path of the image collection for the character. 113 */ 114 this(string path) 115 { 116 import std.file : dirEntries, SpanMode; 117 import std.algorithm : filter, endsWith; 118 119 auto images = dirEntries(to!string(path), SpanMode.shallow).filter!(f => f.name.endsWith(".png")); 120 121 foreach (image; images) 122 { 123 auto name = baseName(image).split(".")[0]; 124 125 _images[name] = image; 126 } 127 } 128 129 /** 130 * Gets an image from the collection. 131 * Params: 132 * name = The name of the image. 133 * Returns: 134 * The image retrieved from the collection. 135 */ 136 string get(string name) 137 { 138 if (!_images) 139 { 140 return null; 141 } 142 143 return _images.get(name, null); 144 } 145 } 146 147 /// The collection of characters. 148 private NovelateCharacter[string] _characters; 149 150 public: 151 /** 152 * Gets a character. 153 * Params: 154 * name = The name of the character. This can also be the alias name. 155 * Returns: 156 * The character from the character collection. 157 */ 158 NovelateCharacter getCharacter(string name) 159 { 160 if (!_characters) 161 { 162 return null; 163 } 164 165 return _characters.get(name, null); 166 } 167 168 package(novelate): 169 /** 170 * Creates a character base and adds it to the character collection. 171 * Params: 172 * name = The name of the character. 173 */ 174 void createCharacterBase(string name) 175 { 176 if (_characters && (name in _characters)) 177 { 178 return; 179 } 180 181 auto character = new NovelateCharacter(name); 182 183 _characters[character.name] = character; 184 } 185 186 /** 187 * Updates a character with parsed configurations. 188 * Params: 189 * characterName = The name of the character to update. 190 * name = The name of the configuration. 191 * value = The value of the configuration. 192 */ 193 void updateCharacter(string characterName, string name, string value) 194 { 195 if (!_characters) 196 { 197 return; 198 } 199 200 auto character = _characters.get(characterName, null); 201 202 if (!character) 203 { 204 return; 205 } 206 207 switch (name) 208 { 209 case "Alias": 210 { 211 character._aliasName = value; 212 213 _characters[character._aliasName] = character; 214 break; 215 } 216 case "NameColor": character._nameColor = value; break; 217 case "About": character._about = value; break; 218 case "AboutImage": character._aboutImage = value; break; 219 220 default: 221 { 222 character._graphics[name] = new NovelateCharacterImageCollection(value); 223 break; 224 } 225 } 226 }