Ok, got it. I forgot about the nearly random tiles. Otherwise, you could use the Galv plugin to spawn event in region ID 0(which means all map tiles that don't have regions), then it will automatically check for solid X, Y, and free to spawn. But guess it's a little complicated to do it.
But I made a function to do it for you. Currently, it will check if the tile X, Y is:
- Passable;
- Doesn't have an event
- Doesn't have a vehicle
- Doesn't have a player
If all of that is true, then you get a free coordinate X, Y
It has four parameters:
px, py, range, eventId
So you can either use the event id for it or an x, y coordinate of your choice.
After that, you set the range parameter which will be responsible to define all the nearby tiles that you want to check.
If you set a range of 2 and put the event id of the chest, then the function will search for free tiles on the range shown in the picture below:
getFreeTileToSpawnEvent(0, 0, 2, chestId)

You can save it as a plugin(recommended) and use a script call to invoke the function.
See if it will work, I believe I made all the necessary checks (Or not? ^^'')
JavaScript:
function getFreeTileToSpawnEvent(px, py, range, eventId) {
if(eventId){
px = $gameMap.event(eventId).x
py = $gameMap.event(eventId).y
}
const startX = Math.max(px - range, 0)
const startY = Math.max(py - range, 0)
const endX = Math.min(px + range, $dataMap.width-1)
const endY = Math.min(py + range, $dataMap.height-1)
const shuffle = function (array) {
let elementsLeft = array.length;
let currentElement;
let randomIndex;
while (elementsLeft) {
randomIndex = Math.floor(Math.random() * elementsLeft--);
currentElement = array[elementsLeft];
array[elementsLeft] = array[randomIndex];
array[randomIndex] = currentElement;
}
return array;
}
let coords = []
for(let x = startX; x <= endX; x++){
for(let y = startY; y <= endY; y++){
coords.push([x, y])
}
}
coords = shuffle(coords)
for(let i = 0; i < coords.length; i++){
const [x, y] = coords[i]
console.log(x, y)
// Check if has a event here
if($gameMap.eventsXyNt(x, y).length > 0) continue
// Check if the player is here
if($gamePlayer.pos(x, y)) continue
// Check if this tile is passable
if(!$gameMap.isPassable(x, y)) continue
// Check if has a vehicle here
if($gameMap.vehicles().some(vehicle => vehicle.pos(x, y))) continue
// If all above is false, you can spawn your event in this coordinate.
// Replace with the function that you use to spawn the event. Then break the loop
console.log('can spawn here!')
break
}
}
[EDIT] Seeing the post of the
@ImaginaryVillain , it seems that I forgot the
random nearby detail...
I Will see what I can do about it to implement in this function xD
[EDIT 2] - Ok, I fixed it! It is disorganized, but it is working xD. Maybe there is a space for improvement too, but I didn't go this far.
Put that code in a .js file and put it into your plugin manager.
Then all you have to do is use the script call:
getFreeTileToSpawnEvent(0, 0, 2, chestId)
Don't forget to replace the "console.log('can spawn here!')" With the function, you use to spawn your events.