조건문 (Conditional Statements)
epScript의 조건문은 파이썬·자바스크립트와 같습니다. if, else if, else 구문과 논리 연산자 &&, ||, !를 사용해 분기합니다. &&/||는 단락 평가(Short‑circuit)를 하므로 조건의 순서에 따라 성능과 동작이 달라질 수 있습니다.
기본 형태
if (조건식) {
// 조건식이 참일 때 실행
} else if (다른_조건식) {
// 앞의 if가 거짓이고, 이 조건식이 참일 때 실행
} else {
// 모든 조건이 거짓일 때 실행 (선택)
}
조건식에는 비교문 또는 비교문으로 해석 가능한 표현식을 넣습니다.- 블록은
{ ... }로 묶습니다. 한 줄이라도 가독성을 위해{}사용을 권장합니다.
var hp = 35;
if (hp <= 0) {
simpleprint("Dead");
} else if (hp < 30) {
simpleprint("Critical");
} else if (hp < 60) {
simpleprint("Wounded");
} else {
simpleprint("Healthy");
}
비교 연산과 진릿값
- 비교:
==,!=,<,>,<=,>= - 논리:
&&(그리고),||(또는),!(부정)
var a = 10;
var b = 5;
if (a > b && a - b >= 5) {
simpleprint("OK");
}
if (!False) {
simpleprint("True로 평가됨");
}
단락 평가(Short‑Circuit)
&&와 ||는 필요할 때만 오른쪽 피연산자를 평가합니다.
A && B: A가 거짓이면 B는 평가하지 않음(결과는 거짓)A || B: A가 참이면 B는 평가하지 않음(결과는 참)
function isExpensive() {
simpleprint("비싼 검사 수행");
return True;
}
var alive = False;
// alive가 거짓이므로 오른쪽은 평가하지 않음
if (alive && isExpensive()) {
simpleprint("실행되지 않음");
}
var ready = True;
// ready가 참이므로 오른쪽은 평가하지 않음
if (ready || isExpensive()) {
simpleprint("빠르게 통과");
}
성능을 위한 조건 순서
&&에서는 실패(거짓) 가능성이 높고 계산이 싼 조건을 왼쪽에 둡니다.||에서는 성공(참) 가능성이 높고 계산이 싼 조건을 왼쪽에 둡니다.- 이렇게 하면 불필요한 계산을 피할 수 있습니다.
예시: 조건 순서에 따른 차이
function isBossInArea(unit) {
// 매우 비싼 판정이라고 가정
return l2v(Bring(...));
}
function isBoss(unit) {
// 값싼 판정: 바로 확인 가능
return unit.ammo > 0;
}
// 비효율적인 순서: 매번 비싼 검사를 먼저 수행
if (isBossInArea(u) && isBoss(u)) {
simpleprint("공격!");
}
// 더 나은 순서: 값싼 조건을 먼저 확인하여 단락 유도
if (isBoss(u) && isBossInArea(u)) {
simpleprint("공격!");
}
switch
클래식 스타 트리거에서는 else 자체를 직접 구현할 수 없습니다. 반면 if(조건) 개념은 트리거의 근간이므로 epScript의 if/else if는 이해만 되면 활용이 어렵지 않습니다. 특히 if → else if 사슬을 잘 구성하면
- 어떤 분기에서 한 번 참을 만나면 뒤의
else if들은 평가하지 않으므로, 불필요한 비교를 피할 수 있습니다. - 즉, “참일 확률이 높거나 값싼 검사”를 앞쪽에 두는 것만으로도 성능 이점을 얻습니다.
이 때문에 “if/else만 알면 switch는 굳이 배울 필요가 없다”고 느낄 수 있지만, epScript의 switch는 더 강력한 형태를 제공합니다.
epScript의 switch(state, bitmask)
epScript는 switch(state, bitmask) 형태와 epd 를 읽고 비교하는 epdswitch(epd, bitmask)를 지원합니다. 스타 트리거에는 Memory, SetMemory는 있지만 일반적인 의미의 GetMemory는 없습니다. 실전에서는 “메모리 값을 읽어오는 행위” 자체가 비용이 큽니다(자료형 섹션에서 한 번 다뤘던 주제). bitmask는 다음 이점을 제공합니다.
- 읽기 범위를 비트 단위로 제한하여 “안 읽어도 되는 부분”을 명시합니다.
epdswitch는 값 읽기와 비교를 한 번에 수행하므로,bread_epd/wread_epd/dwread_epd로 값을 읽고 다시 비교하는 패턴보다 빠릅니다.
사용 예시
아래는 유닛 상태가 저장된 메모리 영역 중 필요한 하위 바이트만 마스크로 제한하여 빠르게 분기하는 예시입니다.
function getUnitSkillRange(epd){
var unit;
var skill_range;
// unitTpye: epd + 0x64 위치, 하위 1바이트만 필요하므로 0xFF
epdswitch(epd + 0x64 / 4, 0xFF) {
case 2: {
// 예: 2 == Ghost
unit = 2;
skill_range = 100;
break;
}
case 64: {
// 예: 64 == 질럿
unit = 64;
skill_range = 15;
break;
}
default: {
unit = 0;
skill_range = 0;
break;
}
}
}
// 이후 로직에서 unit/skill_range 사용
if (unit != 0 && skill_range > 0) {
simpleprint("선택된 unit=", unit, ", range=", skill_range);
}
동일한 분기를 if/else if 사슬로 작성하면, 매 분기마다 값을 읽고 비교하는 비용이 누적될 수 있습니다. 반면 epdswitch는 “읽기+비교”를 한 번에 처리하고, bitmask로 필요한 비트만 제한하여 불필요한 읽기를 줄입니다.
if/else vs epdswitch 선택 가이드
- 값이 이미 지역 변수로 있고 비교만 하면 되는 경우:
if/else if가 간단하고 빠릅니다. - 메모리/EPD에서 직접 값을 판별해야 하는 경우:
epdswitch(epd, bitmask)로 “읽기+비교”를 한 번에 처리하세요. bitmask는 필요한 비트만 읽도록 범위를 좁혀 성능을 챙겨줍니다.