# Coupon / Event Key

### 1) 쿠폰 생성하기

1\. 월드 관리 페이지의 우측 상단 리스트메뉴에서 **쿠폰 설정** 클릭

<figure><img src="/files/V7tzwZnlY6Q9CzuP1BpS" alt=""><figcaption></figcaption></figure>

2\. 쿠폰 설정 페이지는 아래와 같이 구성되어 있어요.

<figure><img src="/files/LTZsRsjXFybZLTTFbpUe" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="104.33333333333331">번호</th><th width="167">항목</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>등록하기 버튼</td><td>등록하기 버튼을 눌러 쿠폰을 등록할 수 있어요.</td></tr><tr><td>2</td><td>쿠폰 정보</td><td>등록된 쿠폰이 표시돼요.</td></tr><tr><td>3</td><td>쿠폰 사용 리스트</td><td>쿠폰을 사용한 플레이어 목록이 표시돼요.</td></tr></tbody></table>

2.1 등록된 쿠폰의 상태는 발급 기간에 따라 달라져요.

<figure><img src="/files/CIo6bZyDhkyyHOI2rRCc" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="104.33333333333331">번호</th><th width="94">상태</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>대기</td><td>발급기간 이전일 때의 상태에요.</td></tr><tr><td>2</td><td>진행</td><td>발급기간 일 때의 상태에요.</td></tr><tr><td>3</td><td>종료</td><td>발급기간 이후일 때의 상태에요.</td></tr><tr><td>4</td><td>중지</td><td>관리자의 비활성 설정했을 때의 상태에요.</td></tr></tbody></table>

2.2 쿠폰 상세 페이지에서는 아래 기능들을 이용할 수 있어요.

<figure><img src="/files/aptsDRQgfUggzhriciiT" alt=""><figcaption></figcaption></figure>

① : 쿠폰 복제

② : (상태 별) 쿠폰 발급 기간 수정 혹은 쿠폰 사용 중지

2.3 쿠폰을 사용한 유저들을 편리하게 구분하여 확인할 수 있어요.

<figure><img src="/files/IdzeP3YS7rWQH95W3nyW" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="99.33333333333331">번호</th><th width="132">종류</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>쿠폰 종류</td><td>원하는 종류의 쿠폰 사용자들을 확인할 수 있어요.</td></tr><tr><td>2</td><td>검색 기준</td><td>쿠폰 사용자들의 ID, 쿠폰 중 선택하여 검색할 수 있어요.</td></tr></tbody></table>

3\. 쿠폰 등록 화면은 아래와 같이 구성되어 있어요.

<figure><img src="/files/86KLQybJ9PmCbWyJBS1u" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="108.33333333333331">번호</th><th width="159">항목</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>쿠폰</td><td>쿠폰의 이름<br>(영문, 숫자 20자 이내로 입력해요)</td></tr><tr><td>2</td><td>쿠폰 타입</td><td>쿠폰을 사용했을 때 어떤 보상을 줄지 정할 수 있어요.</td></tr><tr><td>3</td><td>쿠폰 수량</td><td>발급할 쿠폰 번호의 수량이에요.<br>(쿠폰 번호는 난수로 자동 생성됩니다)</td></tr><tr><td>4</td><td>참여 인원</td><td>쿠폰 수량이 1일 때 선택할 수 있어요.<br>(제한이 없으면 무제한 쿠폰이며, <br>숫자를 입력하면 정해진 인원 수만큼 사용할 수 있어요)</td></tr><tr><td>5</td><td>발급(사용)기간</td><td>쿠폰을 사용할 수 있는 기간이에요.<br>(시작 기간이 되어야 사용할 수 있으며, <br>종료 기간이 되면 사용할 수 없게 됩니다)</td></tr></tbody></table>

3.1 쿠폰 타입 항목에서, 쿠폰 사용 시 지급할 **보상의 이름**을 추가하고 선택할 수 있어요.

<figure><img src="/files/UtnaihogcohI45CvW2AK" alt=""><figcaption></figcaption></figure>

3.2 위에서 선택한 **쿠폰 타입**은 **스크립트에서** 보상 지급을 처리하는데 이용됩니다.

4\. 쿠폰 수량과 참여 인원을 어떻게 설정하느냐에 따라 아래와 같이 활용할 수 있어요.

