List of commits:
Subject Hash Author Date (UTC)
Add array scripting (@ operator, ARRLEN <array>) 3f098b3e0a04922c2c7a981b232efd8d08a8d9a0 mse 2021-09-10 14:02:39
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
Commit 3f098b3e0a04922c2c7a981b232efd8d08a8d9a0 - Add array scripting (@ operator, ARRLEN <array>)
Author: mse
Author date (UTC): 2021-09-10 14:02
Committer name: mse
Committer date (UTC): 2021-09-10 14:02
Parent(s): a298b01c9b77192b7ed8aba3832a8ab51c9d389a
Signing key:
Tree: a183e8d1f4ce5f9b43faeecf1380e586fb5574e6
File Lines added Lines deleted
confec.cpp 5 0
include/dialogue.h 58 2
File confec.cpp changed (mode: 100644) (index 7e0a272..c4db620)
... ... void Render(){
4855 4855 if( it != convo.strings.end() ) if( it != convo.strings.end() )
4856 4856 result = it->second; result = it->second;
4857 4857 } }
4858 }else if( key.back() == '@' ){
4859 key.resize( key.length() - 1 );
4860 auto it = convo.arrays.find( key );
4861 if( it != convo.arrays.end() )
4862 result = convo.stringifyArray( it->second );
4858 4863 }else{ }else{
4859 4864 result = convo.stringifyNumber( convo.getVariable( key ) ); result = convo.stringifyNumber( convo.getVariable( key ) );
4860 4865 } }
File include/dialogue.h changed (mode: 100755) (index ca3df6a..2e70e69)
... ... class Talk {
51 51 std::vector<Screen> screens; std::vector<Screen> screens;
52 52 std::map<std::string,double> numbers; std::map<std::string,double> numbers;
53 53 std::map<std::string,std::string> strings; std::map<std::string,std::string> strings;
54 std::map<std::string,std::vector<std::string>> arrays;
54 55 std::function<double(std::string)> callback; std::function<double(std::string)> callback;
55 56 void go( const std::string &id ); void go( const std::string &id );
56 57 void append( std::string filePath ); void append( std::string filePath );
 
... ... class Talk {
62 63 void setVariable( const std::string &key, double valueNumber ); void setVariable( const std::string &key, double valueNumber );
63 64 int parseJSON( std::string &text ); int parseJSON( std::string &text );
64 65 std::string stringifyNumber( double n ); std::string stringifyNumber( double n );
66 std::string stringifyArray( const std::vector<std::string> &arr );
65 67 Operation getOperation( std::string key, double valueNumber, const std::string &valueKey ); Operation getOperation( std::string key, double valueNumber, const std::string &valueKey );
66 68 void operate( Operation o ); void operate( Operation o );
67 69 void transformString( std::string &str ); void transformString( std::string &str );
 
... ... double Talk::getVariable( std::string key ){
186 188 }else if( key.length() >= 6 && key.substr( 0, 6 ) == "STRLEN" ){ }else if( key.length() >= 6 && key.substr( 0, 6 ) == "STRLEN" ){
187 189 // Returns the length of the parameter string. // Returns the length of the parameter string.
188 190 return std::max( key.length() - 7.0, 0.0 ); return std::max( key.length() - 7.0, 0.0 );
191 }else if( key.length() >= 6 && key.substr( 0, 6 ) == "ARRLEN" ){
192 // Returns the length of the named array if it exists, otherwise 0.
193 if( key.back() == '@' ) key.resize( key.length() - 1 );
194 if( key.length() >= 8 ){
195 auto it = arrays.find( key.substr( 7 ) );
196 if( it != arrays.end() ) return it->second.size();
197 }
189 198 }else if( key.length() >= 5 && key.substr( 0, 5 ) == "GOSUB" ){ }else if( key.length() >= 5 && key.substr( 0, 5 ) == "GOSUB" ){
190 199 // Executes the specified dialogue, then returns 0. // Executes the specified dialogue, then returns 0.
191 200 std::string arg = key.length() >= 7 ? key.substr( 6 ) : ""; std::string arg = key.length() >= 7 ? key.substr( 6 ) : "";
192 201 go( arg ); go( arg );
193 return 0.0;
194 202 }else{ }else{
195 203 // Returns the value of a variable if it exists, otherwise 0. // Returns the value of a variable if it exists, otherwise 0.
196 204 auto it = numbers.find( key ); auto it = numbers.find( key );
 
... ... std::string Talk::stringifyNumber( double n ){
283 291 } }
284 292 } }
285 293
294 // Return a #-separated list of strings with each string's # characters
295 // escaped as: \#
296 std::string Talk::stringifyArray( const std::vector<std::string> &arr ){
297 std::string result;
298 for( size_t i = 0; i < arr.size(); i++ ){
299 // Add separating # characters.
300 if( i > 0 ) result += "#";
301 // Replace # characters with \# and add the fragments to result.
302 const std::string &str = arr[i];
303 size_t start = 0, end = 0;
304 while( ( end = str.find( '#', start ) ) != std::string::npos ){
305 result += str.substr( start, end - start ) + "\\#";
306 start = end + 1;
307 }
308 result += str.substr( start );
309 }
310 return result;
311 }
312
286 313 Operation Talk::getOperation( std::string key, double valueNumber, const std::string &valueKey ){ Operation Talk::getOperation( std::string key, double valueNumber, const std::string &valueKey ){
287 314 char op = ':'; char op = ':';
288 if( key.length() > 0 && key.find_last_of( "$=!<>?%*/+-_" ) == key.length() - 1 ){
315 if( key.length() > 0 && key.find_last_of( "$@=!<>?%*/+-_" ) == key.length() - 1 ){
289 316 op = key.back(); op = key.back();
290 317 key.resize( key.length() - 1 ); key.resize( key.length() - 1 );
291 318 } }
 
... ... void Talk::operate( Operation o ){
311 338 } }
312 339 return; return;
313 340 } }
341 // Array assignment.
342 if( o.op == '@' ){
343 transformString( o.valueKey );
344 // Make an empty array and get the iterator.
345 const auto [it, success] = arrays.insert( { o.key, {} } );
346 if( !success ) it->second = {};
347 // Parse the array.
348 size_t start = 0, off = 0, end = 0;
349 while( ( end = o.valueKey.find( '#', start + off ) ) != std::string::npos ){
350 // Allow \# escaping. TODO: \\ escaping.
351 if( end > 0 && o.valueKey[end - 1] == '\\' ){
352 // Remove the \ character from the string.
353 o.valueKey.erase( end - 1, 1 );
354 // `end` now points to the character after the #.
355 off = end - start;
356 continue;
357 }
358 it->second.push_back( o.valueKey.substr( start, end - start ) );
359 start = end + 1;
360 off = 0;
361 }
362 it->second.push_back( o.valueKey.substr( start ) );
363 return;
364 }
314 365 // Numerical operations. // Numerical operations.
315 366 double in = o.valueNumber, out = getVariable( o.key ); double in = o.valueNumber, out = getVariable( o.key );
316 367 if( o.valueKey.length() > 0 ){ if( o.valueKey.length() > 0 ){
 
... ... void Talk::transformString( std::string &str ){
368 419 if( it != strings.end() ) if( it != strings.end() )
369 420 outStr += it->second; outStr += it->second;
370 421 } }
422 }else if( key.back() == '@' ){
423 key.resize( key.length() - 1 );
424 auto it = arrays.find( key );
425 if( it != arrays.end() )
426 outStr += stringifyArray( it->second );
371 427 }else{ }else{
372 428 outStr += stringifyNumber( getVariable( key ) ); outStr += stringifyNumber( getVariable( key ) );
373 429 } }
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 main