Allow editing weight as percent in Probability popup

This commit is contained in:
Serhii Snitsaruk 2023-09-25 22:36:37 +02:00
parent 52a70fdee5
commit 1df821fdfa
6 changed files with 88 additions and 38 deletions

View File

@ -25,19 +25,23 @@ void BTProbabilitySelector::set_weight(int p_index, double p_weight) {
double BTProbabilitySelector::get_probability(int p_index) const { double BTProbabilitySelector::get_probability(int p_index) const {
ERR_FAIL_INDEX_V(p_index, get_child_count(), 0.0); ERR_FAIL_INDEX_V(p_index, get_child_count(), 0.0);
return _get_weight(p_index) / _get_total_weight(); double total = _get_total_weight();
return total == 0.0 ? 0.0 : _get_weight(p_index) / total;
} }
void BTProbabilitySelector::set_probability(int p_index, double p_probability) { void BTProbabilitySelector::set_probability(int p_index, double p_probability) {
ERR_FAIL_INDEX(p_index, get_child_count()); ERR_FAIL_INDEX(p_index, get_child_count());
ERR_FAIL_COND(p_probability < 0.0); ERR_FAIL_COND(p_probability < 0.0);
ERR_FAIL_COND(p_probability > 1.0); ERR_FAIL_COND(p_probability >= 1.0);
ERR_FAIL_COND(p_probability > 0.99 && get_child_count() > 1);
double others_total = _get_total_weight() - _get_weight(p_index); double others_total = _get_total_weight() - _get_weight(p_index);
double others_probability = 1.0 - p_probability; double others_probability = 1.0 - p_probability;
double new_total = others_total / others_probability; if (others_total == 0.0) {
_set_weight(p_index, new_total - others_total); _set_weight(p_index, p_probability > 0.0 ? 1.0 : 0.0);
} else {
double new_total = others_total / others_probability;
_set_weight(p_index, new_total - others_total);
}
} }
void BTProbabilitySelector::set_abort_on_failure(bool p_abort_on_failure) { void BTProbabilitySelector::set_abort_on_failure(bool p_abort_on_failure) {
@ -108,6 +112,7 @@ void BTProbabilitySelector::_select_task() {
void BTProbabilitySelector::_bind_methods() { void BTProbabilitySelector::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_weight", "p_index"), &BTProbabilitySelector::get_weight); ClassDB::bind_method(D_METHOD("get_weight", "p_index"), &BTProbabilitySelector::get_weight);
ClassDB::bind_method(D_METHOD("set_weight", "p_index", "p_weight"), &BTProbabilitySelector::set_weight); ClassDB::bind_method(D_METHOD("set_weight", "p_index", "p_weight"), &BTProbabilitySelector::set_weight);
ClassDB::bind_method(D_METHOD("get_total_weight"), &BTProbabilitySelector::get_total_weight);
ClassDB::bind_method(D_METHOD("get_probability", "p_index"), &BTProbabilitySelector::get_probability); ClassDB::bind_method(D_METHOD("get_probability", "p_index"), &BTProbabilitySelector::get_probability);
ClassDB::bind_method(D_METHOD("set_probability", "p_index", "p_probability"), &BTProbabilitySelector::set_probability); ClassDB::bind_method(D_METHOD("set_probability", "p_index", "p_probability"), &BTProbabilitySelector::set_probability);
ClassDB::bind_method(D_METHOD("get_abort_on_failure"), &BTProbabilitySelector::get_abort_on_failure); ClassDB::bind_method(D_METHOD("get_abort_on_failure"), &BTProbabilitySelector::get_abort_on_failure);

View File

@ -52,6 +52,7 @@ protected:
public: public:
double get_weight(int p_index) const; double get_weight(int p_index) const;
void set_weight(int p_index, double p_weight); void set_weight(int p_index, double p_weight);
double get_total_weight() const { return _get_total_weight(); };
double get_probability(int p_index) const; double get_probability(int p_index) const;
void set_probability(int p_index, double p_probability); void set_probability(int p_index, double p_probability);

View File

@ -33,6 +33,7 @@
#include "editor/inspector_dock.h" #include "editor/inspector_dock.h"
#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h"
#include "editor/project_settings_editor.h" #include "editor/project_settings_editor.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/separator.h" #include "scene/gui/separator.h"
//**** LimboAIEditor //**** LimboAIEditor
@ -319,7 +320,7 @@ void LimboAIEditor::_action_selected(int p_id) {
rect.position.y += rect.size.y; rect.position.y += rect.size.y;
rect.position += task_tree->get_rect().position; rect.position += task_tree->get_rect().position;
rect = task_tree->get_screen_transform().xform(rect); rect = task_tree->get_screen_transform().xform(rect);
probability_edit->set_value_no_signal(task_tree->get_selected_probability_weight()); _update_probability_edit();
probability_popup->popup(rect); probability_popup->popup(rect);
} break; } break;
case ACTION_EDIT_SCRIPT: { case ACTION_EDIT_SCRIPT: {
@ -438,7 +439,42 @@ void LimboAIEditor::_on_probability_edited(double p_value) {
ERR_FAIL_COND(selected == nullptr); ERR_FAIL_COND(selected == nullptr);
Ref<BTProbabilitySelector> probability_selector = selected->get_parent(); Ref<BTProbabilitySelector> probability_selector = selected->get_parent();
ERR_FAIL_COND(probability_selector.is_null()); ERR_FAIL_COND(probability_selector.is_null());
probability_selector->set_weight(probability_selector->get_child_index(selected), p_value); if (percent_mode->is_pressed()) {
probability_selector->set_probability(probability_selector->get_child_index(selected), p_value * 0.01);
} else {
probability_selector->set_weight(probability_selector->get_child_index(selected), p_value);
}
}
void LimboAIEditor::_update_probability_edit() {
Ref<BTTask> selected = task_tree->get_selected();
ERR_FAIL_COND(selected.is_null());
Ref<BTProbabilitySelector> prob = selected->get_parent();
ERR_FAIL_COND(prob.is_null());
double others_weight = prob->get_total_weight() - prob->get_weight(prob->get_child_index(selected));
bool cannot_edit_percent = others_weight == 0.0;
percent_mode->set_disabled(cannot_edit_percent);
if (cannot_edit_percent && percent_mode->is_pressed()) {
weight_mode->set_pressed(true);
}
if (percent_mode->is_pressed()) {
probability_edit->set_suffix("%");
probability_edit->set_max(99.0);
probability_edit->set_allow_greater(false);
probability_edit->set_step(0.01);
probability_edit->set_value_no_signal(task_tree->get_selected_probability_percent());
} else {
probability_edit->set_suffix("");
probability_edit->set_allow_greater(true);
probability_edit->set_max(10.0);
probability_edit->set_step(0.01);
probability_edit->set_value_no_signal(task_tree->get_selected_probability_weight());
}
}
void LimboAIEditor::_probability_popup_closed() {
probability_edit->get_line_edit()->release_focus();
} }
void LimboAIEditor::_misc_option_selected(int p_id) { void LimboAIEditor::_misc_option_selected(int p_id) {
@ -792,7 +828,6 @@ void LimboAIEditor::_notification(int p_what) {
new_script_btn->set_icon(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons"))); new_script_btn->set_icon(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")));
history_back->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); history_back->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
history_forward->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); history_forward->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
misc_btn->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); misc_btn->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
_update_favorite_tasks(); _update_favorite_tasks();
@ -981,39 +1016,33 @@ LimboAIEditor::LimboAIEditor() {
VBoxContainer *vbc = memnew(VBoxContainer); VBoxContainer *vbc = memnew(VBoxContainer);
probability_popup->add_child(vbc); probability_popup->add_child(vbc);
// PanelContainer *mode_panel = memnew(PanelContainer); PanelContainer *mode_panel = memnew(PanelContainer);
// vbc->add_child(mode_panel); vbc->add_child(mode_panel);
// HBoxContainer *mode_hbox = memnew(HBoxContainer); HBoxContainer *mode_hbox = memnew(HBoxContainer);
// mode_panel->add_child(mode_hbox); mode_panel->add_child(mode_hbox);
// Ref<ButtonGroup> button_group; Ref<ButtonGroup> button_group;
// button_group.instantiate(); button_group.instantiate();
// Button *percent_button = memnew(Button); weight_mode = memnew(Button);
// mode_hbox->add_child(percent_button); mode_hbox->add_child(weight_mode);
// percent_button->set_flat(true); weight_mode->set_toggle_mode(true);
// percent_button->set_toggle_mode(true); weight_mode->set_button_group(button_group);
// percent_button->set_button_group(button_group); weight_mode->set_focus_mode(Control::FOCUS_NONE);
// percent_button->set_focus_mode(Control::FOCUS_NONE); weight_mode->set_text(TTR("Weight"));
// percent_button->set_text(TTR("Percent")); weight_mode->set_tooltip_text(TTR("Edit weight"));
// percent_button->set_tooltip_text(TTR("Edit percent")); weight_mode->connect("pressed", callable_mp(this, &LimboAIEditor::_update_probability_edit));
// percent_button->set_pressed(true); weight_mode->set_pressed_no_signal(true);
// // percent_button->connect(SNAME("pressed"), callable_mp())
// Button *weight_button = memnew(Button); percent_mode = memnew(Button);
// mode_hbox->add_child(weight_button); mode_hbox->add_child(percent_mode);
// weight_button->set_flat(true); percent_mode->set_toggle_mode(true);
// weight_button->set_toggle_mode(true); percent_mode->set_button_group(button_group);
// weight_button->set_button_group(button_group); percent_mode->set_focus_mode(Control::FOCUS_NONE);
// weight_button->set_focus_mode(Control::FOCUS_NONE); percent_mode->set_text(TTR("Percent"));
// weight_button->set_text(TTR("Weight")); percent_mode->set_tooltip_text(TTR("Edit percent"));
// weight_button->set_tooltip_text(TTR("Edit weight")); percent_mode->connect("pressed", callable_mp(this, &LimboAIEditor::_update_probability_edit));
Label *probability_header = memnew(Label);
vbc->add_child(probability_header);
probability_header->set_text(TTR("Weight"));
probability_header->set_theme_type_variation("HeaderSmall");
probability_edit = memnew(EditorSpinSlider); probability_edit = memnew(EditorSpinSlider);
vbc->add_child(probability_edit); vbc->add_child(probability_edit);
@ -1022,7 +1051,9 @@ LimboAIEditor::LimboAIEditor() {
probability_edit->set_step(0.01); probability_edit->set_step(0.01);
probability_edit->set_allow_greater(true); probability_edit->set_allow_greater(true);
probability_edit->set_custom_minimum_size(Size2(200.0 * EDSCALE, 0.0)); probability_edit->set_custom_minimum_size(Size2(200.0 * EDSCALE, 0.0));
probability_edit->connect(SNAME("value_changed"), callable_mp(this, &LimboAIEditor::_on_probability_edited)); probability_edit->connect("value_changed", callable_mp(this, &LimboAIEditor::_on_probability_edited));
probability_popup->connect("popup_hide", callable_mp(this, &LimboAIEditor::_probability_popup_closed));
} }
add_child(probability_popup); add_child(probability_popup);

View File

@ -86,6 +86,8 @@ private:
PopupPanel *probability_popup; PopupPanel *probability_popup;
EditorSpinSlider *probability_edit; EditorSpinSlider *probability_edit;
Button *weight_mode;
Button *percent_mode;
FileDialog *save_dialog; FileDialog *save_dialog;
FileDialog *load_dialog; FileDialog *load_dialog;
@ -131,6 +133,8 @@ private:
void _action_selected(int p_id); void _action_selected(int p_id);
void _misc_option_selected(int p_id); void _misc_option_selected(int p_id);
void _on_probability_edited(double p_value); void _on_probability_edited(double p_value);
void _update_probability_edit();
void _probability_popup_closed();
void _on_tree_task_selected(const Ref<BTTask> &p_task); void _on_tree_task_selected(const Ref<BTTask> &p_task);
void _on_visibility_changed(); void _on_visibility_changed();
void _on_header_pressed(); void _on_header_pressed();

View File

@ -225,6 +225,14 @@ double TaskTree::get_selected_probability_weight() const {
return probability_selector->get_weight(probability_selector->get_child_index(selected)); return probability_selector->get_weight(probability_selector->get_child_index(selected));
} }
double TaskTree::get_selected_probability_percent() const {
Ref<BTTask> selected = get_selected();
ERR_FAIL_COND_V(selected.is_null(), 0.0);
Ref<BTProbabilitySelector> probability_selector = selected->get_parent();
ERR_FAIL_COND_V(probability_selector.is_null(), 0.0);
return probability_selector->get_probability(probability_selector->get_child_index(selected)) * 100.0;
}
bool TaskTree::selected_has_probability() const { bool TaskTree::selected_has_probability() const {
bool result = false; bool result = false;
Ref<BTTask> selected = get_selected(); Ref<BTTask> selected = get_selected();

View File

@ -76,6 +76,7 @@ public:
Rect2 get_selected_probability_rect() const; Rect2 get_selected_probability_rect() const;
double get_selected_probability_weight() const; double get_selected_probability_weight() const;
double get_selected_probability_percent() const;
bool selected_has_probability() const; bool selected_has_probability() const;
virtual bool editor_can_reload_from_file() { return false; } virtual bool editor_can_reload_from_file() { return false; }