Replay
카테고리
작성일
2026. 3. 2. 07:30
작성자
이네젠트

 

*코딩을 할 줄 모르는 사람들이 제미나이로 가볍게 만든 스크립트라 오류가 발생해도 해결해드리기 힘들 수 있습니다...

*코코포리아 컷인이 너무 예뻐서 쓰고 싶었는데 코코포리아랑 안 친함 이슈로 만들었습니다... (나도 친해지고 싶다)

*API 스크립트이기 때문에 Roll 20 프로 계정이어야 사용 가능합니다.

*롤꾸는 필수가 아닙니다!

 

*모르는 게 많습니다... Roll 20에서 컷인 스크립트 등의 사용이 금지라면 알려주세요..!

 

*설명이 많이 조잡합니다. 만약 이해 안 되는 부분이 있다면 말씀해주세요, 최대한 어휘력을 살려보겠습니다.

 


적용 방법

1. 스크립트 적용

 

설정 -> 모드 스크립트

 

언제나처럼 새로운 스크립트를 추가 해주시면 됩니다.


2. 이미지 파일 적용

01

- 이미지 주소는 med.png / med.webm 중으로 설정해주셔야합니다.

ㄴ 기존 파일주소의 확장자 명에 med를 써주셔도 됩니다. 예) 34809.png -> 34809/med.png 

 

- png를 사용하실 경우에는 아래 스크립트를 그대로

webm 파일을 사용하실 경우 - 3. 컷씬 연출 설정 가장 하단의 "max.png", "thumb.png" 와 "med.png", "thumb.png" 의 확장자 명을 각각 webm으로 변경해주시면 됩니다. 

예) max.png -> max.webm

 

*제대로 적용이 되었다면 주사위를 굴렸을 때 자동으로 이미지가 생성되고 사라집니다.

*패널티, 보너스 주사위의 경우 가장 하단(-2 주사위)의 결과값으로 출력됩니다...


3. 스크립트 설정

이미지 파일의 크기, 진행하는 탁의 크기 등을 고려하셔서 크기를 조절하시면 됩니다.

관련된 설정은 4. 컷씬 이미지 생성, 5. 애니메이션 효과 입니다.

 


*스크립트

on("chat:message", function(msg) {
    if (msg.type === "general" && msg.rolltemplate && msg.rolltemplate.indexOf("coc") !== -1) {
        if (!msg.inlinerolls) return;

        // 1. 결과값 계산 (대성공, 대실패 등)
        let rollResult = null;
        let targetValue = null;
        msg.inlinerolls.forEach(roll => {
            const hasDice = roll.results.rolls.some(r => r.dice === 1 && r.sides === 100);
            if (hasDice) rollResult = roll.results.total;
            else if (targetValue === null || roll.results.total > targetValue) targetValue = roll.results.total;
        });

        if (rollResult === null || targetValue === 0) return;

        // 2. 판정별 컷씬 이미지 설정 (본인의 이미지 주소로 교체)
        let imageUrl = "";
        if (rollResult === 1) imageUrl = "대성공_이미지";
        else if ((targetValue < 50 && rollResult >= 96) || rollResult === 100) imageUrl = "대실패_이미지";
        else if (rollResult <= Math.floor(targetValue / 5)) imageUrl = "거대성공_이미지";
        else if (rollResult <= Math.floor(targetValue / 2)) imageUrl = "어려운성공_이미지";
        else if (rollResult <= targetValue) imageUrl = "보통성공_이미지";
        else imageUrl = "실패_이미지";

        if (imageUrl === "" || imageUrl.indexOf("http") === -1) return;

        // 3. 컷씬 연출 설정
        let currentPageId = Campaign().get("playerpageid");
        let page = getObj("page", currentPageId);
        
        // 맵의 중앙 좌표 계산
        let centerX = (page.get("width") * 70) / 2;
        let centerY = (page.get("height") * 70) / 2;

        let cleanUrl = imageUrl.replace("max.png", "thumb.png").replace("med.png", "thumb.png");

        // 4. 컷씬 이미지 생성 (처음에는 작게 시작)
        let cutsceneImg = createObj("graphic", {
            _pageid: currentPageId,
            imgsrc: cleanUrl,
            left: centerX,
            top: centerY,
            width: 100, // 시작 크기
            height: 100,
            layer: "frontoverlay", // 가장 위 레이어 (없으면 'objects')
            isdrawing: true
        });

        // 5. 애니메이션 효과 (커지면서 나타남)
        let size = 100;
        let interval = setInterval(() => {
            size += 40; // 점점 커짐
            if (cutsceneImg) {
                cutsceneImg.set({
                    width: size,
                    height: size
                });
            }
            
            // 일정 크기 이상 커지면 정지 및 삭제
            if (size > 600) { 
                clearInterval(interval);
                setTimeout(() => {
                    if (cutsceneImg) cutsceneImg.remove();
                }, 1000); // 1초 대기 후 삭제
            }
        }, 30); // 0.03초마다 크기 변경
    }
});