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 scenes. 12 */ 13 module novelate.scripting.scene; 14 15 import std.conv : to; 16 import std.algorithm : countUntil, endsWith; 17 18 /// Wrapper around a scene configuration. 19 final class NovelateScene 20 { 21 private: 22 /// The name. 23 string _name; 24 /// The music. 25 string _music; 26 /// The background. 27 string _background; 28 /// The animation. 29 string _animation; 30 /// The animation direction. 31 string _animationDirection; 32 /// The animation start position. 33 string _animationStartPosition; 34 /// Boolean determining whether the scene name should be displayed or not. 35 bool _displaySceneName; 36 /// Boolean determining whether the configuration is parsing actions. 37 bool _parseActions; 38 /// The actions. 39 NovelateSceneAction[] _actions; 40 41 public: 42 final: 43 package(novelate) 44 { 45 this(string name) 46 { 47 _name = name; 48 49 _actions = []; 50 } 51 52 /** 53 * Updates the scene with a line to parse from the parsed Novelate content. 54 * Params: 55 * line = The line to parse. 56 */ 57 void updateScene(string line) 58 { 59 if (line == "---") 60 { 61 _parseActions = true; 62 } 63 else 64 { 65 if (_parseActions) 66 { 67 if (line == "===") 68 { 69 _actions ~= new NovelateSceneAction(NovelateSceneActionType.actionChange, line); 70 } 71 else 72 { 73 auto valueIndex = line.countUntil("="); 74 75 if (valueIndex < 1) 76 { 77 if (line.endsWith(";")) 78 { 79 _actions ~= new NovelateSceneAction(NovelateSceneActionType.action, line[0 .. $-1]); 80 } 81 else 82 { 83 _actions ~= new NovelateSceneAction(NovelateSceneActionType.characterChange, line); 84 } 85 } 86 else 87 { 88 import std.array : replace; 89 90 auto name = line[0 .. valueIndex]; 91 auto value = line[valueIndex + 1 .. $]; 92 93 _actions ~= new NovelateSceneAction(NovelateSceneActionType.option, name, value.replace("\\n", "\n")); 94 } 95 } 96 } 97 else 98 { 99 auto valueIndex = line.countUntil("="); 100 101 if (valueIndex < 1) 102 { 103 return; 104 } 105 106 auto name = line[0 .. valueIndex]; 107 auto value = line[valueIndex + 1 .. $]; 108 109 switch (name) 110 { 111 case "Music": _music = value; break; 112 case "Background": _background = value; break; 113 case "Animation": _animation = value; break; 114 case "AnimationDirection": _animationDirection = value; break; 115 case "AnimationStartPosition": _animationStartPosition = value; break; 116 case "DisplaySceneName": _displaySceneName = to!bool(value); break; 117 118 default: break; 119 } 120 } 121 } 122 } 123 } 124 125 @property 126 { 127 /// Gets the name of the scene. 128 string name() { return _name; } 129 130 /// Gets the music of the scene. 131 string music() { return _music; } 132 133 /// Gets the background of the scene. 134 string background() { return _background; } 135 136 /// Gets the animation of the scene. 137 string animation() { return _animation; } 138 139 /// Gets the animation direction of the scene. 140 string animationDirection() { return _animationDirection; } 141 142 /// Gets the animation start position of the scene. 143 string animationStartPosition() { return _animationStartPosition; } 144 145 /// Gets a boolean determining whether the scene name should be displayed or not. 146 bool displaySceneName() { return _displaySceneName; } 147 148 /// Gets the actions of the scene. 149 NovelateSceneAction[] actions() { return _actions; } 150 } 151 } 152 153 /// Enumeration of scene action types. 154 enum NovelateSceneActionType 155 { 156 /// A character change. 157 characterChange, 158 /// An option. This means an optiion for inputting configurations, setting data etc. 159 option, 160 /// An action to execute. 161 action, 162 /// An action change. This forces a wait for the next set of actions. 163 actionChange 164 } 165 166 /// Wrapper around a scene action. 167 final class NovelateSceneAction 168 { 169 private: 170 /// The type. 171 NovelateSceneActionType _type; 172 /// The name. 173 string _name; 174 /// The value. 175 string _value; 176 177 public: 178 final: 179 /** 180 * Creates a new scene action. 181 * Params: 182 * type = The type of the scene action. 183 * name = The name of the scene action. 184 */ 185 this(NovelateSceneActionType type, string name) 186 { 187 _type = type; 188 _name = name; 189 } 190 191 /** 192 * Creates a new scene action. 193 * Params: 194 * type = The type of the scene action. 195 * name = The name of the scene action. 196 * value = The value of the scene action. 197 */ 198 this(NovelateSceneActionType type, string name, string value) 199 { 200 this(type, name); 201 202 _value = value; 203 } 204 205 @property 206 { 207 /// Gets the type. 208 NovelateSceneActionType type() { return _type; } 209 210 /// Gets the name. 211 string name() { return _name; } 212 213 /// Gets the value. 214 string value() { return _value; } 215 } 216 } 217 218 /// The scene collection. 219 private NovelateScene[string] _scenes; 220 221 public: 222 /** 223 * Gets a scene. 224 * Params: 225 * name = The name of the scene to get. 226 * Returns: 227 * The scene. 228 */ 229 NovelateScene getScene(string name) 230 { 231 if (!_scenes) 232 { 233 return null; 234 } 235 236 return _scenes.get(name, null); 237 } 238 239 package(novelate): 240 /** 241 * Creates a scene base. 242 * Params: 243 * name = The name of the scene to create a base for. 244 * Returns: 245 * The scene base created. 246 */ 247 NovelateScene createSceneBase(string name) 248 { 249 auto scene = new NovelateScene(name); 250 251 _scenes[scene.name] = scene; 252 253 return scene; 254 }