Explore Philand
  • Welcome to Phi
    • 🏝️What's Phi?
    • 🌄Mission
    • 🏃‍♀️Story
    • 🏄Phi Crew
  • ⚡Products
    • 🏝️Phi Land
      • 🔦User Guide for Phi Land
        • 0️⃣Before Playing Phi
          • 🦊Download a Crypto Wallet
          • 🟣Get $MATIC
          • 🔷Get an ENS Domain
        • 1️⃣Access Phi Land
        • 2️⃣Create your Phi Land
        • 3️⃣Claim Quest Objects
        • 4️⃣Purchase Items on Shop
        • 5️⃣Deposit Objects to Land
        • 6️⃣Build your land
        • 7️⃣Share your land on Twitter
      • 🎧Phi Music
      • ⛓️Hyperlinks & Link List
      • 💫Transferring Land
      • ↔️Phi Connect
    • ⚔️Phi Quest
      • 🔦User Guide for Phi Quest
        • 0️⃣Before Playing Phi
          • 🦊Download a Crypto Wallet
          • 🟣Get $MATIC
        • 1️⃣Access Phi Quest
        • 2️⃣Claim Quest Objects
          • Quest List
          • Adventure
          • Campaign
        • 3️⃣Purchase Items on Shop
        • 4️⃣Play Phi Land with Items you got
      • 🧑Account
      • 🏅Active Score Rank Quests
    • 🍭Phi Opportunity (beta)
    • 💎Phi Material
      • ⚒️Phi Craft
      • 🥗UGC Craft
    • 🔮OpenSea Collection Links
    • 💡How-to's
      • 🏷️Mastering ENS (Ethereum Name Service)
        • How to Register an ENS Domain Name
        • How to Renew an ENS Domain Name
        • How to Manage ENS records
          • How to set up the Avatar record in ENS
            • Using MintYourPFP to set an Avatar to an ENS name
        • How to Transfer ENS to Another Wallet
        • How to set up an ENS Subdomain
    • ❓FAQ
      • Must I have an ENS to play Phi Quest?
      • How can I get an ENS domain?
      • Why don't my ENS domains show up?
      • Can I use ENS subdomains for Phi Land?
      • What happens when I transfer ENS?
      • I can't create a land
      • Why cannot access to my land?
      • Why can't I change the baseplate?
      • Why can’t I claim Quest objects?
      • Any rewards for participating in Testnet?
      • What is Phi Quest?
      • How the Leaderboard on Phi Quest is calculated?
      • Why are there two EXPs?
      • I claimed objects on Phi Quest. How can I create my Phi Land?
      • Why can’t I see my objects in my wallet?
      • Can I trade Quest Objects?
      • Are traded objects included in my EXP calculation?
      • My EXP not showing, leaderboard not updating
      • Which browser should I use?
      • Which devices are supported?
      • How to update my Twitter OGP image (card)?
    • 📬Submit Feedback
      • Bug Report
      • Feature Request
      • User Survey
  • ⚙️DEVELOPERS
    • 🪴Create Philand
    • 🎨Objects NFT
      • ⛓️Quest Object
      • 🌾Free Object
      • 🧊Premium Object
      • 🍰Baseplate Object
      • 🧮Wallpaper Object
      • 💄Other Topics
      • 💡Appendix
    • 🛠️Use PhiMap
      • 🗺️Deposit/Withdraw
      • 🍧Save Philand
      • 👀View Function
      • 💡Appendix
    • 💝Philand API
      • ⌚Introduction
      • 🔑Authentication
        • 😄Use API key
        • 😍Get Access Token
        • 🤩Verify Access Token
        • 🤪Get Refresh Token
        • 😎Refresh JWT
      • 🫔Quest
        • 🎾Get Quest List
        • 🏀Get Quest Status
        • ⚽Trigger Eligible Check
        • 🎯Get Claimed Status
        • 🏓Get Verify Coupon
      • 🏝️Philand
        • 🫑View Philand Link
        • 🍍Get Philand Image
      • 🧸Account
        • 🍞Get Philand List
        • 👑Get PhiRank
      • 🎺Object
        • 🎸Get Object Info
      • 🦖Example Call
        • 🤠Quest Claim
      • 👔Related Links
    • 🧑‍🏫How to Verify your transaction
      • 👓Read Contract Method
      • 🚩Third-party API
      • 🦷Whitelist
    • 📄Contracts
      • 👮Audit
  • 💼Career
    • 👯Phi is hiring
  • 🔗Official links
    • Website
    • Twitter
    • Discord
    • Discourse
    • Medium
    • Github
    • Guild.xyz
    • Lenster
    • Instagram
Powered by GitBook
On this page
  • Save
  • Write object
  • Save Object with Link
  • Remove Object
  • Floating Object (transparency)
  • Collision Check
  • In this case, there is no collision .

Was this helpful?

  1. DEVELOPERS
  2. Use PhiMap

Save Philand

User can save Objects to Philand

Save

The save function can be used to update philand by putting the objects and links that you want to write to the contract.

    /*
     * @title save
     * @notice Function for save users map edition
     * @param name : ens name
     * @param removeIndexArray : Array of Object index
     * @param objectData : Array of Object struct (address contractAddress, uint256 tokenId, uint256 xStart, uint256 yStart)
     * @param link : Array of Link struct(stirng title, string url)
     * @param contractAddress : if you dont use, should be 0
     * @param tokenId : if you dont use, should be 0
     * @dev _removeUnUsedUserObject: clear delete empty array
     */
    function save(
        string memory name,
        uint256[] memory removeIndexArray,
        Object[] memory objectDatas,
        Link[] memory links,
        address wcontractAddress,
        uint256 wtokenId,
        address bcontractAddress,
        uint256 btokenId
    ) external nonReentrant onlyNotLocked onlyPhilandOwner(name) {
        _batchRemoveAndWrite(name, removeIndexArray, objectDatas, links);
        _removeUnUsedUserObject(name);
        if (wcontractAddress != address(0) && wtokenId != 0) {
            _changeWallPaper(name, wcontractAddress, wtokenId);
        }
        if (bcontractAddress != address(0) && btokenId != 0) {
            _changeBasePlate(name, bcontractAddress, btokenId);
        }
        emit Save(name, msg.sender);
    }

