Merge pull request #548 from NQNStudios:talk-keys

Better editing for talk node keys

* The fields start out empty, and it is *allowed* to keep *one of them* empty. (A node only needs one key to be useful, right?
* When the node is saved, empty strings are replaced with `"    "`. If this is not harmless to the game logic, then I'll need to make the game aware that either key might be `"    "`.
* You cannot type more than 4 characters in these fields (unless there's a way to insert characters I'm not aware of).
* If you put 'buy' in a field, it automatically becomes 'purc'.
* There is a note next to the response keys (kind of squished in the corner) enumerating the special logic of the in-game Buy and Sell buttons.
This commit is contained in:
2025-02-02 13:57:55 -05:00
committed by GitHub
5 changed files with 57 additions and 13 deletions

View File

@@ -3,6 +3,8 @@
#include <cstring>
#include <stack>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include "scen.global.hpp"
#include "scenario/scenario.hpp"
#include "scenario/town.hpp"
@@ -25,6 +27,9 @@
#include "fileio/fileio.hpp"
#include "fileio/resmgr/res_dialog.hpp"
using boost::algorithm::trim;
using boost::algorithm::to_lower;
extern short cen_x, cen_y, overall_mode;
extern bool mouse_button_held,change_made;
extern short cur_viewing_mode;
@@ -932,13 +937,35 @@ static bool check_talk_key(cDialog& me, std::string item_hit, bool losing) {
if(!losing) return true;
std::string key = me[item_hit].getText();
bool passes = true;
// An empty string is fine, it just means there's only one key.
if(key.empty()){
// But there needs to be at least one.
if(me["key1"].getText() == me["key2"].getText()){
showError("At least one of the words in this node must be filled.");
return false;
}
return true;
}
// I'll always have trouble remembering that it should be 'purc'.
// So why not make it easy?
if(key == "buy"){
me[item_hit].setText("purc");
return true;
}
// We can convert upper-case letters
to_lower(key);
me[item_hit].setText(key);
if(key.length() != 4) passes = false;
for(size_t i = 0; i < 4; i++) {
if(i < key.length() && !islower(key[i]))
if(i < key.length() && !islower(key[i])){
passes = false;
}
}
if(!passes) {
showError("The words this node is the response to must be 4 characters long, and all characters must be lower case letters.", &me);
showError("The words this node is the response to must be 4 characters long, and all characters must be letters.", &me);
return false;
}
return true;
@@ -1088,8 +1115,10 @@ static bool save_talk_node(cDialog& me, std::stack<node_ref_t>& talk_edit_stack,
talk_node.personality = me["who"].getTextAsNum();
std::string link = me["key1"].getText();
if(link.empty()) link = " ";
std::copy(link.begin(), link.begin() + 4, talk_node.link1);
link = me["key2"].getText();
if(link.empty()) link = " ";
std::copy(link.begin(), link.begin() + 4, talk_node.link2);
for(int i = 0; i < 4; i++) {
@@ -1118,9 +1147,12 @@ static void put_talk_node_in_dlog(cDialog& me, std::stack<node_ref_t>& talk_edit
std::string link = "";
for(int i = 0; i < 4; i++) link += talk_node.link1[i];
// I don't want 4 spaces in the text fields
trim(link);
me["key1"].setText(link);
link = "";
for(int i = 0; i < 4; i++) link += talk_node.link2[i];
trim(link);
me["key2"].setText(link);
int iDescBase = int(talk_node.type) * 7;