Closed Kln95130 closed 3 years ago
If you look at lang.exit_list in lang.js (line 748), you will see x and y values are already in there. That should mean you do not need the getMapxAndY()
function. You can access the object in lang.exit_list usinbg the data
attribute of the exit, so if you are in a function that belongs to an exit, you can do this.data.x
to get the x displacement.
With regards to an updating map, that would be cool, and should not be too difficult. It is something Quest 6 needs more generally, and ideally would be integrated with that.
Okay, this seems to work:
for (let exit of this.exits) {
if (typeof exit.isHidden !== 'function' || !exit.isHidden()) {
let newX = exit.x + this[exit.dir].data.x;
let newY = exit.y + this[exit.dir].data.y;
if (x == newX && y == newY) {
return {isLocked: exit.isLocked};
}
}
}
I think I found a way, albeit it relies on the developer positioning the rooms himself, and the rooms being square:
add rooms: []
property to ZONE()
, as an array of generic objects.
Each generic object will have four properties: minX, maxX, minY, maxY
rooms:[
{minX: 0, maxX: 1, minY: 1, maxY: 2}
]
Then, add a function to check if the cell's x and y are within the room's limits. The room could have the option to be hidden (for instance if unexplored.
res.roomColour = "black";
res.getRoomAt=function(x , y) {
for (let room of this.rooms) {
if ((typeof room.isHidden !== 'function' || !room.isHidden()) && x >= room.minX && x <= room.maxX && y >= room.minY && y <=room.maxY) {
return true;
}
}
return false;
}
Then add the control in drawMap:
if (this.getRoomAt(x, y)) {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.roomColour + '"/>')
}
else {
let exit = this.getExitAt(x, y);
if (exit) {
let cellColour = (exit.isLocked) ? this.lockedExitColour : this.openExitColour;
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + cellColour + '"/>');
}
else if (this.getBorderAt(x, y)) {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.outsideColour + '"/>')
}
else {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.insideColour + '"/>')
}
const feature = this.getFeatureAt(x, y)
if (feature) {
const colour = feature.zoneColour || this.featureColour
features.push('<circle cx="' + (x2+this.cellSize/2) + '" cy="' + (y2+this.cellSize/2) + '" r="' + (this.cellSize/2 - 1) + '" stroke="none" fill="' + colour + '"/>')
if (feature.zoneMapName) labels.push('<text x="' + (x2+this.cellSize) + '" y="' + (y2+5) + '" style="font: ' + this.mapFont + '; fill: black;">' + feature.zoneMapName + '</text>')
}
}
You know your code better than me, so you will probably find a more elegant solution. But that should get you started.
I've edited drawMap a little, so that the exit cell gets the exit colour on top of the room's colour.
for (let x = -this.size; x <= this.size; x++) {
for (let y = -this.size; y <= this.size; y++) {
const x2 = (this.size + x) * this.cellSize
const y2 = (this.size - y) * this.cellSize
let exit = this.getExitAt(x, y);
if (exit) {
let cellColour = (exit.isLocked) ? this.lockedExitColour : this.openExitColour;
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + cellColour + '"/>');
}
else if (this.getRoomAt(x, y)) {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.roomColour + '"/>')
}
else if (this.getBorderAt(x, y)) {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.outsideColour + '"/>')
}
else {
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + this.insideColour + '"/>')
}
const feature = this.getFeatureAt(x, y)
if (feature) {
const colour = feature.zoneColour || this.featureColour
features.push('<circle cx="' + (x2+this.cellSize/2) + '" cy="' + (y2+this.cellSize/2) + '" r="' + (this.cellSize/2 - 1) + '" stroke="none" fill="' + colour + '"/>')
if (feature.zoneMapName) labels.push('<text x="' + (x2+this.cellSize) + '" y="' + (y2+5) + '" style="font: ' + this.mapFont + '; fill: black;">' + feature.zoneMapName + '</text>')
}
}
Coming for one last dev proposition (for the moment ;)):
Label your exits with a letter, to help the player. This could tie in, in the future, with the addition of a legend to the map.
exits:[
{x:0, y:0, dir:'north', dest:'playerCabin', msg:'You enter your cabin.', letter: 'E'},
{x:-1, y:0, dir:'south', dest:'captainCabin', msg:"You enter the captain's cabin.", isLocked: true, lockedmsg: "The captain has locked her door. You will need her permission to enter.", letter: 'D'},
{x:-3, y:0, dir:'north', dest:'briefingRoom', msg:'You enter the briefing room.', letter: 'B'},
{x:-3, y:0, dir:'west', dest:'commandRoom', msg:'You enter the command room.', letter: 'A'},
{x:-3, y:0, dir:'south', dest:'shipAirlock', msg:'You enter the airlock.', isLocked: true, lockedmsg: "The airlock is locked during space travel, for obvious safety reasons.", letter: 'C'},
{x:2, y:0, dir:"south", dest: "shipElevator", msg: "You call the ship's elevator, then step inside.", letter: 'G'},
{x:2, y:1, dir: "down", dest: "jollyRiderMidBridge", msg: "You hop into the hole. The magtube makes you glide down gently one floor below.", letter: 'F'}
],
es.getExitAt = function(x, y) {
for (let exit of this.exits) {
//We do the condition here so that we spare the calculation if we do not need to do it
if (typeof exit.isHidden !== 'function' || !exit.isHidden()) {
//let cell = this.getMapXAndY(exit);
let newX = exit.x + this[exit.dir].data.x;
let newY = exit.y + this[exit.dir].data.y;
if (x == newX && y == newY) {
return {letter: exit.letter, isLocked: exit.isLocked};
}
}
}
return false
}
let exit = this.getExitAt(x, y);
if (exit) {
let cellColour = (exit.isLocked) ? this.lockedExitColour : this.openExitColour;
cells.push('<g>');
cells.push('<rect x="' + x2 + '" y="' + y2 + '" width="' + this.cellSize + '" height="' + this.cellSize + '" stroke="none" fill="' + cellColour + '"/>');
if (exit.letter) {
cells.push('<text x="' + (x2 + this.cellSize / 5) + '" y="' + (y2 + this.cellSize * (3/4)) + '" style="font: ' + this.mapFont + '" fill="black">' + exit.letter + '</text>');
}
cells.push('</g>');
}
It looks like you are colouring a cell that has an exit going into it, green if unlocked, red if locked. I am concerned that will not work in some situations. For example, where there are two routes to a room, the player can reach either side of an exit; how does it know which side to colour red/green?
Maybe that is not an issue for you, but I would have to consider a more general solution. My feeling is that a better way would be a smaller box over the join, and colour that.
I did not think of that. As I said in an earlier message, you must have a better vision of things.
My main goal while experimenting was: "when the player uses the map, they must know where their intended destination as quickly as possible". Hence why I sought to add a simple colour code and labels.
Using another criterium, like if the room was visited, might be better if your game has room with exits in different states of locking. Alternatively, you could change exit_list's x and y, so that the mapper could draw a line pointing in the direction, then the exit square in the next cell, and the line itself would be coloured.
"Using another criterium, like if the room was visited, might be better if your game has room with exits in different states of locking."
Yes, doors locked from one side only will be a problem...
Maps have now been fully implemented so I think this has now been done.
Edit: I added the code to take into account the fact that an exit is locked.
So, after getting my hands into the zone library, I have one proposition for the map feature, which is to allow the developer to mark the exits on the map in a simple manner.
First, we will use two properties to the exits of a zone, mapX and mapY. They represent the position of the exit on the map. They will be calculated by a function that I call getMapxAndY().
Second, we add three elements we will make use of: a variable for the exit colour, a function to check if the cell is qualified as an "exit cell", and an edit to drawMap() to check for valid exits before borders. To the occasion, we could add a "hidden" property so that the exit is not drawn on the map.
In a next update, this could lead to allow the player to draw simple (as in quadrilateral) rooms on the map using the coordinates of each angle.
I will keep on experimenting. If I make any substantial progress, I will update this ticket.
Finally, I think it could be a useful option to have a setting, that would run
w[game.player.loc].drawMap();
each time the player starts the turn in a zone, instead of using a turn script. That, or have a permanent map display in the page whenever the player is in a zone.