Upgraded the way the workers work.

This commit is contained in:
2026-07-08 22:29:02 +02:00
parent 078c824c47
commit 09de8b5b4b
14 changed files with 275 additions and 224 deletions

View File

@@ -15,7 +15,7 @@ namespace DouwcoHivemind {
class CreepBase { class CreepBase {
public: public:
CreepRole role; CreepRole role;
std::string target_id; std::string targetId;
protected: protected:
Screeps::Creep creep; Screeps::Creep creep;

View File

@@ -9,7 +9,8 @@ namespace DouwcoHivemind
class Miner : public CreepBase class Miner : public CreepBase
{ {
private: private:
bool arrivedAtContainer; std::string sourceId;
bool arrived;
public: public:
Miner(Screeps::Creep crp); Miner(Screeps::Creep crp);

View File

@@ -3,20 +3,18 @@
#include "Creeps/Worker.hpp" #include "Creeps/Worker.hpp"
namespace DouwcoHivemind namespace DouwcoHivemind {
{ class Supplier : public Worker {
class Supplier : public Worker public:
{ Supplier(Screeps::Creep creep) : Worker(creep) { ignoreStorage = true; }
public:
Supplier(Screeps::Creep creep) : Worker(creep) {}
protected: protected:
void depositEnergy() override; void depositEnergy() override;
private: private:
std::unique_ptr<Screeps::Structure> getEnergyStructureTarget(); std::unique_ptr<Screeps::Structure> getEnergyStructureTarget();
void searchEnergyStructure(); void searchEnergyStructure();
}; };
} } // namespace DouwcoHivemind
#endif // DOUWCO_HIVEMIND_SUPPLIER_HPP #endif // DOUWCO_HIVEMIND_SUPPLIER_HPP

View File

@@ -4,32 +4,28 @@
#include "Creeps/CreepBase.hpp" #include "Creeps/CreepBase.hpp"
#include "Screeps/StructureContainer.hpp" #include "Screeps/StructureContainer.hpp"
namespace DouwcoHivemind namespace DouwcoHivemind {
{ class Worker : public CreepBase {
class Worker : public CreepBase protected:
{ bool ignoreStorage = false;
private:
bool harvesting;
bool foundContainer;
public: private:
bool harvesting;
public:
Worker(Screeps::Creep crp); Worker(Screeps::Creep crp);
~Worker() override; ~Worker() override;
void loop() override; void loop() override;
protected: protected:
virtual void depositEnergy(){} virtual void depositEnergy() {}
private: private:
void getEnergy(); void getEnergy();
void harvestSource(); void searchEnergySource();
void collectEnergyFromContainers(); void extractEnergyFromTarget();
std::unique_ptr<Screeps::Source> getSourceTarget(); };
std::unique_ptr<Screeps::StructureContainer> getContainerTarget(); } // namespace DouwcoHivemind
void searchSource();
void searchContainer();
};
}
#endif // DOUWCO_HIVEMIND_HARVESTER_HPP #endif // DOUWCO_HIVEMIND_HARVESTER_HPP

View File

@@ -10,6 +10,7 @@ class Room {
protected: protected:
Screeps::Room room; Screeps::Room room;
JSON memory; JSON memory;
std::vector<std::string> sources = {};
std::vector<std::string> sourceContainers = {}; std::vector<std::string> sourceContainers = {};
public: public:

View File

@@ -77,7 +77,7 @@ void DouwcoHivemind::Builder::searchConstructionSite()
} }
if (selectedConstructionSite) if (selectedConstructionSite)
target_id = selectedConstructionSite->id(); targetId = selectedConstructionSite->id();
else else
target_id.clear(); targetId.clear();
} }

View File

@@ -16,14 +16,14 @@ DouwcoHivemind::CreepBase::CreepBase(Screeps::Creep crp)
: creep(crp), memory(crp.memory()) { : creep(crp), memory(crp.memory()) {
role = memory.contains("role") ? static_cast<CreepRole>(memory["role"]) role = memory.contains("role") ? static_cast<CreepRole>(memory["role"])
: CreepRole::UNEMPLOYED; : CreepRole::UNEMPLOYED;
target_id = memory.contains("target_id") targetId = memory.contains("targetId")
? static_cast<std::string>(memory["target_id"]) ? static_cast<std::string>(memory["targetId"])
: std::string(); : std::string();
} }
DouwcoHivemind::CreepBase::~CreepBase() { DouwcoHivemind::CreepBase::~CreepBase() {
memory["role"] = role; memory["role"] = role;
memory["target_id"] = target_id; memory["targetId"] = targetId;
creep.setMemory(memory); creep.setMemory(memory);
} }
@@ -127,13 +127,13 @@ void DouwcoHivemind::CreepBase::moveToTarget(int dist) {
std::unique_ptr<Screeps::RoomObject> std::unique_ptr<Screeps::RoomObject>
DouwcoHivemind::CreepBase::getRoomObjectTarget() { DouwcoHivemind::CreepBase::getRoomObjectTarget() {
// Check if any target is present // Check if any target is present
if (target_id.empty()) if (targetId.empty())
return nullptr; return nullptr;
// Check if game can find target // Check if game can find target
auto roomObj = Screeps::Game.getObjectById(target_id); auto roomObj = Screeps::Game.getObjectById(targetId);
if (!roomObj) { if (!roomObj) {
JS::console.log(creep.name() + JS::console.log(creep.name() + ": Game can\'t find target id: " + targetId);
": Game can\'t find target id: " + target_id); targetId.clear();
return nullptr; return nullptr;
} }
return std::move(roomObj); return std::move(roomObj);

View File

@@ -85,7 +85,7 @@ void DouwcoHivemind::Maintainer::searchDamagedStructure()
} }
if (selectedStructure && selectedStructure->hits() != selectedStructure->hitsMax()) if (selectedStructure && selectedStructure->hits() != selectedStructure->hitsMax())
target_id = selectedStructure->id(); targetId = selectedStructure->id();
else else
target_id.clear(); targetId.clear();
} }

View File

@@ -2,39 +2,63 @@
#include "Creeps/CreepBase.hpp" #include "Creeps/CreepBase.hpp"
#include "Screeps/Constants.hpp" #include "Screeps/Constants.hpp"
#include "Screeps/Creep.hpp" #include "Screeps/Creep.hpp"
#include "Screeps/Game.hpp"
#include "Screeps/Room.hpp" #include "Screeps/Room.hpp"
#include "Screeps/RoomPosition.hpp" #include "Screeps/RoomPosition.hpp"
#include "Screeps/Source.hpp" #include "Screeps/Source.hpp"
#include "Screeps/Structure.hpp"
#include <string> #include <string>
DouwcoHivemind::Miner::Miner(Screeps::Creep crp) : CreepBase(crp) { DouwcoHivemind::Miner::Miner(Screeps::Creep crp) : CreepBase(crp) {
arrivedAtContainer = memory.contains("arrivedAtContainer") sourceId = memory.contains("sourceId")
? static_cast<bool>(memory["arrivedAtContainer"]) ? static_cast<std::string>(memory["sourceId"])
: false; : "";
arrived =
memory.contains("arrived") ? static_cast<bool>(memory["arrived"]) : false;
} }
DouwcoHivemind::Miner::~Miner() { DouwcoHivemind::Miner::~Miner() {
memory["arrivedAtContainer"] = arrivedAtContainer; memory["sourceId"] = sourceId;
memory["arrived"] = arrived;
} }
void DouwcoHivemind::Miner::loop() { void DouwcoHivemind::Miner::loop() {
if (arrivedAtContainer) { // Find assigned source
auto source = auto source = static_cast<Screeps::Source *>(
static_cast<Screeps::Source *>(getRoomObjectTarget().release()); Screeps::Game.getObjectById(sourceId).release());
creep.harvest(*source); if (!source)
} else {
auto container = getRoomObjectTarget();
if (!container)
return; return;
if (isNearTo(container->pos(), 0)) { // If arrived just harvest the source
arrivedAtContainer = true; if (arrived) {
int x = creep.pos().x(); creep.harvest(*source);
int y = creep.pos().y(); }
auto roomObjs = creep.pos().findClosestByRange(Screeps::FIND_SOURCES, 2); // Otherwise move towards the source or a container near it
auto source = static_cast<Screeps::Source *>(roomObjs.release()); else {
target_id = source->id(); auto target = getRoomObjectTarget();
// If target is set move to it or detect if you arrive
if (target) {
bool targetIsSource = target->pos().isEqualTo(source->pos());
int closenessToTarget = targetIsSource ? 1 : 0;
if (isNearTo(target->pos(), closenessToTarget)) {
arrived = true;
} else { } else {
moveToTarget(0); moveToTarget(closenessToTarget);
}
}
// if no target look if there are containers near the source otherwise go to source directly.
else {
auto structureRoomObjs =
source->pos().findInRange(Screeps::FIND_STRUCTURES, 2);
for (auto &structureRoomObj : structureRoomObjs) {
auto structure =
static_cast<Screeps::Structure *>(structureRoomObj.get());
if (Screeps::STRUCTURE_CONTAINER == structure->structureType()) {
targetId = structure->id();
break;
}
}
if (targetId.empty())
targetId = sourceId;
} }
} }
} }

View File

@@ -116,7 +116,7 @@ void DouwcoHivemind::Supplier::searchEnergyStructure() {
selectedStructureId = storageStructureId; selectedStructureId = storageStructureId;
if (selectedStructureId.empty()) if (selectedStructureId.empty())
target_id.clear(); targetId.clear();
else else
target_id = selectedStructureId; targetId = selectedStructureId;
} }

