소스모드를 어느정도 한다는 기준하에 좀비한테 훅을 건다고 치자.
이때 걸만한 훅은 플레이어와 대동소이할것이다.
스폰, 데스, 데미지 이 세가지만 훅을 걸어도 대부분의 상황에 응용할수있을것이다.
그런데 문제가 있다. 레포데2는 코드상 좀비가 같은좀비가 아니다. 좀 까다롭다.
간단하게 설명하자면, 1) 일반좀비 + 위치 2) 그외 특수좀비(탱크, 스피터, 헌터, 자키, 등등) 으로 나뉜다.
코드를 작성하는 입장에서 한곳에서 관리하면 편할것을 두개로 나뉘어 코딩해야 한다는점이 참으로 짜증날뿐이다.
왜 이럴까? 뇌피셜이지만 레포데2는 코옵뿐만 아니라 PVP(인간 대 좀비[플레이어])모드도 지원한다. 이때 좀비인 플레이어는 길바닥에서 흔히보이는 일반좀비가 아니라 스피터, 헌터등과 같은 무조건 특수좀비다.
실제로 인게임에서 특수좀비의 클래스 이름은 다름아닌 player 이다. 이는 플레이어의 클래스와도 갔다.
참으로 아이러니하다.
아래에 간단하게 표로써 정리해보았다.
앞서 말한바와 마찬가지로
일반좀비와 위치만 별도의 클래스를 가지고 있고 나머지 좀비는 플레이어와 같다.
따라서 좀비를 대상으로 작업을 하려면 나뉘어서 작업해야한다는 말이 된다.
서론이 길었다 본론으로 들어가 실제 코딩하는 알고리즘에 대해 설명하고자한다.
1. 일반좀비와 위치
- OnTakeDamage : OnEntityCreated안에 클래스 이름을 지정하여 훅을 걸어준다. (확실)
public OnEntityCreated(entity, const String:classname[])
{
if(StrEqual(classname, "infected", false))
{
SDKHook(entity, SDKHook_OnTakeDamage, OnEntityTakeDamage);
}
}
- 스폰 : 위의 온테이크 데미지를 보면 OnEntityCreated를 통해 훅을 걸었다. 위 코드에 추가적으로 적으면될듯 (뇌피셜)
- 데스 : 플레이어한테 거는 훅이벤트 "player_death"를 걸어줘야한다. (확실)
public OnPluginStart()
{
HookEvent("player_death", Event_Death, EventHookMode_Pre); //플레이어 및 일반좀비 해당
}
public void Event_Death(Event event, const char[] name, bool dontBroadcast)
{
int Attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
int Client = GetClientOfUserId(GetEventInt(event, "userid"));
int Target = event.GetInt("entityid");
if(Target != -1 && Target > MaxClients) //일반좀비가 뒤진경우
{
if(IsValidEntity(Target))
{
char ClassName[64];
GetEdictClassname(Target, ClassName, sizeof(ClassName));
if(StrContains(ClassName, "infected", false) != -1)
{
PrintToChatAll("일반좀비조짐");
PrintToChatAll("일반좀비조짐:공격자 %N", Attacker);
}
else if(StrContains(ClassName, "witch", false) != -1)
{
PrintToChat(Attacker, "위치뒤짐");
}
}
}
}
2. 그외 특수좀비
특수좀비는 아직 잘모르겠다. 일단 아는 정보를 적어 놓겠다.
소스모드 API에서 레포데 이벤트 리스트를 살펴보자. ( 클릭시 이동 )
그중 일부 "infected_death", "infected_hurt"가 있는데 이름만 보면 좀비가 쳐맞거나 뒤질때 모두 체크해줄것같다.
하지만 테스트 결과는 실망스러웠다.
- 일반좀비 뒤질때 뒤진좀비의 객체번호(index)를 출력시키면 무조건 0으로 출력됨. 아무것도 아닌것같지만 대단히 큰 문제다. 플레이어, 일반좀비, 탱크 등 각 개체는 고유번호를 가지고있다. 근데 0이 나온다? 이거는 서버자체의 ID값이다.
위 문제를 해결하기 위해서는 위에서 언급한 player_death에서 체크할수있다. (확실)
- OnTakeDamage : 훅이 안걸린다 이유를 모르겠다. 나중에 알게되면 적겠음.
- 스폰 : 확실해지면 적겠음.
- 데스 : 확실해지면 적겠음.
글을 마치며 . . .
긴 글 읽어줘서 고맙다. 테스트 및 구글링을 하며 정보가 확실해지는 데로 이어서 포스팅 하겠다. 오늘은 여기까지