지도 소스 #2

2007.04.12 13:00

그리움 조회 수:195 추천:56

아래 소스는 天地의 조자건님이 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);
}
      

글을 옮기는 과정에서, 일부 누락된 부분이 있을수 있으나,
소스의 전체 흐름을 파악하는데는 아무런 문제가 없을것입니다.

홈지기 "그륨"


XE Login