NSUNI/NSLAR Library a250670
Loading...
Searching...
No Matches
action.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#include <map>
13#include <set>
14
16#include "NNL/common/io.hpp"
18#include "NNL/utility/math.hpp"
19#include "tsl/ordered_map.h"
20
21namespace nnl {
26
31namespace action {
37
38constexpr u16 kNumAnimFuncNSUNI = 0x1C;
40
41constexpr u16 kNumEffectFuncNSUNI = 0x26;
43
44constexpr u16 kNumAnimFuncNSLAR = 0x14;
46
47constexpr u16 kNumEffectFuncNSLAR = 0xC;
49
68enum class AnimationFunction : u16 {
69 kEnd = 0,
70 kNext = 1,
71 kGoto = 2,
73 // 3 NULL, causes a crash
74 // 4 NULL, causes a crash
86 kUnkD = 0xD,
93 kUnk11 = 0x11,
94 kUnk12 = 0x12,
95 kUnk13 = 0x13,
96 // NSUNI ONLY:
99 kWaitAfter = 0x15,
101 kWaitBefore = 0x16,
107 kUnk1A = 0x1A,
112};
113
125 NNL_PACK(struct {
126 AnimationFunction function;
127 u8 next_main_node;
129 bool flag;
131 })
132 main;
133
134 u8 args[4];
135};
136
137static_assert(sizeof(AnimationNode) == 0x4);
138
157enum class EffectFunction : u8 {
158 kEnd = 0,
165 // 5 NULL
171 // 9 NULL
174 kUnkC = 0xC,
175 kNextD = 0xD,
176 kNextE = 0xE,
177 kNextF = 0xF,
178 kUnk10 = 0x10,
179 kUnk11 = 0x11,
180 kUnk12 = 0x12,
181 kSetFlags13 = 0x13,
182 // NSUNI only:
184 kSetFlags15 = 0x15,
185 kSetFlags16 = 0x16,
186 kUnk17 = 0x17,
187 kUnk18 = 0x18,
188 kSlowdown = 0x19,
201 kUnk1C = 0x1C,
216 kSetFlags23 = 0x23,
217 kUnk24 = 0x24,
218 kUnk25 = 0x25
219
220};
221
235 NNL_PACK(struct {
236 EffectFunction function;
237 u8 next_main_node;
240 u16 frame_ticks;
242 })
243 main;
244
245 u8 args[4];
246};
247
248static_assert(sizeof(EffectNode) == 0x4);
249
259struct Action {
260 std::string name = "";
261 std::vector<AnimationNode> animation_nodes;
264
265 std::vector<EffectNode> effect_nodes;
267};
268
285
286using ActionConfig = tsl::ordered_map<action::Id, Action>;
287
299bool IsOfType(BufferView buffer);
300
301bool IsOfType(const std::filesystem::path& path);
302
303bool IsOfType(Reader& f);
304
319
320ActionConfig Import(const std::filesystem::path& path);
321
323
335[[nodiscard]] Buffer Export(const ActionConfig& action_config);
336
337void Export(const ActionConfig& action_config, const std::filesystem::path& path);
338
339void Export(const ActionConfig& action_config, Writer& f); // Main
341
347
357std::map<u16, std::set<std::string>> GetAnimationNames(const ActionConfig& action_config);
358
379template <class... Ts, class Node>
380inline std::tuple<Ts...> ReadArgs(std::size_t main_node_ind, const std::vector<Node>& nodes) {
381 static_assert(std::is_same_v<Node, AnimationNode> || std::is_same_v<Node, EffectNode>, "not a node");
382 std::tuple<Ts...> result;
383 std::size_t offset = 0;
384 std::apply(
385 [&](auto&... args) {
386 (([&]() {
387 static_assert(std::is_trivially_copyable_v<std::remove_reference_t<decltype(args)>>);
388 static_assert(sizeof(args) <= sizeof(Node));
389
390 offset = utl::math::RoundNum(offset, sizeof(args));
391
392 auto& main_node = nodes.at(main_node_ind).main;
393
394 std::size_t required_size =
395 main_node_ind + 1 + (utl::math::RoundNum(offset + sizeof(args), sizeof(Node)) / sizeof(Node));
396
397 if (required_size > nodes.size())
398 NNL_THROW(nnl::RangeError(NNL_SRCTAG("Read exceeds the size of available nodes")));
399
400 if (sizeof(Node) + offset + sizeof(args) > main_node.next_main_node * sizeof(Node))
401 NNL_THROW(nnl::RangeError(NNL_SRCTAG("Read exceeds the size of the argument nodes")));
402
403 std::memcpy(&args, reinterpret_cast<const char*>(nodes.data() + main_node_ind + 1) + offset, sizeof(args));
404
405 offset += sizeof(args);
406 }()),
407 ...);
408 },
409 result);
410
411 return result;
412}
413
439template <class... Ts, class Node>
440inline void WriteArgs(std::size_t main_node_ind, std::vector<Node>& nodes, const Ts&&... args) {
441 static_assert(std::is_same_v<Node, AnimationNode> || std::is_same_v<Node, EffectNode>, "not a node");
442 std::size_t offset = 0;
443 (
444 [&] {
445 static_assert(std::is_trivially_copyable_v<std::remove_reference_t<decltype(args)>>);
446
447 static_assert(sizeof(args) <= sizeof(Node));
448
449 auto& main_node = nodes.at(main_node_ind).main;
450
451 offset = utl::math::RoundNum(offset, sizeof(args));
452
453 std::size_t required_size =
454 main_node_ind + 1 + (utl::math::RoundNum(offset + sizeof(args), sizeof(Node)) / sizeof(Node));
455
456 if (main_node.next_main_node != 0 &&
457 sizeof(Node) + offset + sizeof(args) > main_node.next_main_node * sizeof(Node))
458 NNL_THROW(nnl::RangeError(NNL_SRCTAG("Write exceeds the size of the argument nodes")));
459
460 if (required_size > nodes.size()) {
461 nodes.resize(required_size);
462 }
463
464 std::memcpy(reinterpret_cast<char*>(nodes.data() + main_node_ind + 1) + offset, &args, sizeof(args));
465
466 offset += sizeof(args);
467 }(),
468 ...);
469
470 std::size_t index_next_node = 1 + utl::math::RoundNum(offset, sizeof(Node)) / sizeof(Node);
471
472 auto& main_node = nodes.at(main_node_ind).main;
473
474 if (index_next_node > main_node.next_main_node) main_node.next_main_node = index_next_node;
475}
476
485template <class Node>
486inline std::size_t NextNodeInd(std::size_t main_node_ind, const std::vector<Node>& nodes) {
487 static_assert(std::is_same_v<Node, AnimationNode> || std::is_same_v<Node, EffectNode>, "not a node");
488 const auto& main_node = nodes.at(main_node_ind).main;
489 return main_node_ind + main_node.next_main_node;
490}
491 // Aux
492
493namespace raw {
507
508NNL_PACK(struct RActionCategory {
509 u32 offset = 0;
510 u32 num_actions = 0;
511});
512
513static_assert(sizeof(RActionCategory) == 0x8);
514
515NNL_PACK(struct RHeader { RActionCategory action_categories[kNumActionCategories]; });
516
517static_assert(sizeof(RHeader) == 0x20);
518
519NNL_PACK(struct RAction {
520 u16 offset_animation_nodes = 0;
521 u16 offset_action_name = 0;
522 u16 offset_effect_nodes = 0;
523 u16 offset_unknown = 0; // reserved?
524});
525
526static_assert(sizeof(RAction) == 0x8);
527
528NNL_PACK(struct RAnimationNode {
529 u16 index_function = 0;
530 u8 next_main_node = 1;
531 u8 unk_flag = 0;
532});
533
534static_assert(sizeof(RAnimationNode) == 0x4);
535static_assert(sizeof(RAnimationNode) == sizeof(AnimationNode));
536
537NNL_PACK(struct REffectNode {
538 u8 index_function = 0;
539 u8 next_main_node = 0;
540 u16 time_tick = 0;
541});
542
543static_assert(sizeof(REffectNode) == 0x4);
544static_assert(sizeof(REffectNode) == sizeof(EffectNode));
545
546struct RActionConfig {
547 RHeader header;
548 // Maps of offsets (used in the structures) to their data:
549 std::map<u32, std::vector<RAction>> actions;
550 std::map<u16, std::vector<RAnimationNode>> animation_nodes;
551 std::map<u16, std::string> action_names;
552 std::map<u16, std::vector<REffectNode>> effect_nodes;
553};
554
555ActionConfig Convert(RActionConfig&& raction_config);
556
557RActionConfig Parse(Reader& f); // Raw
559} // namespace raw
560} // namespace action
561
562} // namespace nnl
Contains the definition for action identifiers that are used across different parts of the library.
Contains macros and definitions for fixed-width types.
std::map< u16, std::set< std::string > > GetAnimationNames(const ActionConfig &action_config)
Returns a map of animation IDs and names of all actions in which those animations were used.
std::tuple< Ts... > ReadArgs(std::size_t main_node_ind, const std::vector< Node > &nodes)
Extracts arguments from a series of nodes.
Definition action.hpp:380
std::size_t NextNodeInd(std::size_t main_node_ind, const std::vector< Node > &nodes)
Calculates the absolute index of the next main node in a vector.
Definition action.hpp:486
void WriteArgs(std::size_t main_node_ind, std::vector< Node > &nodes, const Ts &&... args)
Converts arguments to a series of nodes.
Definition action.hpp:440
std::vector< EffectNode > effect_nodes
Definition action.hpp:265
NNL_PACK(struct { AnimationFunction function;u8 next_main_node;bool flag;}) main
Layout of a main node.
u8 args[4]
Raw memory for storing argument values in argument nodes.
Definition action.hpp:134
std::vector< AnimationNode > animation_nodes
Definition action.hpp:261
u8 args[4]
Array for storing argument values (in argument nodes)
Definition action.hpp:245
std::string name
The name of the action. It does not affect anything.
Definition action.hpp:260
A union that represents a function or argument node within an animation playback chain.
Definition action.hpp:124
A union that represents a function or argument node within an auxiliary effect playback chain.
Definition action.hpp:234
Represents an action.
Definition action.hpp:259
constexpr u16 kNumAnimFuncNSLAR
Definition action.hpp:44
ActionConfig Import(BufferView buffer)
Parses a binary file and converts it to ActionConfig.
AnimationFunction
Enumeration for different animation functions.
Definition action.hpp:68
constexpr u16 kNumAnimFuncNSUNI
Definition action.hpp:38
tsl::ordered_map< action::Id, Action > ActionConfig
Represents a collection of actions associated with an entity.
Definition action.hpp:286
constexpr u16 kNumEffectFuncNSUNI
Definition action.hpp:41
EffectFunction
Enumeration for different effect functions.
Definition action.hpp:157
constexpr u16 kNumEffectFuncNSLAR
Definition action.hpp:47
bool IsOfType(BufferView buffer)
Tests if the provided file is an action config.
Buffer Export(const ActionConfig &action_config)
Converts ActionConfig to a binary file representation.
@ kEndAnimationPlayback
This is used after 0xF, 0x6, 0x5; [].
Definition action.hpp:79
@ kEnableEffect
Definition action.hpp:105
@ kSetMeshGroupVisib
Definition action.hpp:97
@ kEnd
Mark the end of a node sequence; [].
Definition action.hpp:69
@ kUnk11
Might call a function; [{u16,_},{u32}].
Definition action.hpp:93
@ kPlayAnimation
Definition action.hpp:89
@ kInitCountdown
Init a countdown; a0 - time?, a1 ? [{u16,u16}].
Definition action.hpp:83
@ kSetBossHitTarget
Something related to a hit circle on bosses; [{i16,i16}].
Definition action.hpp:85
@ kCheckCountdown
Check if the countdown is 0; [].
Definition action.hpp:84
@ kGoto
Definition action.hpp:71
@ kTransitionToAnimation6
Definition action.hpp:76
@ kUnk13
Might call a function; [{unused}].
Definition action.hpp:95
@ kInitAnimationPlayback
This is used before 0xF (sometimes 0x6); [].
Definition action.hpp:80
@ kTransitionToAnimation5
Seems to be almost the same as 0x6; [{i16,i16}].
Definition action.hpp:75
@ kSetFlags
Definition action.hpp:81
@ kWaitAfter
Definition action.hpp:99
@ kNext
Jump to the next specified node; [].
Definition action.hpp:70
@ kWaitBefore
Definition action.hpp:101
@ kUnkD
Might call a function; [{i32}].
Definition action.hpp:86
@ kDisableTextureSwap
Disable a texture swap; a0 - texture swap id; [{u16,_}].
Definition action.hpp:104
@ kUnk12
?; if a0 == 0 animation gets stuck; [{u16,_}]
Definition action.hpp:94
@ kUnk1A
Definition action.hpp:107
@ kSetAnimSpeed
Definition action.hpp:87
@ kEnableTextureSwap
Activate a texture swap; a0 - texture swap id; [{u16,_}].
Definition action.hpp:103
@ kSetComboTransitFrames
Definition action.hpp:109
@ kSetAnimStartFrame
Definition action.hpp:91
@ kSetFlags16
[{u32},{u16,u16}]
Definition action.hpp:185
@ kNextD
Does nothing?; [].
Definition action.hpp:175
@ kOpacityTransition3
? a0 - type, a1 - num frames, a2 - ? [{u16, i16}, {f32}]
Definition action.hpp:163
@ kPlaySFX
Definition action.hpp:167
@ kAnimateCamera1F
Definition action.hpp:211
@ kNextF
Does nothing?; [].
Definition action.hpp:177
@ kPlayUVAnim
a0 - uv anim id, a1 - u_shift, a2 - v_shift [{u16,i16},{i16,_}]
Definition action.hpp:172
@ kOpacityTransitionB
a0 - unk, a1 - vfx group id, [{u8, u8, u16}, {f32}]
Definition action.hpp:173
@ kOpacityTransition4
? [{u16, i16},{f32}]
Definition action.hpp:164
@ kOpacityTransition6
? [{u16,i16},{i16,i16}]
Definition action.hpp:166
@ kEnableEffect14
a0 - effect id [{u16,i16}]
Definition action.hpp:183
@ kMoveRootBone
Definition action.hpp:209
@ kPlaySFXRND
Definition action.hpp:169
@ kUnk17
? [{u16,i16},{f32},{f32},{f32},{f32}];
Definition action.hpp:186
@ kUnk10
?
Definition action.hpp:178
@ kSlowdown
?
Definition action.hpp:188
@ kSetFlags1
Definition action.hpp:159
@ kSetTextureSwapStat
a0 - swap id, a1 - enabled/disabled [{u16, u16}]
Definition action.hpp:215
@ kUnkC
?
Definition action.hpp:174
@ kUnk18
?
Definition action.hpp:187
@ kUnk1C
?
Definition action.hpp:201
@ kSetFlags15
? [{u32},{u16,u16}]
Definition action.hpp:184
@ kUnk25
? Used in "Scene" action configs [{}, {}]
Definition action.hpp:218
@ kSetFlags23
Set some character flags (?) [{i16,i16},{i16,i16},{i16,i16}].
Definition action.hpp:216
@ kEnableEffect1B
Definition action.hpp:199
@ kSetFlags13
?
Definition action.hpp:181
@ kNextE
Does nothing?; [].
Definition action.hpp:176
@ kEnableDisplayEffect
Definition action.hpp:189
@ kAnimateCamera
Definition action.hpp:202
@ kEnableJutsuEffect
The num of args may vary.
Definition action.hpp:214
constexpr std::size_t kNumActionCategories
Defines the number of action categories;.
Definition action_common.hpp:34
Exception thrown for out-of-range errors.
Definition exception.hpp:111
#define NNL_THROW(object)
Throws an exception or terminates the program if exceptions are disabled.
Definition exception.hpp:46
std::uint16_t u16
16-bit unsigned integer
Definition fixed_type.hpp:62
std::uint32_t u32
32-bit unsigned integer
Definition fixed_type.hpp:60
std::uint8_t u8
8-bit unsigned integer
Definition fixed_type.hpp:64
#define NNL_PACK(...)
A structure packing directive.
Definition fixed_type.hpp:41
Reader implementation for read-only memory buffers.
Definition io.hpp:598
Abstract class for writing data.
Definition io.hpp:136
Abstract class for reading data.
Definition io.hpp:78
std::vector< u8 > Buffer
A type alias for std::vector<u8> that denotes a raw, contiguous memory region that may be interpreted...
Definition io.hpp:40
T RoundNum(T number, std::size_t multiple)
Rounds number up to the nearest multiple.
Definition math.hpp:219
Provides classes for reading and writing binary data to and from various sources.
Provides various math utility functions.
Contains structures and functions for working with game actions.
Definition action.hpp:31
Definition exception.hpp:56