0
0
mirror of https://github.com/marcrobledo/savegame-editors.git synced 2025-04-28 09:05:10 +00:00

Merge pull request #53 from faxx1080/botw-save-coordinates

Add support for position editing, and loaded map editing.
This commit is contained in:
Marc Robledo 2018-04-08 09:20:38 +02:00 committed by GitHub
commit 18c3b6961d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 149 additions and 3 deletions

View File

@ -77,6 +77,51 @@
<div class="ten columns"><label for="number-playtime">Playtime</label></div>
<div class="two columns"><input type="text" id="number-playtime" class="text-right full-width" disabled /></div>
</div>
<!-- Coordinates (Requires a memory editor) -->
<h3 class="border-green">Coordinates</h3>
<div class="row">
<div class="six columns"><label for="float-pos-x">X</label></div>
<div class="three columns text-right">
<button onclick="fixPCCoords()">Fix for Dungeon</button>
</div>
<div class="three columns">
<input id="float-pos-x" class="full-width" type="text" />
</div>
</div>
<div class="row">
<div class="nine columns"><label for="float-pos-y">Y</label></div>
<div class="three columns"><input id="float-pos-y" class="full-width" type="text" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="float-pos-z">Z</label></div>
<div class="three columns"><input id="float-pos-z" class="full-width" type="text" /></div>
</div>
<div class="row">
<div class="seven columns"><label for="input-pos-map">Map (44A0)</label></div>
<div class="two columns text-right">
<button onclick="guessMainFieldGrid()">Guess</button>
</div>
<div class="three columns">
<input id="input-pos-map" class="full-width" type="text" />
</div>
</div>
<div class="row">
<div class="nine columns"><label for="input-pos-maptype">Map Type (DC658)</label></div>
<div class="three columns"><input id="input-pos-maptype" class="full-width" type="text" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="float-pos-x-horse">Horse X</label></div>
<div class="three columns"><input id="float-pos-x-horse" class="full-width" type="text" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="float-pos-y-horse">Horse Y</label></div>
<div class="three columns"><input id="float-pos-y-horse" class="full-width" type="text" /></div>
</div>
<div class="row">
<div class="nine columns"><label for="float-pos-z-horse">Horse Z</label></div>
<div class="three columns"><input id="float-pos-z-horse" class="full-width" type="text" /></div>
</div>
<!-- ITEMS -->
<h3>Weapons</h3><div id="container-weapons"></div>
@ -96,6 +141,7 @@
<div class="text-center"><button class="with-icon icon10" onclick="SavegameEditor.editHorse(4)">Edit horse 4</button></div>
<div class="text-center"><button class="with-icon icon10" onclick="SavegameEditor.editHorse(5)">Edit untamed horse</button></div>
<!-- COMPLETIONISM -->
<h3 class="border-green">Completionism</h3>
<div class="row">

View File

@ -1,5 +1,5 @@
CACHE MANIFEST
#v20180212b
#v20180311c
#CACHE:
index.html
zelda-botw.css

View File