<table><thead><tr><th width="118">쿠폰 수량</th><th width="107">참여 인원</th><th width="370">동작</th><th>활용 예</th></tr></thead><tbody><tr><td>1</td><td>제한없음</td><td>동일한 번호로 누구나 사용할 수 있는 쿠폰</td><td>오픈 기념 쿠폰</td></tr><tr><td>1</td><td>n명</td><td>번호 1개를 n명까지 사용할 수 있는 선착순 쿠폰</td><td>선착순 쿠폰</td></tr><tr><td>n개</td><td>-</td><td>각각의 번호로 사용하는 선착순 쿠폰</td><td>선착순 쿠폰</td></tr></tbody></table>

###

### 2) 쿠폰 번호 배포하기

1\. 쿠폰 정보 목록에서 쿠폰 수량 글자를 클릭해요.&#x20;

<figure><img src="/files/UVQV1LHShVEVONWEc9Pp" alt=""><figcaption></figcaption></figure>

2\. 쿠폰 리스트 팝업에서 번호를 확인할 수 있어요. \
CSV 다운로드 버튼을 클릭하면 엑셀로 확인하는 것도 가능해요.

<figure><img src="/files/xJiPMRvb9lTWoQiqqliq" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/wblnwUwApZs49DK2KoSt" alt=""><figcaption></figcaption></figure>

###

### 3) Script에서 쿠폰 연동하기

#### 3-1) 쿠폰 번호 입력해서 사용

플레이어가 UI 에 쿠폰 번호를 입력하면, 해당 쿠폰을 사용하도록 처리하는 스크립트 예시에요.

1. ClientScript에서 버튼 클릭시, TextBox의 입력 내용을 서버의 UseCoupon함수로 전달하는 처리를 \
   아래와 같이 구현해요.

   ```lua
   local CouponUI = Workspace.CouponUI

   local function InputCoupon()
       local couponID = CouponUI.Frame.TextBox:GetText() --TextBox의 입력 내용이에요.
       Game:SendEventToServer("UseCoupon", **couponID**)     --서버의 함수를 호출해요.
   end
   CouponUI.Frame.UseButton.OnUpEvent:Connect(InputCoupon) --버튼 클릭 이벤트
   ```

2. ServerScript에서 쿠폰의 처리를 아래와 같이 구현해요.

   ```lua
   --2. player:UseCoupon 함수에 연결되는 함수에요.
   local function DoUseCoupon(player, couponReturnData)      
       local state = couponReturnData.State --쿠폰의 상태
       local couponType = couponReturnData.CouponType --쿠폰의 보상 종류
       local result = couponReturnData.Result --쿠폰 사용 결과

       --쿠폰 상태 및 보상
       if state == Enum.CouponState.Wait then
           print("쿠폰 상태 : 대기")
       elseif state == Enum.CouponState.Doing then
   	print("쿠폰 상태 : 진행")
       elseif state == Enum.CouponState.Stop then
   	print("쿠폰 상태 : 중지")
       elseif state == Enum.CouponState.End then
   	print("쿠폰 상태 : 종료")
       end
       print("쿠폰 보상 타입 : ", couponType)

       --쿠폰 사용 결과가 Success이면  
       if result == Enum.CouponResult.Success then
           print("쿠폰을 사용했습니다!")    

   	if couponType == "Gold" then
   	    player.Gold = player.Gold + 1000
   	end
           
       --쿠폰 사용 결과가 Exist이면
       elseif result == Enum.CouponResult.Exist then
           print("이미 사용한 쿠폰입니다!")         

       --이외에는
       else
           print("유효하지 않은 쿠폰입니다!")
       end
   end

   --1. ClientScript의 버튼 이벤트에서 호출되는 함수에요.
   local function UseCoupon(player, coupon)
       --플레이어에게 해당 쿠폰을 사용 처리해요. 
       --(쿠폰 번호, 쿠폰 사용 처리 함수)
       player:UseCoupon(coupon, DoUseCoupon)
   end
   Game:ConnectEventFunction("UseCoupon", UseCoupon) 
   ```

#### 3-2) 남아 있는 쿠폰 중 하나를 사용

특정 타입의 쿠폰 중 남아있는 쿠폰이 있다면, 플레이어에게 사용 처리되도록 하는스크립트 예시에요.

