지도 소스 #2
2007.04.12 13:00
아래 소스는 天地의 조자건님이 INS에 올린 글을 옮겨온것입니다.
현재 이 지도 소스가 여러 머드에서 사용되고 있는걸루 알고
있으며, 실제로 천지에서도 이 소스를 사용하고 있는것 같더
군요. 천외천도 이와 비슷한 루틴을 이용해서 만들어졌습니다.
이를 분석하시면, 어떻게 지도가 구성이 되는지 알수 있을겁니다.
멋진 지도 소스가 탄생하길 바라며.
/********************************************************/
/* 지도 */
/********************************************************/
int view_map(ply_ptr)
creature *ply_ptr;
{
room *rom_ptr[5][5]; /* 5 x 5 의 방 배치를 위한 배열 */
xtag *xp;
int xeast[5][5],xwest[5][5],xnorth[5][5],xsouth[5][5],xup[5][5],xdown[5][5];
/* 출구 있나 없나의 플레그 */
unsigned char map[15][5][12],stand_point[20];
unsigned char tmp[5],tmp2[5]; /* 지도 출력용 */
unsigned char stand_name[7];
int i,j,k,l,nowrom;
int last_nfinished,nfinished,is_finished[7][7]; /* last_nfinished는 지난 루틴에서
완성된 방의 갯수 , nfinished는 이번 루프에서 완성된 방의 갯수 */
int sequ[25][2]={{0,0},{-1,0},{0,-1},{1,0},{0,1},{-2,0},{-1,-1},{0,-2},{1,-1
},{2,0},{1,1},{0,2},{-1,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-
2,1},{-2,-2},{2,-2},{2,2},{-2,2}}; /* 지도를 그리는 순서 X축 Y축 */
if(F_ISSET(ply_ptr, PBLIND)) {
ANSI(ply_ptr->fd, BOLD);
ANSI(ply_ptr->fd, RED);
print(ply_ptr->fd, "당신은 눈이 멀어 있습니다!");
ANSI(ply_ptr->fd, WHITE);
ANSI(ply_ptr->fd, NORMAL);
return(0);
}
print(ply_ptr->fd, "\n당신은 지도를 펴서 찬찬히 살핍니다.\n");
broadcast_rom(ply_ptr->fd, ply_ptr->rom_num,"\n%M이 지도를 봅니다.", ply_pt
r);
/* 사용되는 변수의 초기화 */
for(i=0;i<5;i++) for(j=0;j<5;j++) {
xeast[i][j]=xwest[i][j]=xnorth[i][j]=xsouth[i][j]=xup[i][j]=xdown[i][j]=0;
rom_ptr[i][j]=NULL;
is_finished[i][j]=0;
}
xp=NULL;
/* 첫번째 방( 플레이어가 있는방 )의 출구를 검색하는 것을 시작으로 디스플레이
되는 모든 방을 조사한다 */
nfinished=0;
last_nfinished=-1;
rom_ptr[2][2]=ply_ptr->parent_rom;
nowrom=0;
while(1) {
if(last_nfinished==nfinished) break; /* 더이상 방에 대한 수정이 없으면 종료한다. */
last_nfinished=nfinished;
for(l=0;l<25;l++) {
i=sequ[l][1]+2; /* 방을 차례로 검색함 */
j=sequ[l][0]+2;
if(rom_ptr[i][j] && !is_finished[i][j]) {
nowrom=l;
break;
}
}
i=sequ[nowrom][1]+2;
j=sequ[nowrom][0]+2;
if(rom_ptr[i][j] && !is_finished[i][j]) {
nfinished++; /* 완성된 방의 갯수를 하나 늘림 */
is_finished[i][j]=1;
xp=rom_ptr[i][j]->first_ext;
/* 선택된 방에 대하여 출구를 찾는 작업을 수행한다 */
while(xp) {
if(!strcmp(xp->ext->name,"동") && !F_ISSET(xp->ext,XCLOSD) && !F_ISSET
(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT)) {
xeast[i][j]=1;
if(j!=4)
load_rom(xp->ext->room,&rom_ptr[i][j+1]);
}
else if(!strcmp(xp->ext->name,"서") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xwest[i][j]=1;
if(j!=0)
load_rom(xp->ext->room,&rom_ptr[i][j-1]);
}
else if(!strcmp(xp->ext->name,"남") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xsouth[i][j]=1;
if(i!=4)
load_rom(xp->ext->room,&rom_ptr[i+1][j]);
}
else if(!strcmp(xp->ext->name,"북") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xnorth[i][j]=1;
if(i!=0)
load_rom(xp->ext->room,&rom_ptr[i-1][j]);
}
else if(!strcmp(xp->ext->name,"위") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
xup[i][j]=1;
else if(!strcmp(xp->ext->name,"밑") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
xdown[i][j]=1;
xp=xp->next_tag;
}
}
}
for(i=0;i<5;i++) {
for(j=0;j<5;j++) {
if(rom_ptr[i][j]) {
/* 북쪽 */
strcpy(map[i*3][j]," ");
if(xnorth[i][j]) {
if(xnorth[i][j]==1 && xsouth[i-1][j]==1) {
if(i-1>=0) strcat(map[i*3][j],"||");
else strcat(map[i*3][j],"^^");
}
else {
if(i-1>=0) strcat(map[i*3][j],"??");
else strcat(map[i*3][j],"^^");
}
}
else strcat(map[i*3][j]," ");
/* 위 */
if(xup[i][j]) strcat(map[i*3][j]," 위 ");
else strcat(map[i*3][j]," ");
/* 서쪽 */
if(xwest[i][j]) {
if(xwest[i][j]==1 && xeast[i][j-1]==1) {
if(j-1>=0) strcpy(map[i*3+1][j],"=[");
else strcpy(map[i*3+1][j],"<[");
}
else {
if(j-1>=0) strcpy(map[i*3+1][j],"?[");
else strcpy(map[i*3+1][j],"<[");
}
}
else strcpy(map[i*3+1][j]," [");
/* 방이름 */
/* 한글이 잘리는 문제를 처리하기 위한 부분 */
for(k=0;k<8;k++) {
tmp2[k]='\0';
tmp[k]='\0';
}
strncpy(tmp,rom_ptr[i][j]->name,6);
if(strlen(tmp)<6) {
for(k=0;k<6;k++) {
if(tmp[k]=='\0') {
tmp[k]=' ';
tmp[k+1]='\0';
}
}
}
strcpy(tmp2,tmp);
if(!ishan(tmp) && tmp2[5]>=0xb0 && tmp2[5]<=0xc8) {
tmp[0]=' ';
for(k=0;k<6;k++) tmp[k+1]=tmp2[k];
tmp[6]='\0';
strcpy(tmp2,tmp);
}
if(strlen(tmp2)<6) {
for(k=0;k<6;k++) {
if(tmp2[k]=='\0') {
tmp2[k]=' ';
tmp2[k+1]='\0';
}
}
}
strncat(map[i*3+1][j],tmp2,6);
if(i==2 && j==2) strcpy(stand_name,tmp2);
/* 동쪽 */
if(xeast[i][j]) {
if(xeast[i][j]==1 && xwest[i][j+1]==1) {
if(j+1<=4) strcat(map[i*3+1][j],"]=");
else strcat(map[i*3+1][j],"]>");
}
else {
if(j+1<=4) strcat(map[i*3+1][j],"]?");
else strcat(map[i*3+1][j],"]>");
}
}
else strcat(map[i*3+1][j],"] ");
/* 남쪽 */
strcpy(map[i*3+2][j]," ");
if(xsouth[i][j]) {
if(xsouth[i][j]==1 && xnorth[i+1][j]==1) {
if(i+1<=4) strcat(map[i*3+2][j],"||");
else strcat(map[i*3+2][j],"vv");
}
else {
if(i+1<=4) strcat(map[i*3+2][j],"??");
else strcat(map[i*3+2][j],"vv");
}
}
else strcat(map[i*3+2][j]," ");
/* 밑 */
if(xdown[i][j]) strcat(map[i*3+2][j]," 밑 ");
else strcat(map[i*3+2][j]," ");
}
else { /* 방이 로드되어있지 않은 경우 */
strcpy(map[i*3][j]," ");
strcpy(map[i*3+1][j]," ");
strcpy(map[i*3+2][j]," ");
}
}
}
/* 서있는 곳의 설명과 색을 바꾼다 */
i=j=2;
/* 서쪽 */
if(xwest[i][j]) {
if(xwest[i][j]==1 && xeast[i][j-1]==1) strcpy(stand_point,"=[");
else strcpy(stand_point,"?[");
}
else strcpy(stand_point," [");
/* 방이름 */
strcat(stand_point,"{녹");
strcat(stand_point,stand_name);
strcat(stand_point,"}");
/* 동쪽 */
if(xeast[i][j]) {
if(xeast[i][j]==1 && xwest[i][j+1]==1) strcat(stand_point,"]=");
else strcat(stand_point,"]?");
}
else strcat(stand_point,"] ");
/* 화면에 뿌린다 */
print(ply_ptr->fd,"\n_____[ 주변의 지도 ]__________________________________\
n|%52s|"," ");
for(i=0;i<15;i++) {
print(ply_ptr->fd,"\n| ");
for(j=0;j<5;j++) {
if(i==7 && j==2) print(ply_ptr->fd,"%10s",ansi_print(ply_ptr,stand_point));
else print(ply_ptr->fd,"%10s",map[i][j]);
}
if(i==14) print(ply_ptr->fd,"_|");
else print(ply_ptr->fd," |");
}
print(ply_ptr->fd,"\n|__________________________________________________|/\n
");
return(0);
}
글을 옮기는 과정에서, 일부 누락된 부분이 있을수 있으나,
소스의 전체 흐름을 파악하는데는 아무런 문제가 없을것입니다.
홈지기 "그륨"
현재 이 지도 소스가 여러 머드에서 사용되고 있는걸루 알고
있으며, 실제로 천지에서도 이 소스를 사용하고 있는것 같더
군요. 천외천도 이와 비슷한 루틴을 이용해서 만들어졌습니다.
이를 분석하시면, 어떻게 지도가 구성이 되는지 알수 있을겁니다.
멋진 지도 소스가 탄생하길 바라며.
/********************************************************/
/* 지도 */
/********************************************************/
int view_map(ply_ptr)
creature *ply_ptr;
{
room *rom_ptr[5][5]; /* 5 x 5 의 방 배치를 위한 배열 */
xtag *xp;
int xeast[5][5],xwest[5][5],xnorth[5][5],xsouth[5][5],xup[5][5],xdown[5][5];
/* 출구 있나 없나의 플레그 */
unsigned char map[15][5][12],stand_point[20];
unsigned char tmp[5],tmp2[5]; /* 지도 출력용 */
unsigned char stand_name[7];
int i,j,k,l,nowrom;
int last_nfinished,nfinished,is_finished[7][7]; /* last_nfinished는 지난 루틴에서
완성된 방의 갯수 , nfinished는 이번 루프에서 완성된 방의 갯수 */
int sequ[25][2]={{0,0},{-1,0},{0,-1},{1,0},{0,1},{-2,0},{-1,-1},{0,-2},{1,-1
},{2,0},{1,1},{0,2},{-1,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-
2,1},{-2,-2},{2,-2},{2,2},{-2,2}}; /* 지도를 그리는 순서 X축 Y축 */
if(F_ISSET(ply_ptr, PBLIND)) {
ANSI(ply_ptr->fd, BOLD);
ANSI(ply_ptr->fd, RED);
print(ply_ptr->fd, "당신은 눈이 멀어 있습니다!");
ANSI(ply_ptr->fd, WHITE);
ANSI(ply_ptr->fd, NORMAL);
return(0);
}
print(ply_ptr->fd, "\n당신은 지도를 펴서 찬찬히 살핍니다.\n");
broadcast_rom(ply_ptr->fd, ply_ptr->rom_num,"\n%M이 지도를 봅니다.", ply_pt
r);
/* 사용되는 변수의 초기화 */
for(i=0;i<5;i++) for(j=0;j<5;j++) {
xeast[i][j]=xwest[i][j]=xnorth[i][j]=xsouth[i][j]=xup[i][j]=xdown[i][j]=0;
rom_ptr[i][j]=NULL;
is_finished[i][j]=0;
}
xp=NULL;
/* 첫번째 방( 플레이어가 있는방 )의 출구를 검색하는 것을 시작으로 디스플레이
되는 모든 방을 조사한다 */
nfinished=0;
last_nfinished=-1;
rom_ptr[2][2]=ply_ptr->parent_rom;
nowrom=0;
while(1) {
if(last_nfinished==nfinished) break; /* 더이상 방에 대한 수정이 없으면 종료한다. */
last_nfinished=nfinished;
for(l=0;l<25;l++) {
i=sequ[l][1]+2; /* 방을 차례로 검색함 */
j=sequ[l][0]+2;
if(rom_ptr[i][j] && !is_finished[i][j]) {
nowrom=l;
break;
}
}
i=sequ[nowrom][1]+2;
j=sequ[nowrom][0]+2;
if(rom_ptr[i][j] && !is_finished[i][j]) {
nfinished++; /* 완성된 방의 갯수를 하나 늘림 */
is_finished[i][j]=1;
xp=rom_ptr[i][j]->first_ext;
/* 선택된 방에 대하여 출구를 찾는 작업을 수행한다 */
while(xp) {
if(!strcmp(xp->ext->name,"동") && !F_ISSET(xp->ext,XCLOSD) && !F_ISSET
(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT)) {
xeast[i][j]=1;
if(j!=4)
load_rom(xp->ext->room,&rom_ptr[i][j+1]);
}
else if(!strcmp(xp->ext->name,"서") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xwest[i][j]=1;
if(j!=0)
load_rom(xp->ext->room,&rom_ptr[i][j-1]);
}
else if(!strcmp(xp->ext->name,"남") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xsouth[i][j]=1;
if(i!=4)
load_rom(xp->ext->room,&rom_ptr[i+1][j]);
}
else if(!strcmp(xp->ext->name,"북") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
{
xnorth[i][j]=1;
if(i!=0)
load_rom(xp->ext->room,&rom_ptr[i-1][j]);
}
else if(!strcmp(xp->ext->name,"위") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
xup[i][j]=1;
else if(!strcmp(xp->ext->name,"밑") && !F_ISSET(xp->ext,XCLOSD) && !F_
ISSET(xp->ext,XINVIS) && !F_ISSET(xp->ext,XLOCKD) && !F_ISSET(xp->ext,XSECRT))
xdown[i][j]=1;
xp=xp->next_tag;
}
}
}
for(i=0;i<5;i++) {
for(j=0;j<5;j++) {
if(rom_ptr[i][j]) {
/* 북쪽 */
strcpy(map[i*3][j]," ");
if(xnorth[i][j]) {
if(xnorth[i][j]==1 && xsouth[i-1][j]==1) {
if(i-1>=0) strcat(map[i*3][j],"||");
else strcat(map[i*3][j],"^^");
}
else {
if(i-1>=0) strcat(map[i*3][j],"??");
else strcat(map[i*3][j],"^^");
}
}
else strcat(map[i*3][j]," ");
/* 위 */
if(xup[i][j]) strcat(map[i*3][j]," 위 ");
else strcat(map[i*3][j]," ");
/* 서쪽 */
if(xwest[i][j]) {
if(xwest[i][j]==1 && xeast[i][j-1]==1) {
if(j-1>=0) strcpy(map[i*3+1][j],"=[");
else strcpy(map[i*3+1][j],"<[");
}
else {
if(j-1>=0) strcpy(map[i*3+1][j],"?[");
else strcpy(map[i*3+1][j],"<[");
}
}
else strcpy(map[i*3+1][j]," [");
/* 방이름 */
/* 한글이 잘리는 문제를 처리하기 위한 부분 */
for(k=0;k<8;k++) {
tmp2[k]='\0';
tmp[k]='\0';
}
strncpy(tmp,rom_ptr[i][j]->name,6);
if(strlen(tmp)<6) {
for(k=0;k<6;k++) {
if(tmp[k]=='\0') {
tmp[k]=' ';
tmp[k+1]='\0';
}
}
}
strcpy(tmp2,tmp);
if(!ishan(tmp) && tmp2[5]>=0xb0 && tmp2[5]<=0xc8) {
tmp[0]=' ';
for(k=0;k<6;k++) tmp[k+1]=tmp2[k];
tmp[6]='\0';
strcpy(tmp2,tmp);
}
if(strlen(tmp2)<6) {
for(k=0;k<6;k++) {
if(tmp2[k]=='\0') {
tmp2[k]=' ';
tmp2[k+1]='\0';
}
}
}
strncat(map[i*3+1][j],tmp2,6);
if(i==2 && j==2) strcpy(stand_name,tmp2);
/* 동쪽 */
if(xeast[i][j]) {
if(xeast[i][j]==1 && xwest[i][j+1]==1) {
if(j+1<=4) strcat(map[i*3+1][j],"]=");
else strcat(map[i*3+1][j],"]>");
}
else {
if(j+1<=4) strcat(map[i*3+1][j],"]?");
else strcat(map[i*3+1][j],"]>");
}
}
else strcat(map[i*3+1][j],"] ");
/* 남쪽 */
strcpy(map[i*3+2][j]," ");
if(xsouth[i][j]) {
if(xsouth[i][j]==1 && xnorth[i+1][j]==1) {
if(i+1<=4) strcat(map[i*3+2][j],"||");
else strcat(map[i*3+2][j],"vv");
}
else {
if(i+1<=4) strcat(map[i*3+2][j],"??");
else strcat(map[i*3+2][j],"vv");
}
}
else strcat(map[i*3+2][j]," ");
/* 밑 */
if(xdown[i][j]) strcat(map[i*3+2][j]," 밑 ");
else strcat(map[i*3+2][j]," ");
}
else { /* 방이 로드되어있지 않은 경우 */
strcpy(map[i*3][j]," ");
strcpy(map[i*3+1][j]," ");
strcpy(map[i*3+2][j]," ");
}
}
}
/* 서있는 곳의 설명과 색을 바꾼다 */
i=j=2;
/* 서쪽 */
if(xwest[i][j]) {
if(xwest[i][j]==1 && xeast[i][j-1]==1) strcpy(stand_point,"=[");
else strcpy(stand_point,"?[");
}
else strcpy(stand_point," [");
/* 방이름 */
strcat(stand_point,"{녹");
strcat(stand_point,stand_name);
strcat(stand_point,"}");
/* 동쪽 */
if(xeast[i][j]) {
if(xeast[i][j]==1 && xwest[i][j+1]==1) strcat(stand_point,"]=");
else strcat(stand_point,"]?");
}
else strcat(stand_point,"] ");
/* 화면에 뿌린다 */
print(ply_ptr->fd,"\n_____[ 주변의 지도 ]__________________________________\
n|%52s|"," ");
for(i=0;i<15;i++) {
print(ply_ptr->fd,"\n| ");
for(j=0;j<5;j++) {
if(i==7 && j==2) print(ply_ptr->fd,"%10s",ansi_print(ply_ptr,stand_point));
else print(ply_ptr->fd,"%10s",map[i][j]);
}
if(i==14) print(ply_ptr->fd,"_|");
else print(ply_ptr->fd," |");
}
print(ply_ptr->fd,"\n|__________________________________________________|/\n
");
return(0);
}
글을 옮기는 과정에서, 일부 누락된 부분이 있을수 있으나,
소스의 전체 흐름을 파악하는데는 아무런 문제가 없을것입니다.
홈지기 "그륨"
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
57 | 특수 아이템 만들기 | 그리움 | 2007.04.12 | 253 |
56 | 몹과 자신을 "비교" | 그리움 | 2007.04.12 | 219 |
55 | 패거리 전쟁시 적과 아군 구분 | 그리움 | 2007.04.12 | 216 |
54 | 순위 소스 | 그리움 | 2007.04.12 | 215 |
53 | 개량형 우체국 | 그리움 | 2007.04.12 | 228 |
52 | 명성치 도입 | 그리움 | 2007.04.12 | 229 |
51 | 자기 아파트 방설명은 자기가 #2 | 그리움 | 2007.04.12 | 222 |
50 | 이동력 추가하기 | 그리움 | 2007.04.12 | 225 |
49 | 경매 소스 | 그리움 | 2007.04.12 | 217 |
48 | 글자색, 배경색 15색 사용하기 | 그리움 | 2007.04.12 | 213 |
47 | Ctrl+Enter 패치하기 | 그리움 | 2007.04.12 | 198 |
46 | 패거리 상점 만들기 | 그리움 | 2007.04.12 | 199 |
45 | 귀환장소 설정 | 그리움 | 2007.04.12 | 228 |
44 | 출구 정렬 | 그리움 | 2007.04.12 | 222 |
43 | 게시판 검색 기능 추가하기 | 그리움 | 2007.04.12 | 207 |
42 | 암호 *****로 보이게 하기 | 그리움 | 2007.04.12 | 215 |
41 | 레벨을 32767까지 가능하게 | 그리움 | 2007.04.12 | 236 |
40 | 잡담 안시 사용하기 | 그리움 | 2007.04.12 | 236 |
» | 지도 소스 #2 | 그리움 | 2007.04.12 | 230 |
38 | 베팅소스 | 그리움 | 2007.04.12 | 242 |