0
0
mirror of https://github.com/marcrobledo/savegame-editors.git synced 2025-04-24 16:35:10 +00:00

TOTK: fixed BoolArray handling

This commit is contained in:
Marc Robledo 2023-08-02 21:01:22 +02:00
parent 7b0b7026e3
commit e9ee2af7cf
4 changed files with 69 additions and 51 deletions

View File

@ -1,16 +1,15 @@
/*
The legend of Zelda: Tears of the Kingdom savegame editor - Autobuilder class (last update 2023-07-08)
The legend of Zelda: Tears of the Kingdom savegame editor - Autobuilder class (last update 2023-08-02)
by Marc Robledo 2023
thanks to SuperSpazzy's hash crack
*/
function AutoBuilder(_index, index, combinedActorInfo, cameraPos, cameraAt, isFavorite){
function AutoBuilder(_index, index, combinedActorInfo, cameraPos, cameraAt){
this._index=_index;
this.index=index;
this.combinedActorInfo=combinedActorInfo;
this.cameraPos=cameraPos;
this.cameraAt=cameraAt;
this.isFavorite=isFavorite;
}
AutoBuilder.prototype.export=function(){
var file=new MarcFile(AutoBuilder.CAI_EDITOR_SIZE);
@ -31,7 +30,6 @@ AutoBuilder.prototype.save=function(){
SavegameEditor.writeBinary('AutoBuilder.Draft.Content.CombinedActorInfo', this._index, this.combinedActorInfo);
SavegameEditor.writeVector3F('AutoBuilder.Draft.Content.CameraPos', this._index, this.cameraPos);
SavegameEditor.writeVector3F('AutoBuilder.Draft.Content.CameraAt', this._index, this.cameraAt);
SavegameEditor.writeS32('AutoBuilder.Draft.Content.IsFavorite', this._index, this.isFavorite);
}
AutoBuilder.CAI_HEADER='CmbAct';
@ -48,14 +46,13 @@ AutoBuilder.readSingle=function(autobuilderIndex){
var combinedActorInfo=SavegameEditor.readBinaryArray('AutoBuilder.Draft.Content.CombinedActorInfo', _index);
var cameraPos=SavegameEditor.readVector3FArray('AutoBuilder.Draft.Content.CameraPos', _index);
var cameraAt=SavegameEditor.readVector3FArray('AutoBuilder.Draft.Content.CameraAt', _index);
var isFavorite=SavegameEditor.readS32Array('AutoBuilder.Draft.Content.IsFavorite', _index);
return new AutoBuilder(
_index,
index,
combinedActorInfo,
cameraPos,
cameraAt,
isFavorite
cameraAt
);
}
AutoBuilder.fromFile=function(file){
@ -83,35 +80,11 @@ AutoBuilder.fromFile=function(file){
null,
caiData,
cameraPos,
cameraAt,
-1
cameraAt
);
}
return null;
}
AutoBuilder.getIndexByAutobuilderIndex=function(autobuilderIndex){
return SavegameEditor.readU32Array('AutoBuilder.Draft.Content.Index').indexOf(autobuilderIndex);
}
/*AutoBuilder.readAll=function(){
var index=SavegameEditor.readU32Array('AutoBuilder.Draft.Content.Index');
var combinedActorInfo=SavegameEditor.readBinaryArray('AutoBuilder.Draft.Content.CombinedActorInfo');
var cameraPos=SavegameEditor.readVector3FArray('AutoBuilder.Draft.Content.CameraPos');
var cameraAt=SavegameEditor.readVector3FArray('AutoBuilder.Draft.Content.CameraAt');
var isFavorite=SavegameEditor.readS32Array('AutoBuilder.Draft.Content.IsFavorite');
var autobuilders=[];
for(var i=0; i<combinedActorInfo.length; i++){
autobuilders.push(new AutoBuilder(
i,
index[i],
combinedActorInfo[i],
cameraPos[i],
cameraAt[i],
isFavorite[i]
));
}
return autobuilders.sort(function(a,b){
return a.index - b.index;
});
}*/
}

View File

