diff --git a/src/editor/node_marker.cpp b/src/editor/node_marker.cpp index 5b7d3b74aa4..20bda73a61b 100644 --- a/src/editor/node_marker.cpp +++ b/src/editor/node_marker.cpp @@ -39,17 +39,11 @@ NodeMarker::update_iterator() Vector NodeMarker::get_point_vector() const { - std::vector::iterator next_node = m_node + 1; - if (next_node == m_path->m_nodes.end()) { - if (m_path->m_mode == WalkMode::CIRCULAR) { - //loop to the first node - return m_path->m_nodes.begin()->position - m_node->position; - } else { - return Vector(0,0); - } + std::vector::const_iterator next = next_node(); + if (next == m_path->m_nodes.end()) { + return Vector(0,0); } else { - //point to the next node - return next_node->position - m_node->position; + return next->position - m_node->position; } } @@ -64,6 +58,7 @@ NodeMarker::move_to(const Vector& pos) { MovingObject::move_to(pos); m_node->position = m_col.m_bbox.get_middle(); + update_node_times(); } void @@ -73,6 +68,9 @@ NodeMarker::editor_delete() { return; } + std::vector::iterator prev = prev_node(); + std::vector::const_iterator next = next_node(); + update_node_time(prev, next); m_path->m_nodes.erase(m_node); Editor::current()->update_node_iterators(); } @@ -82,6 +80,7 @@ NodeMarker::get_settings() { ObjectSettings result(_("Path Node")); result.add_float(_("Time"), &(m_node->time)); + result.add_float(_("Speed"), &(m_node->speed)); return result; } @@ -89,6 +88,47 @@ void NodeMarker::editor_update() { set_pos(m_node->position - Vector(8, 8)); + update_node_time(m_node, next_node()); +} + +std::vector::iterator NodeMarker::prev_node() { + std::vector::iterator node = m_node; + if (node == m_path->m_nodes.begin()) { + if (m_path->m_mode == WalkMode::CIRCULAR) { + node = m_path->m_nodes.end(); + } else { + return m_path->m_nodes.end(); + } + } + --node; + return node; +} + +std::vector::const_iterator NodeMarker::next_node() const { + std::vector::const_iterator node = m_node + 1; + if (node == m_path->m_nodes.end()) { + if (m_path->m_mode == WalkMode::CIRCULAR) { + node = m_path->m_nodes.begin(); + } + } + return node; +} + +void NodeMarker::update_node_times() { + update_node_time(prev_node(), m_node); + update_node_time(m_node, next_node()); +} + +void NodeMarker::update_node_time(std::vector::iterator current, std::vector::const_iterator next) { + if (current == m_path->m_nodes.end() || next == m_path->m_nodes.end()) { + return; // Nothing to do. + } + if (current->speed > 0) { + float delta = (next->position - current->position).norm(); + if (delta > 0) { + current->time = delta / current->speed; + } + } } /* EOF */ diff --git a/src/editor/node_marker.hpp b/src/editor/node_marker.hpp index c20a5507032..fa5a2c08b10 100644 --- a/src/editor/node_marker.hpp +++ b/src/editor/node_marker.hpp @@ -34,9 +34,13 @@ class NodeMarker : public MarkerObject virtual void editor_update() override; void update_iterator(); + void update_node_times(); private: Path* m_path; + std::vector::iterator prev_node(); + std::vector::const_iterator next_node() const; + void update_node_time(std::vector::iterator current, std::vector::const_iterator next); public: std::vector::iterator m_node; diff --git a/src/editor/overlay_widget.cpp b/src/editor/overlay_widget.cpp index 5a28df02820..1b07c9a008a 100644 --- a/src/editor/overlay_widget.cpp +++ b/src/editor/overlay_widget.cpp @@ -488,9 +488,10 @@ EditorOverlayWidget::add_path_node() new_node.position = m_sector_pos; new_node.time = 1; m_edited_path->m_nodes.insert(m_last_node_marker->m_node + 1, new_node); - Sector::get().add(m_edited_path, m_edited_path->m_nodes.end() - 1, m_edited_path->m_nodes.size() - 1); + auto& new_marker = Sector::get().add(m_edited_path, m_edited_path->m_nodes.end() - 1, m_edited_path->m_nodes.size() - 1); //last_node_marker = dynamic_cast(marker.get()); update_node_iterators(); + new_marker.update_node_times(); m_editor.get_sector()->flush_game_objects(); grab_object(); } diff --git a/src/object/path.cpp b/src/object/path.cpp index 747496a80e2..12a1e1b8d78 100644 --- a/src/object/path.cpp +++ b/src/object/path.cpp @@ -67,6 +67,7 @@ Path::Path(const Vector& pos) : Node first_node; first_node.position = pos; first_node.time = 1; + first_node.speed = 0; m_nodes.push_back(first_node); } @@ -88,10 +89,12 @@ Path::read(const ReaderMapping& reader) // each new node will inherit all values from the last one Node node; node.time = 1; + node.speed = 0; if ( (!node_mapping.get("x", node.position.x) || !node_mapping.get("y", node.position.y))) throw std::runtime_error("Path node without x and y coordinate specified"); node_mapping.get("time", node.time); + node_mapping.get("speed", node.speed); if (node.time <= 0) throw std::runtime_error("Path node with non-positive time"); @@ -123,6 +126,9 @@ Path::save(Writer& writer) if (nod.time != 1.0f) { writer.write("time", nod.time); } + if (nod.speed != 0.0f) { + writer.write("speed", nod.speed); + } writer.end_list("node"); } diff --git a/src/object/path.hpp b/src/object/path.hpp index 0ac9e710972..cf1d37d31d5 100644 --- a/src/object/path.hpp +++ b/src/object/path.hpp @@ -50,10 +50,12 @@ class Path final public: Vector position; /**< the position of this node */ float time; /**< time (in seconds) to get from this node to next node */ + float speed; /**< speed (in px/seconds); editor use only */ Node() : position(), - time() + time(), + speed() {} };