void RoomContainer::DrawObject(const Object& object) { if (const Actor* actor = dynamic_cast<const Actor*>(&object)) { IE::point actorPosition = actor->Position(); if (actor->IsSelected()) { IE::point position = offset_point(actorPosition, -fAreaOffset.x, -fAreaOffset.y); Bitmap* image = fBackMap->Image(); image->Lock(); uint32 color = image->MapColor(0, 255, 0); image->StrokeCircle(position.x, position.y, sSelectedActorRadius, color); if (actor->Destination() != actor->Position()) { IE::point destination = offset_point(actor->Destination(), -fAreaOffset.x, -fAreaOffset.y); image->StrokeCircle( destination.x, destination.y, sSelectedActorRadius - 10, color); } image->Unlock(); } const Bitmap* actorFrame = actor->Bitmap(); int32 pointHeight = PointHeight(actorPosition); actorPosition.y += pointHeight - 8; DrawObject(actorFrame, actorPosition, true); } }
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); } }
IE::point PathFinder::_GeneratePath(const IE::point& start, const IE::point& end) { fPoints.clear(); IE::point maxReachableDirectly = start;//_CreateDirectPath(start, end); if (PointSufficientlyClose(maxReachableDirectly, end) || !_IsPassable(end)) return maxReachableDirectly; std::list<point_node*> openList; std::list<point_node*> closedList; point_node* currentNode = new point_node(maxReachableDirectly, NULL, 0); openList.push_back(currentNode); uint32 tries = 4000; bool notFound = false; for (;;) { // If adiacent nodes are passable, add them to the list _AddIfPassable(offset_point(currentNode->point, fStep, 0), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, fStep, fStep), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, 0, fStep), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, -fStep, fStep), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, -fStep, 0), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, -fStep, -fStep), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, fStep, -fStep), *currentNode, openList, closedList); _AddIfPassable(offset_point(currentNode->point, 0, -fStep), *currentNode, openList, closedList); openList.remove(currentNode); closedList.push_back(currentNode); if (PointSufficientlyClose(currentNode->point, end)) break; currentNode = _GetCheapestNode(openList, end); if (currentNode == NULL || --tries == 0) { notFound = true; break; } } //std::list<point_node*>::const_iterator i; if (notFound) { // TODO: Destination is unreachable. // Try to find a reachable point near destination std::cout << "Path not found" << std::endl; EmptyList(closedList); EmptyList(openList); return start; } EmptyList(openList); std::list<point_node*>::reverse_iterator r = closedList.rbegin(); point_node* walkNode = *r; for (;;) { //fPoints.insert(directRouteEnd, walkNode->point); //directRouteEnd--; fPoints.push_front(walkNode->point); const point_node* parent = walkNode->parent; if (parent == NULL) break; walkNode = const_cast<point_node*>(parent); } EmptyList(closedList); assert (PointSufficientlyClose(fPoints.back(), end)); return fPoints.back(); }
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); } }