View File

@@ -21,7 +21,7 @@
void DouwcoHivemind::Upgrader::depositEnergy() void DouwcoHivemind::Upgrader::depositEnergy()
{ {
auto controller = creep.room().controller().value(); auto controller = creep.room().controller().value();
target_id = controller.id(); targetId = controller.id();
if (isNearTo(controller.pos(), 3)) if (isNearTo(controller.pos(), 3))
{ {
int resp = creep.upgradeController(controller); int resp = creep.upgradeController(controller);

View File

@@ -1,4 +1,5 @@
#include <emscripten.h> #include <emscripten.h>
#include <iterator>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -17,159 +18,179 @@
#include <Screeps/StructureSpawn.hpp> #include <Screeps/StructureSpawn.hpp>
#include <Screeps/StructureTower.hpp> #include <Screeps/StructureTower.hpp>
#include "Constants.hpp"
#include "Creeps/Worker.hpp" #include "Creeps/Worker.hpp"
#include "Screeps/Resource.hpp"
#include "Screeps/Ruin.hpp"
#include "Screeps/StructureContainer.hpp" #include "Screeps/StructureContainer.hpp"
#include "Screeps/StructureStorage.hpp"
#include "Screeps/Tombstone.hpp"
DouwcoHivemind::Worker::Worker(Screeps::Creep crp) : CreepBase(crp) { DouwcoHivemind::Worker::Worker(Screeps::Creep crp) : CreepBase(crp) {
harvesting = memory.contains("harvesting") harvesting = memory.contains("harvesting")
? static_cast<bool>(memory["harvesting"]) ? static_cast<bool>(memory["harvesting"])
: false; : false;
foundContainer = memory.contains("foundContainer")
? static_cast<bool>(memory["foundContainer"])
: false;
} }
DouwcoHivemind::Worker::~Worker() { DouwcoHivemind::Worker::~Worker() { memory["harvesting"] = harvesting; }
memory["harvesting"] = harvesting;
memory["foundContainer"] = foundContainer;
}
void DouwcoHivemind::Worker::loop() { void DouwcoHivemind::Worker::loop() {
if (harvesting) { if (harvesting) {
JS::console.log(std::string("worker: harvesting"));
if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0) { if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0) {
JS::console.log(std::string("worker: harvesting full"));
harvesting = false; harvesting = false;
target_id.clear(); targetId.clear();
} } else {
getEnergy(); getEnergy();
}
} else { } else {
if (creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0) { if (creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0) {
harvesting = true; harvesting = true;
target_id.clear(); targetId.clear();
} } else {
depositEnergy(); depositEnergy();
} }
}
} }
void DouwcoHivemind::Worker::getEnergy() { void DouwcoHivemind::Worker::getEnergy() {
if (foundContainer || Screeps::Game.time()%100==0) collectEnergyFromContainers(); JS::console.log(std::string("worker: get energy"));
else harvestSource(); if (targetId.empty()) {
} JS::console.log(std::string("worker: No target search energy"));
searchEnergySource();
void DouwcoHivemind::Worker::collectEnergyFromContainers() {
auto container = getContainerTarget();
if (!container)
return;
if (isNearTo(container->pos(), 1)) {
int resp = creep.withdraw(*container, Screeps::RESOURCE_ENERGY);
} else { } else {
moveToTarget(); JS::console.log(std::string("worker: has target with energy"));
} auto target = getRoomObjectTarget();
} if (!target)
void DouwcoHivemind::Worker::harvestSource() {
auto source = getSourceTarget();
if (!source)
return; return;
if (isNearTo(target->pos(), 1)) {
if (isNearTo(source->pos(), 1)) { JS::console.log(std::string("worker: collect energy"));
int resp = creep.harvest(*source); extractEnergyFromTarget();
} else { } else {
moveToTarget(); JS::console.log(std::string("worker: go to energy"));
moveToTarget(1);
}
} }
} }
std::unique_ptr<Screeps::StructureContainer> void DouwcoHivemind::Worker::searchEnergySource() {
DouwcoHivemind::Worker::getContainerTarget() { // Search for storage and containers
auto roomObj = getRoomObjectTarget(); std::string containerID = std::string();
if (!roomObj) {
searchContainer();
return nullptr;
}
// Check if found roomobject is an actual source
auto container = std::unique_ptr<Screeps::StructureContainer>(
dynamic_cast<Screeps::StructureContainer *>(roomObj.release()));
if (!container) {
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')},
// creep.name().c_str());
searchContainer();
return nullptr;
}
// Check if the source still has energy to harvest
if (container->store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0) {
searchContainer();
return nullptr;
}
return std::move(container);
}
std::unique_ptr<Screeps::Source> DouwcoHivemind::Worker::getSourceTarget() {
auto roomObj = getRoomObjectTarget();
if (!roomObj) {
searchSource();
return nullptr;
}
// Check if found roomobject is an actual source
auto source = std::unique_ptr<Screeps::Source>(
dynamic_cast<Screeps::Source *>(roomObj.release()));
if (!source) {
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')},
// creep.name().c_str());
searchSource();
return nullptr;
}
// Check if the source still has energy to harvest
if (source->energy() == 0) {
searchSource();
return nullptr;
}
return std::move(source);
}
void DouwcoHivemind::Worker::searchSource() {
target_id.clear();
auto sourceObject = creep.pos().findClosestByRange(Screeps::FIND_SOURCES);
if (!sourceObject)
return;
auto source = dynamic_cast<Screeps::Source *>(sourceObject.release());
target_id = source->id();
}
void DouwcoHivemind::Worker::searchContainer() {
target_id.clear();
auto structureObjects = creep.room().find(Screeps::FIND_STRUCTURES); auto structureObjects = creep.room().find(Screeps::FIND_STRUCTURES);
if (structureObjects.size() == 0) if (structureObjects.size() > 0) {
return;
int fullestContents = 0; int fullestContents = 0;
Screeps::StructureContainer *selectedContainer;
for (auto &structureObject : structureObjects) { for (auto &structureObject : structureObjects) {
auto structure = auto structure = static_cast<Screeps::Structure *>(structureObject.get());
dynamic_cast<Screeps::Structure *>(structureObject.release()); auto structureType = structure->structureType();
if (structure->structureType() != Screeps::STRUCTURE_CONTAINER) if (structureType == Screeps::STRUCTURE_STORAGE) {
if (ignoreStorage)
continue; continue;
auto container = dynamic_cast<Screeps::StructureContainer *>(structure); targetId = structure->id();
int availableEnergy = return;
container->store().getUsedCapacity(Screeps::RESOURCE_ENERGY).value(); } else if (structureType == Screeps::STRUCTURE_CONTAINER) {
auto container = static_cast<Screeps::StructureContainer *>(structure);
int availableEnergy = container->store()
.getUsedCapacity(Screeps::RESOURCE_ENERGY)
.value_or(0);
if (availableEnergy == 0) if (availableEnergy == 0)
continue; continue;
if (fullestContents < availableEnergy) { if (fullestContents < availableEnergy) {
fullestContents = availableEnergy; fullestContents = availableEnergy;
selectedContainer = container; containerID = container->id();
}
}
} }
} }
if (!selectedContainer) { // Search for loose resources
foundContainer = false; auto resourceObjects = creep.room().find(Screeps::FIND_DROPPED_RESOURCES);
} else { if (resourceObjects.size() > 0) {
foundContainer = true; int highestAmount = 0;
target_id = selectedContainer->id(); std::string resourceID = std::string();
for (auto &resourceObject : resourceObjects) {
auto resource = static_cast<Screeps::Resource *>(resourceObject.get());
if (resource->resourceType() != Screeps::RESOURCE_ENERGY)
continue;
int amount = resource->amount();
if (amount < 100)
continue;
if (amount > highestAmount) {
highestAmount = amount;
resourceID = resource->id();
} }
}
if (!resourceID.empty()) {
targetId = resourceID;
return;
}
}
// Search for existing ruins
auto ruinObjects = creep.room().find(Screeps::FIND_RUINS);
if (ruinObjects.size() > 0) {
int highestAmount = 0;
std::string ruinID = std::string();
for (auto &ruinObject : ruinObjects) {
auto ruin = static_cast<Screeps::Ruin *>(ruinObject.get());
if (ruin->ticksToDecay() < 100)
continue;
int amount =
ruin->store().getUsedCapacity(Screeps::RESOURCE_ENERGY).value_or(0);
if (amount > highestAmount) {
highestAmount = amount;
ruinID = ruin->id();
}
}
if (!ruinID.empty()) {
targetId = ruinID;
return;
}
}
// Search for existing tombstones
auto tombstoneObjects = creep.room().find(Screeps::FIND_TOMBSTONES);
if (tombstoneObjects.size() > 0) {
int highestAmount = 0;
std::string TombstoneID = std::string();
for (auto &tombstoneObject : tombstoneObjects) {
auto tombstone = static_cast<Screeps::Tombstone *>(tombstoneObject.get());
if (tombstone->ticksToDecay() < 100)
continue;
int amount = tombstone->store()
.getUsedCapacity(Screeps::RESOURCE_ENERGY)
.value_or(0);
if (amount > highestAmount) {
highestAmount = amount;
TombstoneID = tombstone->id();
}
}
if (!TombstoneID.empty()) {
targetId = TombstoneID;
return;
}
}
// If still nothing found take the earlier found container.
if (!containerID.empty()) {
targetId = containerID;
}
// If still nothing found, there is no target and search should start again.
targetId = std::string();
}
void DouwcoHivemind::Worker::extractEnergyFromTarget() {
auto roomObj = getRoomObjectTarget();
if (!roomObj) {
targetId.clear();
return;
}
auto resource = dynamic_cast<Screeps::Resource *>(roomObj.get());
if (resource)
creep.pickup(*resource);
else
creep.withdraw(*roomObj.get(), Screeps::RESOURCE_ENERGY);
targetId.clear();
} }

View File

@@ -6,42 +6,50 @@
#include "Screeps/RoomObject.hpp" #include "Screeps/RoomObject.hpp"
#include "Screeps/RoomPosition.hpp" #include "Screeps/RoomPosition.hpp"
#include "Screeps/RoomTerrain.hpp" #include "Screeps/RoomTerrain.hpp"
#include "Screeps/Source.hpp"
#include "Screeps/Structure.hpp" #include "Screeps/Structure.hpp"
#include "Screeps/StructureContainer.hpp" #include "Screeps/StructureContainer.hpp"
#include "Screeps/StructureController.hpp" #include "Screeps/StructureController.hpp"
#include "Constants.hpp" #include "Constants.hpp"
#include <cstdint>
DouwcoHivemind::Room::Room(Screeps::Room rm) : room(rm), memory(rm.memory()) { DouwcoHivemind::Room::Room(Screeps::Room rm) : room(rm), memory(rm.memory()) {
if (memory.contains("sources"))
sources = static_cast<std::vector<std::string>>(memory["sources"]);
if (memory.contains("sourceContainers")) if (memory.contains("sourceContainers"))
sourceContainers = sourceContainers =
static_cast<std::vector<std::string>>(memory["sourceContainers"]); static_cast<std::vector<std::string>>(memory["sourceContainers"]);
} }
DouwcoHivemind::Room::~Room() { DouwcoHivemind::Room::~Room() {
memory["sources"] = sources;
memory["sourceContainers"] = sourceContainers; memory["sourceContainers"] = sourceContainers;
room.setMemory(memory); room.setMemory(memory);
} }
void DouwcoHivemind::Room::loop() { void DouwcoHivemind::Room::loop() {
// Check on building setup if (sources.size() == 0) {
if(Screeps::Game.time()%1000!=0) return; auto sources_ = room.find(Screeps::FIND_SOURCES);
for (auto &source : sources_) {
sources.push_back(static_cast<Screeps::Source *>(source.get())->id());
}
}
placeContainers(); placeContainers();
} }
void DouwcoHivemind::Room::placeContainers() { void DouwcoHivemind::Room::placeContainers() {
auto sources = room.find(Screeps::FIND_SOURCES);
// No containers planned or build, planning now // No containers planned or build, planning now
if (sourceContainers.size() < sources.size()) { if (sourceContainers.size() < sources.size()) {
int controller_x = room.controller().value().pos().x(); int controller_x = room.controller().value().pos().x();
int controller_y = room.controller().value().pos().y(); int controller_y = room.controller().value().pos().y();
for (auto &source : sources) { for (auto sourceId : sources) {
int source_x = source->pos().x(); auto roomObj = Screeps::Game.getObjectById(sourceId);
int source_y = source->pos().y(); int source_x = roomObj->pos().x();
int source_y = roomObj->pos().y();
int lowest_cost = 1000; int lowest_cost = INT16_MAX;
int best_x; int best_x;
int best_y; int best_y;
for (int dx = -1; dx < 2; dx++) { for (int dx = -1; dx < 2; dx++) {
@@ -82,8 +90,9 @@ void DouwcoHivemind::Room::placeContainers() {
return; return;
} }
// Check if containers still exist // Check if containers still exist
for(int i = 0; i < sourceContainers.size(); i++){ for (int i = 0; i < sourceContainers.size(); i++) {
auto roomObj = Screeps::Game.getObjectById(sourceContainers[i]); auto roomObj = Screeps::Game.getObjectById(sourceContainers[i]);
if(!roomObj) sourceContainers.erase(sourceContainers.begin() + i); if (!roomObj)
sourceContainers.erase(sourceContainers.begin() + i);
} }
} }

View File

@@ -1,5 +1,6 @@
#include <Screeps/Game.hpp> #include <Screeps/Game.hpp>
#include <Screeps/Room.hpp> #include <Screeps/Room.hpp>
#include <Screeps/StructureController.hpp>
#include "Creeps/CreepBase.hpp" #include "Creeps/CreepBase.hpp"
#include "Structures/Spawn.hpp" #include "Structures/Spawn.hpp"
@@ -16,13 +17,10 @@ void DouwcoHivemind::Spawn::loop() {
// Calculate needed creep roles // Calculate needed creep roles
int required_upgraders = 1; int required_upgraders = 1;
int required_suppliers = 2; int required_suppliers = 2;
int required_maintainers = int required_maintainers = 1;
spawn.room().find(Screeps::FIND_STRUCTURES).size() <= 2 ? 0 : 1;
;
int required_builders = int required_builders =
spawn.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() == 0 ? 0 spawn.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() > 0 ? 1 : 0;
: 1; int required_miners = 1; // spawn.room().memory()["sources"].size();
int required_miners = 1; // spawn.room().memory()["sourceContainers"].size();
// Count existing roles // Count existing roles
int existing_upgraders = 0; int existing_upgraders = 0;
@@ -56,8 +54,8 @@ void DouwcoHivemind::Spawn::loop() {
CreepRole role = CreepRole::UNEMPLOYED; CreepRole role = CreepRole::UNEMPLOYED;
if (required_miners > existing_miners) { if (required_miners > existing_miners) {
role = CreepRole::MINER; role = CreepRole::MINER;
opts["memory"]["target_id"] = opts["memory"]["sourceId"] =
spawn.room().memory()["sourceContainers"][0]; // make logic for more spawn.room().memory()["sources"][0]; // make logic for more
name = "Miner: "; name = "Miner: ";
} else if (required_suppliers > existing_suppliers) { } else if (required_suppliers > existing_suppliers) {
role = CreepRole::SUPPLIER; role = CreepRole::SUPPLIER;
@@ -78,21 +76,24 @@ void DouwcoHivemind::Spawn::loop() {
// Build creep body // Build creep body
std::vector<std::string> body; std::vector<std::string> body;
// Miner body with up to 5 work (10 en/s) bits for 3000 source mining in 300
// tick regen.
if (role == CreepRole::MINER) { if (role == CreepRole::MINER) {
body.push_back("move"); body.push_back("move");
body.push_back("work"); body.push_back("work");
for (int i = 0; i < (energyAvailable - 150) / 100 && i < 5; i++) { for (int i = 0; i < (energyAvailable - 150) / 100 && i < 5; i++) {
body.push_back("work"); body.push_back("work");
} }
} else if (role == SUPPLIER) { }
body.push_back("move"); // Supplier body with only move and carry to move energy around
body.push_back("work"); else if (role == SUPPLIER) {
body.push_back("carry"); for (int i = 0; i < energyAvailable / 100; i++) {
for (int i = 0; i < (energyAvailable - 200) / 100 && i * 50 < energyCapacityAvailable; i++) {
body.push_back("move"); body.push_back("move");
body.push_back("carry"); body.push_back("carry");
} }
} else { }
// Worker body with balanced parts.
else {
for (int i = 0; i < energyAvailable / 200; i++) { for (int i = 0; i < energyAvailable / 200; i++) {
body.push_back("work"); body.push_back("work");
body.push_back("carry"); body.push_back("carry");