mirror of
https://github.com/marcrobledo/savegame-editors.git
synced 2025-04-28 09:05:10 +00:00
TOTK: no more hardcoded offsets, using real hash offsets now :)
This commit is contained in:
parent
15f401771c
commit
624ee098d8
@ -398,7 +398,7 @@ function select(id,options,func,def){
|
||||
select.appendChild(options[i]);
|
||||
}
|
||||
|
||||
if(unknownValue && options[i].value!=def){
|
||||
if(unknownValue && options[i].value==def){
|
||||
unknownValue=false;
|
||||
}
|
||||
}
|
||||
@ -410,7 +410,7 @@ function select(id,options,func,def){
|
||||
if(unknownValue){
|
||||
var option=document.createElement('option');
|
||||
option.value=def;
|
||||
option.innerHTML='Unknown: '+def;
|
||||
option.innerHTML='['+(typeof def==='number'? def.toString(16) : def)+']';
|
||||
select.appendChild(option);
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,16 @@ caches.keys().then(function(cacheNames){
|
||||
});
|
||||
|
||||
var PRECACHE_ID='zelda-totk-editor';
|
||||
var PRECACHE_VERSION='v0a';
|
||||
var PRECACHE_VERSION='v0';
|
||||
var PRECACHE_URLS=[
|
||||
//is hashes file too big for cacheing?
|
||||
'/savegame-editors/zelda-totk/','/savegame-editors/zelda-totk/index.html',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.css',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.data.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.locations.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.class.equipment.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.class.armor.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.class.item.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.class.horse.js',
|
||||
'/savegame-editors/zelda-totk/zelda-totk.master.js',
|
||||
'/savegame-editors/zelda-totk/favicon.png',
|
||||
'/savegame-editors/zelda-totk/assets/_blank.png',
|
||||
|
@ -108,7 +108,7 @@
|
||||
<div class="ten columns"><label for="select-max-hearts">Max. hearts</label></div>
|
||||
<div class="two columns">
|
||||
<select id="select-max-hearts" class="full-width">
|
||||
<option value="4">1</option>
|
||||
<option value="4">1 heart</option>
|
||||
<option value="8">2 hearts</option>
|
||||
<option value="12">3 hearts</option>
|
||||
<option value="16">4 hearts</option>
|
||||
@ -152,7 +152,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="ten columns"><label for="select-max-stamina">Max. stamina </label></div>
|
||||
<div class="ten columns"><label for="select-max-stamina">Max. stamina</label></div>
|
||||
<div class="two columns">
|
||||
<select id="select-max-stamina" class="full-width">
|
||||
<option value="1148846080">1 wheel</option>
|
||||
@ -169,6 +169,10 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="ten columns"><label for="number-pony-points">Pony points</label></div>
|
||||
<div class="two columns"><input id="number-pony-points" class="full-width" type="text" /></div>
|
||||
</div>
|
||||
|
||||
<!-- Pouch size -->
|
||||
<h3 class="border-green">Pouch size</h3>
|
||||
@ -268,7 +272,7 @@
|
||||
<div id="tab-weapons">
|
||||
<h3>Weapons</h3><div id="container-weapons"></div>
|
||||
<div class="text-center">
|
||||
<!-- <button onclick="SavegameEditor.restoreDurability('weapons')">Restore durability</button> -->
|
||||
<button onclick="SavegameEditor.restoreDurability('weapons')">Restore durability</button>
|
||||
<button class="with-icon icon1" onclick="SavegameEditor.addItem('weapons')">Add weapon</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -277,6 +281,7 @@
|
||||
<div id="tab-bows">
|
||||
<h3>Bows</h3><div id="container-bows"></div>
|
||||
<div class="text-center">
|
||||
<button onclick="SavegameEditor.restoreDurability('bows')">Restore durability</button>
|
||||
<button class="with-icon icon1" onclick="SavegameEditor.addItem('bows')">Add bow</button>
|
||||
</div>
|
||||
<h3>Arrows</h3><div id="container-arrows"></div>
|
||||
@ -286,6 +291,7 @@
|
||||
<div id="tab-shields">
|
||||
<h3>Shields</h3><div id="container-shields"></div>
|
||||
<div class="text-center">
|
||||
<button onclick="SavegameEditor.restoreDurability('shields')">Restore durability</button>
|
||||
<button class="with-icon icon1" onclick="SavegameEditor.addItem('shields')">Add shield</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -309,6 +315,9 @@
|
||||
<!-- TAB: FOOD -->
|
||||
<div id="tab-food">
|
||||
<h3>Food</h3><div id="container-food"></div>
|
||||
<div class="text-center">
|
||||
<button class="with-icon icon1" onclick="SavegameEditor.addItem('food')">Add food</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: ZONAI DEVICES -->
|
||||
|
@ -1,31 +1,32 @@
|
||||
/*
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Armor class) v20230519
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Armor class) v20230521
|
||||
|
||||
by Marc Robledo 2023
|
||||
item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007
|
||||
*/
|
||||
|
||||
function Armor(index, read){
|
||||
function Armor(index, id, dye){
|
||||
this.category='armors';
|
||||
this.index=index;
|
||||
this._offsets=Armor.Offsets.Armor;
|
||||
|
||||
if(read){
|
||||
this.id=SavegameEditor.readString64Array(this._offsets.ID, index);
|
||||
this.dyeColor=0xdeadbeef;
|
||||
}else{
|
||||
this.id='\0';
|
||||
this.dyeColor=0xdeadbeef;
|
||||
}
|
||||
this.id=id;
|
||||
this.dye=dye || '';
|
||||
|
||||
Armor.buildHtmlElements(this);
|
||||
}
|
||||
Armor.prototype.getItemTranslation=function(){
|
||||
return Armor.TRANSLATIONS[this.id] || this.id;
|
||||
}
|
||||
Armor.prototype.copy=function(index, newId){
|
||||
return new Armor(
|
||||
index,
|
||||
typeof newId==='string'? newId : this.id,
|
||||
this.dye
|
||||
);
|
||||
}
|
||||
Armor.prototype.save=function(){
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, this.index, this.id);
|
||||
//SavegameEditor.writeString64Array(this._offsets.DYE, this.dyeColor, this.index);
|
||||
SavegameEditor.writeString64('ArrayArmorIds', this.index, this.id);
|
||||
//SavegameEditor.writeString64('ArrayArmorDyeColors', this.index, this.dyeColor);
|
||||
}
|
||||
|
||||
|
||||
@ -34,18 +35,19 @@ Armor.buildHtmlElements=function(item){
|
||||
//to-do: add dye selector
|
||||
}
|
||||
|
||||
Armor.readMaxCapacity=function(catId){
|
||||
return SavegameEditor.readArraySize(Armor.Offsets.Armor.ID);
|
||||
}
|
||||
Armor.readAll=function(){
|
||||
var items=[];
|
||||
var maxItems=Armor.readMaxCapacity();
|
||||
for(var i=0; i<maxItems; i++){
|
||||
var item=new Armor(i, true);
|
||||
if(item.id)
|
||||
items.push(item);
|
||||
var armorIds=SavegameEditor.readString64Array('ArrayArmorIds');
|
||||
var validArmors=[];
|
||||
for(var i=0; i<armorIds.length; i++){
|
||||
if(armorIds[i]){
|
||||
validArmors.push(new Armor(
|
||||
i,
|
||||
armorIds[i],
|
||||
null
|
||||
));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
return validArmors;
|
||||
}
|
||||
Armor.remove=function(index){
|
||||
if(typeof index==='object')
|
||||
@ -58,12 +60,6 @@ Armor.remove=function(index){
|
||||
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, '\0', Armor.items.length);
|
||||
}
|
||||
Armor.Offsets={ //v1.0 offsets, v1.1=v1.0 + 0x38
|
||||
Armor:{
|
||||
ID: 0x00061bbc,
|
||||
DYE: 0xdeadbeef
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Armor.DYE_COLORS:['-default-','Blue','Red','Yellow','White','Black','Purple','Green','Light Blue','Navy','Orange','Peach','Crimson','Light Yellow','Brown','Gray',{value:0xffffffff,name:'locked color'}],
|
||||
|
@ -1,31 +1,23 @@
|
||||
/*
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Equipment class) v20230519
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Equipment class) v20230521
|
||||
|
||||
by Marc Robledo 2023
|
||||
item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007
|
||||
*/
|
||||
|
||||
function Equipment(catId, index, read){ //Weapon, Bow or Shield
|
||||
function Equipment(catId, index, id, durability, modifier, modifierValue, fuseId){ //Weapon, Bow or Shield
|
||||
this.category=catId;
|
||||
this.index=index;
|
||||
this._offsets=Equipment.getOffsetsByCategoryId(catId);
|
||||
|
||||
if(read){
|
||||
this.id=SavegameEditor.readString64Array(this._offsets.ID, index);
|
||||
this.durability=SavegameEditor.readU32Array(this._offsets.DURABILITY, index);
|
||||
this.modifier=SavegameEditor.readU32Array(this._offsets.MODIFIER, index);
|
||||
this.modifierValue=SavegameEditor.readU32Array(this._offsets.MODIFIER_VALUE, index);
|
||||
|
||||
if(catId==='weapons' || catId==='shields')
|
||||
this.fuseId=SavegameEditor.readString64Array(this._offsets.FUSE_ID, index);
|
||||
}else{
|
||||
this.id='\0';
|
||||
this.durability=70;
|
||||
this.modifier=Equipment.MODIFIER_NO_BONUS;
|
||||
this.modifierValue=0;
|
||||
|
||||
if(catId==='weapons' || catId==='shields')
|
||||
this.fuseId='\0';
|
||||
this.id=id;
|
||||
this.durability=durability || 70;
|
||||
this.modifier=modifier || Equipment.MODIFIER_NO_BONUS;
|
||||
this.modifierValue=modifierValue || 0;
|
||||
if(this.isFusable()){
|
||||
this.fuseId=fuseId || '';
|
||||
if(this.fuseId && Equipment.FUSABLE_WITH.indexOf(this.fuseId)===-1){
|
||||
console.warn('unknown fusable item['+catId+','+index+']: '+this.fuseId);
|
||||
}
|
||||
}
|
||||
|
||||
Equipment.buildHtmlElements(this);
|
||||
@ -33,23 +25,44 @@ function Equipment(catId, index, read){ //Weapon, Bow or Shield
|
||||
Equipment.prototype.getItemTranslation=function(){
|
||||
return Equipment.TRANSLATIONS[this.category][this.id] || this.id;
|
||||
}
|
||||
Equipment.prototype.isFusable=function(){
|
||||
return (this.category==='weapons' || this.category==='shields')
|
||||
}
|
||||
Equipment.prototype.getFusableTranslation=function(){
|
||||
if(!this.fuseId)
|
||||
return null;
|
||||
//to-do
|
||||
}
|
||||
Equipment.prototype.restoreDurability=function(){
|
||||
this.durability=this.getMaximumDurability();
|
||||
this._htmlInputDurability.value=this.durability;
|
||||
}
|
||||
Equipment.prototype.getMaximumDurability=function(){
|
||||
var defaultDurability=Equipment.DEFAULT_DURABILITY[this.id] || 70;
|
||||
if(this.modifier===Equipment.MODIFIER_DURABILITY || this.modifier===Equipment.MODIFIER_DURABILITY2) //Durability ↑/↑↑
|
||||
return 2100000000;
|
||||
return Equipment.DEFAULT_DURABILITY[this.id] || 70;
|
||||
return defaultDurability + this.modifierValue;
|
||||
return defaultDurability;
|
||||
}
|
||||
Equipment.prototype.copy=function(index, newId){
|
||||
return new Equipment(
|
||||
this.category,
|
||||
index,
|
||||
typeof newId==='string'? newId : this.id,
|
||||
this.durability,
|
||||
this.modifier,
|
||||
this.modifierValue,
|
||||
this.isFusable()? this.fuseId : null
|
||||
);
|
||||
}
|
||||
Equipment.prototype.save=function(){
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, this.index, this.id);
|
||||
SavegameEditor.writeU32Array(this._offsets.DURABILITY, this.index, this.durability);
|
||||
SavegameEditor.writeU32Array(this._offsets.MODIFIER, this.index, this.modifier);
|
||||
SavegameEditor.writeU32Array(this._offsets.MODIFIER_VALUE, this.index, this.modifierValue);
|
||||
var categoryHash=capitalizeCategoryId(this.category);
|
||||
SavegameEditor.writeString64('Array'+categoryHash+'Ids', this.index, this.id);
|
||||
SavegameEditor.writeU32('Array'+categoryHash+'Durabilities', this.index, this.durability);
|
||||
SavegameEditor.writeU32('Array'+categoryHash+'Modifiers', this.index, this.modifier);
|
||||
SavegameEditor.writeU32('Array'+categoryHash+'ModifierValue', this.index, this.modifierValue);
|
||||
|
||||
/*if(this.category==='weapons' || this.category==='shields')
|
||||
SavegameEditor.writeString64Array(this._offsets.FUSE_ID, this.index, this.fuseId);*/
|
||||
/*if(this.isFusable())
|
||||
SavegameEditor.writeString64('ArrayWeaponFuseIds', this.index, this.fuseId);*/
|
||||
}
|
||||
|
||||
|
||||
@ -110,14 +123,14 @@ Equipment.buildHtmlElements=function(item){
|
||||
get('number-item-durability-'+item.category+'-'+item.index).maxValue=maximumDurability;
|
||||
|
||||
if(item.modifier===Equipment.MODIFIER_NO_BONUS){
|
||||
item.restoreDurability();
|
||||
item.modifierValue=0;
|
||||
item._htmlInputModifierValue.value=0;
|
||||
}else if(fromNoBonus && (item.modifier===Equipment.MODIFIER_DURABILITY || item.modifier===Equipment.MODIFIER_DURABILITY2)){
|
||||
item.restoreDurability();
|
||||
item.modifierValue=maximumDurability;
|
||||
item._htmlInputModifierValue.value=maximumDurability;
|
||||
}else if(fromNoBonus || fromModifierDurability){
|
||||
if(fromNoBonus && (item.modifier===Equipment.MODIFIER_DURABILITY || item.modifier===Equipment.MODIFIER_DURABILITY2)){
|
||||
item.modifierValue=2100000000;
|
||||
item._htmlInputModifierValue.value=2100000000;
|
||||
}
|
||||
item.restoreDurability();
|
||||
}
|
||||
}, item.modifier);
|
||||
@ -136,33 +149,33 @@ Equipment.buildHtmlElements=function(item){
|
||||
}
|
||||
});
|
||||
item._htmlInputModifierValue.title='Modifier value';
|
||||
}
|
||||
|
||||
Equipment.readMaxCapacity=function(catId){
|
||||
return SavegameEditor.readArraySize(Equipment.getOffsetsByCategoryId(catId).ID);
|
||||
}
|
||||
Equipment.readAll=function(catId){
|
||||
var offsets=Equipment.getOffsetsByCategoryId(catId);
|
||||
|
||||
var items=[];
|
||||
var maxItems=Equipment.readMaxCapacity(catId);
|
||||
for(var i=0; i<maxItems; i++){
|
||||
var item=new Equipment(catId, i, true);
|
||||
if(item.id)
|
||||
items.push(item);
|
||||
|
||||
if(item.isFusable()){
|
||||
}
|
||||
return items;
|
||||
}
|
||||
Equipment.getOffsetsByCategoryId=function(catId){
|
||||
if(catId==='weapons')
|
||||
return Equipment.Offsets.Weapons;
|
||||
else if(catId==='bows')
|
||||
return Equipment.Offsets.Bows;
|
||||
else if(catId==='shields')
|
||||
return Equipment.Offsets.Shields;
|
||||
|
||||
return null;
|
||||
Equipment.readAll=function(catId){
|
||||
var categoryHash=capitalizeCategoryId(catId);
|
||||
var equipmentIds=SavegameEditor.readString64Array('Array'+categoryHash+'Ids');
|
||||
var isFusable=(catId==='weapons' || catId==='shields');
|
||||
var validEquipment=[];
|
||||
for(var i=0; i<equipmentIds.length; i++){
|
||||
if(equipmentIds[i]){
|
||||
validEquipment.push(new Equipment(
|
||||
catId,
|
||||
i,
|
||||
equipmentIds[i],
|
||||
SavegameEditor.readU32('Array'+categoryHash+'Durabilities', i),
|
||||
SavegameEditor.readU32('Array'+categoryHash+'Modifiers', i),
|
||||
SavegameEditor.readU32('Array'+categoryHash+'ModifierValues', i),
|
||||
isFusable? SavegameEditor.readString64('Array'+categoryHash+'FuseIds', i) : null
|
||||
));
|
||||
}
|
||||
}
|
||||
return validEquipment;
|
||||
}
|
||||
|
||||
|
||||
Equipment.remove=function(index){
|
||||
if(typeof index==='object')
|
||||
index=Equipment.items.indexOf(index);
|
||||
@ -174,28 +187,7 @@ Equipment.remove=function(index){
|
||||
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, '\0', Equipment.items.length);
|
||||
}
|
||||
Equipment.Offsets={ //v1.0 offsets, v1.1=v1.0 + 0x38
|
||||
Weapons:{
|
||||
ID: 0x000c3b58,
|
||||
DURABILITY: 0x0004d1c0,
|
||||
MODIFIER: 0x000515bc,
|
||||
MODIFIER_VALUE: 0x0004eed4,
|
||||
FUSE_ID: 0x000a65d4
|
||||
},
|
||||
Bows:{
|
||||
ID: 0x0007b4e4,
|
||||
DURABILITY: 0x0004aab8,
|
||||
MODIFIER: 0x0005252c,
|
||||
MODIFIER_VALUE: 0x0004cafc
|
||||
},
|
||||
Shields:{
|
||||
ID: 0x000760f0,
|
||||
DURABILITY: 0x0004a3b0,
|
||||
MODIFIER: 0x00051070,
|
||||
MODIFIER_VALUE: 0x0004ba54,
|
||||
FUSE_ID: 0x000aa07c
|
||||
}
|
||||
}
|
||||
|
||||
Equipment.MODIFIER_NO_BONUS=0xb6eede09;
|
||||
Equipment.MODIFIER_ATTACK=0xa9384c6c;
|
||||
Equipment.MODIFIER_ATTACK2=0xdad10617;
|
||||
@ -254,6 +246,8 @@ Equipment.DEFAULT_DURABILITY={
|
||||
Weapon_Sword_166:15,
|
||||
Weapon_Sword_167:4,
|
||||
Weapon_Sword_168:12,
|
||||
Weapon_Sword_077:30,
|
||||
|
||||
Weapon_Lsword_001:20,
|
||||
Weapon_Lsword_002:25,
|
||||
Weapon_Lsword_003:30,
|
||||
@ -419,25 +413,26 @@ Weapon_Sword_070:'Master Sword',
|
||||
Weapon_Sword_101:'Zonaite Sword',
|
||||
Weapon_Sword_103:'Wooden Stick',
|
||||
Weapon_Sword_105:'Boomerang',
|
||||
Weapon_Sword_106:'Traveler\'s Sword *',
|
||||
Weapon_Sword_106:'Traveler\'s Sword (decayed)',
|
||||
Weapon_Sword_107:'Lizal Boomerang',
|
||||
Weapon_Sword_108:'Sturdy Wooden Stick',
|
||||
Weapon_Sword_109:'Gnarled Wooden Stick',
|
||||
Weapon_Sword_112:'Soldier\'s Broadsword *',
|
||||
Weapon_Sword_113:'Knight\'s Broadsword *',
|
||||
Weapon_Sword_114:'Eightfold Blade *',
|
||||
Weapon_Sword_124:'Royal Broadsword *',
|
||||
Weapon_Sword_125:'Forest Dweller\'s Sword *',
|
||||
Weapon_Sword_127:'Zora Sword *',
|
||||
Weapon_Sword_129:'Gerudo Scimitar *',
|
||||
Weapon_Sword_131:'Feathered Edge *',
|
||||
Weapon_Sword_147:'Royal Guard\'s Sword *',
|
||||
Weapon_Sword_112:'Soldier\'s Broadsword (decayed)',
|
||||
Weapon_Sword_113:'Knight\'s Broadsword (decayed)',
|
||||
Weapon_Sword_114:'Eightfold Blade (decayed)',
|
||||
Weapon_Sword_124:'Royal Broadsword (decayed)',
|
||||
Weapon_Sword_125:'Forest Dweller\'s Sword (decayed)',
|
||||
Weapon_Sword_127:'Zora Sword (decayed)',
|
||||
Weapon_Sword_129:'Gerudo Scimitar (decayed)',
|
||||
Weapon_Sword_131:'Feathered Edge (decayed)',
|
||||
Weapon_Sword_147:'Royal Guard\'s Sword (decayed)',
|
||||
Weapon_Sword_161:'Magic Rod',
|
||||
Weapon_Sword_163:'Strong Zonaite Sword',
|
||||
Weapon_Sword_164:'Mighty Zonaite Sword',
|
||||
Weapon_Sword_166:'Gloom Sword',
|
||||
Weapon_Sword_167:'Tree Branch *',
|
||||
Weapon_Sword_168:'Wooden Stick *',
|
||||
Weapon_Sword_167:'Tree Branch (sky)',
|
||||
Weapon_Sword_168:'Wooden Stick (decayed)',
|
||||
Weapon_Sword_077:'Master Sword (glitched)',
|
||||
|
||||
Weapon_Lsword_001:'Traveler\'s Claymore',
|
||||
Weapon_Lsword_002:'Soldier\'s Claymore',
|
||||
@ -459,23 +454,23 @@ Weapon_Lsword_059:'Biggoron\'s Sword',
|
||||
Weapon_Lsword_060:'Fierce Deity Sword',
|
||||
Weapon_Lsword_101:'Zonaite Longsword',
|
||||
Weapon_Lsword_103:'Thick Stick',
|
||||
Weapon_Lsword_106:'Traveler\'s Claymore *',
|
||||
Weapon_Lsword_106:'Traveler\'s Claymore (decayed)',
|
||||
Weapon_Lsword_108:'Sturdy Thick Stick',
|
||||
Weapon_Lsword_109:'Gnarled Thick Stick',
|
||||
Weapon_Lsword_112:'Soldier\'s Claymore *',
|
||||
Weapon_Lsword_113:'Knight\'s Claymore *',
|
||||
Weapon_Lsword_114:'Eightfold Longblade *',
|
||||
Weapon_Lsword_124:'Royal Claymore *',
|
||||
Weapon_Lsword_127:'Zora Longsword *',
|
||||
Weapon_Lsword_129:'Gerudo Claymore *',
|
||||
Weapon_Lsword_136:'Cobble Crusher *',
|
||||
Weapon_Lsword_147:'Royal Guard\'s Claymore *',
|
||||
Weapon_Lsword_112:'Soldier\'s Claymore (decayed)',
|
||||
Weapon_Lsword_113:'Knight\'s Claymore (decayed)',
|
||||
Weapon_Lsword_114:'Eightfold Longblade (decayed)',
|
||||
Weapon_Lsword_124:'Royal Claymore (decayed)',
|
||||
Weapon_Lsword_127:'Zora Longsword (decayed)',
|
||||
Weapon_Lsword_129:'Gerudo Claymore (decayed)',
|
||||
Weapon_Lsword_136:'Cobble Crusher (decayed)',
|
||||
Weapon_Lsword_147:'Royal Guard\'s Claymore (decayed)',
|
||||
Weapon_Lsword_161:'Magic Scepter',
|
||||
Weapon_Lsword_163:'Strong Zonaite Longsword',
|
||||
Weapon_Lsword_164:'Mighty Zonaite Longsword',
|
||||
Weapon_Lsword_166:'Gloom Club',
|
||||
Weapon_Lsword_168:'Thick Stick *',
|
||||
Weapon_Lsword_174:'Giant Boomerang *',
|
||||
Weapon_Lsword_168:'Thick Stick (decayed)',
|
||||
Weapon_Lsword_174:'Giant Boomerang (decayed)',
|
||||
|
||||
Weapon_Spear_001:'Traveler\'s Spear',
|
||||
Weapon_Spear_002:'Soldier\'s Spear',
|
||||
@ -494,23 +489,23 @@ Weapon_Spear_047:'Royal Guard\'s Spear',
|
||||
Weapon_Spear_050:'Lightscale Trident',
|
||||
Weapon_Spear_101:'Zonaite Spear',
|
||||
Weapon_Spear_103:'Long Stick',
|
||||
Weapon_Spear_106:'Traveler\'s Spear *',
|
||||
Weapon_Spear_106:'Traveler\'s Spear (decayed)',
|
||||
Weapon_Spear_108:'Sturdy Long Stick',
|
||||
Weapon_Spear_109:'Gnarled Long Stick',
|
||||
Weapon_Spear_112:'Soldier\'s Spear *',
|
||||
Weapon_Spear_113:'Knight\'s Halberd *',
|
||||
Weapon_Spear_124:'Royal Halberd *',
|
||||
Weapon_Spear_125:'Forest Dweller\'s Spear *',
|
||||
Weapon_Spear_127:'Zora Spear *',
|
||||
Weapon_Spear_129:'Gerudo Spear *',
|
||||
Weapon_Spear_132:'Feathered Spear *',
|
||||
Weapon_Spear_147:'Royal Guard\'s Spear *',
|
||||
Weapon_Spear_112:'Soldier\'s Spear (decayed)',
|
||||
Weapon_Spear_113:'Knight\'s Halberd (decayed)',
|
||||
Weapon_Spear_124:'Royal Halberd (decayed)',
|
||||
Weapon_Spear_125:'Forest Dweller\'s Spear (decayed)',
|
||||
Weapon_Spear_127:'Zora Spear (decayed)',
|
||||
Weapon_Spear_129:'Gerudo Spear (decayed)',
|
||||
Weapon_Spear_132:'Feathered Spear (decayed)',
|
||||
Weapon_Spear_147:'Royal Guard\'s Spear (decayed)',
|
||||
Weapon_Spear_161:'Magic Staff',
|
||||
Weapon_Spear_163:'Strong Zonaite Spear',
|
||||
Weapon_Spear_164:'Mighty Zonaite Spear',
|
||||
Weapon_Spear_166:'Gloom Spear',
|
||||
Weapon_Spear_168:'Long Stick *',
|
||||
Weapon_Spear_173:'Throwing Spear *'
|
||||
Weapon_Spear_168:'Long Stick (decayed)',
|
||||
Weapon_Spear_173:'Throwing Spear (decayed)'
|
||||
},
|
||||
|
||||
'bows':{
|
||||
@ -581,4 +576,59 @@ Weapon_Shield_102:'Strong Zonaite Shield',
|
||||
Weapon_Shield_103:'Mighty Zonaite Shield',
|
||||
Weapon_Shield_107:'Old Wooden Shield'
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Equipment.TRANSLATIONS_FUSE_ONLY={
|
||||
}
|
||||
|
||||
Equipment.FUSABLE_WITH=[
|
||||
'AsbObj_RockParts_C_S_01',
|
||||
'AsbObj_SharpRock_A_S_01',
|
||||
'AsbObj_WhiteWoodRectangle_A_LL_01',
|
||||
'Barrel_SkyObj',
|
||||
'DgnObj_BoardIron_E',
|
||||
'DgnObj_SpikeBallWood_A',
|
||||
'IceWall_Piece',
|
||||
'Item_Enemy_106',
|
||||
'Item_Enemy_109',
|
||||
'Item_Enemy_134',
|
||||
'Item_Enemy_137',
|
||||
'Item_Enemy_138',
|
||||
'Item_Enemy_139',
|
||||
'Item_Enemy_141',
|
||||
'Item_Enemy_142',
|
||||
'Item_Enemy_149',
|
||||
'Item_Enemy_150',
|
||||
'Item_Enemy_151',
|
||||
'Item_Enemy_153',
|
||||
'Item_Enemy_166',
|
||||
'Item_Enemy_168',
|
||||
'Item_Enemy_192',
|
||||
'Item_Enemy_193',
|
||||
'Item_Enemy_225',
|
||||
'Item_Enemy_227',
|
||||
'Item_Enemy_58',
|
||||
'Item_Enemy_59',
|
||||
'Item_Enemy_60',
|
||||
'Item_Enemy_77',
|
||||
'Item_Ore_B',
|
||||
'Item_Ore_C',
|
||||
'Item_Ore_D',
|
||||
'Obj_GerudoHoleCover_A_03',
|
||||
'Obj_LiftRockWhite_A_01',
|
||||
'Obj_SpikeBall_B',
|
||||
'SpObj_Cannon_A_01',
|
||||
'SpObj_ElectricBoxGenerator',
|
||||
'SpObj_FlameThrower_A_01',
|
||||
'SpObj_SlipBoard_A_01',
|
||||
'SpObj_SpringPiston_A_01',
|
||||
'Weapon_Bow_036',
|
||||
'Weapon_Lsword_041',
|
||||
'Weapon_Shield_002',
|
||||
'Weapon_Shield_006',
|
||||
'Weapon_Shield_103',
|
||||
'Weapon_Sword_019',
|
||||
'Weapon_Sword_101',
|
||||
'Weapon_Sword_112',
|
||||
'Weapon_Sword_124'
|
||||
];
|
@ -1,20 +1,19 @@
|
||||
/*
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Horse class) v20230519
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Horse class) v20230521
|
||||
|
||||
by Marc Robledo 2023
|
||||
item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007
|
||||
*/
|
||||
|
||||
function Horse(index){
|
||||
function Horse(index, id, name){
|
||||
this.category='horses';
|
||||
this.index=index;
|
||||
this._offsets=Horses.Offsets;
|
||||
|
||||
this.id=SavegameEditor.readString64Array(this._offsets.ID, index);
|
||||
this.name=SavegameEditor.readUTF8String64Array(this._offsets.NAME, index);
|
||||
this.id=id;
|
||||
this.name=name;
|
||||
}
|
||||
Horse.prototype.save=function(){
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, this.index, this.id);
|
||||
SavegameEditor.writeString64('ArrayHorseIds', this.index, this.id);
|
||||
}
|
||||
|
||||
|
||||
@ -23,57 +22,22 @@ Horse.buildHtmlElements=function(horse){
|
||||
//to-do
|
||||
}
|
||||
|
||||
/*setHorseName:function(i,val){
|
||||
if(i<5)
|
||||
this._writeString64(this.Offsets.HORSE_NAMES, val, i);
|
||||
},
|
||||
setHorseSaddle:function(i,val){
|
||||
if(i<5)
|
||||
this._writeString64(this.Offsets.HORSE_SADDLES, val, i);
|
||||
},
|
||||
setHorseReins:function(i,val){
|
||||
if(i<5)
|
||||
this._writeString64(this.Offsets.HORSE_REINS, val, i);
|
||||
},
|
||||
setHorseType:function(i,val){
|
||||
if(currentEditingItem<6){
|
||||
this._writeString64(this.Offsets.HORSE_TYPES, val, i);
|
||||
// fix mane
|
||||
this._writeString64(this.Offsets.HORSE_MANES, (val==='GameRomHorse00L'?'Horse_Link_Mane_00L':'Horse_Link_Mane'), i);
|
||||
Horse.readAll=function(){
|
||||
var horsesIds=SavegameEditor.readString64Array('ArrayHorseIds');
|
||||
var validHorses=[];
|
||||
for(var i=0; i<horsesIds.length; i++){
|
||||
if(horsesIds[i]){
|
||||
validHorses.push(new Horse(
|
||||
i,
|
||||
horsesIds[i],
|
||||
SavegameEditor.readStringUTF8('ArrayHorseNames', i)
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
for(var i=0; i<6; i++){
|
||||
if(i<6){
|
||||
//get('select-horse'+i+'-saddles').horseIndex=i;
|
||||
//get('select-horse'+i+'-saddles').addEventListener('change', function(){SavegameEditor.setHorseSaddle(this.horseIndex, this.value)}, false);
|
||||
//get('select-horse'+i+'-reins').horseIndex=i;
|
||||
//get('select-horse'+i+'-reins').addEventListener('change', function(){SavegameEditor.setHorseReins(this.horseIndex, this.value)}, false);
|
||||
}
|
||||
get('select-horse'+i+'-type').horseIndex=i;
|
||||
get('select-horse'+i+'-type').addEventListener('change', function(){SavegameEditor.setHorseType(this.horseIndex, this.value)}, false);
|
||||
|
||||
//select('horse'+i+'-saddles', this._arrayToSelectOpts(TOTK_Data.HORSE_SADDLES));
|
||||
//select('horse'+i+'-reins', this._arrayToSelectOpts(TOTK_Data.HORSE_REINS));
|
||||
//select('horse'+i+'-type', this._arrayToSelectOpts(i===6?TOTK_Data.HORSE_TYPES.concat(TOTK_Data.HORSE_TYPES_UNTAMMED):TOTK_Data.HORSE_TYPES));
|
||||
}
|
||||
*/
|
||||
var Horses={};
|
||||
Horses.readAll=function(){
|
||||
var horses=[];
|
||||
var maxHorses=SavegameEditor.readArraySize(Horses.Offsets.ID);
|
||||
for(var i=0; i<maxHorses; i++){
|
||||
var horse=new Horse(i);
|
||||
if(horse.id)
|
||||
horses.push(horse);
|
||||
}
|
||||
return horses;
|
||||
}
|
||||
Horses.Offsets={ //v1.0 offsets, v1.1=v1.0 + 0x38
|
||||
ID: 0x0008a0ec,
|
||||
NAME: 0x0010a148
|
||||
return validHorses;
|
||||
}
|
||||
|
||||
Horses.HORSE_TYPES=[
|
||||
Horse.HORSE_TYPES=[
|
||||
'GameRomHorse00','GameRomHorse01','GameRomHorse02','GameRomHorse03','GameRomHorse04','GameRomHorse05','GameRomHorse06','GameRomHorse07','GameRomHorse08','GameRomHorse09','GameRomHorse10','GameRomHorse11','GameRomHorse12','GameRomHorse13','GameRomHorse14','GameRomHorse15','GameRomHorse16','GameRomHorse17','GameRomHorse18','GameRomHorse19','GameRomHorse20','GameRomHorse21','GameRomHorse22','GameRomHorse23','GameRomHorse25','GameRomHorse26','GameRomHorseEpona','GameRomHorseZelda','GameRomHorse00L','GameRomHorse01L','GameRomHorseGold',
|
||||
|
||||
//untested, posible freeze
|
||||
@ -82,13 +46,11 @@ Horses.HORSE_TYPES=[
|
||||
'GameRomHorseForStreetVender',
|
||||
'GameRomHorseNushi'
|
||||
];
|
||||
Horses.HORSE_REINS=['GameRomHorseReins_00','GameRomHorseReins_01','GameRomHorseReins_02','GameRomHorseReins_03','GameRomHorseReins_04','GameRomHorseReins_05','GameRomHorseReins_06','GameRomHorseReins_00L','GameRomHorseReins_10'];
|
||||
Horses.HORSE_SADDLES=['GameRomHorseSaddle_00','GameRomHorseSaddle_01','GameRomHorseSaddle_02','GameRomHorseSaddle_03','GameRomHorseSaddle_04','GameRomHorseSaddle_05','GameRomHorseSaddle_06','GameRomHorseSaddle_00L','GameRomHorseSaddle_00S','GameRomHorseSaddle_10'];
|
||||
Horses.HORSE_TYPES_UNTAMMED=[];
|
||||
Horse.HORSE_REINS=['GameRomHorseReins_00','GameRomHorseReins_01','GameRomHorseReins_02','GameRomHorseReins_03','GameRomHorseReins_04','GameRomHorseReins_05','GameRomHorseReins_06','GameRomHorseReins_00L','GameRomHorseReins_10'];
|
||||
Horse.HORSE_SADDLES=['GameRomHorseSaddle_00','GameRomHorseSaddle_01','GameRomHorseSaddle_02','GameRomHorseSaddle_03','GameRomHorseSaddle_04','GameRomHorseSaddle_05','GameRomHorseSaddle_06','GameRomHorseSaddle_00L','GameRomHorseSaddle_00S','GameRomHorseSaddle_10'];
|
||||
Horse.HORSE_TYPES_UNTAMMED=[];
|
||||
|
||||
|
||||
Horses.TRANSLATIONS={
|
||||
Horse.TRANSLATIONS={
|
||||
//to-do
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
@ -1,39 +1,62 @@
|
||||
/*
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Item class) v20230519
|
||||
The legend of Zelda: Tears of the Kingdom Savegame Editor (Item class) v20230521
|
||||
|
||||
by Marc Robledo 2023
|
||||
item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007
|
||||
*/
|
||||
|
||||
function Item(catId, index, read){
|
||||
function Item(catId, index, id, quantity, foodEffect, foodEffectHearts, foodEffectMultiplier, foodEffectTime, foodEffectUnknown1){
|
||||
this.category=catId;
|
||||
this.index=index;
|
||||
this._offsets=Items.getOffsetsByCategoryId(catId);
|
||||
|
||||
if(read){
|
||||
this.id=SavegameEditor.readString64Array(this._offsets.ID, index);
|
||||
this.quantity=SavegameEditor.readU32Array(this._offsets.QUANTITY, index);
|
||||
}else{
|
||||
this.id='\0';
|
||||
this.quantity=1;
|
||||
this.id=id;
|
||||
this.quantity=quantity || 1;
|
||||
|
||||
if(catId==='food'){
|
||||
this.foodEffect=typeof foodEffect==='number'? foodEffect : Item.FOOD_NO_EFFECT;
|
||||
this.foodEffectHearts=typeof foodEffectHearts==='number'? foodEffectHearts : 4;
|
||||
this.foodEffectMultiplier=typeof foodEffectMultiplier==='number'? foodEffectMultiplier : 0;
|
||||
this.foodEffectTime=typeof foodEffectTime==='number'? foodEffectTime : 0;
|
||||
this.foodEffectUnknown1=typeof foodEffectUnknown1==='number'? foodEffectUnknown1 : 1;
|
||||
}
|
||||
|
||||
Items.buildHtmlElements(this);
|
||||
Item.buildHtmlElements(this);
|
||||
}
|
||||
|
||||
Item.prototype.getItemTranslation=function(){
|
||||
return Items.TRANSLATIONS[this.category][this.id] || this.id;
|
||||
return Item.TRANSLATIONS[this.category][this.id] || this.id;
|
||||
}
|
||||
Item.prototype.copy=function(index, newId){
|
||||
return new Item(
|
||||
this.category,
|
||||
index,
|
||||
typeof newId==='string'? newId : this.id,
|
||||
this.quantity,
|
||||
this.category==='food'? this.foodEffect : null,
|
||||
this.category==='food'? this.foodEffectHearts : null,
|
||||
this.category==='food'? this.foodEffectMultiplier : null,
|
||||
this.category==='food'? this.foodEffectTime : null,
|
||||
this.category==='food'? this.foodEffectUnknown1 : null
|
||||
);
|
||||
}
|
||||
|
||||
Item.prototype.save=function(){
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, this.index, this.id);
|
||||
SavegameEditor.writeU32Array(this._offsets.QUANTITY, this.index, this.quantity);
|
||||
var categoryHash=capitalizeCategoryId(this.category);
|
||||
SavegameEditor.writeString64('Array'+categoryHash+'Ids', this.index, this.id);
|
||||
SavegameEditor.writeU32('Array'+categoryHash+'Quantities', this.index, this.quantity);
|
||||
if(this.category==='food'){
|
||||
SavegameEditor.writeU32('ArrayFoodEffects', this.index, this.foodEffect);
|
||||
SavegameEditor.writeU32('ArrayFoodEffectsHearts', this.index, this.foodEffectHearts);
|
||||
SavegameEditor.writeU32('ArrayFoodEffectsMultiplier', this.index, this.foodEffectMultiplier);
|
||||
SavegameEditor.writeU32('ArrayFoodEffectsTime', this.index, this.foodEffectTime);
|
||||
SavegameEditor.writeU32('ArrayFoodEffectsUnknown1', this.index, this.foodEffectUnknown1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var Items={};
|
||||
Items.buildHtmlElements=function(item){
|
||||
Item.buildHtmlElements=function(item){
|
||||
//build html elements
|
||||
var maxValue=Items.MAXIMUM_QUANTITY[item.id] || 999;
|
||||
var maxValue=Item.MAXIMUM_QUANTITY[item.id] || 999;
|
||||
item._htmlInputQuantity=inputNumber('item-quantity-'+item.category+'-'+item.index, 1, maxValue, item.quantity);
|
||||
item._htmlInputQuantity.addEventListener('change', function(){
|
||||
var newVal=parseInt(this.value);
|
||||
@ -41,72 +64,78 @@ Items.buildHtmlElements=function(item){
|
||||
item.quantity=newVal;
|
||||
});
|
||||
item._htmlInputQuantity.title='Quantity';
|
||||
}
|
||||
Items.readMaxCapacity=function(catId){
|
||||
return SavegameEditor.readArraySize(Items.getOffsetsByCategoryId(catId).ID);
|
||||
}
|
||||
Items.readAll=function(catId){
|
||||
var offsets=Items.getOffsetsByCategoryId(catId);
|
||||
|
||||
var items=[];
|
||||
var maxItems=Items.readMaxCapacity(catId);
|
||||
for(var i=0; i<maxItems; i++){
|
||||
var item=new Item(catId, i, true);
|
||||
if(item.id)
|
||||
items.push(item);
|
||||
|
||||
if(item.category==='food'){
|
||||
var foodEffects=[
|
||||
{name:'none', value:Item.FOOD_NO_EFFECT},
|
||||
{name:'Stamina', value:0xe9a30056},
|
||||
{name:'Attack+', value:0xa9384c6c},
|
||||
{name:'Attack+ with cold', value:0x4a3e58f6},
|
||||
{name:'Attack+ with heat', value:0x4c6a85d2},
|
||||
{name:'Defense+', value:0xa0a00c0e},
|
||||
{name:'Speed+', value:0xb3f6b87a},
|
||||
{name:'Brightness', value:0x4939dca1}
|
||||
];
|
||||
item._htmlSelectFoodEffect=select('item-food-effects-'+item.category+'-'+item.index, foodEffects, function(){
|
||||
item.foodEffect=parseInt(this.value);
|
||||
}, item.foodEffect);
|
||||
item._htmlSelectFoodEffect.title='Food effect';
|
||||
|
||||
item._htmlSelectFoodEffectHearts=inputNumber('item-food-effects-hearts-'+item.category+'-'+item.index, 0, 40*4, item.foodEffectHearts);
|
||||
item._htmlSelectFoodEffectHearts.addEventListener('change', function(){
|
||||
var newVal=parseInt(this.value);
|
||||
if(!isNaN(newVal) && newVal>0)
|
||||
item.foodEffectHearts=newVal;
|
||||
});
|
||||
item._htmlSelectFoodEffectHearts.title='Heart quarters heal';
|
||||
|
||||
item._htmlSelectFoodEffectMultiplier=inputNumber('item-food-effects-multiplier-'+item.category+'-'+item.index, 1, 8, item.foodEffectMultiplier);
|
||||
item._htmlSelectFoodEffectMultiplier.addEventListener('change', function(){
|
||||
var newVal=parseInt(this.value);
|
||||
if(!isNaN(newVal) && newVal>0)
|
||||
item.foodEffectMultiplier=newVal;
|
||||
});
|
||||
item._htmlSelectFoodEffectMultiplier.title='Multiplier';
|
||||
|
||||
item._htmlSelectFoodEffectTime=inputNumber('item-food-effects-time-'+item.category+'-'+item.index, 30, 4800, item.foodEffectTime);
|
||||
item._htmlSelectFoodEffectTime.addEventListener('change', function(){
|
||||
var newVal=parseInt(this.value);
|
||||
if(!isNaN(newVal) && newVal>0)
|
||||
item.foodEffectTime=newVal;
|
||||
});
|
||||
item._htmlSelectFoodEffectTime.title='Duration (in seconds)';
|
||||
}
|
||||
return items;
|
||||
}
|
||||
Items.getOffsetsByCategoryId=function(catId){
|
||||
if(catId==='arrows')
|
||||
return Items.Offsets.Arrows;
|
||||
else if(catId==='materials')
|
||||
return Items.Offsets.Materials;
|
||||
else if(catId==='food')
|
||||
return Items.Offsets.Food;
|
||||
else if(catId==='devices')
|
||||
return Items.Offsets.Devices;
|
||||
else if(catId==='key')
|
||||
return Items.Offsets.Key;
|
||||
|
||||
return null;
|
||||
}
|
||||
Items.remove=function(index){
|
||||
if(typeof index==='object')
|
||||
index=Items.items.indexOf(index);
|
||||
|
||||
Items.items.splice(index, 1);
|
||||
for(var i=index; i<Items.items.length; i++){
|
||||
Items.items[i].index--;
|
||||
Item.readAll=function(catId){
|
||||
var categoryHash=capitalizeCategoryId(catId);
|
||||
var itemIds=SavegameEditor.readString64Array('Array'+categoryHash+'Ids');
|
||||
var isFood=(catId==='food');
|
||||
var validItems=[];
|
||||
for(var i=0; i<itemIds.length; i++){
|
||||
if(itemIds[i]){
|
||||
validItems.push(new Item(
|
||||
catId,
|
||||
i,
|
||||
itemIds[i],
|
||||
SavegameEditor.readU32('Array'+categoryHash+'Quantities', i),
|
||||
isFood? SavegameEditor.readU32('ArrayFoodEffects', i) : null,
|
||||
isFood? SavegameEditor.readU32('ArrayFoodEffectsHearts', i) : null,
|
||||
isFood? SavegameEditor.readU32('ArrayFoodEffectsMultiplier', i) : null,
|
||||
isFood? SavegameEditor.readU32('ArrayFoodEffectsTime', i) : null,
|
||||
isFood? SavegameEditor.readU32('ArrayFoodEffectsUnknown1', i) : null
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
SavegameEditor.writeString64Array(this._offsets.ID, '\0', Items.items.length);
|
||||
return validItems;
|
||||
}
|
||||
Item.remove=function(index){
|
||||
//to-do
|
||||
}
|
||||
Items.Offsets={ //v1.0 offsets, v1.1=v1.0 + 0x38
|
||||
Arrows:{
|
||||
ID: 0x000820ec,
|
||||
QUANTITY: 0x00046ff4
|
||||
},
|
||||
Materials:{
|
||||
ID: 0x000afbf4,
|
||||
QUANTITY: 0x000477a4
|
||||
},
|
||||
Food:{
|
||||
ID: 0x00087ca4,
|
||||
QUANTITY: 0x0004e984
|
||||
},
|
||||
Devices:{
|
||||
ID: 0x0009cb70,
|
||||
QUANTITY: 0x00046148
|
||||
},
|
||||
Key:{
|
||||
ID: 0x000b9488,
|
||||
QUANTITY: 0x0004eb98
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Items.MAXIMUM_QUANTITY={
|
||||
Item.MAXIMUM_QUANTITY={
|
||||
Item_Ore_L:999999, //Zonaite
|
||||
Item_Ore_M:999999, //Large Zonaite
|
||||
Energy_Material_01:99999, //Crystallized Charge
|
||||
@ -119,8 +148,9 @@ MinusRupee_00:99999 //Poe
|
||||
};
|
||||
|
||||
|
||||
Item.FOOD_NO_EFFECT=0xb6eede09;
|
||||
|
||||
Items.TRANSLATIONS={
|
||||
Item.TRANSLATIONS={
|
||||
'arrows':{
|
||||
NormalArrow:'Arrow'
|
||||
},
|
||||
@ -830,6 +860,9 @@ Obj_SubstituteCloth_56:"Addison's Fabric"
|
||||
}
|
||||
};
|
||||
|
||||
Item.TRANSLATIONS_FUSE_ONLY={
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
The legend of Zelda: Tears of the Kingdom savegame editor v20230519
|
||||
The legend of Zelda: Tears of the Kingdom savegame editor v20230521
|
||||
by Marc Robledo 2017-2020
|
||||
*/
|
||||
var currentEditingItem;
|
||||
@ -7,14 +7,11 @@ var currentEditingItem;
|
||||
SavegameEditor={
|
||||
Name:'The legend of Zelda: Tears of the Kingdom',
|
||||
Filename:['progress.sav','caption.sav'],
|
||||
Version:20230519,
|
||||
Version:20230521,
|
||||
noDemo:true,
|
||||
|
||||
/* Constants */
|
||||
Constants:{
|
||||
STRING_SIZE:0x20,
|
||||
STRING64_SIZE:0x40,
|
||||
|
||||
VERSION: ['v1.0', 'v1.1'],
|
||||
FILESIZE: [2307552, 2307656],
|
||||
HEADER: [0x0046c3c8, 0x0047e0f4],
|
||||
@ -23,94 +20,144 @@ SavegameEditor={
|
||||
|
||||
BLANK_ICON_PATH:'./assets/_blank.png'
|
||||
},
|
||||
currentItemOffset:null,
|
||||
|
||||
/* Hashes */
|
||||
Hashes:[
|
||||
0xfbe01da1, 'TempMaxHearts',
|
||||
0xa77921d7, 'TempRupees',
|
||||
//0x31ab5580, 'TempHearts',
|
||||
0xf9212c74, 'TempStamina',
|
||||
0xe573f564, 'TempPlaytime',
|
||||
0xa3db7114, 'TempItemData' //???
|
||||
0xfbe01da1, 'MaxHearts',
|
||||
0xa77921d7, 'CurrentRupees',
|
||||
//0x31ab5580, 'CurrentHearts',
|
||||
0xf9212c74, 'MaxStamina',
|
||||
0x15ec5858, 'PonyPoints',
|
||||
0xe573f564, 'Playtime',
|
||||
|
||||
0xd7a3f6ba, 'ArrayPouchSwords',
|
||||
0xc61785c2, 'ArrayPouchBows',
|
||||
0x05271e7d, 'ArrayPouchShields',
|
||||
|
||||
0x65efd0be, 'ArrayWeaponIds',
|
||||
0x8b12d062, 'ArrayWeaponDurabilities',
|
||||
0xdd846288, 'ArrayWeaponModifiers',
|
||||
0xfda1d214, 'ArrayWeaponModifierValue',
|
||||
0x80707cad, 'ArrayWeaponFuseIds',
|
||||
0x791c4a0b, 'ArrayBowIds',
|
||||
0x60589200, 'ArrayBowDurabilities',
|
||||
0xd59aeed5, 'ArrayBowModifiers',
|
||||
0xdfd216f2, 'ArrayBowModifierValue',
|
||||
0x273190f4, 'ArrayShieldIds',
|
||||
0xc3416d19, 'ArrayShieldDurabilities',
|
||||
0x464b410c, 'ArrayShieldModifiers',
|
||||
0xa6a38304, 'ArrayShieldModifierValue',
|
||||
0xc95833d9, 'ArrayShieldFuseIds',
|
||||
0x754e8549, 'ArrayArmorIds',
|
||||
0x24dd3262, 'ArrayArrowIds',
|
||||
0x53b27d94, 'ArrayArrowQuantities',
|
||||
0xd96ebf12, 'ArrayMaterialIds',
|
||||
0xde2d8500, 'ArrayMaterialQuantities',
|
||||
0x7c0f89ad, 'ArrayFoodIds',
|
||||
0x2a952a60, 'ArrayFoodQuantities',
|
||||
0x6f743e98, 'ArrayFoodEffects',
|
||||
0x9d3b5847, 'ArrayFoodEffectsHearts',
|
||||
0x904a7213, 'ArrayFoodEffectsMultiplier',
|
||||
0xf097cefa, 'ArrayFoodEffectsTime', // in seconds
|
||||
0x2e470848, 'ArrayFoodEffectsUnknown1', //???
|
||||
0xa86f2f10, 'ArrayDeviceIds',
|
||||
0x60d16ab0, 'ArrayDeviceQuantities',
|
||||
0x22c6530a, 'ArrayKeyIds',
|
||||
0x60fac288, 'ArrayKeyQuantities',
|
||||
|
||||
0x7bde80e9, 'ArrayHorseIds',
|
||||
0xd2ddb868, 'ArrayHorseNames'
|
||||
],
|
||||
|
||||
OffsetsItems:{
|
||||
'pouchSword':0x04aa64,
|
||||
'pouchBow':0x047630,
|
||||
'pouchShield':0x04d080
|
||||
},
|
||||
|
||||
/* read/write data */
|
||||
readArraySize:function(arrayOffset){
|
||||
return tempFile.readU32(this.currentItemOffset + arrayOffset);
|
||||
readU32:function(hashKey, arrayIndex){
|
||||
if(typeof arrayIndex==='number')
|
||||
return tempFile.readU32(SavegameEditor.Offsets[hashKey] + 0x04 + arrayIndex*0x04);
|
||||
return tempFile.readU32(SavegameEditor.Offsets[hashKey]);
|
||||
},
|
||||
readU32Array:function(arrayOffset, index){
|
||||
return tempFile.readU32(this.currentItemOffset + 0x04 + arrayOffset + index*4);
|
||||
readString64:function(hashKey, arrayIndex){
|
||||
if(typeof arrayIndex==='number')
|
||||
return tempFile.readString(SavegameEditor.Offsets[hashKey] + 0x04 + arrayIndex*0x40, 0x40).replace(/\u0000+$/,'');
|
||||
return tempFile.readString(SavegameEditor.Offsets[hashKey], 0x40).replace(/\u0000+$/,'');
|
||||
},
|
||||
readString64Array:function(arrayOffset, index){
|
||||
return tempFile.readString(this.currentItemOffset + 0x04 + arrayOffset + index*this.Constants.STRING64_SIZE, this.Constants.STRING64_SIZE);
|
||||
},
|
||||
readUTF8String64Array:function(arrayOffset, index){
|
||||
readStringUTF8:function(hashKey, arrayIndex){
|
||||
var offset=this.Offsets[hashKey];
|
||||
if(typeof arrayIndex==='number')
|
||||
offset+=0x04 + arrayIndex*0x20;
|
||||
var str='';
|
||||
var offset=this.currentItemOffset + 0x04 + arrayOffset + index*this.Constants.STRING_SIZE;
|
||||
for(var i=0; i<this.Constants.STRING_SIZE/2; i++){
|
||||
for(var i=0; i<0x20; i+=2){
|
||||
var charCode=tempFile.readU16(offset);
|
||||
if(!charCode)
|
||||
break;
|
||||
str+=String.fromCharCode(charCode);
|
||||
offset+=2;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
writeU32Array:function(arrayOffset, index, value){
|
||||
tempFile.writeU32(this.currentItemOffset + 0x04 + arrayOffset + index*4, value);
|
||||
},
|
||||
writeString64Array:function(arrayOffset, index, value){
|
||||
tempFile.writeString(this.currentItemOffset + 0x04 + arrayOffset + index*this.Constants.STRING64_SIZE, value, this.Constants.STRING64_SIZE);
|
||||
return str.replace(/\u0000+$/,'');
|
||||
},
|
||||
|
||||
_toHexInt:function(i){var s=i.toString(16);while(s.length<8)s='0'+s;return '0x'+s},
|
||||
_writeBoolean:function(offset,val,arrayIndex){if(arrayIndex)tempFile.writeU32(offset+8*arrayIndex,val?1:0);else tempFile.writeU32(offset,val?1:0)},
|
||||
_writeValue:function(offset,val,arrayIndex){if(arrayIndex)tempFile.writeU32(offset+8*arrayIndex,val);else tempFile.writeU32(offset,val)},
|
||||
/*_writeFloat32:function(offset,val,arrayIndex){if(arrayIndex)tempFile.writeF32(offset+8*arrayIndex,val);else tempFile.writeF32(offset,val)},*/
|
||||
_readArray:function(hashKey, arrayIndex, callback){
|
||||
var arraySize=SavegameEditor.readU32(hashKey);
|
||||
if(typeof arrayIndex==='number'){
|
||||
if(arrayIndex>=0 && arrayIndex<arraySize)
|
||||
return callback(hashKey, arrayIndex);
|
||||
return null;
|
||||
}
|
||||
var elems=[];
|
||||
for(var i=0; i<arraySize; i++){
|
||||
elems.push(callback(hashKey, i));
|
||||
}
|
||||
return elems;
|
||||
},
|
||||
readU32Array:function(hashKey, arrayIndex){
|
||||
return this._readArray(hashKey, arrayIndex, this.readU32);
|
||||
},
|
||||
readString64Array:function(hashKey, arrayIndex){
|
||||
return this._readArray(hashKey, arrayIndex, this.readString64);
|
||||
},
|
||||
readStringUTF8Array:function(hashKey, arrayIndex){
|
||||
return this._readArray(hashKey, arrayIndex, this.readStringUTF8);
|
||||
},
|
||||
|
||||
writeU32:function(hashKey, arrayIndex, value){
|
||||
if(typeof arrayIndex==='number')
|
||||
tempFile.writeU32(this.Offsets[hashKey] + 0x04 + arrayIndex*0x04, value);
|
||||
else
|
||||
tempFile.writeU32(this.Offsets[hashKey], value);
|
||||
},
|
||||
writeString64:function(hashKey, arrayIndex, value){
|
||||
if(typeof arrayIndex==='number')
|
||||
tempFile.writeString(this.Offsets[hashKey] + 0x04 + arrayIndex*0x40, value, 0x40);
|
||||
else
|
||||
tempFile.writeString(this.Offsets[hashKey], value, 0x40);
|
||||
},
|
||||
writeF32:function(hashKey, arrayIndex, value){
|
||||
if(typeof arrayIndex==='number')
|
||||
tempFile.writeF32(this.Offsets[hashKey] + 0x04 + arrayIndex*0x04, value);
|
||||
else
|
||||
tempFile.writeF32(this.Offsets[hashKey], value);
|
||||
},
|
||||
|
||||
|
||||
/* private functions */
|
||||
_searchHash:function(hash){
|
||||
for(var i=0x0c; i<tempFile.fileSize; i+=8)
|
||||
if(hash===tempFile.readU32(i))
|
||||
return i;
|
||||
return false;
|
||||
},
|
||||
_readFromHash:function(hash){
|
||||
var offset=this._searchHash(hash);
|
||||
if(typeof offset === 'number')
|
||||
return tempFile.readU32(offset+4);
|
||||
return false;
|
||||
},
|
||||
_writeValueAtHash:function(hash,val){
|
||||
var offset=this._searchHash(hash);
|
||||
if(typeof offset==='number')
|
||||
this._writeValue(offset+4,val);
|
||||
},
|
||||
|
||||
_toHexInt:function(i){var s=i.toString(16);while(s.length<8)s='0'+s;return '0x'+s},
|
||||
_getOffsets:function(){
|
||||
this.Offsets={};
|
||||
this.Headers={};
|
||||
var startSearchOffset=0x28;
|
||||
for(var i=0; i<this.Hashes.length; i+=2){
|
||||
for(var j=startSearchOffset; j<tempFile.fileSize; j+=8){
|
||||
if(this.Hashes[i]===tempFile.readU32(j)){
|
||||
this.Offsets[this.Hashes[i+1]]=j+4;
|
||||
this.Headers[this.Hashes[i+1]]=this.Hashes[i];
|
||||
startSearchOffset=j+8;
|
||||
break;
|
||||
}
|
||||
for(var i=0x000028; i<0x03c800; i+=8){
|
||||
var hash=tempFile.readU32(i);
|
||||
var foundHashIndex=this.Hashes.indexOf(hash);
|
||||
if(hash===0xa3db7114){ //looks like this hash is always the final one (at least in v1.0 and v1.1)
|
||||
break;
|
||||
}else if(foundHashIndex!==-1){
|
||||
if(/^Array/.test(this.Hashes[foundHashIndex+1]))
|
||||
this.Offsets[this.Hashes[foundHashIndex+1]]=tempFile.readU32(i+4);
|
||||
else
|
||||
this.Offsets[this.Hashes[foundHashIndex+1]]=i+4;
|
||||
}
|
||||
}
|
||||
for(var i=0; i<this.Hashes.length; i+=2){
|
||||
if(typeof this.Offsets[this.Hashes[i+1]] === 'undefined'){
|
||||
console.log(this.Hashes[i+1]+' not found');
|
||||
console.error('hash '+this.Hashes[i+1]+' not found');
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -137,6 +184,9 @@ SavegameEditor={
|
||||
spanItemId.className='item-name clickable';
|
||||
spanItemId.id='item-name-'+item.category+'-'+item.index;
|
||||
spanItemId.innerHTML=item.getItemTranslation();
|
||||
if(item.getItemTranslation()===item.id){
|
||||
spanItemId.style.color='red';
|
||||
}
|
||||
spanItemId.addEventListener('click', function(){
|
||||
SavegameEditor.editItem(item);
|
||||
}, false);
|
||||
@ -152,6 +202,12 @@ SavegameEditor={
|
||||
lastColumn.appendChild(item._htmlInputModifierValue);
|
||||
}else if(item.quantity!==0xffffffff && (item.category==='arrows' || item.category==='materials' || item.category==='food' || item.category==='devices' || item.category==='key')){
|
||||
lastColumn.appendChild(item._htmlInputQuantity);
|
||||
if(item.category==='food'){
|
||||
lastColumn.appendChild(item._htmlSelectFoodEffect);
|
||||
lastColumn.appendChild(item._htmlSelectFoodEffectHearts);
|
||||
lastColumn.appendChild(item._htmlSelectFoodEffectMultiplier);
|
||||
lastColumn.appendChild(item._htmlSelectFoodEffectTime);
|
||||
}
|
||||
}
|
||||
|
||||
var r=row([1,6,3,2],
|
||||
@ -168,46 +224,44 @@ SavegameEditor={
|
||||
},
|
||||
|
||||
addItem:function(catId){
|
||||
var categoryHash=capitalizeCategoryId(catId);
|
||||
var maxItems=SavegameEditor.readU32('Array'+categoryHash+'Ids');
|
||||
|
||||
var lastItem=this.getLastItem(catId);
|
||||
var newItem, maxItems;
|
||||
if(catId==='weapons' || catId==='bows' || catId==='shields'){
|
||||
newItem=new Equipment(catId, lastItem? lastItem.index+1 : 0);
|
||||
if(lastItem){
|
||||
newItem.durability=lastItem.durability;
|
||||
newItem.modifier=lastItem.modifier;
|
||||
newItem.modifierValue=lastItem.modifierValue;
|
||||
newItem.fuseId=lastItem.fuseId;
|
||||
}
|
||||
maxItems=Equipment.readMaxCapacity(catId);
|
||||
}else if(catId==='armors'){
|
||||
newItem=new Armor(lastItem? lastItem.index+1 : 0);
|
||||
if(lastItem){
|
||||
newItem.dyeColor=lastItem.dyeColor;
|
||||
}
|
||||
maxItems=Armor.readMaxCapacity();
|
||||
}else if(catId==='arrows' || catId==='materials' || catId==='food' || catId==='devices' || catId==='key'){
|
||||
newItem=new Item(catId, lastItem? lastItem.index+1 : 0);
|
||||
if(lastItem){
|
||||
newItem.quantity=lastItem.quantity;
|
||||
}
|
||||
maxItems=Items.readMaxCapacity(catId);
|
||||
var newId;
|
||||
|
||||
if(lastItem && lastItem.index===(maxItems -1)){
|
||||
console.warn('not enough space in '+catId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(lastItem.index===(maxItems -1))
|
||||
return false;
|
||||
|
||||
|
||||
var itemList=this.getTranslationHash(newItem);
|
||||
var itemList=this.getTranslationHash(catId);
|
||||
var itemListArray=[];
|
||||
for(var id in itemList){
|
||||
itemListArray.push(id);
|
||||
}
|
||||
|
||||
if(lastItem){
|
||||
var nextIndexId=itemListArray.indexOf(lastItem.id)+1;
|
||||
if(nextIndexId===itemListArray.length)
|
||||
nextIndexId=0;
|
||||
newId=itemListArray[nextIndexId];
|
||||
}else{
|
||||
newId=itemListArray[0];
|
||||
}
|
||||
|
||||
var nextIndexId=itemListArray.indexOf(lastItem.id)+1;
|
||||
if(nextIndexId===itemListArray.length)
|
||||
nextIndexId=0;
|
||||
newItem.id=itemListArray[nextIndexId];
|
||||
var newItem, maxItems;
|
||||
if(catId==='weapons' || catId==='bows' || catId==='shields'){
|
||||
newItem=lastItem? lastItem.copy(lastItem.index+1, newId) : new Equipment(catId, 0, newId);
|
||||
if(lastItem)
|
||||
newItem.restoreDurability();
|
||||
}else if(catId==='armors'){
|
||||
newItem=lastItem? lastItem.copy(lastItem.index+1, newId) : new Armor(0, newId);
|
||||
}else if(catId==='arrows' || catId==='materials' || catId==='food' || catId==='devices' || catId==='key'){
|
||||
newItem=lastItem? lastItem.copy(lastItem.index+1, newId) : new Item(catId, 0, newId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.currentItems[catId].push(newItem);
|
||||
var row=this._createItemRow(newItem);
|
||||
@ -228,13 +282,13 @@ SavegameEditor={
|
||||
return null;
|
||||
},
|
||||
|
||||
getTranslationHash:function(item){
|
||||
if(typeof item.durability==='number') //weapons, bows or shields
|
||||
return Equipment.TRANSLATIONS[item.category];
|
||||
else if(item.category==='armors')
|
||||
getTranslationHash:function(catId){
|
||||
if(catId==='weapons' || catId==='bows' || catId==='shields')
|
||||
return Equipment.TRANSLATIONS[catId];
|
||||
else if(catId==='armors')
|
||||
return Armor.TRANSLATIONS;
|
||||
else if(typeof item.quantity==='number') //arrows, materials, food, devices or key
|
||||
return Items.TRANSLATIONS[item.category];
|
||||
else if(catId==='arrows' || catId==='materials' || catId==='food' || catId==='devices' || catId==='key')
|
||||
return Item.TRANSLATIONS[catId];
|
||||
return null;
|
||||
},
|
||||
|
||||
@ -244,28 +298,24 @@ SavegameEditor={
|
||||
/* prepare edit item selector */
|
||||
if(this.selectItem.lastCategory !== item.category){
|
||||
this.selectItem.innerHTML='';
|
||||
var foundItemId=false;
|
||||
var itemList=this.getTranslationHash(item);
|
||||
var itemList=this.getTranslationHash(item.category);
|
||||
for(var itemId in itemList){
|
||||
var opt=document.createElement('option');
|
||||
opt.value=itemId;
|
||||
opt.innerHTML=itemList[itemId];
|
||||
|
||||
if(itemId===item.id)
|
||||
foundItemId=true;
|
||||
|
||||
this.selectItem.appendChild(opt);
|
||||
}
|
||||
if(!foundItemId){
|
||||
var opt=document.createElement('option');
|
||||
opt.value=item.id;
|
||||
opt.innerHTML=item.id;
|
||||
this.selectItem.appendChild(opt);
|
||||
}
|
||||
|
||||
this.selectItem.lastCategory=item.category;
|
||||
}
|
||||
this.selectItem.value=item.id;
|
||||
if(!this.selectItem.value){
|
||||
var opt=document.createElement('option');
|
||||
opt.value=item.id;
|
||||
opt.innerHTML='Unknown: '+item.id;
|
||||
this.selectItem.appendChild(opt);
|
||||
this.selectItem.value=item.id;
|
||||
}
|
||||
|
||||
document.getElementById('item-name-'+item.category+'-'+item.index).innerHTML='';
|
||||
document.getElementById('item-name-'+item.category+'-'+item.index).parentElement.appendChild(this.selectItem);
|
||||
@ -284,6 +334,12 @@ SavegameEditor={
|
||||
// document.getElementById('number-item'+i).maxValue=this._getItemMaximumQuantity(newId);
|
||||
},
|
||||
|
||||
restoreDurability:function(catId){
|
||||
this.currentItems[catId].forEach(function(equipment, i){
|
||||
equipment.restoreDurability();
|
||||
});
|
||||
},
|
||||
|
||||
/* check if savegame is valid */
|
||||
checkValidSavegame:function(){
|
||||
tempFile.littleEndian=true;
|
||||
@ -321,7 +377,6 @@ SavegameEditor={
|
||||
|
||||
if(tempFile.fileSize===this.Constants.FILESIZE[i] && dummyHeader===0x01020304 && versionHash===this.Constants.HEADER[i]){
|
||||
this._getOffsets();
|
||||
this.currentItemOffset=(SavegameEditor.Offsets.TempItemData - 0x04) - 0x3c048;
|
||||
setValue('version', this.Constants.VERSION[i]);
|
||||
return true;
|
||||
}
|
||||
@ -343,6 +398,7 @@ SavegameEditor={
|
||||
}, false);
|
||||
|
||||
setNumericRange('rupees', 0, 999999);
|
||||
setNumericRange('pony-points', 0, 999999);
|
||||
|
||||
setNumericRange('pouch-size-swords', 9, 18);
|
||||
setNumericRange('pouch-size-bows', 5, 13);
|
||||
@ -364,7 +420,7 @@ SavegameEditor={
|
||||
});
|
||||
|
||||
var horseTypes=[];
|
||||
Horses.HORSE_TYPES.forEach(function(id){
|
||||
Horse.HORSE_TYPES.forEach(function(id){
|
||||
horseTypes.push({name:id, value:id});
|
||||
});
|
||||
for(var i=0; i<6; i++){
|
||||
@ -452,6 +508,8 @@ SavegameEditor={
|
||||
load:function(){
|
||||
tempFile.fileName='progress.sav';
|
||||
|
||||
this.selectItem.lastCategory=null;
|
||||
|
||||
/* empty item containers */
|
||||
var ITEM_CATS=['weapons','bows','shields','armors','arrows','materials','food','devices','key'];
|
||||
ITEM_CATS.forEach(function(catId, i){
|
||||
@ -464,30 +522,27 @@ SavegameEditor={
|
||||
'bows':Equipment.readAll('bows'),
|
||||
'shields':Equipment.readAll('shields'),
|
||||
'armors':Armor.readAll(),
|
||||
'arrows':Items.readAll('arrows'),
|
||||
'materials':Items.readAll('materials'),
|
||||
'food':Items.readAll('food'),
|
||||
'devices':Items.readAll('devices'),
|
||||
'key':Items.readAll('key'),
|
||||
'arrows':Item.readAll('arrows'),
|
||||
'materials':Item.readAll('materials'),
|
||||
'food':Item.readAll('food'),
|
||||
'devices':Item.readAll('devices'),
|
||||
'key':Item.readAll('key'),
|
||||
|
||||
'horses':Horses.readAll(),
|
||||
|
||||
'pouchSword':SavegameEditor.readU32Array(SavegameEditor.OffsetsItems.pouchSword, 0),
|
||||
'pouchBow':SavegameEditor.readU32Array(SavegameEditor.OffsetsItems.pouchBow, 0),
|
||||
'pouchShield':SavegameEditor.readU32Array(SavegameEditor.OffsetsItems.pouchShield, 0)
|
||||
'horses':Horse.readAll()
|
||||
};
|
||||
|
||||
|
||||
/* prepare editor */
|
||||
setValue('rupees', tempFile.readU32(this.Offsets.TempRupees));
|
||||
/*setValue('mons', tempFile.readU32(this.Offsets.MONS));*/
|
||||
setValue('max-hearts', tempFile.readU32(this.Offsets.TempMaxHearts));
|
||||
setValue('max-stamina', tempFile.readU32(this.Offsets.TempStamina));
|
||||
setValue('rupees', this.readU32('CurrentRupees'));
|
||||
/*setValue('mons', this.readU32(this.Offsets.MONS));*/
|
||||
setValue('max-hearts', this.readU32('MaxHearts'));
|
||||
setValue('max-stamina', this.readU32('MaxStamina'));
|
||||
setValue('pony-points', this.readU32('PonyPoints'));
|
||||
|
||||
setValue('number-pouch-size-swords', this.currentItems.pouchSword);
|
||||
setValue('number-pouch-size-bows', this.currentItems.pouchBow);
|
||||
setValue('number-pouch-size-shields', this.currentItems.pouchShield);
|
||||
setValue('number-pouch-size-swords', this.readU32Array('ArrayPouchSwords', 0));
|
||||
setValue('number-pouch-size-bows', this.readU32Array('ArrayPouchBows', 0));
|
||||
setValue('number-pouch-size-shields', this.readU32Array('ArrayPouchShields', 0));
|
||||
|
||||
setValue('playtime', this._timeToString(tempFile.readU32(this.Offsets.TempPlaytime)));
|
||||
setValue('playtime', this._timeToString(this.readU32('Playtime')));
|
||||
|
||||
/*setValue('relic-gerudo', tempFile.readU32(this.Offsets.RELIC_GERUDO));
|
||||
setValue('relic-goron', tempFile.readU32(this.Offsets.RELIC_GORON));
|
||||
@ -570,14 +625,15 @@ SavegameEditor={
|
||||
/* save function */
|
||||
save:function(){
|
||||
/* STATS */
|
||||
tempFile.writeU32(this.Offsets.TempRupees, getValue('rupees'));
|
||||
/*tempFile.writeU32(this.Offsets.MONS, getValue('mons'));*/
|
||||
tempFile.writeU32(this.Offsets.TempMaxHearts, getValue('max-hearts'));
|
||||
tempFile.writeU32(this.Offsets.TempStamina, getValue('max-stamina'));
|
||||
this.writeU32('CurrentRupees', null, getValue('rupees'));
|
||||
/*this.writeU32('Mons', getValue('mons'));*/
|
||||
this.writeU32('MaxHearts', null, getValue('max-hearts'));
|
||||
this.writeU32('MaxStamina', null, getValue('max-stamina'));
|
||||
this.writeU32('PonyPoints', null, getValue('pony-points'));
|
||||
|
||||
SavegameEditor.writeU32Array(this.OffsetsItems.pouchSword, 0, this.currentItems.pouchSword);
|
||||
SavegameEditor.writeU32Array(this.OffsetsItems.pouchBow, 0, this.currentItems.pouchBow);
|
||||
SavegameEditor.writeU32Array(this.OffsetsItems.pouchShield, 0, this.currentItems.pouchShield);
|
||||
this.writeU32('ArrayPouchSwords', 0, getValue('pouch-size-swords'));
|
||||
this.writeU32('ArrayPouchBows', 0, getValue('pouch-size-bows'));
|
||||
this.writeU32('ArrayPouchShields', 0, getValue('pouch-size-shields'));
|
||||
|
||||
/*tempFile.writeU32(this.Offsets.RELIC_GERUDO, getValue('relic-gerudo'));
|
||||
tempFile.writeU32(this.Offsets.RELIC_GORON, getValue('relic-goron'));
|
||||
@ -611,9 +667,9 @@ SavegameEditor={
|
||||
|
||||
|
||||
/* HORSES */
|
||||
SavegameEditor.currentItems.horses.forEach(function(horse, j){
|
||||
horse.save();
|
||||
});
|
||||
for(var i=0; i<SavegameEditor.currentItems.horses.length; i++){
|
||||
SavegameEditor.currentItems.horses[i].save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,7 +718,9 @@ window.addEventListener('scroll', onScroll, false);
|
||||
|
||||
|
||||
|
||||
|
||||
function capitalizeCategoryId(catId){
|
||||
return (catId.charAt(0).toUpperCase() + catId.substr(1)).replace(/s$/, '')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -119,12 +119,12 @@ function createHashInput(container, hashId, type, offset){
|
||||
|
||||
|
||||
function setBoolean(){
|
||||
SavegameEditor._writeBoolean(this.offset, this.checked, 0);
|
||||
tempFile.writeU32(this.offset, this.checked? 1: 0);
|
||||
}
|
||||
function setS32(){
|
||||
SavegameEditor._writeValue(this.offset, this.value, 0);
|
||||
tempFile.writeU32(this.offset, parseInt(this.value));
|
||||
}
|
||||
function setF32(){
|
||||
/*function setF32(){
|
||||
SavegameEditor._writeFloat32(this.offset, this.value, 0);
|
||||
}
|
||||
function setString(){
|
||||
@ -135,7 +135,7 @@ function setString64(){
|
||||
}
|
||||
function setString256(){
|
||||
SavegameEditor._writeString256(this.offset, this.value);
|
||||
}
|
||||
}*/
|
||||
|
||||
var TOTKMasterEditor=(function(){
|
||||
var HASHES_PER_PAGE=100;
|
||||
|
Loading…
x
Reference in New Issue
Block a user