@ -7,7 +7,7 @@ var currentEditingItem=0;
SavegameEditor={
Name:'The legend of Zelda: Breath of the wild',
Filename:'game_data.sav',
Version:20181202,
Version:20180311,
/* Constants */
Constants:{
@ -58,7 +58,11 @@ SavegameEditor={
RELIC_GORON: [0xf1cf4807, 0x0cb3c0, 0x0cb488, 0x0cb460, 0x0cdbf8, 0x0e6340, 0x0e7ba0, 0x0e7ba0],
RELIC_RITO: [0xfda0cde4, 0x0da0d8, 0x0da190, 0x0da160, 0x0dcac0, 0x0f8370, 0x0f9cc8, 0x0f9cc8],
MOTORCYCLE: [0xc9328299, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d2660, 0x0d2660] /* IsGet_Obj_Motorcycle */
MOTORCYCLE: [0xc9328299, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0d2660, 0x0d2660], /* IsGet_Obj_Motorcycle */
HORSE_POSITION: [0x00000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x089a7C, 0x089a7C],
MAP: [0x00000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0044A0, 0x0044A0],
MAPTYPE: [0x00000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x0dc658, 0x0dc658],
},
@ -395,6 +399,32 @@ SavegameEditor={
document.getElementById('row-motorcycle').style.display='none';
}
// Coordinates
var px = 0, py = 0, pz = 0;
var off = SavegameEditor._searchHash(SavegameEditor.Constants.PLAYER_LOCATION);
if (off){
px = tempFile.readFloat32(off+4)
py = tempFile.readFloat32(off+12)
pz = tempFile.readFloat32(off+20)
}
setValue('pos-x',px)
setValue('pos-y',py)
setValue('pos-z',pz)
// map, maptype
setValue('pos-map',this._readString(this.Offsets.MAP))
setValue('pos-maptype',this._readString(this.Offsets.MAPTYPE))
// horse
off = undefined
off = this.Offsets.HORSE_POSITION
if (off){
px = tempFile.readFloat32(off+4)
py = tempFile.readFloat32(off+12)
pz = tempFile.readFloat32(off+20)
}
setValue('pos-x-horse',px) // cx
setValue('pos-y-horse',py)
setValue('pos-z-horse',pz)
loadMapPins()
/* items */
@ -478,6 +508,26 @@ SavegameEditor={
if(this.Offsets.MOTORCYCLE){
tempFile.writeInt(this.Offsets.MOTORCYCLE, getField('checkbox-motorcycle').checked?1:0);
}
// position
var px = 0, py = 0, pz = 0;
var off = SavegameEditor._searchHash(SavegameEditor.Constants.PLAYER_LOCATION);
if (off){
tempFile.writeFloat32(off+4, getValue('pos-x'))
tempFile.writeFloat32(off+12, getValue('pos-y'))
tempFile.writeFloat32(off+20, getValue('pos-z'))
}
// map, maptype
this._writeString(this.Offsets.MAP, getValue('pos-map'))
this._writeString(this.Offsets.MAPTYPE, getValue('pos-maptype'))
// horse
off = undefined
off = this.Offsets.HORSE_POSITION
if (off){
tempFile.writeFloat32(off+4, getValue('pos-x-horse'))
tempFile.writeFloat32(off+12, getValue('pos-y-horse'))
tempFile.writeFloat32(off+20, getValue('pos-z-horse'))
}
/* ITEMS */
for(var i=0; i<this.Constants.MAX_ITEMS; i++){
@ -612,6 +662,54 @@ function loadMapPins(){
setValue('number-map-pins', count);
}
function guessMainFieldGrid() {
if (getValue('pos-maptype') == "MainField")
setValue("pos-map",guessMainFieldGridInternal(getValue("pos-x"), getValue("pos-z")))
else
MarcDialogs.alert("This only applies for MainField, not trials or divine beasts.")
}
function fixPCCoords() {
let dungeon = getValue('pos-map')
if (dungeon == "RemainsFire") {
setValue('pos-x', 0)
setValue('pos-y',16.8)
setValue('pos-z',69.5)
} else if (dungeon == "RemainsWater") {
setValue('pos-x',47.7)
setValue('pos-y',6.05)
setValue('pos-z',6.3)
} else if (dungeon == "RemainsWind") {
setValue('pos-x',0)
setValue('pos-y',3.4)
setValue('pos-z',-77.7)
} else if (dungeon == "RemainsElectric") {
setValue('pos-x',0)
setValue('pos-y',71.9)
setValue('pos-z',3.7)
} else if (dungeon == "FinalTrial") {
setValue('pos-x',0)
setValue('pos-y',-0.4)
setValue('pos-z',64.5)
}
}
function guessMainFieldGridInternal(xpos, zpos) {
// A1 = -4974.629, -3974.629
// J8 = 4974.629, 3974.629
// X and letter part of grid: west/east
// Z and number part of grid: north/south
// grid also visible at https://mrcheeze.github.io/botw-object-map/
// idea: Take position fraction out of the whole grid and divide equally.
let gridvalX = Math.min(10, Math.max(1, Math.trunc((xpos + 4974.629) / 9949.258 * 10 + 1)))
let gridvalZ = Math.min( 8, Math.max(1, Math.trunc((zpos + 3974.629) / 7949.258 * 8 + 1)))
return String.fromCharCode(64 + gridvalX) + '-' + gridvalZ
}
function clearMapPins(){
// types
var count = 0;
@ -676,6 +774,8 @@ function dist(px,py,pz,l){
return Math.sqrt((Math.pow(l[0]-px,2))+(Math.pow(l[2]-pz,2)))
}
function addToMap(data, icon){
var px = 0, py = 0, pz = 0;
var off = SavegameEditor._searchHash(SavegameEditor.Constants.PLAYER_LOCATION);