Closed thehatb0y closed 6 years ago
Hi @azshalasa Try to pass a pointer to a geiser unit instead of a 3d point.
Tx for reply @alkurbatov ! i'm not sure if i understood what to do... You mean a pointer to Point3D ?
Even functions like that are not working properly
const Unit* FindNearestVespenelPatch(const Point3D& start) { Units units = Observation()->GetUnits(Unit::Alliance::Neutral); float distance = std::numeric_limits<float>::max(); const Unit* target = nullptr; for (const auto& u : units) { if (u->unit_type == UNIT_TYPEID::NEUTRAL_VESPENEGEYSER) { std::cout << u->pos.x << std::endl; std::cout << u->pos.y << std::endl; float d = DistanceSquared3D(u->pos, start); if (d < distance) { distance = d; target = u; } } } return target; } const Unit* FindNearestCC(const Point2D& start) { Units units = Observation()->GetUnits(Unit::Alliance::Neutral); float distance = std::numeric_limits<float>::max(); const Unit* target = nullptr; for (const auto& u : units) { if (u->unit_type == UNIT_TYPEID::TERRAN_COMMANDCENTER) { float d = DistanceSquared2D(u->pos, start); if (d < distance) { distance = d; target = u; } } } return target; }
With the functions above(FindNearest stuff), SCV are acting like crazy, looking for far mining places and wrong gaiser... So FindNearest Stuff are not working and neither my specific functions wich tells exact where to build.
I've got a similar function to build Depos wich are working 100%
if (CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) > 1) { if (CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) > 1 && CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) <= 8) { Point3D Location; Location.x = (float)138.0 + (float)(CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) * 2); Location.y = 32.0; Location.z = 12; return Location; } if (CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) > 8 && CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) <= 14) { Point3D Location; Location.x = (float)124.0 + (float)(CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) * 2); Location.y = 30.0; Location.z = 12; return Location; } if (CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) > 14 && CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) <= 16) { Point3D Location; Location.x = (float)112.0 + (float)(CountUnitType(UNIT_TYPEID::TERRAN_SUPPLYDEPOT) * 2); Location.y = 28.0; Location.z = 12; return Location; } }
Take a look at examples from the API's sources (bool TerranMultiplayerBot::BuildRefinery() ): https://github.com/Blizzard/s2client-api/blob/master/examples/common/bot_examples.cc
Usually, you should find the nearest mineral or vesper geyser (these are neutral units on the map), use the unit found as a target for the 'build' command instead of a point.
Another example: https://github.com/alkurbatov/suvorov-bot/blob/master/src/blueprints/Refinery.cpp
Ah, suddenly I've remembered. I've used the example from the API (with location point) and it failed to build a refinery. Then I've switched to another solution, you can see it in my bot's sources.
So the following advice should help:
Usually, you should find the nearest mineral or vesper geyser (these are neutral units on the map), use the unit found as a target for the 'build' command instead of a point.
@alkurbatov Thanks alot! I think i can solve the problem but i'll ask to keep this issue open util i check that, prob todady at night i'll back to code again.
Actually nearest mineral or nearest vespene are pointing SCVs to the wrong way. When some SCV finish something and get iddle he's sent to findnearestminerals and mine there, but for some reason he's getting wrong mineral and gaiser, and i already tryed to push them to CC before getting iddle, no sucess.
That's explain why my pointers are not working properly ~~maybe. ~
Here's a iddle function:
case UNIT_TYPEID::TERRAN_SCV: { const Unit* cc_target = FindNearestCC(unit->pos); const Unit* mineral_target = FindNearestMineralPatch(unit->pos); if (!mineral_target) { break; } Actions()->UnitCommand(unit, ABILITY_ID::SMART, cc_target); Actions()->UnitCommand(unit, ABILITY_ID::SMART, mineral_target); break; }
Heres Nearest Vespene
const Unit FindNearestVespenelPatch(const Point3D& start) { Units units = Observation()->GetUnits(Unit::Alliance::Neutral); float distance = std::numeric_limits
::max(); const Unit target = nullptr; for (const auto& u : units) { if (u->unit_type == UNIT_TYPEID::NEUTRAL_VESPENEGEYSER) { std::cout << u->pos.x << std::endl; std::cout << u->pos.y << std::endl; float d = DistanceSquared3D(u->pos, start); if (d < distance) { distance = d; target = u; } } }
Heres Nearest Minerals
const Unit* FindNearestMineralPatch(const Point2D& start) { Units units = Observation()->GetUnits(Unit::Alliance::Neutral); float distance = std::numeric_limits<float>::max(); const Unit* target = nullptr; for (const auto& u : units) { if (u->unit_type == UNIT_TYPEID::NEUTRAL_MINERALFIELD) { float d = DistanceSquared2D(u->pos, start); if (d < distance) { distance = d; target = u; } } } return target; }
Minerals: There are two flaws in your code. First: why are you looking for a mineral that is closest to the unit position and not cc_target->pos? You don't want the closest mineral to the worker, you want the closest mineral that belongs to the closest cc to the worker. Second: if you issue two commands in the same frame without queuing, the second overrides the first. So the move command to the cc will never be used. Anyway, you don't need to queue. Just look for the right closest mineral.
Gas: You could also here use a cc position rather than a worker position as start. You just need to make sure that the gas positions are not already occupied for the cc.
(Sry I'm at my phone so no nice formating.)
One thing I forgot to mention: keep in mind that there are different types if mineral/gas. On some maps your functions won't find minerals/gas because you are only looking for one specific type. See type enums for the others.
By the way, is there any simple approach to identify that the gas positions are not already occupied (i.e. without additional memory and comparison of refineries with vespene points)?
@Archiatrus Minerals:
There are two flaws in your code. First: why are you looking for a mineral that is closest to the unit.....
R: I was trying to send SCV to CC before start to find for nearest minerals, to check if SCV would try some distant mine. Already fixed that.
One thing I forgot to mention: keep in mind that there are different types if mineral/gas. On some maps your functions won't find minerals/gas because you are only looking for one specific type. See type enums for the others.
R: That post was the key to solve the problem, since Geyser on plataform are named NEUTRAL_SPACEPLATFORMGEYSER instead of NEUTRAL_VESPENEGEYSER, just like the minerals.
So the problem is solved, but i'll ask to keep that issue open just a little more, i'll close by my self when i feel confident.
Ok, thx to @alkurbatov and @Archiatrus all problems are fixed and i'll close the issue. If somebody are facing some problem related just feel free to inbox me any time.
Hello i'm trying to build refinery on vespene but i've no idea why it's not working, if some one could help i would appreciate.
Here's a function wich give a exact position of Vespene Geyser .
And Here's a function wich ask to build the Refinery
But some how the svc can't find the way to build giving the alert " Can't place, locaton invalid "