contract CryptoWarriorCore is CoreRecovery {

    /// @notice Creates the main CryptoWarrior smart contract instance.
    function CryptoWarriorCore() public {
        // Starts paused.
        paused = true;

        // the creator of the contract is the initial Admin
        adminAddress = msg.sender;

        // the creator of the contract is also the initial COO
        issuerAddress = msg.sender;
        
        // the creator of the contract is also the initial Bank
        bankAddress = msg.sender;
    }
    
    /// @notice No tipping!
    /// @dev Reject all Ether from being sent here
    /// (Hopefully, we can prevent user accidents.)
    function() external payable {
        require(false);
    }
    
    /// @dev Override unpause so it requires all external contract addresses
    ///  to be set before contract can be unpaused. Also, we can't have
    ///  newContractAddress set either, because then the contract was upgraded.
    /// @notice This is public rather than external so we can call super.unpause
    ///  without using an expensive CALL.
    function unpause() public onlyAdmin whenPaused {
        require(address(saleAuction) != address(0));
        require(address(sanctuary) != address(0));
        require(address(battleProvider) != address(0));
        require(newContractAddress == address(0));

        // Actually unpause the contract.
        super.unpause();
    }
    
    function getBeneficiary() external view returns(address) {
        return bankAddress;
    }
    
    function isPVPListener() public pure returns (bool) {
        return true;
    }
       
    /**
     *@param _warriorIds array of warriorIds, 
     * for those IDs warrior data will be packed into warriorsData array
     *@return warriorsData packed warrior data
     *@return stepSize number of fields in single warrior data */
    function getWarriors(uint256[] _warriorIds) external view returns (uint256[] memory warriorsData, uint256 stepSize) {
        stepSize = 6;
        warriorsData = new uint256[](_warriorIds.length * stepSize);
        for(uint256 i = 0; i < _warriorIds.length; i++) {
            _setWarriorData(warriorsData, warriors[_warriorIds[i]], i * stepSize);
        }
    }
    
    /**
     *@param indexFrom index in global warrior storage (aka warriorId), 
     * from this index(including), warriors data will be gathered
     *@param count Number of warriors to include in packed data
     *@return warriorsData packed warrior data
     *@return stepSize number of fields in single warrior data */
    function getWarriorsFromIndex(uint256 indexFrom, uint256 count) external view returns (uint256[] memory warriorsData, uint256 stepSize) {
        stepSize = 6;
        //check length
        uint256 lenght = (warriors.length - indexFrom >= count ? count : warriors.length - indexFrom);
        
        warriorsData = new uint256[](lenght * stepSize);
        for(uint256 i = 0; i < lenght; i ++) {
            _setWarriorData(warriorsData, warriors[indexFrom + i], i * stepSize);
        }
    }
    
    function getWarriorOwners(uint256[] _warriorIds) external view returns (address[] memory owners) {
        uint256 lenght = _warriorIds.length;
        owners = new address[](lenght);
        
        for(uint256 i = 0; i < lenght; i ++) {
            owners[i] = warriorToOwner[_warriorIds[i]];
        }
    }
    
    
    function _setWarriorData(uint256[] memory warriorsData, DataTypes.Warrior storage warrior, uint256 id) internal view {
        warriorsData[id] = uint256(warrior.identity);//0
        warriorsData[id + 1] = uint256(warrior.cooldownEndBlock);//1
        warriorsData[id + 2] = uint256(warrior.level);//2
        warriorsData[id + 3] = uint256(warrior.rating);//3
        warriorsData[id + 4] = uint256(warrior.action);//4
        warriorsData[id + 5] = uint256(warrior.dungeonIndex);//5
    }
    
	function getWarrior(uint256 _id) external view returns 
    (
        uint256 identity, 
        uint256 cooldownEndBlock, 
        uint256 level,
        uint256 rating, 
        uint256 action,
        uint256 dungeonIndex
    ) {
        DataTypes.Warrior storage warrior = warriors[_id];

        identity = uint256(warrior.identity);
        cooldownEndBlock = uint256(warrior.cooldownEndBlock);
        level = uint256(warrior.level);
		rating = uint256(warrior.rating);
		action = uint256(warrior.action);
		dungeonIndex = uint256(warrior.dungeonIndex);
    }
    
}
function unpause() public onlyAdmin whenPaused {
    require(address(saleAuction) != address(0));
    require(address(sanctuary) != address(0));
    require(address(battleProvider) != address(0));
    require(newContractAddress == address(0));

    // Actually unpause the contract.
    super.unpause();
}

/// @dev Override unpause so it requires all external contract addresses
///  to be set before contract can be unpaused. Also, we can't have
///  newContractAddress set either, because then the contract was upgraded.
/// @notice This is public rather than external so we can call super.unpause
///  without using an expensive CALL.