* **UseRemainCoupon 함수**를 이용해서, **남아있는 쿠폰 중 하나를 사용**하도록 할 수 있어요.

  1. 플레이어에게 쿠폰을 사용 처리할 수 있도록,  ClientScript 에서 Server 함수를 호출해요.

     ```lua
     local function ClearGame()
         Game:SendEventToServer("UseCoupon", "ClearReward")
     end

     ClearGame()
     ```
  2. ServerScript에서 쿠폰의 처리를 아래와 같이 구현해요.

     ```lua
     --2. player:UseRemainCoupon 함수에 연결되는 함수에요. 
     -- (3-1 샘플 코드 중, DoUseCoupon 함수와 동일한 방식으로 사용할 수 있어요)
     local function DoUseCoupon(player, couponReturnData)      
         ...
     end

     --1. 특정 상황일 때 ClientScript 에서 호출되는 함수에요.
     local function UseCoupon(player, couponType)
         --남아 있는 쿠폰 중 하나를 플레이어에게 사용 처리해요. 
         --(남은 쿠폰을 찾을 쿠폰 타입, 남은 쿠폰 사용 처리 함수)
         player:UseRemainCoupon(couponType, DoUseCoupon)
     end
     Game:ConnectEventFunction("UseCoupon", UseCoupon)
     ```

* **GetRemainCouponCount 함수**를 이용해서, **남아있는 쿠폰의 수량을 확인**할 수 있어요.
  1. ClientScript 에서 Server 함수를 호출하고, Server 에서 처리된 정보를 받아와요.

     ```lua
     local CouponUI = Workspace.ScreenUI

     -- 1. ClientScript 에서 Server 함수를 호출해요.
     local function Refresh_CouponCountUI()
         Game:SendEventToServer("ConfirmRemainCouponCount", "ClearReward")
     end

     Refresh_CouponCountUI()

     -- 4. Server 에서 받은 수량 정보로, UI 를 갱신해요.
     local function DoRefresh_CouponCountUI(count)
         CouponUI.Text:SetText(count)
     end
     Game:ConnectEventFunction("DoRefresh_CouponCountUI", DoRefresh_CouponCountUI)
     ```
  2. ServerScript 에서 남아있는 쿠폰의 수량 정보와 함께 Client 함수를 호출해요.

     ```lua
     --3. player:GetRemainCouponCount 함수에 연결되는 함수에요.
     local function DoGetRemainCouponCount(player, count)   
         local playerID = player:GetPlayerID()
         Game:SendEventToClient(playerID , "DoRefresh_CouponCountUI", count)
     end

     --2. 특정 상황일 때 ClientScript 에서 호출되는 함수에요.
     local function ConfirmRemainCouponCount(player, couponType)
         --남아있는 쿠폰의 수량을 확인해요. 
         --(확인할 쿠폰 타입, 남은 쿠폰 확인 처리 함수)
         player:GetRemainCouponCount(couponType, DoGetRemainCouponCount)
     end
     Game:ConnectEventFunction("ConfirmRemainCouponCount", ConfirmRemainCouponCount)
     ```

## 이벤트 키 사용법

### 1) 이벤트 키 생성하기

1\. 월드 관리 페이지의 우측 상단 리스트 메뉴에서 **이벤트 키 설정** 클릭해요.&#x20;

<figure><img src="/files/9qfvarQ3Ok6EiDIRq1Gy" alt=""><figcaption></figcaption></figure>

2\. 이벤트 키 설정 페이지는 아래와 같이 구성되어 있어요.

<figure><img src="/files/dh8tfZjLJ3zViUG8p3BA" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="92.33333333333331">번호</th><th width="207">항목</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>등록하기 버튼</td><td>등록하기 버튼을 눌러 이벤트 키를 등록할 수 있어요.</td></tr><tr><td>2</td><td>이벤트 키 정보</td><td>등록된 이벤트 키 정보가 표시돼요.</td></tr><tr><td>3</td><td>이벤트 키 참여 리스트</td><td>이벤트 키 참여 유저 리스트가 표시돼요.</td></tr></tbody></table>

2.1 등록된 이벤트 키의 상태는 유효 기간에 따라 달라져요.

<figure><img src="/files/LqEeGQw5RetKpUKvXPCJ" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="94.33333333333331">번호</th><th width="104">상태</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>대기</td><td>유효기간 이전일 때의 상태에요.</td></tr><tr><td>2</td><td>진행</td><td>유효기간 일 때의 상태에요.</td></tr><tr><td>3</td><td>종료</td><td>유효기간 이후일 때의 상태에요.</td></tr><tr><td>4</td><td>중지</td><td>관리자의 비활성 설정했을 때의 상태에요.</td></tr></tbody></table>

