Screeps - 如何从多个容器中撤出,同时从多个来源中挖掘?

时间:2017-05-27 17:32:22

标签: screeps

我的矿工代码:

var roleMiner = {
run: function(creep) {
    if(creep.carry.energy < creep.carryCapacity) {
        var sources = creep.room.find(FIND_SOURCES_ACTIVE);
        if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
            creep.moveTo(sources[0], {visualizePathStyle: {stroke: '#ffaa00'}});

        }
    } else {
       var containers = creep.room.find(FIND_STRUCTURES, {filter: (s) => (s.structureType == STRUCTURE_CONTAINER && s.store.energy< s.storeCapacity)}); 
        if(containers != undefined){
            creep.moveTo(containers[0]);
            creep.transfer(containers[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE

             }
        }
    }
 };

 module.exports = roleMiner;

和我的转运代码:

var roleTransporter = {

run: function(creep) {
    if(creep.carry.energy == 0) {
        var containers = creep.room.find(FIND_STRUCTURES, {filter: (s) => (s.structureType == STRUCTURE_CONTAINER && s.store.energy <= s.storeCapacity)}); 
        if (creep.withdraw(containers[1], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
            creep.moveTo(containers, {visualizePathStyle: {stroke: '#ffaa00'}});
    }
} else {
        var targets = creep.room.find(FIND_STRUCTURES, {
                filter: (structure) => {
                    return (structure.structureType == STRUCTURE_EXTENSION ||
                            structure.structureType == STRUCTURE_SPAWN ||
                            structure.structureType == STRUCTURE_TOWER) && structure.energy < structure.energyCapacity;
                }
        });
        if(targets.length > 0) {
            if(creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                creep.moveTo(targets[0], {visualizePathStyle: {stroke: '#ffffff'}});
            }
        }
    }
 }
 };
 module.exports = roleTransporter;

关键是,我有容器[0]或源[0],数字是容器或源对象。

我怎样才能让矿工一次收获多个来源,因为我有2个来源,而且运输商可以同时从多个容器中撤出。

3 个答案:

答案 0 :(得分:2)

creep只能执行每个tick的相同类型的一个动作。如果您的creep执行两次撤销,则服务器将仅评估最后一次调用。它在技术上与移动相同。每次打勾只能移动一次,这只是移动到服务器的最后一次调用。

当您的代码调用withdraw并且方法返回OK时,并不意味着该操作已执行。这意味着该操作已成功注册为“意图”。蠕变只能为每个动作注册一个意图。当代码完成执行后,这些意图将发送到服务器进行评估。如果你有一个拥有100个能量和两个小兵的容器试图撤回这个能量,两个小兵都会得到回应,但是当服务器执行你的意图时,实际上只会执行其中一个。

要记住的另一件事是同步执行规则。 creep可以在同一个tick中执行收获和移动,但如果它尝试同时进行构建和修复,则只会执行构建。

有关此内容的更多信息: http://docs.screeps.com/simultaneous-actions.html

答案 1 :(得分:2)

有些人使用所有可用来源的简单随机选择。这很简单,但不是优选的。我所做的是,当蠕变准备好收获时,我使用算法来选择源并将源ID保存到creep的内存中。

我用来选择源的算法考虑了已经定位到该源的其他小兵的数量,到源的距离以及未被阻挡的相邻方块的数量(通过墙壁之类的东西)。

var source;

if (creep.memory.sourceId) {
    source = Game.getObjectById(creep.memory.sourceId);
} else {
    //Find all active sources
    //Count the number of creeps targeting that source
    //Count the accessible adjacent squares using something like room.lookForAt(...)
    //source = ... the source you selected
}

if (creep.harvest(source) == ERR_NOT_IN_RANGE) {
        creep.moveTo(source, {visualizePathStyle: {stroke: '#ffaa00'}});
}

也可以为运输商做类似的事情。

答案 2 :(得分:0)

我认为根本不可能。虽然不是specifically stated,但我认为它与transfer的情况相同:

  

虽然transfer可能会work同时掉落,但每次打勾都不能执行transfer两次或多次(将能量转移到多个对象)。所有类似的方法都是如此。