From ce1acac5b6501ce5303755735d4a287c9b083f38 Mon Sep 17 00:00:00 2001
From: Pewtro <29204244+Pewtro@users.noreply.github.com>
Date: Fri, 24 Apr 2026 16:39:13 +0200
Subject: [PATCH 1/2] Add spell name and spell id to json for sequences
---
engine/action/sequence.cpp | 7 ++++++-
engine/player/player.cpp | 14 ++++++++++++++
engine/player/player_collected_data.cpp | 2 +-
engine/player/player_collected_data.hpp | 2 ++
engine/report/json/report_json.cpp | 12 ++++++++++--
5 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/engine/action/sequence.cpp b/engine/action/sequence.cpp
index 4c4044d78b0..ad1c423db1f 100644
--- a/engine/action/sequence.cpp
+++ b/engine/action/sequence.cpp
@@ -185,7 +185,12 @@ void sequence_t::sequence_add_fn( std::string& a_str, std::string& t_str ) const
{
// current_action is advanced in schedule_execute so we need to use current_action - 1
auto _idx = current_action - 1;
- a_str = fmt::format( "SEQ {}[{}]
{}", name_str, _idx, sub_actions[ _idx ]->name_str );
+ const action_t* sub_action = sub_actions[ _idx ];
+ const char* sub_action_name = sub_action->data_reporting().name_cstr();
+ if ( sub_action_name == nullptr || sub_action_name[ 0 ] == '\0' )
+ sub_action_name = sub_action->name_reporting();
+
+ a_str = fmt::format( "SEQ {}[{}]
{}", name_str, _idx, sub_action_name );
t_str = target->name_str;
}
diff --git a/engine/player/player.cpp b/engine/player/player.cpp
index 5ded848c9e9..ef386fdd101 100644
--- a/engine/player/player.cpp
+++ b/engine/player/player.cpp
@@ -6359,6 +6359,20 @@ void player_t::sequence_add( const action_t* a, const player_t* t )
{
auto& data = collected_data.action_sequence.emplace_back( a, t, sim->current_time(), this );
a->sequence_add_fn( data.action_reporting, data.target_reporting );
+ data.spell_id = a->id;
+ if ( data.spell_id == 0 && a->type == ACTION_SEQUENCE )
+ {
+ const sequence_t* seq = static_cast( a );
+ if ( seq->current_action > 0 && seq->current_action <= as( seq->sub_actions.size() ) )
+ {
+ const action_t* sub_action = seq->sub_actions[ seq->current_action - 1 ];
+ data.spell_id = sub_action->id;
+ const char* spell_name = sub_action->data_reporting().name_cstr();
+ if ( spell_name == nullptr || spell_name[ 0 ] == '\0' )
+ spell_name = sub_action->name_reporting();
+ data.spell_name = spell_name;
+ }
+ }
}
}
else
diff --git a/engine/player/player_collected_data.cpp b/engine/player/player_collected_data.cpp
index 0c5bd0b3dac..921ec8b6459 100644
--- a/engine/player/player_collected_data.cpp
+++ b/engine/player/player_collected_data.cpp
@@ -33,7 +33,7 @@ double player_collected_data_t::health_changes_timeline_t::get_bin_size() const
player_collected_data_t::action_sequence_data_t::action_sequence_data_t( const action_t* a, const player_t* t,
timespan_t ts, timespan_t wait,
const player_t* p )
- : action( a ), target( t ), time( ts ), wait_time( wait ), queue_failed( false )
+ : action( a ), target( t ), time( ts ), wait_time( wait ), spell_id( 0 ), spell_name(), queue_failed( false )
{
for ( buff_t* b : p->buff_list )
{
diff --git a/engine/player/player_collected_data.hpp b/engine/player/player_collected_data.hpp
index a72f83f6184..8c1268f913a 100644
--- a/engine/player/player_collected_data.hpp
+++ b/engine/player/player_collected_data.hpp
@@ -123,6 +123,8 @@ struct player_collected_data_t
std::string target_reporting; // reporting override
const timespan_t time;
timespan_t wait_time;
+ unsigned spell_id;
+ std::string spell_name;
bool queue_failed;
std::vector> buff_list;
std::vector> cooldown_list;
diff --git a/engine/report/json/report_json.cpp b/engine/report/json/report_json.cpp
index 80db8ebbb11..a9a7b6688fd 100644
--- a/engine/report/json/report_json.cpp
+++ b/engine/report/json/report_json.cpp
@@ -484,10 +484,18 @@ void to_json( JsonOutput root, const ::report::json::report_configuration_t& rep
json[ "time" ] = entry.time;
if ( entry.action )
{
- json[ "id" ] = entry.action->id;
+ json[ "id" ] = entry.action->id != 0 ? entry.action->id : entry.spell_id;
json[ "name" ] = entry.action->name();
json[ "target" ] = entry.action->harmful ? entry.target->name() : "none";
- json[ "spell_name" ] = entry.action->data_reporting().name_cstr();
+ util::string_view spell_name_view = entry.spell_name;
+ if ( spell_name_view.empty() )
+ {
+ const char* spell_name = entry.action->data_reporting().name_cstr();
+ if ( spell_name == nullptr || spell_name[ 0 ] == '\0' )
+ spell_name = entry.action->name_reporting();
+ spell_name_view = spell_name;
+ }
+ json[ "spell_name" ] = spell_name_view;
json[ "queue_failed" ] = entry.queue_failed;
if ( entry.action->item )
{
From 2ef993f3bb180f3f7044629f41f1e1f774b37db2 Mon Sep 17 00:00:00 2001
From: Pewtro <29204244+Pewtro@users.noreply.github.com>
Date: Fri, 24 Apr 2026 22:03:54 +0200
Subject: [PATCH 2/2] Handle strict sequences too
---
engine/player/player.cpp | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/engine/player/player.cpp b/engine/player/player.cpp
index ef386fdd101..973b1a24e70 100644
--- a/engine/player/player.cpp
+++ b/engine/player/player.cpp
@@ -6362,15 +6362,25 @@ void player_t::sequence_add( const action_t* a, const player_t* t )
data.spell_id = a->id;
if ( data.spell_id == 0 && a->type == ACTION_SEQUENCE )
{
- const sequence_t* seq = static_cast( a );
- if ( seq->current_action > 0 && seq->current_action <= as( seq->sub_actions.size() ) )
+ const sequence_t* seq = dynamic_cast( a );
+ const strict_sequence_t* strict_seq = nullptr;
+ if ( !seq )
+ strict_seq = dynamic_cast( a );
+
+ if ( seq || strict_seq )
{
- const action_t* sub_action = seq->sub_actions[ seq->current_action - 1 ];
- data.spell_id = sub_action->id;
- const char* spell_name = sub_action->data_reporting().name_cstr();
- if ( spell_name == nullptr || spell_name[ 0 ] == '\0' )
- spell_name = sub_action->name_reporting();
- data.spell_name = spell_name;
+ int idx = seq ? seq->current_action : static_cast( strict_seq->current_action );
+ const auto& sub_actions = seq ? seq->sub_actions : strict_seq->sub_actions;
+
+ if ( idx > 0 && idx <= as( sub_actions.size() ) )
+ {
+ const action_t* sub_action = sub_actions[ idx - 1 ];
+ data.spell_id = sub_action->id;
+ const char* spell_name = sub_action->data_reporting().name_cstr();
+ if ( spell_name == nullptr || spell_name[ 0 ] == '\0' )
+ spell_name = sub_action->name_reporting();
+ data.spell_name = spell_name;
+ }
}
}
}