S Price: $0.859992 (-0.65%)

Contract Diff Checker

Contract Name:
FARPG_QuestSystemV1

Contract Source Code:

File 1 of 1 : FARPG_QuestSystemV1

// File: @openzeppelin/[email protected]/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/[email protected]/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: FINALdeployFA/LIB - Common Structs.sol


pragma solidity ^0.8.9;
        
        
library S { 

//Pet struct
   
    struct Unit {
        uint hp; //unit fainted when hp <= 0
        uint attack; //attack - defense = damage on hp
        uint defense; //attack - defense = damage on hp
        uint speed; //how frequent to take a move
        uint intelligence; //how frequent to use skill
        uint genestrength; //depends on how many duplicates
        uint range; //range skill, id
        uint special; //special skill, id
    }

    struct Status {
        
        uint id; //unit id
        uint family; //determine which class of gear it can be wore. record while evolve, since its only has max 2 family, example Dragon+phantom, and 30gene max, so can use *100
       
        uint stage; //1 is rookie, 2 is mature, 3 is perfect
       
    }


    struct Time {
        uint bond; //how many time you took on this unit , use to evolve
        uint stamina; //how much you can train it per day. it should follow saturation graph
        uint hunger; //how much you feed it per day. it should follow saturation graph
    }


}
// File: FINALdeployFA/LIB - WeatherOutfit.sol


pragma solidity ^0.8.0;


