88
99#define upn (val, start, end ) for (int val = start; val <= end; ++val)
1010#define JRef QJsonValueRef
11- #define VERSION " v2.1.1 "
11+ #define VERSION " v2.2 "
1212#define MAU W3MayaAnimUtil
1313
1414MAU::MAU (QWidget *parent)
@@ -17,7 +17,14 @@ MAU::MAU(QWidget *parent)
1717{
1818 ui->setupUi (this );
1919 // ui->textLog->setFontPointSize(20);
20- ui->textLog ->setHtml (" Welcome to <span style=\" font-weight:700;\" >MAU " + QString (VERSION " (" __DATE__ " )" ) + " </span>!<br>Made by <span style=\" color:#6f00a6;font-weight:700;\" >nikich340</span> for better the Witcher 3 modding experiene.<br><br>Click \" Load anim .json\" to start" );
20+ ui->textLog ->setHtml (" <!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0//EN\" \" http://www.w3.org/TR/REC-html40/strict.dtd\" >"
21+ " <html><head><meta name=\" qrichtext\" content=\" 1\" /><meta charset=\" utf-8\" /><style type=\" text/css\" >"
22+ " p, li { white-space: pre-wrap; }"
23+ " </style></head><body style=\" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;\" >"
24+ " <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\" >Welcome to <span style=\" font-weight:700;\" >W3MayaAnimUtil"
25+ + QString (VERSION " (" __DATE__ " )" )
26+ + " </span>.<br />Made by <span style=\" font-weight:696; color:#6f00a6;\" >nikich340</span> for better the Witcher 3 modding experiene.<br /><span style=\" font-style:italic;\" ><br /></span>Click "Load anim .json" to start.</p>"
27+ " <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\" ><img src=\" :/icons/motivated_small.png\" /></p></body></html>" );
2128 ui->spinSensivity ->setMinimum (0.0000000001 );
2229 ui->spinSensivity ->setSingleStep (0.00001 );
2330 ui->spinSensivity ->setValue (0.00001 );
@@ -28,6 +35,15 @@ MAU::MAU(QWidget *parent)
2835 }
2936 pLabelInfo = new QLabel ();
3037
38+ if (QSettings ().value (" GUIStyle" , " windowsvista" ) == " windowsvista" ) {
39+ ui->comboGUIStyle ->setCurrentText (" Windows" );
40+ } else if (QSettings ().value (" GUIStyle" , " windowsvista" ) == " Windows" ) {
41+ ui->comboGUIStyle ->setCurrentText (" WindowsXP" );
42+ } else {
43+ ui->comboGUIStyle ->setCurrentText (" Fusion" );
44+ }
45+
46+ connect (ui->comboGUIStyle , SIGNAL (currentTextChanged (QString)), this , SLOT (onChanged_GUIStyle (QString)));
3147 connect (ui->buttonLoad , SIGNAL (clicked (bool )), this , SLOT (onClicked_Load ()));
3248 connect (ui->buttonSave , SIGNAL (clicked (bool )), this , SLOT (onClicked_Save ()));
3349 connect (ui->buttonSaveSplit , SIGNAL (clicked (bool )), this , SLOT (onClicked_SaveSplit ()));
@@ -55,6 +71,7 @@ MAU::MAU(QWidget *parent)
5571 /* EVENTS EDIT */
5672 ui->comboEventsType ->addItems (m_knownEventTypes);
5773 ui->comboEventsVarType ->addItems (m_knownVarTypes);
74+ ui->comboEventsVarType ->addItems (m_knownEnumTypes.keys ());
5875 ui->stackEventsValue ->widget (0 )->setProperty (" type" , QString (" Bool" ));
5976 ui->stackEventsValue ->widget (1 )->setProperty (" type" , QString (" Int32" ));
6077 ui->stackEventsValue ->widget (2 )->setProperty (" type" , QString (" Float" ));
@@ -86,6 +103,8 @@ MAU::MAU(QWidget *parent)
86103 connect (ui->buttonResetEvents , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsReset ()));
87104 connect (ui->buttonApplyEvents , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsApply ()));
88105
106+ connect (ui->buttonEventsSort , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsSort ()));
107+ connect (ui->buttonEventsFixAnimationName , SIGNAL (clicked (bool )), this , SLOT (onClicked_fixAnimationNames ()));
89108 connect (ui->buttonEventsType , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsSetType ()));
90109 connect (ui->buttonEventsAdd , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsAdd ()));
91110 connect (ui->buttonEventsClone , SIGNAL (clicked (bool )), this , SLOT (onClicked_eventsClone ()));
@@ -214,8 +233,8 @@ void MAU::setEventStartTime(QJsonObject& eventObj, double newTime) {
214233 eventObj[" Content" ] = contentArr;
215234}
216235void MAU::onChanged_GUIStyle (QString newStyle) {
217- if (newStyle == " Windows " ) {
218- QSettings ().setValue (" GUIStyle" , " windowsvista " );
236+ if (newStyle == " Default " ) {
237+ QSettings ().remove (" GUIStyle" );
219238 } else if (newStyle == " WindowsXP" ) {
220239 QSettings ().setValue (" GUIStyle" , " Windows" );
221240 } else if (newStyle == " Fusion" ) {
@@ -357,12 +376,18 @@ void MAU::editRenameAnim(QJsonObject& animObj, QJsonArray& eventsArray, QString
357376void MAU::editSetCDPRDuration (QJsonObject& animObj) {
358377 QJsonObject animBuff = animObj.value (" animBuffer" ).toObject ();
359378 int animFrames = animBuff.value (" numFrames" ).toInt ();
379+ double durationCDPR = framesToSec (animFrames - 1 );
360380 addLog (QString (" \t [EDIT] Set anim and animBuffer duration = %1 s." )
361- .arg ( framesToSec (animFrames - 1 ) ));
381+ .arg ( durationCDPR ));
362382
363- animBuff[" duration" ] = framesToSec (animFrames - 1 ) ;
383+ animBuff[" duration" ] = durationCDPR ;
364384 animObj[" animBuffer" ] = animBuff;
365- animObj[" duration" ] = framesToSec (animFrames - 1 );
385+ animObj[" duration" ] = durationCDPR;
386+ if ( animObj.contains (" motionExtraction" ) ) {
387+ JSO motionObj = animObj[" motionExtraction" ].toObject ();
388+ motionObj[" duration" ] = qMin (motionObj[" duration" ].toDouble (), durationCDPR);
389+ animObj[" motionExtraction" ] = motionObj;
390+ }
366391 m_animDurations[m_animIndex] = framesToSec (animFrames - 1 );
367392}
368393
@@ -765,6 +790,9 @@ JSO MAU::varToEntry(QString entryName, QVariant val, QString customType) {
765790 if (customType.toUpper () == " CNAME" ) {
766791 entry[" Type" ] = " CName" ;
767792 entry[" Value" ] = val.toString ();
793+ } else if (m_knownEnumTypes.contains (customType)) {
794+ entry[" Type" ] = customType;
795+ entry[" Value" ] = val.toString ();
768796 } else {
769797 entry[" Type" ] = " StringAnsi" ;
770798 entry[" val" ] = val.toString ();
@@ -813,7 +841,7 @@ JSO MAU::varToEntry(QString entryName, QVariant val, QString customType) {
813841 QPair<QString, QString>(" cameraAnimOnMissedHit" , " CName" ),
814842 };
815843 } else {
816- qDebug () << QString (" varToEntry: Unknown type %2 for %1! " ).arg (entryName).arg (val.typeName ());
844+ addLog ( QString (" [ERROR] varToEntry: unknown type %1 for %2 " ).arg (entryName).arg (val.typeName ()), logError );
817845 return JSO ();
818846 }
819847 for (QPair<QString, QString> p : mapKeys) {
@@ -829,6 +857,7 @@ JSO MAU::varToEntry(QString entryName, QVariant val, QString customType) {
829857 }
830858 return entry;
831859}
860+
832861QVariant MAU::entryToVar (JSO entry) {
833862 if ( !entry.contains (" Type" ) ) {
834863 qDebug () << " entryToVar: entry type not found! Name: " << entry.value (" Name" ).toString ();;
@@ -852,6 +881,8 @@ QVariant MAU::entryToVar(JSO entry) {
852881 ret.append ( array.at (i).toString () );
853882 }
854883 return ret;
884+ } else if (m_knownEnumTypes.contains (type)) {
885+ return entry.value (" Value" ).toString ();
855886 } else if (type == " SEnumVariant" || type == " CPreAttackEventData" ) {
856887 QHash<QString, QVariant> ret = QHash<QString, QVariant>();
857888 JSA array = entry.value (" Content" ).toArray ();
@@ -864,10 +895,11 @@ QVariant MAU::entryToVar(JSO entry) {
864895 }
865896 return ret;
866897 } else {
867- qDebug () << QString (" entryToVar: Unknown type %1! " ).arg (type);
898+ addLog ( QString (" [ERROR] entryToVar: unknown type %1 for %2 " ).arg (type). arg (entry[ " Name " ]. toString ()), logError );
868899 return QVariant ();
869900 }
870901}
902+
871903void MAU::eventsLoad () {
872904 ui->listEvents ->clear ();
873905
@@ -878,6 +910,7 @@ void MAU::eventsLoad() {
878910 ui->listEvents ->setCurrentRow (0 );
879911 }
880912}
913+
881914QVariant MAU::getEventParam (QJsonObject eventObj, QString paramName, QVariant defaultValue) {
882915 QJsonArray contentArr = eventObj.value (" Content" ).toArray ();
883916 upn (j, 0 , contentArr.count () - 1 ) {
@@ -889,6 +922,7 @@ QVariant MAU::getEventParam(QJsonObject eventObj, QString paramName, QVariant de
889922 qDebug () << QString (" Can't find event %1! Type: %2" ).arg (paramName).arg (eventObj.value (" Type" ).toString ());
890923 return defaultValue;
891924}
925+
892926void MAU::eventsUpdateLabel (int eventIndex, bool add) {
893927 if (eventIndex < 0 )
894928 return ;
@@ -912,6 +946,7 @@ void MAU::eventsUpdateLabel(int eventIndex, bool add) {
912946 ui->listEvents ->item (eventIndex)->setText ( QString (" %1 #%2 [%3 s]" ).arg (type).arg (eventIndex).arg (startTime, 0 , ' f' , 3 ) );
913947 }
914948}
949+
915950void MAU::eventsUpdateContentLabel (int eventIndex, int index, bool add) {
916951 if (index < 0 || eventIndex < 0 )
917952 return ;
@@ -933,6 +968,7 @@ void MAU::eventsUpdateContentLabel(int eventIndex, int index, bool add) {
933968 ui->listEventsContent ->item (index)->setText ( QString (" %1 (%2) = %3" ).arg (entryName).arg (entryType).arg (value.toString ()) );
934969 }
935970}
971+
936972JSO MAU::defaultEntry (QString name, QString type) {
937973 JSO contentEntry = JSO ();
938974 if (type == " Bool" ) {
@@ -947,6 +983,8 @@ JSO MAU::defaultEntry(QString name, QString type) {
947983 contentEntry = varToEntry (name, " " , " CName" );
948984 } else if (type == " array:2,0,StringAnsi" ) {
949985 contentEntry = varToEntry ( name, QStringList ({" " }) );
986+ } else if (m_knownEnumTypes.contains (type)) {
987+ contentEntry = varToEntry (name, m_knownEnumTypes[type].first (), type);
950988 } else if (type == " SEnumVariant" ) {
951989 QHash<QString, QVariant> map = QHash<QString, QVariant>();
952990 map[" enumType" ] = QString (" ERotationRate" );
@@ -958,11 +996,40 @@ JSO MAU::defaultEntry(QString name, QString type) {
958996 map[" soundAttackType" ] = QString (" monster_big_bite" );
959997 map[" hitReactionType" ] = 1 ;
960998 contentEntry = varToEntry ( name, QVariant::fromValue (map), " CPreAttackEventData" );
999+ } else {
1000+ addLog (QString (" [ERROR] defaultEntry: unknown type %1 for %2" ).arg (type).arg (name), logError);
9611001 }
9621002 return contentEntry;
9631003}
9641004
9651005// EVENTS slots
1006+ void MAU::onClicked_eventsSort () {
1007+ editSortEvents (m_animEvents);
1008+ eventsLoad ();
1009+ addLog (QString (" [EVENTS] Sorted event entries: %2." )
1010+ .arg (m_animEvents.count ()));
1011+ }
1012+ void MAU::onClicked_fixAnimationNames () {
1013+ int fixed_vars = 0 ;
1014+
1015+ upn (eventIndex, 0 , m_animEvents.count () - 1 ) {
1016+ JSO eventObj = m_animEvents.at (eventIndex).toObject ();
1017+ JSA contentArr = eventObj.value (" Content" ).toArray ();
1018+ upn (index, 0 , contentArr.count () - 1 ) {
1019+ JSO contentEntry = contentArr.at (index).toObject ();
1020+ if (contentEntry[" Name" ] == " animationName" && contentEntry[" Value" ].toString () != m_animNames[m_animIndex]) {
1021+ contentEntry[" Value" ] = m_animNames[m_animIndex];
1022+ contentArr[index] = contentEntry;
1023+ ++fixed_vars;
1024+ }
1025+ }
1026+ eventObj[" Content" ] = contentArr;
1027+ m_animEvents[eventIndex] = eventObj;
1028+ }
1029+ eventsLoad ();
1030+ addLog (QString (" [EVENTS] Fixed animationName vars: %1." )
1031+ .arg (fixed_vars));
1032+ }
9661033void MAU::onChecked_DynamicLabel (bool checked) {
9671034 QCheckBox* box = qobject_cast<QCheckBox*>(sender ());
9681035 if (box != nullptr ) {
@@ -1014,16 +1081,61 @@ void MAU::onClicked_eventsAdd() {
10141081
10151082 QString type = ui->comboEventsType ->currentText ();
10161083 // generic CExtAnimEvent
1017- contentArr.append ( varToEntry (" eventName" , " - " , " CName" ) );
1018- contentArr.append ( varToEntry (" startTime" , 0.0 ) );
1084+ contentArr.append ( defaultEntry (" eventName" , " CName" ) );
1085+ contentArr.append ( defaultEntry (" startTime" , " Float " ) );
10191086 contentArr.append ( varToEntry (" animationName" , m_animNames[m_animIndex], " CName" ) );
1020- if (type.endsWith (" DurationEvent" )) {
1087+
1088+ if (type.endsWith (" DurationEvent" ) || type == " CEASEnumEvent" || type == " CPreAttackEvent" ) {
10211089 contentArr.append ( varToEntry (" duration" , qMax (0.01 , m_animDurations[m_animIndex] - framesToSec (1 ))) );
1022- contentArr.append ( varToEntry (" alwaysFiresEnd" , false ) );
1023- } else if (type.startsWith (" CExtAnimEffect" )) {
1024- contentArr.append ( varToEntry (" effectName" , " " , " CName" ) );
1090+ contentArr.append ( defaultEntry (" alwaysFiresEnd" , " Bool" ) );
1091+ }
1092+
1093+ if (type.startsWith (" CExtAnimEffect" )) {
1094+ contentArr.append ( defaultEntry (" effectName" , " CName" ) );
1095+ }
1096+ if (type == " CExtAnimEffectEvent" ) {
1097+ contentArr.append ( defaultEntry (" action" , " EAnimEffectAction" ) );
1098+ }
1099+ if (type == " CExtAnimItemEvent" ) {
1100+ contentArr.append ( defaultEntry (" category" , " CName" ) );
1101+ contentArr.append ( defaultEntry (" itemName_optional" , " CName" ) );
1102+ contentArr.append ( defaultEntry (" ignoreItemsWithTag" , " CName" ) );
1103+ contentArr.append ( defaultEntry (" action" , " EItemAction" ) );
1104+ }
1105+ if (type == " CExtAnimItemEffectEvent" ) {
1106+ contentArr.append ( defaultEntry (" effectName" , " CName" ) );
1107+ contentArr.append ( defaultEntry (" itemSlot" , " CName" ) );
1108+ contentArr.append ( defaultEntry (" action" , " EItemEffectAction" ) );
1109+ }
1110+
1111+ if (type.startsWith (" CExp" )) {
1112+ contentArr.append ( defaultEntry (" translation" , " Bool" ) );
1113+ contentArr.append ( defaultEntry (" rotation" , " Bool" ) );
1114+ }
1115+
1116+ if (type == " CExtAnimAttackEvent" ) {
1117+ contentArr.append ( defaultEntry (" soundAttackType" , " CName" ) );
1118+ }
1119+
1120+ if (type == " CExtAnimSoundEvent" || type == " CExtAnimFootstepEvent" ) {
1121+ contentArr.append ( defaultEntry (" soundEventName" , " StringAnsi" ) );
1122+ contentArr.append ( defaultEntry (" maxDistance" , " Float" ) );
1123+ contentArr.append ( defaultEntry (" bone" , " CName" ) );
1124+ contentArr.append ( defaultEntry (" switchesToUpdate" , " array:2,0,StringAnsi" ) );
1125+ }
1126+
1127+ if (type == " CExtAnimFootstepEvent" ) {
1128+ contentArr.append ( defaultEntry (" fx" , " Bool" ) );
1129+ contentArr.append ( defaultEntry (" customFxName" , " CName" ) );
1130+ }
1131+
1132+ if (type == " CEASEnumEvent" ) {
1133+ contentArr.append ( defaultEntry (" enumVariant" , " SEnumVariant" ) );
1134+ }
1135+
1136+ if (type == " CPreAttackEvent" ) {
1137+ contentArr.append ( defaultEntry (" data" , " CPreAttackEventData" ) );
10251138 }
1026- // TODO!!!
10271139
10281140 eventObj[" Content" ] = contentArr;
10291141 eventObj[" Name" ] = type;
@@ -1165,6 +1277,11 @@ void MAU::onChanged_eventContentRow(int newRow) {
11651277 } else if (entryType == " array:2,0,StringAnsi" ) {
11661278 ui->stackEventsValue ->setCurrentIndex (4 );
11671279 ui->editEventsValueArrayString ->setPlainText ( value.toStringList ().join (" \n " ) );
1280+ } else if (m_knownEnumTypes.contains (entryType)) {
1281+ ui->stackEventsValue ->setCurrentIndex (7 );
1282+ ui->comboEventsValueEnum ->clear ();
1283+ ui->comboEventsValueEnum ->addItems ( m_knownEnumTypes[entryType] );
1284+ ui->comboEventsValueEnum ->setCurrentText ( value.toString () );
11681285 } else if (entryType == " SEnumVariant" ) {
11691286 ui->stackEventsValue ->setCurrentIndex (5 );
11701287 QHash<QString, QVariant> map = value.value < QHash<QString, QVariant> >();
@@ -1304,6 +1421,8 @@ void MAU::onChanged_eventsVarAny() {
13041421 contentEntry = varToEntry ( entryName, ui->lineEventsValueString ->text (), entryType );
13051422 } else if (entryType == " array:2,0,StringAnsi" ) {
13061423 contentEntry = varToEntry ( entryName, ui->editEventsValueArrayString ->toPlainText ().split (" \n " ), entryType );
1424+ } else if (m_knownEnumTypes.contains (entryType)) {
1425+ contentEntry = varToEntry ( entryName, ui->comboEventsValueEnum ->currentText (), entryType );
13071426 } else if (entryType == " SEnumVariant" ) {
13081427 ui->stackEventsValue ->setCurrentIndex (5 );
13091428 QHash<QString, QVariant> map = QHash<QString, QVariant>();
0 commit comments