static void
diff_rects (Rect r1,
            Rect r2,
            int *count,
            Rect result[4])
{
    g_assert (count != NULL);
    g_assert (result != NULL);

    *count = 0;

    if (rects_intersect (r1, r2))
    {
        diff_rects_guts (r1, r2, count, result);
        diff_rects_guts (r2, r1, count, result);
    }
    else
    {
        if (!rect_empty (&r1))
        {
            result[(*count)++] = r1;
        }
        if (!rect_empty (&r2))
        {
            result[(*count)++] = r2;
        }
    }
}
Пример #2
0
/* Returns true if the ghost can see pacman from its position; looks at most
   max_dist blocks in the given cardinal direction. */
int agent_can_see_agent(GameAgent *ga, GameAgent *pman, FixedVector *direction, int max_dist)
{
	FixedVector dir_block_size;
	FixedVector ga_new_loc;
	SDL_Rect r_pman;
	SDL_Rect r_block;
	int blocks_seen = 0;

	fixed_vector_to_rect_dimensions(&pman->physical_dim, &r_pman);
	fixed_vector_to_rect_coords(&pman->loc, &r_pman);

	r_block.h = BLOCK_SIZE; r_block.w = BLOCK_SIZE;

	dir_block_size = fixed_vector_scale(direction, FIXED_SET_INT(BLOCK_SIZE));

	ga_new_loc = fixed_vector_add(&ga->loc, &dir_block_size);

	while ( blocks_seen < max_dist && agent_is_position_viable(ga, &ga_new_loc) ) {
		blocks_seen++;
		fixed_vector_to_rect_coords(&ga_new_loc, &r_block);
		if ( rects_intersect(&r_pman, &r_block) ) {
			return 1;
		}
		ga_new_loc = fixed_vector_add(&ga_new_loc, &dir_block_size);

	}
	return 0;
}
Пример #3
0
bool entity_collides_with_entity(const entity& e, const entity& other, collision_info* info)
{
	if((e.solid_dimensions()&other.weak_solid_dimensions()) == 0 &&
	   (e.weak_solid_dimensions()&other.solid_dimensions()) == 0) {
		return false;
	}

	const rect& our_rect = e.solid_rect();
	const rect& other_rect = other.solid_rect();

	if(!rects_intersect(our_rect, other_rect)) {
		return false;
	}

	if(other.destroyed()) {
		return false;
	}

	const rect area = intersection_rect(our_rect, other_rect);

	const solid_info* our_solid = e.solid();
	const solid_info* other_solid = other.solid();
	assert(our_solid && other_solid);

	const frame& our_frame = e.current_frame();
	const frame& other_frame = other.current_frame();

	for(int y = area.y(); y <= area.y2(); ++y) {
		for(int x = area.x(); x < area.x2(); ++x) {
			const int our_x = e.face_right() ? x - e.x() : (e.x() + our_frame.width()-1) - x;
			const int our_y = y - e.y();
			if(our_solid->solid_at(our_x, our_y, info ? &info->area_id : NULL)) {
				const int other_x = other.face_right() ? x - other.x() : (other.x() + other_frame.width()-1) - x;
				const int other_y = y - other.y();
				if(other_solid->solid_at(other_x, other_y, info ? &info->collide_with_area_id : NULL)) {
					return true;
				}
			}
		}
	}

	return false;
}
Пример #4
0
void
RoomContainer::DrawObject(const Bitmap* bitmap, const IE::point& point, bool mask)
{
	if (bitmap == NULL)
		return;

	IE::point leftTop = offset_point(point,
							-(bitmap->Frame().x + bitmap->Frame().w / 2),
							-(bitmap->Frame().y + bitmap->Frame().h / 2));

	GFX::rect rect(leftTop.x, leftTop.y, bitmap->Width(), bitmap->Height());

	if (rects_intersect(fMapArea, rect)) {
		GFX::rect offsetRect = offset_rect(rect, -fAreaOffset.x, -fAreaOffset.y);
		if (mask)
			GraphicsEngine::BlitBitmapWithMask(bitmap, NULL,
					fBackMap->Image(), &offsetRect, fBlitMask, &rect);
		else
			GraphicsEngine::BlitBitmap(bitmap, NULL, fBackMap->Image(), &offsetRect);
	}
}
Пример #5
0
int rect_difference(const rect& a, const rect& b, rect* output)
{
	if (rects_intersect(a,b) == false){  //return empty if there's no intersection
		return -1;
	}
		
	/* returning 4 rectangles in this orientation:
	 _________
	 | |___| |
	 | |   | |
	 | |___| |
	 |_|___|_|  */

	const rect* begin_output = output;

	if(a.x() < b.x()) {
		//get the left section of the source rectangle
		*output++ = rect(a.x(), a.y(), b.x() - a.x(), a.h());
	}

	if(a.x() + a.w() > b.x() + b.w()) {
		*output++ = rect(b.x() + b.w(), a.y(), (a.x() + a.w()) - (b.x() + b.w()), a.h());
	}

	if(a.y() < b.y()) {
		const int x1 = std::max(a.x(), b.x());
		const int x2 = std::min(a.x() + a.w(), b.x() + b.w());
		*output++ = rect(x1, a.y(), x2 - x1, b.y() - a.y());
	}

	if(a.y() + a.h() > b.y() + b.h()) {
		const int x1 = std::max(a.x(), b.x());
		const int x2 = std::min(a.x() + a.w(), b.x() + b.w());
		*output++ = rect(x1, b.y() + b.h(), x2 - x1, (a.y() + a.h()) - (b.y() + b.h()));
	}
	
	return output - begin_output;
}
Пример #6
0
void
RoomContainer::Draw(Bitmap *surface)
{
	GraphicsEngine* gfx = GraphicsEngine::Get();

	if (fWorldMap != NULL) {
		GFX::rect sourceRect = offset_rect(fViewPort,
				-fViewPort.x, -fViewPort.y);
		sourceRect = offset_rect(sourceRect, fAreaOffset.x, fAreaOffset.y);
		if (sourceRect.w < gfx->ScreenFrame().w || sourceRect.h < gfx->ScreenFrame().h) {
			GFX::rect clippingRect = fViewPort;
			clippingRect.w = gfx->ScreenFrame().w;
			clippingRect.h = gfx->ScreenFrame().h;
			gfx->SetClipping(&clippingRect);
			gfx->ScreenBitmap()->Clear(0);
			gfx->SetClipping(NULL);
		}
		gfx->BlitToScreen(fWorldMapBitmap, &sourceRect, &fViewPort);
	} else {
		if (sSelectedActorRadius > 22) {
			sSelectedActorRadiusStep = -1;
		} else if (sSelectedActorRadius < 18) {
			sSelectedActorRadiusStep = 1;
		}
		sSelectedActorRadius += sSelectedActorRadiusStep;

		GFX::rect mapRect = offset_rect_to(fViewPort,
				fAreaOffset.x, fAreaOffset.y);

		bool paused = Core::Get()->IsPaused();
		if (!paused) {
			assert(fBackMap != NULL);
			fBackMap->Update(mapRect);
		}

		if (fDrawAnimations) {
			Timer* timer = Timer::Get("ANIMATIONS");
			bool advance = timer != NULL && timer->Expired() && !paused;
			_DrawAnimations(advance);
		}
		_DrawActors();

		if (fDrawPolygons) {
			fBackMap->Image()->Lock();
			for (uint32 p = 0; p < fWed->CountPolygons(); p++) {
				const Polygon* poly = fWed->PolygonAt(p);
				if (poly != NULL && poly->CountPoints() > 0) {
					if (rects_intersect(poly->Frame(), mapRect)) {
						uint32 color = 0;
						if (poly->Flags() & IE::POLY_SHADE_WALL)
							color = 200;
						else if (poly->Flags() & IE::POLY_HOVERING)
							color = 500;
						else if (poly->Flags() & IE::POLY_COVER_ANIMATIONS)
							color = 1000;

						fBackMap->Image()->FillPolygon(*poly, color,
											-fAreaOffset.x, -fAreaOffset.y);
						fBackMap->Image()->StrokePolygon(*poly, color,
											-fAreaOffset.x, -fAreaOffset.y);
					}
				}
			}
			fBackMap->Image()->Unlock();
		}

		// TODO: handle this better
		if (Door* door = dynamic_cast<Door*>(fMouseOverObject.Target())) {
			GFX::rect rect = rect_to_gfx_rect(door->Frame());
			rect = offset_rect(rect, -mapRect.x, -mapRect.y);
			fBackMap->Image()->Lock();
			fBackMap->Image()->StrokeRect(rect, 70);
			fBackMap->Image()->Unlock();
		} else if (Actor* actor = dynamic_cast<Actor*>(fMouseOverObject.Target())) {
			try {
				GFX::rect rect = rect_to_gfx_rect(actor->Frame());
				rect = offset_rect(rect, -mapRect.x, -mapRect.y);
				fBackMap->Image()->Lock();
				IE::point position = offset_point(actor->Position(), -mapRect.x, -mapRect.y);
				uint32 color = fBackMap->Image()->MapColor(255, 255, 255);
				fBackMap->Image()->StrokeCircle(position.x, position.y, 20, color);
				fBackMap->Image()->Unlock();
			} catch (const char* string) {
				std::cerr << string << std::endl;
			} catch (...) {

			}
		} else if (Region* region = dynamic_cast<Region*>(fMouseOverObject.Target())) {
			GFX::rect rect = rect_to_gfx_rect(region->Frame());
			rect = offset_rect(rect, -mapRect.x, -mapRect.y);

			uint32 color = 0;
			switch (region->Type()) {
				case IE::REGION_TYPE_TRAVEL:
					color = fBackMap->Image()->MapColor(0, 125, 0);
					break;
				case IE::REGION_TYPE_TRIGGER:
					color = fBackMap->Image()->MapColor(125, 0, 0);
					break;
				default:
					color = fBackMap->Image()->MapColor(255, 255, 255);
					break;
			}

			fBackMap->Image()->Lock();

			if (region->Polygon().CountPoints() > 2) {
				fBackMap->Image()->StrokePolygon(region->Polygon(), color,
									-mapRect.x, -mapRect.y);
			} else
				fBackMap->Image()->StrokeRect(rect, color);
			fBackMap->Image()->Unlock();
		} else if (Container* container = dynamic_cast<Container*>(fMouseOverObject.Target())) {
			uint32 color = 0;
			color = fBackMap->Image()->MapColor(0, 125, 0);
			// TODO: Different colors for trapped/nontrapped
			fBackMap->Image()->Lock();

			if (container->Polygon().CountPoints() > 2) {
				fBackMap->Image()->StrokePolygon(container->Polygon(), color,
											-mapRect.x, -mapRect.y);
			}
			fBackMap->Image()->Unlock();
		}

		gfx->BlitToScreen(fBackMap->Image(), NULL, &fViewPort);
		_DrawSearchMap(mapRect);
	}
}