2023-05-04 09:57:42 +08:00
const path = require ( "path" ) ;
const fs = require ( "fs" ) ;
2024-06-15 14:30:50 +08:00
const questData3 _2 = "QuestExcelConfigData_3.2.json" ;
const fileOutput = path . join ( _ _dirname , "../Resources/ExcelBinOutput/QuestExcelConfigData.json" ) ;
2023-05-04 09:57:42 +08:00
if ( ! fs . existsSync ( questData3 _2 ) ) {
2024-06-15 14:30:50 +08:00
console . log ( "Place a copy of QuestExcelConfigData for game version 3.2 ori or 4.0 mod in same directory as this script." ) ;
2023-05-27 14:18:32 +08:00
console . log ( ` Name the file ${ questData3 _2 } . ` ) ;
return ;
2023-05-04 09:57:42 +08:00
}
2024-06-15 14:30:50 +08:00
const questPatches32Bin = "Quest32" ;
2023-09-26 13:07:09 +08:00
2023-05-26 08:07:57 +08:00
const questPatchesDir = "Patches/Quest" ;
if ( ! fs . existsSync ( questPatchesDir ) ) {
2023-05-27 14:18:32 +08:00
console . log (
"Place a copy of the patches directory from the custom resources repository in the same directory as this script."
) ;
console . log ( "Ensure the custom resources has a 'Quest' directory." ) ;
return ;
2023-05-26 08:07:57 +08:00
}
// btw use `npx prettier --write .` in folder scene after patch
2024-06-15 14:30:50 +08:00
// This should only be done if it is truly unknown and should only be done manually quest
2023-05-04 09:57:42 +08:00
const unknownCondition = {
2023-05-27 14:18:32 +08:00
type : "QUEST_COND_UNKNOWN" ,
param : [ 0 , 0 ] ,
2023-09-28 17:39:43 +08:00
param _str : ""
2023-05-04 09:57:42 +08:00
} ;
2023-09-28 17:39:43 +08:00
2024-06-15 14:30:50 +08:00
// Not all quests have cond in 3.2 but they are already known so it should be QUEST_COND_NONE right?
const NoneCondition = {
type : "QUEST_COND_NONE" ,
param : [ 0 , 0 ] ,
param _str : ""
} ;
2023-05-04 09:57:42 +08:00
const questBlacklist = [
2023-05-27 14:18:32 +08:00
"acceptCond" ,
"finishCond" ,
"failCond" ,
"beginExec" ,
"finishExec" ,
"failExec" ,
2023-05-04 09:57:42 +08:00
] ;
/ *
* These are quests patches which should be applied .
* These are ( basically ) applied last .
2023-09-26 13:07:09 +08:00
* Format is : { questId : { ( patches _data ) } }
2023-05-04 09:57:42 +08:00
* /
2023-09-26 13:07:09 +08:00
const patches _data = {
2023-05-27 14:18:32 +08:00
35402 : {
gainItems : [
{
itemId : 1021 ,
count : 1 ,
} ,
] ,
} ,
35104 : {
beginExec : [
{
type : "QUEST_EXEC_SET_IS_GAME_TIME_LOCKED" ,
param : [ "1" ] ,
param _str : "" ,
} ,
] ,
} ,
2023-05-04 09:57:42 +08:00
} ;
2023-05-26 08:07:57 +08:00
/ *
* These are main quest patches which should be applied .
* These are ( basically ) applied last .
2023-09-26 13:07:09 +08:00
* Format is : { mainId : { ( patches _data ) } }
2023-05-26 08:07:57 +08:00
* /
2023-05-27 14:18:32 +08:00
const mainPatches = { } ;
2023-05-26 08:07:57 +08:00
// Load quest patches from the patches directory.
const questPatches = fs . readdirSync ( questPatchesDir ) ;
for ( const questPatch of questPatches ) {
2023-05-27 14:18:32 +08:00
const patchData = JSON . parse (
fs . readFileSync ( path . join ( questPatchesDir , questPatch ) , "utf-8" )
) ;
const mainQuestId = patchData . id ;
// Check if the patch has sub-quests.
if ( patchData . subQuests ) {
2023-09-26 13:07:09 +08:00
for ( const i of patchData . subQuests ) {
const { subId } = i ;
2023-05-27 14:18:32 +08:00
// Clean the quest data.
2023-09-26 13:07:09 +08:00
delete i . subId ;
delete i . mainId ;
2023-05-27 14:18:32 +08:00
2023-09-26 13:07:09 +08:00
// Apply patch.
patches _data [ subId ] = i ;
2023-05-26 08:07:57 +08:00
}
2023-05-27 14:18:32 +08:00
}
2023-05-26 08:07:57 +08:00
2023-05-27 14:18:32 +08:00
delete patchData . id ;
delete patchData . subQuests ;
if ( Object . keys ( patchData ) . length > 0 ) {
mainPatches [ mainQuestId ] = patchData ;
}
2023-05-26 08:07:57 +08:00
}
2023-09-28 17:39:43 +08:00
// Function to remove duplicates
function removeDuplicates ( array ) {
const uniqueArray = [ ] ;
array . forEach ( ( item ) => {
if (
! uniqueArray . some ( ( existingItem ) =>
JSON . stringify ( existingItem ) === JSON . stringify ( item )
)
) {
uniqueArray . push ( item ) ;
}
} ) ;
return uniqueArray ;
}
2023-05-04 09:57:42 +08:00
/ * *
* Returns a cleaned version of a condition / execution .
*
* @ param condition The condition data .
* /
function clean ( condition ) {
2023-05-27 14:18:32 +08:00
let { type , param , param _str , count } = {
type : condition . _type ? ? condition . type ,
param : condition . _param ? ? condition . param ,
2023-09-28 17:39:43 +08:00
param _str : condition . _param _str ? ? condition . param _str ? ? condition . paramString ,
2023-05-27 14:18:32 +08:00
count : condition . _count ? ? condition [ "count" ] ,
} ;
const object = {
type ,
param : ! param
2023-09-28 17:39:43 +08:00
? [ 0 , 0 ] // fix Index 0 out of bounds for length 0 (1=main quest id, 2=status?)
2023-05-27 14:18:32 +08:00
: param . filter ( ( param ) => param !== null && param !== "" ) ,
2023-09-28 17:39:43 +08:00
param _str : param _str ? ? "" , // java.lang.NumberFormatException: For input string: "" (need fix in gc)
2023-05-27 14:18:32 +08:00
} ;
// Check for a 'count' parameter.
if ( count ) object . count = count ;
2023-09-28 17:39:43 +08:00
// make sure there is always status?
if ( object . param . length >= 0 ) {
if ( typeof object . param [ 0 ] == "number" ) {
if ( object . param [ 1 ] == null ) {
object . param [ 1 ] = 0 ;
}
} else if ( object . param [ 0 ] == null ) {
//console.log(object);
object . param [ 0 ] = 0 ;
object . param [ 1 ] = 0 ;
} else {
if ( object . param [ 1 ] == null ) {
object . param [ 1 ] = ` 0 ` ;
}
}
} else {
object . param = [ 0 , 0 ]
}
// skip
if ( object . type == null ) {
object . param = [ ] ;
object . param _str = ""
}
2023-05-27 14:18:32 +08:00
return object ;
2023-05-04 09:57:42 +08:00
}
/ * *
* Returns a cleaned version of the guide .
*
* @ param guide The guide data .
* /
function cleanGuide ( guide ) {
2023-05-27 14:18:32 +08:00
// Check for a param field.
if ( guide . param == null ) return guide ;
2023-05-04 09:57:42 +08:00
2023-05-27 14:18:32 +08:00
guide . param = guide . param . filter ( ( param ) => param !== null && param !== "" ) ;
2023-05-04 09:57:42 +08:00
2023-05-27 14:18:32 +08:00
return guide ;
2023-05-04 09:57:42 +08:00
}
/ * *
* Removes un - used fields from an object .
*
* @ param object The object .
* @ param blacklist Fields to ignore .
* /
function removeFields ( object , blacklist = [ ] ) {
2023-05-27 14:18:32 +08:00
for ( const field in object ) {
if ( blacklist . includes ( field ) ) continue ;
2023-05-04 09:57:42 +08:00
2023-05-27 14:18:32 +08:00
if ( object [ field ] == null ) delete object [ field ] ;
if ( Array . isArray ( object [ field ] ) ) {
if ( object [ field ] . length === 0 ) delete object [ field ] ;
2023-05-04 09:57:42 +08:00
}
2023-05-27 14:18:32 +08:00
}
2023-05-04 09:57:42 +08:00
}
const binOutput = path . join ( _ _dirname , "../Resources/BinOutput/Quest" ) ;
2023-05-27 14:18:32 +08:00
const mainQuestFile = path . join (
_ _dirname ,
"../Resources/ExcelBinOutput/MainQuestExcelConfigData.json"
) ;
const talkFile = path . join (
_ _dirname ,
"../Resources/ExcelBinOutput/TalkExcelConfigData.json"
) ;
2023-05-04 09:57:42 +08:00
// Load the data from the files.
const rel3 _2 = fs . readFileSync ( questData3 _2 , "utf-8" ) ;
const latest = fs . readFileSync ( fileOutput , "utf-8" ) ;
const mainQuest = fs . readFileSync ( mainQuestFile , "utf-8" ) ;
const talks = fs . readFileSync ( talkFile , "utf-8" ) ;
// Parse the data into JSON.
/** @type array */
const rel3 _2 _data = JSON . parse ( rel3 _2 ) ;
/** @type array */
const latest _data = JSON . parse ( latest ) ;
/** @type array */
const mainQuest _data = JSON . parse ( mainQuest ) ;
/** @type array */
const talks _data = JSON . parse ( talks ) ;
// Merge the data.
2023-09-26 13:07:09 +08:00
const quests _config = [ ] ;
2023-05-04 11:40:41 +08:00
const newQuests = [ ] ;
2023-05-26 18:58:49 +08:00
const newQuestsNoFound = [ ] ;
2023-09-28 17:39:43 +08:00
2023-09-26 13:07:09 +08:00
var count _patch32 = 0 ;
2023-09-28 17:39:43 +08:00
var count _no _acceptCond = 0 ;
var count _no _finishCond = 0 ;
// quest data (in bin, new)
2023-05-04 09:57:42 +08:00
for ( const mainQuestData of mainQuest _data ) {
2023-05-27 14:18:32 +08:00
const mainQuestId = mainQuestData . id ;
2023-09-28 17:39:43 +08:00
// dev tes
/ *
if ( mainQuestId != 3000 ) { // or 3000 or 347
// skip
continue ;
}
* /
2023-05-27 14:18:32 +08:00
const binfile = ` ${ binOutput } / ${ mainQuestId } .json ` ;
2023-09-26 13:07:09 +08:00
const binfile32 = ` ${ questPatches32Bin } / ${ mainQuestId } .json ` ;
2023-05-27 14:18:32 +08:00
2023-09-26 13:07:09 +08:00
//console.log(`Scanning main quest ${mainQuestId}...`);
2023-05-27 14:18:32 +08:00
// Find all sub-quests for the main quest.
let isNewQuest = false ;
2023-09-28 17:39:43 +08:00
// quest data (in config quest 3.2 old)
let main _data = rel3 _2 _data . filter ( ( i ) => i . mainId === mainQuestId ) ;
if ( main _data . length == 0 ) {
// This will be considered a new quest if no quest configuration is found in version 3.2. based on main_data file data
2023-05-27 14:18:32 +08:00
isNewQuest = true ;
2023-05-27 15:06:47 +08:00
2023-09-28 17:39:43 +08:00
// since not all new quests are in `QuestExcelConfigData` we have to look again in `Quest bin folder` so both should be there. and sometimes the `Quest Bin Folder` doesn't have new quest data so we have to look in `quest main` or `quest config` in `Excel folder` or use gio data?
var check _new = latest _data . filter ( ( i ) => i . mainId === mainQuestId ) ; // Note: this as subQuests
if ( check _new . length == 0 ) {
// if new not found, find alt
//process.exit()
2024-06-15 14:30:50 +08:00
2023-09-26 13:07:09 +08:00
if ( fs . existsSync ( binfile ) ) {
2023-09-28 17:39:43 +08:00
const binsub _d = JSON . parse ( fs . readFileSync ( binfile ) ) ;
let r = binsub _d . subQuests ;
2024-06-15 14:30:50 +08:00
if ( r ) {
main _data = r ; // copy `bin sub quest` to `config main_data for sub quest` (copy as laset quest bin)
2023-09-28 17:39:43 +08:00
} else {
2024-06-15 14:30:50 +08:00
console . log ( ` not found sub quest alternatives quest main ${ binfile } ` , binsub _d ) ;
2023-09-26 13:07:09 +08:00
}
2023-09-28 17:39:43 +08:00
} else {
2024-06-15 14:30:50 +08:00
console . log ( ` not found file bin sub quest: ${ binfile } ` ) ;
2023-05-27 14:18:32 +08:00
}
2023-09-28 17:39:43 +08:00
} else {
main _data = check _new // copy as 3.2
2023-05-27 14:18:32 +08:00
}
2023-09-28 17:39:43 +08:00
// count (subQuests)
if ( main _data . length != 0 ) {
2023-05-27 14:18:32 +08:00
newQuests . push ( mainQuestId ) ;
} else {
newQuestsNoFound . push ( mainQuestId ) ;
}
2023-09-26 13:07:09 +08:00
}
2023-09-28 17:39:43 +08:00
// Check if quest has sub-quests. (main_data as subQuests)
if ( main _data . length == 0 ) {
2024-06-15 14:30:50 +08:00
console . log ( ` Main quest ${ mainQuestId } has no sub-quests, skipping... ` , mainQuestData ) ;
2023-09-26 13:07:09 +08:00
continue ;
}
2024-06-15 14:30:50 +08:00
console . log ( "=====================================" ) ;
console . log ( ` Performing merge on main quest ${ mainQuestId } . ` ) ;
console . log ( ` There are ${ main _data . length } sub-quests. ` ) ;
console . log ( "=====================================" ) ;
2023-05-27 14:18:32 +08:00
// Create the base quest data.
2023-09-26 13:07:09 +08:00
const quest _bin = {
2023-05-27 14:18:32 +08:00
/** @type number */ id : mainQuestId ,
/** @type string */ type : mainQuestData . type ,
/** @type number */ series : mainQuestData . series ,
/** @type number */ titleTextMapHash : mainQuestData . titleTextMapHash ,
/** @type number */ descTextMapHash : mainQuestData . descTextMapHash ,
/** @type string */ luaPath : mainQuestData . luaPath ,
/** @type string */ showType : mainQuestData . showType ,
2023-09-28 17:39:43 +08:00
/** @type number[] */ suggestTrackMainQuestList : mainQuestData . suggestTrackMainQuestList ,
2023-05-27 14:18:32 +08:00
/** @type number[] */ rewardIdList : mainQuestData . rewardIdList ,
/** @type number[] */ chapterId : mainQuestData . chapterId ,
/** @type any[] */ subQuests : [ ] ,
/** @type any[] */ talks : [ ] ,
} ;
2023-09-28 17:39:43 +08:00
// find patch 3.2
var bin32 ;
if ( fs . existsSync ( binfile32 ) ) {
bin32 = JSON . parse ( fs . readFileSync ( binfile32 ) ) ;
}
// Create sub-quests for quest.
for ( const subQuestBin of main _data ) {
// Patch all to bin quest, if found config 3.2 gio
const bin32config = bin32 . subQuests . filter ( ( item ) => item . subId === subQuestBin . subId ) [ 0 ] ;
if ( bin32config ) {
if ( bin32config . acceptCond != null )
subQuestBin . acceptCond = bin32config . acceptCond ;
if ( bin32config . finishCond != null )
subQuestBin . finishCond = bin32config . finishCond ;
if ( bin32config . guide != null )
subQuestBin . guide = bin32config . guide ;
if ( bin32config . failCond != null )
subQuestBin . failCond = bin32config . failCond ;
if ( bin32config . beginExec != null )
subQuestBin . beginExec = bin32config . beginExec ;
if ( bin32config . finishExec != null )
subQuestBin . finishExec = bin32config . finishExec ;
if ( bin32config . failExec != null )
subQuestBin . failExec = bin32config . failExec ;
if ( bin32config . acceptCondComb != null )
subQuestBin . acceptCondComb = bin32config . acceptCondComb ;
if ( bin32config . finishCondComb != null )
subQuestBin . finishCondComb = bin32config . finishCondComb ;
count _patch32 ++ ;
}
2023-09-26 13:07:09 +08:00
// sub config
const subQuest _config = {
2023-05-27 14:18:32 +08:00
json _file : ` ${ mainQuestId } .json ` ,
2023-09-26 13:07:09 +08:00
... subQuestBin ,
2023-05-27 14:18:32 +08:00
} ;
2023-05-26 18:58:49 +08:00
2024-06-15 14:30:50 +08:00
//console.log(subQuest_config)
//process.exit(1)
2023-05-27 14:18:32 +08:00
// Validate conditions.
const {
/** @type any[] */ acceptCond ,
/** @type any[] */ finishCond ,
/** @type any[] */ failCond ,
2023-09-26 13:07:09 +08:00
} = subQuestBin ;
2023-05-27 14:18:32 +08:00
if ( acceptCond ) {
2023-09-28 17:39:43 +08:00
subQuest _config . acceptCond = removeDuplicates ( acceptCond . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( finishCond ) {
2023-09-28 17:39:43 +08:00
subQuest _config . finishCond = removeDuplicates ( finishCond . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( failCond ) {
2023-09-28 17:39:43 +08:00
subQuest _config . failCond = removeDuplicates ( failCond . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
2023-05-04 09:57:42 +08:00
2023-05-27 14:18:32 +08:00
// Validate executions.
const {
/** @type any[] */ beginExec ,
/** @type any[] */ finishExec ,
/** @type any[] */ failExec ,
2023-09-26 13:07:09 +08:00
} = subQuestBin ;
2023-05-27 14:18:32 +08:00
if ( beginExec ) {
2023-09-28 17:39:43 +08:00
subQuest _config . beginExec = removeDuplicates ( beginExec . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( finishExec ) {
2023-09-28 17:39:43 +08:00
subQuest _config . finishExec = removeDuplicates ( finishExec . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( failExec ) {
2023-09-28 17:39:43 +08:00
subQuest _config . failExec = removeDuplicates ( failExec . filter ( ( cond ) => cond . _type !== null || cond . type !== null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
// fix (Expected a string but was BEGIN_OBJECT)
2023-09-26 13:07:09 +08:00
if ( typeof subQuest _config . acceptCondComb === "object" ) {
subQuest _config . acceptCondComb = "LOGIC_NONE" ; // ???
2023-05-27 14:18:32 +08:00
}
2023-09-26 13:07:09 +08:00
if ( typeof subQuest _config . finishCondComb === "object" ) {
subQuest _config . finishCondComb = "LOGIC_NONE" ; // ???
2023-05-27 14:18:32 +08:00
}
2023-09-26 13:07:09 +08:00
if ( typeof subQuest _config . failCondComb === "object" ) {
subQuest _config . failCondComb = "LOGIC_NONE" ; // ???
2023-05-27 14:18:32 +08:00
}
2023-05-04 09:57:42 +08:00
2023-05-27 14:18:32 +08:00
// fix null
2023-09-28 17:39:43 +08:00
// acceptCond (this is always there)
if ( subQuest _config . acceptCond == null ) {
2024-06-15 14:30:50 +08:00
if ( bin32config ) {
subQuest _config . acceptCond = [ NoneCondition ] ;
} else {
subQuest _config . acceptCond = [ unknownCondition ] ;
}
2023-09-28 17:39:43 +08:00
console . log ( ` no acceptCond for ${ mainQuestId } / ${ subQuestBin . subId } ` ) ;
count _no _acceptCond ++ ;
2023-05-27 14:18:32 +08:00
}
2023-09-28 17:39:43 +08:00
// finishCond (this is always there)
2023-09-26 13:07:09 +08:00
if ( subQuest _config . finishCond == null ) {
2024-06-15 14:30:50 +08:00
if ( bin32config ) {
subQuest _config . finishCond = [ NoneCondition ] ;
} else {
subQuest _config . finishCond = [ unknownCondition ] ;
}
2023-09-28 17:39:43 +08:00
console . log ( ` no finishCond for ${ mainQuestId } / ${ subQuestBin . subId } ` ) ;
count _no _finishCond ++ ;
2023-05-27 14:18:32 +08:00
}
2023-09-28 17:39:43 +08:00
// - ot -
2023-09-26 13:07:09 +08:00
if ( subQuest _config . failCond == null ) {
subQuest _config . failCond = [ ] ; // ???
2023-05-04 09:57:42 +08:00
}
2023-09-26 13:07:09 +08:00
if ( subQuest _config . beginExec == null ) {
subQuest _config . beginExec = [ ] ; // ???
2023-05-27 14:18:32 +08:00
}
2023-09-26 13:07:09 +08:00
if ( subQuest _config . finishExec == null ) {
subQuest _config . finishExec = [ ] ; // ???
2023-05-27 14:18:32 +08:00
}
2023-09-26 13:07:09 +08:00
if ( subQuest _config . failExec == null ) {
subQuest _config . failExec = [ ] ; // ???
2023-05-27 14:18:32 +08:00
}
2023-09-26 13:07:09 +08:00
//console.log(subQuest_config)
// Validate quest guide (in config quest)
const { guide } = subQuestBin ;
2023-05-27 14:18:32 +08:00
if ( guide !== undefined && guide . type !== undefined ) {
2023-09-26 13:07:09 +08:00
subQuest _config . guide = cleanGuide ( guide ) ;
} else subQuest _config . guide = { } ;
2023-05-04 09:57:42 +08:00
2023-09-26 13:07:09 +08:00
// Remove fields which are empty. (in config quest)
removeFields ( subQuest _config , questBlacklist ) ;
2023-05-27 14:18:32 +08:00
2023-09-28 17:39:43 +08:00
// Check if quest has any patches. (in config quest)
2023-09-26 13:07:09 +08:00
if ( patches _data [ subQuestBin . subId ] ) {
Object . assign ( subQuest _config , patches _data [ subQuestBin . subId ] ) ;
2023-05-26 08:07:57 +08:00
}
2023-09-28 17:39:43 +08:00
//console.log(subQuest_config)
2024-06-15 14:30:50 +08:00
//process.exit(1)
2023-09-26 13:07:09 +08:00
2023-05-27 14:18:32 +08:00
// Add to the main quest's collection.
2023-09-26 13:07:09 +08:00
const subQuestForMain = Object . assign ( { } , subQuest _config ) ;
2023-05-27 14:18:32 +08:00
delete subQuestForMain . json _file ;
delete subQuestForMain . stepDescTextMapHash ;
delete subQuestForMain . guideTipsTextMapHash ;
2023-09-26 13:07:09 +08:00
quest _bin . subQuests . push ( subQuestForMain ) ;
2023-05-27 14:18:32 +08:00
// Add to the global collection.
2023-09-26 13:07:09 +08:00
quests _config . push ( subQuest _config ) ;
2023-05-27 14:18:32 +08:00
}
2024-06-15 14:30:50 +08:00
// Find all talks for main quest.
const talks = talks _data . filter ( ( talk ) => talk . questId === mainQuestId ) ;
2023-05-27 14:18:32 +08:00
// Create talks for the main quest.
for ( const talkData of talks ) {
const talk = {
... talkData ,
} ;
// Validate conditions.
const {
/** @type any[] */ beginCond ,
/** @type any[] */ finishCond ,
/** @type any[] */ failCond ,
} = talkData ;
if ( beginCond ) {
2023-09-28 17:39:43 +08:00
talk . beginCond = removeDuplicates ( beginCond . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( finishCond ) {
2023-09-28 17:39:43 +08:00
talk . finishCond = removeDuplicates ( finishCond . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( failCond ) {
2023-09-28 17:39:43 +08:00
talk . failCond = removeDuplicates ( failCond . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
// Validate executions.
const {
/** @type any[] */ beginExec ,
/** @type any[] */ finishExec ,
/** @type any[] */ failExec ,
} = talkData ;
if ( beginExec ) {
2023-09-28 17:39:43 +08:00
talk . beginExec = removeDuplicates ( beginExec . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
if ( finishExec ) {
2023-09-28 17:39:43 +08:00
talk . finishExec = removeDuplicates ( finishExec . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-26 18:58:49 +08:00
}
2023-05-27 14:18:32 +08:00
if ( failExec ) {
2023-09-28 17:39:43 +08:00
talk . failExec = removeDuplicates ( failExec . filter ( ( cond ) => cond . type != null ) . map ( clean ) ) ;
2023-05-27 14:18:32 +08:00
}
// Remove un-used fields.
removeFields ( talk ) ;
// Add to the main quest's collection.
2023-09-26 13:07:09 +08:00
quest _bin . talks . push ( talk ) ;
2023-05-27 14:18:32 +08:00
}
// Remove un-used fields.
2023-09-26 13:07:09 +08:00
removeFields ( quest _bin ) ;
2023-05-27 14:18:32 +08:00
// Check if the main quest has any patches.
2023-09-26 13:07:09 +08:00
if ( mainPatches [ quest _bin . id ] ) {
Object . assign ( quest _bin , mainPatches [ quest _bin . id ] ) ;
2023-05-27 14:18:32 +08:00
}
// Create the main quest file.
2023-09-26 13:07:09 +08:00
fs . writeFileSync ( binfile , JSON . stringify ( quest _bin , null , 2 ) ) ;
//console.log(JSON.stringify(quest_bin, null, 2))
//process.exit();
2023-05-04 09:57:42 +08:00
}
// Write the new quest data.
2023-09-26 13:07:09 +08:00
fs . writeFileSync ( fileOutput , JSON . stringify ( quests _config , null , 2 ) ) ;
2023-05-04 11:40:41 +08:00
console . log ( "=====================================" ) ;
2023-09-26 13:07:09 +08:00
console . log ( ` There are ${ quests _config . length } quests. ` ) ;
2023-05-04 11:40:41 +08:00
console . log ( ` There are ${ newQuests . length } new quests. ` ) ;
2023-05-27 15:06:47 +08:00
console . log ( ` There are ${ newQuestsNoFound . length } quests not found. ` ) ;
2023-09-28 17:39:43 +08:00
console . log ( ` There are ${ count _patch32 } sub quest use bin 3.2 gio ` ) ;
console . log ( ` There are ${ count _no _acceptCond } sub quest with no acceptCond ` ) ;
console . log ( ` There are ${ count _no _finishCond } sub quest with no finishCond ` ) ;
2023-05-04 11:40:41 +08:00
for ( let i = 0 ; i < newQuests . length ; i += 9 ) {
2023-05-27 14:18:32 +08:00
const newQuestsSlice = newQuests . slice ( i , i + 9 ) ;
console . log ( ` New quests: ${ newQuestsSlice . join ( ", " ) } ` ) ;
2023-05-04 11:40:41 +08:00
}
console . log ( "=====================================" ) ;