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 {
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) {
ERR_FAIL_INDEX(p_index, get_child_count());
ERR_FAIL_COND(p_probability < 0.0);
ERR_FAIL_COND(p_probability > 1.0);
ERR_FAIL_COND(p_probability > 0.99 && get_child_count() > 1);
ERR_FAIL_COND(p_probability >= 1.0);
double others_total = _get_total_weight() - _get_weight(p_index);
double others_probability = 1.0 - p_probability;
double new_total = others_total / others_probability;
_set_weight(p_index, new_total - others_total);
if (others_total == 0.0) {
_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) {
@ -108,6 +112,7 @@ void BTProbabilitySelector::_select_task() {
void BTProbabilitySelector::_bind_methods() {
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("get_total_weight"), &BTProbabilitySelector::get_total_weight);
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("get_abort_on_failure"), &BTProbabilitySelector::get_abort_on_failure);

View File

@ -52,6 +52,7 @@ protected:
public:
double get_weight(int p_index) const;
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;
void set_probability(int p_index, double p_probability);

View File

@ -33,6 +33,7 @@
#include "editor/inspector_dock.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/project_settings_editor.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/separator.h"
//**** LimboAIEditor
@ -319,7 +320,7 @@ void LimboAIEditor::_action_selected(int p_id) {
rect.position.y += rect.size.y;
rect.position += task_tree->get_rect().position;
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);
} break;
case ACTION_EDIT_SCRIPT: {
@ -438,7 +439,42 @@ void LimboAIEditor::_on_probability_edited(double p_value) {
ERR_FAIL_COND(selected == nullptr);
Ref<BTProbabilitySelector> probability_selector = selected->get_parent();
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) {
@ -792,7 +828,6 @@ void LimboAIEditor::_notification(int p_what) {
new_script_btn->set_icon(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")));
history_back->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons")));
history_forward->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons")));
misc_btn->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
_update_favorite_tasks();
@ -981,39 +1016,33 @@ LimboAIEditor::LimboAIEditor() {
VBoxContainer *vbc = memnew(VBoxContainer);
probability_popup->add_child(vbc);
// PanelContainer *mode_panel = memnew(PanelContainer);
// vbc->add_child(mode_panel);
PanelContainer *mode_panel = memnew(PanelContainer);
vbc->add_child(mode_panel);
// HBoxContainer *mode_hbox = memnew(HBoxContainer);
// mode_panel->add_child(mode_hbox);
HBoxContainer *mode_hbox = memnew(HBoxContainer);
mode_panel->add_child(mode_hbox);
// Ref<ButtonGroup> button_group;
// button_group.instantiate();
Ref<ButtonGroup> button_group;
button_group.instantiate();
// Button *percent_button = memnew(Button);
// mode_hbox->add_child(percent_button);
// percent_button->set_flat(true);
// percent_button->set_toggle_mode(true);
// percent_button->set_button_group(button_group);
// percent_button->set_focus_mode(Control::FOCUS_NONE);
// percent_button->set_text(TTR("Percent"));
// percent_button->set_tooltip_text(TTR("Edit percent"));
// percent_button->set_pressed(true);
// // percent_button->connect(SNAME("pressed"), callable_mp())
weight_mode = memnew(Button);
mode_hbox->add_child(weight_mode);
weight_mode->set_toggle_mode(true);
weight_mode->set_button_group(button_group);
weight_mode->set_focus_mode(Control::FOCUS_NONE);
weight_mode->set_text(TTR("Weight"));
weight_mode->set_tooltip_text(TTR("Edit weight"));
weight_mode->connect("pressed", callable_mp(this, &LimboAIEditor::_update_probability_edit));
weight_mode->set_pressed_no_signal(true);
// Button *weight_button = memnew(Button);
// mode_hbox->add_child(weight_button);
// weight_button->set_flat(true);
// weight_button->set_toggle_mode(true);
// weight_button->set_button_group(button_group);
// weight_button->set_focus_mode(Control::FOCUS_NONE);
// weight_button->set_text(TTR("Weight"));
// weight_button->set_tooltip_text(TTR("Edit weight"));
Label *probability_header = memnew(Label);
vbc->add_child(probability_header);
probability_header->set_text(TTR("Weight"));
probability_header->set_theme_type_variation("HeaderSmall");
percent_mode = memnew(Button);
mode_hbox->add_child(percent_mode);
percent_mode->set_toggle_mode(true);
percent_mode->set_button_group(button_group);
percent_mode->set_focus_mode(Control::FOCUS_NONE);
percent_mode->set_text(TTR("Percent"));
percent_mode->set_tooltip_text(TTR("Edit percent"));
percent_mode->connect("pressed", callable_mp(this, &LimboAIEditor::_update_probability_edit));
probability_edit = memnew(EditorSpinSlider);
vbc->add_child(probability_edit);
@ -1022,7 +1051,9 @@ LimboAIEditor::LimboAIEditor() {
probability_edit->set_step(0.01);
probability_edit->set_allow_greater(true);
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);

View File

@ -86,6 +86,8 @@ private:
PopupPanel *probability_popup;
EditorSpinSlider *probability_edit;
Button *weight_mode;
Button *percent_mode;
FileDialog *save_dialog;
FileDialog *load_dialog;
@ -131,6 +133,8 @@ private:
void _action_selected(int p_id);
void _misc_option_selected(int p_id);
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_visibility_changed();
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));
}
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 result = false;
Ref<BTTask> selected = get_selected();

View File

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