laverdet / xxscreeps

Other
71 stars 16 forks source link

[Bug] Creep.moveTo treats tiles with roads under unpathable objects as pathable #29

Closed NesCafe62 closed 3 years ago

NesCafe62 commented 3 years ago

According to this line https://github.com/laverdet/xxscreeps/blob/a7cb6ef183e85f577050d3db6201378389dd8954/src/game/path-finder/index.ts#L81 it can be possible that unpathable tile with higher cost (for example 255) will be overwritten by lower cost (for example 1 road)

if (cost !== undefined && cost < costMatrix.get(x, y)) {
    costMatrix.set(x, y, cost);
}
NesCafe62 commented 3 years ago

this is what I use for my custom pathing module

const terrain = TerrainCache.get(room.name);
room.find(FIND_STRUCTURES).forEach( structure => {
    const {x, y} = structure.pos;
    if (structure.structureType === STRUCTURE_ROAD) {
        const cell = terrain.get(x, y);
        if (!ignoreTunnels && (cell & TERRAIN_MASK_WALL)) {
            matrix.set(x, y, 1);
        } else if (
            (
                !ignoreRoads ||
                (swampRoads && (cell & TERRAIN_MASK_SWAMP))
            ) && matrix.get(x, y) === 0
        ) {
            matrix.set(x, y, roadCost);
        }
    } else if (structure.structureType === STRUCTURE_CONTAINER) {
        if (!ignoreContainers) {
            matrix.set(x, y, containerCost);
        }
    } else if (
        !ignoreStructures && (
            structure.structureType !== STRUCTURE_RAMPART ||
            (!structure.my && !structure.isPublic)
        )
    ) {
        matrix.set(x, y, 255);
    }
});
if (!ignoreStructures) {
    room.find(FIND_MY_CONSTRUCTION_SITES).forEach( construction => {
        if (![STRUCTURE_CONTAINER, STRUCTURE_ROAD, STRUCTURE_RAMPART].includes(construction.structureType)) {
            const {x, y} = construction.pos;
            matrix.set(x, y, 255);
        }
    });
}
NesCafe62 commented 3 years ago

oh and constMatrix initially contains all zero values. it has no populated values from Terrain data. so comparing cost < costMatrix.get(x, y) when looking over plain road tile makes it 1 < 0 and this condition not fires for roads

Gadjung commented 3 years ago

regarding the last part - not sure when in implementation it goes, but for 0, it should 1st set value according to terrain at given position, and then try to update it with whatever is constructed on said tile