예제 #1
0
파일: C4FindObject.cpp 프로젝트: ev1313/yaC
C4Object *C4FindObject::Find(const C4ObjectList &Objs, const C4LSectors &Sct) {
  // Trivial case
  if (IsImpossible()) return NULL;
  C4Object *pBestResult = NULL;
  // Check bounds
  C4Rect *pBounds = GetBounds();
  if (!pBounds) return Find(Objs);
  // Traverse areas, return first matching object w/o sort or best with sort
  else if (UseShapes()) {
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    C4Object *pObj;
    for (C4ObjectList *pLst = Area.FirstObjectShapes(&pSct); pLst;
         pLst = Area.NextObjectShapes(pLst, &pSct))
      if (pObj = Find(*pLst))
        if (!pSort)
          return pObj;
        else if (!pBestResult || pSort->Compare(pObj, pBestResult) > 0)
          if (pObj->Status) pBestResult = pObj;
  } else {
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    C4Object *pObj;
    for (C4ObjectList *pLst = Area.FirstObjects(&pSct); pLst;
         pLst = Area.NextObjects(pLst, &pSct))
      if (pObj = Find(*pLst))
        if (!pSort)
          return pObj;
        else if (!pBestResult || pSort->Compare(pObj, pBestResult) > 0)
          if (pObj->Status) pBestResult = pObj;
  }
  return pBestResult;
}
예제 #2
0
파일: C4FindObject.cpp 프로젝트: ev1313/yaC
C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs,
                                     const C4LSectors &Sct) {
  // Trivial case
  if (IsImpossible()) return new C4ValueArray();
  C4Rect *pBounds = GetBounds();
  if (!pBounds) return FindMany(Objs);
  // Prepare for array that may be generated
  C4ValueArray *pArray;
  int32_t iSize;
  // Check shape lists?
  if (UseShapes()) {
    // Get area
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    C4ObjectList *pLst = Area.FirstObjectShapes(&pSct);
    // Check if a single-sector check is enough
    if (!Area.Next(pSct)) return FindMany(pSct->ObjectShapes);
    // Set up array
    pArray = new C4ValueArray(32);
    iSize = 0;
    // Create marker, search all areas
    uint32_t iMarker = ::Game.Objects.GetNextMarker();
    for (; pLst; pLst = Area.NextObjectShapes(pLst, &pSct))
      for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next)
        if (pLnk->Obj->Status)
          if (pLnk->Obj->Marker != iMarker) {
            pLnk->Obj->Marker = iMarker;
            if (Check(pLnk->Obj)) {
              // Grow the array, if neccessary
              if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2);
              // Add object
              (*pArray)[iSize++] = C4VObj(pLnk->Obj);
            }
          }
  } else {
    // Set up array
    pArray = new C4ValueArray(32);
    iSize = 0;
    // Search
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    for (C4ObjectList *pLst = Area.FirstObjects(&pSct); pLst;
         pLst = Area.NextObjects(pLst, &pSct))
      for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next)
        if (pLnk->Obj->Status)
          if (Check(pLnk->Obj)) {
            // Grow the array, if neccessary
            if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2);
            // Add object
            (*pArray)[iSize++] = C4VObj(pLnk->Obj);
          }
  }
  // Shrink array
  pArray->SetSize(iSize);
  // Recheck object status (may shrink array again)
  CheckObjectStatus(pArray);
  // Apply sorting
  if (pSort) pSort->SortObjects(pArray);
  return pArray;
}
예제 #3
0
int32_t C4FindObject::Count(const C4ObjectList &Objs, const C4LSectors &Sct)
{
	// Trivial cases
	if (IsImpossible())
		return 0;
	if (IsEnsured())
		return Objs.ObjectCount();
	// Check bounds
	C4Rect *pBounds = GetBounds();
	if (!pBounds)
		return Count(Objs);
	else if (UseShapes())
	{
		// Get area
		C4LArea Area(&::Objects.Sectors, *pBounds); C4LSector *pSct;
		C4ObjectList *pLst = Area.FirstObjectShapes(&pSct);
		// Check if a single-sector check is enough
		if (!Area.Next(pSct))
			return Count(pSct->ObjectShapes);
		// Create marker, count over all areas
		uint32_t iMarker = ::Objects.GetNextMarker();
		int32_t iCount = 0;
		for (; pLst; pLst=Area.NextObjectShapes(pLst, &pSct))
			for (C4Object *obj : Objs)
				if (obj->Status)
					if (obj->Marker != iMarker)
					{
						obj->Marker = iMarker;
						if (Check(obj))
							iCount++;
					}
		return iCount;
	}
	else
	{
		// Count objects per area
		C4LArea Area(&::Objects.Sectors, *pBounds); C4LSector *pSct;
		int32_t iCount = 0;
		for (C4ObjectList *pLst=Area.FirstObjects(&pSct); pLst; pLst=Area.NextObjects(pLst, &pSct))
			iCount += Count(*pLst);
		return iCount;
	}
}