2.2 이벤트 키 상세 페이지에서는 아래 기능들을 이용할 수 있어요.

<figure><img src="/files/mWAJGVKdXQZNXKHHutLX" alt=""><figcaption></figcaption></figure>

① : 이벤트 키 복제

② : (상태 별) 이벤트 키 유효 기간 수정, 이벤트 키 진행 중지

2.3 이벤트에 참여한 유저들을 편리하게 구분하여 확인할 수 있어요.

<figure><img src="/files/KHPPrETLrB79KxDCWQeh" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="93.33333333333331">번호</th><th width="157">종류</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>이벤트 키 종류</td><td>원하는 종류의 이벤트 키 참여 유저들을 확인할 수 있어요.</td></tr><tr><td>2</td><td>검색 기준</td><td>이벤트 키 참여 유저들의 ID, 쿠폰 중 선택하여 검색할 수 있어요.</td></tr></tbody></table>

3\. 이벤트 키 등록 화면은 아래와 같이 구성되어 있어요.

<figure><img src="/files/E9zkDkYzIkZXohgqlwcp" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="91.33333333333331">번호</th><th width="108">항목</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>이벤트 키</td><td>이벤트 키의 이름<br>(영문, 숫자 20자 이내로 입력해요)</td></tr><tr><td>2</td><td>참여 수</td><td>이벤트에 참여할 유저의 수에요.<br>(제한이 없으면 모든 유저가 참여 가능하고, <br>숫자를 입력하면 정해진 인원 수만큼 참여할 수 있어요)</td></tr><tr><td>3</td><td>유효 기간</td><td>이벤트에 참여할 수 있는 기간이에요.<br>(시작 기간이 되어야 사용할 수 있으며, <br>종료 기간이 되면 사용할 수 없게 됩니다)</td></tr><tr><td>4</td><td>설명</td><td>해당 이벤트 키에 대한 설명이에요.<br>(생략 가능합니다)</td></tr></tbody></table>

###

### 2) Script에서 이벤트 키 연동하기

1. ServerScript에서 이벤트 키의 처리를 아래와 같이 구현해요.

   ```lua
   --2. player:AddEventKey 함수에 연결되는 함수에요.
   local function DoEventKey(player, eventKeyReturnData)       
       wait(1)
       
       local state = eventKeyReturnData.State --이벤트키의 상태
       local maxCount = eventKeyReturnData.MaxCount --이벤트키의 최대 인원
       local useCount = eventKeyReturnData.UseCount --이벤트키의 참여자 수
       local result = eventKeyReturnData.Result --이벤트키 등록 결과

       --이벤트키 상태 및 등록 수
       if state == Enum.EventKeyState.Wait then
       	print("이벤트키 상태 : 대기")
       elseif state == Enum.EventKeyState.Doing then
   	print("이벤트키 상태 : 진행")
       elseif state == Enum.EventKeyState.Stop then
   	print("이벤트키 상태 : 중지")
       elseif state == Enum.EventKeyState.End then
   	print("이벤트키 상태 : 종료")
       end
       print("이벤트키 등록 수 : ", useCount, " / ", maxCount)

       --이벤트키 등록 결과가 Success이면  
       if result == Enum.EventKeyResult.Success then
           print("이벤트키를 등록했습니다!")
    
       --이벤트키 사용 결과가 Exist이면
       elseif result == Enum.EventKeyResult.Exist then
           print("이미 등록한 이벤트키입니다!")

       --이외에는
       else
           print("유효하지 않은 이벤트키입니다!")
       end
   end

   ---------------------------------------------------------------------
   --1. 콜라이더 충돌시 호출되는 함수에요.
   local function EnterTrigger(self, target)
      if target == nil or not target:IsCharacter() then
          return
      end

      local player = target:GetPlayer()

      --이벤트키에 플레이어를 등록 처리해요. 
      --(이벤트키 이름, 이벤트키 등록 처리 함수)
      player:AddEventKey("EventKeyName", DoEventKey)
   end
   BoxCollider.Collision.OnBeginOverlapEvent:Connect(EnterTrigger)
   ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ditoland-utplus.gitbook.io/ditoland/manual/coupon-event-key.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