library WO {


    function WeatherBuff (S.Unit[6] memory _UnitGroup, uint _weather) external pure returns (S.Unit[6] memory UnitGroup) {
        UnitGroup = _UnitGroup;
        //--------weather system---------
        //   WARNING: Cannot have + stats, because empty slot still empty after multiply.
        //enum Weather { Sunny, Cloudy, Rainy, Thunderstorm, Snowy, Aurora, BloodMoon, NONE } 0=Sunny and so on 7 or more = none
        //0 Sunny day Fire ATK x2, Nature INTx2
        //1 Cloudy day has nothing
        //2 Rainy day, Water HPx1.5
        //3 Thunderstorm day, Electric SPDx2
        //4 Snowy day, Ice DEF x2
        //5 Aurora day, Light speed x2
        //6 Bloodmoon day, Dark HPx2
        //****Lings with special type
        //Fire = 3, 5, 10, 23, 28, 38, 39, 60, 63, 69, 81, 95
        //Nature = 20, 21, 22, 24, 26, 29, 30, 42, 51, 72, 76, 80, 86, 96
        //Water = 15, 17, 31, 35, 71, 75, 79, 98
        //Electric = 2, 4, 27, 55, 57, 62, 73, 85, 87, 97
        //Ice = 12, 14, 16, 25, 43, 46, 47, 61, 64, 82
        //Dark = 8, 9, 11, 18, 32, 33, 36, 44, 54, 56, 58, 70, 74, 78, 84, 88
        //Light = 6, 34, 40, 48, 77, 89, 99
        for (uint i = 0; i < UnitGroup.length; i++) {
                if (_weather == 0 && (  UnitGroup[i].special == 3 || 
                                        UnitGroup[i].special == 5 || 
                                        UnitGroup[i].special == 10 || 
                                        UnitGroup[i].special == 23 || 
                                        UnitGroup[i].special == 28 || 
                                        UnitGroup[i].special == 38 || 
                                        UnitGroup[i].special == 39 || 
                                        UnitGroup[i].special == 60 || 
                                        UnitGroup[i].special == 63 || 
                                        UnitGroup[i].special == 69 || 
                                        UnitGroup[i].special == 81 || 
                                        UnitGroup[i].special == 95)) { //Fire
                    UnitGroup[i].attack = UnitGroup[i].attack*2;
                } else if (_weather == 0 && (   UnitGroup[i].special == 20 || 
                                                UnitGroup[i].special == 21 || 
                                                UnitGroup[i].special == 22 || 
                                                UnitGroup[i].special == 24 || 
                                                UnitGroup[i].special == 26 || 
                                                UnitGroup[i].special == 29 || 
                                                UnitGroup[i].special == 30 || 
                                                UnitGroup[i].special == 42 || 
                                                UnitGroup[i].special == 51 || 
                                                UnitGroup[i].special == 72 || 
                                                UnitGroup[i].special == 76 || 
                                                UnitGroup[i].special == 80 || 
                                                UnitGroup[i].special == 86 || 
                                                UnitGroup[i].special == 96)) { //Nature
                    UnitGroup[i].intelligence = UnitGroup[i].intelligence*2;
                } else if (_weather == 2 && (   UnitGroup[i].special == 15 || 
                                                UnitGroup[i].special == 17 || 
                                                UnitGroup[i].special == 31 || 
                                                UnitGroup[i].special == 35 || 
                                                UnitGroup[i].special == 71 || 
                                                UnitGroup[i].special == 75 || 
                                                UnitGroup[i].special == 79 || 
                                                UnitGroup[i].special == 98)) { //Water
                    UnitGroup[i].hp = (UnitGroup[i].hp*15)/10;
                } else if (_weather == 3 && (   UnitGroup[i].special == 2 || 
                                                UnitGroup[i].special == 4 || 
                                                UnitGroup[i].special == 27 || 
                                                UnitGroup[i].special == 55 || 
                                                UnitGroup[i].special == 57 || 
                                                UnitGroup[i].special == 62 || 
                                                UnitGroup[i].special == 73 || 
                                                UnitGroup[i].special == 85 || 
                                                UnitGroup[i].special == 87 || 
                                                UnitGroup[i].special == 97)) { //Electric
                    UnitGroup[i].speed = UnitGroup[i].speed*2;
                } else if (_weather == 4 && (   UnitGroup[i].special == 12 || 
                                                UnitGroup[i].special == 14 || 
                                                UnitGroup[i].special == 16 || 
                                                UnitGroup[i].special == 25 || 
                                                UnitGroup[i].special == 43 || 
                                                UnitGroup[i].special == 46 || 
                                                UnitGroup[i].special == 47 || 
                                                UnitGroup[i].special == 61 || 
                                                UnitGroup[i].special == 64 || 
                                                UnitGroup[i].special == 82)) { //Ice
                    UnitGroup[i].defense = UnitGroup[i].defense*2;
                } else if (_weather == 6 && (   UnitGroup[i].special == 8 || 
                                                UnitGroup[i].special == 9 || 
                                                UnitGroup[i].special == 11 || 
                                                UnitGroup[i].special == 18 || 
                                                UnitGroup[i].special == 32 || 
                                                UnitGroup[i].special == 33 || 
                                                UnitGroup[i].special == 36 || 
                                                UnitGroup[i].special == 44 || 
                                                UnitGroup[i].special == 54 || 
                                                UnitGroup[i].special == 56 || 
                                                UnitGroup[i].special == 58 || 
                                                UnitGroup[i].special == 70 || 
                                                UnitGroup[i].special == 74 || 
                                                UnitGroup[i].special == 78 || 
                                                UnitGroup[i].special == 84 || 
                                                UnitGroup[i].special == 88)) { //Dark
                    UnitGroup[i].hp = UnitGroup[i].hp*2;
                } else if (_weather == 5 && (   UnitGroup[i].special == 6 || 
                                                UnitGroup[i].special == 34 || 
                                                UnitGroup[i].special == 40 || 
                                                UnitGroup[i].special == 48 || 
                                                UnitGroup[i].special == 77 || 
                                                UnitGroup[i].special == 89 || 
                                                UnitGroup[i].special == 99)) { //Light
                    UnitGroup[i].speed = UnitGroup[i].speed*2;
                }
            }

    }

 /*   function calibrate() public returns (S.Unit[6] memory UnitGroup) {
        S.Unit[6] memory _UnitGroup;
        uint[5] memory _outfitsID; uint[5] memory _outfitBalance;

        _outfitsID[0] = 3015;
        _outfitsID[1] = 6020;
        _outfitsID[2] = 1133;
        _outfitsID[3] = 1140;
        _outfitsID[4] = 1147;

        _outfitBalance[0] = 1;
        _outfitBalance[1] = 2;
        _outfitBalance[2] = 3;
        _outfitBalance[3] = 4;
        _outfitBalance[4] = 5;

        UnitGroup = TrainersOutfitBonus(_UnitGroup, _outfitsID,_outfitBalance);
    }*/
    
    
    function TrainersOutfitBonus (S.Unit[6] memory _UnitGroup, uint[5] memory _outfitsID, uint[5] memory _outfitBalance) 
                internal pure returns (S.Unit[6] memory UnitGroup) {
        //_outfit[0~4] is outfit ID for the trainer ID. (what to wear) ID 0 means wearing nothing
        //[0] = Aerobot  [1] = headgear  [2] = Body   [3] = Leggings  [4 = Boots
        UnitGroup = _UnitGroup;
        //convert Outfit balance into Multiplier
        for (uint i=0; i<5; i++) {
            if (_outfitBalance[i] >= 4096) {
                _outfitBalance[i] = 5;
            } else if (_outfitBalance[i] >= 512) {
                _outfitBalance[i] = 4;
            } else if (_outfitBalance[i] >= 64) {
                _outfitBalance[i] = 3;
            } else if (_outfitBalance[i] >= 8) {
                _outfitBalance[i] = 2;
            } else if (_outfitBalance[i] >= 1) {
                _outfitBalance[i] = 1;
            } //otherwise = 0, multiplier =0
        }
        S.Unit memory Bonus;

        //Get Bonus from each outfit
       //==========   AEROBOT ======================
        if (_outfitsID[0] == 3001) { //Bolt (Aerobot) //spd + 6
            Bonus.speed += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3002) { //Pixi (Aerobot) //atk + 6
            Bonus.attack += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3003) { //Finspark (Aerobot) //SPD + 10
            Bonus.speed += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3004) { //Cyanite //ATK + 10
            Bonus.attack += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3005) { //Daemon //all (20, 2, 2, 2, 1)
            Bonus.hp += (20 * _outfitBalance[0]);
            Bonus.attack += (2 * _outfitBalance[0]);
            Bonus.defense += (2 * _outfitBalance[0]);
            Bonus.speed += (2 * _outfitBalance[0]);
            Bonus.intelligence += (1 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3006) { //Skye //Int +4
            Bonus.intelligence += (4 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3007) { //Cocoon //int +3
            Bonus.intelligence += (3 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3008) { //Orbitron //Spd +8
            Bonus.speed += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3009) { //Glide //Atk +8
            Bonus.attack += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3010) { //Bolt Mark II //Def + 8
            Bonus.defense += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3011) { //Lovey //Hp + 80
            Bonus.hp += (80 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3012) { //Zetabot //hp + 60
            Bonus.hp += (60 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3013) { //Roxie //def + 6
            Bonus.defense += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3014) { //Puzzle //INT + 5
            Bonus.intelligence += (5 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3015) { //Aura //all (20, 2, 2, 2, 1)
            Bonus.hp += (20 * _outfitBalance[0]);
            Bonus.attack += (2 * _outfitBalance[0]);
            Bonus.defense += (2 * _outfitBalance[0]);
            Bonus.speed += (2 * _outfitBalance[0]);
            Bonus.intelligence += (1 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3016) { //Goldon //DEF + 10
            Bonus.defense += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3017) { //Meteoron //HP + 100
            Bonus.hp += (100 * _outfitBalance[0]);
        }

       //==========   Headgear ======================
        if (_outfitsID[1] == 6001) { //headgear 1 //hp+50
            Bonus.hp += (50 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6002) { //headgear 2 //atk+3
            Bonus.attack += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6003) { //headgear 3 //def+3
            Bonus.defense += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6004) { //headgear 4 //spd+3
            Bonus.speed += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6005) { //headgear 5 //int+1
            Bonus.intelligence += (1 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6006) { //headgear 6 //hp+60
            Bonus.hp += (60 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6007) { //headgear 7 //atk+6
            Bonus.attack += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6008) { //headgear 8 //def+6
            Bonus.defense += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6009) { //headgear 9 //spd+6
            Bonus.speed += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6010) { //headgear 10 //int+3
            Bonus.intelligence += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6011) { //headgear 11 //hp+80
            Bonus.hp += (80 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6012) { //headgear 12 //atk+8
            Bonus.attack += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6013) { //headgear 13 //def+8
            Bonus.defense += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6014) { //headgear 14 //spd+8
            Bonus.speed += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6015) { //headgear 15 //int+4
            Bonus.intelligence += (4 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6016) { //headgear 16 //hp+100
            Bonus.hp += (100 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6017) { //headgear 17 //atk+10
            Bonus.attack += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6018) { //headgear 18 //def+10
            Bonus.defense += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6019) { //headgear 19 //spd+10
            Bonus.speed += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6020) { //headgear 20 //int+5
            Bonus.intelligence += (5 * _outfitBalance[1]);
        }
        
        //==========   Body ======================
        if (_outfitsID[2] == 1001) { //Scholar (Body) //hp 50
            Bonus.hp += (50 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1002) { //Scholar (Body) //atk 3
            Bonus.attack += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1003) { //Scholar (Body) //def 3
            Bonus.defense += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1004) { //Scholar (Body) //spd 3
            Bonus.speed += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1005) { //Scholar (Body) //int 1
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1006 || _outfitsID[2] == 1007) { //Scholar (Body) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[2]);
            Bonus.attack += (1 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1022) { //Love Embrace (Body) //hp 60
            Bonus.hp += (60 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1023) { //Love Embrace (Body) //atk 6
            Bonus.attack += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1024) { //Love Embrace (Body) //def 6
            Bonus.defense += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1025) { //Love Embrace (Body) //spd 6
            Bonus.speed += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1026) { //Love Embrace (Body) //int 3
            Bonus.intelligence += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1027 || _outfitsID[2] == 1028) { //Love Embrace (Body) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1043) { //Celestial Harmony (Body) //hp 80
            Bonus.hp += (80 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1044) { //Celestial Harmony (Body) //atk 8
            Bonus.attack += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1045) { //Celestial Harmony (Body) //def 8
            Bonus.defense += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1046) { //Celestial Harmony (Body) //spd 8
            Bonus.speed += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1047) { //Celestial Harmony (Body) //int 4
            Bonus.intelligence += (4 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1048 || _outfitsID[2] == 1049) { //Celestial Harmony (Body) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1064) { //Cyber Strike (Body) //hp 80
            Bonus.hp += (80 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1065) { //Cyber Strike (Body) //atk 8
            Bonus.attack += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1066) { //Cyber Strike (Body) //def 8
            Bonus.defense += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1067) { //Cyber Strike (Body) //spd 8
            Bonus.speed += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1068) { //Cyber Strike (Body) //int 4
            Bonus.intelligence += (4 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1069 || _outfitsID[2] == 1070) { //Cyber Strike (Body) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1085) { //Serpent Tribe (Body) //hp 50
            Bonus.hp += (50 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1086) { //Serpent Tribe (Body) //atk 3
            Bonus.attack += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1087) { //Serpent Tribe (Body) //def 3
            Bonus.defense += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1088) { //Serpent Tribe (Body) //spd 3
            Bonus.speed += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1089) { //Serpent Tribe (Body) //int 1
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1090 || _outfitsID[2] == 1091) { //Serpent Tribe (Body) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[2]);
            Bonus.attack += (1 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1106) { //Pearl Empress (Body) //hp 60
            Bonus.hp += (60 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1107) { //Pearl Empress (Body) //atk 6
            Bonus.attack += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1108) { //Pearl Empress (Body) //def 6
            Bonus.defense += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1109) { //Pearl Empress (Body) //spd 6
            Bonus.speed += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1110) { //Pearl Empress (Body) //int 3
            Bonus.intelligence += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1111 || _outfitsID[2] == 1112) { //Pearl Empress (Body) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1127) { //Starlight Diva (Body) //hp 100
            Bonus.hp += (100 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1128) { //Starlight Diva (Body) //atk 10
            Bonus.attack += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1129) { //Starlight Diva (Body) //def 10
            Bonus.defense += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1130) { //Starlight Diva (Body) //spd 10
            Bonus.speed += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1131) { //Starlight Diva (Body) //int 5
            Bonus.intelligence += (5 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1132 || _outfitsID[2] == 1133) { //Starlight Diva (Body) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (2 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        }
        
        //========== Leggings======================
        if (_outfitsID[3] == 1008) { //Scholar (Leggings) //hp 50
            Bonus.hp += (50 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1009) { //Scholar (Leggings) //atk 3
            Bonus.attack += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1010) { //Scholar (Leggings) //def 3
            Bonus.defense += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1011) { //Scholar (Leggings) //spd 3
            Bonus.speed += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1012) { //Scholar (Leggings) //int 1
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1013 || _outfitsID[3] == 1014) { //Scholar (Leggings) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[3]);
            Bonus.attack += (1 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1029) { //Love Embrace (Leggings) //hp 60
            Bonus.hp += (60 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1030) { //Love Embrace (Leggings) //atk 6
            Bonus.attack += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1031) { //Love Embrace (Leggings) //def 6
            Bonus.defense += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1032) { //Love Embrace (Leggings) //spd 6
            Bonus.speed += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1033) { //Love Embrace (Leggings) //int 3
            Bonus.intelligence += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1034 || _outfitsID[3] == 1035) { //Love Embrace (Leggings) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1050) { //Celestial Harmony (Leggings) //hp 80
            Bonus.hp += (80 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1051) { //Celestial Harmony (Leggings) //atk 8
            Bonus.attack += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1052) { //Celestial Harmony (Leggings) //def 8
            Bonus.defense += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1053) { //Celestial Harmony (Leggings) //spd 8
            Bonus.speed += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1054) { //Celestial Harmony (Leggings) //int 4
            Bonus.intelligence += (4 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1055 || _outfitsID[3] == 1056) { //Celestial Harmony (Leggings) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1071) { //Cyber Strike (Leggings) //hp 80
            Bonus.hp += (80 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1072) { //Cyber Strike (Leggings) //atk 8
            Bonus.attack += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1073) { //Cyber Strike (Leggings) //def 8
            Bonus.defense += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1074) { //Cyber Strike (Leggings) //spd 8
            Bonus.speed += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1075) { //Cyber Strike (Leggings) //int 4
            Bonus.intelligence += (4 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1076 || _outfitsID[3] == 1077) { //Cyber Strike (Leggings) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1092) { //Serpent Tribe (Leggings) //hp 50
            Bonus.hp += (50 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1093) { //Serpent Tribe (Leggings) //atk 3
            Bonus.attack += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1094) { //Serpent Tribe (Leggings) //def 3
            Bonus.defense += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1095) { //Serpent Tribe (Leggings) //spd 3
            Bonus.speed += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1096) { //Serpent Tribe (Leggings) //int 1
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1097 || _outfitsID[3] == 1098) { //Serpent Tribe (Leggings) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[3]);
            Bonus.attack += (1 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1113) { //Pearl Empress (Leggings) //hp 60
            Bonus.hp += (60 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1114) { //Pearl Empress (Leggings) //atk 6
            Bonus.attack += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1115) { //Pearl Empress (Leggings) //def 6
            Bonus.defense += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1116) { //Pearl Empress (Leggings) //spd 6
            Bonus.speed += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1117) { //Pearl Empress (Leggings) //int 3
            Bonus.intelligence += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1118 || _outfitsID[3] == 1119) { //Pearl Empress (Leggings) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1134) { //Starlight Diva (Leggings) //hp 100
            Bonus.hp += (100 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1135) { //Starlight Diva (Leggings) //atk 10
            Bonus.attack += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1136) { //Starlight Diva (Leggings) //def 10
            Bonus.defense += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1137) { //Starlight Diva (Leggings) //spd 10
            Bonus.speed += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1138) { //Starlight Diva (Leggings) //int 5
            Bonus.intelligence += (5 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1139 || _outfitsID[3] == 1140) { //Starlight Diva (Leggings) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (2 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        }

        //========== Boots======================
        if (_outfitsID[4] == 1015) { //Scholar (Boots) //hp 50
            Bonus.hp += (50 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1016) { //Scholar (Boots) //atk 3
            Bonus.attack += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1017) { //Scholar (Boots) //def 3
            Bonus.defense += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1018) { //Scholar (Boots) //spd 3
            Bonus.speed += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1019) { //Scholar (Boots) //int 1
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1020 || _outfitsID[4] == 1021) { //Scholar (Boots) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[4]);
            Bonus.attack += (1 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1036) { //Love Embrace (Boots) //hp 60
            Bonus.hp += (60 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1037) { //Love Embrace (Boots) //atk 6
            Bonus.attack += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1038) { //Love Embrace (Boots) //def 6
            Bonus.defense += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1039) { //Love Embrace (Boots) //spd 6
            Bonus.speed += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1040) { //Love Embrace (Boots) //int 3
            Bonus.intelligence += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1041 || _outfitsID[4] == 1042) { //Love Embrace (Boots) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1057) { //Celestial Harmony (Boots) //hp 80
            Bonus.hp += (80 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1058) { //Celestial Harmony (Boots) //atk 8
            Bonus.attack += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1059) { //Celestial Harmony (Boots) //def 8
            Bonus.defense += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1060) { //Celestial Harmony (Boots) //spd 8
            Bonus.speed += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1061) { //Celestial Harmony (Boots) //int 4
            Bonus.intelligence += (4 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1062 || _outfitsID[4] == 1063) { //Celestial Harmony (Boots) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1078) { //Cyber Strike (Boots) //hp 80
            Bonus.hp += (80 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1079) { //Cyber Strike (Boots) //atk 8
            Bonus.attack += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1080) { //Cyber Strike (Boots) //def 8
            Bonus.defense += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1081) { //Cyber Strike (Boots) //spd 8
            Bonus.speed += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1082) { //Cyber Strike (Boots) //int 4
            Bonus.intelligence += (4 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1083 || _outfitsID[4] == 1084) { //Cyber Strike (Boots) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1099) { //Serpent Tribe (Boots) //hp 50
            Bonus.hp += (50 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1100) { //Serpent Tribe (Boots) //atk 3
            Bonus.attack += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1101) { //Serpent Tribe (Boots) //def 3
            Bonus.defense += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1102) { //Serpent Tribe (Boots) //spd 3
            Bonus.speed += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1103) { //Serpent Tribe (Boots) //int 1
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1104 || _outfitsID[4] == 1105) { //Serpent Tribe (Boots) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[4]);
            Bonus.attack += (1 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1120) { //Pearl Empress (Boots) //hp 60
            Bonus.hp += (60 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1121) { //Pearl Empress (Boots) //atk 6
            Bonus.attack += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1122) { //Pearl Empress (Boots) //def 6
            Bonus.defense += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1123) { //Pearl Empress (Boots) //spd 6
            Bonus.speed += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1124) { //Pearl Empress (Boots) //int 3
            Bonus.intelligence += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1125 || _outfitsID[4] == 1126) { //Pearl Empress (Boots) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1141) { //Starlight Diva (Boots) //hp 100
            Bonus.hp += (100 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1142) { //Starlight Diva (Boots) //atk 10
            Bonus.attack += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1143) { //Starlight Diva (Boots) //def 10
            Bonus.defense += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1144) { //Starlight Diva (Boots) //spd 10
            Bonus.speed += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1145) { //Starlight Diva (Boots) //int 5
            Bonus.intelligence += (5 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1146 || _outfitsID[4] == 1147) { //Starlight Diva (Boots) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (2 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        }

        for (uint i=0; i<3; i++) {
            if (UnitGroup[i].hp >0 ) { //not empty slot
                UnitGroup[i].hp = _UnitGroup[i].hp += Bonus.hp;
                UnitGroup[i].attack = _UnitGroup[i].attack += Bonus.attack;
                UnitGroup[i].defense = _UnitGroup[i].defense += Bonus.defense;
                UnitGroup[i].speed = _UnitGroup[i].speed += Bonus.speed;
                UnitGroup[i].intelligence = _UnitGroup[i].intelligence += Bonus.intelligence;
            }
           
        }

    }


    
    function readOutfitBonus (uint[5] memory _outfitsID, uint[5] memory _outfitBalance) 
                internal pure returns (S.Unit memory Bonus) {
        //_outfit[0~4] is outfit ID for the trainer ID. (what to wear) ID 0 means wearing nothing
        //[0] = Aerobot  [1] = headgear  [2] = Body   [3] = Leggings  [4 = Boots
        
        //convert Outfit balance into Multiplier
        for (uint i=0; i<5; i++) {
            if (_outfitBalance[i] >= 4096) {
                _outfitBalance[i] = 5;
            } else if (_outfitBalance[i] >= 512) {
                _outfitBalance[i] = 4;
            } else if (_outfitBalance[i] >= 64) {
                _outfitBalance[i] = 3;
            } else if (_outfitBalance[i] >= 8) {
                _outfitBalance[i] = 2;
            } else if (_outfitBalance[i] >= 1) {
                _outfitBalance[i] = 1;
            } //otherwise = 0, multiplier =0
        }

        //Get Bonus from each outfit
       //==========   AEROBOT ======================
        if (_outfitsID[0] == 3001) { //Bolt (Aerobot) //spd + 6
            Bonus.speed += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3002) { //Pixi (Aerobot) //atk + 6
            Bonus.attack += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3003) { //Finspark (Aerobot) //SPD + 10
            Bonus.speed += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3004) { //Cyanite //ATK + 10
            Bonus.attack += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3005) { //Daemon //all (20, 2, 2, 2, 1)
            Bonus.hp += (20 * _outfitBalance[0]);
            Bonus.attack += (2 * _outfitBalance[0]);
            Bonus.defense += (2 * _outfitBalance[0]);
            Bonus.speed += (2 * _outfitBalance[0]);
            Bonus.intelligence += (1 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3006) { //Skye //Int +4
            Bonus.intelligence += (4 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3007) { //Cocoon //int +3
            Bonus.intelligence += (3 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3008) { //Orbitron //Spd +8
            Bonus.speed += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3009) { //Glide //Atk +8
            Bonus.attack += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3010) { //Bolt Mark II //Def + 8
            Bonus.defense += (8 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3011) { //Lovey //Hp + 80
            Bonus.hp += (80 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3012) { //Zetabot //hp + 60
            Bonus.hp += (60 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3013) { //Roxie //def + 6
            Bonus.defense += (6 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3014) { //Puzzle //INT + 5
            Bonus.intelligence += (5 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3015) { //Aura //all (20, 2, 2, 2, 1)
            Bonus.hp += (20 * _outfitBalance[0]);
            Bonus.attack += (2 * _outfitBalance[0]);
            Bonus.defense += (2 * _outfitBalance[0]);
            Bonus.speed += (2 * _outfitBalance[0]);
            Bonus.intelligence += (1 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3016) { //Goldon //DEF + 10
            Bonus.defense += (10 * _outfitBalance[0]);
        } else if (_outfitsID[0] == 3017) { //Meteoron //HP + 100
            Bonus.hp += (100 * _outfitBalance[0]);
        }

       //==========   Headgear ======================
        if (_outfitsID[1] == 6001) { //headgear 1 //hp+50
            Bonus.hp += (50 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6002) { //headgear 2 //atk+3
            Bonus.attack += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6003) { //headgear 3 //def+3
            Bonus.defense += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6004) { //headgear 4 //spd+3
            Bonus.speed += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6005) { //headgear 5 //int+1
            Bonus.intelligence += (1 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6006) { //headgear 6 //hp+60
            Bonus.hp += (60 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6007) { //headgear 7 //atk+6
            Bonus.attack += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6008) { //headgear 8 //def+6
            Bonus.defense += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6009) { //headgear 9 //spd+6
            Bonus.speed += (6 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6010) { //headgear 10 //int+3
            Bonus.intelligence += (3 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6011) { //headgear 11 //hp+80
            Bonus.hp += (80 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6012) { //headgear 12 //atk+8
            Bonus.attack += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6013) { //headgear 13 //def+8
            Bonus.defense += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6014) { //headgear 14 //spd+8
            Bonus.speed += (8 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6015) { //headgear 15 //int+4
            Bonus.intelligence += (4 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6016) { //headgear 16 //hp+100
            Bonus.hp += (100 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6017) { //headgear 17 //atk+10
            Bonus.attack += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6018) { //headgear 18 //def+10
            Bonus.defense += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6019) { //headgear 19 //spd+10
            Bonus.speed += (10 * _outfitBalance[1]);
        } else if (_outfitsID[1] == 6020) { //headgear 20 //int+5
            Bonus.intelligence += (5 * _outfitBalance[1]);
        }
        
        //==========   Body ======================
        if (_outfitsID[2] == 1001) { //Scholar (Body) //hp 50
            Bonus.hp += (50 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1002) { //Scholar (Body) //atk 3
            Bonus.attack += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1003) { //Scholar (Body) //def 3
            Bonus.defense += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1004) { //Scholar (Body) //spd 3
            Bonus.speed += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1005) { //Scholar (Body) //int 1
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1006 || _outfitsID[2] == 1007) { //Scholar (Body) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[2]);
            Bonus.attack += (1 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1022) { //Love Embrace (Body) //hp 60
            Bonus.hp += (60 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1023) { //Love Embrace (Body) //atk 6
            Bonus.attack += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1024) { //Love Embrace (Body) //def 6
            Bonus.defense += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1025) { //Love Embrace (Body) //spd 6
            Bonus.speed += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1026) { //Love Embrace (Body) //int 3
            Bonus.intelligence += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1027 || _outfitsID[2] == 1028) { //Love Embrace (Body) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1043) { //Celestial Harmony (Body) //hp 80
            Bonus.hp += (80 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1044) { //Celestial Harmony (Body) //atk 8
            Bonus.attack += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1045) { //Celestial Harmony (Body) //def 8
            Bonus.defense += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1046) { //Celestial Harmony (Body) //spd 8
            Bonus.speed += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1047) { //Celestial Harmony (Body) //int 4
            Bonus.intelligence += (4 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1048 || _outfitsID[2] == 1049) { //Celestial Harmony (Body) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1064) { //Cyber Strike (Body) //hp 80
            Bonus.hp += (80 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1065) { //Cyber Strike (Body) //atk 8
            Bonus.attack += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1066) { //Cyber Strike (Body) //def 8
            Bonus.defense += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1067) { //Cyber Strike (Body) //spd 8
            Bonus.speed += (8 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1068) { //Cyber Strike (Body) //int 4
            Bonus.intelligence += (4 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1069 || _outfitsID[2] == 1070) { //Cyber Strike (Body) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1085) { //Serpent Tribe (Body) //hp 50
            Bonus.hp += (50 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1086) { //Serpent Tribe (Body) //atk 3
            Bonus.attack += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1087) { //Serpent Tribe (Body) //def 3
            Bonus.defense += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1088) { //Serpent Tribe (Body) //spd 3
            Bonus.speed += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1089) { //Serpent Tribe (Body) //int 1
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1090 || _outfitsID[2] == 1091) { //Serpent Tribe (Body) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[2]);
            Bonus.attack += (1 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1106) { //Pearl Empress (Body) //hp 60
            Bonus.hp += (60 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1107) { //Pearl Empress (Body) //atk 6
            Bonus.attack += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1108) { //Pearl Empress (Body) //def 6
            Bonus.defense += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1109) { //Pearl Empress (Body) //spd 6
            Bonus.speed += (6 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1110) { //Pearl Empress (Body) //int 3
            Bonus.intelligence += (3 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1111 || _outfitsID[2] == 1112) { //Pearl Empress (Body) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (1 * _outfitBalance[2]);
            Bonus.speed += (1 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1127) { //Starlight Diva (Body) //hp 100
            Bonus.hp += (100 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1128) { //Starlight Diva (Body) //atk 10
            Bonus.attack += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1129) { //Starlight Diva (Body) //def 10
            Bonus.defense += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1130) { //Starlight Diva (Body) //spd 10
            Bonus.speed += (10 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1131) { //Starlight Diva (Body) //int 5
            Bonus.intelligence += (5 * _outfitBalance[2]);
        } else if (_outfitsID[2] == 1132 || _outfitsID[2] == 1133) { //Starlight Diva (Body) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[2]);
            Bonus.attack += (2 * _outfitBalance[2]);
            Bonus.defense += (2 * _outfitBalance[2]);
            Bonus.speed += (2 * _outfitBalance[2]);
            Bonus.intelligence += (1 * _outfitBalance[2]);
        }
        
        //========== Leggings======================
        if (_outfitsID[3] == 1008) { //Scholar (Leggings) //hp 50
            Bonus.hp += (50 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1009) { //Scholar (Leggings) //atk 3
            Bonus.attack += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1010) { //Scholar (Leggings) //def 3
            Bonus.defense += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1011) { //Scholar (Leggings) //spd 3
            Bonus.speed += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1012) { //Scholar (Leggings) //int 1
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1013 || _outfitsID[3] == 1014) { //Scholar (Leggings) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[3]);
            Bonus.attack += (1 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1029) { //Love Embrace (Leggings) //hp 60
            Bonus.hp += (60 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1030) { //Love Embrace (Leggings) //atk 6
            Bonus.attack += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1031) { //Love Embrace (Leggings) //def 6
            Bonus.defense += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1032) { //Love Embrace (Leggings) //spd 6
            Bonus.speed += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1033) { //Love Embrace (Leggings) //int 3
            Bonus.intelligence += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1034 || _outfitsID[3] == 1035) { //Love Embrace (Leggings) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1050) { //Celestial Harmony (Leggings) //hp 80
            Bonus.hp += (80 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1051) { //Celestial Harmony (Leggings) //atk 8
            Bonus.attack += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1052) { //Celestial Harmony (Leggings) //def 8
            Bonus.defense += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1053) { //Celestial Harmony (Leggings) //spd 8
            Bonus.speed += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1054) { //Celestial Harmony (Leggings) //int 4
            Bonus.intelligence += (4 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1055 || _outfitsID[3] == 1056) { //Celestial Harmony (Leggings) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1071) { //Cyber Strike (Leggings) //hp 80
            Bonus.hp += (80 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1072) { //Cyber Strike (Leggings) //atk 8
            Bonus.attack += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1073) { //Cyber Strike (Leggings) //def 8
            Bonus.defense += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1074) { //Cyber Strike (Leggings) //spd 8
            Bonus.speed += (8 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1075) { //Cyber Strike (Leggings) //int 4
            Bonus.intelligence += (4 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1076 || _outfitsID[3] == 1077) { //Cyber Strike (Leggings) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1092) { //Serpent Tribe (Leggings) //hp 50
            Bonus.hp += (50 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1093) { //Serpent Tribe (Leggings) //atk 3
            Bonus.attack += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1094) { //Serpent Tribe (Leggings) //def 3
            Bonus.defense += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1095) { //Serpent Tribe (Leggings) //spd 3
            Bonus.speed += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1096) { //Serpent Tribe (Leggings) //int 1
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1097 || _outfitsID[3] == 1098) { //Serpent Tribe (Leggings) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[3]);
            Bonus.attack += (1 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1113) { //Pearl Empress (Leggings) //hp 60
            Bonus.hp += (60 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1114) { //Pearl Empress (Leggings) //atk 6
            Bonus.attack += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1115) { //Pearl Empress (Leggings) //def 6
            Bonus.defense += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1116) { //Pearl Empress (Leggings) //spd 6
            Bonus.speed += (6 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1117) { //Pearl Empress (Leggings) //int 3
            Bonus.intelligence += (3 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1118 || _outfitsID[3] == 1119) { //Pearl Empress (Leggings) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (1 * _outfitBalance[3]);
            Bonus.speed += (1 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1134) { //Starlight Diva (Leggings) //hp 100
            Bonus.hp += (100 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1135) { //Starlight Diva (Leggings) //atk 10
            Bonus.attack += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1136) { //Starlight Diva (Leggings) //def 10
            Bonus.defense += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1137) { //Starlight Diva (Leggings) //spd 10
            Bonus.speed += (10 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1138) { //Starlight Diva (Leggings) //int 5
            Bonus.intelligence += (5 * _outfitBalance[3]);
        } else if (_outfitsID[3] == 1139 || _outfitsID[3] == 1140) { //Starlight Diva (Leggings) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[3]);
            Bonus.attack += (2 * _outfitBalance[3]);
            Bonus.defense += (2 * _outfitBalance[3]);
            Bonus.speed += (2 * _outfitBalance[3]);
            Bonus.intelligence += (1 * _outfitBalance[3]);
        }

        //========== Boots======================
        if (_outfitsID[4] == 1015) { //Scholar (Boots) //hp 50
            Bonus.hp += (50 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1016) { //Scholar (Boots) //atk 3
            Bonus.attack += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1017) { //Scholar (Boots) //def 3
            Bonus.defense += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1018) { //Scholar (Boots) //spd 3
            Bonus.speed += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1019) { //Scholar (Boots) //int 1
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1020 || _outfitsID[4] == 1021) { //Scholar (Boots) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[4]);
            Bonus.attack += (1 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1036) { //Love Embrace (Boots) //hp 60
            Bonus.hp += (60 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1037) { //Love Embrace (Boots) //atk 6
            Bonus.attack += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1038) { //Love Embrace (Boots) //def 6
            Bonus.defense += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1039) { //Love Embrace (Boots) //spd 6
            Bonus.speed += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1040) { //Love Embrace (Boots) //int 3
            Bonus.intelligence += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1041 || _outfitsID[4] == 1042) { //Love Embrace (Boots) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1057) { //Celestial Harmony (Boots) //hp 80
            Bonus.hp += (80 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1058) { //Celestial Harmony (Boots) //atk 8
            Bonus.attack += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1059) { //Celestial Harmony (Boots) //def 8
            Bonus.defense += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1060) { //Celestial Harmony (Boots) //spd 8
            Bonus.speed += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1061) { //Celestial Harmony (Boots) //int 4
            Bonus.intelligence += (4 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1062 || _outfitsID[4] == 1063) { //Celestial Harmony (Boots) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1078) { //Cyber Strike (Boots) //hp 80
            Bonus.hp += (80 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1079) { //Cyber Strike (Boots) //atk 8
            Bonus.attack += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1080) { //Cyber Strike (Boots) //def 8
            Bonus.defense += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1081) { //Cyber Strike (Boots) //spd 8
            Bonus.speed += (8 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1082) { //Cyber Strike (Boots) //int 4
            Bonus.intelligence += (4 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1083 || _outfitsID[4] == 1084) { //Cyber Strike (Boots) //all (16,2,2,1,1)
            Bonus.hp += (16 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1099) { //Serpent Tribe (Boots) //hp 50
            Bonus.hp += (50 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1100) { //Serpent Tribe (Boots) //atk 3
            Bonus.attack += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1101) { //Serpent Tribe (Boots) //def 3
            Bonus.defense += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1102) { //Serpent Tribe (Boots) //spd 3
            Bonus.speed += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1103) { //Serpent Tribe (Boots) //int 1
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1104 || _outfitsID[4] == 1105) { //Serpent Tribe (Boots) //all (10,1,1,1,1)
            Bonus.hp += (10 * _outfitBalance[4]);
            Bonus.attack += (1 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1120) { //Pearl Empress (Boots) //hp 60
            Bonus.hp += (60 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1121) { //Pearl Empress (Boots) //atk 6
            Bonus.attack += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1122) { //Pearl Empress (Boots) //def 6
            Bonus.defense += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1123) { //Pearl Empress (Boots) //spd 6
            Bonus.speed += (6 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1124) { //Pearl Empress (Boots) //int 3
            Bonus.intelligence += (3 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1125 || _outfitsID[4] == 1126) { //Pearl Empress (Boots) //all (12,2,1,1,1)
            Bonus.hp += (12 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (1 * _outfitBalance[4]);
            Bonus.speed += (1 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1141) { //Starlight Diva (Boots) //hp 100
            Bonus.hp += (100 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1142) { //Starlight Diva (Boots) //atk 10
            Bonus.attack += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1143) { //Starlight Diva (Boots) //def 10
            Bonus.defense += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1144) { //Starlight Diva (Boots) //spd 10
            Bonus.speed += (10 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1145) { //Starlight Diva (Boots) //int 5
            Bonus.intelligence += (5 * _outfitBalance[4]);
        } else if (_outfitsID[4] == 1146 || _outfitsID[4] == 1147) { //Starlight Diva (Boots) //all (20,2,2,2,1)
            Bonus.hp += (20 * _outfitBalance[4]);
            Bonus.attack += (2 * _outfitBalance[4]);
            Bonus.defense += (2 * _outfitBalance[4]);
            Bonus.speed += (2 * _outfitBalance[4]);
            Bonus.intelligence += (1 * _outfitBalance[4]);
        }


    }






}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

// File: FINALdeployFA/INTERFACE - StorageV2.sol


pragma solidity ^0.8.20;

// Import your custom structs


/**
 * @title IFARPG_Storage
 * @dev Interface for FARPG_Storage so other contracts can call it
 */
interface IFARPG_Storage {
    //-------------------------------------------------------------------------
    // Administrative / Master Contract Access
    //-------------------------------------------------------------------------
    function owner() external view returns (address);
    function masterContracts(uint index) external view returns (address);
    function masterIndex(address) external view returns (uint);
    function addMasterContract(address _address, uint _index) external;
    function addMasterContractBatch(address[] memory _addresses, uint[] memory _indices) external;
    function removeMasterContract(uint _index) external;
    function getAllMasterContracts() external view returns (address[] memory, uint[] memory);

    //-------------------------------------------------------------------------
    // UID Management
    //-------------------------------------------------------------------------
    function UIDmain(address) external view returns (uint);
    function UID_ownedby(uint) external view returns (address);
    function UIDcounter() external view returns (uint);
    function getUID(address player) external view returns (uint _UID);
    function transferUID(address player, address newplayerwallet) external;
    function registerUID(address player) external;

    function setUIDmain (address playerAddress, uint UID) external;
    function setUID_ownedby (uint UID, address playerAddress) external;

    //-------------------------------------------------------------------------
    // Quest (setters)
    //-------------------------------------------------------------------------
    function setMainQuest(address player, uint index, uint8 progress) external;
    function setSideQuest(address player, uint index, uint8 progress) external;
    function setPremiumScore(address player, uint score) external;
    function setPlayerGeneStrength(address player, uint index, uint strength) external;
    function setPlayerVitamin(address player, uint index, uint amount) external;

    //-------------------------------------------------------------------------
    // Quest (getters)
    //-------------------------------------------------------------------------
    function getMainQuestProgress(address player, uint index) external view returns (uint8);
    function getSideQuestProgress(address player, uint index) external view returns (uint8);
    function getPremiumScore(address player) external view returns (uint);
    function getPlayerQuestAndScore(address player, uint index) external view returns (uint, uint, uint);
    function getMainQuestProgressArray(address player) external view returns (uint8[64] memory);
    function getSideQuestProgressArray(address player) external view returns (uint8[64] memory);


    //-------------------------------------------------------------------------
    // Player Stats (setters)
    //-------------------------------------------------------------------------
    function setPersonalWallet(address player, address personal) external;
    function setGiveControlTo(address player, address web2wallet) external;
    function setExp(address player, uint experience) external;
    function setRankScore(address player, uint score) external;
    function setEnergy1(address player, uint energy) external;
    function setEnergy2(address player, uint energy) external;
    function setEnergy22(address player, uint energy) external;
    function setEnergy3(address player, uint energy) external;
    function setTeamFormat(address player, uint[60] calldata format) external;
    function setUsernameToUID(string memory username, uint _UID) external;
    function setUIDToUsername(uint _UID, string memory username) external;
    function deleteUsernameToAddress (string memory username) external;

    // Points
    function setPoint1(address player, uint point) external;
    function setPoint2(address player, uint point) external;
    function setPoint3(address player, uint point) external;
    function setPoint4(address player, uint point) external;
    function setPoint5(address player, uint point) external;
    function addPoint1(address player, uint point) external;
    function addPoint2(address player, uint point) external;
    function addPoint3(address player, uint point) external;
    function addPoint4(address player, uint point) external;
    function addPoint5(address player, uint point) external;

    //-------------------------------------------------------------------------
    // Player Stats (getters)
    //-------------------------------------------------------------------------
    function personalwallet(address) external view returns (address);
    function givecontrolto(address) external view returns (address);
    function getExperience(address player) external view returns (uint);
    function getRankingScore(address player) external view returns (uint);
    function getEnergy1(address player) external view returns (uint);
    function getEnergy2(address player) external view returns (uint);
    function getEnergy22(address player) external view returns (uint);
    function getEnergy3(address player) external view returns (uint);
    function getPlayerStats(address player) external view returns (uint, uint, uint, uint, uint, uint);
    function UIDToUsername(uint) external view returns (string memory);
    function usernameToUID(string memory) external view returns (uint);
    function getPoint1(address player) external view returns (uint);
    function getPoint2(address player) external view returns (uint);
    function getPoint3(address player) external view returns (uint);
    function getPoint4(address player) external view returns (uint);
    function getPoint5(address player) external view returns (uint);
    function getPlayerPoints(address player) external view returns (uint, uint, uint, uint, uint);
    function getPlayergenestrengthArray(address player) external view returns (uint[50] memory);
    function getPlayerGeneStrength(address player, uint index) external view returns (uint);
    function getPlayervitaminArray(address player) external view returns (uint[50] memory);
    function getPlayerVitamin(address player, uint index) external view returns (uint);
    //-------------------------------------------------------------------------
    // Limits (setters)
    //-------------------------------------------------------------------------
    function setLimit1(address player, uint limit) external;
    function setLimit2(address player, uint limit) external;
    function setLimit3(address player, uint limit) external;
    function setTimebound1(address player, uint timestamp) external;
    function setTimebound2(address player, uint timestamp) external;
    function setTimebound3(address player, uint timestamp) external;

    //-------------------------------------------------------------------------
    // Limits (getters)
    //-------------------------------------------------------------------------
    function getLimit1(address player) external view returns (uint);
    function getLimit2(address player) external view returns (uint);
    function getLimit3(address player) external view returns (uint);
    function getTimebound1(address player) external view returns (uint);
    function getTimebound2(address player) external view returns (uint);
    function getTimebound3(address player) external view returns (uint);
    function getPlayerLimits(address player) external view returns (uint, uint, uint, uint, uint, uint);

    //-------------------------------------------------------------------------
    // Numberset (setters)
    //-------------------------------------------------------------------------
    function setNumberSet1(address player, uint[6] memory number) external;
    function setNumberSet2(address player, uint[5] memory number) external;
    function setNumberSet3(address player, uint[5] memory number) external;
    function setNumberSet4(address player, uint[5] memory number) external;
    function setNumberSet5(address player, uint[5] memory number) external;
    function setNumberSet6(address player, uint[5] memory number) external;
    function setNumberSet7(address player, uint[5] memory number) external;
    function setNumberSet8(address player, uint[5] memory number) external;
    function setNumberSet9(address player, uint[5] memory number) external;
     function setNumberSetA(address player, uint[5] memory number) external; 
    function setNumberSetB(address player, uint[5] memory number) external; 
    function setNumberSetC(address player, uint[5] memory number) external; 
    function setNumberSetD(address player, uint[5] memory number) external; 
    function setNumberSetE(address player, uint[10] memory number) external; 
    function setNumberSetF(address player, uint[10] memory number) external; 
    function setNumberSetG(address player, uint[10] memory number) external; 
    function setNumberSetH(address player, uint[10] memory number) external;    

    //-------------------------------------------------------------------------
    // Numberset (getters)
    //-------------------------------------------------------------------------
    function getNumberSet1(address player) external view returns (uint[6] memory);
    function getNumberSet2(address player) external view returns (uint[5] memory);
    function getNumberSet3(address player) external view returns (uint[5] memory);
    function getNumberSet4(address player) external view returns (uint[5] memory);
    function getNumberSet5(address player) external view returns (uint[5] memory);
    function getNumberSet6(address player) external view returns (uint[5] memory);
    function getNumberSet7(address player) external view returns (uint[5] memory);
    function getNumberSet8(address player) external view returns (uint[5] memory);
    function getNumberSet9(address player) external view returns (uint[5] memory);
    function getNumberSetA(address player) external view returns (uint[5] memory);
    function getNumberSetB(address player) external view returns (uint[5] memory);
    function getNumberSetC(address player) external view returns (uint[5] memory);
    function getNumberSetD(address player) external view returns (uint[5] memory);
    function getNumberSetE(address player) external view returns (uint[10] memory);
    function getNumberSetF(address player) external view returns (uint[10] memory);
    function getNumberSetG(address player) external view returns (uint[10] memory);
    function getNumberSetH(address player) external view returns (uint[10] memory);
    
    //-------------------------------------------------------------------------
    // PVP Ranks
    //-------------------------------------------------------------------------
    struct Player {
        uint256 rankPoints;
        uint256 league;
        uint256 indexInLeague; // Index of the player within their league array
    }
    function setPlayers(address player, Player memory rankpointleagueindexinleague) external; 
    function setReset_Time_Attempts(address player, uint[2] memory resettimeattemps) external;  
    function setEligible_Opponents(address player, address[5] memory eligibleOppo) external;  
    function setFaught_Opponents(address player, uint[5] memory faughtOppo) external;  
    function setDefending_Formation(address player, uint[3] memory defendingslot) external;  
    function getPlayers(address player) external view returns (Player memory ) ;
    function getReset_Time_Attempts(address player ) external view returns (uint[2] memory );
    function getEligible_Opponents(address player  ) external view returns (address[5] memory);
    function getFaught_Opponents(address player ) external view returns(uint[5] memory) ;
    function getDefending_Formation(address player) external view returns (uint[3] memory );



    //-------------------------------------------------------------------------
    // Pet data (setters)
    //-------------------------------------------------------------------------
    function setPetUnits(address player, uint index, S.Unit memory newUnit) external;
    function setPetUnitsMaxVitamined(address player, uint index, S.Unit memory newUnit) external;
    function setPetStatuses(address player, uint index, S.Status memory newStatus) external;
    function setPetTimes(address player, uint index, S.Time memory newTime) external;

    //-------------------------------------------------------------------------
    // Pet data (getters)
    //-------------------------------------------------------------------------
    function getPetUnitsAll(address player) external view returns (S.Unit[500] memory);
    function getPetUnits(address player, uint _index) external view returns (S.Unit memory);
    function getPetUnitsMaxVitaminedAll(address player) external view returns (S.Unit[500] memory);
    function getPetUnitsMaxVitamined(address player, uint _index) external view returns (S.Unit memory);
    function getPetStatusesAll(address player) external view returns (S.Status[500] memory);
    function getPetStatuses(address player, uint _index) external view returns (S.Status memory);
    function getPetTimesAll(address player) external view returns (S.Time[500] memory);
    function getPetTimes(address player, uint _index) external view returns (S.Time memory);

    //-------------------------------------------------------------------------
    // Party / Outfit
    //-------------------------------------------------------------------------
    function setPartyFormation(address player, uint[30] memory slots) external;
    function setTrainerOutfitPosition(address player, uint[150] memory outfitIds) external;
    function getPartyFormation(address player) external view returns (uint[30] memory);
    function getAllOutfits(address player) external view returns (uint[150] memory);

    //-------------------------------------------------------------------------
    // Trainer Gene Infusing
    //-------------------------------------------------------------------------
    function setTrainerGeneInfusingGene(address player, uint index, uint value) external; 
    function setTrainerGeneInfusingGeneAll(address player, uint[50] memory newData) external;
    function setTrainerGeneInfusingTimer(address player, uint index, uint value) external; 
    function setTrainerGeneInfusingTimerAll(address player, uint[50] memory newData) external;

    function getTrainerGeneInfusingGeneAll(address player) external view returns (uint[50] memory) ;
    function getTrainerGeneInfusingTimerAll(address player) external view returns (uint[50] memory);
    function getTrainerGeneInfusingGene(address player, uint Index)external  view returns (uint ) ;
    function getTrainerGeneInfusingTimer(address player, uint Index)external  view returns (uint );


    //-------------------------------------------------------------------------
    // Additional Utility
    //-------------------------------------------------------------------------
    function getBattleUnit3(address player, uint[3] calldata slots)
        external
        view
        returns (S.Unit[3] memory Units3, uint[3] memory UnitIds);

    function getSlotUnitMore(address player, uint startindex, uint stopindex)
        external
        view
        returns (S.Unit[] memory Units, uint[] memory UnitIds);

    function getTeamFormat(address _addr) external view returns (uint[60] memory);

    //-------------------------------------------------------------------------
    // Weather System
    //-------------------------------------------------------------------------
    function getWeatherUnity() external view returns (uint _weather, uint _daylight, uint _blocktime);
    function getWeatherBattle(uint _timenow) external view returns (uint _weather);
    function setWeatherConstants(uint[12] memory _weatherIndices) external;
    function getWeatherIndexConstants() external view returns (uint[] memory);
}

// File: FINALdeployFA/PUBLIC - QuestSystemV1.sol


pragma solidity ^0.8.19;

//_______________________________________________________________
//    ___ __   __     _   ___      _   ___    _ __  
//   | _ )\ \ / /  _ | | / _ \  _ | | / _ \  (_)\ \ 
//   | _ \ \ V /  | || || (_) || || || (_) |  _  | |
//   |___/  |_|    \__/  \___/  \__/  \___/  ( ) | |
//                                           |/ /_/ 
//_______________________________________________________________






// Interface for accessing Storage
//-------------------------------------------------------------------
//    _____ _   _ _______ ______ _____  ______      _____ ______ 
//   |_   _| \ | |__   __|  ____|  __ \|  ____/\   / ____|  ____|
//     | | |  \| |  | |  | |__  | |__) | |__ /  \ | |    | |__   
//     | | | . ` |  | |  |  __| |  _  /|  __/ /\ \| |    |  __|  
//    _| |_| |\  |  | |  | |____| | \ \| | / ____ \ |____| |____ 
//   |_____|_| \_|  |_|  |______|_|  \_\_|/_/    \_\_____|______|
//                                                          
//-------------------------------------------------------------------

interface BattleV4 {
    //enum Weather { Sunny, Cloudy, Rainy, Thunderstorm, Snowy, Aurora, BloodMoon, NONE }
    function BattleV4_3v3(S.Unit[6] memory _UnitGroup) external 
    returns (uint BattleRhythm, uint bit, bool Won, uint randret);

    function Calibrate(uint index) external returns (uint, uint, bool, uint);
}
interface FARPG_RAMInterface {
    // Read functions
    struct TrainerData {
        uint gene;
        uint[50] genestrength;
        uint hashed;
    }
    function genetoid_mapping(uint trainergene) external pure returns (uint);
    function petunitsmax(uint id) external pure returns (S.Unit calldata);
    function petunitsevolveid(S.Status calldata _status, S.Unit calldata _Unit, TrainerData calldata _trainerData) external pure returns (S.Status memory , uint  );
}
contract FARPG_QuestSystemV1 is Ownable , ReentrancyGuard {
    IFARPG_Storage public contractStorage;
    FARPG_RAMInterface public contractRAM;
    BattleV4 public Battle;
    constructor() {
        
    }
    event StatChangedResult(S.Unit AfterUnit, S.Status AfterStatus, S.Time AfterTime);
    event BattleResultV2(uint BattleRythm, uint bit, bool Won, uint randret, S.Unit[6] unitgroup,uint[3] oponentid, uint[3] attackerid);

//-------------------------------------------------------------------
//    _____ _      ____  ____          _       __      __    
//   / ____| |    / __ \|  _ \   /\   | |      \ \    / /    
//  | |  __| |   | |  | | |_) | /  \  | |       \ \  / /     
//  | | |_ | |   | |  | |  _ < / /\ \ | |        \ \/ /      
//  | |__| | |___| |__| | |_) / ____ \| |____     \  /     _ 
//   \_____|______\____/|____/_/    \_\______|     \/     (_)
//                                                                                                             
//-------------------------------------------------------------------
    uint private QuesttoQuestDelay3 = 3 seconds; //prevent a bot to finish the quest too fast
    uint private QuesttoQuestDelay10 = 10 seconds; //prevent a bot to finish the quest too fast
    mapping (address => uint) private reentrant_time;
    uint constant PRICE_TOOPENBOX = 5 ether; //dont have to change, as this will not happened since First quest only run once. Even is, that is attempt to exploit. 5 FTM will prevent that.
    uint constant TIME_INITIALSTAMINA = 24 hours; //initial stamina
    uint constant TIME_INITIALENDURANCE = 3 hours; //initial endurance/hunger
    string constant MESSAGE_STANDARDQUESTCONDITIONUNMATCHED = "Quest requirement unmatched.";
//--------------------------------------------------------- 
//                     _____  __  __ _____ _   _ 
//               /\   |  __ \|  \/  |_   _| \ | |
//              /  \  | |  | | \  / | | | |  \| |
//             / /\ \ | |  | | |\/| | | | | . ` |
//            / ____ \| |__| | |  | |_| |_| |\  |
//           /_/    \_\_____/|_|  |_|_____|_| \_|
//                                               
//---------------------------------------------------------                                               

    function updateStorageContractAAddress(address _newContractAAddress) external onlyOwner {
        require(_newContractAAddress != address(0), "Invalid address");
        contractStorage = IFARPG_Storage(_newContractAAddress);
    }
    function updateRAMContractAAddress(address _newContractAAddress) external onlyOwner {
        require(_newContractAAddress != address(0), "Invalid address");
        contractRAM = FARPG_RAMInterface(_newContractAAddress);
    }
    function updateBattleV4Address(address _newContractAAddress) external onlyOwner {
        require(_newContractAAddress != address(0), "Invalid address");
        Battle = BattleV4(_newContractAAddress);
    }
    function withdraw() external onlyOwner {
        // Function to withdraw all balance from the contract for revenue
        require(address(this).balance > 0, "Contract balance is zero");
        payable(msg.sender).transfer(address(this).balance);
    }
//---------------------------------------------------------
//              
//             _____ _______       _____ _______ 
//            / ____|__   __|/\   |  __ \__   __|
//           | (___    | |  /  \  | |__) | | |   
//            \___ \   | | / /\ \ |  _  /  | |   
//            ____) |  | |/ ____ \| | \ \  | |   
//           |_____/   |_/_/    \_\_|  \_\ |_|   
//                                               
//---------------------------------------------------------                                     

//--------- sub functions ---------------
    function accountAddressToProceed() public view returns (address) {
    // Ready for account abstraction
    // If the player doesn't provide a personal wallet, all data will be recorded in the trainer wallet
    address playerAddress = contractStorage.personalwallet(msg.sender);
        if (playerAddress == address(0)) {
            return msg.sender;
        } else {
            return playerAddress;
        }
    }

    modifier onlyEOA() {
        require(!isContract(msg.sender), "Smart contracts not allowed");
        _;
    }
    function noneReentrant_time(address player, uint delay) internal  {
        require(reentrant_time[player] < block.timestamp ,"Spam prevention activated.");
        reentrant_time[player] = block.timestamp + delay;
    }
    function isContract(address _addr) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(_addr)
        }
        return size > 0;
    }
    function openBoxIn24Hr_paid() public view returns (uint boxOpened, uint remainingTimeReset_s, uint pricePerBox) {
        //check the timenow and minted 0th box whether the limit has reset
        address playerAddress = accountAddressToProceed();
        uint timeElapsed = block.timestamp - contractStorage.getTimebound1(playerAddress);
        if (timeElapsed >= 24 hours) { //over the TIME limit for 0th box open
            boxOpened = 0;
            remainingTimeReset_s = 0;
        } else { //still within TIME limit since last 0th box opened
            boxOpened = contractStorage.getLimit1(playerAddress);
            remainingTimeReset_s = 24 hours - timeElapsed;
            pricePerBox = PRICE_TOOPENBOX*boxOpened;
        }
    }
    
///////////////////////////////////////   QUEST START  //////////////////////////////////////////////////////////////////    

    function Q1_1JojoTranscended() public nonReentrant   {
    
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        contractStorage.registerUID(playerAddress);
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        uint jojoStrength = contractStorage.getPlayerGeneStrength(playerAddress,0);
        contractStorage.setPlayerGeneStrength(playerAddress, 0, jojoStrength+1);
        contractStorage.setMainQuest(playerAddress,1,1); //done the quest
    }
    


    function Q1_2GetFirstLings(uint slot, uint trainergene) public payable nonReentrant{
      
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,2); //done the quest
        uint limit2 = contractStorage.getLimit2(playerAddress); //limit2 is slot limit
        uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,trainergene);
        uint _timenow = block.timestamp;
        //check to see the chosen slot has occupied or exceed the slotlimit
        S.Status memory _petstatus = contractStorage.getPetStatuses(playerAddress, slot);
        if (limit2 == 0) {
            limit2 = 5;
            contractStorage.setLimit2(playerAddress, limit2); //initialize for the limit2 since its a new player
        }
        require(slot < limit2, "Chosen slot exceeds limit.");
        require(_petstatus.id == 0, "Chosen slot is occupied.");
        require(trainergene == 0, "must be Jojo."); //prevent exploit to get 1 day 2 limited Lings (Quest and Free)
      
        S.Unit memory _petunit = S.Unit({ hp: 1000, attack: 100, defense: 50, speed: 100, intelligence: 100, genestrength: genestrength, range: 0, special: 0});
        _petstatus = S.Status({id: contractRAM.genetoid_mapping(trainergene), family: trainergene + 1 , stage: 1});
        S.Time memory _pettime =  S.Time({bond: 0, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
        contractStorage.setPetUnits(playerAddress, slot ,_petunit);
        contractStorage.setPetStatuses(playerAddress,slot , _petstatus);
        contractStorage.setPetTimes(playerAddress, slot ,_pettime);
       
        contractStorage.setPetUnitsMaxVitamined(playerAddress, slot ,contractRAM.petunitsmax(_petstatus.id));
        
        uint GENEbit = contractStorage.getPoint2(playerAddress);
        
        GENEbit |= (1 << (_petstatus.id%10000)); //DO not minus 1 bit as no shinning check
        contractStorage.setPoint2(playerAddress,GENEbit);
       
        
        emit StatChangedResult(_petunit,_petstatus,_pettime);
    }

/////////////// FEED AND TRAIN PET TUTORIAL ///////////////////////
    uint constant REENTRANT_TIMELIMIT = 2 seconds; // default 2 seconds. means u cannot run the nonreentrant functions >1 time within 3 seconds.
    uint constant PET_STAMINA_MAX = 24 hours; //maximum stamina even rested for so long
    uint constant PET_HUNGER_MAX = 24 hours; // if a pet left for very long time. the MAX hunger should be...

    uint constant ROOKIETOMATURE_BOND = 35 hours; // if Bond more than this, evolve. BUT it is Stamina + Hunger, thus 48hr per day, open Box gave 24+21= 45 hours
   
    uint constant MATURETOPERFECT_BOND = 81 hours; // on evolved, you gain max stamina and initial hunger again, means 45hours again.
//////////////////////////////// sub functions ///////////////////
    struct PetData { //resolve stack too deep
        S.Status petstatuses;
        S.Unit petunits;
        S.Time pettimes;
        S.Unit petunitsmax;
    }
    function UnitUpdateStats(S.Unit memory petunits, S.Unit memory petunitsmax , uint stats_type, uint rate) internal pure returns (S.Unit memory petunitsout){
        //************* rate in 100% = 1000 ***********
        petunitsout = petunits;
        if        (stats_type == 0) { //hp
            if (petunitsmax.hp > petunits.hp) { //no overflow
                petunitsout.hp = petunits.hp + ((petunitsmax.hp - petunits.hp)*rate)/1000;
            } else {petunitsout.hp = petunitsmax.hp;}
        } else if (stats_type == 1) { // atk
            if (petunitsmax.attack > petunits.attack) { //no overflow
                petunitsout.attack = petunits.attack + ((petunitsmax.attack - petunits.attack)*rate)/1000;
            } else {petunitsout.attack = petunitsmax.attack;}
        } else if (stats_type == 2) { // def
            if (petunitsmax.defense > petunits.defense) { //no overflow
                petunitsout.defense = petunits.defense + ((petunitsmax.defense - petunits.defense)*rate)/1000;
            } else {petunitsout.defense = petunitsmax.defense;}
        } else if (stats_type == 3) { // spd
            if (petunitsmax.speed > petunits.speed) { //no overflow
                petunitsout.speed = petunits.speed + ((petunitsmax.speed - petunits.speed)*rate)/1000;
            } else {petunitsout.speed = petunitsmax.speed;}
        } else if (stats_type == 4) { // int
            if (petunitsmax.intelligence > petunits.intelligence) { //no overflow
                petunitsout.intelligence = petunits.intelligence + ((petunitsmax.intelligence - petunits.intelligence)*rate)/1000;
            } else {petunitsout.intelligence = petunitsmax.intelligence;}
        }
    }
    function feedPet(uint _slot, uint _foodtype, uint _trainergene) internal {
        address playerAddress = accountAddressToProceed();
        uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,_trainergene);
       
            require(genestrength > 0, "Don't have the gene.");
        //}
        PetData memory Lings;
        Lings.petstatuses = contractStorage.getPetStatuses(playerAddress,_slot);
        Lings.petunits = contractStorage.getPetUnits(playerAddress,_slot);
        Lings.pettimes = contractStorage.getPetTimes(playerAddress,_slot);
        Lings.petunitsmax = contractStorage.getPetUnitsMaxVitamined(playerAddress,_slot);
        uint _exp = contractStorage.getExperience(playerAddress);
        uint _full; //determine how full is the food after eaten in time
        uint _partialstat; // partial stat gain only. 100% = 10000
        uint _timenow = block.timestamp;
        require (Lings.petstatuses.id != 0, "empty slot");
        require(_foodtype <= 10, "Invalid food type");
        if      (_foodtype==0){_full = 6 hours;} //backpack food
        else if (_foodtype==1){_full = 12 hours; } //shop1
        else if (_foodtype==2){_full = 10 hours; } 
        else if (_foodtype==3){_full = 10 hours; } 
        else if (_foodtype==4){_full = 11 hours; } //shop1.1
        else if (_foodtype==5){_full = 11 hours; } 
        else if (_foodtype==6){_full = 24 hours; } //shop2
        else if (_foodtype==7){_full = 24 hours; } 
        else if (_foodtype==8){_full = 24 hours; } 
        else if (_foodtype==9){_full = 24 hours; } //shop2.2
        else if (_foodtype==10){_full = 24 hours; } 
        if (Lings.pettimes.hunger < _timenow) { //super hungry, endurance = 0
            Lings.pettimes.bond = Lings.pettimes.bond + _full;
            _exp += _full;
            Lings.pettimes.hunger = _timenow + _full;
            _partialstat= 10; // 100% = 10
        } else if (Lings.pettimes.hunger - _timenow + _full> PET_HUNGER_MAX) { //over feed, gain partial stat
            uint fullhittingcap = (PET_HUNGER_MAX- (Lings.pettimes.hunger - _timenow));
            Lings.pettimes.bond = Lings.pettimes.bond + fullhittingcap; 
            _exp += fullhittingcap;
            _partialstat = (fullhittingcap*10)/ (_full); //100 = 1 = 100% (upscale 2 0)
            //this has to run last otherwise alter the hunger variable for above
            Lings.pettimes.hunger = _timenow + PET_HUNGER_MAX; 
        } else { //no over feed. stat gain all
            Lings.pettimes.bond = Lings.pettimes.bond + _full;
            _exp += _full;
            Lings.pettimes.hunger = Lings.pettimes.hunger + _full; 
            _partialstat= 10; // 100% = 10
        }
       
        if      (_foodtype==0){} //backpack food
       
        else if (_foodtype==1){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,10*_partialstat);} //hp + 10% //shop1 
        else if (_foodtype==2){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,5*_partialstat);} //atk + 5%
        else if (_foodtype==3){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,5*_partialstat);} //def + 5%
        else if (_foodtype==4){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,5*_partialstat);} //spd + 5% //shop1.1
        else if (_foodtype==5){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,5*_partialstat);} //int + 5%
        else if (_foodtype==6){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,19*_partialstat);} //hp + 19% //shop2 
        else if (_foodtype==7){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,11*_partialstat);} //atk + 11%
        else if (_foodtype==8){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,11*_partialstat);} //def + 11%
        else if (_foodtype==9){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,11*_partialstat);} //spd + 11% //shop2.2
        else if (_foodtype==10){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,11*_partialstat);} //int + 11%
        
    
        //***************   check evolve **************
        if ((Lings.petstatuses.stage == 1   &&   Lings.pettimes.bond > ROOKIETOMATURE_BOND)|| //check if rookie, then to mature
            (Lings.petstatuses.stage == 2   &&   Lings.pettimes.bond > MATURETOPERFECT_BOND)) { // check if mature, then to perfect
            //evolve id and maxstats
            //this need from RAM as update each patch
            FARPG_RAMInterface.TrainerData memory _trainerdata;
            _trainerdata.gene = _trainergene;
            _trainerdata.genestrength = contractStorage.getPlayergenestrengthArray(playerAddress);
            _trainerdata.hashed = uint(keccak256(abi.encodePacked(playerAddress,block.timestamp,block.prevrandao)));
            uint compiledGenestrength;
            (Lings.petstatuses, compiledGenestrength)= contractRAM.petunitsevolveid(Lings.petstatuses,Lings.petunits, _trainerdata);
           
            contractStorage.setPetStatuses(playerAddress,_slot , Lings.petstatuses); //update: ID, family, stage
            
            Lings.pettimes = S.Time({bond: Lings.pettimes.bond, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
            contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes); //update: bond for evolve, stamina, hunger
            Lings.petunitsmax = contractRAM.petunitsmax(Lings.petstatuses.id); //use new id to get max stat, no genestrength and skills yet
            contractStorage.setPetUnitsMaxVitamined(playerAddress, _slot, Lings.petunitsmax);
            //evolve gain all stats by 30%
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,300);
            
            //gain new skill, with training stats above
            if (Lings.petstatuses.stage == 2) {//evolved into Mature
                    Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
                    if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
                        Lings.petunits.range = Lings.petstatuses.id - 10001;
                    } else {
                        Lings.petunits.range = Lings.petstatuses.id - 1;
                    }
                }
            if (Lings.petstatuses.stage == 3) {
                Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
                if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
                    Lings.petunits.special = Lings.petstatuses.id - 10001;
                } else {
                    Lings.petunits.special = Lings.petstatuses.id - 1;
                }
            }
            contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits); //final write into petUnits (stats, genestrength, skills)
           
            uint GENEbit = contractStorage.getPoint2(playerAddress);
            // Set the bit at the position corresponding to ID
            GENEbit |= (1 << ((Lings.petstatuses.id-1)%10000));//need to minus 1 bit because of previous add on shinning check
            contractStorage.setPoint2(playerAddress,GENEbit);
           
            
        } else { 
            contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits);
            contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes);
        }
        //************** check evolve end ******************
        contractStorage.setExp(playerAddress, _exp);
        emit StatChangedResult(Lings.petunits,Lings.petstatuses,Lings.pettimes);
    }   
///////////////////////////////////////   TRAIN PET  //////////////////////////////////////////////////////////////////
    function trainPet(uint _slot, uint _traintype, uint _trainergene) internal  {
        address playerAddress = accountAddressToProceed();
        uint _exp = contractStorage.getExperience(playerAddress);
        uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,_trainergene);
        //if (_trainergene !=0) { //if the trainer is not default Jojo, then make sure this player has different trainer
            require(genestrength > 0, "Don't have the gene.");
        //}
        PetData memory Lings;
        Lings.petstatuses = contractStorage.getPetStatuses(playerAddress,_slot);
        Lings.petunits = contractStorage.getPetUnits(playerAddress,_slot);
        Lings.pettimes = contractStorage.getPetTimes(playerAddress,_slot);
        Lings.petunitsmax = contractStorage.getPetUnitsMaxVitamined(playerAddress,_slot);
        uint _effort; //determine how full is the food after eaten in time
        uint _timenow = block.timestamp;
        require (Lings.petstatuses.id != 0, "empty slot");
      
        require(_traintype <= 24, "Invalid training type");
        if      (_traintype==0){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //basic 1, 0hp / 1atk / 2def/ 3spd / 4int
        else if (_traintype==1){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); } 
        else if (_traintype==2){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); } 
        else if (_traintype==3){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); } 
        else if (_traintype==4){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); } 
        else if (_traintype==5){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 1
        else if (_traintype==6){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); } 
        else if (_traintype==7){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); } 
        else if (_traintype==8){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); } 
        else if (_traintype==9){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); } 
        else if (_traintype==10){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 2
        else if (_traintype==11){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); } 
        else if (_traintype==12){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); } 
        else if (_traintype==13){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); } 
        else if (_traintype==14){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); } 
        else if (_traintype==15){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 3
        else if (_traintype==16){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); } 
        else if (_traintype==17){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); } 
        else if (_traintype==18){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); } 
        else if (_traintype==19){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); } 
        else if (_traintype==20){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 4
        else if (_traintype==21){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); } 
        else if (_traintype==22){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); } 
        else if (_traintype==23){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); } 
        else if (_traintype==24){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); } 
        uint _staminaleft = _timenow - Lings.pettimes.stamina; //staminatime sure lower than timenow. NO WAY staminatime > timenow, really is, then revert
        require(_staminaleft >= _effort, "Not enough stamina.");
        if (_staminaleft > PET_STAMINA_MAX) {_staminaleft = PET_STAMINA_MAX;} //capping stamina before spending
        _staminaleft -= _effort; //remaining stamina
        Lings.pettimes.stamina = _timenow - _staminaleft; //timenow always larger than staminaleft.
        Lings.pettimes.bond += _effort;
        _exp += _effort;
        //***************   check evolve **************
        if ((Lings.petstatuses.stage == 1   &&   Lings.pettimes.bond > ROOKIETOMATURE_BOND)|| //check if rookie, then to mature
            (Lings.petstatuses.stage == 2   &&   Lings.pettimes.bond > MATURETOPERFECT_BOND)) { // check if mature, then to perfect
            //evolve id and maxstats
            //this need from RAM as update each patch
            FARPG_RAMInterface.TrainerData memory _trainerdata;
            _trainerdata.gene = _trainergene;
            _trainerdata.genestrength = contractStorage.getPlayergenestrengthArray(playerAddress);
            _trainerdata.hashed = uint(keccak256(abi.encodePacked(playerAddress,block.timestamp,block.prevrandao)));
            uint compiledGenestrength;
            (Lings.petstatuses, compiledGenestrength)= contractRAM.petunitsevolveid(Lings.petstatuses,Lings.petunits, _trainerdata);
            
            contractStorage.setPetStatuses(playerAddress,_slot , Lings.petstatuses); //update: ID, family, stage
            //ONCE evolve you gain Stamina and Endurance
            Lings.pettimes = S.Time({bond: Lings.pettimes.bond, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
            contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes); //update: bond for evolve, stamina, hunger
            Lings.petunitsmax = contractRAM.petunitsmax(Lings.petstatuses.id); //use new id to get max stat, no genestrength and skills yet
            contractStorage.setPetUnitsMaxVitamined(playerAddress, _slot, Lings.petunitsmax);
            //evolve gain all stats by 30%
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,300);
            Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,300);
            
          
            if (Lings.petstatuses.stage == 2) {//evolved into Mature
                    Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
                    if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
                        Lings.petunits.range = Lings.petstatuses.id - 10001;
                    } else {
                        Lings.petunits.range = Lings.petstatuses.id - 1;
                    }
                }
            if (Lings.petstatuses.stage == 3) {
                Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
                if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
                    Lings.petunits.special = Lings.petstatuses.id - 10001;
                } else {
                    Lings.petunits.special = Lings.petstatuses.id - 1;
                }
            }
            contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits); //final write into petUnits (stats, genestrength, skills)
            
            uint GENEbit = contractStorage.getPoint2(playerAddress);
            // Set the bit at the position corresponding to ID
            GENEbit |= (1 << ((Lings.petstatuses.id-1)%10000));//need to minus 1 bit because of previous add on shinning check
            contractStorage.setPoint2(playerAddress,GENEbit);
            //**//***//////////////////////////////////////////
            
        } else { //if no evolve, follow back the stamina and hunger, only update Units states and time, Status(ID, Family, stage) no change. 
            contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits);
            contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes);
        }
        //************** check evolve end ******************
        contractStorage.setExp(playerAddress, _exp);
        emit StatChangedResult(Lings.petunits,Lings.petstatuses,Lings.pettimes);


    }
    function Q1_3FeedPet(uint _slot, uint _foodtype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 2,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,3); //Fed Pet, set Quest1 to 3, if unsuccessful, revert, so it wont set.
        feedPet(_slot,  _foodtype,  _trainergene);
    }
   
    function Q1_4TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 3,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,4); //trainPet, set Quest1 to 4, if unsuccessful, revert, so it wont set.
        trainPet(_slot, _traintype, _trainergene);
    }

    function Q1_5TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 4,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,5); //trainPet, set Quest1 to 5, if unsuccessful, revert, so it wont set.
        trainPet(_slot, _traintype, _trainergene);
    }
    function Q1_6TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 5,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,6); //trainPet, set Quest1 to 6, if unsuccessful, revert, so it wont set.
        trainPet(_slot, _traintype, _trainergene);
    }
    function Q1_7TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 6,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,7); //trainPet, set Quest1 to 7, if unsuccessful, revert, so it wont set.
        trainPet(_slot, _traintype, _trainergene);
    }
    function Q1_8TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 7,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,1,8); //trainPet, set Quest1 to 8, if unsuccessful, revert, so it wont set.
        trainPet(_slot, _traintype, _trainergene);
    }

    function Q1_9SetPartyTutorial(uint[30] memory partyFormation) public nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 8,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setPartyFormation(playerAddress,partyFormation);
        contractStorage.setMainQuest(playerAddress,1,9); //done the quest
    }

    function Q1_10FirstBattle(uint[3] calldata attackersID) public nonReentrant{
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 9,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        reentrant_time[playerAddress] = block.timestamp;
       
        bool AttackerWin;
        uint BattleRhythm;
        uint randret;
        S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
        uint bit;
        uint[3] memory OpponIDs;
        (AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID); //get attacker/player data
        require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
        
        UnitGroup[0] = AttackerUnits[0];
        UnitGroup[1] = AttackerUnits[1];
        UnitGroup[2] = AttackerUnits[2];
       
        UnitGroup[3] = S.Unit({ hp: 1300, attack: 110, defense: 12, speed: 311, intelligence: 355, genestrength: 10, range: 15, special: 0 }); //preset opponent, skill decide later.
        
        OpponIDs = [uint256(15), uint256(0), uint256(0)]; // will finalize later after decide the first battle //saved for event emit.
     
        (BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
        
        
        if (AttackerWin == true) { 
            //give treasure box, need items contract
            contractStorage.setMainQuest(playerAddress,1,10); //done the quest 1, set to 10
        } else {
            //nothing happened... front end make them back to town and say better train more/listen to advice.
        }
        emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
        
    }
////////////////////////////////////////////Quest 2 3 4 STARTED Parallel/////////////////////////////////////////////////////////////
    function Q2_1FightLena(uint[3] calldata attackersID) public payable nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 10 &&
        contractStorage.getMainQuestProgress(playerAddress,2) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
     
        bool AttackerWin;
        uint BattleRhythm;
        uint randret;
        S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
        uint bit;
        uint[3] memory OpponIDs;
        (AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID);
        require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
        //player's Lings
        UnitGroup[0] = AttackerUnits[0];
        UnitGroup[1] = AttackerUnits[1];
        UnitGroup[2] = AttackerUnits[2];
        //Lena's Lings Wolf M1	Packer	ID 42
        UnitGroup[3] = S.Unit({ hp: 3200, attack: 800, defense: 100, speed: 253, intelligence: 455, genestrength: 0, range: 8, special: 0 }); //range suppose ID42, but pending
      
        OpponIDs = [uint(42), uint(0), uint(0)];
        
        (BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
        
        
        if (AttackerWin == true) { 
            if (contractStorage.getMainQuestProgress(playerAddress,2) == 0) { //<-----prevent exploit to reset quest
                contractStorage.setMainQuest(playerAddress,2,1); //WIN LENA, set the quest2 to 1
            }
        } else {
           
        }
        emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
        //If WON, she will go to town and Open SHOP
    }

    function Q2_2ShoppingTutorial() public nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,2) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,2,2); //done the quest
       
    }
///--------------------------
    function Q3_1SaveQingYue() public nonReentrant{
        
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 10 &&
         contractStorage.getMainQuestProgress(playerAddress,3) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        if (contractStorage.getMainQuestProgress(playerAddress,3) == 0) { //<-----prevent exploit to reset quest
            contractStorage.setMainQuest(playerAddress,3,1); //done the quest
        }
    }
    function Q3_2RestaurantTutorial() public nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
        require(contractStorage.getMainQuestProgress(playerAddress,3) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,3,2); //done the quest
        //can feed 24 hours food.
    }
//--------------------------

    function Q4_1FightKlue(uint[3] calldata attackersID) public payable nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
       
        require(contractStorage.getMainQuestProgress(playerAddress,1) == 10,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
       
        bool AttackerWin;
        uint BattleRhythm;
        uint randret;
        S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
        S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
        uint bit;
        uint[3] memory OpponIDs;
        (AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID);
        require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
        //player's Lings
        UnitGroup[0] = AttackerUnits[0];
        UnitGroup[1] = AttackerUnits[1];
        UnitGroup[2] = AttackerUnits[2];
       
        UnitGroup[3] = S.Unit({ hp: 32152, attack: 4500, defense: 3600, speed: 610, intelligence: 355, genestrength: 50, range: 14, special: 16 }); 
        UnitGroup[4] = S.Unit({ hp: 26431, attack: 2300, defense: 1060, speed: 650, intelligence: 355, genestrength: 50, range: 14, special: 0 }); 
        UnitGroup[5] = S.Unit({ hp: 21002, attack: 2800, defense: 730, speed: 820, intelligence: 355, genestrength: 50, range: 15, special: 0 });
        OpponIDs = [uint(16), uint(14), uint(15)];
        // Call the BattleV4_3v3 function with matching types
        (BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
        //(BattleRhythm, bit, AttackerWin, randret)=Battle.Calibrate(1);
        if (contractStorage.getMainQuestProgress(playerAddress,4) == 0) { //<-----prevent exploit to reset quest
            contractStorage.setMainQuest(playerAddress,4,1); //lose klue, escaped but pass quest
        }
        emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
        //This suppose to be sure lose battle. but even lose, will complete the quest
    }

    
    function Q5_1AndreAskToFindMichael() public nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
       
        require(contractStorage.getMainQuestProgress(playerAddress,2) > 0 &&
        contractStorage.getMainQuestProgress(playerAddress,3) > 0 &&
        contractStorage.getMainQuestProgress(playerAddress,4) > 0 &&
        contractStorage.getMainQuestProgress(playerAddress,5) == 0 ,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,5,1); //done the quest
    }

    function Q5_2MichaelShowBridge() public nonReentrant{
       
        address playerAddress = accountAddressToProceed();
        noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
       
        require(contractStorage.getMainQuestProgress(playerAddress,5) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
        contractStorage.setMainQuest(playerAddress,5,2); //done the quest -- UNLOCK Simulated Dungeon
    }



}

Please enter a contract address above to load the contract details and source code.

Context size (optional):