valheim trader locations
HTML
<html>
<body>
<p>
<h1>
Valheim trader map tool!
</h1>
<h3><a href="https://i.imgur.com/vUZXnn3.png">exmaple result</a></h3>
</p>
<ol>
<li>Click the choose file button (don't worry, your world will not leave your computer)</li>
<li>Browse to your "world.db" file - it is named what you named your world. It is in folder: <code>%appdata%\..\LocalLow\IronGate\Valheim\worlds</code></li>
<li> Use the map or coordinates below to find your trader! Each world can have a large number of traders, but they won't be generated unless a player entered the same general region some time. No cheating needed, but if you wanted to.... <sub>press f5, enter "imacheater", then "goto x,y"</sub></li>
</ol>
Select your world below: <br />
<input type="file" onChange="onPressLoad(this)">
<br /> <br />
Locations of traders (x,y,z):<br />
<code id="locations"></code><br /><br />
<canvas id="map" width="100%" height="auto" style="cursor:crosshair;background:url(https://i.imgur.com/R7xPHaY.png)"/>
<img id="shopicon" src="https://i.imgur.com/Sk6Nll8.png">
thx to modding discord: https://discord.gg/RBq2mzeu4z
</body>
</html>
JavaScript
// https://discord.gg/RBq2mzeu4z
// thanks n.#4414 & Nem#1860
// get offset of bytes after occurrence of 'ascii' that occurs at/after 'pos' in 'buf'
function findText(buf, pos, ascii) {
// grab a uint8array of the ascii string to find
var encoder = new TextEncoder();
var findview = encoder.encode(ascii);
var endsz = (buf.byteLength - findview.byteLength)
console.log("Searching "+endsz+" bytes starting from "+pos);
// return the first occurrence
for (var iter_buf = pos; iter_buf != endsz; iter_buf++) {
for (var iter_find = 0; iter_find != findview.byteLength; iter_find++) {
if (findview[iter_find] != buf[iter_buf+iter_find]) break;
if (iter_find == findview.byteLength-1) return iter_buf+findview.byteLength;
}
}
// if we didn't find it...
return -1;
}
// image: (0,0) is top left || world: (0,0) is center altar
// image: y grows going down || world: y reduces going down
function worldtoimage(coord) {
var imgrect = document.getElementById("map").getBoundingClientRect();
var newcoord = {x:coord.x, y:coord.y, z:coord.z};
// invert the y axis because html5 canvas...
newcoord.y = newcoord.y * -1;
// scale it to our image. world is 10k radius, so *2
newcoord.x = newcoord.x * (imgrect.width / (10000*2));
newcoord.y = newcoord.y * (imgrect.height / (10000*2));
// center-offset it
newcoord.x += Math.floor(imgrect.width/2);
newcoord.y += Math.floor(imgrect.height/2);
return newcoord;
}
function drawShop(ctx, coord) {
var imagecoord = worldtoimage(coord);
// draw the icon for roleplay
var icon = document.getElementById("shopicon");
ctx.drawImage(icon, imagecoord.x-20, imagecoord.y-30);
// draw a dot for precision
ctx.fillStyle = "#ff0000"; // Red color
ctx.beginPath();
ctx.arc(imagecoord.x, imagecoord.y, 4, 0, Math.PI * 2, true);
ctx.fill();
ctx.font = "12px Georgia";
ctx.fillText("("+coord.x.toFixed(0)+","+coord.y.toFixed(0)+")", imagecoord.x-25, imagecoord.y-35);
}
// draw some shops
function...