네번째 포켓몬, 랜드로스 구현 (유턴)
네번째 포켓몬 랜드로스를 구현해보자.
https://pikalytics.com/pokedex/homebss/landorus-therian
Landorus-Therian Series 12 Battle Stadium Singles Stats Pokédex | Pokémon | Pikalytics
Life Orb 21.800% Focus Sash 21.500% Sitrus Berry 15.200% Rocky Helmet 14.300% Lum Berry 10.800% Choice Scarf 6.900% Assault Vest 3.700% Choice Band 2.200% Leftovers 1.500% Figy Berry 0.400%
pikalytics.com
통계를 확인해본 결과
지진, 암석봉인, 칼춤 3개는 필수고,
공중날기는 저번의 에이스번과 같이 다이맥스가 구현 안되어있으므로 패스,
채용률 5위는 스텔스락, 6위는 유턴인데
유턴쪽이 더 구현하기 어려울것같아서 유턴을 구현하기로 했다.
사실 썬더를 구현할때 10만볼트보다 볼트체인지쪽이 더 채용률이 좋았는데,
"마비" 상태이상을 구현하기도 해야하고,
교체기 구현하기 귀찮아서 그냥 10만볼트로 떄운것도 있어서
이번엔 유턴을 구현해보고자 했다.
그럼 스킬을 하나하나 살펴보자면
1.지진
국민기술 지진이다.
더블 배틀이 아니라면 별다른 부가효과는 없어서 그냥 스킬 정보값만 배열에 넣으면 구현 완료
2.칼춤
자신의 공격을 2랭크 올리는 변화기이다.
if (skillname == "칼춤") {
//칼춤 : 자신의 공격을 2랭크 상승
랭크(p, pn, "공격", 2, 1);
}
"특수스킬" 함수에서,
사용 스킬 이름이 "칼춤"일때
"랭크" 함수에 공격, +2를 인자로 넣어주면 구현 끝(...)
3.암석봉인
상대방의 스피드를 100% 떨어뜨린다.
이 역시 자시안의 "치근거리기"를 구현할때 다 구현해놨으므로
스킬 정보값만 배열에 넣어서 구현 끝.
마지막 스킬 유턴!
을 구현하기 전에
특성 위협부터 간단하게 구현하고 가자
if (p[pp][0][12] == "불요의 검") {
//자시안의 불요의 검, 자신의 공격력 1랭크 상승
cout << "[특성 불요의 검]\n";
if (s == 0) cout << "상대 ";
랭크(p, pp, "공격", 1, 1);
}
if (p[pp][0][12] == "위협") {
//랜드로스의 위협, 상대방의 공격력 1랭크 하락
cout << "[특성 위협]\n";
if (s == 1) cout << "상대 ";
랭크(k, kn, "공격", -1, 1);
}
"위협" 특성은 등장시 상대방의 공격력을 1랭크 하락시키는 특성으로,
자시안의 "불요의 검"과 비슷하다.
위와 같은 특성들을 모아놓은 "즉발특성" 함수에서,
특성 이름이 "위협"일때
"랭크" 함수에 상대방 배열값, "공격", -1을 인자로 넣으면 구현 끝.
이대로 끝내면 아쉬우니 살짝 이야기를 덧붙이자면,
처음에 이러한 "즉발특성" 함수는 교체 함수 안에 넣어놨었다.
맨 처음 등장할때 말고는, 누군가와 교체할때 즉발 특성이 발동하므로,
그런데 문제가 생겼으니
내가 a를 위협 특성을 지닌 b로 교체하고,
상대가 c를 d로 교체할때
원래 순서는
a->b 교체
c->d 교체
b의 위협으로 d의 공격이 1랭크 까임
이 순서가 맞는데
즉발특성 함수를 교체 함수 안에 넣어놨다보니
a->b 교체
b의 위협으로 c의 공격이 1랭크 까임
c-> d 교체
즉 위협 특성이 없는것과 마찬가지가 된것이다.
이는 중대사항이므로 즉시 수정했다.
"즉발특성"함수를 교체함수 안에서 빼고,
교체함수와 즉발특성 함수를 동시에 호출했다.
//교체 및 특성 처리
while (1) {
if (number == 5 && snumber != 5) {//나만 교체한 경우
교체(plife, ps[0], p, ps, s, ps[1]);
즉발특성(p, ps[0], 1, s, ps[1], ps);//교체 및 특성 발동
}
else if (number != 5 && snumber == 5) {//상대만 교체한 경우
상대교체(slife, ps[1], s, ps, ps[0], p);
즉발특성(s, ps[1], 0, p, ps[0], ps);
}
else if (number == 5 && snumber == 5) {//둘다 교체한 경우
int tsspeed = 스피드비교(p, s, 1, 1);
if (tsspeed == 1) {//내가 더 빠른 경우
교체(plife, ps[0], p, ps, s, ps[1]);
상대교체(slife, ps[1], s, ps, ps[0], p);
printf("\n");
즉발특성(p, ps[0], 1, s, ps[1], ps);//내 특성 먼저 발동
즉발특성(s, ps[1], 0, p, ps[0], ps);
}
else if (tsspeed == 0) {//상대가 더 빠른 경우
교체(plife, ps[0], p, ps, s, ps[1]);//상대 먼저 교체하면 상대가 무엇으로 교체했는지 텍스트가 뜬다.
상대교체(slife, ps[1], s, ps, ps[0], p);//이를 막기 위해 상대가 빨라도 교체는 플레이어 먼저.
printf("\n");
즉발특성(s, ps[1], 0, p, ps[0], ps);
즉발특성(p, ps[0], 1, s, ps[1], ps);
}
else
printf("startspeed 오류, main파일, id 3283524\n");
}
break;
}
메인 함수에서 플레이어와 cpu가 행동을 선택하고,
배틀에 들어가기 전 교체 파트의 코드이다.
한쪽만 교체했다면 별 상관 없고,
둘이 동시에 교체했다면
교체 - 상대교체 - 스피드가 빠른쪽 특성 - 스피드가 느린쪽 특성
이와 같은 순서로 진행되게 구현하였다.
교체도 특성과 마찬가지로 스피드가 빠른쪽부터 하는게 맞다만..
상대방이 더 빠르다고 상대교체 - 교체 순으로 함수를 호출하면
상대방이 누구로 교체하였는지 확인하고 교체하게된다.
이건 인게임과 심각한 차이가 발생하므로
상대가 더 빠르더라고 교체는 플레이어부터 하도록하였다.
다만 스피드가 빠른쪽 먼저 교체하는것도 나름의 전략으로서 쓰이기에
왠만하면 구현하고싶다만...
이를 수정하려면 교체 함수랑 메인함수를 전체적으로 수정해야하는데
너무 고칠게 많다...
이는 나중에 생각나면 고치도록 하고...
쨌든 랜드로스의 마지막 스킬 유턴을 구현해보았는데,
일단 유턴은 상대방을 공격하고, 다른 포켓몬으로 교체하는 스킬이다.
교체 심리전을 상당히 수월하게 풀어나가게 해주는 중요한 스킬이다.
그래서 이를 구현하는건...
if (a[aa][skillnumber][6] == "교체") {
//공격 후 바로 교체하는 스킬
if (s == 1) {//내 포켓몬이 사용한 경우
cout << a[aa][0][11] << s1(a, aa) << "내 곁으로 돌아왔다!\n";
교체(alife, aa, a, ps, b, bb);//"교체" 함수 호출
즉발특성(a, ps[0], 1, b, bb, ps);
}
else {//상대 포켓몬이 사용한 경우
cout << a[aa][0][11] << s1(a, aa) << "상대 곁으로 돌아갔다!\n";
상대교체(alife, aa, a, ps, bb, b);//"상대 교체" 함수 호출
즉발특성(a, ps[1], 0, b, bb, ps);
}
}
금방 끝났다.
정확히는 "교체" 함수와 "상대교체" 함수를 이때 대대적으로 수정하였는데
https://khs20010327.tistory.com/22
"교체" 함수 구현
배틀 시스템의 기초가 되는 대부분의 함수는 설명이 끝났다. 딱 하나 남았는데, 바로 "교체" 함수이다. 처음에 교체 함수는 교체가 아니라 "기절" 함수였다. 포켓몬을 교체하는 순간은 크게 3가지
khs20010327.tistory.com
이는 이전글에서 설명하였고...
큰일이다. 설명을 해당 글에서 다 해버려서 설명할게 없다.
유턴은 그냥 "부가효과" 함수에서 "교체", "상대교체" 함수를 호출하면 끝이다.
교체 이후 "즉발특성" 함수도 같이 호출해주고.
아 이야기할게 살짝 생겼다.
상대교체(alife, aa, a, ps, bb, b);//"상대 교체" 함수 호출
즉발특성(a, ps[1], 0, b, bb, ps);
두 함수의 인자를 잘 보면
상대교체에선 포켓몬 번호로 aa를,
즉발특성에선 포켓몬 번호로 ps[1]을 준것을 알 수 있다.
이렇게 한 이유는,
지금까지는 함수 안에 함수 안에 함수를 호출하는 방식이였지
위와같이 두 함수를 병렬적으로 호출하는 경우가 거의 없었다.
그래서 생긴 문제가
상대교체 함수에서 포켓몬을 교체하므로 필드 위 포켓몬의 번호인, aa값이 변경되는데
그렇다고 즉발특성에 aa를 그대로 인자에 넣어도 변경된 값이 적용되지 않는다.
이 aa 값은 "부가효과" 함수에 인자로 주어진 값으로, 상대교체에서 수정해도 즉발특성 함수에 반영되지 않기 때문이다.
그래서 해결법은, 그냥 어디서 값을 수정하든 바로 수정된 값이 적용되는
배열 값을 넣으므로 간단하게 해결.
간단하게 해결된것에 비해 고치기 전에 문제는 심각했다.
자시안을 랜드로스로 교체하면
즉발특성에 랜드로스의 버호가 들어가 "위협" 특성이 발동해야하는데
자시안의 "불요의 검" 특성이 발동되지 않는가...
순간 멘붕이 왔지만 의외로 문제점은 금방 찾을수 있어서 다행이였다.
맞다, 유턴떄문에 또 다른 버그가 발생했는데,
이는 유턴 보다는 메타몽때문에 발생한 문제라,
다음 글 메타몽에서 이야기를 이어가고자 한다.
근데 랜드로스 지닌물건으로 열매 주지 않나,
통계를 확인해보니 생구나 기띠가 훨씬 높다.
생구는 저번에 썬더에서 구현 완료헀으니... 아이템도 구현할게 없다.
스텔스록이라도 구현해놓을걸 그랬나.
일단 생략하고 다음 구현으로 넘어가자.
일단 해당 랜드로스는 공격에 집중한 형태이니,
나중에 열매와 스텔스록을 채용한 방어적 형태를 추가로 구현해봐야겠다.
구현 완료된 모습