SCM player skins Line Up: [드래프트 강좌] 광역 회복 스킬을 만들어보자

2/18/2015

[드래프트 강좌] 광역 회복 스킬을 만들어보자


결과













요약

  • 배틀쿠르저에 Carrier Stop 명령을 하는 버튼을 추가.
  • scbw::UnitFinder(int left, int top, int right, int bottom) : 주어진 구역 안의 유닛들을 찾음.
  • unit->hitPoints : 해당 유닛의 체력 (1hp=256)
  • unit->sprite->createTopOverlay(이미지 ID) : 해당 이미지 오버레이를 유닛 위에 생성









내용

일단 먼저 Firegraft를 켜서 배틀쿠르저에 버튼을 추가해줍니다. 저는 07 위치에 하나 추가했습니다. 버튼의 내용은 Carrier Stop이나 Reaver Stop처럼 적당한 것들로 적용합니다. 다른 버튼들을 적용해도 되는데 굳이 Carrier Stop같은 걸 하는 이유는 개그맨이야님의 GAG Mania Draft나 버닝그라운드의 플러그인 오픈소스(https://code.google.com/p/gptp/source/browse/)를 보면 Carrier Stop이나 Reaver Stop버튼을 사용해 새로운 기능이나 스킬을 만들길래 저도 똑같이 따라했습니다.ㅎㅎ.. 오픈소스니까 상관없겠죠 뭐...










그리고 Dat Requirements 탭으로 들어가셔서 [52]Carrier Stop 명령을 배틀쿠르저도 사용할 수 있도록 설정합니다.











광역 회복 스킬을 만들기 위해서는 주위의 유닛들을 하나하나 읽어야 합니다. GPTP에서는 다음 메서드를 지원합니다. scbw 네임스페이스에 UnitFinder 메서드가 정의되어 있습니다. 사용하기 위해서는 #include <SCBW/UnitFinder.h>를 추가해야합니다.
UnitFinder();
UnitFinder(int left, int top, int right, int bottom);
UnitFinder 메서드를 이용해 유닛들을 찾으면 하나씩 순회해야합니다. 그러기 위해서 다음 forEach 메서드를 사용할 것입니다.
template <class Callback>
void forEach(Callback &func) const;

이를 이용해 일단 주위 유닛들을 찾는 코드를 작성합시다.
if (unit->id == UnitId::battlecruiser && unit->mainOrderId == OrderId::CarrierStop) {
 u32 distance = unit->getMaxWeaponRange(unit->getGroundWeapon());
 scbw::UnitFinder unitsToHeal(
  unit->getX() - distance, unit->getY() - distance, 
  unit->getX() + distance, unit->getY() + distance );

 unitsToHeal.forEach([] (CUnit* target) {
 });
}

유닛이 배틀쿠르저이고 Carrier Stop 버튼을 눌렀을 때 인식합니다. 유닛을 찾을 범위는 배틀쿠르저의 지상무기 사거리(distance)로 설정하였습니다.









그럼 이제 forEach를 통해 배틀쿠르저 주변의 유닛들을 순회하면서 체력을 회복시키는 코드를 짜봅시다. 사용할 것들은 다음과 같습니다.

unit->hitPoints : 유닛의 현재 체력 (1hp=256)
unit->sprite->createTopOverlay(이미지 ID) : 해당 이미지 오버레이를 유닛 위에 생성
units_dat::MaxHitPoints[유닛 ID] : 해당 유닛의 최대 체력
if (unit->id == UnitId::battlecruiser && unit->mainOrderId == OrderId::CarrierStop) {
 u32 distance = unit->getMaxWeaponRange(unit->getGroundWeapon());
 scbw::UnitFinder unitsToHeal(
  unit->getX() - distance, unit->getY() - distance, 
  unit->getX() + distance, unit->getY() + distance );

 unitsToHeal.forEach([unit] (CUnit* target) {
  if (target->playerId == unit->playerId) {
   if ((units_dat::MaxHitPoints[target->id] - target->hitPoints) < 12800)
    target->hitPoints = units_dat::MaxHitPoints[target->id];
   else
    target->hitPoints += 12800;
   target->sprite->createTopOverlay(ImageId::UnusedHeal_Small + scbw::getUnitOverlayAdjustment(target));
  }
 });
}
치료할 유닛이 같은 플레이어의 유닛이면 유닛의 체력을 50만큼 회복시킵니다. 체력을 50 회복시켰을 때, 최대체력을 넘기면 안되므로 최대체력과 현재체력의 차이가 50이하이면 현재체력을 최대체력으로 설정하고, 아닐 경우에는 현재체력에 50만큼의 체력을 더합니다. 이 때, 회복하는 이미지를 생성할 건데 [970]Heal(Small) 이미지를 사용합니다. 유닛의 크기에 따라 이미지의 크기를 다르게 하였는데, 자세한 내용은 http://cafe.naver.com/sdraft/70745 참고바랍니다.







프로젝트를 빌드하고 'GPTP.qdp'파일을 Firegraft를 이용하여 플러그인 해줍니다. 그리고 드래프트를 실행하면 다음과 같이 정상적으로 작동함을 확인할 수 있습니다.


댓글 없음:

댓글 쓰기