Пример #1
0
/*
// Callback Clone Functions
const int SQUARE_SIZE = 8;
#include <algorithm>
// Stolen directly from ALCallback.cpp
struct SearchOffset {
	int dx,dy;
	int qdist; // dx*dx+dy*dy
};
// Stolen directly from ALCallback.cpp
bool SearchOffsetComparator (const SearchOffset& a, const SearchOffset& b)
{	return a.qdist < b.qdist;	}
// Stolen directly from ALCallback.cpp
const vector<SearchOffset>& GetSearchOffsetTable (int radius)
{	static vector <SearchOffset> searchOffsets;
	int size = radius*radius*4;
	if (size > searchOffsets.size()) {
		searchOffsets.resize (size);
		for (int y=0;y<radius*2;y++)
			for (int x=0;x<radius*2;x++)
			{	SearchOffset& i = searchOffsets[y*radius*2+x];
				i.dx = x-radius;
				i.dy = y-radius;
				i.qdist = i.dx*i.dx+i.dy*i.dy;
			}
		sort (searchOffsets.begin(), searchOffsets.end(), SearchOffsetComparator);
	}
	return searchOffsets;
}
float3 cBuilderPlacement::ClosestBuildSite(const UnitDef* ud, float3 p, float sRadius, int facing)
{
	if (!ud) return float3(-1.0f,0.0f,0.0f);
	int endr = (int)(sRadius/(SQUARE_SIZE*2));
	const vector<SearchOffset>& ofs = GetSearchOffsetTable (endr);
	for(int so=0;so<endr*endr*4;so++)
	{
		float x = p.x+ofs[so].dx*SQUARE_SIZE*2;
		float z = p.z+ofs[so].dy*SQUARE_SIZE*2;
		if( cb->CanBuildAt(ud,float3(x,0,z),facing) )
		{
			return float3(x,0,z);
		}
	}
	return float3(-1.0f,0.0f,0.0f);
}
*/
bool cBuilderPlacement::FindWeaponPlacement(UnitInfo *U, float3& position)
{
	if( U->BuildQ->creationUD->WeaponGuardRange == 0 )
		return false;

	if( U->BuildQ->creationUD->ud->minWaterDepth < 0 && U->BuildQ->creationUD->WeaponSeaEff.BestRange > 0 )
	{
		int iS = G->TM->GetSectorIndex(position);
		if( !G->TM->sector[iS].isWater )
			position = G->TM->GetClosestSector(G->TM->waterSectorType,iS)->position;
		return true;
	}

	int BID = -1;
	float3 buildPosition;
	for(map<int,UnitInfo*>::iterator i=G->UImmobile.begin(); i!=G->UImmobile.end(); ++i )
	{
		buildPosition = cb->GetUnitPos(i->first);
		if( i->second->udr->WeaponGuardRange == 0 && int(i->second->UDefences.size()) == 0 &&
			CanBuildAt(U,position,buildPosition) && CanBeBuiltAt(U->BuildQ->creationUD,buildPosition,i->second->udr->WeaponGuardRange) )
			if( BID == -1 || position.distance2D(buildPosition) < position.distance2D(cb->GetUnitPos(BID)) )
				BID = i->first;
	}

	if( BID > 0 )
	{
		position = cb->GetUnitPos(BID);
		return true;
	}

	return false;
}
Пример #2
0
// this only verifies the existence, it does not check whether the building is currently
// in a state that allows it to kick out units. however, it respects BuiltAt.
bool HouseExt::FactoryForObjectExists(HouseClass *pHouse, TechnoTypeClass *pItem) {
	eAbstractType WhatAmI = pItem->WhatAmI();
	auto pExt = TechnoTypeExt::ExtMap.Find(pItem);

	for(int i = 0; i < pHouse->Buildings.Count; ++i) {
		BuildingTypeClass *pType = pHouse->Buildings[i]->Type;
		if(pType->Factory == WhatAmI
			&& pType->Naval == pItem->Naval
			&& pExt->CanBeBuiltAt(pType)) {
			return true;
		}
	}
	return false;
}
Пример #3
0
HouseExt::FactoryState HouseExt::HasFactory(
	HouseClass const* const pHouse, TechnoTypeClass const* const pItem,
	bool const requirePower)
{
	auto const pExt = TechnoTypeExt::ExtMap.Find(pItem);
	auto const bitsOwners = pItem->GetOwners();
	auto const isNaval = pItem->Naval;
	auto const abs = pItem->WhatAmI();

	auto ret = FactoryState::NoFactory;

	for(auto const& pBld : pHouse->Buildings) {
		if(pBld->InLimbo
			|| pBld->GetCurrentMission() == Mission::Selling
			|| pBld->QueuedMission == Mission::Selling)
		{
			continue;
		}

		auto const pType = pBld->Type;

		if(pType->Factory != abs
			|| (abs == AbstractType::UnitType && pType->Naval != isNaval)
			|| !pExt->CanBeBuiltAt(pType)
			|| !pType->InOwners(bitsOwners))
		{
			continue;
		}

		if(!requirePower || pBld->HasPower) {
			return FactoryState::Available;
		}

		ret = FactoryState::Unpowered;
	}

	return ret;
}
Пример #4
0
float3 cBuilderPlacement::FindBuildPosition(sBuildQuarry *BQ)
{
	const UnitDef* bd = BQ->creationUD->ud;
	if( BQ->RS != 0 ) // Resource is set
		return cb->ClosestBuildSite(bd,BQ->RS->S->position,BQ->RS->searchRadius,BQ->RS->disApart);

	float3 cPosition = cb->GetUnitPos(BQ->builderID); // Construction Position
	if( NeedResourceSite(BQ->creationUD->ud) )
	{
		cPosition.x = -2;
		cPosition.z = -1;
		cPosition.y = -1;
		return cPosition;
	}

	G->CorrectPosition(cPosition);
	float3 bPosition = cPosition; // Builder Position
	if( FindWeaponPlacement(BQ->builderUI,cPosition) )
	{
		cPosition.x+=rand()%81-40;
		cPosition.z+=rand()%81-40;
		G->CorrectPosition(cPosition);
	}
	else if( BQ->builderUI->ud->speed == 0.0 )
	{
		cPosition.x+=rand()%int(1.8*BQ->builderUI->ud->buildDistance)-0.9*BQ->builderUI->ud->buildDistance;
		cPosition.z+=rand()%int(1.8*BQ->builderUI->ud->buildDistance)-0.9*BQ->builderUI->ud->buildDistance;
		G->CorrectPosition(cPosition);
	}
	else
	{
		cPosition.x+=rand()%int(0.9*BQ->builderUI->ud->buildDistance)-0.45*BQ->builderUI->ud->buildDistance;
		cPosition.z+=rand()%int(0.9*BQ->builderUI->ud->buildDistance)-0.45*BQ->builderUI->ud->buildDistance;
		G->CorrectPosition(cPosition);
	}

	int iS;
	if( !CanBuildAt(BQ->builderUI,bPosition,cPosition) || !CanBeBuiltAt(BQ->creationUD,cPosition) )
	{
		iS = G->TM->GetSectorIndex(cPosition);
		if( BQ->creationUD->mobileType != 0 ) // a factory or mobile unit
		{
			TerrainMapAreaSector *AS = G->TM->GetAlternativeSector(BQ->builderUI->area,iS,BQ->creationUD->mobileType);
			if( BQ->creationUD->immobileType != 0 ) // a factory
			{
				TerrainMapSector *S = G->TM->GetAlternativeSector(AS->area,iS,BQ->creationUD->immobileType);
				if( S != 0 )
					cPosition = S->position;
				else
				{
					cPosition.x = -3;
					cPosition.z = -1;
					cPosition.y = -1;
					return cPosition;
				}
			}
			else
				cPosition = AS->S->position;
		}
		else if( BQ->creationUD->immobileType != 0 ) // buildings
			cPosition = G->TM->GetClosestSector(BQ->creationUD->immobileType,iS)->position;
	}
	if( BQ->builderUI->ud->speed == 0.0 )
	{
		float3 cPosition2 = cb->ClosestBuildSite(bd,cPosition,BQ->builderUI->ud->buildDistance,5);
		if( cPosition2.x <= 0 && cPosition2.y <= 0 && cPosition2.z <= 0 )
			cPosition2 = cb->ClosestBuildSite(bd,cPosition,BQ->builderUI->ud->buildDistance+25,1);
		return cPosition2;
	}

	iS = G->TM->GetSectorIndex(cPosition);
	float fSearchRadius=1000.0f;
	int iDisApart=10;
	if( G->TM->sector[iS].isWater )
		iDisApart=15;
	else if( bd->speed > 0 )
		iDisApart=5;
	else if( int(bd->buildOptions.size())>0 )
		iDisApart=15;
	if( iDisApart < int(bd->kamikazeDist/8.0) )
		iDisApart = int(bd->kamikazeDist/8.0);

	float3 cPosition2 = cb->ClosestBuildSite(bd,cPosition,fSearchRadius,iDisApart);
	if( cPosition2.x == -1 )
	{
		cPosition2 = cb->ClosestBuildSite(bd,cPosition,2500.0f,iDisApart);
		if( cPosition2.x == -1 )
			return bPosition;
	}
	return cPosition2;
}