Write object

    /*
     * @title writeObjectToLand
     * @notice Return philand object
     * @param name : ens name
     * @param objectData : Object (address contractAddress,uint256 tokenId, uint256 xStart, uint256 yStart)
     * @param link : Link (stirng title, string url)
     * @dev NFT must be deposited in the contract before writing.
     */
    function writeObjectToLand(
        string memory name,
        Object memory objectData,
        Link memory link
    ) public onlyNotLocked onlyPhilandOwner(name) onlyDepositObject(name, objectData) {
        // Check the number of deposit NFTs to write object
        _checkDepositAvailable(name, objectData.contractAddress, objectData.tokenId);
        depositInfo[name][objectData.contractAddress][objectData.tokenId].used++;

        // Check the contractAddress is whitelisted.
        if (!_whitelist[objectData.contractAddress]) revert InvalidWhitelist();
        IObject _object = IObject(objectData.contractAddress);

        // Object contract requires getSize functions for x,y,z
        IObject.Size memory size = _object.getSize(objectData.tokenId);
        ObjectInfo memory writeObjectInfo = ObjectInfo(
            objectData.contractAddress,
            objectData.tokenId,
            objectData.xStart,
            objectData.yStart,
            objectData.xStart + size.x,
            objectData.yStart + size.y,
            link
        );
        // Check map range MapSettings
        _checkMapRange(writeObjectInfo);
        // Check Write Object dosen't collide with previous written objects
        _checkCollision(name, writeObjectInfo);

        userObject[name].push(writeObjectInfo);
        emit WriteObject(name, objectData.contractAddress, objectData.tokenId, objectData.xStart, objectData.yStart);
        emit WriteLink(name, objectData.contractAddress, objectData.tokenId, link.title, link.url, link.data);
    }

Save Object with Link

Each object has the ability to have a link function, which can have a title, link, and data columns. The link function is typically used to associate an object with a web page

// Each object can save with Link
struct Link {
        string title;
        string url;
        uint256 data;
    }

Remove Object

    /*
     * @title _removeUnUsedUserObject
     * @notice Functions for erase the 0 array value that has already been deleted.
     * @param name : ens name
     * @dev execute when writing an object.
     * @notion Erases the 0 array value that has already been deleted.
     */
    function _removeUnUsedUserObject(string memory name) private {
        uint256 index = 0;
        bool check = false;
        uint256 objectLength = userObject[name].length;
        ObjectInfo[] memory _userObjects = userObject[name];
        ObjectInfo[] memory newUserObjects = new ObjectInfo[](objectLength);
        for (uint256 i = 0; i < objectLength; ++i) {
            //  Erases the address(0) array that has already been deleted.
            if (_userObjects[i].contractAddress == address(0)) {
                check = true;
                continue;
            }
            newUserObjects[index] = _userObjects[i];
            index = index + 1;
        }
        if (check) {
            for (uint256 i = 0; i < objectLength; ++i) {
                if (_userObjects[i].contractAddress != address(0)) {
                    _removeObjectFromLand(name, i);
                }
            }
            delete userObject[name];

            for (uint256 i = 0; i < index; ++i) {
                _writeObjectToLand(name, newUserObjects[i]);
            }
        }
        return;
    }

Floating Object (transparency)

Some objects may appear to be floating in the scene. In these cases, the objects are written to the contract in the vertical direction, and transparency is applied to make the objects behind them visible. This allows for a more realistic and immersive experience

Collision Check

When writing objects to the contract, collision detection between rectangles is performed. The current implementation uses a simple method for detecting collisions, but we are always looking for better ways to do this. In future implementations, we may change the collision detection to use a more efficient way

    /*
     * @title checkCollision
     * @notice Functions for collision detection
     * @param name : Ens name
     * @param writeObjectInfo : Information about the object you want to write.
     * @dev execute when writing an object.
     */
    function _checkCollision(string memory name, ObjectInfo memory writeObjectInfo) private view {
        uint256 objectLength = userObject[name].length;
        ObjectInfo[] memory _userObjects = userObject[name];
        if (objectLength == 0) {
            return;
        }

        for (uint256 i = 0; i < objectLength; ++i) {
            // Skip if already deleted
            if (_userObjects[i].contractAddress == address(0)) {
                continue;
            }
            // Rectangular objects do not collide when any of the following four conditions are satisfied
            if (
                writeObjectInfo.xEnd <= _userObjects[i].xStart ||
                _userObjects[i].xEnd <= writeObjectInfo.xStart ||
                writeObjectInfo.yEnd <= _userObjects[i].yStart ||
                _userObjects[i].yEnd <= writeObjectInfo.yStart
            ) {
                continue;
            } else {
                revert ObjectCollision({
                    writeObjectInfo: writeObjectInfo,
                    userObjectInfo: _userObjects[i],
                    errorBoader: "invalid objectInfo"
                });
            }
        }
        return;
    }

In this case, there is no collision .

PreviousDeposit/WithdrawNextView Function

Last updated 2 years ago

Was this helpful?

⚙️
🛠️
🍧
Save Land
check collision