상태 이상 기반 자체는 꽤 오래전에 다져 놨으나, 항상 처리되는 상태 이상을 조금 고민하던 와중에 해결책이 떠올랐고, 일단 상태이상 시스템을 완성함
모든 상태이상은 enum으로 관리함. 상태 이상의 적용 시점과 사용성을 모두 고려하여 이런 방식으로 해두었음
추가적으로 카테고리 분류를 위한 배열이라던가 특정 조건에서 체크해야 할 "부정적 효과" 를 위한 해쉬셋
그리고 Delegate return용 매핑 함수를 만들었음. Dictionary가 아니라 Switch-Case를 쓴 이유는 TryGetValue하기가 매우 귀찮기도 하고 코드 일관성을 확보 가능하기도 해서...
기본적인 상태 효과 추가 함수. 볼 건 그다지 없고, 추가 및 갱신 예외 처리나 UI갱신을 위한 대리자 정도만 존재함. 적들은 아직 리팩터링 덜 끝내서 못 넣음 ㅋㅋ
상태 이상 갱신 함수. 이것 말고도 _rdc = 1로 잡은 파라미터가 없는 함수도 있음. 순서를 보장하기 위해, enum을 통해 실행되는 타이밍을 정렬했기에 "함수 등록 -> 대리자 덮어쓰기" 를 반복하는 구조로 간단하게 만들 수 있었음.
DoesSeAffectUnit을 통해 대리자에 등록할 함수를 분류함. 예를 들어 "부정적 효과 + 무적" 상태면, 애초에 대리자에 등록이 안되서 효과를 발휘하지 못하도록 했고,
이 함수에 한해서는 후술할 ALWAYS의 실행이 필요하지 않아서 제외함.(ALWAYS 타이밍에 등록된 함수들은 턴 시작과 동시에 호출되며, 따라서 이 함수 실행이 끝나면 흐름에 따라 알아서 실행될 것이기 때문)
지금 보니까 RefreshStats는 Stat 갱신하면서 지워도 됐는데 깜빡하고 안 지웠다 ㅋㅋㅋ
이건 그냥 유틸리티 함수임 아까 말했던 무적 + 부정적 효과도 위처럼 처리하는거고
아래는 그냥 지속시간 반환하는 함수
AddEffect는 뭐 함수 넣고 RefreshStatusEffect 돌려도 됐겠지만, 그래도 최적화 조금 해준답시고 카테고리 분류해서 그 부분만 갱신하도록 했고,
RemoveEffect 같은 경우에는 카테고리 delegate에서 메서드를 제거해도, 순서가 깨질일 없기 때문에 그냥 직접 빼줬음.
주석 처리된 GetSubEffect는 글쓰다가 발견함 ㅋㅋ
ALWAYS 카테고리에 있는 함수들에 한해서, 등록 즉시 갱신해야하기 때문에 Add와 Remove 모두 if문으로 분리해서 처리했음.
실제 사용될 상태 이상 함수들. Main과 Sub를 통해서, 타이밍 관리를 추가적으로 해주도록 함. 이 구조는 효과 시점과 효과 종료 시점을 좀 더 유연하게 설정하기 위해서 만듬.
Faint같은건 호출 즉시 효과 적용 -> Sub 등록 -> RefreshStatusEffect를 통해 갱신 -> 턴 시작 시 Sub 호출 (ALWAYS_SUB 타이밍을 의도적으로 ALWAYS 타이밍보다 먼저 호출하도록 만듬) -> 지속 시간이 존재하여 대리자에 존재한다면 호출
이런 식으로 턴 시작 시점에 갱신하는 방식으로 아무 때나 적용 시 효과 적용 + 턴 기반 지속을 구현함.
Enforce는 공격 직전에 공격력 * 1.5 이후 공격력 정상화, Burn은 공격 직후에 체력 -1을 구현하기 위해 그냥 동일하게 BEFORE_ATTACK 타이밍에 Main을 넣고, Sub함수를 통해 AFTER_ATTACK 시점에 다시 효과 적용 및 복원을 구현함. 상태 이상을 BEFORE_ATTACK, AFTER_ATTACK 으로 분류하면 너무 더럽기도 하니까.
Invincible 같은 경우에는 모든 Sub함수의 방식을 통일한다는 전제 하에서 저렇게 만들 수 있었음 모든 Sub 함수는 호출 시 자신이 등록된 델리게이트에서 반드시 자신을 제거하고, Main함수가 적용되었다는 플래그가 존재하면, 복원을 담당하는 형식임. (Burn같은 예외도 있긴 하지만). 이후 RefreshStatusEffect(0) (지속시간이 줄지 않는 갱신)을 통해서, 부정적인 효과를 적용되지 않게 만듦. 물론 무적이라 체력 감소 방지 처리 이런 것도 해야겠지만, 일단은 나중으로 미루어둠... 아마도 CurHP 프로퍼티의 set에 직접 DoesSeAffectUnit 플래그를 체킹하는 식으로 구현 할듯?
아무튼 이렇게 구현된 놈들을 플레이어 유닛의 이펙트 관련 클래스에 넣어주고
이런 식으로 간접적으로 등록해주고(이 역시 순서 보장을 위해서임)
또한 플레이어 유닛은 ON_MY_TURN_END 타이밍의 액션과 상태효과 갱신을 OnEnemyPhaseEnds에 실행되도록 했지만,
적 유닛은 ON_MY_TURN_END 타이밍의 액션을 OnPlayerPhaseEnds에 등록했음. 물론 아직 리팩토링 덜 끝나서 아직 테스트는 못해봤지만...
이제 구현은 끝났으니 대충 테스트 코드 넣고 돌려봤음
일단 유닛의 스탯을 이렇게 잡아두고
기절 -> 시야 감소 + 행동력 0으로 제한
무적 획득 즉시 기절 효과 무효화 (행동력 감소까지는 무효화하지 못하게 할거임) 기절 상태는 Flag 기반으로 아이템 사용 및 드랍등의 제한도 걸려있어서, 해제 하고나면 행동력 회복 아이템 등을 사용할 수 있음
다만, 무적이 기절 전에 걸렸다면 무효화 가능
강화 -> 3~3 데미지 - 방어력 3 이라 데미지가 0이여야 하지만, 강화를 적용해 3*1.5를 반올림해서 5가 됐기에 2데미지가 들어가는 모습.
출혈 (행동력 감소 시 데미지 1)
화상(공격 시 데미지 1, 테스트를 위해 일부러 공격이 행동력을 소모하지 않게 해놓음)
독과 맹독 적용 이후 턴 갱신 (독은 턴 종료 1데미지, 맹독은 턴 종료 시점 남은 지속 시간만큼 데미지 이긴 한데, 둘 다 1이라 최종적으로 2만 감소했음)
아마 나중에 필요하면 Main - Sub를 묶어서 하나의 클래스로 만들고, 함수에 들어가는 수치를 커스텀 가능하게 만들수도 있을듯?
저거 캐릭터 위 아이콘 중에 마더 스타맨처럼 생긴 사람 서있는 그림이 무적인가? 무적이라고 잘 안 느껴지는데 방패나 다른 모양으로 바꾸는 건 어떤가여?
방패 아이콘 쓰는 게 방어력 강화 효과가 있어서... 고민 좀 하다가 넣었어요 ㅋㅋ 상세 스탯에서 이펙트 아이콘 자체는 확인 가능하게 해둘거라 일단은 냅두려구요
뭔가 더 강해보이면 좋을 것 같아여
방사형으로 퍼지는 빛줄기 같은거 좀 넣어봐야겠네요
우리도 버프 시스템 슬슬 체계화해야되는데 종류대분류/발동시점분류/연결 착착 해두신거 되게 이쁘다
버프시스템 분류 시점 너무 나누면 그것대로 힘들어져서 그냥 Main-Sub 구조로 관리하게 해뒀어요 ㅋㅋ Sub만 잘 제어해주면 공격시 버프 주고, 턴 종료시 버프 해제등도 가능해요
지금은 일단 그럴일 없을거같아서 보류중인데, 나중에 Sub함수들도 순서 관리 필요할거같으면 메서드 만들어야하고 함수 자체의 커스터마이징을 위해서 class로 다루는 방식도 고려중이에요 ㅋㅋㅋ