Page 1 of 1

Building inside yardmaps

Posted: 01 Oct 2015, 14:36
by lamer
Is building a structure inside a factory is correct behaviour?
For example next CppTestAI will build radar inside factory (spring 100 + BA 9.10)

Code: Select all

/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include "CppTestAI.h"
#include "ExternalAI/Interface/AISEvents.h"
#include "ExternalAI/Interface/AISCommands.h"
// generated by the C++ Wrapper scripts
#include "OOAICallback.h"
#include "UnitDef.h"
#include "WrappUnit.h"
#include "Map.h"
#include <string>
cpptestai::CCppTestAI::CCppTestAI(springai::OOAICallback* callback):
		callback(callback),
		skirmishAIId(callback != NULL ? callback->GetSkirmishAIId() : -1)
		{}
cpptestai::CCppTestAI::~CCppTestAI() {}

int cpptestai::CCppTestAI::HandleEvent(int topic, const void* data) {
	switch (topic) {
		case EVENT_UNIT_CREATED: {
			struct SUnitCreatedEvent* evt = (struct SUnitCreatedEvent*)data;
			springai::Unit* unit = springai::WrappUnit::GetInstance(skirmishAIId, evt->unit);
			static springai::AIFloat3 labPos = ZeroVector;
			static springai::Unit* com = nullptr;  // leak
			springai::UnitDef* def = unit->GetDef();
			if (std::string("armcom") == def->GetName()) {
				com = unit;
				springai::UnitDef* buildDef = callback->GetUnitDefByName("armlab");
				com->Build(buildDef, com->GetPos(), 0);
				delete buildDef;
			} else if (std::string("armlab") == def->GetName()) {
				labPos = unit->GetPos() + springai::AIFloat3(0, 0, 32);
				springai::UnitDef* buildDef = callback->GetUnitDefByName("armpw");
				unit->Build(buildDef, labPos, 0);
				delete unit, delete buildDef;
			} else if (std::string("armpw") == def->GetName()) {
				springai::UnitDef* buildDef = callback->GetUnitDefByName("armrad");
				springai::Map* map = callback->GetMap();
				springai::AIFloat3 buildPos = map->FindClosestBuildSite(buildDef, labPos, 600.0f, 0, 0);
				com->Build(buildDef, buildPos, 0);
				delete unit, delete buildDef, delete map;
			}
			delete def;
			break;
		}
		default: break;
	}
	// signal: everything went OK
	return 0;
}
Feels like a bug. Or probably function responsible for validation of position ("IsPossibleToBuildAt") should take additional parameter "bool doNotAllowBuildingInsideOpenYardMap"?
Also same behaviour is allowed for players (can't think of any reason for that in perspective of BA, ZK, S44).

Didn't mantise it as my ai uses own implementation of FindClosestBuildSite so it's not affected by described "feature" and i'm not sure it's a bug.

Re: Building inside yardmaps

Posted: 01 Oct 2015, 15:25
by Anarchid
People used to use this competitively in Evo by building radars and turrets inside of enemy factories, disabling nanoframe creation.

Was more hilarious in evo compared to other games because of its weird clipping rules and extreme armor modifiers for building vs building combat.

Re: Building inside yardmaps

Posted: 01 Oct 2015, 17:57
by Silentwings
If you don't want it you can prevent it with a gadget - http://imolarpg.dyndns.org/trac/balates ... ab_hax.lua, so it shouldn't be possible in BA (and if it is, afaik that's a bug). I guess the AI doesn't know any of this, though.

Re: Building inside yardmaps

Posted: 01 Oct 2015, 22:16
by lamer
The bug is possible in BA as a player within own factory, tested with springlobby+spring100+BA9.10+singleplayer vs NullAI
yardmap.jpg
(148.62 KiB) Not downloaded yet
But if i understood right it's solvable with gadget for players.
Btw, CAI (zk's ai) suffer from same issue: builds nano-turrets inside factories.
Anyway, for native AIs Map::IsPossibleToBuildAt and Map::FindClosestBuildSite with additional parameter "bool doNotAllowBuildingInsideOpenYardMap" should address the issue (maybe). But thats another story (feature request).

Re: Building inside yardmaps

Posted: 01 Oct 2015, 22:38
by Silentwings
Sorry - I meant to refer to what Anarchid said. If I remember rightly, BA allows you to build/move inside your own factories but not inside your enemies.

Re: Building inside yardmaps

Posted: 01 Oct 2015, 22:49
by 8611z
yardmap.jpg
I think http://imolarpg.dyndns.org/trac/balates ... ab_hax.lua is not supposed to prevent that.
It might be about different bug/tactic: Walking units into an enemy factory, where they are harder/impossible to target.
Building into enemy factories is not so relevant in BA (short buildranges etc), but walking into them was somewhat common.

Code: Select all

for Lid,Lv in pairs(lab) do 
  local units = spGetUnitsInBox(Lv.minx, Lv.miny, Lv.minz, Lv.maxx, Lv.maxy, Lv.maxz)
    for i,id in ipairs(units) do
      local team = spGetUnitAllyTeam(id) 
      ...
      ...
      if (team ~= Lv.team) and not fly then
         ...
Note: team ~= Lv.team, if factory and unit are same team then it does nothing.


Howerver the zero-K version https://github.com/ZeroK-RTS/Zero-K/blo ... x.lua#L186 looks it tries to prevent the
"Build inside factory" thing:

Code: Select all

function AllowUnitCreation( ... )
for Lid,Lv in pairs(lab) do
  -- intersection of 2 rectangles
  if Lv.minx < maxx and Lv.maxx > minx and Lv.minz < maxz and Lv.maxz > minz then
  return false
end
Callin AllowUnitCreation returns false = engine blocks creation of that unit.
solvable with gadget for players
Well, wrt "solveable":
There is kinda conflict that the GUI tells player with green preview-thing that he can build there. Then he tries but nothing happens. Similiar to how AIs feel.

Re: Building inside yardmaps

Posted: 02 Oct 2015, 00:15
by abma
IMHO thats a feature.

also: FindClosestBuildSite has a minDist parameter, it can be used to prevent that.