function buyTicket(uint8 lotteryId,uint16[] tickets,address referer) payable public {
        
        
        require(state[lotteryId] == State.Running);
        
        
        require(maxTickets[lotteryId] > ticketsSold[lotteryId]);
        
        if (referer != address(0)) {
            setReferer(referer);
        }
        
        uint16 ticketsToBuy = uint16(tickets.length);
        
        
        uint256 valueRequired = ticketsToBuy*ticketPrice[lotteryId];
        require(valueRequired <= msg.value);
        
        
        require((maxTickets[lotteryId] - ticketsSold[lotteryId]) >= ticketsToBuy); 
        
        Player storage pInfo = playerInfoMappings[lotteryId][msg.sender];
        if (pInfo.changedOn < started[lotteryId]) {
            pInfo.changedOn = block.timestamp;
            pInfo.ticketsCount = 0;
        }
        
        
        require ((pInfo.ticketsCount+ticketsToBuy) <= ((maxTickets[lotteryId]*maxPercentPerPlayer)/100));
        
        for (uint16 i; i < ticketsToBuy; i++) {
            
            require((tickets[i] - 1) >= 0);
            
            
            require (get512(bitMaskForPlayFields[lotteryId],tickets[i]-1) == 0);
            set512(bitMaskForPlayFields[lotteryId],tickets[i]-1,1);
            ticketsAllocator[lotteryId][tickets[i]-1] = msg.sender;
        }
            
        pInfo.ticketsCount += ticketsToBuy;

        
        lastTicketBought[lotteryId] = block.timestamp;
        
        
        ticketsSold[lotteryId] +=  ticketsToBuy;
        
        
        if (ticketsSold[lotteryId] == maxTickets[lotteryId]) {
            finalizeRoom(lotteryId);
        }
        
        
        TicketsBought(lotteryId,msg.sender,tickets);
    }