List of commits:
Subject Hash Author Date (UTC)
Optimize script runtime a298b01c9b77192b7ed8aba3832a8ab51c9d389a mse 2021-09-09 06:57:49
Scriptable bg$, fg$, caption$ 0ad08aa3887118d2376f4fa7f8b7c66e0f164c73 mse 2021-09-06 11:04:38
Animation command: ANIM <loop|play> <bg|fg> <fps> <directory> 6066e2cae1dc29043902d46549f443c7b683fd88 mse 2021-09-06 06:42:13
Switch to C++17 489987b1b2749f37e0ac76594308635affbd24f2 mse 2021-09-05 10:51:02
Fix stats synchronization bug 3b6195c3321a6f10af43839cc00d24f301eddb3e mse 2021-09-05 04:45:58
Add top-level command: STRLEN, scriptable player name$ ec7a623cdc98b9832f35f0beb3e45179e6094436 mse 2021-09-05 03:17:47
Start work on animation system d2aafd6f46c719342054e3f256f972f4917f2231 mse 2021-09-05 02:41:28
Add string scripting with $ operator 20034a2b658ee8ad4f2082c44301c231b0323fc7 mse 2021-09-03 10:20:55
Enhance console /set command to support operators 61032844fcb833f04e2f6d1e123f8f0f89333107 mse 2021-09-02 11:06:00
Add scriptable bribing & remove hard-coded karma increment 41b4d79da6331b4b1ffd96f36ae1b032a869b482 mse 2021-08-31 17:51:29
Add floor operator (_) 819304b561d474e962afa7397ef68ffae83e8649 mse 2021-08-31 13:49:57
Switch inventories and stats to floating-point c6e4142e664648ca8f4aa913b48526093c985987 mse 2021-08-31 13:35:20
Switch scripting to floating-point & code comments eb067496f4edb4420c05a09dc034ad0a25ad1e56 mse 2021-08-31 11:06:01
Add top-level command: GOSUB 62e9520aec0471fe023ead290595f735a30eb806 mse 2021-08-26 09:31:27
Add persistent VN stats 2d1ffc35afd8ae0f477cbd5aac0559fc02571600 mse 2021-08-23 10:44:16
Bribes increase karma 643f0fc6da65316aa799bbe00cea2030e2c1ccd6 mse 2021-08-17 08:16:36
Add command: #RUMBLE <intensity> <milliseconds> 02964b2ecc57a48192522ef369e33c4912d2f0d2 mse 2021-08-16 07:17:40
Reset position in non-mouse menu selection c21eb6a9d238fa1909dbbbc49907ad09bfca52c8 mse 2021-08-16 03:30:49
Add haptic rumble for combat 65ff172308b0ba26b8930e8e83eb41bd36c6b008 mse 2021-08-15 06:11:25
Reduce joystick sensitivity 3804492a52d36c40cd51d42a971fe92f4fdd52ba mse 2021-08-14 22:37:19
Commit a298b01c9b77192b7ed8aba3832a8ab51c9d389a - Optimize script runtime
Author: mse
Author date (UTC): 2021-09-09 06:57
Committer name: mse
Committer date (UTC): 2021-09-09 06:57
Parent(s): 0ad08aa3887118d2376f4fa7f8b7c66e0f164c73
Signing key:
Tree: 4d9b5d217e53b5993346f33edc34ed6002404881
File Lines added Lines deleted
confec.cpp 16 15
include/dialogue.h 36 50
File confec.cpp changed (mode: 100644) (index 054dec5..7e0a272)
... ... int main( int argc, char* argv[] ){
1306 1306 } }
1307 1307 if( param == "DELETEALL" ){ if( param == "DELETEALL" ){
1308 1308 DeleteAllUserFiles(); DeleteAllUserFiles();
1309 convo.variables.clear();
1309 convo.numbers.clear();
1310 convo.strings.clear();
1310 1311 InitSettings(); InitSettings();
1311 1312 recipes = {}; recipes = {};
1312 1313 return 0.0; return 0.0;
 
... ... void vnDataUpload(){
2090 2091 convo.setVariable( "health", player.health ); convo.setVariable( "health", player.health );
2091 2092 convo.setVariable( "money", player.money ); convo.setVariable( "money", player.money );
2092 2093 convo.setVariable( "karma", player.karma ); convo.setVariable( "karma", player.karma );
2093 // Clear the global stats namespace using erase-remove idiom.
2094 convo.variables.erase(
2095 std::remove_if(
2096 convo.variables.begin(),
2097 convo.variables.end(),
2098 []( const dialogue::Variable &v ){
2099 return v.key.length() > 6 && v.key.substr( 0, 6 ) == "stats.";
2100 }
2101 ),
2102 convo.variables.end()
2103 );
2094 // Clear the global stats namespace using erase_if algorithm.
2095 for( auto it = convo.numbers.begin(), last = convo.numbers.end(); it != last; ){
2096 if( it->first.length() > 6 && it->first.substr( 0, 6 ) == "stats." ){
2097 it = convo.numbers.erase( it );
2098 }else{
2099 // Pre-incrementing an iterator is faster because
2100 // post-increment must make a copy of the previous value
2101 // and return it.
2102 ++it;
2103 }
2104 }
2104 2105 // Copy the player's bribeItems into the VN stats namespace. // Copy the player's bribeItems into the VN stats namespace.
2105 2106 for( auto &item : player.bribeItems ){ for( auto &item : player.bribeItems ){
2106 2107 convo.setVariable( "stats." + item.first, item.second ); convo.setVariable( "stats." + item.first, item.second );
 
... ... void vnDataDownload( const std::string &data_path ){
2156 2157 player.money = money; player.money = money;
2157 2158 player.karma = convo.getVariable( "karma" ); player.karma = convo.getVariable( "karma" );
2158 2159 // Copy VN stats into the player's bribeItems. // Copy VN stats into the player's bribeItems.
2159 for( auto &v : convo.variables ){
2160 if( v.key.length() > 6 && v.key.substr( 0, 6 ) == "stats." )
2161 player.bribeItems.set( v.key.substr( 6 ), v.valueNumber );
2160 for( auto &p : convo.numbers ){
2161 if( p.first.length() > 6 && p.first.substr( 0, 6 ) == "stats." )
2162 player.bribeItems.set( p.first.substr( 6 ), p.second );
2162 2163 } }
2163 2164 } }
2164 2165 // Override the CANCEL ID. // Override the CANCEL ID.
File include/dialogue.h changed (mode: 100755) (index 667033c..ca3df6a)
23 23
24 24 namespace dialogue { namespace dialogue {
25 25
26 // Key/value pairs.
27 struct Variable {
28 std::string key;
29 double valueNumber;
30 };
31
32 26 // Arithmetic operations on key/value pairs. // Arithmetic operations on key/value pairs.
33 27 struct Operation { struct Operation {
34 28 std::string key; std::string key;
 
... ... class Talk {
55 49 std::string file; std::string file;
56 50 Screen screen; Screen screen;
57 51 std::vector<Screen> screens; std::vector<Screen> screens;
58 std::vector<Variable> variables;
52 std::map<std::string,double> numbers;
59 53 std::map<std::string,std::string> strings; std::map<std::string,std::string> strings;
60 54 std::function<double(std::string)> callback; std::function<double(std::string)> callback;
61 void go( std::string id );
55 void go( const std::string &id );
62 56 void append( std::string filePath ); void append( std::string filePath );
63 bool hasScreen( std::string id );
64 Screen getScreen( std::string id );
65 void setScreen( Screen scr );
66 bool hasVariable( std::string key );
57 bool hasScreen( const std::string &id );
58 Screen getScreen( const std::string &id );
59 void setScreen( const Screen &scr );
60 bool hasVariable( const std::string &key );
67 61 double getVariable( std::string key ); double getVariable( std::string key );
68 void setVariable( std::string key, double valueNumber );
62 void setVariable( const std::string &key, double valueNumber );
69 63 int parseJSON( std::string &text ); int parseJSON( std::string &text );
70 64 std::string stringifyNumber( double n ); std::string stringifyNumber( double n );
71 Operation getOperation( std::string key, double valueNumber, std::string valueKey );
65 Operation getOperation( std::string key, double valueNumber, const std::string &valueKey );
72 66 void operate( Operation o ); void operate( Operation o );
73 67 void transformString( std::string &str ); void transformString( std::string &str );
74 Talk( std::string filePath = "" );
68 Talk( const std::string &filePath = "" );
75 69 }; };
76 70
77 void Talk::go( std::string id ){
71 void Talk::go( const std::string &id ){
78 72 if( id.length() >= 5 && id.substr( id.length() - 5 ) == ".json" ){ if( id.length() >= 5 && id.substr( id.length() - 5 ) == ".json" ){
79 73 screens.clear(); screens.clear();
80 74 std::string filePath = file.substr( 0, file.find_last_of( '/' ) + 1 ) + id; std::string filePath = file.substr( 0, file.find_last_of( '/' ) + 1 ) + id;
 
... ... void Talk::append( std::string filePath ){
139 133 } }
140 134 } }
141 135
142 bool Talk::hasScreen( std::string id ){
136 bool Talk::hasScreen( const std::string &id ){
143 137 for( Screen &s : screens ){ for( Screen &s : screens ){
144 138 if( s.id == id ){ if( s.id == id ){
145 139 return true; return true;
 
... ... bool Talk::hasScreen( std::string id ){
148 142 return false; return false;
149 143 } }
150 144
151 Screen Talk::getScreen( std::string id ){
145 Screen Talk::getScreen( const std::string &id ){
152 146 for( Screen &s : screens ){ for( Screen &s : screens ){
153 147 if( s.id == id ){ if( s.id == id ){
154 148 return s; return s;
 
... ... Screen Talk::getScreen( std::string id ){
165 159 }; };
166 160 } }
167 161
168 void Talk::setScreen( Screen scr ){
162 void Talk::setScreen( const Screen &scr ){
169 163 for( Screen &s : screens ){ for( Screen &s : screens ){
170 164 if( s.id == scr.id ){ if( s.id == scr.id ){
171 165 s = scr; s = scr;
 
... ... void Talk::setScreen( Screen scr ){
175 169 screens.push_back( scr ); screens.push_back( scr );
176 170 } }
177 171
178 bool Talk::hasVariable( std::string key ){
179 for( Variable &v : variables ) if( v.key == key ) return true;
180 return false;
172 bool Talk::hasVariable( const std::string &key ){
173 return numbers.count( key ) > 0;
181 174 } }
182 175
183 176 double Talk::getVariable( std::string key ){ double Talk::getVariable( std::string key ){
 
... ... double Talk::getVariable( std::string key ){
200 193 return 0.0; return 0.0;
201 194 }else{ }else{
202 195 // Returns the value of a variable if it exists, otherwise 0. // Returns the value of a variable if it exists, otherwise 0.
203 for( Variable &v : variables ){
204 if( v.key == key ) return v.valueNumber;
205 }
196 auto it = numbers.find( key );
197 if( it != numbers.end() ) return it->second;
206 198 } }
207 199 return 0.0; return 0.0;
208 200 } }
209 201
210 void Talk::setVariable( std::string key, double valueNumber ){
211 for( Variable &v : variables ){
212 if( v.key == key ){
213 v.valueNumber = valueNumber;
214 return;
215 }
216 }
217 variables.push_back( { key, valueNumber } );
202 void Talk::setVariable( const std::string &key, double valueNumber ){
203 numbers[key] = valueNumber;
218 204 } }
219 205
220 206 int Talk::parseJSON( std::string &text ){ int Talk::parseJSON( std::string &text ){
221 207 // All code dependent on tm_json.h is contained within this function. // All code dependent on tm_json.h is contained within this function.
222 208
223 209 auto allocatedDocument = jsonAllocateDocumentEx( text.c_str(), text.size(), JSON_READER_JSON5 ); auto allocatedDocument = jsonAllocateDocumentEx( text.c_str(), text.size(), JSON_READER_JSON5 );
224
210
225 211 auto err = allocatedDocument.document.error; auto err = allocatedDocument.document.error;
226 212 if( err.type != JSON_OK ){ if( err.type != JSON_OK ){
227 213 screen = { screen = {
 
... ... int Talk::parseJSON( std::string &text ){
239 225 jsonFreeDocument( &allocatedDocument ); jsonFreeDocument( &allocatedDocument );
240 226 return err.type; return err.type;
241 227 } }
242
228
243 229 auto viewToString = []( JsonStringView str ){ auto viewToString = []( JsonStringView str ){
244 230 return std::string( str.data, str.size ); return std::string( str.data, str.size );
245 231 }; };
246
232
247 233 for( auto s : allocatedDocument.document.root.getObject() ){ for( auto s : allocatedDocument.document.root.getObject() ){
248 234 std::vector<Operation> exec; std::vector<Operation> exec;
249 235 for( auto o : s.value["exec"].getObject() ){ for( auto o : s.value["exec"].getObject() ){
 
... ... int Talk::parseJSON( std::string &text ){
277 263 } }
278 264 if( !over ) screens.push_back( scr ); if( !over ) screens.push_back( scr );
279 265 } }
280
266
281 267 jsonFreeDocument( &allocatedDocument ); jsonFreeDocument( &allocatedDocument );
282
268
283 269 return 0; return 0;
284 270 } }
285 271
 
... ... std::string Talk::stringifyNumber( double n ){
297 283 } }
298 284 } }
299 285
300 Talk::Talk( std::string filePath ){
301 callback = []( std::string param ){
302 // Suppress unused parameter warnings.
303 param = "";
304 return 0.0;
305 };
306 if( filePath.length() > 0 ){
307 go( filePath );
308 }
309 }
310
311 Operation Talk::getOperation( std::string key, double valueNumber, std::string valueKey ){
286 Operation Talk::getOperation( std::string key, double valueNumber, const std::string &valueKey ){
312 287 char op = ':'; char op = ':';
313 288 if( key.length() > 0 && key.find_last_of( "$=!<>?%*/+-_" ) == key.length() - 1 ){ if( key.length() > 0 && key.find_last_of( "$=!<>?%*/+-_" ) == key.length() - 1 ){
314 289 op = key.back(); op = key.back();
 
... ... void Talk::transformString( std::string &str ){
413 388 str = outStr; str = outStr;
414 389 } }
415 390
391 Talk::Talk( const std::string &filePath ){
392 callback = []( std::string param ){
393 // Suppress unused parameter warnings.
394 param = "";
395 return 0.0;
396 };
397 if( filePath.length() > 0 ){
398 go( filePath );
399 }
400 }
401
416 402 } // namespace dialogue } // namespace dialogue
417 403
418 404 #endif // DIALOGUE_H #endif // DIALOGUE_H
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using git:
git clone git://git.rocketgit.com/user/mse/ConfectionerEngine

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin master