Пример #1
0
Chit* LumosChitBag::FindBuilding(	const grinliz::IString&  name, 
									const grinliz::Vector2I& sector, 
									const grinliz::Vector2F* pos, 
									LumosChitBag::EFindMode flags,
									CDynArray<Chit*>* arr,
									IChitAccept* filter )
{
	CDynArray<Chit*>& match = arr ? *arr : findMatch;	// sleazy reference trick to point to either passed in or local.
	match.Clear();
	findWeight.Clear();

	for( MapSpatialComponent* it = mapSpatialHash[sector.y*NUM_SECTORS+sector.x]; it; it = it->nextBuilding ) {
		Chit* chit = it->ParentChit();
		GLASSERT( chit );
		if ( filter && !filter->Accept( chit )) {				// if a filter, check it.
			continue;
		}

		const GameItem* item = chit->GetItem();

		if ( item && ( name.empty() || item->IName() == name )) {	// name, if empty, matches everything
			match.Push( chit );
		}
	}

	// If we found nothing, or we don't care about the position, return early.
	// Else deal with choice / sorting / etc. below.
	if ( match.Empty() )
		return 0;
	if ( !pos )
		return match[0];

	// NEAREST scans and finds the closest one.
	// RANDOM_NEAR chooses one at random, but weighted by the (inverse) of the distance
	if ( flags == EFindMode::NEAREST ) {
		float closest = ( ToWorld2F(match[0]->Position()) - *pos ).LengthSquared();
		int   ci = 0;
		for( int i=1; i<match.Size(); ++i ) {
			float len2 = ( ToWorld2F(match[i]->Position()) - *pos ).LengthSquared();
			if ( len2 < closest ) {
				closest = len2;
				ci = i;
			}
		}
		return match[ci];
	}
	if ( flags == EFindMode::RANDOM_NEAR ) {
		for( int i=0; i<match.Size(); ++i ) {
			float len = ( ToWorld2F(match[i]->Position()) - *pos ).Length();
			if (len < 1) len = 1;
			findWeight.Push( 1.0f/len );
		}
		int index = random.Select( findWeight.Mem(), findWeight.Size() );
		return match[index];
	}

	// Bad flag? Something didn't return?
	GLASSERT( 0 );
	return 0;
}
Пример #2
0
Chit* LumosChitBag::QueryPorch( const grinliz::Vector2I& pos )
{
	Vector2I sector = ToSector(pos);
	for( MapSpatialComponent* it = mapSpatialHash[SectorIndex(sector)]; it; it = it->nextBuilding ) {
		if ( it->PorchPos().Contains( pos )) {
			return it->ParentChit();
		}
	}
	return 0;
}
Пример #3
0
void LumosChitBag::BuildingCounts(const Vector2I& sector, int* counts, int n)
{
	BuildScript buildScript;

	for( MapSpatialComponent* it = mapSpatialHash[sector.y*NUM_SECTORS+sector.x]; it; it = it->nextBuilding ) {
		Chit* chit = it->ParentChit();
		GLASSERT( chit );

		const GameItem* item = chit->GetItem();
		if (!item)
			continue;
		const IString& name = item->IName();

		int id = 0;
		if (!name.empty()) {
			buildScript.GetDataFromStructure(name, &id);
			if (id < n) {
				counts[id] += 1;
			}
		}
	}
}
Пример #4
0
Chit* LumosChitBag::QueryBuilding( const IString& name, const grinliz::Rectangle2I& bounds, CChitArray* arr )
{
	GLASSERT( MAX_BUILDING_SIZE == 2 );	// else adjust logic
	Vector2I sector = ToSector( bounds.min );

	for( MapSpatialComponent* it = mapSpatialHash[SectorIndex(sector)]; it; it = it->nextBuilding ) {
		if ( it->Bounds().Intersect( bounds )) {
			Chit* chit = it->ParentChit();
			if (name.empty() || (chit->GetItem() && chit->GetItem()->IName() == name)) {
				if (!arr) {
					return chit;
				}
				if (arr->HasCap()) {
					arr->Push(chit);
				}
			}
		}
	}
	if (arr && !arr->Empty()) {
		return (*arr)[0];
	}
	return 0;
}