목요일, 10월 19, 2006

Purpose: Command Menu 만들기(CS 처럼)

Command Menu 만들기(CS 처럼)

Purpose: Command Menu 만들기(CS 처럼)
Author: godmode2k (godmode2k@hotmail.com | MSN IM)
Date: July. 25. 2004
Destination: 모드나라 (http://mod.zoa.to)
Source: http://www.thewavelength.net/forums/oldthreads/007197.html
http://forums.bots-united.com/archive/index.php/t-1617
http://u.glassfish.net/~elf/Botman_Forum/2%20Bot%20developer's%20discussions/209.txt
http://u.glassfish.net/~elf/Botman_Forum/2%20Bot%20developer's%20discussions/3034.txt
http://www.thewavelength.net/forums/oldthreads/000248.html

SDK: HL1 SDK 2.3
Code: Single-Player Source
Tested: Steam based

(*)Special thanks to:
- botman @ http://www.bots-united.com
- daas Lead Programer|Liquid Fire Productions @ http://www.planethalflife.com/assignment





Description:
이 예제는 지난번 tutorial "게임내에서 wave 파일을 재생하자!"
주소는: http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=49
에서 작성을 하신 다음에(필히 참조) 아래의 내용을 보시면 이해가 빠르실 것입니다.

[ 주의 ]
* 여기에서의 라디오 메시지는 자신의 PC에서 밖엔 소리가 나지 않습니다.
code를 추가해 줄 때,

// CMD_MENU: RadioMenu [
// CMD_MENU: RadioMenu ]

사이 부분의 code를 추가해 주시면 됩니다

그럼 code를 작성해 보겠습니다.




파일명: C:/Games/Sierra/Steam/SteamApps/Steam_ID_(스팀계정)/half-life/My_MOD_NAME_(모드)/config.cfg
code:
CMD_MENU: RadioMenu [
bind "z" "radio1"

- slot0, 1, 2, 3, 9가 있는지 확인. 없다면 추가 (대부분 1 - 5 까지는 있을 것입니다.)
bind "0" "slot10"
bind "1" "slot1"
bind "2" "slot2"
bind "3" "slot3"
bind "4" "slot4"
bind "5" "slot5"
bind "6" "slot6"
bind "7" "slot7"
bind "8" "slot8"
bind "9" "slot9"
CMD_MENU: RadioMenu ]

- 그런데, 써놓고 보니 1 - 5 까지만 있어도 문제가 없어 보입니다.
- 마지막에 보시면 아시겠지만 slot1 - slot10 이라는 string을
SDK의 "menuselect" 변수에서 체크를 못합니다. 그래서 숫자를 문자로 사용합니다.
"1", "2", ... 이렇게 말이죠...



파일명: player.h
함수위치:
class CBasePlayer : public CBaseMonster
{
public:

code:
// CMD_MENU: RadioMenu [
void UTIL_ShowMenu( edict_t *pEdict, int slots, int displaytime, bool needmore, char *pText );
// CMD_MENU: RadioMenu ]



파일명: player.cpp
함수위치: 전역변수로 선언
code:
// CMD_MENU: RadioMenu [
int gmsgShowRadioMsgMenu = 0;
// CMD_MENU: RadioMenu ]



파일명: player.cpp
함수위치:
void LinkUserMessages( void )
{
...
}
이 함수 아래
code:
// CMD_MENU: RadioMenu [
void CBasePlayer :: UTIL_ShowMenu( edict_t *pEdict, int slots, int displaytime, bool needmore, char *pText )
{
if (gmsgShowRadioMsgMenu == 0)
gmsgShowRadioMsgMenu = REG_USER_MSG( "ShowMenu", -1 );

while (strlen(pText) >= 64)
{
MESSAGE_BEGIN(MSG_ONE, gmsgShowRadioMsgMenu, NULL, pEdict);
WRITE_SHORT(slots);
WRITE_CHAR(displaytime);
WRITE_BYTE(1);

for (int i = 0; i <= 63; i++)
WRITE_CHAR(pText[i]);

MESSAGE_END();

pText += 64;
}

MESSAGE_BEGIN(MSG_ONE, gmsgShowRadioMsgMenu, NULL, pEdict);
WRITE_SHORT(slots);
WRITE_CHAR(displaytime);
WRITE_BYTE(needmore);
WRITE_STRING(pText);
MESSAGE_END();
}
// CMD_MENU: RadioMenu ]



파일명: client.cpp
함수위치: 전역변수로 선언
// CMD_MENU: RadioMenu [
char *slc_menu = {
"Grunt Radios\n\n\
1. Enemy spotted!!\n\
2. Assault!\n\
3. Move spotted!!\n\
4. Move in!\n\
5. I'm going to check!\n\
6. Area clear!\n\
7. Affirmitive! or Yes, sir!\n\
8. Negative!\n\
9. All guys are safe!\n\
0. Cancel\
"
};
// CMD_MENU: RadioMenu ]



파일명: client.cpp
함수위치:
void ClientCommand( edict_t *pEntity )
{
이 함수 중간에 추가

code:
...
// CMD_MENU: RadioMenu [
else if( FStrEq(pcmd, "radio1") )
{
//EMIT_SOUND(ENT(pev), CHAN_VOICE, slc[0][1], 1, ATTN_NORM);
GetClassPtr( (CBasePlayer *)pev )->UTIL_ShowMenu( pEntity, 0x3FF, -1, FALSE, slc_menu );
//ClientPrint(pev, MSG_ONE, "radio1 worked!\n");


// function: UTIL_ShowMenu( pEntity, 0x1F, -1, FALSE, slc_menu );
//
// 0x3FF: 1024(d), 0-9 ( 참고: 10진수 1024가 16진수로 0x3FF 입니다. 1024란 숫자는 0 - 9 까지 개수인 10 입니다. )
// 0x1F: corresponds to keys 1-5 (bit 0 through bit 4)
// FALSE: is used to indicate that there isn't any more menu text after this one.
// If you are sending a long menu (>120 bytes)
// it will need to be broken up into parts sending TRUE for the first parts and FALSE for the last one.

/*
// source: http://www.thewavelength.net/forums/oldthreads/000248.html
// code by daas
// slot 개수를 Hexa code로 구하기
#include

int main(void)
{
int num;
int out;
int total;

printf( "Enter Amount Menu Options : " );
scanf( "%d", &num );

out = 1;
total = out;

for( int x = 1; x {
out = out * 2;
total += out;
}

printf( "bitValidSlots: %d\n", total );

return 0;
}
*/
}
else if( FStrEq(pcmd, "menuselect") )
{
// CMD_ARGV(1)은 config.cfg에서 BIND 했던 변수와 비교 검색이 안된다.
// 따라서 그냥 string으로 비교한다.
// i.g., if( FStrEq(CMD_ARGV(1), "1") ) {}

if( FStrEq(CMD_ARGV(1), "1") )
{
EMIT_SOUND(ENT(pev), CHAN_VOICE, slc[8][1], 1, ATTN_NORM);
ClientPrint(pev, MSG_ONE, "1, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "2") )
{
EMIT_SOUND(ENT(pev), CHAN_VOICE, slc[9][1], 1, ATTN_NORM);
ClientPrint(pev, MSG_ONE, "2, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "3") )
{
ClientPrint(pev, MSG_ONE, "3, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "4") )
{
ClientPrint(pev, MSG_ONE, "4, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "5") )
{
ClientPrint(pev, MSG_ONE, "5, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "6") )
{
ClientPrint(pev, MSG_ONE, "6, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "7") )
{
ClientPrint(pev, MSG_ONE, "7, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "8") )
{
ClientPrint(pev, MSG_ONE, "8, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "9") )
{
ClientPrint(pev, MSG_ONE, "9, It worked!\n");
}
else if( FStrEq(CMD_ARGV(1), "10") )
{
ClientPrint(pev, MSG_ONE, "0, It worked!\n");
}
}
// CMD_MENU: RadioMenu ]

이제 스팀으로 MOD를 실행하시고,
게임화면에서 'z' 키를 눌러 보세요.
그러면 Counter-Strike 와 같은 라디오 메시지 메뉴가 나올것입니다.
이제 숫자를 눌러주시면 사운드가 play 될 것입니다.

여기에서의 라디오 메시지는 자신의 PC에서 밖엔 소리가 나지 않습니다.

이상입니다.
수고하셨습니다.

- godmode2k

댓글 없음:

댓글 쓰기