/** * @file llviewerparcelmgr.h * @brief Viewer-side representation of owned land * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef LL_LLVIEWERPARCELMGR_H #define LL_LLVIEWERPARCELMGR_H #include "v3dmath.h" #include "llframetimer.h" #include "llsingleton.h" #include "llparcelselection.h" #include "llui.h" #include <boost/function.hpp> #include <boost/signals2.hpp> class LLUUID; class LLMessageSystem; class LLParcel; class LLViewerTexture; class LLViewerRegion; const F32 DWELL_NAN = -1.0f; // A dwell having this value will be displayed as Loading... // Constants for sendLandOwner //const U32 NO_NEIGHBOR_JOIN = 0x0; //const U32 ALL_NEIGHBOR_JOIN = U32( NORTH_MASK // | SOUTH_MASK // | EAST_MASK // | WEST_MASK); // Specify the type of land transfer taking place //enum ELandTransferType //{ // LTT_RELEASE_LAND = 0x1, // LTT_CLAIM_LAND = 0x2, // LTT_BUY_LAND = 0x4, // LTT_DEED_LAND = 0x8, // LTT_FOR_GROUP = 0x16 //}; // Base class for people who want to "observe" changes in the viewer // parcel selection. //FIXME: this should be done by grabbing a floating parcel selection and observing changes on it, not the parcel mgr //--RN class LLParcelObserver { public: virtual ~LLParcelObserver() {}; virtual void changed() = 0; }; class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> { LLSINGLETON(LLViewerParcelMgr); ~LLViewerParcelMgr(); public: typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t; typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t; typedef boost::function<void()> teleport_failed_callback_t; typedef boost::signals2::signal<void()> teleport_failed_signal_t; static void cleanupGlobals(); BOOL selectionEmpty() const; F32 getSelectionWidth() const { return F32(mEastNorth.mdV[VX] - mWestSouth.mdV[VX]); } F32 getSelectionHeight() const { return F32(mEastNorth.mdV[VY] - mWestSouth.mdV[VY]); } BOOL getSelection(LLVector3d &min, LLVector3d &max) { min = mWestSouth; max = mEastNorth; return !selectionEmpty();} LLViewerRegion* getSelectionRegion(); F32 getDwelling() const { return mSelectedDwell;} void getDisplayInfo(S32* area, S32* claim, S32* rent, BOOL* for_sale, F32* dwell); // Returns selected area S32 getSelectedArea() const; void resetSegments(U8* segments); // write a rectangle's worth of line segments into the highlight array void writeHighlightSegments(F32 west, F32 south, F32 east, F32 north); // Write highlight segments from a packed bitmap of the appropriate // parcel. void writeSegmentsFromBitmap(U8* bitmap, U8* segments); void writeAgentParcelFromBitmap(U8* bitmap); // Select the collision parcel void selectCollisionParcel(); // Select the parcel at a specific point LLParcelSelectionHandle selectParcelAt(const LLVector3d& pos_global); // Take the current rectangle select, and select the parcel contained // within it. LLParcelSelectionHandle selectParcelInRectangle(); // Select a piece of land LLParcelSelectionHandle selectLand(const LLVector3d &corner1, const LLVector3d &corner2, BOOL snap_to_parcel); // Clear the selection, and stop drawing the highlight. void deselectLand(); void deselectUnused(); void addObserver(LLParcelObserver* observer); void removeObserver(LLParcelObserver* observer); void notifyObservers(); void setSelectionVisible(BOOL visible) { mRenderSelection = visible; } BOOL isOwnedAt(const LLVector3d& pos_global) const; BOOL isOwnedSelfAt(const LLVector3d& pos_global) const; BOOL isOwnedOtherAt(const LLVector3d& pos_global) const; BOOL isSoundLocal(const LLVector3d &pos_global) const; BOOL canHearSound(const LLVector3d &pos_global) const; // Returns a reference counted pointer to current parcel selection. // Selection does not change to reflect new selections made by user // Use this when implementing a task UI that refers to a specific // selection. LLParcelSelectionHandle getParcelSelection() const; // Returns a reference counted pointer to current parcel selection. // Pointer tracks whatever the user has currently selected. // Use this when implementing an inspector UI. // http://en.wikipedia.org/wiki/Inspector_window LLParcelSelectionHandle getFloatingParcelSelection() const; //LLParcel *getParcelSelection() const; LLParcel *getAgentParcel() const; LLParcel *getAgentOrSelectedParcel() const; BOOL inAgentParcel(const LLVector3d &pos_global) const; // Returns a pointer only when it has valid data. LLParcel* getHoverParcel() const; LLParcel* getCollisionParcel() const; // Can this agent build on the parcel he is on? // Used for parcel property icons in nav bar. bool allowAgentBuild() const; bool allowAgentBuild(const LLParcel* parcel) const; // Can this agent speak on the parcel he is on? // Used for parcel property icons in nav bar. bool allowAgentVoice() const; bool allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const; // Can this agent start flying on this parcel? // Used for parcel property icons in nav bar. bool allowAgentFly(const LLViewerRegion* region, const LLParcel* parcel) const; // Can this agent be pushed by llPushObject() on this parcel? // Used for parcel property icons in nav bar. bool allowAgentPush(const LLViewerRegion* region, const LLParcel* parcel) const; // Can scripts written by non-parcel-owners run on the agent's current // parcel? Used for parcel property icons in nav bar. bool allowAgentScripts(const LLViewerRegion* region, const LLParcel* parcel) const; // Can the agent be damaged here? // Used for parcel property icons in nav bar. bool allowAgentDamage(const LLViewerRegion* region, const LLParcel* parcel) const; F32 getHoverParcelWidth() const { return F32(mHoverEastNorth.mdV[VX] - mHoverWestSouth.mdV[VX]); } F32 getHoverParcelHeight() const { return F32(mHoverEastNorth.mdV[VY] - mHoverWestSouth.mdV[VY]); } // UTILITIES void render(); void renderParcelCollision(); void renderRect( const LLVector3d &west_south_bottom, const LLVector3d &east_north_top ); void renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 height, U8 direction, LLViewerRegion* regionp); void renderHighlightSegments(const U8* segments, LLViewerRegion* regionp); void renderCollisionSegments(U8* segments, BOOL use_pass, LLViewerRegion* regionp); static S32 PARCEL_BAN_LINES_HIDE; static S32 PARCEL_BAN_LINES_ON_COLLISION; static S32 PARCEL_BAN_LINES_ON_PROXIMITY; void resetCollisionTimer(); // Ban lines visibility timer void sendParcelGodForceOwner(const LLUUID& owner_id); // make the selected parcel a content parcel. void sendParcelGodForceToContent(); // Pack information about this parcel and send it to the region // containing the southwest corner of the selection. // If want_reply_to_update, simulator will send back a ParcelProperties // message. void sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListUpdate(U32 which); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListRequest(U32 flags); // Dwell is not part of the usual parcel update information because the // simulator doesn't actually know the per-parcel dwell. Ack! We have // to get it out of the database. void sendParcelDwellRequest(); // If the point is outside the current hover parcel, request more data void setHoverParcel(const LLVector3d& pos_global); bool canAgentBuyParcel(LLParcel*, bool forGroup) const; // void startClaimLand(BOOL is_for_group = FALSE); void startBuyLand(BOOL is_for_group = FALSE); void startSellLand(); void startReleaseLand(); void startDivideLand(); void startJoinLand(); void startDeedLandToGroup(); void reclaimParcel(); void buyPass(); // Buying Land class ParcelBuyInfo; ParcelBuyInfo* setupParcelBuy(const LLUUID& agent_id, const LLUUID& session_id, const LLUUID& group_id, BOOL is_group_owned, BOOL is_claim, BOOL remove_contribution); // callers responsibility to call deleteParcelBuy() on return value void sendParcelBuy(ParcelBuyInfo*); void deleteParcelBuy(ParcelBuyInfo* *info); void sendParcelDeed(const LLUUID& group_id); // Send the ParcelRelease message void sendParcelRelease(); // accessors for mAgentParcel const std::string& getAgentParcelName() const; const S32 getAgentParcelId() const; // Create a landmark at the "appropriate" location for the // currently selected parcel. // *NOTE: Taken out 2005-03-21. Phoenix. //void makeLandmarkAtSelection(); static void onStartMusicResponse(const LLUUID ®ion_id, const S32 &parcel_id, const std::string &url, const bool &play); static void optionallyStartMusic(const std::string &music_url, const S32 &local_id, const LLUUID ®ion_id, bool switched_parcel); static void processParcelOverlay(LLMessageSystem *msg, void **user_data); static void processParcelProperties(LLMessageSystem *msg, void **user_data); static void processParcelAccessListReply(LLMessageSystem *msg, void **user); static void processParcelDwellReply(LLMessageSystem *msg, void **user); void dump(); // Whether or not the collision border around the parcel is there because // the agent is banned or not in the allowed group BOOL isCollisionBanned(); boost::signals2::connection setTeleportFinishedCallback(teleport_finished_callback_t cb); boost::signals2::connection setTeleportFailedCallback(teleport_failed_callback_t cb); void onTeleportFinished(bool local, const LLVector3d& new_pos); void onTeleportFailed(); bool getTeleportInProgress(); static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power); static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); private: static void sendParcelAccessListUpdate(U32 flags, const std::map<LLUUID, class LLAccessEntry>& entries, LLViewerRegion* region, S32 parcel_local_id); static void sendParcelExperienceUpdate( const U32 flags, uuid_vec_t experience_ids, LLViewerRegion* region, S32 parcel_local_id ); static bool releaseAlertCB(const LLSD& notification, const LLSD& response); // If the user is claiming land and the current selection // borders a piece of land the user already owns, ask if he // wants to join this land to the other piece. //void askJoinIfNecessary(ELandTransferType land_transfer_type); //static void joinAlertCB(S32 option, void* data); //void buyAskMoney(ELandTransferType land_transfer_type); // move land from current owner to it's group. void deedLandToGroup(); static bool deedAlertCB(const LLSD& notification, const LLSD& response); static bool callbackDivideLand(const LLSD& notification, const LLSD& response); static bool callbackJoinLand(const LLSD& notification, const LLSD& response); //void finishClaim(BOOL user_to_user_sale, U32 join); LLViewerTexture* getBlockedImage() const; LLViewerTexture* getPassImage() const; private: BOOL mSelected; LLParcel* mCurrentParcel; // selected parcel info LLParcelSelectionHandle mCurrentParcelSelection; LLParcelSelectionHandle mFloatingParcelSelection; S32 mRequestResult; // result of last parcel request LLVector3d mWestSouth; LLVector3d mEastNorth; F32 mSelectedDwell; LLParcel *mAgentParcel; // info for parcel agent is in S32 mAgentParcelSequenceID; // incrementing counter to suppress out of order updates LLParcel* mHoverParcel; S32 mHoverRequestResult; LLVector3d mHoverWestSouth; LLVector3d mHoverEastNorth; std::vector<LLParcelObserver*> mObservers; BOOL mTeleportInProgress; LLVector3d mTeleportInProgressPosition; teleport_finished_signal_t mTeleportFinishedSignal; teleport_failed_signal_t mTeleportFailedSignal; // Array of pieces of parcel edges to potentially draw // Has (parcels_per_edge + 1) * (parcels_per_edge + 1) elements so // we can represent edges of the grid. // WEST_MASK = draw west edge // SOUTH_MASK = draw south edge S32 mParcelsPerEdge; U8* mHighlightSegments; U8* mAgentParcelOverlay; // Raw data buffer for unpacking parcel overlay chunks // Size = parcels_per_edge * parcels_per_edge / parcel_overlay_chunks static U8* sPackedOverlay; // Watch for pending collisions with a parcel you can't access. // If it's coming, draw the parcel's boundaries. LLParcel* mCollisionParcel; U8* mCollisionSegments; bool mRenderCollision; BOOL mRenderSelection; S32 mCollisionBanned; LLFrameTimer mCollisionTimer; LLViewerTexture* mBlockedImage; LLViewerTexture* mPassImage; // Media S32 mMediaParcelId; U64 mMediaRegionId; }; void sanitize_corners(const LLVector3d &corner1, const LLVector3d &corner2, LLVector3d &west_south_bottom, LLVector3d &east_north_top); #endif