@ -1,5 +1,5 @@
/*
The legend of Zelda: Tears of the Kingdom savegame editor - Pouch class (last update 2023-07-11)
The legend of Zelda: Tears of the Kingdom savegame editor - Pouch class (last update 2023-08-02)
by Marc Robledo 2023
item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007
@ -520,7 +520,7 @@ Pouch.Structs=Object.freeze({
{hash:'OwnedHorseList.Saddle', type:'EnumArray', propertyName:'saddles', enumValues:['None','GameRomHorseSaddle_00','GameRomHorseSaddle_01','GameRomHorseSaddle_02','GameRomHorseSaddle_03','GameRomHorseSaddle_04','GameRomHorseSaddle_05','GameRomHorseSaddle_06','GameRomHorseSaddle_07','GameRomHorseSaddle_00L','GameRomHorseSaddle_00S']},
{hash:'OwnedHorseList.Rein', type:'EnumArray', propertyName:'reins', enumValues:['None','GameRomHorseReins_00','GameRomHorseReins_01','GameRomHorseReins_02','GameRomHorseReins_03','GameRomHorseReins_04','GameRomHorseReins_05','GameRomHorseReins_06','GameRomHorseReins_00L','GameRomHorseReins_00S']},
{hash:'OwnedHorseList.Familiarity', type:'FloatArray', propertyName:'bond'},
{hash:'OwnedHorseList.IsFamiliarityChecked', type:'UIntArray', propertyName:'bondChecked'}, //BoolArray but it is indeed a 'BitArray'
{hash:'OwnedHorseList.IsFamiliarityChecked', type:'BoolArray', propertyName:'bondChecked'},
{hash:'OwnedHorseList.Toughness', type:'IntArray', propertyName:'statsStrength'},
{hash:'OwnedHorseList.Speed', type:'IntArray', propertyName:'statsSpeed'},
{hash:'OwnedHorseList.ChargeNum', type:'IntArray', propertyName:'statsStamina'},

View File

@ -1,5 +1,5 @@
/*
The legend of Zelda: Tears of the Kingdom - Master editor v20230617
The legend of Zelda: Tears of the Kingdom - Master editor v20230802
by Marc Robledo 2023
thanks to the immeasurable work, hash crack and research of MacSpazzy, MrCheeze and Karlos007
@ -61,6 +61,17 @@ var TOTKMasterEditor=(function(){
};
var _setBooleanBit=function(){
var offset=this.offset;
offset+=Math.floor(this.arrayIndex / 8);
var fullByte=tempFile.readU8(offset);
var bitMask=1 << (this.arrayIndex % 8);
if(this.checked)
fullByte|=bitMask;
else
fullByte&=((~bitMask & 0xff) >>> 0);
tempFile.writeU8(offset, fullByte);
}
var _setBoolean=function(){
tempFile.writeU32(this.offset, this.checked? 1: 0);
}
@ -109,7 +120,9 @@ var TOTKMasterEditor=(function(){
if(/Array$/.test(hashType)){
if(typeof arrayIndex==='number'){
offset+=0x04;
if(/Vector2/.test(hashType)){
if(/Bool/.test(hashType)){
//if boolArray, calculate bit offset during checkbox change
}else if(/Vector2/.test(hashType)){
offset+=arrayIndex*0x08;
}else if(/Vector3/.test(hashType)){
offset+=arrayIndex*0x0c;
@ -145,9 +158,17 @@ var TOTKMasterEditor=(function(){
var field=checkbox(fieldId);
field.offset=offset;
field.arrayIndex=arrayIndex;
field.addEventListener('change', _setBoolean);
if(tempFile.readU32(offset))
field.checked=true;
if(typeof arrayIndex==='number'){
field.addEventListener('change', _setBooleanBit);
var byteRead=tempFile.readU8(offset + (Math.floor(arrayIndex / 8)));
if((byteRead >> ((arrayIndex % 8))) & 0x01)
field.checked=true;
}else{
field.addEventListener('change', _setBoolean);
if(tempFile.readU32(offset))
field.checked=true;
}
tr.children[1].appendChild(field);
}else if(hashType==='Int' || hashType==='UInt'){

View File

@ -1,5 +1,5 @@
/*
The legend of Zelda: Tears of the Kingdom savegame editor - variable reader/writer (last update 2023-07-11)
The legend of Zelda: Tears of the Kingdom savegame editor - variable reader/writer (last update 2023-08-02)
by Marc Robledo 2023
*/
@ -229,9 +229,15 @@ Variable.prototype.read=function(){
var offset=this.offset + 4;
var maxLen=Variable._read(this.offset, 'UInt');
this.value=new Array(maxLen);
for(var i=0; i<maxLen && i<this.value.length; i++){
this.value[i]=Variable._read(offset, typeSingle);
offset+=typeSize;
if(this.type==='BoolArray'){
for(var i=0; i<maxLen && i<this.value.length; i++){
this.value[i]=Variable._read(offset, 'BoolArray', i);
}
}else{
for(var i=0; i<maxLen && i<this.value.length; i++){
this.value[i]=Variable._read(offset, typeSingle);
offset+=typeSize;
}
}
}
}
@ -254,9 +260,15 @@ Variable.prototype.save=function(){
var typeSize=Variable.getVariableSize(typeSingle);
var offset=this.offset + 4;
var maxLen=Variable._read(this.offset, 'UInt');
for(var i=0; i<maxLen && i<this.value.length; i++){
Variable._save(offset, typeSingle, this.value[i]);
offset+=typeSize;
if(this.type==='BoolArray'){
for(var i=0; i<maxLen && i<this.value.length; i++){
Variable._save(offset, 'BoolArray', this.value[i], i);
}
}else{
for(var i=0; i<maxLen && i<this.value.length; i++){
Variable._save(offset, typeSingle, this.value[i]);
offset+=typeSize;
}
}
}
}
@ -429,8 +441,11 @@ Variable.prototype.updateHtmlInputValue=function(arrayIndex){
}
}
Variable._read=function(offset, type){
if(type==='Bool'){
Variable._read=function(offset, type, bitIndex){
if(type==='BoolArray' && typeof bitIndex==='number'){
var byteRead=tempFile.readU8(offset + (Math.floor(bitIndex / 8)));
return !!((byteRead >> ((bitIndex % 8))) & 0x01);
}else if(type==='Bool'){
return tempFile.readU32(offset);
}else if(type==='Int'){
return tempFile.readS32(offset);
@ -477,8 +492,17 @@ Variable._read=function(offset, type){
throw new Error('Invalid variable type: '+type);
}
}
Variable._save=function(offset, type, value){
if(type==='Bool'){
Variable._save=function(offset, type, value, bitIndex){
if(type==='BoolArray' && typeof bitIndex==='number'){
offset+=Math.floor(bitIndex / 8);
var fullByte=tempFile.readU8(offset);
var bitMask=1 << (bitIndex % 8);
if(value)
fullByte|=bitMask;
else
fullByte&=((~bitMask & 0xff) >>> 0);
tempFile.writeU8(offset, fullByte);
}else if(type==='Bool'){
tempFile.writeU32(offset, !!value? 1: 0);
}else if(type==='Int'){
tempFile.writeS32(offset, value);